1/*! 2 * jQuery JavaScript Library v1.7.2 3 * http://jquery.com/ 4 * 5 * Copyright 2011, John Resig 6 * Dual licensed under the MIT or GPL Version 2 licenses. 7 * http://jquery.org/license 8 * 9 * Includes Sizzle.js 10 * http://sizzlejs.com/ 11 * Copyright 2011, The Dojo Foundation 12 * Released under the MIT, BSD, and GPL Licenses. 13 * 14 * Date: Wed Mar 21 12:46:34 2012 -0700 15 */ 16 17(function( window, undefined ) { 18 19// Use the correct document accordingly with window argument (sandbox) 20var document = window.document, 21 navigator = window.navigator, 22 location = window.location; 23var jQuery = (function() { 24 25// Define a local copy of jQuery 26var jQuery = function( selector, context ) { 27 // The jQuery object is actually just the init constructor 'enhanced' 28 return new jQuery.fn.init( selector, context, rootjQuery ); 29 }, 30 31 // Map over jQuery in case of overwrite 32 _jQuery = window.jQuery, 33 34 // Map over the $ in case of overwrite 35 _$ = window.$, 36 37 // A central reference to the root jQuery(document) 38 rootjQuery, 39 40 // A simple way to check for HTML strings or ID strings 41 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 42 quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, 43 44 // Check if a string has a non-whitespace character in it 45 rnotwhite = /\S/, 46 47 // Used for trimming whitespace 48 trimLeft = /^\s+/, 49 trimRight = /\s+$/, 50 51 // Match a standalone tag 52 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, 53 54 // JSON RegExp 55 rvalidchars = /^[\],:{}\s]*$/, 56 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 57 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 58 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 59 60 // Useragent RegExp 61 rwebkit = /(webkit)[ \/]([\w.]+)/, 62 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, 63 rmsie = /(msie) ([\w.]+)/, 64 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 65 66 // Matches dashed string for camelizing 67 rdashAlpha = /-([a-z]|[0-9])/ig, 68 rmsPrefix = /^-ms-/, 69 70 // Used by jQuery.camelCase as callback to replace() 71 fcamelCase = function( all, letter ) { 72 return ( letter + "" ).toUpperCase(); 73 }, 74 75 // Keep a UserAgent string for use with jQuery.browser 76 userAgent = navigator.userAgent, 77 78 // For matching the engine and version of the browser 79 browserMatch, 80 81 // The deferred used on DOM ready 82 readyList, 83 84 // The ready event handler 85 DOMContentLoaded, 86 87 // Save a reference to some core methods 88 toString = Object.prototype.toString, 89 hasOwn = Object.prototype.hasOwnProperty, 90 push = Array.prototype.push, 91 slice = Array.prototype.slice, 92 trim = String.prototype.trim, 93 indexOf = Array.prototype.indexOf, 94 95 // [[Class]] -> type pairs 96 class2type = {}; 97 98jQuery.fn = jQuery.prototype = { 99 constructor: jQuery, 100 init: function( selector, context, rootjQuery ) { 101 var match, elem, ret, doc; 102 103 // Handle $(""), $(null), or $(undefined) 104 if ( !selector ) { 105 return this; 106 } 107 108 // Handle $(DOMElement) 109 if ( selector.nodeType ) { 110 this.context = this[0] = selector; 111 this.length = 1; 112 return this; 113 } 114 115 // The body element only exists once, optimize finding it 116 if ( selector === "body" && !context && document.body ) { 117 this.context = document; 118 this[0] = document.body; 119 this.selector = selector; 120 this.length = 1; 121 return this; 122 } 123 124 // Handle HTML strings 125 if ( typeof selector === "string" ) { 126 // Are we dealing with HTML string or an ID? 127 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 128 // Assume that strings that start and end with <> are HTML and skip the regex check 129 match = [ null, selector, null ]; 130 131 } else { 132 match = quickExpr.exec( selector ); 133 } 134 135 // Verify a match, and that no context was specified for #id 136 if ( match && (match[1] || !context) ) { 137 138 // HANDLE: $(html) -> $(array) 139 if ( match[1] ) { 140 context = context instanceof jQuery ? context[0] : context; 141 doc = ( context ? context.ownerDocument || context : document ); 142 143 // If a single string is passed in and it's a single tag 144 // just do a createElement and skip the rest 145 ret = rsingleTag.exec( selector ); 146 147 if ( ret ) { 148 if ( jQuery.isPlainObject( context ) ) { 149 selector = [ document.createElement( ret[1] ) ]; 150 jQuery.fn.attr.call( selector, context, true ); 151 152 } else { 153 selector = [ doc.createElement( ret[1] ) ]; 154 } 155 156 } else { 157 ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); 158 selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; 159 } 160 161 return jQuery.merge( this, selector ); 162 163 // HANDLE: $("#id") 164 } else { 165 elem = document.getElementById( match[2] ); 166 167 // Check parentNode to catch when Blackberry 4.6 returns 168 // nodes that are no longer in the document #6963 169 if ( elem && elem.parentNode ) { 170 // Handle the case where IE and Opera return items 171 // by name instead of ID 172 if ( elem.id !== match[2] ) { 173 return rootjQuery.find( selector ); 174 } 175 176 // Otherwise, we inject the element directly into the jQuery object 177 this.length = 1; 178 this[0] = elem; 179 } 180 181 this.context = document; 182 this.selector = selector; 183 return this; 184 } 185 186 // HANDLE: $(expr, $(...)) 187 } else if ( !context || context.jquery ) { 188 return ( context || rootjQuery ).find( selector ); 189 190 // HANDLE: $(expr, context) 191 // (which is just equivalent to: $(context).find(expr) 192 } else { 193 return this.constructor( context ).find( selector ); 194 } 195 196 // HANDLE: $(function) 197 // Shortcut for document ready 198 } else if ( jQuery.isFunction( selector ) ) { 199 return rootjQuery.ready( selector ); 200 } 201 202 if ( selector.selector !== undefined ) { 203 this.selector = selector.selector; 204 this.context = selector.context; 205 } 206 207 return jQuery.makeArray( selector, this ); 208 }, 209 210 // Start with an empty selector 211 selector: "", 212 213 // The current version of jQuery being used 214 jquery: "1.7.2", 215 216 // The default length of a jQuery object is 0 217 length: 0, 218 219 // The number of elements contained in the matched element set 220 size: function() { 221 return this.length; 222 }, 223 224 toArray: function() { 225 return slice.call( this, 0 ); 226 }, 227 228 // Get the Nth element in the matched element set OR 229 // Get the whole matched element set as a clean array 230 get: function( num ) { 231 return num == null ? 232 233 // Return a 'clean' array 234 this.toArray() : 235 236 // Return just the object 237 ( num < 0 ? this[ this.length + num ] : this[ num ] ); 238 }, 239 240 // Take an array of elements and push it onto the stack 241 // (returning the new matched element set) 242 pushStack: function( elems, name, selector ) { 243 // Build a new jQuery matched element set 244 var ret = this.constructor(); 245 246 if ( jQuery.isArray( elems ) ) { 247 push.apply( ret, elems ); 248 249 } else { 250 jQuery.merge( ret, elems ); 251 } 252 253 // Add the old object onto the stack (as a reference)
vendor: 4,209 bytes, lines 254-434
254 ret.prevObject = this; 255 256 ret.context = this.context; 257 258 if ( name === "find" ) { 259 ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; 260 } else if ( name ) { 261 ret.selector = this.selector + "." + name + "(" + selector + ")"; 262 } 263 264 // Return the newly-formed element set 265 return ret; 266 }, 267 268 // Execute a callback for every element in the matched set. 269 // (You can seed the arguments with an array of args, but this is 270 // only used internally.) 271 each: function( callback, args ) { 272 return jQuery.each( this, callback, args ); 273 }, 274 275 ready: function( fn ) { 276 // Attach the listeners 277 jQuery.bindReady(); 278 279 // Add the callback 280 readyList.add( fn ); 281 282 return this; 283 }, 284 285 eq: function( i ) { 286 i = +i; 287 return i === -1 ? 288 this.slice( i ) : 289 this.slice( i, i + 1 ); 290 }, 291 292 first: function() { 293 return this.eq( 0 ); 294 }, 295 296 last: function() { 297 return this.eq( -1 ); 298 }, 299 300 slice: function() { 301 return this.pushStack( slice.apply( this, arguments ), 302 "slice", slice.call(arguments).join(",") ); 303 }, 304 305 map: function( callback ) { 306 return this.pushStack( jQuery.map(this, function( elem, i ) { 307 return callback.call( elem, i, elem ); 308 })); 309 }, 310 311 end: function() { 312 return this.prevObject || this.constructor(null); 313 }, 314 315 // For internal use only. 316 // Behaves like an Array's method, not like a jQuery method. 317 push: push, 318 sort: [].sort, 319 splice: [].splice 320}; 321 322// Give the init function the jQuery prototype for later instantiation 323jQuery.fn.init.prototype = jQuery.fn; 324 325jQuery.extend = jQuery.fn.extend = function() { 326 var options, name, src, copy, copyIsArray, clone, 327 target = arguments[0] || {}, 328 i = 1, 329 length = arguments.length, 330 deep = false; 331 332 // Handle a deep copy situation 333 if ( typeof target === "boolean" ) { 334 deep = target; 335 target = arguments[1] || {}; 336 // skip the boolean and the target 337 i = 2; 338 } 339 340 // Handle case when target is a string or something (possible in deep copy) 341 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 342 target = {}; 343 } 344 345 // extend jQuery itself if only one argument is passed 346 if ( length === i ) { 347 target = this; 348 --i; 349 } 350 351 for ( ; i < length; i++ ) { 352 // Only deal with non-null/undefined values 353 if ( (options = arguments[ i ]) != null ) { 354 // Extend the base object 355 for ( name in options ) { 356 src = target[ name ]; 357 copy = options[ name ]; 358 359 // Prevent never-ending loop 360 if ( target === copy ) { 361 continue; 362 } 363 364 // Recurse if we're merging plain objects or arrays 365 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 366 if ( copyIsArray ) { 367 copyIsArray = false; 368 clone = src && jQuery.isArray(src) ? src : []; 369 370 } else { 371 clone = src && jQuery.isPlainObject(src) ? src : {}; 372 } 373 374 // Never move original objects, clone them 375 target[ name ] = jQuery.extend( deep, clone, copy ); 376 377 // Don't bring in undefined values 378 } else if ( copy !== undefined ) { 379 target[ name ] = copy; 380 } 381 } 382 } 383 } 384 385 // Return the modified object 386 return target; 387}; 388 389jQuery.extend({ 390 noConflict: function( deep ) { 391 if ( window.$ === jQuery ) { 392 window.$ = _$; 393 } 394 395 if ( deep && window.jQuery === jQuery ) { 396 window.jQuery = _jQuery; 397 } 398 399 return jQuery; 400 }, 401 402 // Is the DOM ready to be used? Set to true once it occurs. 403 isReady: false, 404 405 // A counter to track how many items to wait for before 406 // the ready event fires. See #6781 407 readyWait: 1, 408 409 // Hold (or release) the ready event 410 holdReady: function( hold ) { 411 if ( hold ) { 412 jQuery.readyWait++; 413 } else { 414 jQuery.ready( true ); 415 } 416 }, 417 418 // Handle when the DOM is ready 419 ready: function( wait ) { 420 // Either a released hold or an DOMready/load event and not yet ready 421 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { 422 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 423 if ( !document.body ) { 424 return setTimeout( jQuery.ready, 1 ); 425 } 426 427 // Remember that the DOM is ready 428 jQuery.isReady = true; 429 430 // If a normal DOM Ready event fired, decrement, and wait if need be 431 if ( wait !== true && --jQuery.readyWait > 0 ) { 432 return; 433 } 434
435 // If there are functions bound, to execute 436 readyList.fireWith( document, [ jQuery ] ); 437 438 // Trigger any bound ready events 439 if ( jQuery.fn.trigger ) { 440 jQuery( document ).trigger( "ready" ).off( "ready" ); 441 } 442 } 443 }, 444 445 bindReady: function() { 446 if ( readyList ) { 447 return; 448 } 449 450 readyList = jQuery.Callbacks( "once memory" ); 451 452 // Catch cases where $(document).ready() is called after the 453 // browser event has already occurred. 454 if ( document.readyState === "complete" ) { 455 // Handle it asynchronously to allow scripts the opportunity to delay ready 456 return setTimeout( jQuery.ready, 1 ); 457 } 458 459 // Mozilla, Opera and webkit nightlies currently support this event 460 if ( document.addEventListener ) { 461 // Use the handy event callback 462 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 463 464 // A fallback to window.onload, that will always work 465 window.addEventListener( "load", jQuery.ready, false ); 466 467 // If IE event model is used 468 } else if ( document.attachEvent ) { 469 // ensure firing before onload, 470 // maybe late but safe also for iframes 471 document.attachEvent( "onreadystatechange", DOMContentLoaded ); 472 473 // A fallback to window.onload, that will always work 474 window.attachEvent( "onload", jQuery.ready ); 475 476 // If IE and not a frame 477 // continually check to see if the document is ready 478 var toplevel = false; 479 480 try { 481 toplevel = window.frameElement == null; 482 } catch(e) {} 483 484 if ( document.documentElement.doScroll && toplevel ) { 485 doScrollCheck(); 486 } 487 } 488 }, 489 490 // See test/unit/core.js for details concerning isFunction. 491 // Since version 1.3, DOM methods and functions like alert 492 // aren't supported. They return false on IE (#2968). 493 isFunction: function( obj ) { 494 return jQuery.type(obj) === "function"; 495 }, 496 497 isArray: Array.isArray || function( obj ) { 498 return jQuery.type(obj) === "array"; 499 }, 500 501 isWindow: function( obj ) { 502 return obj != null && obj == obj.window; 503 }, 504 505 isNumeric: function( obj ) { 506 return !isNaN( parseFloat(obj) ) && isFinite( obj ); 507 }, 508 509 type: function( obj ) { 510 return obj == null ? 511 String( obj ) : 512 class2type[ toString.call(obj) ] || "object"; 513 }, 514 515 isPlainObject: function( obj ) { 516 // Must be an Object. 517 // Because of IE, we also have to check the presence of the constructor property. 518 // Make sure that DOM nodes and window objects don't pass through, as well 519 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 520 return false; 521 } 522 523 try { 524 // Not own constructor property must be Object 525 if ( obj.constructor && 526 !hasOwn.call(obj, "constructor") && 527 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { 528 return false; 529 } 530 } catch ( e ) { 531 // IE8,9 Will throw exceptions on certain host objects #9897 532 return false; 533 } 534 535 // Own properties are enumerated firstly, so to speed up, 536 // if last one is own, then all properties are own. 537 538 var key; 539 for ( key in obj ) {} 540 541 return key === undefined || hasOwn.call( obj, key ); 542 }, 543 544 isEmptyObject: function( obj ) { 545 for ( var name in obj ) { 546 return false; 547 } 548 return true; 549 }, 550 551 error: function( msg ) { 552 throw new Error( msg ); 553 }, 554 555 parseJSON: function( data ) { 556 if ( typeof data !== "string" || !data ) { 557 return null; 558 } 559 560 // Make sure leading/trailing whitespace is removed (IE can't handle it) 561 data = jQuery.trim( data ); 562 563 // Attempt to parse using the native JSON parser first 564 if ( window.JSON && window.JSON.parse ) { 565 return window.JSON.parse( data ); 566 } 567 568 // Make sure the incoming data is actual JSON 569 // Logic borrowed from http://json.org/json2.js 570 if ( rvalidchars.test( data.replace( rvalidescape, "@" ) 571 .replace( rvalidtokens, "]" ) 572 .replace( rvalidbraces, "")) ) { 573 574 return ( new Function( "return " + data ) )(); 575 576 } 577 jQuery.error( "Invalid JSON: " + data ); 578 }, 579 580 // Cross-browser xml parsing 581 parseXML: function( data ) { 582 if ( typeof data !== "string" || !data ) { 583 return null; 584 } 585 var xml, tmp; 586 try { 587 if ( window.DOMParser ) { // Standard 588 tmp = new DOMParser(); 589 xml = tmp.parseFromString( data , "text/xml" ); 590 } else { // IE 591 xml = new ActiveXObject( "Microsoft.XMLDOM" ); 592 xml.async = "false"; 593 xml.loadXML( data ); 594 } 595 } catch( e ) { 596 xml = undefined; 597 } 598 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { 599 jQuery.error( "Invalid XML: " + data ); 600 } 601 return xml; 602 }, 603 604 noop: function() {}, 605 606 // Evaluates a script in a global context 607 // Workarounds based on findings by Jim Driscoll 608 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 609 globalEval: function( data ) { 610 if ( data && rnotwhite.test( data ) ) { 611 // We use execScript on Internet Explorer 612 // We use an anonymous function so that context is window 613 // rather than jQuery in Firefox 614 ( window.execScript || function( data ) { 615 window[ "eval" ].call( window, data ); 616 } )( data ); 617 } 618 }, 619 620 // Convert dashed to camelCase; used by the css and data modules 621 // Microsoft forgot to hump their vendor prefix (#9572) 622 camelCase: function( string ) { 623 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 624 }, 625
vendor: 7,502 bytes, lines 626-936
626 nodeName: function( elem, name ) { 627 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); 628 }, 629 630 // args is for internal usage only 631 each: function( object, callback, args ) { 632 var name, i = 0, 633 length = object.length, 634 isObj = length === undefined || jQuery.isFunction( object ); 635 636 if ( args ) { 637 if ( isObj ) { 638 for ( name in object ) { 639 if ( callback.apply( object[ name ], args ) === false ) { 640 break; 641 } 642 } 643 } else { 644 for ( ; i < length; ) { 645 if ( callback.apply( object[ i++ ], args ) === false ) { 646 break; 647 } 648 } 649 } 650 651 // A special, fast, case for the most common use of each 652 } else { 653 if ( isObj ) { 654 for ( name in object ) { 655 if ( callback.call( object[ name ], name, object[ name ] ) === false ) { 656 break; 657 } 658 } 659 } else { 660 for ( ; i < length; ) { 661 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { 662 break; 663 } 664 } 665 } 666 } 667 668 return object; 669 }, 670 671 // Use native String.trim function wherever possible 672 trim: trim ? 673 function( text ) { 674 return text == null ? 675 "" : 676 trim.call( text ); 677 } : 678 679 // Otherwise use our own trimming functionality 680 function( text ) { 681 return text == null ? 682 "" : 683 text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); 684 }, 685 686 // results is for internal usage only 687 makeArray: function( array, results ) { 688 var ret = results || []; 689 690 if ( array != null ) { 691 // The window, strings (and functions) also have 'length' 692 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 693 var type = jQuery.type( array ); 694 695 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { 696 push.call( ret, array ); 697 } else { 698 jQuery.merge( ret, array ); 699 } 700 } 701 702 return ret; 703 }, 704 705 inArray: function( elem, array, i ) { 706 var len; 707 708 if ( array ) { 709 if ( indexOf ) { 710 return indexOf.call( array, elem, i ); 711 } 712 713 len = array.length; 714 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; 715 716 for ( ; i < len; i++ ) { 717 // Skip accessing in sparse arrays 718 if ( i in array && array[ i ] === elem ) { 719 return i; 720 } 721 } 722 } 723 724 return -1; 725 }, 726 727 merge: function( first, second ) { 728 var i = first.length, 729 j = 0; 730 731 if ( typeof second.length === "number" ) { 732 for ( var l = second.length; j < l; j++ ) { 733 first[ i++ ] = second[ j ]; 734 } 735 736 } else { 737 while ( second[j] !== undefined ) { 738 first[ i++ ] = second[ j++ ]; 739 } 740 } 741 742 first.length = i; 743 744 return first; 745 }, 746 747 grep: function( elems, callback, inv ) { 748 var ret = [], retVal; 749 inv = !!inv; 750 751 // Go through the array, only saving the items 752 // that pass the validator function 753 for ( var i = 0, length = elems.length; i < length; i++ ) { 754 retVal = !!callback( elems[ i ], i ); 755 if ( inv !== retVal ) { 756 ret.push( elems[ i ] ); 757 } 758 } 759 760 return ret; 761 }, 762 763 // arg is for internal usage only 764 map: function( elems, callback, arg ) { 765 var value, key, ret = [], 766 i = 0, 767 length = elems.length, 768 // jquery objects are treated as arrays 769 isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; 770 771 // Go through the array, translating each of the items to their 772 if ( isArray ) { 773 for ( ; i < length; i++ ) { 774 value = callback( elems[ i ], i, arg ); 775 776 if ( value != null ) { 777 ret[ ret.length ] = value; 778 } 779 } 780 781 // Go through every key on the object, 782 } else { 783 for ( key in elems ) { 784 value = callback( elems[ key ], key, arg ); 785 786 if ( value != null ) { 787 ret[ ret.length ] = value; 788 } 789 } 790 } 791 792 // Flatten any nested arrays 793 return ret.concat.apply( [], ret ); 794 }, 795 796 // A global GUID counter for objects 797 guid: 1, 798 799 // Bind a function to a context, optionally partially applying any 800 // arguments. 801 proxy: function( fn, context ) { 802 if ( typeof context === "string" ) { 803 var tmp = fn[ context ]; 804 context = fn; 805 fn = tmp; 806 } 807 808 // Quick check to determine if target is callable, in the spec 809 // this throws a TypeError, but we will just return undefined. 810 if ( !jQuery.isFunction( fn ) ) { 811 return undefined; 812 } 813 814 // Simulated bind 815 var args = slice.call( arguments, 2 ), 816 proxy = function() { 817 return fn.apply( context, args.concat( slice.call( arguments ) ) ); 818 }; 819 820 // Set the guid of unique handler to the same of original handler, so it can be removed 821 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; 822 823 return proxy; 824 }, 825 826 // Mutifunctional method to get and set values to a collection 827 // The value/s can optionally be executed if it's a function 828 access: function( elems, fn, key, value, chainable, emptyGet, pass ) { 829 var exec, 830 bulk = key == null, 831 i = 0, 832 length = elems.length; 833 834 // Sets many values 835 if ( key && typeof key === "object" ) { 836 for ( i in key ) { 837 jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); 838 } 839 chainable = 1; 840 841 // Sets one value 842 } else if ( value !== undefined ) { 843 // Optionally, function values get executed if exec is true 844 exec = pass === undefined && jQuery.isFunction( value ); 845 846 if ( bulk ) { 847 // Bulk operations only iterate when executing function values 848 if ( exec ) { 849 exec = fn; 850 fn = function( elem, key, value ) { 851 return exec.call( jQuery( elem ), value ); 852 }; 853 854 // Otherwise they run against the entire set 855 } else { 856 fn.call( elems, value ); 857 fn = null; 858 } 859 } 860 861 if ( fn ) { 862 for (; i < length; i++ ) { 863 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); 864 } 865 } 866 867 chainable = 1; 868 } 869 870 return chainable ? 871 elems : 872 873 // Gets 874 bulk ? 875 fn.call( elems ) : 876 length ? fn( elems[0], key ) : emptyGet; 877 }, 878 879 now: function() { 880 return ( new Date() ).getTime(); 881 }, 882 883 // Use of jQuery.browser is frowned upon. 884 // More details: http://docs.jquery.com/Utilities/jQuery.browser 885 uaMatch: function( ua ) { 886 ua = ua.toLowerCase(); 887 888 var match = rwebkit.exec( ua ) || 889 ropera.exec( ua ) || 890 rmsie.exec( ua ) || 891 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || 892 []; 893 894 return { browser: match[1] || "", version: match[2] || "0" }; 895 }, 896 897 sub: function() { 898 function jQuerySub( selector, context ) { 899 return new jQuerySub.fn.init( selector, context ); 900 } 901 jQuery.extend( true, jQuerySub, this ); 902 jQuerySub.superclass = this; 903 jQuerySub.fn = jQuerySub.prototype = this(); 904 jQuerySub.fn.constructor = jQuerySub; 905 jQuerySub.sub = this.sub; 906 jQuerySub.fn.init = function init( selector, context ) { 907 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { 908 context = jQuerySub( context ); 909 } 910 911 return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); 912 }; 913 jQuerySub.fn.init.prototype = jQuerySub.fn; 914 var rootjQuerySub = jQuerySub(document); 915 return jQuerySub; 916 }, 917 918 browser: {} 919}); 920 921// Populate the class2type map 922jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { 923 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 924}); 925 926browserMatch = jQuery.uaMatch( userAgent ); 927if ( browserMatch.browser ) { 928 jQuery.browser[ browserMatch.browser ] = true; 929 jQuery.browser.version = browserMatch.version; 930} 931 932// Deprecated, use jQuery.browser.webkit instead 933if ( jQuery.browser.webkit ) { 934 jQuery.browser.safari = true; 935} 936
937// IE doesn't match non-breaking spaces with \s 938if ( rnotwhite.test( "\xA0" ) ) { 939 trimLeft = /^[\s\xA0]+/; 940 trimRight = /[\s\xA0]+$/; 941} 942 943// All jQuery objects should point back to these 944rootjQuery = jQuery(document); 945 946// Cleanup functions for the document ready method 947if ( document.addEventListener ) { 948 DOMContentLoaded = function() { 949 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); 950 jQuery.ready(); 951 }; 952 953} else if ( document.attachEvent ) { 954 DOMContentLoaded = function() { 955 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). 956 if ( document.readyState === "complete" ) { 957 document.detachEvent( "onreadystatechange", DOMContentLoaded ); 958 jQuery.ready(); 959 } 960 }; 961} 962 963// The DOM ready check for Internet Explorer 964function doScrollCheck() { 965 if ( jQuery.isReady ) { 966 return; 967 } 968 969 try { 970 // If IE is used, use the trick by Diego Perini 971 // http://javascript.nwbox.com/IEContentLoaded/ 972 document.documentElement.doScroll("left"); 973 } catch(e) { 974 setTimeout( doScrollCheck, 1 ); 975 return; 976 } 977 978 // and execute any waiting functions 979 jQuery.ready(); 980} 981 982return jQuery; 983 984})(); 985 986 987// String to Object flags format cache 988var flagsCache = {}; 989 990// Convert String-formatted flags into Object-formatted ones and store in cache 991function createFlags( flags ) { 992 var object = flagsCache[ flags ] = {}, 993 i, length; 994 flags = flags.split( /\s+/ ); 995 for ( i = 0, length = flags.length; i < length; i++ ) { 996 object[ flags[i] ] = true; 997 } 998 return object; 999} 1000 1001/* 1002 * Create a callback list using the following parameters: 1003 * 1004 * flags: an optional list of space-separated flags that will change how 1005 * the callback list behaves 1006 * 1007 * By default a callback list will act like an event callback list and can be 1008 * "fired" multiple times. 1009 * 1010 * Possible flags: 1011 * 1012 * once: will ensure the callback list can only be fired once (like a Deferred) 1013 * 1014 * memory: will keep track of previous values and will call any callback added 1015 * after the list has been fired right away with the latest "memorized" 1016 * values (like a Deferred) 1017 * 1018 * unique: will ensure a callback can only be added once (no duplicate in the list) 1019 * 1020 * stopOnFalse: interrupt callings when a callback returns false 1021 * 1022 */ 1023jQuery.Callbacks = function( flags ) { 1024 1025 // Convert flags from String-formatted to Object-formatted 1026 // (we check in cache first) 1027 flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; 1028 1029 var // Actual callback list 1030 list = [], 1031 // Stack of fire calls for repeatable lists 1032 stack = [], 1033 // Last fire value (for non-forgettable lists) 1034 memory, 1035 // Flag to know if list was already fired 1036 fired, 1037 // Flag to know if list is currently firing 1038 firing, 1039 // First callback to fire (used internally by add and fireWith) 1040 firingStart, 1041 // End of the loop when firing 1042 firingLength, 1043 // Index of currently firing callback (modified by remove if needed) 1044 firingIndex, 1045 // Add one or several callbacks to the list 1046 add = function( args ) { 1047 var i, 1048 length, 1049 elem, 1050 type, 1051 actual; 1052 for ( i = 0, length = args.length; i < length; i++ ) { 1053 elem = args[ i ]; 1054 type = jQuery.type( elem ); 1055 if ( type === "array" ) { 1056 // Inspect recursively 1057 add( elem ); 1058 } else if ( type === "function" ) { 1059 // Add if not in unique mode and callback is not in 1060 if ( !flags.unique || !self.has( elem ) ) { 1061 list.push( elem ); 1062 } 1063 } 1064 } 1065 }, 1066 // Fire callbacks 1067 fire = function( context, args ) { 1068 args = args || []; 1069 memory = !flags.memory || [ context, args ]; 1070 fired = true; 1071 firing = true; 1072 firingIndex = firingStart || 0; 1073 firingStart = 0; 1074 firingLength = list.length; 1075 for ( ; list && firingIndex < firingLength; firingIndex++ ) { 1076 if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { 1077 memory = true; // Mark as halted 1078 break; 1079 } 1080 } 1081 firing = false; 1082 if ( list ) { 1083 if ( !flags.once ) { 1084 if ( stack && stack.length ) { 1085 memory = stack.shift(); 1086 self.fireWith( memory[ 0 ], memory[ 1 ] ); 1087 } 1088 } else if ( memory === true ) { 1089 self.disable(); 1090 } else { 1091 list = []; 1092 } 1093 } 1094 }, 1095 // Actual Callbacks object 1096 self = { 1097 // Add a callback or a collection of callbacks to the list 1098 add: function() { 1099 if ( list ) { 1100 var length = list.length; 1101 add( arguments ); 1102 // Do we need to add the callbacks to the 1103 // current firing batch? 1104 if ( firing ) { 1105 firingLength = list.length; 1106 // With memory, if we're not firing then 1107 // we should call right away, unless previous 1108 // firing was halted (stopOnFalse) 1109 } else if ( memory && memory !== true ) { 1110 firingStart = length; 1111 fire( memory[ 0 ], memory[ 1 ] ); 1112 } 1113 } 1114 return this; 1115 }, 1116 // Remove a callback from the list 1117 remove: function() { 1118 if ( list ) { 1119 var args = arguments, 1120 argIndex = 0, 1121 argLength = args.length; 1122 for ( ; argIndex < argLength ; argIndex++ ) { 1123 for ( var i = 0; i < list.length; i++ ) { 1124 if ( args[ argIndex ] === list[ i ] ) { 1125 // Handle firingIndex and firingLength 1126 if ( firing ) { 1127 if ( i <= firingLength ) { 1128 firingLength--; 1129 if ( i <= firingIndex ) { 1130 firingIndex--; 1131 } 1132 } 1133 } 1134 // Remove the element 1135 list.splice( i--, 1 ); 1136 // If we have some unicity property then 1137 // we only need to do this once 1138 if ( flags.unique ) { 1139 break; 1140 } 1141 } 1142 } 1143 } 1144 } 1145 return this; 1146 }, 1147 // Control if a given callback is in the list 1148 has: function( fn ) { 1149 if ( list ) { 1150 var i = 0, 1151 length = list.length; 1152 for ( ; i < length; i++ ) { 1153 if ( fn === list[ i ] ) { 1154 return true; 1155 } 1156 } 1157 } 1158 return false;
1159 }, 1160 // Remove all callbacks from the list 1161 empty: function() { 1162 list = []; 1163 return this; 1164 }, 1165 // Have the list do nothing anymore 1166 disable: function() { 1167 list = stack = memory = undefined; 1168 return this; 1169 }, 1170 // Is it disabled? 1171 disabled: function() { 1172 return !list; 1173 }, 1174 // Lock the list in its current state 1175 lock: function() { 1176 stack = undefined; 1177 if ( !memory || memory === true ) { 1178 self.disable(); 1179 } 1180 return this; 1181 }, 1182 // Is it locked? 1183 locked: function() { 1184 return !stack; 1185 }, 1186 // Call all callbacks with the given context and arguments 1187 fireWith: function( context, args ) { 1188 if ( stack ) { 1189 if ( firing ) { 1190 if ( !flags.once ) { 1191 stack.push( [ context, args ] ); 1192 } 1193 } else if ( !( flags.once && memory ) ) { 1194 fire( context, args ); 1195 } 1196 } 1197 return this; 1198 }, 1199 // Call all the callbacks with the given arguments 1200 fire: function() { 1201 self.fireWith( this, arguments ); 1202 return this; 1203 }, 1204 // To know if the callbacks have already been called at least once 1205 fired: function() { 1206 return !!fired; 1207 } 1208 }; 1209 1210 return self; 1211}; 1212 1213 1214 1215 1216var // Static reference to slice 1217 sliceDeferred = [].slice; 1218 1219jQuery.extend({ 1220 1221 Deferred: function( func ) { 1222 var doneList = jQuery.Callbacks( "once memory" ), 1223 failList = jQuery.Callbacks( "once memory" ), 1224 progressList = jQuery.Callbacks( "memory" ), 1225 state = "pending", 1226 lists = { 1227 resolve: doneList, 1228 reject: failList, 1229 notify: progressList 1230 }, 1231 promise = { 1232 done: doneList.add, 1233 fail: failList.add, 1234 progress: progressList.add, 1235 1236 state: function() { 1237 return state; 1238 }, 1239 1240 // Deprecated 1241 isResolved: doneList.fired, 1242 isRejected: failList.fired, 1243 1244 then: function( doneCallbacks, failCallbacks, progressCallbacks ) { 1245 deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); 1246 return this; 1247 }, 1248 always: function() { 1249 deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); 1250 return this; 1251 }, 1252 pipe: function( fnDone, fnFail, fnProgress ) { 1253 return jQuery.Deferred(function( newDefer ) { 1254 jQuery.each( { 1255 done: [ fnDone, "resolve" ], 1256 fail: [ fnFail, "reject" ], 1257 progress: [ fnProgress, "notify" ] 1258 }, function( handler, data ) { 1259 var fn = data[ 0 ], 1260 action = data[ 1 ], 1261 returned; 1262 if ( jQuery.isFunction( fn ) ) { 1263 deferred[ handler ](function() { 1264 returned = fn.apply( this, arguments ); 1265 if ( returned && jQuery.isFunction( returned.promise ) ) { 1266 returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); 1267 } else { 1268 newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); 1269 } 1270 }); 1271 } else { 1272 deferred[ handler ]( newDefer[ action ] ); 1273 } 1274 }); 1275 }).promise(); 1276 }, 1277 // Get a promise for this deferred 1278 // If obj is provided, the promise aspect is added to the object 1279 promise: function( obj ) { 1280 if ( obj == null ) { 1281 obj = promise; 1282 } else { 1283 for ( var key in promise ) { 1284 obj[ key ] = promise[ key ]; 1285 } 1286 } 1287 return obj; 1288 } 1289 }, 1290 deferred = promise.promise({}), 1291 key; 1292 1293 for ( key in lists ) { 1294 deferred[ key ] = lists[ key ].fire; 1295 deferred[ key + "With" ] = lists[ key ].fireWith; 1296 } 1297 1298 // Handle state 1299 deferred.done( function() { 1300 state = "resolved"; 1301 }, failList.disable, progressList.lock ).fail( function() { 1302 state = "rejected"; 1303 }, doneList.disable, progressList.lock ); 1304 1305 // Call given func if any 1306 if ( func ) { 1307 func.call( deferred, deferred ); 1308 } 1309 1310 // All done! 1311 return deferred; 1312 }, 1313 1314 // Deferred helper 1315 when: function( firstParam ) { 1316 var args = sliceDeferred.call( arguments, 0 ), 1317 i = 0, 1318 length = args.length, 1319 pValues = new Array( length ), 1320 count = length, 1321 pCount = length, 1322 deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? 1323 firstParam : 1324 jQuery.Deferred(), 1325 promise = deferred.promise(); 1326 function resolveFunc( i ) { 1327 return function( value ) { 1328 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1329 if ( !( --count ) ) { 1330 deferred.resolveWith( deferred, args ); 1331 } 1332 }; 1333 } 1334 function progressFunc( i ) { 1335 return function( value ) { 1336 pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; 1337 deferred.notifyWith( promise, pValues ); 1338 }; 1339 } 1340 if ( length > 1 ) { 1341 for ( ; i < length; i++ ) { 1342 if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { 1343 args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); 1344 } else { 1345 --count; 1346 } 1347 } 1348 if ( !count ) { 1349 deferred.resolveWith( deferred, args ); 1350 } 1351 } else if ( deferred !== firstParam ) { 1352 deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); 1353 } 1354 return promise; 1355 } 1356}); 1357 1358 1359 1360 1361jQuery.support = (function() { 1362 1363 var support, 1364 all, 1365 a, 1366 select, 1367 opt, 1368 input, 1369 fragment, 1370 tds, 1371 events, 1372 eventName, 1373 i, 1374 isSupported, 1375 div = document.createElement( "div" ), 1376 documentElement = document.documentElement; 1377 1378 // Preliminary tests 1379 div.setAttribute("className", "t"); 1380 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a>
1380<input type='checkbox'/>"; 1381 1382 all = div.getElementsByTagName( "*" ); 1383 a = div.getElementsByTagName( "a" )[ 0 ]; 1384 1385 // Can't get basic test support 1386 if ( !all || !all.length || !a ) { 1387 return {}; 1388 } 1389 1390 // First batch of supports tests 1391 select = document.createElement( "select" ); 1392 opt = select.appendChild( document.createElement("option") ); 1393 input = div.getElementsByTagName( "input" )[ 0 ]; 1394 1395 support = { 1396 // IE strips leading whitespace when .innerHTML is used 1397 leadingWhitespace: ( div.firstChild.nodeType === 3 ), 1398 1399 // Make sure that tbody elements aren't automatically inserted 1400 // IE will insert them into empty tables 1401 tbody: !div.getElementsByTagName("tbody").length, 1402 1403 // Make sure that link elements get serialized correctly by innerHTML 1404 // This requires a wrapper element in IE 1405 htmlSerialize: !!div.getElementsByTagName("link").length, 1406 1407 // Get the style information from getAttribute 1408 // (IE uses .cssText instead) 1409 style: /top/.test( a.getAttribute("style") ), 1410 1411 // Make sure that URLs aren't manipulated 1412 // (IE normalizes it by default) 1413 hrefNormalized: ( a.getAttribute("href") === "/a" ), 1414 1415 // Make sure that element opacity exists 1416 // (IE uses filter instead) 1417 // Use a regex to work around a WebKit issue. See #5145 1418 opacity: /^0.55/.test( a.style.opacity ), 1419 1420 // Verify style float existence 1421 // (IE uses styleFloat instead of cssFloat) 1422 cssFloat: !!a.style.cssFloat, 1423 1424 // Make sure that if no value is specified for a checkbox 1425 // that it defaults to "on". 1426 // (WebKit defaults to "" instead) 1427 checkOn: ( input.value === "on" ), 1428 1429 // Make sure that a selected-by-default option has a working selected property. 1430 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 1431 optSelected: opt.selected, 1432 1433 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) 1434 getSetAttribute: div.className !== "t", 1435 1436 // Tests for enctype support on a form(#6743) 1437 enctype: !!document.createElement("form").enctype, 1438 1439 // Makes sure cloning an html5 element does not cause problems 1440 // Where outerHTML is undefined, this still works 1441 html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", 1442 1443 // Will be defined later 1444 submitBubbles: true, 1445 changeBubbles: true, 1446 focusinBubbles: false, 1447 deleteExpando: true, 1448 noCloneEvent: true, 1449 inlineBlockNeedsLayout: false, 1450 shrinkWrapBlocks: false, 1451 reliableMarginRight: true, 1452 pixelMargin: true 1453 }; 1454 1455 // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead 1456 jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); 1457 1458 // Make sure checked status is properly cloned 1459 input.checked = true; 1460 support.noCloneChecked = input.cloneNode( true ).checked; 1461 1462 // Make sure that the options inside disabled selects aren't marked as disabled 1463 // (WebKit marks them as disabled) 1464 select.disabled = true; 1465 support.optDisabled = !opt.disabled; 1466 1467 // Test to see if it's possible to delete an expando from an element 1468 // Fails in Internet Explorer 1469 try { 1470 delete div.test; 1471 } catch( e ) { 1472 support.deleteExpando = false; 1473 } 1474 1475 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { 1476 div.attachEvent( "onclick", function() { 1477 // Cloning a node shouldn't copy over any 1478 // bound event handlers (IE does this) 1479 support.noCloneEvent = false; 1480 }); 1481 div.cloneNode( true ).fireEvent( "onclick" ); 1482 } 1483 1484 // Check if a radio maintains its value 1485 // after being appended to the DOM 1486 input = document.createElement("input"); 1487 input.value = "t"; 1488 input.setAttribute("type", "radio"); 1489 support.radioValue = input.value === "t"; 1490 1491 input.setAttribute("checked", "checked"); 1492 1493 // #11217 - WebKit loses check when the name is after the checked attribute 1494 input.setAttribute( "name", "t" ); 1495 1496 div.appendChild( input ); 1497 fragment = document.createDocumentFragment(); 1498 fragment.appendChild( div.lastChild ); 1499 1500 // WebKit doesn't clone checked state correctly in fragments 1501 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; 1502 1503 // Check if a disconnected checkbox will retain its checked 1504 // value of true after appended to the DOM (IE6/7)
1505 support.appendChecked = input.checked; 1506 1507 fragment.removeChild( input ); 1508 fragment.appendChild( div ); 1509 1510 // Technique from Juriy Zaytsev 1511 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ 1512 // We only care about the case where non-standard event systems 1513 // are used, namely in IE. Short-circuiting here helps us to 1514 // avoid an eval call (in setAttribute) which can cause CSP 1515 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP 1516 if ( div.attachEvent ) { 1517 for ( i in { 1518 submit: 1, 1519 change: 1, 1520 focusin: 1 1521 }) { 1522 eventName = "on" + i; 1523 isSupported = ( eventName in div ); 1524 if ( !isSupported ) { 1525 div.setAttribute( eventName, "return;" ); 1526 isSupported = ( typeof div[ eventName ] === "function" ); 1527 } 1528 support[ i + "Bubbles" ] = isSupported; 1529 } 1530 } 1531 1532 fragment.removeChild( div ); 1533 1534 // Null elements to avoid leaks in IE 1535 fragment = select = opt = div = input = null; 1536 1537 // Run tests that need a body at doc ready 1538 jQuery(function() { 1539 var container, outer, inner, table, td, offsetSupport, 1540 marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, 1541 paddingMarginBorderVisibility, paddingMarginBorder, 1542 body = document.getElementsByTagName("body")[0]; 1543 1544 if ( !body ) { 1545 // Return for frameset docs that don't have a body 1546 return; 1547 } 1548 1549 conMarginTop = 1; 1550 paddingMarginBorder = "padding:0;margin:0;border:"; 1551 positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; 1552 paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; 1553 style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; 1554 html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" + 1555 "<table " + style + "' cellpadding='0' cellspacing='0'>" + 1556 "<tr><td></td></tr></table>"; 1557 1558 container = document.createElement("div"); 1559 container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; 1560 body.insertBefore( container, body.firstChild ); 1561 1562 // Construct the test element 1563 div = document.createElement("div"); 1564 container.appendChild( div ); 1565 1566 // Check if table cells still have offsetWidth/Height when they are set 1567 // to display:none and there are still other visible table cells in a 1568 // table row; if so, offsetWidth/Height are not reliable for use when 1569 // determining if an element has been hidden directly using 1570 // display:none (it is still safe to use offsets if a parent element is 1571 // hidden; don safety goggles and see bug #4512 for more information). 1572 // (only IE 8 fails this test) 1573 div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>"; 1574 tds = div.getElementsByTagName( "td" ); 1575 isSupported = ( tds[ 0 ].offsetHeight === 0 ); 1576 1577 tds[ 0 ].style.display = ""; 1578 tds[ 1 ].style.display = "none"; 1579 1580 // Check if empty table cells still have offsetWidth/Height 1581 // (IE <= 8 fail this test) 1582 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); 1583 1584 // Check if div with explicit width and no margin-right incorrectly 1585 // gets computed margin-right based on width of container. For more 1586 // info see bug #3333 1587 // Fails in WebKit before Feb 2011 nightlies 1588 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 1589 if ( window.getComputedStyle ) { 1590 div.innerHTML = ""; 1591 marginDiv = document.createElement( "div" ); 1592 marginDiv.style.width = "0"; 1593 marginDiv.style.marginRight = "0"; 1594 div.style.width = "2px"; 1595 div.appendChild( marginDiv ); 1596 support.reliableMarginRight = 1597 ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; 1598 } 1599 1600 if ( typeof div.style.zoom !== "undefined" ) { 1601 // Check if natively block-level elements act like inline-block 1602 // elements when setting their display to 'inline' and giving 1603 // them layout 1604 // (IE < 8 does this) 1605 div.innerHTML = ""; 1606 div.style.width = div.style.padding = "1px"; 1607 div.style.border = 0; 1608 div.style.overflow = "hidden"; 1609 div.style.display = "inline"; 1610 div.style.zoom = 1; 1611 support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); 1612 1613 // Check if elements with layout shrink-wrap their children 1614 // (IE 6 does this) 1615 div.style.display = "block"; 1616 div.style.overflow = "visible"; 1617 div.innerHTML = "<div style='width:5px;'></div>"; 1618 support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); 1619 } 1620 1621 div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; 1622 div.innerHTML = html; 1623 1624 outer = div.firstChild; 1625 inner = outer.firstChild; 1626 td = outer.nextSibling.firstChild.firstChild; 1627 1628 offsetSupport = { 1629 doesNotAddBorder: ( inner.offsetTop !== 5 ), 1630 doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) 1631 }; 1632 1633 inner.style.position = "fixed"; 1634 inner.style.top = "20px"; 1635 1636 // safari subtracts parent border width here which is 5px 1637 offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); 1638 inner.style.position = inner.style.top = ""; 1639 1640 outer.style.overflow = "hidden"; 1641 outer.style.position = "relative"; 1642 1643 offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); 1644 offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); 1645 1646 if ( window.getComputedStyle ) { 1647 div.style.marginTop = "1%"; 1648 support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; 1649 } 1650 1651 if ( typeof container.style.zoom !== "undefined" ) { 1652 container.style.zoom = 1; 1653 } 1654 1655 body.removeChild( container ); 1656 marginDiv = div = container = null; 1657 1658 jQuery.extend( support, offsetSupport ); 1659 }); 1660 1661 return support; 1662})(); 1663 1664 1665 1666 1667var rbrace = /^(?:\{.*\}|\[.*\])$/, 1668 rmultiDash = /([A-Z])/g; 1669 1670jQuery.extend({ 1671 cache: {}, 1672 1673 // Please use with caution 1674 uuid: 0, 1675 1676 // Unique for each copy of jQuery on the page 1677 // Non-digits removed to match rinlinejQuery 1678 expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), 1679 1680 // The following elements throw uncatchable exceptions if you 1681 // attempt to add expando properties to them. 1682 noData: { 1683 "embed": true, 1684 // Ban all objects except for Flash (which handle expandos) 1685 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", 1686 "applet": true 1687 }, 1688 1689 hasData: function( elem ) { 1690 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; 1691 return !!elem && !isEmptyDataObject( elem ); 1692 }, 1693 1694 data: function( elem, name, data, pvt /* Internal Use Only */ ) { 1695 if ( !jQuery.acceptData( elem ) ) { 1696 return; 1697 } 1698 1699 var privateCache, thisCache, ret, 1700 internalKey = jQuery.expando, 1701 getByName = typeof name === "string", 1702 1703 // We have to handle DOM nodes and JS objects differently because IE6-7 1704 // can't GC object references properly across the DOM-JS boundary 1705 isNode = elem.nodeType, 1706 1707 // Only DOM nodes need the global jQuery cache; JS object data is 1708 // attached directly to the object so GC can occur automatically 1709 cache = isNode ? jQuery.cache : elem, 1710 1711 // Only defining an ID for JS objects if its cache already exists allows 1712 // the code to shortcut on the same path as a DOM node with no cache 1713 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, 1714 isEvents = name === "events"; 1715 1716 // Avoid doing any more work than we need to when trying to get data on an 1717 // object that has no data at all 1718 if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { 1719 return; 1720 } 1721 1722 if ( !id ) { 1723 // Only DOM nodes need a new unique ID for each element since their data 1724 // ends up in the global cache 1725 if ( isNode ) { 1726 elem[ internalKey ] = id = ++jQuery.uuid; 1727 } else { 1728 id = internalKey; 1729 } 1730 } 1731 1732 if ( !cache[ id ] ) { 1733 cache[ id ] = {}; 1734 1735 // Avoids exposing jQuery metadata on plain JS objects when the object 1736 // is serialized using JSON.stringify 1737 if ( !isNode ) { 1738 cache[ id ].toJSON = jQuery.noop; 1739 } 1740 } 1741
1742 // An object can be passed to jQuery.data instead of a key/value pair; this gets 1743 // shallow copied over onto the existing cache 1744 if ( typeof name === "object" || typeof name === "function" ) { 1745 if ( pvt ) { 1746 cache[ id ] = jQuery.extend( cache[ id ], name ); 1747 } else { 1748 cache[ id ].data = jQuery.extend( cache[ id ].data, name ); 1749 } 1750 } 1751 1752 privateCache = thisCache = cache[ id ]; 1753 1754 // jQuery data() is stored in a separate object inside the object's internal data 1755 // cache in order to avoid key collisions between internal data and user-defined 1756 // data. 1757 if ( !pvt ) { 1758 if ( !thisCache.data ) { 1759 thisCache.data = {}; 1760 } 1761 1762 thisCache = thisCache.data; 1763 } 1764 1765 if ( data !== undefined ) { 1766 thisCache[ jQuery.camelCase( name ) ] = data; 1767 } 1768 1769 // Users should not attempt to inspect the internal events object using jQuery.data, 1770 // it is undocumented and subject to change. But does anyone listen? No. 1771 if ( isEvents && !thisCache[ name ] ) { 1772 return privateCache.events; 1773 } 1774 1775 // Check for both converted-to-camel and non-converted data property names 1776 // If a data property was specified 1777 if ( getByName ) { 1778 1779 // First Try to find as-is property data 1780 ret = thisCache[ name ]; 1781 1782 // Test for null|undefined property data 1783 if ( ret == null ) { 1784 1785 // Try to find the camelCased property 1786 ret = thisCache[ jQuery.camelCase( name ) ]; 1787 } 1788 } else { 1789 ret = thisCache; 1790 } 1791 1792 return ret; 1793 }, 1794 1795 removeData: function( elem, name, pvt /* Internal Use Only */ ) { 1796 if ( !jQuery.acceptData( elem ) ) { 1797 return; 1798 } 1799 1800 var thisCache, i, l, 1801 1802 // Reference to internal data cache key 1803 internalKey = jQuery.expando, 1804 1805 isNode = elem.nodeType, 1806 1807 // See jQuery.data for more information 1808 cache = isNode ? jQuery.cache : elem, 1809 1810 // See jQuery.data for more information 1811 id = isNode ? elem[ internalKey ] : internalKey; 1812 1813 // If there is already no cache entry for this object, there is no 1814 // purpose in continuing 1815 if ( !cache[ id ] ) { 1816 return; 1817 } 1818 1819 if ( name ) { 1820 1821 thisCache = pvt ? cache[ id ] : cache[ id ].data; 1822 1823 if ( thisCache ) { 1824 1825 // Support array or space separated string names for data keys 1826 if ( !jQuery.isArray( name ) ) { 1827 1828 // try the string as a key before any manipulation 1829 if ( name in thisCache ) { 1830 name = [ name ]; 1831 } else { 1832 1833 // split the camel cased version by spaces unless a key with the spaces exists 1834 name = jQuery.camelCase( name ); 1835 if ( name in thisCache ) { 1836 name = [ name ]; 1837 } else { 1838 name = name.split( " " ); 1839 } 1840 } 1841 } 1842 1843 for ( i = 0, l = name.length; i < l; i++ ) { 1844 delete thisCache[ name[i] ]; 1845 } 1846 1847 // If there is no data left in the cache, we want to continue 1848 // and let the cache object itself get destroyed 1849 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { 1850 return; 1851 } 1852 } 1853 } 1854 1855 // See jQuery.data for more information 1856 if ( !pvt ) { 1857 delete cache[ id ].data; 1858 1859 // Don't destroy the parent cache unless the internal data object 1860 // had been the only thing left in it 1861 if ( !isEmptyDataObject(cache[ id ]) ) { 1862 return; 1863 } 1864 } 1865 1866 // Browsers that fail expando deletion also refuse to delete expandos on 1867 // the window, but it will allow it on all other JS objects; other browsers 1868 // don't care 1869 // Ensure that `cache` is not a window object #10080 1870 if ( jQuery.support.deleteExpando || !cache.setInterval ) { 1871 delete cache[ id ]; 1872 } else { 1873 cache[ id ] = null; 1874 } 1875 1876 // We destroyed the cache and need to eliminate the expando on the node to avoid 1877 // false lookups in the cache for entries that no longer exist 1878 if ( isNode ) { 1879 // IE does not allow us to delete expando properties from nodes, 1880 // nor does it have a removeAttribute function on Document nodes; 1881 // we must handle all of these cases 1882 if ( jQuery.support.deleteExpando ) { 1883 delete elem[ internalKey ]; 1884 } else if ( elem.removeAttribute ) { 1885 elem.removeAttribute( internalKey ); 1886 } else { 1887 elem[ internalKey ] = null; 1888 } 1889 } 1890 }, 1891 1892 // For internal use only. 1893 _data: function( elem, name, data ) { 1894 return jQuery.data( elem, name, data, true ); 1895 }, 1896 1897 // A method for determining if a DOM node can handle the data expando 1898 acceptData: function( elem ) { 1899 if ( elem.nodeName ) { 1900 var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; 1901 1902 if ( match ) { 1903 return !(match === true || elem.getAttribute("classid") !== match); 1904 } 1905 } 1906 1907 return true; 1908 } 1909}); 1910 1911jQuery.fn.extend({ 1912 data: function( key, value ) { 1913 var parts, part, attr, name, l, 1914 elem = this[0], 1915 i = 0, 1916 data = null; 1917 1918 // Gets all values 1919 if ( key === undefined ) { 1920 if ( this.length ) { 1921 data = jQuery.data( elem ); 1922 1923 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { 1924 attr = elem.attributes; 1925 for ( l = attr.length; i < l; i++ ) { 1926 name = attr[i].name; 1927
1928 if ( name.indexOf( "data-" ) === 0 ) { 1929 name = jQuery.camelCase( name.substring(5) ); 1930 1931 dataAttr( elem, name, data[ name ] ); 1932 } 1933 } 1934 jQuery._data( elem, "parsedAttrs", true ); 1935 } 1936 } 1937 1938 return data; 1939 } 1940 1941 // Sets multiple values 1942 if ( typeof key === "object" ) { 1943 return this.each(function() { 1944 jQuery.data( this, key ); 1945 }); 1946 } 1947 1948 parts = key.split( ".", 2 ); 1949 parts[1] = parts[1] ? "." + parts[1] : ""; 1950 part = parts[1] + "!"; 1951 1952 return jQuery.access( this, function( value ) { 1953 1954 if ( value === undefined ) { 1955 data = this.triggerHandler( "getData" + part, [ parts[0] ] ); 1956 1957 // Try to fetch any internally stored data first 1958 if ( data === undefined && elem ) { 1959 data = jQuery.data( elem, key ); 1960 data = dataAttr( elem, key, data ); 1961 } 1962 1963 return data === undefined && parts[1] ? 1964 this.data( parts[0] ) : 1965 data; 1966 } 1967 1968 parts[1] = value; 1969 this.each(function() { 1970 var self = jQuery( this ); 1971 1972 self.triggerHandler( "setData" + part, parts ); 1973 jQuery.data( this, key, value ); 1974 self.triggerHandler( "changeData" + part, parts ); 1975 }); 1976 }, null, value, arguments.length > 1, null, false ); 1977 }, 1978 1979 removeData: function( key ) { 1980 return this.each(function() { 1981 jQuery.removeData( this, key ); 1982 }); 1983 } 1984}); 1985 1986function dataAttr( elem, key, data ) { 1987 // If nothing was found internally, try to fetch any 1988 // data from the HTML5 data-* attribute 1989 if ( data === undefined && elem.nodeType === 1 ) { 1990 1991 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); 1992 1993 data = elem.getAttribute( name ); 1994 1995 if ( typeof data === "string" ) { 1996 try { 1997 data = data === "true" ? true : 1998 data === "false" ? false : 1999 data === "null" ? null : 2000 jQuery.isNumeric( data ) ? +data : 2001 rbrace.test( data ) ? jQuery.parseJSON( data ) : 2002 data; 2003 } catch( e ) {} 2004 2005 // Make sure we set the data so it isn't changed later 2006 jQuery.data( elem, key, data ); 2007 2008 } else { 2009 data = undefined; 2010 } 2011 } 2012 2013 return data; 2014} 2015 2016// checks a cache object for emptiness 2017function isEmptyDataObject( obj ) { 2018 for ( var name in obj ) { 2019 2020 // if the public data object is empty, the private is still empty 2021 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { 2022 continue; 2023 } 2024 if ( name !== "toJSON" ) { 2025 return false; 2026 } 2027 } 2028 2029 return true; 2030} 2031 2032 2033 2034 2035function handleQueueMarkDefer( elem, type, src ) { 2036 var deferDataKey = type + "defer", 2037 queueDataKey = type + "queue", 2038 markDataKey = type + "mark", 2039 defer = jQuery._data( elem, deferDataKey ); 2040 if ( defer && 2041 ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && 2042 ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { 2043 // Give room for hard-coded callbacks to fire first 2044 // and eventually mark/queue something else on the element 2045 setTimeout( function() { 2046 if ( !jQuery._data( elem, queueDataKey ) && 2047 !jQuery._data( elem, markDataKey ) ) { 2048 jQuery.removeData( elem, deferDataKey, true ); 2049 defer.fire(); 2050 } 2051 }, 0 ); 2052 } 2053} 2054 2055jQuery.extend({ 2056 2057 _mark: function( elem, type ) { 2058 if ( elem ) { 2059 type = ( type || "fx" ) + "mark"; 2060 jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); 2061 } 2062 }, 2063 2064 _unmark: function( force, elem, type ) { 2065 if ( force !== true ) { 2066 type = elem; 2067 elem = force; 2068 force = false; 2069 } 2070 if ( elem ) { 2071 type = type || "fx"; 2072 var key = type + "mark", 2073 count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); 2074 if ( count ) { 2075 jQuery._data( elem, key, count ); 2076 } else { 2077 jQuery.removeData( elem, key, true ); 2078 handleQueueMarkDefer( elem, type, "mark" ); 2079 } 2080 } 2081 }, 2082 2083 queue: function( elem, type, data ) { 2084 var q; 2085 if ( elem ) { 2086 type = ( type || "fx" ) + "queue"; 2087 q = jQuery._data( elem, type ); 2088 2089 // Speed up dequeue by getting out quickly if this is just a lookup 2090 if ( data ) { 2091 if ( !q || jQuery.isArray(data) ) { 2092 q = jQuery._data( elem, type, jQuery.makeArray(data) ); 2093 } else { 2094 q.push( data ); 2095 } 2096 } 2097 return q || []; 2098 } 2099 }, 2100 2101 dequeue: function( elem, type ) { 2102 type = type || "fx"; 2103 2104 var queue = jQuery.queue( elem, type ), 2105 fn = queue.shift(), 2106 hooks = {}; 2107 2108 // If the fx queue is dequeued, always remove the progress sentinel 2109 if ( fn === "inprogress" ) { 2110 fn = queue.shift(); 2111 } 2112 2113 if ( fn ) { 2114 // Add a progress sentinel to prevent the fx queue from being 2115 // automatically dequeued 2116 if ( type === "fx" ) { 2117 queue.unshift( "inprogress" ); 2118 } 2119 2120 jQuery._data( elem, type + ".run", hooks ); 2121 fn.call( elem, function() { 2122 jQuery.dequeue( elem, type ); 2123 }, hooks ); 2124 } 2125 2126 if ( !queue.length ) { 2127 jQuery.removeData( elem, type + "queue " + type + ".run", true ); 2128 handleQueueMarkDefer( elem, type, "queue" ); 2129 } 2130 } 2131}); 2132 2133jQuery.fn.extend({ 2134 queue: function( type, data ) { 2135 var setter = 2; 2136 2137 if ( typeof type !== "string" ) { 2138 data = type; 2139 type = "fx"; 2140 setter--; 2141 } 2142 2143 if ( arguments.length < setter ) { 2144 return jQuery.queue( this[0], type ); 2145 } 2146 2147 return data === undefined ?
2148 this : 2149 this.each(function() { 2150 var queue = jQuery.queue( this, type, data ); 2151 2152 if ( type === "fx" && queue[0] !== "inprogress" ) { 2153 jQuery.dequeue( this, type ); 2154 } 2155 }); 2156 }, 2157 dequeue: function( type ) { 2158 return this.each(function() { 2159 jQuery.dequeue( this, type ); 2160 }); 2161 }, 2162 // Based off of the plugin by Clint Helfers, with permission. 2163 // http://blindsignals.com/index.php/2009/07/jquery-delay/ 2164 delay: function( time, type ) { 2165 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 2166 type = type || "fx"; 2167 2168 return this.queue( type, function( next, hooks ) { 2169 var timeout = setTimeout( next, time ); 2170 hooks.stop = function() { 2171 clearTimeout( timeout ); 2172 }; 2173 }); 2174 }, 2175 clearQueue: function( type ) { 2176 return this.queue( type || "fx", [] ); 2177 }, 2178 // Get a promise resolved when queues of a certain type 2179 // are emptied (fx is the type by default) 2180 promise: function( type, object ) { 2181 if ( typeof type !== "string" ) { 2182 object = type; 2183 type = undefined; 2184 } 2185 type = type || "fx"; 2186 var defer = jQuery.Deferred(), 2187 elements = this, 2188 i = elements.length, 2189 count = 1, 2190 deferDataKey = type + "defer", 2191 queueDataKey = type + "queue", 2192 markDataKey = type + "mark", 2193 tmp; 2194 function resolve() { 2195 if ( !( --count ) ) { 2196 defer.resolveWith( elements, [ elements ] ); 2197 } 2198 } 2199 while( i-- ) { 2200 if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || 2201 ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || 2202 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && 2203 jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { 2204 count++; 2205 tmp.add( resolve ); 2206 } 2207 } 2208 resolve(); 2209 return defer.promise( object ); 2210 } 2211}); 2212 2213 2214 2215 2216var rclass = /[\n\t\r]/g, 2217 rspace = /\s+/, 2218 rreturn = /\r/g, 2219 rtype = /^(?:button|input)$/i, 2220 rfocusable = /^(?:button|input|object|select|textarea)$/i, 2221 rclickable = /^a(?:rea)?$/i, 2222 rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, 2223 getSetAttribute = jQuery.support.getSetAttribute, 2224 nodeHook, boolHook, fixSpecified; 2225 2226jQuery.fn.extend({ 2227 attr: function( name, value ) { 2228 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); 2229 }, 2230 2231 removeAttr: function( name ) { 2232 return this.each(function() { 2233 jQuery.removeAttr( this, name ); 2234 }); 2235 }, 2236 2237 prop: function( name, value ) { 2238 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); 2239 }, 2240 2241 removeProp: function( name ) { 2242 name = jQuery.propFix[ name ] || name; 2243 return this.each(function() { 2244 // try/catch handles cases where IE balks (such as removing a property on window) 2245 try { 2246 this[ name ] = undefined; 2247 delete this[ name ]; 2248 } catch( e ) {} 2249 }); 2250 }, 2251 2252 addClass: function( value ) { 2253 var classNames, i, l, elem, 2254 setClass, c, cl; 2255 2256 if ( jQuery.isFunction( value ) ) { 2257 return this.each(function( j ) { 2258 jQuery( this ).addClass( value.call(this, j, this.className) ); 2259 }); 2260 } 2261 2262 if ( value && typeof value === "string" ) { 2263 classNames = value.split( rspace ); 2264 2265 for ( i = 0, l = this.length; i < l; i++ ) { 2266 elem = this[ i ]; 2267 2268 if ( elem.nodeType === 1 ) { 2269 if ( !elem.className && classNames.length === 1 ) { 2270 elem.className = value; 2271 2272 } else { 2273 setClass = " " + elem.className + " "; 2274 2275 for ( c = 0, cl = classNames.length; c < cl; c++ ) { 2276 if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { 2277 setClass += classNames[ c ] + " "; 2278 } 2279 } 2280 elem.className = jQuery.trim( setClass ); 2281 } 2282 } 2283 } 2284 } 2285 2286 return this; 2287 }, 2288 2289 removeClass: function( value ) { 2290 var classNames, i, l, elem, className, c, cl; 2291 2292 if ( jQuery.isFunction( value ) ) { 2293 return this.each(function( j ) { 2294 jQuery( this ).removeClass( value.call(this, j, this.className) ); 2295 }); 2296 } 2297 2298 if ( (value && typeof value === "string") || value === undefined ) { 2299 classNames = ( value || "" ).split( rspace ); 2300 2301 for ( i = 0, l = this.length; i < l; i++ ) { 2302 elem = this[ i ]; 2303 2304 if ( elem.nodeType === 1 && elem.className ) { 2305 if ( value ) { 2306 className = (" " + elem.className + " ").replace( rclass, " " ); 2307 for ( c = 0, cl = classNames.length; c < cl; c++ ) { 2308 className = className.replace(" " + classNames[ c ] + " ", " "); 2309 } 2310 elem.className = jQuery.trim( className ); 2311 2312 } else { 2313 elem.className = ""; 2314 } 2315 } 2316 } 2317 } 2318 2319 return this; 2320 }, 2321 2322 toggleClass: function( value, stateVal ) { 2323 var type = typeof value, 2324 isBool = typeof stateVal === "boolean"; 2325 2326 if ( jQuery.isFunction( value ) ) { 2327 return this.each(function( i ) { 2328 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); 2329 }); 2330 } 2331 2332 return this.each(function() { 2333 if ( type === "string" ) { 2334 // toggle individual class names 2335 var className, 2336 i = 0, 2337 self = jQuery( this ), 2338 state = stateVal, 2339 classNames = value.split( rspace ); 2340 2341 while ( (className = classNames[ i++ ]) ) { 2342 // check each className given, space seperated list 2343 state = isBool ? state : !self.hasClass( className ); 2344 self[ state ? "addClass" : "removeClass" ]( className ); 2345 } 2346 2347 } else if ( type === "undefined" || type === "boolean" ) { 2348 if ( this.className ) { 2349 // store className if set 2350 jQuery._data( this, "__className__", this.className ); 2351 } 2352 2353 // toggle whole className 2354 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; 2355 } 2356 }); 2357 }, 2358 2359 hasClass: function( selector ) { 2360 var className = " " + selector + " ", 2361 i = 0, 2362 l = this.length; 2363 for ( ; i < l; i++ ) { 2364 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { 2365 return true; 2366 } 2367 } 2368 2369 return false;
2370 }, 2371 2372 val: function( value ) { 2373 var hooks, ret, isFunction, 2374 elem = this[0]; 2375 2376 if ( !arguments.length ) { 2377 if ( elem ) { 2378 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 2379 2380 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 2381 return ret; 2382 } 2383 2384 ret = elem.value; 2385 2386 return typeof ret === "string" ? 2387 // handle most common string cases 2388 ret.replace(rreturn, "") : 2389 // handle cases where value is null/undef or number 2390 ret == null ? "" : ret; 2391 } 2392 2393 return; 2394 } 2395 2396 isFunction = jQuery.isFunction( value ); 2397 2398 return this.each(function( i ) { 2399 var self = jQuery(this), val; 2400 2401 if ( this.nodeType !== 1 ) { 2402 return; 2403 } 2404 2405 if ( isFunction ) { 2406 val = value.call( this, i, self.val() ); 2407 } else { 2408 val = value; 2409 } 2410 2411 // Treat null/undefined as ""; convert numbers to string 2412 if ( val == null ) { 2413 val = ""; 2414 } else if ( typeof val === "number" ) { 2415 val += ""; 2416 } else if ( jQuery.isArray( val ) ) { 2417 val = jQuery.map(val, function ( value ) { 2418 return value == null ? "" : value + ""; 2419 }); 2420 } 2421 2422 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 2423 2424 // If set returns undefined, fall back to normal setting 2425 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 2426 this.value = val; 2427 } 2428 }); 2429 } 2430}); 2431 2432jQuery.extend({ 2433 valHooks: { 2434 option: { 2435 get: function( elem ) { 2436 // attributes.value is undefined in Blackberry 4.7 but 2437 // uses .value. See #6932 2438 var val = elem.attributes.value; 2439 return !val || val.specified ? elem.value : elem.text; 2440 } 2441 }, 2442 select: { 2443 get: function( elem ) { 2444 var value, i, max, option, 2445 index = elem.selectedIndex, 2446 values = [], 2447 options = elem.options, 2448 one = elem.type === "select-one"; 2449 2450 // Nothing was selected 2451 if ( index < 0 ) { 2452 return null; 2453 } 2454 2455 // Loop through all the selected options 2456 i = one ? index : 0; 2457 max = one ? index + 1 : options.length; 2458 for ( ; i < max; i++ ) { 2459 option = options[ i ]; 2460 2461 // Don't return options that are disabled or in a disabled optgroup 2462 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && 2463 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { 2464 2465 // Get the specific value for the option 2466 value = jQuery( option ).val(); 2467 2468 // We don't need an array for one selects 2469 if ( one ) { 2470 return value; 2471 } 2472 2473 // Multi-Selects return an array 2474 values.push( value ); 2475 } 2476 } 2477 2478 // Fixes Bug #2551 -- select.val() broken in IE after form.reset() 2479 if ( one && !values.length && options.length ) { 2480 return jQuery( options[ index ] ).val(); 2481 } 2482 2483 return values; 2484 }, 2485 2486 set: function( elem, value ) { 2487 var values = jQuery.makeArray( value ); 2488 2489 jQuery(elem).find("option").each(function() { 2490 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; 2491 }); 2492 2493 if ( !values.length ) { 2494 elem.selectedIndex = -1; 2495 } 2496 return values; 2497 } 2498 } 2499 }, 2500 2501 attrFn: { 2502 val: true, 2503 css: true, 2504 html: true, 2505 text: true, 2506 data: true, 2507 width: true, 2508 height: true, 2509 offset: true 2510 }, 2511 2512 attr: function( elem, name, value, pass ) { 2513 var ret, hooks, notxml, 2514 nType = elem.nodeType; 2515 2516 // don't get/set attributes on text, comment and attribute nodes 2517 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2518 return; 2519 } 2520 2521 if ( pass && name in jQuery.attrFn ) { 2522 return jQuery( elem )[ name ]( value ); 2523 } 2524 2525 // Fallback to prop when attributes are not supported 2526 if ( typeof elem.getAttribute === "undefined" ) { 2527 return jQuery.prop( elem, name, value ); 2528 } 2529 2530 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2531 2532 // All attributes are lowercase 2533 // Grab necessary hook if one is defined 2534 if ( notxml ) { 2535 name = name.toLowerCase(); 2536 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); 2537 } 2538 2539 if ( value !== undefined ) { 2540 2541 if ( value === null ) { 2542 jQuery.removeAttr( elem, name ); 2543 return; 2544 2545 } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { 2546 return ret; 2547 2548 } else { 2549 elem.setAttribute( name, "" + value ); 2550 return value; 2551 } 2552 2553 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { 2554 return ret; 2555 2556 } else { 2557 2558 ret = elem.getAttribute( name ); 2559 2560 // Non-existent attributes return null, we normalize to undefined 2561 return ret === null ? 2562 undefined : 2563 ret; 2564 } 2565 }, 2566 2567 removeAttr: function( elem, value ) { 2568 var propName, attrNames, name, l, isBool, 2569 i = 0; 2570 2571 if ( value && elem.nodeType === 1 ) { 2572 attrNames = value.toLowerCase().split( rspace ); 2573 l = attrNames.length; 2574 2575 for ( ; i < l; i++ ) { 2576 name = attrNames[ i ]; 2577
vendor: 5,739 bytes, lines 2578-2775
2578 if ( name ) { 2579 propName = jQuery.propFix[ name ] || name; 2580 isBool = rboolean.test( name ); 2581 2582 // See #9699 for explanation of this approach (setting first, then removal) 2583 // Do not do this for boolean attributes (see #10870) 2584 if ( !isBool ) { 2585 jQuery.attr( elem, name, "" ); 2586 } 2587 elem.removeAttribute( getSetAttribute ? name : propName ); 2588 2589 // Set corresponding property to false for boolean attributes 2590 if ( isBool && propName in elem ) { 2591 elem[ propName ] = false; 2592 } 2593 } 2594 } 2595 } 2596 }, 2597 2598 attrHooks: { 2599 type: { 2600 set: function( elem, value ) { 2601 // We can't allow the type property to be changed (since it causes problems in IE) 2602 if ( rtype.test( elem.nodeName ) && elem.parentNode ) { 2603 jQuery.error( "type property can't be changed" ); 2604 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { 2605 // Setting the type on a radio button after the value resets the value in IE6-9 2606 // Reset value to it's default in case type is set after value 2607 // This is for element creation 2608 var val = elem.value; 2609 elem.setAttribute( "type", value ); 2610 if ( val ) { 2611 elem.value = val; 2612 } 2613 return value; 2614 } 2615 } 2616 }, 2617 // Use the value property for back compat 2618 // Use the nodeHook for button elements in IE6/7 (#1954) 2619 value: { 2620 get: function( elem, name ) { 2621 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2622 return nodeHook.get( elem, name ); 2623 } 2624 return name in elem ? 2625 elem.value : 2626 null; 2627 }, 2628 set: function( elem, value, name ) { 2629 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { 2630 return nodeHook.set( elem, value, name ); 2631 } 2632 // Does not return so that setAttribute is also used 2633 elem.value = value; 2634 } 2635 } 2636 }, 2637 2638 propFix: { 2639 tabindex: "tabIndex", 2640 readonly: "readOnly", 2641 "for": "htmlFor", 2642 "class": "className", 2643 maxlength: "maxLength", 2644 cellspacing: "cellSpacing", 2645 cellpadding: "cellPadding", 2646 rowspan: "rowSpan", 2647 colspan: "colSpan", 2648 usemap: "useMap", 2649 frameborder: "frameBorder", 2650 contenteditable: "contentEditable" 2651 }, 2652 2653 prop: function( elem, name, value ) { 2654 var ret, hooks, notxml, 2655 nType = elem.nodeType; 2656 2657 // don't get/set properties on text, comment and attribute nodes 2658 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 2659 return; 2660 } 2661 2662 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 2663 2664 if ( notxml ) { 2665 // Fix name and attach hooks 2666 name = jQuery.propFix[ name ] || name; 2667 hooks = jQuery.propHooks[ name ]; 2668 } 2669 2670 if ( value !== undefined ) { 2671 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 2672 return ret; 2673 2674 } else { 2675 return ( elem[ name ] = value ); 2676 } 2677 2678 } else { 2679 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { 2680 return ret; 2681 2682 } else { 2683 return elem[ name ]; 2684 } 2685 } 2686 }, 2687 2688 propHooks: { 2689 tabIndex: { 2690 get: function( elem ) { 2691 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set 2692 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 2693 var attributeNode = elem.getAttributeNode("tabindex"); 2694 2695 return attributeNode && attributeNode.specified ? 2696 parseInt( attributeNode.value, 10 ) : 2697 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 2698 0 : 2699 undefined; 2700 } 2701 } 2702 } 2703}); 2704 2705// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) 2706jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; 2707 2708// Hook for boolean attributes 2709boolHook = { 2710 get: function( elem, name ) { 2711 // Align boolean attributes with corresponding properties 2712 // Fall back to attribute presence where some booleans are not supported 2713 var attrNode, 2714 property = jQuery.prop( elem, name ); 2715 return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? 2716 name.toLowerCase() : 2717 undefined; 2718 }, 2719 set: function( elem, value, name ) { 2720 var propName; 2721 if ( value === false ) { 2722 // Remove boolean attributes when set to false 2723 jQuery.removeAttr( elem, name ); 2724 } else { 2725 // value is true since we know at this point it's type boolean and not false 2726 // Set boolean attributes to the same name and set the DOM property 2727 propName = jQuery.propFix[ name ] || name; 2728 if ( propName in elem ) { 2729 // Only set the IDL specifically if it already exists on the element 2730 elem[ propName ] = true; 2731 } 2732 2733 elem.setAttribute( name, name.toLowerCase() ); 2734 } 2735 return name; 2736 } 2737}; 2738 2739// IE6/7 do not support getting/setting some attributes with get/setAttribute 2740if ( !getSetAttribute ) { 2741 2742 fixSpecified = { 2743 name: true, 2744 id: true, 2745 coords: true 2746 }; 2747 2748 // Use this for any attribute in IE6/7 2749 // This fixes almost every IE6/7 issue 2750 nodeHook = jQuery.valHooks.button = { 2751 get: function( elem, name ) { 2752 var ret; 2753 ret = elem.getAttributeNode( name ); 2754 return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? 2755 ret.nodeValue : 2756 undefined; 2757 }, 2758 set: function( elem, value, name ) { 2759 // Set the existing or create a new attribute node 2760 var ret = elem.getAttributeNode( name ); 2761 if ( !ret ) { 2762 ret = document.createAttribute( name ); 2763 elem.setAttributeNode( ret ); 2764 } 2765 return ( ret.nodeValue = value + "" ); 2766 } 2767 }; 2768 2769 // Apply the nodeHook to tabindex 2770 jQuery.attrHooks.tabindex.set = nodeHook.set; 2771 2772 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 2773 // This is for removals 2774 jQuery.each([ "width", "height" ], function( i, name ) { 2775 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2776 set: function( elem, value ) { 2777 if ( value === "" ) { 2778 elem.setAttribute( name, "auto" ); 2779 return value; 2780 } 2781 } 2782 }); 2783 }); 2784 2785 // Set contenteditable to false on removals(#10429) 2786 // Setting to empty string throws an error as an invalid value 2787 jQuery.attrHooks.contenteditable = { 2788 get: nodeHook.get, 2789 set: function( elem, value, name ) { 2790 if ( value === "" ) { 2791 value = "false"; 2792 } 2793 nodeHook.set( elem, value, name ); 2794 } 2795 }; 2796} 2797 2798 2799// Some attributes require a special call on IE 2800if ( !jQuery.support.hrefNormalized ) { 2801 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { 2802 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { 2803 get: function( elem ) { 2804 var ret = elem.getAttribute( name, 2 ); 2805 return ret === null ? undefined : ret; 2806 } 2807 }); 2808 }); 2809} 2810 2811if ( !jQuery.support.style ) { 2812 jQuery.attrHooks.style = { 2813 get: function( elem ) { 2814 // Return undefined in the case of empty string 2815 // Normalize to lowercase since IE uppercases css property names 2816 return elem.style.cssText.toLowerCase() || undefined; 2817 }, 2818 set: function( elem, value ) { 2819 return ( elem.style.cssText = "" + value ); 2820 } 2821 }; 2822} 2823 2824// Safari mis-reports the default selected property of an option 2825// Accessing the parent's selectedIndex property fixes it 2826if ( !jQuery.support.optSelected ) { 2827 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { 2828 get: function( elem ) { 2829 var parent = elem.parentNode; 2830 2831 if ( parent ) { 2832 parent.selectedIndex; 2833 2834 // Make sure that it also works with optgroups, see #5701 2835 if ( parent.parentNode ) { 2836 parent.parentNode.selectedIndex; 2837 } 2838 } 2839 return null; 2840 } 2841 }); 2842} 2843 2844// IE6/7 call enctype encoding 2845if ( !jQuery.support.enctype ) { 2846 jQuery.propFix.enctype = "encoding"; 2847} 2848 2849// Radios and checkboxes getter/setter 2850if ( !jQuery.support.checkOn ) { 2851 jQuery.each([ "radio", "checkbox" ], function() { 2852 jQuery.valHooks[ this ] = { 2853 get: function( elem ) { 2854 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified 2855 return elem.getAttribute("value") === null ? "on" : elem.value; 2856 } 2857 }; 2858 }); 2859} 2860jQuery.each([ "radio", "checkbox" ], function() { 2861 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { 2862 set: function( elem, value ) { 2863 if ( jQuery.isArray( value ) ) { 2864 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); 2865 } 2866 } 2867 }); 2868}); 2869 2870 2871 2872 2873var rformElems = /^(?:textarea|input|select)$/i, 2874 rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, 2875 rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, 2876 rkeyEvent = /^key/, 2877 rmouseEvent = /^(?:mouse|contextmenu)|click/, 2878 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 2879 rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, 2880 quickParse = function( selector ) { 2881 var quick = rquickIs.exec( selector ); 2882 if ( quick ) { 2883 // 0 1 2 3 2884 // [ _, tag, id, class ] 2885 quick[1] = ( quick[1] || "" ).toLowerCase(); 2886 quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); 2887 } 2888 return quick; 2889 }, 2890 quickIs = function( elem, m ) { 2891 var attrs = elem.attributes || {}; 2892 return ( 2893 (!m[1] || elem.nodeName.toLowerCase() === m[1]) && 2894 (!m[2] || (attrs.id || {}).value === m[2]) && 2895 (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) 2896 ); 2897 }, 2898 hoverHack = function( events ) { 2899 return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); 2900 }; 2901 2902/* 2903 * Helper functions for managing events -- not part of the public interface. 2904 * Props to Dean Edwards' addEvent library for many of the ideas. 2905 */ 2906jQuery.event = { 2907 2908 add: function( elem, types, handler, data, selector ) { 2909 2910 var elemData, eventHandle, events, 2911 t, tns, type, namespaces, handleObj, 2912 handleObjIn, quick, handlers, special; 2913 2914 // Don't attach events to noData or text/comment nodes (allow plain objects tho) 2915 if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { 2916 return; 2917 } 2918 2919 // Caller can pass in an object of custom data in lieu of the handler 2920 if ( handler.handler ) { 2921 handleObjIn = handler; 2922 handler = handleObjIn.handler; 2923 selector = handleObjIn.selector; 2924 } 2925 2926 // Make sure that the handler has a unique ID, used to find/remove it later 2927 if ( !handler.guid ) { 2928 handler.guid = jQuery.guid++; 2929 } 2930 2931 // Init the element's event structure and main handler, if this is the first 2932 events = elemData.events; 2933 if ( !events ) { 2934 elemData.events = events = {}; 2935 } 2936 eventHandle = elemData.handle; 2937 if ( !eventHandle ) { 2938 elemData.handle = eventHandle = function( e ) { 2939 // Discard the second event of a jQuery.event.trigger() and 2940 // when an event is called after a page has unloaded 2941 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? 2942 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : 2943 undefined; 2944 }; 2945 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events 2946 eventHandle.elem = elem; 2947 } 2948 2949 // Handle multiple events separated by a space 2950 // jQuery(...).bind("mouseover mouseout", fn); 2951 types = jQuery.trim( hoverHack(types) ).split( " " ); 2952 for ( t = 0; t < types.length; t++ ) { 2953 2954 tns = rtypenamespace.exec( types[t] ) || []; 2955 type = tns[1];
vendor: 29,262 bytes, lines 2956-3929
2956 namespaces = ( tns[2] || "" ).split( "." ).sort(); 2957 2958 // If event changes its type, use the special event handlers for the changed type 2959 special = jQuery.event.special[ type ] || {}; 2960 2961 // If selector defined, determine special event api type, otherwise given type 2962 type = ( selector ? special.delegateType : special.bindType ) || type; 2963 2964 // Update special based on newly reset type 2965 special = jQuery.event.special[ type ] || {}; 2966 2967 // handleObj is passed to all event handlers 2968 handleObj = jQuery.extend({ 2969 type: type, 2970 origType: tns[1], 2971 data: data, 2972 handler: handler, 2973 guid: handler.guid, 2974 selector: selector, 2975 quick: selector && quickParse( selector ), 2976 namespace: namespaces.join(".") 2977 }, handleObjIn ); 2978 2979 // Init the event handler queue if we're the first 2980 handlers = events[ type ]; 2981 if ( !handlers ) { 2982 handlers = events[ type ] = []; 2983 handlers.delegateCount = 0; 2984 2985 // Only use addEventListener/attachEvent if the special events handler returns false 2986 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 2987 // Bind the global event handler to the element 2988 if ( elem.addEventListener ) { 2989 elem.addEventListener( type, eventHandle, false ); 2990 2991 } else if ( elem.attachEvent ) { 2992 elem.attachEvent( "on" + type, eventHandle ); 2993 } 2994 } 2995 } 2996 2997 if ( special.add ) { 2998 special.add.call( elem, handleObj ); 2999 3000 if ( !handleObj.handler.guid ) { 3001 handleObj.handler.guid = handler.guid; 3002 } 3003 } 3004 3005 // Add to the element's handler list, delegates in front 3006 if ( selector ) { 3007 handlers.splice( handlers.delegateCount++, 0, handleObj ); 3008 } else { 3009 handlers.push( handleObj ); 3010 } 3011 3012 // Keep track of which events have ever been used, for event optimization 3013 jQuery.event.global[ type ] = true; 3014 } 3015 3016 // Nullify elem to prevent memory leaks in IE 3017 elem = null; 3018 }, 3019 3020 global: {}, 3021 3022 // Detach an event or set of events from an element 3023 remove: function( elem, types, handler, selector, mappedTypes ) { 3024 3025 var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), 3026 t, tns, type, origType, namespaces, origCount, 3027 j, events, special, handle, eventType, handleObj; 3028 3029 if ( !elemData || !(events = elemData.events) ) { 3030 return; 3031 } 3032 3033 // Once for each type.namespace in types; type may be omitted 3034 types = jQuery.trim( hoverHack( types || "" ) ).split(" "); 3035 for ( t = 0; t < types.length; t++ ) { 3036 tns = rtypenamespace.exec( types[t] ) || []; 3037 type = origType = tns[1]; 3038 namespaces = tns[2]; 3039 3040 // Unbind all events (on this namespace, if provided) for the element 3041 if ( !type ) { 3042 for ( type in events ) { 3043 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 3044 } 3045 continue; 3046 } 3047 3048 special = jQuery.event.special[ type ] || {}; 3049 type = ( selector? special.delegateType : special.bindType ) || type; 3050 eventType = events[ type ] || []; 3051 origCount = eventType.length; 3052 namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; 3053 3054 // Remove matching events 3055 for ( j = 0; j < eventType.length; j++ ) { 3056 handleObj = eventType[ j ]; 3057 3058 if ( ( mappedTypes || origType === handleObj.origType ) && 3059 ( !handler || handler.guid === handleObj.guid ) && 3060 ( !namespaces || namespaces.test( handleObj.namespace ) ) && 3061 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { 3062 eventType.splice( j--, 1 ); 3063 3064 if ( handleObj.selector ) { 3065 eventType.delegateCount--; 3066 } 3067 if ( special.remove ) { 3068 special.remove.call( elem, handleObj ); 3069 } 3070 } 3071 } 3072 3073 // Remove generic event handler if we removed something and no more handlers exist 3074 // (avoids potential for endless recursion during removal of special event handlers) 3075 if ( eventType.length === 0 && origCount !== eventType.length ) { 3076 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { 3077 jQuery.removeEvent( elem, type, elemData.handle ); 3078 } 3079 3080 delete events[ type ]; 3081 } 3082 } 3083 3084 // Remove the expando if it's no longer used 3085 if ( jQuery.isEmptyObject( events ) ) { 3086 handle = elemData.handle; 3087 if ( handle ) { 3088 handle.elem = null; 3089 } 3090 3091 // removeData also checks for emptiness and clears the expando if empty 3092 // so use it instead of delete 3093 jQuery.removeData( elem, [ "events", "handle" ], true ); 3094 } 3095 }, 3096 3097 // Events that are safe to short-circuit if no handlers are attached. 3098 // Native DOM events should not be added, they may have inline handlers. 3099 customEvent: { 3100 "getData": true, 3101 "setData": true, 3102 "changeData": true 3103 }, 3104 3105 trigger: function( event, data, elem, onlyHandlers ) { 3106 // Don't do events on text and comment nodes 3107 if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { 3108 return; 3109 } 3110 3111 // Event object or event type 3112 var type = event.type || event, 3113 namespaces = [], 3114 cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; 3115 3116 // focus/blur morphs to focusin/out; ensure we're not firing them right now 3117 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 3118 return; 3119 } 3120 3121 if ( type.indexOf( "!" ) >= 0 ) { 3122 // Exclusive events trigger only for the exact event (no namespaces) 3123 type = type.slice(0, -1); 3124 exclusive = true; 3125 } 3126 3127 if ( type.indexOf( "." ) >= 0 ) { 3128 // Namespaced trigger; create a regexp to match event type in handle() 3129 namespaces = type.split("."); 3130 type = namespaces.shift(); 3131 namespaces.sort(); 3132 } 3133 3134 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { 3135 // No jQuery handlers for this event type, and it can't have inline handlers 3136 return; 3137 } 3138 3139 // Caller can pass in an Event, Object, or just an event type string 3140 event = typeof event === "object" ? 3141 // jQuery.Event object 3142 event[ jQuery.expando ] ? event : 3143 // Object literal 3144 new jQuery.Event( type, event ) : 3145 // Just the event type (string) 3146 new jQuery.Event( type ); 3147 3148 event.type = type; 3149 event.isTrigger = true; 3150 event.exclusive = exclusive; 3151 event.namespace = namespaces.join( "." ); 3152 event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; 3153 ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; 3154 3155 // Handle a global trigger 3156 if ( !elem ) { 3157 3158 // TODO: Stop taunting the data cache; remove global events and always attach to document 3159 cache = jQuery.cache; 3160 for ( i in cache ) { 3161 if ( cache[ i ].events && cache[ i ].events[ type ] ) { 3162 jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); 3163 } 3164 } 3165 return; 3166 } 3167 3168 // Clean up the event in case it is being reused 3169 event.result = undefined; 3170 if ( !event.target ) { 3171 event.target = elem; 3172 } 3173 3174 // Clone any incoming data and prepend the event, creating the handler arg list 3175 data = data != null ? jQuery.makeArray( data ) : []; 3176 data.unshift( event ); 3177 3178 // Allow special events to draw outside the lines 3179 special = jQuery.event.special[ type ] || {}; 3180 if ( special.trigger && special.trigger.apply( elem, data ) === false ) { 3181 return; 3182 } 3183 3184 // Determine event propagation path in advance, per W3C events spec (#9951) 3185 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 3186 eventPath = [[ elem, special.bindType || type ]]; 3187 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 3188 3189 bubbleType = special.delegateType || type; 3190 cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; 3191 old = null; 3192 for ( ; cur; cur = cur.parentNode ) { 3193 eventPath.push([ cur, bubbleType ]); 3194 old = cur; 3195 } 3196 3197 // Only add window if we got to document (e.g., not plain obj or detached DOM) 3198 if ( old && old === elem.ownerDocument ) { 3199 eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); 3200 } 3201 } 3202 3203 // Fire handlers on the event path 3204 for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { 3205 3206 cur = eventPath[i][0]; 3207 event.type = eventPath[i][1]; 3208 3209 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); 3210 if ( handle ) { 3211 handle.apply( cur, data ); 3212 } 3213 // Note that this is a bare JS function and not a jQuery handler 3214 handle = ontype && cur[ ontype ]; 3215 if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { 3216 event.preventDefault(); 3217 } 3218 } 3219 event.type = type; 3220 3221 // If nobody prevented the default action, do it now 3222 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 3223 3224 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && 3225 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { 3226 3227 // Call a native DOM method on the target with the same name name as the event. 3228 // Can't use an .isFunction() check here because IE6/7 fails that test. 3229 // Don't do default actions on window, that's where global variables be (#6170) 3230 // IE<9 dies on focus/blur to hidden element (#1486) 3231 if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { 3232 3233 // Don't re-trigger an onFOO event when we call its FOO() method 3234 old = elem[ ontype ]; 3235 3236 if ( old ) { 3237 elem[ ontype ] = null; 3238 } 3239 3240 // Prevent re-triggering of the same event, since we already bubbled it above 3241 jQuery.event.triggered = type; 3242 elem[ type ](); 3243 jQuery.event.triggered = undefined; 3244 3245 if ( old ) { 3246 elem[ ontype ] = old; 3247 } 3248 } 3249 } 3250 } 3251 3252 return event.result; 3253 }, 3254 3255 dispatch: function( event ) { 3256 3257 // Make a writable jQuery.Event from the native event object 3258 event = jQuery.event.fix( event || window.event ); 3259 3260 var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), 3261 delegateCount = handlers.delegateCount, 3262 args = [].slice.call( arguments, 0 ), 3263 run_all = !event.exclusive && !event.namespace, 3264 special = jQuery.event.special[ event.type ] || {}, 3265 handlerQueue = [], 3266 i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; 3267 3268 // Use the fix-ed jQuery.Event rather than the (read-only) native event 3269 args[0] = event; 3270 event.delegateTarget = this; 3271 3272 // Call the preDispatch hook for the mapped type, and let it bail if desired 3273 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 3274 return; 3275 } 3276 3277 // Determine handlers that should run if there are delegated events 3278 // Avoid non-left-click bubbling in Firefox (#3861) 3279 if ( delegateCount && !(event.button && event.type === "click") ) { 3280 3281 // Pregenerate a single jQuery object for reuse with .is() 3282 jqcur = jQuery(this); 3283 jqcur.context = this.ownerDocument || this; 3284 3285 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { 3286 3287 // Don't process events on disabled elements (#6911, #8165) 3288 if ( cur.disabled !== true ) { 3289 selMatch = {}; 3290 matches = []; 3291 jqcur[0] = cur; 3292 for ( i = 0; i < delegateCount; i++ ) { 3293 handleObj = handlers[ i ]; 3294 sel = handleObj.selector; 3295 3296 if ( selMatch[ sel ] === undefined ) { 3297 selMatch[ sel ] = ( 3298 handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) 3299 ); 3300 } 3301 if ( selMatch[ sel ] ) { 3302 matches.push( handleObj ); 3303 } 3304 } 3305 if ( matches.length ) { 3306 handlerQueue.push({ elem: cur, matches: matches }); 3307 } 3308 } 3309 } 3310 } 3311 3312 // Add the remaining (directly-bound) handlers 3313 if ( handlers.length > delegateCount ) { 3314 handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); 3315 } 3316 3317 // Run delegates first; they may want to stop propagation beneath us 3318 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { 3319 matched = handlerQueue[ i ]; 3320 event.currentTarget = matched.elem; 3321 3322 for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { 3323 handleObj = matched.matches[ j ]; 3324 3325 // Triggered event must either 1) be non-exclusive and have no namespace, or 3326 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). 3327 if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { 3328 3329 event.data = handleObj.data; 3330 event.handleObj = handleObj; 3331 3332 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) 3333 .apply( matched.elem, args ); 3334 3335 if ( ret !== undefined ) { 3336 event.result = ret; 3337 if ( ret === false ) { 3338 event.preventDefault(); 3339 event.stopPropagation(); 3340 } 3341 } 3342 } 3343 } 3344 } 3345 3346 // Call the postDispatch hook for the mapped type 3347 if ( special.postDispatch ) { 3348 special.postDispatch.call( this, event ); 3349 } 3350 3351 return event.result; 3352 }, 3353 3354 // Includes some event props shared by KeyEvent and MouseEvent 3355 // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** 3356 props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), 3357 3358 fixHooks: {}, 3359 3360 keyHooks: { 3361 props: "char charCode key keyCode".split(" "), 3362 filter: function( event, original ) { 3363 3364 // Add which for key events 3365 if ( event.which == null ) { 3366 event.which = original.charCode != null ? original.charCode : original.keyCode; 3367 } 3368 3369 return event; 3370 } 3371 }, 3372 3373 mouseHooks: { 3374 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), 3375 filter: function( event, original ) { 3376 var eventDoc, doc, body, 3377 button = original.button, 3378 fromElement = original.fromElement; 3379 3380 // Calculate pageX/Y if missing and clientX/Y available 3381 if ( event.pageX == null && original.clientX != null ) { 3382 eventDoc = event.target.ownerDocument || document; 3383 doc = eventDoc.documentElement; 3384 body = eventDoc.body; 3385 3386 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 3387 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); 3388 } 3389 3390 // Add relatedTarget, if necessary 3391 if ( !event.relatedTarget && fromElement ) { 3392 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; 3393 } 3394 3395 // Add which for click: 1 === left; 2 === middle; 3 === right 3396 // Note: button is not normalized, so don't use it 3397 if ( !event.which && button !== undefined ) { 3398 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 3399 } 3400 3401 return event; 3402 } 3403 }, 3404 3405 fix: function( event ) { 3406 if ( event[ jQuery.expando ] ) { 3407 return event; 3408 } 3409 3410 // Create a writable copy of the event object and normalize some properties 3411 var i, prop, 3412 originalEvent = event, 3413 fixHook = jQuery.event.fixHooks[ event.type ] || {}, 3414 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 3415 3416 event = jQuery.Event( originalEvent ); 3417 3418 for ( i = copy.length; i; ) { 3419 prop = copy[ --i ]; 3420 event[ prop ] = originalEvent[ prop ]; 3421 } 3422 3423 // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) 3424 if ( !event.target ) { 3425 event.target = originalEvent.srcElement || document; 3426 } 3427 3428 // Target should not be a text node (#504, Safari) 3429 if ( event.target.nodeType === 3 ) { 3430 event.target = event.target.parentNode; 3431 } 3432 3433 // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) 3434 if ( event.metaKey === undefined ) { 3435 event.metaKey = event.ctrlKey; 3436 } 3437 3438 return fixHook.filter? fixHook.filter( event, originalEvent ) : event; 3439 }, 3440 3441 special: { 3442 ready: { 3443 // Make sure the ready event is setup 3444 setup: jQuery.bindReady 3445 }, 3446 3447 load: { 3448 // Prevent triggered image.load events from bubbling to window.load 3449 noBubble: true 3450 }, 3451 3452 focus: { 3453 delegateType: "focusin" 3454 }, 3455 blur: { 3456 delegateType: "focusout" 3457 }, 3458 3459 beforeunload: { 3460 setup: function( data, namespaces, eventHandle ) { 3461 // We only want to do this special case on windows 3462 if ( jQuery.isWindow( this ) ) { 3463 this.onbeforeunload = eventHandle; 3464 } 3465 }, 3466 3467 teardown: function( namespaces, eventHandle ) { 3468 if ( this.onbeforeunload === eventHandle ) { 3469 this.onbeforeunload = null; 3470 } 3471 } 3472 } 3473 }, 3474 3475 simulate: function( type, elem, event, bubble ) { 3476 // Piggyback on a donor event to simulate a different one. 3477 // Fake originalEvent to avoid donor's stopPropagation, but if the 3478 // simulated event prevents default then we do the same on the donor. 3479 var e = jQuery.extend( 3480 new jQuery.Event(), 3481 event, 3482 { type: type, 3483 isSimulated: true, 3484 originalEvent: {} 3485 } 3486 ); 3487 if ( bubble ) { 3488 jQuery.event.trigger( e, null, elem ); 3489 } else { 3490 jQuery.event.dispatch.call( elem, e ); 3491 } 3492 if ( e.isDefaultPrevented() ) { 3493 event.preventDefault(); 3494 } 3495 } 3496}; 3497 3498// Some plugins are using, but it's undocumented/deprecated and will be removed. 3499// The 1.7 special event interface should provide all the hooks needed now. 3500jQuery.event.handle = jQuery.event.dispatch; 3501 3502jQuery.removeEvent = document.removeEventListener ? 3503 function( elem, type, handle ) { 3504 if ( elem.removeEventListener ) { 3505 elem.removeEventListener( type, handle, false ); 3506 } 3507 } : 3508 function( elem, type, handle ) { 3509 if ( elem.detachEvent ) { 3510 elem.detachEvent( "on" + type, handle ); 3511 } 3512 }; 3513 3514jQuery.Event = function( src, props ) { 3515 // Allow instantiation without the 'new' keyword 3516 if ( !(this instanceof jQuery.Event) ) { 3517 return new jQuery.Event( src, props ); 3518 } 3519 3520 // Event object 3521 if ( src && src.type ) { 3522 this.originalEvent = src; 3523 this.type = src.type; 3524 3525 // Events bubbling up the document may have been marked as prevented 3526 // by a handler lower down the tree; reflect the correct value. 3527 this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || 3528 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; 3529 3530 // Event type 3531 } else { 3532 this.type = src; 3533 } 3534 3535 // Put explicitly provided properties onto the event object 3536 if ( props ) { 3537 jQuery.extend( this, props ); 3538 } 3539 3540 // Create a timestamp if incoming event doesn't have one 3541 this.timeStamp = src && src.timeStamp || jQuery.now(); 3542 3543 // Mark it as fixed 3544 this[ jQuery.expando ] = true; 3545}; 3546 3547function returnFalse() { 3548 return false; 3549} 3550function returnTrue() { 3551 return true; 3552} 3553 3554// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 3555// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 3556jQuery.Event.prototype = { 3557 preventDefault: function() { 3558 this.isDefaultPrevented = returnTrue; 3559 3560 var e = this.originalEvent; 3561 if ( !e ) { 3562 return; 3563 } 3564 3565 // if preventDefault exists run it on the original event 3566 if ( e.preventDefault ) { 3567 e.preventDefault(); 3568 3569 // otherwise set the returnValue property of the original event to false (IE) 3570 } else { 3571 e.returnValue = false; 3572 } 3573 }, 3574 stopPropagation: function() { 3575 this.isPropagationStopped = returnTrue; 3576 3577 var e = this.originalEvent; 3578 if ( !e ) { 3579 return; 3580 } 3581 // if stopPropagation exists run it on the original event 3582 if ( e.stopPropagation ) { 3583 e.stopPropagation(); 3584 } 3585 // otherwise set the cancelBubble property of the original event to true (IE) 3586 e.cancelBubble = true; 3587 }, 3588 stopImmediatePropagation: function() { 3589 this.isImmediatePropagationStopped = returnTrue; 3590 this.stopPropagation(); 3591 }, 3592 isDefaultPrevented: returnFalse, 3593 isPropagationStopped: returnFalse, 3594 isImmediatePropagationStopped: returnFalse 3595}; 3596 3597// Create mouseenter/leave events using mouseover/out and event-time checks 3598jQuery.each({ 3599 mouseenter: "mouseover", 3600 mouseleave: "mouseout" 3601}, function( orig, fix ) { 3602 jQuery.event.special[ orig ] = { 3603 delegateType: fix, 3604 bindType: fix, 3605 3606 handle: function( event ) { 3607 var target = this, 3608 related = event.relatedTarget, 3609 handleObj = event.handleObj, 3610 selector = handleObj.selector, 3611 ret; 3612 3613 // For mousenter/leave call the handler if related is outside the target. 3614 // NB: No relatedTarget if the mouse left/entered the browser window 3615 if ( !related || (related !== target && !jQuery.contains( target, related )) ) { 3616 event.type = handleObj.origType; 3617 ret = handleObj.handler.apply( this, arguments ); 3618 event.type = fix; 3619 } 3620 return ret; 3621 } 3622 }; 3623}); 3624 3625// IE submit delegation 3626if ( !jQuery.support.submitBubbles ) { 3627 3628 jQuery.event.special.submit = { 3629 setup: function() { 3630 // Only need this for delegated form submit events 3631 if ( jQuery.nodeName( this, "form" ) ) { 3632 return false; 3633 } 3634 3635 // Lazy-add a submit handler when a descendant form may potentially be submitted 3636 jQuery.event.add( this, "click._submit keypress._submit", function( e ) { 3637 // Node name check avoids a VML-related crash in IE (#9807) 3638 var elem = e.target, 3639 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; 3640 if ( form && !form._submit_attached ) { 3641 jQuery.event.add( form, "submit._submit", function( event ) { 3642 event._submit_bubble = true; 3643 }); 3644 form._submit_attached = true; 3645 } 3646 }); 3647 // return undefined since we don't need an event listener 3648 }, 3649 3650 postDispatch: function( event ) { 3651 // If form was submitted by the user, bubble the event up the tree 3652 if ( event._submit_bubble ) { 3653 delete event._submit_bubble; 3654 if ( this.parentNode && !event.isTrigger ) { 3655 jQuery.event.simulate( "submit", this.parentNode, event, true ); 3656 } 3657 } 3658 }, 3659 3660 teardown: function() { 3661 // Only need this for delegated form submit events 3662 if ( jQuery.nodeName( this, "form" ) ) { 3663 return false; 3664 } 3665 3666 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above 3667 jQuery.event.remove( this, "._submit" ); 3668 } 3669 }; 3670} 3671 3672// IE change delegation and checkbox/radio fix 3673if ( !jQuery.support.changeBubbles ) { 3674 3675 jQuery.event.special.change = { 3676 3677 setup: function() { 3678 3679 if ( rformElems.test( this.nodeName ) ) { 3680 // IE doesn't fire change on a check/radio until blur; trigger it on click 3681 // after a propertychange. Eat the blur-change in special.change.handle. 3682 // This still fires onchange a second time for check/radio after blur. 3683 if ( this.type === "checkbox" || this.type === "radio" ) { 3684 jQuery.event.add( this, "propertychange._change", function( event ) { 3685 if ( event.originalEvent.propertyName === "checked" ) { 3686 this._just_changed = true; 3687 } 3688 }); 3689 jQuery.event.add( this, "click._change", function( event ) { 3690 if ( this._just_changed && !event.isTrigger ) { 3691 this._just_changed = false; 3692 jQuery.event.simulate( "change", this, event, true ); 3693 } 3694 }); 3695 } 3696 return false; 3697 } 3698 // Delegated event; lazy-add a change handler on descendant inputs 3699 jQuery.event.add( this, "beforeactivate._change", function( e ) { 3700 var elem = e.target; 3701 3702 if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { 3703 jQuery.event.add( elem, "change._change", function( event ) { 3704 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { 3705 jQuery.event.simulate( "change", this.parentNode, event, true ); 3706 } 3707 }); 3708 elem._change_attached = true; 3709 } 3710 }); 3711 }, 3712 3713 handle: function( event ) { 3714 var elem = event.target; 3715 3716 // Swallow native change events from checkbox/radio, we already triggered them above 3717 if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { 3718 return event.handleObj.handler.apply( this, arguments ); 3719 } 3720 }, 3721 3722 teardown: function() { 3723 jQuery.event.remove( this, "._change" ); 3724 3725 return rformElems.test( this.nodeName ); 3726 } 3727 }; 3728} 3729 3730// Create "bubbling" focus and blur events 3731if ( !jQuery.support.focusinBubbles ) { 3732 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 3733 3734 // Attach a single capturing handler while someone wants focusin/focusout 3735 var attaches = 0, 3736 handler = function( event ) { 3737 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); 3738 }; 3739 3740 jQuery.event.special[ fix ] = { 3741 setup: function() { 3742 if ( attaches++ === 0 ) { 3743 document.addEventListener( orig, handler, true ); 3744 } 3745 }, 3746 teardown: function() { 3747 if ( --attaches === 0 ) { 3748 document.removeEventListener( orig, handler, true ); 3749 } 3750 } 3751 }; 3752 }); 3753} 3754 3755jQuery.fn.extend({ 3756 3757 on: function( types, selector, data, fn, /*INTERNAL*/ one ) { 3758 var origFn, type; 3759 3760 // Types can be a map of types/handlers 3761 if ( typeof types === "object" ) { 3762 // ( types-Object, selector, data ) 3763 if ( typeof selector !== "string" ) { // && selector != null 3764 // ( types-Object, data ) 3765 data = data || selector; 3766 selector = undefined; 3767 } 3768 for ( type in types ) { 3769 this.on( type, selector, data, types[ type ], one ); 3770 } 3771 return this; 3772 } 3773 3774 if ( data == null && fn == null ) { 3775 // ( types, fn ) 3776 fn = selector; 3777 data = selector = undefined; 3778 } else if ( fn == null ) { 3779 if ( typeof selector === "string" ) { 3780 // ( types, selector, fn ) 3781 fn = data; 3782 data = undefined; 3783 } else { 3784 // ( types, data, fn ) 3785 fn = data; 3786 data = selector; 3787 selector = undefined; 3788 } 3789 } 3790 if ( fn === false ) { 3791 fn = returnFalse; 3792 } else if ( !fn ) { 3793 return this; 3794 } 3795 3796 if ( one === 1 ) { 3797 origFn = fn; 3798 fn = function( event ) { 3799 // Can use an empty set, since event contains the info 3800 jQuery().off( event ); 3801 return origFn.apply( this, arguments ); 3802 }; 3803 // Use same guid so caller can remove using origFn 3804 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 3805 } 3806 return this.each( function() { 3807 jQuery.event.add( this, types, fn, data, selector ); 3808 }); 3809 }, 3810 one: function( types, selector, data, fn ) { 3811 return this.on( types, selector, data, fn, 1 ); 3812 }, 3813 off: function( types, selector, fn ) { 3814 if ( types && types.preventDefault && types.handleObj ) { 3815 // ( event ) dispatched jQuery.Event 3816 var handleObj = types.handleObj; 3817 jQuery( types.delegateTarget ).off( 3818 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, 3819 handleObj.selector, 3820 handleObj.handler 3821 ); 3822 return this; 3823 } 3824 if ( typeof types === "object" ) { 3825 // ( types-object [, selector] ) 3826 for ( var type in types ) { 3827 this.off( type, selector, types[ type ] ); 3828 } 3829 return this; 3830 } 3831 if ( selector === false || typeof selector === "function" ) { 3832 // ( types [, fn] ) 3833 fn = selector; 3834 selector = undefined; 3835 } 3836 if ( fn === false ) { 3837 fn = returnFalse; 3838 } 3839 return this.each(function() { 3840 jQuery.event.remove( this, types, fn, selector ); 3841 }); 3842 }, 3843 3844 bind: function( types, data, fn ) { 3845 return this.on( types, null, data, fn ); 3846 }, 3847 unbind: function( types, fn ) { 3848 return this.off( types, null, fn ); 3849 }, 3850 3851 live: function( types, data, fn ) { 3852 jQuery( this.context ).on( types, this.selector, data, fn ); 3853 return this; 3854 }, 3855 die: function( types, fn ) { 3856 jQuery( this.context ).off( types, this.selector || "**", fn ); 3857 return this; 3858 }, 3859 3860 delegate: function( selector, types, data, fn ) { 3861 return this.on( types, selector, data, fn ); 3862 }, 3863 undelegate: function( selector, types, fn ) { 3864 // ( namespace ) or ( selector, types [, fn] ) 3865 return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); 3866 }, 3867 3868 trigger: function( type, data ) { 3869 return this.each(function() { 3870 jQuery.event.trigger( type, data, this ); 3871 }); 3872 }, 3873 triggerHandler: function( type, data ) { 3874 if ( this[0] ) { 3875 return jQuery.event.trigger( type, data, this[0], true ); 3876 } 3877 }, 3878 3879 toggle: function( fn ) { 3880 // Save reference to arguments for access in closure 3881 var args = arguments, 3882 guid = fn.guid || jQuery.guid++, 3883 i = 0, 3884 toggler = function( event ) { 3885 // Figure out which function to execute 3886 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; 3887 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 3888 3889 // Make sure that clicks stop 3890 event.preventDefault(); 3891 3892 // and execute the function 3893 return args[ lastToggle ].apply( this, arguments ) || false; 3894 }; 3895 3896 // link all the functions, so any of them can unbind this click handler 3897 toggler.guid = guid; 3898 while ( i < args.length ) { 3899 args[ i++ ].guid = guid; 3900 } 3901 3902 return this.click( toggler ); 3903 }, 3904 3905 hover: function( fnOver, fnOut ) { 3906 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 3907 } 3908}); 3909 3910jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 3911 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 3912 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { 3913 3914 // Handle event binding 3915 jQuery.fn[ name ] = function( data, fn ) { 3916 if ( fn == null ) { 3917 fn = data; 3918 data = null; 3919 } 3920 3921 return arguments.length > 0 ? 3922 this.on( name, null, data, fn ) : 3923 this.trigger( name ); 3924 }; 3925 3926 if ( jQuery.attrFn ) { 3927 jQuery.attrFn[ name ] = true; 3928 } 3929
3930 if ( rkeyEvent.test( name ) ) { 3931 jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; 3932 } 3933 3934 if ( rmouseEvent.test( name ) ) { 3935 jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; 3936 } 3937}); 3938 3939 3940 3941/*! 3942 * Sizzle CSS Selector Engine 3943 * Copyright 2011, The Dojo Foundation 3944 * Released under the MIT, BSD, and GPL Licenses. 3945 * More information: http://sizzlejs.com/ 3946 */ 3947(function(){ 3948 3949var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, 3950 expando = "sizcache" + (Math.random() + '').replace('.', ''), 3951 done = 0, 3952 toString = Object.prototype.toString, 3953 hasDuplicate = false, 3954 baseHasDuplicate = true, 3955 rBackslash = /\\/g, 3956 rReturn = /\r\n/g, 3957 rNonWord = /\W/; 3958 3959// Here we check if the JavaScript engine is using some sort of 3960// optimization where it does not always call our comparision 3961// function. If that is the case, discard the hasDuplicate value. 3962// Thus far that includes Google Chrome. 3963[0, 0].sort(function() { 3964 baseHasDuplicate = false; 3965 return 0; 3966}); 3967 3968var Sizzle = function( selector, context, results, seed ) { 3969 results = results || []; 3970 context = context || document; 3971 3972 var origContext = context; 3973 3974 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { 3975 return []; 3976 } 3977 3978 if ( !selector || typeof selector !== "string" ) { 3979 return results; 3980 } 3981 3982 var m, set, checkSet, extra, ret, cur, pop, i, 3983 prune = true, 3984 contextXML = Sizzle.isXML( context ), 3985 parts = [], 3986 soFar = selector; 3987 3988 // Reset the position of the chunker regexp (start from head) 3989 do { 3990 chunker.exec( "" ); 3991 m = chunker.exec( soFar ); 3992 3993 if ( m ) { 3994 soFar = m[3]; 3995 3996 parts.push( m[1] ); 3997 3998 if ( m[2] ) { 3999 extra = m[3]; 4000 break; 4001 } 4002 } 4003 } while ( m ); 4004 4005 if ( parts.length > 1 && origPOS.exec( selector ) ) { 4006 4007 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { 4008 set = posProcess( parts[0] + parts[1], context, seed ); 4009 4010 } else { 4011 set = Expr.relative[ parts[0] ] ? 4012 [ context ] : 4013 Sizzle( parts.shift(), context ); 4014 4015 while ( parts.length ) { 4016 selector = parts.shift(); 4017 4018 if ( Expr.relative[ selector ] ) { 4019 selector += parts.shift(); 4020 } 4021 4022 set = posProcess( selector, set, seed ); 4023 } 4024 } 4025 4026 } else { 4027 // Take a shortcut and set the context if the root selector is an ID 4028 // (but not if it'll be faster if the inner selector is an ID) 4029 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && 4030 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { 4031 4032 ret = Sizzle.find( parts.shift(), context, contextXML ); 4033 context = ret.expr ? 4034 Sizzle.filter( ret.expr, ret.set )[0] : 4035 ret.set[0]; 4036 } 4037 4038 if ( context ) { 4039 ret = seed ? 4040 { expr: parts.pop(), set: makeArray(seed) } : 4041 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); 4042 4043 set = ret.expr ? 4044 Sizzle.filter( ret.expr, ret.set ) : 4045 ret.set; 4046 4047 if ( parts.length > 0 ) { 4048 checkSet = makeArray( set ); 4049 4050 } else { 4051 prune = false;
4052 } 4053 4054 while ( parts.length ) { 4055 cur = parts.pop(); 4056 pop = cur; 4057 4058 if ( !Expr.relative[ cur ] ) { 4059 cur = ""; 4060 } else { 4061 pop = parts.pop(); 4062 } 4063 4064 if ( pop == null ) { 4065 pop = context; 4066 } 4067 4068 Expr.relative[ cur ]( checkSet, pop, contextXML ); 4069 } 4070 4071 } else { 4072 checkSet = parts = []; 4073 } 4074 } 4075 4076 if ( !checkSet ) { 4077 checkSet = set; 4078 } 4079 4080 if ( !checkSet ) { 4081 Sizzle.error( cur || selector ); 4082 } 4083 4084 if ( toString.call(checkSet) === "[object Array]" ) { 4085 if ( !prune ) { 4086 results.push.apply( results, checkSet ); 4087 4088 } else if ( context && context.nodeType === 1 ) { 4089 for ( i = 0; checkSet[i] != null; i++ ) { 4090 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { 4091 results.push( set[i] ); 4092 } 4093 } 4094 4095 } else { 4096 for ( i = 0; checkSet[i] != null; i++ ) { 4097 if ( checkSet[i] && checkSet[i].nodeType === 1 ) { 4098 results.push( set[i] ); 4099 } 4100 } 4101 } 4102 4103 } else { 4104 makeArray( checkSet, results ); 4105 } 4106 4107 if ( extra ) { 4108 Sizzle( extra, origContext, results, seed ); 4109 Sizzle.uniqueSort( results ); 4110 } 4111 4112 return results; 4113}; 4114 4115Sizzle.uniqueSort = function( results ) { 4116 if ( sortOrder ) { 4117 hasDuplicate = baseHasDuplicate; 4118 results.sort( sortOrder ); 4119 4120 if ( hasDuplicate ) { 4121 for ( var i = 1; i < results.length; i++ ) { 4122 if ( results[i] === results[ i - 1 ] ) { 4123 results.splice( i--, 1 ); 4124 } 4125 } 4126 } 4127 } 4128 4129 return results; 4130}; 4131 4132Sizzle.matches = function( expr, set ) { 4133 return Sizzle( expr, null, null, set ); 4134}; 4135 4136Sizzle.matchesSelector = function( node, expr ) { 4137 return Sizzle( expr, null, null, [node] ).length > 0; 4138}; 4139 4140Sizzle.find = function( expr, context, isXML ) { 4141 var set, i, len, match, type, left; 4142 4143 if ( !expr ) { 4144 return []; 4145 } 4146 4147 for ( i = 0, len = Expr.order.length; i < len; i++ ) { 4148 type = Expr.order[i]; 4149 4150 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 4151 left = match[1]; 4152 match.splice( 1, 1 ); 4153 4154 if ( left.substr( left.length - 1 ) !== "\\" ) { 4155 match[1] = (match[1] || "").replace( rBackslash, "" ); 4156 set = Expr.find[ type ]( match, context, isXML ); 4157 4158 if ( set != null ) { 4159 expr = expr.replace( Expr.match[ type ], "" ); 4160 break; 4161 } 4162 } 4163 } 4164 } 4165 4166 if ( !set ) { 4167 set = typeof context.getElementsByTagName !== "undefined" ? 4168 context.getElementsByTagName( "*" ) : 4169 []; 4170 } 4171 4172 return { set: set, expr: expr }; 4173}; 4174 4175Sizzle.filter = function( expr, set, inplace, not ) { 4176 var match, anyFound, 4177 type, found, item, filter, left, 4178 i, pass, 4179 old = expr, 4180 result = [], 4181 curLoop = set, 4182 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); 4183 4184 while ( expr && set.length ) { 4185 for ( type in Expr.filter ) { 4186 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { 4187 filter = Expr.filter[ type ]; 4188 left = match[1]; 4189 4190 anyFound = false; 4191 4192 match.splice(1,1); 4193 4194 if ( left.substr( left.length - 1 ) === "\\" ) { 4195 continue; 4196 } 4197 4198 if ( curLoop === result ) { 4199 result = []; 4200 } 4201 4202 if ( Expr.preFilter[ type ] ) { 4203 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); 4204 4205 if ( !match ) { 4206 anyFound = found = true; 4207 4208 } else if ( match === true ) { 4209 continue; 4210 } 4211 } 4212 4213 if ( match ) { 4214 for ( i = 0; (item = curLoop[i]) != null; i++ ) { 4215 if ( item ) { 4216 found = filter( item, match, i, curLoop ); 4217 pass = not ^ found; 4218 4219 if ( inplace && found != null ) { 4220 if ( pass ) { 4221 anyFound = true; 4222 4223 } else { 4224 curLoop[i] = false; 4225 } 4226 4227 } else if ( pass ) { 4228 result.push( item ); 4229 anyFound = true; 4230 } 4231 } 4232 } 4233 } 4234 4235 if ( found !== undefined ) { 4236 if ( !inplace ) { 4237 curLoop = result; 4238 } 4239 4240 expr = expr.replace( Expr.match[ type ], "" ); 4241 4242 if ( !anyFound ) { 4243 return []; 4244 } 4245 4246 break; 4247 } 4248 } 4249 } 4250 4251 // Improper expression 4252 if ( expr === old ) { 4253 if ( anyFound == null ) { 4254 Sizzle.error( expr ); 4255 4256 } else { 4257 break; 4258 } 4259 } 4260 4261 old = expr; 4262 } 4263 4264 return curLoop; 4265}; 4266 4267Sizzle.error = function( msg ) { 4268 throw new Error( "Syntax error, unrecognized expression: " + msg ); 4269}; 4270 4271/** 4272 * Utility function for retreiving the text value of an array of DOM nodes 4273 * @param {Array|Element} elem 4274 */ 4275var getText = Sizzle.getText = function( elem ) { 4276 var i, node, 4277 nodeType = elem.nodeType, 4278 ret = ""; 4279 4280 if ( nodeType ) { 4281 if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 4282 // Use textContent || innerText for elements 4283 if ( typeof elem.textContent === 'string' ) { 4284 return elem.textContent; 4285 } else if ( typeof elem.innerText === 'string' ) { 4286 // Replace IE's carriage returns 4287 return elem.innerText.replace( rReturn, '' ); 4288 } else { 4289 // Traverse it's children 4290 for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { 4291 ret += getText( elem ); 4292 } 4293 } 4294 } else if ( nodeType === 3 || nodeType === 4 ) { 4295 return elem.nodeValue; 4296 } 4297 } else { 4298 4299 // If no nodeType, this is expected to be an array 4300 for ( i = 0; (node = elem[i]); i++ ) {
4301 // Do not traverse comment nodes 4302 if ( node.nodeType !== 8 ) { 4303 ret += getText( node ); 4304 } 4305 } 4306 } 4307 return ret; 4308}; 4309 4310var Expr = Sizzle.selectors = { 4311 order: [ "ID", "NAME", "TAG" ], 4312 4313 match: { 4314 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4315 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, 4316 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, 4317 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, 4318 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, 4319 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, 4320 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, 4321 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ 4322 }, 4323 4324 leftMatch: {}, 4325 4326 attrMap: { 4327 "class": "className", 4328 "for": "htmlFor" 4329 }, 4330 4331 attrHandle: { 4332 href: function( elem ) { 4333 return elem.getAttribute( "href" ); 4334 }, 4335 type: function( elem ) { 4336 return elem.getAttribute( "type" ); 4337 } 4338 }, 4339 4340 relative: { 4341 "+": function(checkSet, part){ 4342 var isPartStr = typeof part === "string", 4343 isTag = isPartStr && !rNonWord.test( part ), 4344 isPartStrNotTag = isPartStr && !isTag; 4345 4346 if ( isTag ) { 4347 part = part.toLowerCase(); 4348 } 4349 4350 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { 4351 if ( (elem = checkSet[i]) ) { 4352 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} 4353 4354 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? 4355 elem || false : 4356 elem === part; 4357 } 4358 } 4359 4360 if ( isPartStrNotTag ) { 4361 Sizzle.filter( part, checkSet, true ); 4362 } 4363 }, 4364 4365 ">": function( checkSet, part ) { 4366 var elem, 4367 isPartStr = typeof part === "string", 4368 i = 0, 4369 l = checkSet.length; 4370 4371 if ( isPartStr && !rNonWord.test( part ) ) { 4372 part = part.toLowerCase(); 4373 4374 for ( ; i < l; i++ ) { 4375 elem = checkSet[i]; 4376 4377 if ( elem ) { 4378 var parent = elem.parentNode; 4379 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; 4380 } 4381 } 4382 4383 } else { 4384 for ( ; i < l; i++ ) { 4385 elem = checkSet[i]; 4386 4387 if ( elem ) { 4388 checkSet[i] = isPartStr ? 4389 elem.parentNode : 4390 elem.parentNode === part; 4391 } 4392 } 4393 4394 if ( isPartStr ) { 4395 Sizzle.filter( part, checkSet, true ); 4396 } 4397 } 4398 }, 4399 4400 "": function(checkSet, part, isXML){ 4401 var nodeCheck, 4402 doneName = done++, 4403 checkFn = dirCheck; 4404 4405 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4406 part = part.toLowerCase(); 4407 nodeCheck = part; 4408 checkFn = dirNodeCheck; 4409 } 4410 4411 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); 4412 }, 4413 4414 "~": function( checkSet, part, isXML ) { 4415 var nodeCheck, 4416 doneName = done++, 4417 checkFn = dirCheck; 4418 4419 if ( typeof part === "string" && !rNonWord.test( part ) ) { 4420 part = part.toLowerCase(); 4421 nodeCheck = part; 4422 checkFn = dirNodeCheck; 4423 } 4424 4425 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); 4426 } 4427 }, 4428 4429 find: { 4430 ID: function( match, context, isXML ) { 4431 if ( typeof context.getElementById !== "undefined" && !isXML ) { 4432 var m = context.getElementById(match[1]); 4433 // Check parentNode to catch when Blackberry 4.6 returns 4434 // nodes that are no longer in the document #6963 4435 return m && m.parentNode ? [m] : []; 4436 } 4437 }, 4438 4439 NAME: function( match, context ) { 4440 if ( typeof context.getElementsByName !== "undefined" ) { 4441 var ret = [], 4442 results = context.getElementsByName( match[1] ); 4443 4444 for ( var i = 0, l = results.length; i < l; i++ ) { 4445 if ( results[i].getAttribute("name") === match[1] ) { 4446 ret.push( results[i] ); 4447 } 4448 } 4449 4450 return ret.length === 0 ? null : ret; 4451 } 4452 }, 4453 4454 TAG: function( match, context ) { 4455 if ( typeof context.getElementsByTagName !== "undefined" ) { 4456 return context.getElementsByTagName( match[1] ); 4457 } 4458 } 4459 }, 4460 preFilter: { 4461 CLASS: function( match, curLoop, inplace, result, not, isXML ) { 4462 match = " " + match[1].replace( rBackslash, "" ) + " "; 4463 4464 if ( isXML ) { 4465 return match; 4466 } 4467 4468 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { 4469 if ( elem ) { 4470 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { 4471 if ( !inplace ) { 4472 result.push( elem ); 4473 } 4474 4475 } else if ( inplace ) { 4476 curLoop[i] = false;
4477 } 4478 } 4479 } 4480 4481 return false; 4482 }, 4483 4484 ID: function( match ) { 4485 return match[1].replace( rBackslash, "" ); 4486 }, 4487 4488 TAG: function( match, curLoop ) { 4489 return match[1].replace( rBackslash, "" ).toLowerCase(); 4490 }, 4491 4492 CHILD: function( match ) { 4493 if ( match[1] === "nth" ) { 4494 if ( !match[2] ) { 4495 Sizzle.error( match[0] ); 4496 } 4497 4498 match[2] = match[2].replace(/^\+|\s*/g, ''); 4499 4500 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' 4501 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( 4502 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || 4503 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); 4504 4505 // calculate the numbers (first)n+(last) including if they are negative 4506 match[2] = (test[1] + (test[2] || 1)) - 0; 4507 match[3] = test[3] - 0; 4508 } 4509 else if ( match[2] ) { 4510 Sizzle.error( match[0] ); 4511 } 4512 4513 // TODO: Move to normal caching system 4514 match[0] = done++; 4515 4516 return match; 4517 }, 4518 4519 ATTR: function( match, curLoop, inplace, result, not, isXML ) { 4520 var name = match[1] = match[1].replace( rBackslash, "" ); 4521 4522 if ( !isXML && Expr.attrMap[name] ) { 4523 match[1] = Expr.attrMap[name]; 4524 } 4525 4526 // Handle if an un-quoted value was used 4527 match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); 4528 4529 if ( match[2] === "~=" ) { 4530 match[4] = " " + match[4] + " "; 4531 } 4532 4533 return match; 4534 }, 4535 4536 PSEUDO: function( match, curLoop, inplace, result, not ) { 4537 if ( match[1] === "not" ) { 4538 // If we're dealing with a complex expression, or a simple one 4539 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { 4540 match[3] = Sizzle(match[3], null, null, curLoop); 4541 4542 } else { 4543 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); 4544 4545 if ( !inplace ) { 4546 result.push.apply( result, ret ); 4547 } 4548 4549 return false; 4550 } 4551 4552 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { 4553 return true; 4554 } 4555 4556 return match; 4557 }, 4558 4559 POS: function( match ) { 4560 match.unshift( true ); 4561 4562 return match; 4563 } 4564 }, 4565 4566 filters: { 4567 enabled: function( elem ) { 4568 return elem.disabled === false && elem.type !== "hidden"; 4569 }, 4570 4571 disabled: function( elem ) { 4572 return elem.disabled === true; 4573 }, 4574 4575 checked: function( elem ) { 4576 return elem.checked === true; 4577 }, 4578 4579 selected: function( elem ) { 4580 // Accessing this property makes selected-by-default 4581 // options in Safari work properly 4582 if ( elem.parentNode ) { 4583 elem.parentNode.selectedIndex; 4584 } 4585 4586 return elem.selected === true; 4587 }, 4588 4589 parent: function( elem ) { 4590 return !!elem.firstChild; 4591 }, 4592 4593 empty: function( elem ) { 4594 return !elem.firstChild; 4595 }, 4596 4597 has: function( elem, i, match ) { 4598 return !!Sizzle( match[3], elem ).length; 4599 }, 4600 4601 header: function( elem ) { 4602 return (/h\d/i).test( elem.nodeName ); 4603 }, 4604 4605 text: function( elem ) { 4606 var attr = elem.getAttribute( "type" ), type = elem.type; 4607 // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 4608 // use getAttribute instead to test this case 4609 return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); 4610 }, 4611 4612 radio: function( elem ) { 4613 return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; 4614 }, 4615 4616 checkbox: function( elem ) { 4617 return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; 4618 }, 4619 4620 file: function( elem ) { 4621 return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; 4622 }, 4623 4624 password: function( elem ) { 4625 return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; 4626 }, 4627 4628 submit: function( elem ) { 4629 var name = elem.nodeName.toLowerCase(); 4630 return (name === "input" || name === "button") && "submit" === elem.type; 4631 }, 4632 4633 image: function( elem ) { 4634 return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; 4635 }, 4636 4637 reset: function( elem ) { 4638 var name = elem.nodeName.toLowerCase(); 4639 return (name === "input" || name === "button") && "reset" === elem.type; 4640 }, 4641 4642 button: function( elem ) { 4643 var name = elem.nodeName.toLowerCase(); 4644 return name === "input" && "button" === elem.type || name === "button"; 4645 }, 4646 4647 input: function( elem ) { 4648 return (/input|select|textarea|button/i).test( elem.nodeName ); 4649 }, 4650 4651 focus: function( elem ) { 4652 return elem === elem.ownerDocument.activeElement; 4653 } 4654 }, 4655 setFilters: { 4656 first: function( elem, i ) { 4657 return i === 0; 4658 }, 4659 4660 last: function( elem, i, match, array ) { 4661 return i === array.length - 1; 4662 }, 4663 4664 even: function( elem, i ) { 4665 return i % 2 === 0; 4666 }, 4667 4668 odd: function( elem, i ) { 4669 return i % 2 === 1; 4670 }, 4671 4672 lt: function( elem, i, match ) { 4673 return i < match[3] - 0; 4674 }, 4675 4676 gt: function( elem, i, match ) { 4677 return i > match[3] - 0; 4678 }, 4679 4680 nth: function( elem, i, match ) { 4681 return match[3] - 0 === i; 4682 }, 4683 4684 eq: function( elem, i, match ) { 4685 return match[3] - 0 === i; 4686 } 4687 }, 4688 filter: { 4689 PSEUDO: function( elem, match, i, array ) { 4690 var name = match[1], 4691 filter = Expr.filters[ name ]; 4692 4693 if ( filter ) { 4694 return filter( elem, i, match, array ); 4695 4696 } else if ( name === "contains" ) { 4697 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; 4698 4699 } else if ( name === "not" ) { 4700 var not = match[3]; 4701 4702 for ( var j = 0, l = not.length; j < l; j++ ) { 4703 if ( not[j] === elem ) { 4704 return false;
4705 } 4706 } 4707 4708 return true; 4709 4710 } else { 4711 Sizzle.error( name ); 4712 } 4713 }, 4714 4715 CHILD: function( elem, match ) { 4716 var first, last, 4717 doneName, parent, cache, 4718 count, diff, 4719 type = match[1], 4720 node = elem; 4721 4722 switch ( type ) { 4723 case "only": 4724 case "first": 4725 while ( (node = node.previousSibling) ) { 4726 if ( node.nodeType === 1 ) { 4727 return false; 4728 } 4729 } 4730 4731 if ( type === "first" ) { 4732 return true; 4733 } 4734 4735 node = elem; 4736 4737 /* falls through */ 4738 case "last": 4739 while ( (node = node.nextSibling) ) { 4740 if ( node.nodeType === 1 ) { 4741 return false; 4742 } 4743 } 4744 4745 return true; 4746 4747 case "nth": 4748 first = match[2]; 4749 last = match[3]; 4750 4751 if ( first === 1 && last === 0 ) { 4752 return true; 4753 } 4754 4755 doneName = match[0]; 4756 parent = elem.parentNode; 4757 4758 if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { 4759 count = 0; 4760 4761 for ( node = parent.firstChild; node; node = node.nextSibling ) { 4762 if ( node.nodeType === 1 ) { 4763 node.nodeIndex = ++count; 4764 } 4765 } 4766 4767 parent[ expando ] = doneName; 4768 } 4769 4770 diff = elem.nodeIndex - last; 4771 4772 if ( first === 0 ) { 4773 return diff === 0; 4774 4775 } else { 4776 return ( diff % first === 0 && diff / first >= 0 ); 4777 } 4778 } 4779 }, 4780 4781 ID: function( elem, match ) { 4782 return elem.nodeType === 1 && elem.getAttribute("id") === match; 4783 }, 4784 4785 TAG: function( elem, match ) { 4786 return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; 4787 }, 4788 4789 CLASS: function( elem, match ) { 4790 return (" " + (elem.className || elem.getAttribute("class")) + " ") 4791 .indexOf( match ) > -1; 4792 }, 4793 4794 ATTR: function( elem, match ) { 4795 var name = match[1], 4796 result = Sizzle.attr ? 4797 Sizzle.attr( elem, name ) : 4798 Expr.attrHandle[ name ] ? 4799 Expr.attrHandle[ name ]( elem ) : 4800 elem[ name ] != null ? 4801 elem[ name ] : 4802 elem.getAttribute( name ), 4803 value = result + "", 4804 type = match[2], 4805 check = match[4]; 4806 4807 return result == null ? 4808 type === "!=" : 4809 !type && Sizzle.attr ? 4810 result != null : 4811 type === "=" ? 4812 value === check : 4813 type === "*=" ? 4814 value.indexOf(check) >= 0 : 4815 type === "~=" ? 4816 (" " + value + " ").indexOf(check) >= 0 : 4817 !check ? 4818 value && result !== false : 4819 type === "!=" ? 4820 value !== check : 4821 type === "^=" ? 4822 value.indexOf(check) === 0 : 4823 type === "$=" ? 4824 value.substr(value.length - check.length) === check : 4825 type === "|=" ? 4826 value === check || value.substr(0, check.length + 1) === check + "-" : 4827 false; 4828 }, 4829 4830 POS: function( elem, match, i, array ) { 4831 var name = match[2], 4832 filter = Expr.setFilters[ name ]; 4833 4834 if ( filter ) { 4835 return filter( elem, i, match, array ); 4836 } 4837 } 4838 } 4839}; 4840 4841var origPOS = Expr.match.POS, 4842 fescape = function(all, num){ 4843 return "\\" + (num - 0 + 1); 4844 }; 4845 4846for ( var type in Expr.match ) { 4847 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); 4848 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); 4849} 4850// Expose origPOS 4851// "global" as in regardless of relation to brackets/parens 4852Expr.match.globalPOS = origPOS; 4853 4854var makeArray = function( array, results ) { 4855 array = Array.prototype.slice.call( array, 0 ); 4856 4857 if ( results ) { 4858 results.push.apply( results, array ); 4859 return results; 4860 } 4861 4862 return array; 4863}; 4864 4865// Perform a simple check to determine if the browser is capable of 4866// converting a NodeList to an array using builtin methods. 4867// Also verifies that the returned array holds DOM nodes 4868// (which is not the case in the Blackberry browser) 4869try { 4870 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; 4871 4872// Provide a fallback method if it does not work 4873} catch( e ) { 4874 makeArray = function( array, results ) { 4875 var i = 0, 4876 ret = results || []; 4877 4878 if ( toString.call(array) === "[object Array]" ) { 4879 Array.prototype.push.apply( ret, array ); 4880 4881 } else { 4882 if ( typeof array.length === "number" ) { 4883 for ( var l = array.length; i < l; i++ ) {
4884 ret.push( array[i] ); 4885 } 4886 4887 } else { 4888 for ( ; array[i]; i++ ) { 4889 ret.push( array[i] ); 4890 } 4891 } 4892 } 4893 4894 return ret; 4895 }; 4896} 4897 4898var sortOrder, siblingCheck; 4899 4900if ( document.documentElement.compareDocumentPosition ) { 4901 sortOrder = function( a, b ) { 4902 if ( a === b ) { 4903 hasDuplicate = true; 4904 return 0; 4905 } 4906 4907 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { 4908 return a.compareDocumentPosition ? -1 : 1; 4909 } 4910 4911 return a.compareDocumentPosition(b) & 4 ? -1 : 1; 4912 }; 4913 4914} else { 4915 sortOrder = function( a, b ) { 4916 // The nodes are identical, we can exit early 4917 if ( a === b ) { 4918 hasDuplicate = true; 4919 return 0; 4920 4921 // Fallback to using sourceIndex (in IE) if it's available on both nodes 4922 } else if ( a.sourceIndex && b.sourceIndex ) { 4923 return a.sourceIndex - b.sourceIndex; 4924 } 4925 4926 var al, bl, 4927 ap = [], 4928 bp = [], 4929 aup = a.parentNode, 4930 bup = b.parentNode, 4931 cur = aup; 4932 4933 // If the nodes are siblings (or identical) we can do a quick check 4934 if ( aup === bup ) { 4935 return siblingCheck( a, b ); 4936 4937 // If no parents were found then the nodes are disconnected 4938 } else if ( !aup ) { 4939 return -1; 4940 4941 } else if ( !bup ) { 4942 return 1; 4943 } 4944 4945 // Otherwise they're somewhere else in the tree so we need 4946 // to build up a full list of the parentNodes for comparison 4947 while ( cur ) { 4948 ap.unshift( cur ); 4949 cur = cur.parentNode; 4950 } 4951 4952 cur = bup; 4953 4954 while ( cur ) { 4955 bp.unshift( cur ); 4956 cur = cur.parentNode; 4957 } 4958 4959 al = ap.length; 4960 bl = bp.length; 4961 4962 // Start walking down the tree looking for a discrepancy 4963 for ( var i = 0; i < al && i < bl; i++ ) { 4964 if ( ap[i] !== bp[i] ) { 4965 return siblingCheck( ap[i], bp[i] ); 4966 } 4967 } 4968 4969 // We ended someplace up the tree so do a sibling check 4970 return i === al ? 4971 siblingCheck( a, bp[i], -1 ) : 4972 siblingCheck( ap[i], b, 1 ); 4973 }; 4974 4975 siblingCheck = function( a, b, ret ) { 4976 if ( a === b ) { 4977 return ret; 4978 } 4979 4980 var cur = a.nextSibling; 4981 4982 while ( cur ) { 4983 if ( cur === b ) { 4984 return -1; 4985 } 4986 4987 cur = cur.nextSibling; 4988 } 4989 4990 return 1; 4991 }; 4992} 4993 4994// Check to see if the browser returns elements by name when 4995// querying by getElementById (and provide a workaround) 4996(function(){ 4997 // We're going to inject a fake input element with a specified name 4998 var form = document.createElement("div"), 4999 id = "script" + (new Date()).getTime(), 5000 root = document.documentElement; 5001 5002 form.innerHTML = "<a name='" + id + "'/>"; 5003 5004 // Inject it into the root element, check its status, and remove it quickly 5005 root.insertBefore( form, root.firstChild ); 5006 5007 // The workaround has to do additional checks after a getElementById 5008 // Which slows things down for other browsers (hence the branching) 5009 if ( document.getElementById( id ) ) { 5010 Expr.find.ID = function( match, context, isXML ) { 5011 if ( typeof context.getElementById !== "undefined" && !isXML ) { 5012 var m = context.getElementById(match[1]); 5013 5014 return m ? 5015 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? 5016 [m] : 5017 undefined : 5018 []; 5019 } 5020 }; 5021 5022 Expr.filter.ID = function( elem, match ) { 5023 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 5024 5025 return elem.nodeType === 1 && node && node.nodeValue === match; 5026 }; 5027 } 5028 5029 root.removeChild( form ); 5030 5031 // release memory in IE 5032 root = form = null; 5033})(); 5034 5035(function(){ 5036 // Check to see if the browser returns only elements 5037 // when doing getElementsByTagName("*") 5038 5039 // Create a fake element 5040 var div = document.createElement("div"); 5041 div.appendChild( document.createComment("") ); 5042 5043 // Make sure no comments are found 5044 if ( div.getElementsByTagName("*").length > 0 ) { 5045 Expr.find.TAG = function( match, context ) { 5046 var results = context.getElementsByTagName( match[1] ); 5047 5048 // Filter out possible comments 5049 if ( match[1] === "*" ) { 5050 var tmp = []; 5051 5052 for ( var i = 0; results[i]; i++ ) { 5053 if ( results[i].nodeType === 1 ) { 5054 tmp.push( results[i] ); 5055 } 5056 } 5057 5058 results = tmp; 5059 } 5060 5061 return results; 5062 }; 5063 } 5064 5065 // Check to see if an attribute returns normalized href attributes 5066 div.innerHTML = "<a href='#'></a>"; 5067 5068 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && 5069 div.firstChild.getAttribute("href") !== "#" ) { 5070 5071 Expr.attrHandle.href = function( elem ) { 5072 return elem.getAttribute( "href", 2 ); 5073 }; 5074 } 5075 5076 // release memory in IE 5077 div = null; 5078})(); 5079 5080if ( document.querySelectorAll ) { 5081 (function(){
5082 var oldSizzle = Sizzle, 5083 div = document.createElement("div"), 5084 id = "__sizzle__"; 5085 5086 div.innerHTML = "<p class='TEST'></p>"; 5087 5088 // Safari can't handle uppercase or unicode characters when 5089 // in quirks mode. 5090 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 5091 return; 5092 } 5093 5094 Sizzle = function( query, context, extra, seed ) { 5095 context = context || document; 5096 5097 // Only use querySelectorAll on non-XML documents 5098 // (ID selectors don't work in non-HTML documents) 5099 if ( !seed && !Sizzle.isXML(context) ) { 5100 // See if we find a selector to speed up 5101 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); 5102 5103 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { 5104 // Speed-up: Sizzle("TAG") 5105 if ( match[1] ) { 5106 return makeArray( context.getElementsByTagName( query ), extra ); 5107 5108 // Speed-up: Sizzle(".CLASS") 5109 } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { 5110 return makeArray( context.getElementsByClassName( match[2] ), extra ); 5111 } 5112 } 5113 5114 if ( context.nodeType === 9 ) { 5115 // Speed-up: Sizzle("body") 5116 // The body element only exists once, optimize finding it 5117 if ( query === "body" && context.body ) { 5118 return makeArray( [ context.body ], extra ); 5119 5120 // Speed-up: Sizzle("#ID") 5121 } else if ( match && match[3] ) { 5122 var elem = context.getElementById( match[3] ); 5123 5124 // Check parentNode to catch when Blackberry 4.6 returns 5125 // nodes that are no longer in the document #6963 5126 if ( elem && elem.parentNode ) { 5127 // Handle the case where IE and Opera return items 5128 // by name instead of ID 5129 if ( elem.id === match[3] ) { 5130 return makeArray( [ elem ], extra ); 5131 } 5132 5133 } else { 5134 return makeArray( [], extra ); 5135 } 5136 } 5137 5138 try { 5139 return makeArray( context.querySelectorAll(query), extra ); 5140 } catch(qsaError) {} 5141 5142 // qSA works strangely on Element-rooted queries 5143 // We can work around this by specifying an extra ID on the root 5144 // and working up from there (Thanks to Andrew Dupont for the technique) 5145 // IE 8 doesn't work on object elements 5146 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 5147 var oldContext = context, 5148 old = context.getAttribute( "id" ), 5149 nid = old || id, 5150 hasParent = context.parentNode, 5151 relativeHierarchySelector = /^\s*[+~]/.test( query ); 5152 5153 if ( !old ) { 5154 context.setAttribute( "id", nid ); 5155 } else { 5156 nid = nid.replace( /'/g, "\\$&" ); 5157 } 5158 if ( relativeHierarchySelector && hasParent ) { 5159 context = context.parentNode; 5160 } 5161 5162 try { 5163 if ( !relativeHierarchySelector || hasParent ) { 5164 return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); 5165 } 5166 5167 } catch(pseudoError) { 5168 } finally { 5169 if ( !old ) { 5170 oldContext.removeAttribute( "id" ); 5171 } 5172 } 5173 } 5174 } 5175 5176 return oldSizzle(query, context, extra, seed); 5177 }; 5178 5179 for ( var prop in oldSizzle ) { 5180 Sizzle[ prop ] = oldSizzle[ prop ]; 5181 } 5182 5183 // release memory in IE 5184 div = null; 5185 })(); 5186} 5187 5188(function(){ 5189 var html = document.documentElement, 5190 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; 5191 5192 if ( matches ) { 5193 // Check to see if it's possible to do matchesSelector 5194 // on a disconnected node (IE 9 fails this) 5195 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), 5196 pseudoWorks = false; 5197 5198 try { 5199 // This should fail with an exception 5200 // Gecko does not error, returns false instead
5201 matches.call( document.documentElement, "[test!='']:sizzle" ); 5202 5203 } catch( pseudoError ) { 5204 pseudoWorks = true; 5205 } 5206 5207 Sizzle.matchesSelector = function( node, expr ) { 5208 // Make sure that attribute selectors are quoted 5209 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); 5210 5211 if ( !Sizzle.isXML( node ) ) { 5212 try { 5213 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { 5214 var ret = matches.call( node, expr ); 5215 5216 // IE 9's matchesSelector returns false on disconnected nodes 5217 if ( ret || !disconnectedMatch || 5218 // As well, disconnected nodes are said to be in a document 5219 // fragment in IE 9, so check for that 5220 node.document && node.document.nodeType !== 11 ) { 5221 return ret; 5222 } 5223 } 5224 } catch(e) {} 5225 } 5226 5227 return Sizzle(expr, null, null, [node]).length > 0; 5228 }; 5229 } 5230})(); 5231 5232(function(){ 5233 var div = document.createElement("div"); 5234 5235 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; 5236 5237 // Opera can't find a second classname (in 9.6) 5238 // Also, make sure that getElementsByClassName actually exists 5239 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { 5240 return; 5241 } 5242 5243 // Safari caches class attributes, doesn't catch changes (in 3.2) 5244 div.lastChild.className = "e"; 5245 5246 if ( div.getElementsByClassName("e").length === 1 ) { 5247 return; 5248 } 5249 5250 Expr.order.splice(1, 0, "CLASS"); 5251 Expr.find.CLASS = function( match, context, isXML ) { 5252 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { 5253 return context.getElementsByClassName(match[1]); 5254 } 5255 }; 5256 5257 // release memory in IE 5258 div = null; 5259})(); 5260 5261function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 5262 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 5263 var elem = checkSet[i]; 5264 5265 if ( elem ) { 5266 var match = false; 5267 5268 elem = elem[dir]; 5269 5270 while ( elem ) { 5271 if ( elem[ expando ] === doneName ) { 5272 match = checkSet[elem.sizset]; 5273 break; 5274 } 5275 5276 if ( elem.nodeType === 1 && !isXML ){ 5277 elem[ expando ] = doneName; 5278 elem.sizset = i; 5279 } 5280 5281 if ( elem.nodeName.toLowerCase() === cur ) { 5282 match = elem; 5283 break; 5284 } 5285 5286 elem = elem[dir]; 5287 } 5288 5289 checkSet[i] = match; 5290 } 5291 } 5292} 5293 5294function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { 5295 for ( var i = 0, l = checkSet.length; i < l; i++ ) { 5296 var elem = checkSet[i]; 5297 5298 if ( elem ) { 5299 var match = false; 5300 5301 elem = elem[dir]; 5302 5303 while ( elem ) { 5304 if ( elem[ expando ] === doneName ) { 5305 match = checkSet[elem.sizset]; 5306 break; 5307 } 5308 5309 if ( elem.nodeType === 1 ) { 5310 if ( !isXML ) { 5311 elem[ expando ] = doneName; 5312 elem.sizset = i; 5313 } 5314 5315 if ( typeof cur !== "string" ) { 5316 if ( elem === cur ) { 5317 match = true; 5318 break; 5319 } 5320 5321 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { 5322 match = elem; 5323 break; 5324 } 5325 } 5326 5327 elem = elem[dir]; 5328 } 5329 5330 checkSet[i] = match; 5331 } 5332 } 5333} 5334 5335if ( document.documentElement.contains ) { 5336 Sizzle.contains = function( a, b ) { 5337 return a !== b && (a.contains ? a.contains(b) : true); 5338 }; 5339 5340} else if ( document.documentElement.compareDocumentPosition ) { 5341 Sizzle.contains = function( a, b ) { 5342 return !!(a.compareDocumentPosition(b) & 16); 5343 }; 5344 5345} else { 5346 Sizzle.contains = function() { 5347 return false; 5348 }; 5349} 5350 5351Sizzle.isXML = function( elem ) { 5352 // documentElement is verified for cases where it doesn't yet exist 5353 // (such as loading iframes in IE - #4833) 5354 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; 5355 5356 return documentElement ? documentElement.nodeName !== "HTML" : false; 5357}; 5358 5359var posProcess = function( selector, context, seed ) { 5360 var match, 5361 tmpSet = [], 5362 later = "", 5363 root = context.nodeType ? [context] : context; 5364 5365 // Position selectors must be done after the filter 5366 // And so must :not(positional) so we move all PSEUDOs to the end 5367 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { 5368 later += match[0]; 5369 selector = selector.replace( Expr.match.PSEUDO, "" ); 5370 } 5371 5372 selector = Expr.relative[selector] ? selector + "*" : selector; 5373 5374 for ( var i = 0, l = root.length; i < l; i++ ) { 5375 Sizzle( selector, root[i], tmpSet, seed ); 5376 } 5377 5378 return Sizzle.filter( later, tmpSet ); 5379}; 5380 5381// EXPOSE 5382// Override sizzle attribute retrieval 5383Sizzle.attr = jQuery.attr; 5384Sizzle.selectors.attrMap = {}; 5385jQuery.find = Sizzle; 5386jQuery.expr = Sizzle.selectors; 5387jQuery.expr[":"] = jQuery.expr.filters; 5388jQuery.unique = Sizzle.uniqueSort; 5389jQuery.text = Sizzle.getText; 5390jQuery.isXMLDoc = Sizzle.isXML; 5391jQuery.contains = Sizzle.contains; 5392 5393 5394})(); 5395 5396 5397var runtil = /Until$/, 5398 rparentsprev = /^(?:parents|prevUntil|prevAll)/, 5399 // Note: This RegExp should be improved, or likely pulled from Sizzle 5400 rmultiselector = /,/, 5401 isSimple = /^.[^:#\[\.,]*$/, 5402 slice = Array.prototype.slice, 5403 POS = jQuery.expr.match.globalPOS, 5404 // methods guaranteed to produce a unique set when starting from a unique set 5405 guaranteedUnique = { 5406 children: true, 5407 contents: true, 5408 next: true, 5409 prev: true 5410 }; 5411 5412jQuery.fn.extend({ 5413 find: function( selector ) { 5414 var self = this, 5415 i, l; 5416 5417 if ( typeof selector !== "string" ) {
5418 return jQuery( selector ).filter(function() { 5419 for ( i = 0, l = self.length; i < l; i++ ) { 5420 if ( jQuery.contains( self[ i ], this ) ) { 5421 return true; 5422 } 5423 } 5424 }); 5425 } 5426 5427 var ret = this.pushStack( "", "find", selector ), 5428 length, n, r; 5429 5430 for ( i = 0, l = this.length; i < l; i++ ) { 5431 length = ret.length; 5432 jQuery.find( selector, this[i], ret ); 5433 5434 if ( i > 0 ) { 5435 // Make sure that the results are unique 5436 for ( n = length; n < ret.length; n++ ) { 5437 for ( r = 0; r < length; r++ ) { 5438 if ( ret[r] === ret[n] ) { 5439 ret.splice(n--, 1); 5440 break; 5441 } 5442 } 5443 } 5444 } 5445 } 5446 5447 return ret; 5448 }, 5449 5450 has: function( target ) { 5451 var targets = jQuery( target ); 5452 return this.filter(function() { 5453 for ( var i = 0, l = targets.length; i < l; i++ ) { 5454 if ( jQuery.contains( this, targets[i] ) ) { 5455 return true; 5456 } 5457 } 5458 }); 5459 }, 5460 5461 not: function( selector ) { 5462 return this.pushStack( winnow(this, selector, false), "not", selector); 5463 }, 5464 5465 filter: function( selector ) { 5466 return this.pushStack( winnow(this, selector, true), "filter", selector ); 5467 }, 5468 5469 is: function( selector ) { 5470 return !!selector && ( 5471 typeof selector === "string" ? 5472 // If this is a positional selector, check membership in the returned set 5473 // so $("p:first").is("p:last") won't return true for a doc with two "p". 5474 POS.test( selector ) ? 5475 jQuery( selector, this.context ).index( this[0] ) >= 0 : 5476 jQuery.filter( selector, this ).length > 0 : 5477 this.filter( selector ).length > 0 ); 5478 }, 5479 5480 closest: function( selectors, context ) { 5481 var ret = [], i, l, cur = this[0]; 5482 5483 // Array (deprecated as of jQuery 1.7) 5484 if ( jQuery.isArray( selectors ) ) { 5485 var level = 1; 5486 5487 while ( cur && cur.ownerDocument && cur !== context ) { 5488 for ( i = 0; i < selectors.length; i++ ) { 5489 5490 if ( jQuery( cur ).is( selectors[ i ] ) ) { 5491 ret.push({ selector: selectors[ i ], elem: cur, level: level }); 5492 } 5493 } 5494 5495 cur = cur.parentNode; 5496 level++; 5497 } 5498 5499 return ret; 5500 } 5501 5502 // String 5503 var pos = POS.test( selectors ) || typeof selectors !== "string" ? 5504 jQuery( selectors, context || this.context ) : 5505 0; 5506 5507 for ( i = 0, l = this.length; i < l; i++ ) { 5508 cur = this[i]; 5509 5510 while ( cur ) { 5511 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { 5512 ret.push( cur ); 5513 break; 5514 5515 } else { 5516 cur = cur.parentNode; 5517 if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { 5518 break; 5519 } 5520 } 5521 } 5522 } 5523 5524 ret = ret.length > 1 ? jQuery.unique( ret ) : ret; 5525 5526 return this.pushStack( ret, "closest", selectors ); 5527 }, 5528 5529 // Determine the position of an element within 5530 // the matched set of elements 5531 index: function( elem ) { 5532 5533 // No argument, return index in parent 5534 if ( !elem ) { 5535 return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; 5536 } 5537 5538 // index in selector 5539 if ( typeof elem === "string" ) { 5540 return jQuery.inArray( this[0], jQuery( elem ) ); 5541 } 5542 5543 // Locate the position of the desired element 5544 return jQuery.inArray( 5545 // If it receives a jQuery object, the first element is used 5546 elem.jquery ? elem[0] : elem, this ); 5547 }, 5548 5549 add: function( selector, context ) { 5550 var set = typeof selector === "string" ? 5551 jQuery( selector, context ) : 5552 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), 5553 all = jQuery.merge( this.get(), set ); 5554 5555 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? 5556 all : 5557 jQuery.unique( all ) ); 5558 }, 5559 5560 andSelf: function() { 5561 return this.add( this.prevObject ); 5562 } 5563}); 5564 5565// A painfully simple check to see if an element is disconnected 5566// from a document (should be improved, where feasible). 5567function isDisconnected( node ) { 5568 return !node || !node.parentNode || node.parentNode.nodeType === 11; 5569} 5570 5571jQuery.each({ 5572 parent: function( elem ) { 5573 var parent = elem.parentNode; 5574 return parent && parent.nodeType !== 11 ? parent : null; 5575 }, 5576 parents: function( elem ) { 5577 return jQuery.dir( elem, "parentNode" ); 5578 }, 5579 parentsUntil: function( elem, i, until ) { 5580 return jQuery.dir( elem, "parentNode", until ); 5581 }, 5582 next: function( elem ) { 5583 return jQuery.nth( elem, 2, "nextSibling" ); 5584 }, 5585 prev: function( elem ) { 5586 return jQuery.nth( elem, 2, "previousSibling" ); 5587 }, 5588 nextAll: function( elem ) { 5589 return jQuery.dir( elem, "nextSibling" ); 5590 }, 5591 prevAll: function( elem ) { 5592 return jQuery.dir( elem, "previousSibling" ); 5593 }, 5594 nextUntil: function( elem, i, until ) { 5595 return jQuery.dir( elem, "nextSibling", until ); 5596 }, 5597 prevUntil: function( elem, i, until ) { 5598 return jQuery.dir( elem, "previousSibling", until ); 5599 }, 5600 siblings: function( elem ) { 5601 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); 5602 }, 5603 children: function( elem ) { 5604 return jQuery.sibling( elem.firstChild ); 5605 }, 5606 contents: function( elem ) { 5607 return jQuery.nodeName( elem, "iframe" ) ? 5608 elem.contentDocument || elem.contentWindow.document : 5609 jQuery.makeArray( elem.childNodes ); 5610 } 5611}, function( name, fn ) { 5612 jQuery.fn[ name ] = function( until, selector ) { 5613 var ret = jQuery.map( this, fn, until ); 5614 5615 if ( !runtil.test( name ) ) { 5616 selector = until; 5617 } 5618 5619 if ( selector && typeof selector === "string" ) { 5620 ret = jQuery.filter( selector, ret ); 5621 } 5622 5623 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; 5624 5625 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { 5626 ret = ret.reverse(); 5627 } 5628 5629 return this.pushStack( ret, name, slice.call( arguments ).join(",") ); 5630 }; 5631}); 5632 5633jQuery.extend({ 5634 filter: function( expr, elems, not ) { 5635 if ( not ) { 5636 expr = ":not(" + expr + ")"; 5637 } 5638 5639 return elems.length === 1 ? 5640 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : 5641 jQuery.find.matches(expr, elems); 5642 }, 5643 5644 dir: function( elem, dir, until ) { 5645 var matched = [], 5646 cur = elem[ dir ]; 5647 5648 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { 5649 if ( cur.nodeType === 1 ) { 5650 matched.push( cur ); 5651 } 5652 cur = cur[dir]; 5653 } 5654 return matched; 5655 }, 5656 5657 nth: function( cur, result, dir, elem ) { 5658 result = result || 1; 5659 var num = 0; 5660 5661 for ( ; cur; cur = cur[dir] ) { 5662 if ( cur.nodeType === 1 && ++num === result ) { 5663 break; 5664 } 5665 } 5666 5667 return cur; 5668 }, 5669 5670 sibling: function( n, elem ) { 5671 var r = []; 5672 5673 for ( ; n; n = n.nextSibling ) { 5674 if ( n.nodeType === 1 && n !== elem ) { 5675 r.push( n ); 5676 } 5677 } 5678 5679 return r; 5680 } 5681}); 5682 5683// Implement the identical functionality for filter and not 5684function winnow( elements, qualifier, keep ) { 5685 5686 // Can't pass null or undefined to indexOf in Firefox 4 5687 // Set to 0 to skip string check 5688 qualifier = qualifier || 0; 5689 5690 if ( jQuery.isFunction( qualifier ) ) { 5691 return jQuery.grep(elements, function( elem, i ) { 5692 var retVal = !!qualifier.call( elem, i, elem ); 5693 return retVal === keep; 5694 }); 5695 5696 } else if ( qualifier.nodeType ) { 5697 return jQuery.grep(elements, function( elem, i ) { 5698 return ( elem === qualifier ) === keep; 5699 }); 5700 5701 } else if ( typeof qualifier === "string" ) { 5702 var filtered = jQuery.grep(elements, function( elem ) { 5703 return elem.nodeType === 1; 5704 }); 5705 5706 if ( isSimple.test( qualifier ) ) { 5707 return jQuery.filter(qualifier, filtered, !keep); 5708 } else { 5709 qualifier = jQuery.filter( qualifier, filtered ); 5710 } 5711 } 5712 5713 return jQuery.grep(elements, function( elem, i ) { 5714 return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; 5715 }); 5716} 5717 5718 5719 5720 5721function createSafeFragment( document ) { 5722 var list = nodeNames.split( "|" ),
vendor: 3,444 bytes, lines 5723-5852
5723 safeFrag = document.createDocumentFragment(); 5724 5725 if ( safeFrag.createElement ) { 5726 while ( list.length ) { 5727 safeFrag.createElement( 5728 list.pop() 5729 ); 5730 } 5731 } 5732 return safeFrag; 5733} 5734 5735var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + 5736 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", 5737 rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, 5738 rleadingWhitespace = /^\s+/, 5739 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 5740 rtagName = /<([\w:]+)/, 5741 rtbody = /<tbody/i, 5742 rhtml = /<|&#?\w+;/, 5743 rnoInnerhtml = /<(?:script|style)/i, 5744 rnocache = /<(?:script|object|embed|option|style)/i, 5745 rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), 5746 // checked="checked" or checked 5747 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5748 rscriptType = /\/(java|ecma)script/i, 5749 rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/, 5750 wrapMap = { 5751 option: [ 1, "<select multiple='multiple'>", "</select>" ], 5752 legend: [ 1, "<fieldset>", "</fieldset>" ], 5753 thead: [ 1, "<table>", "</table>" ], 5754 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5755 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5756 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], 5757 area: [ 1, "<map>", "</map>" ], 5758 _default: [ 0, "", "" ] 5759 }, 5760 safeFragment = createSafeFragment( document ); 5761 5762wrapMap.optgroup = wrapMap.option; 5763wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5764wrapMap.th = wrapMap.td; 5765 5766// IE can't serialize <link> and <script> tags normally 5767if ( !jQuery.support.htmlSerialize ) { 5768 wrapMap._default = [ 1, "div<div>", "</div>" ]; 5769} 5770 5771jQuery.fn.extend({ 5772 text: function( value ) { 5773 return jQuery.access( this, function( value ) { 5774 return value === undefined ? 5775 jQuery.text( this ) : 5776 this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); 5777 }, null, value, arguments.length ); 5778 }, 5779 5780 wrapAll: function( html ) { 5781 if ( jQuery.isFunction( html ) ) { 5782 return this.each(function(i) { 5783 jQuery(this).wrapAll( html.call(this, i) ); 5784 }); 5785 } 5786 5787 if ( this[0] ) { 5788 // The elements to wrap the target around 5789 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); 5790 5791 if ( this[0].parentNode ) { 5792 wrap.insertBefore( this[0] ); 5793 } 5794 5795 wrap.map(function() { 5796 var elem = this; 5797 5798 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { 5799 elem = elem.firstChild; 5800 } 5801 5802 return elem; 5803 }).append( this ); 5804 } 5805 5806 return this; 5807 }, 5808 5809 wrapInner: function( html ) { 5810 if ( jQuery.isFunction( html ) ) { 5811 return this.each(function(i) { 5812 jQuery(this).wrapInner( html.call(this, i) ); 5813 }); 5814 } 5815 5816 return this.each(function() { 5817 var self = jQuery( this ), 5818 contents = self.contents(); 5819 5820 if ( contents.length ) { 5821 contents.wrapAll( html ); 5822 5823 } else { 5824 self.append( html ); 5825 } 5826 }); 5827 }, 5828 5829 wrap: function( html ) { 5830 var isFunction = jQuery.isFunction( html ); 5831 5832 return this.each(function(i) { 5833 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); 5834 }); 5835 }, 5836 5837 unwrap: function() { 5838 return this.parent().each(function() { 5839 if ( !jQuery.nodeName( this, "body" ) ) { 5840 jQuery( this ).replaceWith( this.childNodes ); 5841 } 5842 }).end(); 5843 }, 5844 5845 append: function() { 5846 return this.domManip(arguments, true, function( elem ) { 5847 if ( this.nodeType === 1 ) { 5848 this.appendChild( elem ); 5849 } 5850 }); 5851 }, 5852
5853 prepend: function() { 5854 return this.domManip(arguments, true, function( elem ) { 5855 if ( this.nodeType === 1 ) { 5856 this.insertBefore( elem, this.firstChild ); 5857 } 5858 }); 5859 }, 5860 5861 before: function() { 5862 if ( this[0] && this[0].parentNode ) { 5863 return this.domManip(arguments, false, function( elem ) { 5864 this.parentNode.insertBefore( elem, this ); 5865 }); 5866 } else if ( arguments.length ) { 5867 var set = jQuery.clean( arguments ); 5868 set.push.apply( set, this.toArray() ); 5869 return this.pushStack( set, "before", arguments ); 5870 } 5871 }, 5872 5873 after: function() { 5874 if ( this[0] && this[0].parentNode ) { 5875 return this.domManip(arguments, false, function( elem ) { 5876 this.parentNode.insertBefore( elem, this.nextSibling ); 5877 }); 5878 } else if ( arguments.length ) { 5879 var set = this.pushStack( this, "after", arguments ); 5880 set.push.apply( set, jQuery.clean(arguments) ); 5881 return set; 5882 } 5883 }, 5884 5885 // keepData is for internal use only--do not document 5886 remove: function( selector, keepData ) { 5887 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5888 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { 5889 if ( !keepData && elem.nodeType === 1 ) { 5890 jQuery.cleanData( elem.getElementsByTagName("*") ); 5891 jQuery.cleanData( [ elem ] ); 5892 } 5893 5894 if ( elem.parentNode ) { 5895 elem.parentNode.removeChild( elem ); 5896 } 5897 } 5898 } 5899 5900 return this; 5901 }, 5902 5903 empty: function() { 5904 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) { 5905 // Remove element nodes and prevent memory leaks 5906 if ( elem.nodeType === 1 ) { 5907 jQuery.cleanData( elem.getElementsByTagName("*") ); 5908 } 5909 5910 // Remove any remaining nodes 5911 while ( elem.firstChild ) { 5912 elem.removeChild( elem.firstChild ); 5913 } 5914 } 5915 5916 return this; 5917 }, 5918 5919 clone: function( dataAndEvents, deepDataAndEvents ) { 5920 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5921 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5922 5923 return this.map( function () { 5924 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5925 }); 5926 }, 5927 5928 html: function( value ) { 5929 return jQuery.access( this, function( value ) { 5930 var elem = this[0] || {}, 5931 i = 0, 5932 l = this.length; 5933 5934 if ( value === undefined ) { 5935 return elem.nodeType === 1 ? 5936 elem.innerHTML.replace( rinlinejQuery, "" ) : 5937 null; 5938 } 5939 5940 5941 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 5942 ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && 5943 !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { 5944 5945 value = value.replace( rxhtmlTag, "<$1></$2>" ); 5946 5947 try { 5948 for (; i < l; i++ ) { 5949 // Remove element nodes and prevent memory leaks 5950 elem = this[i] || {}; 5951 if ( elem.nodeType === 1 ) { 5952 jQuery.cleanData( elem.getElementsByTagName( "*" ) ); 5953 elem.innerHTML = value; 5954 } 5955 } 5956 5957 elem = 0; 5958 5959 // If using innerHTML throws an exception, use the fallback method 5960 } catch(e) {} 5961 } 5962 5963 if ( elem ) { 5964 this.empty().append( value ); 5965 } 5966 }, null, value, arguments.length ); 5967 }, 5968 5969 replaceWith: function( value ) { 5970 if ( this[0] && this[0].parentNode ) { 5971 // Make sure that the elements are removed from the DOM before they are inserted 5972 // this can help fix replacing a parent with child elements 5973 if ( jQuery.isFunction( value ) ) { 5974 return this.each(function(i) { 5975 var self = jQuery(this), old = self.html(); 5976 self.replaceWith( value.call( this, i, old ) ); 5977 }); 5978 } 5979 5980 if ( typeof value !== "string" ) { 5981 value = jQuery( value ).detach(); 5982 } 5983 5984 return this.each(function() { 5985 var next = this.nextSibling, 5986 parent = this.parentNode; 5987 5988 jQuery( this ).remove(); 5989 5990 if ( next ) { 5991 jQuery(next).before( value ); 5992 } else { 5993 jQuery(parent).append( value ); 5994 } 5995 }); 5996 } else { 5997 return this.length ? 5998 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : 5999 this; 6000 } 6001 }, 6002 6003 detach: function( selector ) { 6004 return this.remove( selector, true ); 6005 }, 6006 6007 domManip: function( args, table, callback ) { 6008 var results, first, fragment, parent, 6009 value = args[0], 6010 scripts = []; 6011 6012 // We can't cloneNode fragments that contain checked, in WebKit 6013 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { 6014 return this.each(function() { 6015 jQuery(this).domManip( args, table, callback, true ); 6016 }); 6017 } 6018 6019 if ( jQuery.isFunction(value) ) { 6020 return this.each(function(i) { 6021 var self = jQuery(this); 6022 args[0] = value.call(this, i, table ? self.html() : undefined); 6023 self.domManip( args, table, callback ); 6024 }); 6025 } 6026 6027 if ( this[0] ) { 6028 parent = value && value.parentNode; 6029 6030 // If we're in a fragment, just use that instead of building a new one 6031 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { 6032 results = { fragment: parent }; 6033 6034 } else { 6035 results = jQuery.buildFragment( args, this, scripts ); 6036 } 6037 6038 fragment = results.fragment; 6039 6040 if ( fragment.childNodes.length === 1 ) { 6041 first = fragment = fragment.firstChild; 6042 } else { 6043 first = fragment.firstChild; 6044 } 6045 6046 if ( first ) { 6047 table = table && jQuery.nodeName( first, "tr" ); 6048 6049 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { 6050 callback.call( 6051 table ? 6052 root(this[i], first) : 6053 this[i], 6054 // Make sure that we do not leak memory by inadvertently discarding 6055 // the original fragment (which might have attached data) instead of 6056 // using it; in addition, use the original fragment object for the last 6057 // item instead of first because it can end up being emptied incorrectly 6058 // in certain situations (Bug #8070). 6059 // Fragments from the fragment cache must always be cloned and never used 6060 // in place. 6061 results.cacheable || ( l > 1 && i < lastIndex ) ? 6062 jQuery.clone( fragment, true, true ) : 6063 fragment 6064 ); 6065 } 6066 } 6067 6068 if ( scripts.length ) { 6069 jQuery.each( scripts, function( i, elem ) { 6070 if ( elem.src ) { 6071 jQuery.ajax({ 6072 type: "GET", 6073 global: false, 6074 url: elem.src, 6075 async: false, 6076 dataType: "script" 6077 }); 6078 } else { 6079 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); 6080 } 6081 6082 if ( elem.parentNode ) { 6083 elem.parentNode.removeChild( elem ); 6084 } 6085 }); 6086 } 6087 } 6088 6089 return this; 6090 } 6091}); 6092 6093function root( elem, cur ) { 6094 return jQuery.nodeName(elem, "table") ? 6095 (elem.getElementsByTagName("tbody")[0] || 6096 elem.appendChild(elem.ownerDocument.createElement("tbody"))) : 6097 elem; 6098} 6099 6100function cloneCopyEvent( src, dest ) { 6101
6102 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { 6103 return; 6104 } 6105 6106 var type, i, l, 6107 oldData = jQuery._data( src ), 6108 curData = jQuery._data( dest, oldData ), 6109 events = oldData.events; 6110 6111 if ( events ) { 6112 delete curData.handle; 6113 curData.events = {}; 6114 6115 for ( type in events ) { 6116 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 6117 jQuery.event.add( dest, type, events[ type ][ i ] ); 6118 } 6119 } 6120 } 6121 6122 // make the cloned public data object a copy from the original 6123 if ( curData.data ) { 6124 curData.data = jQuery.extend( {}, curData.data ); 6125 } 6126} 6127 6128function cloneFixAttributes( src, dest ) { 6129 var nodeName; 6130 6131 // We do not need to do anything for non-Elements 6132 if ( dest.nodeType !== 1 ) { 6133 return; 6134 } 6135 6136 // clearAttributes removes the attributes, which we don't want, 6137 // but also removes the attachEvent events, which we *do* want 6138 if ( dest.clearAttributes ) { 6139 dest.clearAttributes(); 6140 } 6141 6142 // mergeAttributes, in contrast, only merges back on the 6143 // original attributes, not the events 6144 if ( dest.mergeAttributes ) { 6145 dest.mergeAttributes( src ); 6146 } 6147 6148 nodeName = dest.nodeName.toLowerCase(); 6149 6150 // IE6-8 fail to clone children inside object elements that use 6151 // the proprietary classid attribute value (rather than the type 6152 // attribute) to identify the type of content to display 6153 if ( nodeName === "object" ) { 6154 dest.outerHTML = src.outerHTML; 6155 6156 } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { 6157 // IE6-8 fails to persist the checked state of a cloned checkbox 6158 // or radio button. Worse, IE6-7 fail to give the cloned element 6159 // a checked appearance if the defaultChecked value isn't also set 6160 if ( src.checked ) { 6161 dest.defaultChecked = dest.checked = src.checked; 6162 } 6163 6164 // IE6-7 get confused and end up setting the value of a cloned 6165 // checkbox/radio button to an empty string instead of "on" 6166 if ( dest.value !== src.value ) { 6167 dest.value = src.value; 6168 } 6169 6170 // IE6-8 fails to return the selected option to the default selected 6171 // state when cloning options 6172 } else if ( nodeName === "option" ) { 6173 dest.selected = src.defaultSelected; 6174 6175 // IE6-8 fails to set the defaultValue to the correct value when 6176 // cloning other types of input fields 6177 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6178 dest.defaultValue = src.defaultValue; 6179 6180 // IE blanks contents when cloning scripts 6181 } else if ( nodeName === "script" && dest.text !== src.text ) { 6182 dest.text = src.text; 6183 } 6184 6185 // Event data gets referenced instead of copied if the expando 6186 // gets copied too 6187 dest.removeAttribute( jQuery.expando ); 6188 6189 // Clear flags for bubbling special change/submit events, they must 6190 // be reattached when the newly cloned events are first activated 6191 dest.removeAttribute( "_submit_attached" ); 6192 dest.removeAttribute( "_change_attached" ); 6193} 6194 6195jQuery.buildFragment = function( args, nodes, scripts ) { 6196 var fragment, cacheable, cacheresults, doc, 6197 first = args[ 0 ]; 6198 6199 // nodes may contain either an explicit document object, 6200 // a jQuery collection or context object. 6201 // If nodes[0] contains a valid object to assign to doc 6202 if ( nodes && nodes[0] ) { 6203 doc = nodes[0].ownerDocument || nodes[0]; 6204 } 6205 6206 // Ensure that an attr object doesn't incorrectly stand in as a document object 6207 // Chrome and Firefox seem to allow this to occur and will throw exception 6208 // Fixes #8950 6209 if ( !doc.createDocumentFragment ) { 6210 doc = document; 6211 } 6212 6213 // Only cache "small" (1/2 KB) HTML strings that are associated with the main document 6214 // Cloning options loses the selected state, so don't cache them 6215 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment 6216 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache 6217 // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 6218 if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && 6219 first.charAt(0) === "<" && !rnocache.test( first ) && 6220 (jQuery.support.checkClone || !rchecked.test( first )) && 6221 (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { 6222 6223 cacheable = true; 6224 6225 cacheresults = jQuery.fragments[ first ]; 6226 if ( cacheresults && cacheresults !== 1 ) { 6227 fragment = cacheresults; 6228 } 6229 } 6230 6231 if ( !fragment ) { 6232 fragment = doc.createDocumentFragment(); 6233 jQuery.clean( args, doc, fragment, scripts ); 6234 } 6235 6236 if ( cacheable ) {
6237 jQuery.fragments[ first ] = cacheresults ? fragment : 1; 6238 } 6239 6240 return { fragment: fragment, cacheable: cacheable }; 6241}; 6242 6243jQuery.fragments = {}; 6244 6245jQuery.each({ 6246 appendTo: "append", 6247 prependTo: "prepend", 6248 insertBefore: "before", 6249 insertAfter: "after", 6250 replaceAll: "replaceWith" 6251}, function( name, original ) { 6252 jQuery.fn[ name ] = function( selector ) { 6253 var ret = [], 6254 insert = jQuery( selector ), 6255 parent = this.length === 1 && this[0].parentNode; 6256 6257 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 6258 insert[ original ]( this[0] ); 6259 return this; 6260 6261 } else { 6262 for ( var i = 0, l = insert.length; i < l; i++ ) { 6263 var elems = ( i > 0 ? this.clone(true) : this ).get(); 6264 jQuery( insert[i] )[ original ]( elems ); 6265 ret = ret.concat( elems ); 6266 } 6267 6268 return this.pushStack( ret, name, insert.selector ); 6269 } 6270 }; 6271}); 6272 6273function getAll( elem ) { 6274 if ( typeof elem.getElementsByTagName !== "undefined" ) { 6275 return elem.getElementsByTagName( "*" ); 6276 6277 } else if ( typeof elem.querySelectorAll !== "undefined" ) { 6278 return elem.querySelectorAll( "*" ); 6279 6280 } else { 6281 return []; 6282 } 6283} 6284 6285// Used in clean, fixes the defaultChecked property 6286function fixDefaultChecked( elem ) { 6287 if ( elem.type === "checkbox" || elem.type === "radio" ) { 6288 elem.defaultChecked = elem.checked; 6289 } 6290} 6291// Finds all inputs and passes them to fixDefaultChecked 6292function findInputs( elem ) { 6293 var nodeName = ( elem.nodeName || "" ).toLowerCase(); 6294 if ( nodeName === "input" ) { 6295 fixDefaultChecked( elem ); 6296 // Skip scripts, get other children 6297 } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) { 6298 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); 6299 } 6300} 6301 6302// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js 6303function shimCloneNode( elem ) { 6304 var div = document.createElement( "div" ); 6305 safeFragment.appendChild( div ); 6306 6307 div.innerHTML = elem.outerHTML; 6308 return div.firstChild; 6309} 6310 6311jQuery.extend({ 6312 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6313 var srcElements, 6314 destElements, 6315 i, 6316 // IE<=8 does not properly clone detached, unknown element nodes 6317 clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ? 6318 elem.cloneNode( true ) : 6319 shimCloneNode( elem ); 6320 6321 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && 6322 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { 6323 // IE copies events bound via attachEvent when using cloneNode. 6324 // Calling detachEvent on the clone will also remove the events 6325 // from the original. In order to get around this, we use some 6326 // proprietary methods to clear the events. Thanks to MooTools 6327 // guys for this hotness. 6328 6329 cloneFixAttributes( elem, clone ); 6330 6331 // Using Sizzle here is crazy slow, so we use getElementsByTagName instead 6332 srcElements = getAll( elem ); 6333 destElements = getAll( clone ); 6334 6335 // Weird iteration because IE will replace the length property 6336 // with an element if you are cloning the body and one of the 6337 // elements on the page has a name or id of "length" 6338 for ( i = 0; srcElements[i]; ++i ) { 6339 // Ensure that the destination node is not null; Fixes #9587 6340 if ( destElements[i] ) { 6341 cloneFixAttributes( srcElements[i], destElements[i] ); 6342 } 6343 } 6344 } 6345 6346 // Copy the events from the original to the clone 6347 if ( dataAndEvents ) { 6348 cloneCopyEvent( elem, clone ); 6349 6350 if ( deepDataAndEvents ) { 6351 srcElements = getAll( elem ); 6352 destElements = getAll( clone ); 6353 6354 for ( i = 0; srcElements[i]; ++i ) { 6355 cloneCopyEvent( srcElements[i], destElements[i] ); 6356 } 6357 } 6358 } 6359 6360 srcElements = destElements = null; 6361 6362 // Return the cloned set 6363 return clone; 6364 }, 6365 6366 clean: function( elems, context, fragment, scripts ) { 6367 var checkScriptType, script, j, 6368 ret = []; 6369 6370 context = context || document; 6371 6372 // !context.createElement fails in IE with an error but returns typeof 'object' 6373 if ( typeof context.createElement === "undefined" ) { 6374 context = context.ownerDocument || context[0] && context[0].ownerDocument || document; 6375 } 6376 6377 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6378 if ( typeof elem === "number" ) { 6379 elem += ""; 6380 } 6381 6382 if ( !elem ) { 6383 continue; 6384 } 6385 6386 // Convert html string into DOM nodes 6387 if ( typeof elem === "string" ) { 6388 if ( !rhtml.test( elem ) ) { 6389 elem = context.createTextNode( elem ); 6390 } else { 6391 // Fix "XHTML"-style tags in all browsers 6392 elem = elem.replace(rxhtmlTag, "<$1></$2>"); 6393 6394 // Trim whitespace, otherwise indexOf won't work as expected 6395 var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(), 6396 wrap = wrapMap[ tag ] || wrapMap._default, 6397 depth = wrap[0], 6398 div = context.createElement("div"), 6399 safeChildNodes = safeFragment.childNodes, 6400 remove; 6401 6402 // Append wrapper element to unknown element safe doc fragment 6403 if ( context === document ) { 6404 // Use the fragment we've already created for this document 6405 safeFragment.appendChild( div ); 6406 } else { 6407 // Use a fragment created with the owner document 6408 createSafeFragment( context ).appendChild( div ); 6409 } 6410 6411 // Go to html and back, then peel off extra wrappers 6412 div.innerHTML = wrap[1] + elem + wrap[2]; 6413 6414 // Move to the right depth 6415 while ( depth-- ) {
6416 div = div.lastChild; 6417 } 6418 6419 // Remove IE's autoinserted <tbody> from table fragments 6420 if ( !jQuery.support.tbody ) { 6421 6422 // String was a <table>, *may* have spurious <tbody> 6423 var hasBody = rtbody.test(elem), 6424 tbody = tag === "table" && !hasBody ? 6425 div.firstChild && div.firstChild.childNodes : 6426 6427 // String was a bare <thead> or <tfoot> 6428 wrap[1] === "<table>" && !hasBody ? 6429 div.childNodes : 6430 []; 6431 6432 for ( j = tbody.length - 1; j >= 0 ; --j ) { 6433 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { 6434 tbody[ j ].parentNode.removeChild( tbody[ j ] ); 6435 } 6436 } 6437 } 6438 6439 // IE completely kills leading whitespace when innerHTML is used 6440 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { 6441 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); 6442 } 6443 6444 elem = div.childNodes; 6445 6446 // Clear elements from DocumentFragment (safeFragment or otherwise) 6447 // to avoid hoarding elements. Fixes #11356 6448 if ( div ) { 6449 div.parentNode.removeChild( div ); 6450 6451 // Guard against -1 index exceptions in FF3.6 6452 if ( safeChildNodes.length > 0 ) { 6453 remove = safeChildNodes[ safeChildNodes.length - 1 ]; 6454 6455 if ( remove && remove.parentNode ) { 6456 remove.parentNode.removeChild( remove ); 6457 } 6458 } 6459 } 6460 } 6461 } 6462 6463 // Resets defaultChecked for any radios and checkboxes 6464 // about to be appended to the DOM in IE 6/7 (#8060) 6465 var len; 6466 if ( !jQuery.support.appendChecked ) { 6467 if ( elem[0] && typeof (len = elem.length) === "number" ) { 6468 for ( j = 0; j < len; j++ ) { 6469 findInputs( elem[j] ); 6470 } 6471 } else { 6472 findInputs( elem ); 6473 } 6474 } 6475 6476 if ( elem.nodeType ) { 6477 ret.push( elem ); 6478 } else { 6479 ret = jQuery.merge( ret, elem ); 6480 } 6481 } 6482 6483 if ( fragment ) { 6484 checkScriptType = function( elem ) { 6485 return !elem.type || rscriptType.test( elem.type ); 6486 }; 6487 for ( i = 0; ret[i]; i++ ) { 6488 script = ret[i]; 6489 if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) { 6490 scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script ); 6491 6492 } else { 6493 if ( script.nodeType === 1 ) { 6494 var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType ); 6495 6496 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); 6497 } 6498 fragment.appendChild( script ); 6499 } 6500 } 6501 } 6502 6503 return ret; 6504 }, 6505 6506 cleanData: function( elems ) { 6507 var data, id, 6508 cache = jQuery.cache, 6509 special = jQuery.event.special, 6510 deleteExpando = jQuery.support.deleteExpando; 6511 6512 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { 6513 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { 6514 continue; 6515 } 6516 6517 id = elem[ jQuery.expando ]; 6518 6519 if ( id ) { 6520 data = cache[ id ]; 6521 6522 if ( data && data.events ) { 6523 for ( var type in data.events ) { 6524 if ( special[ type ] ) { 6525 jQuery.event.remove( elem, type ); 6526 6527 // This is a shortcut to avoid jQuery.event.remove's overhead 6528 } else { 6529 jQuery.removeEvent( elem, type, data.handle ); 6530 } 6531 } 6532 6533 // Null the DOM reference to avoid IE6/7/8 leak (#7054) 6534 if ( data.handle ) { 6535 data.handle.elem = null; 6536 } 6537 } 6538 6539 if ( deleteExpando ) { 6540 delete elem[ jQuery.expando ]; 6541 6542 } else if ( elem.removeAttribute ) { 6543 elem.removeAttribute( jQuery.expando ); 6544 } 6545 6546 delete cache[ id ]; 6547 } 6548 } 6549 } 6550}); 6551 6552 6553 6554 6555var ralpha = /alpha\([^)]*\)/i, 6556 ropacity = /opacity=([^)]*)/, 6557 // fixed for IE9, see #8346 6558 rupper = /([A-Z]|^ms)/g, 6559 rnum = /^[\-+]?(?:\d*\.)?\d+$/i, 6560 rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i, 6561 rrelNum = /^([\-+])=([\-+.\de]+)/, 6562 rmargin = /^margin/, 6563 6564 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6565 6566 // order is important! 6567 cssExpand = [ "Top", "Right", "Bottom", "Left" ], 6568 6569 curCSS, 6570 6571 getComputedStyle, 6572 currentStyle; 6573 6574jQuery.fn.css = function( name, value ) { 6575 return jQuery.access( this, function( elem, name, value ) { 6576 return value !== undefined ? 6577 jQuery.style( elem, name, value ) : 6578 jQuery.css( elem, name ); 6579 }, name, value, arguments.length > 1 ); 6580}; 6581 6582jQuery.extend({ 6583 // Add in style property hooks for overriding the default 6584 // behavior of getting and setting a style property 6585 cssHooks: { 6586 opacity: { 6587 get: function( elem, computed ) { 6588 if ( computed ) { 6589 // We should always get a number back from opacity 6590 var ret = curCSS( elem, "opacity" ); 6591 return ret === "" ? "1" : ret; 6592 6593 } else { 6594 return elem.style.opacity; 6595 } 6596 } 6597 } 6598 }, 6599 6600 // Exclude the following css properties to add px 6601 cssNumber: { 6602 "fillOpacity": true, 6603 "fontWeight": true, 6604 "lineHeight": true, 6605 "opacity": true, 6606 "orphans": true, 6607 "widows": true, 6608 "zIndex": true, 6609 "zoom": true 6610 }, 6611 6612 // Add in properties whose names you wish to fix before 6613 // setting or getting the value 6614 cssProps: { 6615 // normalize float css property 6616 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" 6617 }, 6618 6619 // Get and set the style property on a DOM Node 6620 style: function( elem, name, value, extra ) { 6621 // Don't set styles on text and comment nodes 6622 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6623 return; 6624 } 6625 6626 // Make sure that we're working with the right name 6627 var ret, type, origName = jQuery.camelCase( name ), 6628 style = elem.style, hooks = jQuery.cssHooks[ origName ]; 6629 6630 name = jQuery.cssProps[ origName ] || origName; 6631 6632 // Check if we're setting a value 6633 if ( value !== undefined ) { 6634 type = typeof value; 6635 6636 // convert relative number strings (+= or -=) to relative numbers. #7345 6637 if ( type === "string" && (ret = rrelNum.exec( value )) ) { 6638 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) ); 6639 // Fixes bug #9237 6640 type = "number"; 6641 } 6642 6643 // Make sure that NaN and null values aren't set. See: #7116 6644 if ( value == null || type === "number" && isNaN( value ) ) { 6645 return; 6646 } 6647 6648 // If a number was passed in, add 'px' to the (except for certain CSS properties) 6649 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { 6650 value += "px"; 6651 } 6652 6653 // If a hook was provided, use that value, otherwise just set the specified value 6654 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6655 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided 6656 // Fixes bug #5509 6657 try { 6658 style[ name ] = value; 6659 } catch(e) {} 6660 } 6661 6662 } else { 6663 // If a hook was provided get the non-computed value from there 6664 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 6665 return ret; 6666 } 6667 6668 // Otherwise just get the value from the style object 6669 return style[ name ]; 6670 } 6671 }, 6672 6673 css: function( elem, name, extra ) { 6674 var ret, hooks; 6675 6676 // Make sure that we're working with the right name 6677 name = jQuery.camelCase( name ); 6678 hooks = jQuery.cssHooks[ name ]; 6679 name = jQuery.cssProps[ name ] || name; 6680 6681 // cssFloat needs a special treatment 6682 if ( name === "cssFloat" ) { 6683 name = "float"; 6684 } 6685 6686 // If a hook was provided get the computed value from there 6687 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { 6688 return ret; 6689 6690 // Otherwise, if a way to get the computed value exists, use that 6691 } else if ( curCSS ) { 6692 return curCSS( elem, name ); 6693 } 6694 }, 6695 6696 // A method for quickly swapping in/out CSS properties to get correct calculations 6697 swap: function( elem, options, callback ) { 6698 var old = {}, 6699 ret, name; 6700 6701 // Remember the old values, and insert the new ones 6702 for ( name in options ) { 6703 old[ name ] = elem.style[ name ]; 6704 elem.style[ name ] = options[ name ]; 6705 } 6706 6707 ret = callback.call( elem ); 6708 6709 // Revert the old values 6710 for ( name in options ) { 6711 elem.style[ name ] = old[ name ]; 6712 } 6713 6714 return ret; 6715 } 6716}); 6717 6718// DEPRECATED in 1.3, Use jQuery.css() instead 6719jQuery.curCSS = jQuery.css; 6720 6721if ( document.defaultView && document.defaultView.getComputedStyle ) { 6722 getComputedStyle = function( elem, name ) { 6723 var ret, defaultView, computedStyle, width, 6724 style = elem.style; 6725 6726 name = name.replace( rupper, "-$1" ).toLowerCase(); 6727 6728 if ( (defaultView = elem.ownerDocument.defaultView) && 6729 (computedStyle = defaultView.getComputedStyle( elem, null )) ) { 6730 6731 ret = computedStyle.getPropertyValue( name ); 6732 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { 6733 ret = jQuery.style( elem, name ); 6734 } 6735 } 6736 6737 // A tribute to the "awesome hack by Dean Edwards" 6738 // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins 6739 // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values 6740 if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) { 6741 width = style.width; 6742 style.width = ret; 6743 ret = computedStyle.width; 6744 style.width = width; 6745 } 6746 6747 return ret; 6748 }; 6749} 6750 6751if ( document.documentElement.currentStyle ) { 6752 currentStyle = function( elem, name ) { 6753 var left, rsLeft, uncomputed, 6754 ret = elem.currentStyle && elem.currentStyle[ name ], 6755 style = elem.style; 6756 6757 // Avoid setting ret to empty string here 6758 // so we don't default to auto 6759 if ( ret == null && style && (uncomputed = style[ name ]) ) { 6760 ret = uncomputed; 6761 } 6762 6763 // From the awesome hack by Dean Edwards 6764 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6765 6766 // If we're not dealing with a regular pixel number 6767 // but a number that has a weird ending, we need to convert it to pixels 6768 if ( rnumnonpx.test( ret ) ) { 6769 6770 // Remember the original values 6771 left = style.left; 6772 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; 6773 6774 // Put in the new values to get a computed value out 6775 if ( rsLeft ) { 6776 elem.runtimeStyle.left = elem.currentStyle.left; 6777 } 6778 style.left = name === "fontSize" ? "1em" : ret; 6779 ret = style.pixelLeft + "px"; 6780 6781 // Revert the changed values 6782 style.left = left; 6783 if ( rsLeft ) { 6784 elem.runtimeStyle.left = rsLeft; 6785 } 6786 } 6787 6788 return ret === "" ? "auto" : ret; 6789 }; 6790} 6791 6792curCSS = getComputedStyle || currentStyle; 6793 6794function getWidthOrHeight( elem, name, extra ) { 6795 6796 // Start with offset property 6797 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 6798 i = name === "width" ? 1 : 0, 6799 len = 4; 6800 6801 if ( val > 0 ) { 6802 if ( extra !== "border" ) { 6803 for ( ; i < len; i += 2 ) { 6804 if ( !extra ) { 6805 val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; 6806 } 6807 if ( extra === "margin" ) { 6808 val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; 6809 } else { 6810 val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; 6811 } 6812 } 6813 } 6814 6815 return val + "px"; 6816 } 6817 6818 // Fall back to computed then uncomputed css if necessary 6819 val = curCSS( elem, name ); 6820 if ( val < 0 || val == null ) { 6821 val = elem.style[ name ]; 6822 } 6823 6824 // Computed unit is not pixels. Stop here and return. 6825 if ( rnumnonpx.test(val) ) { 6826 return val; 6827 } 6828 6829 // Normalize "", auto, and prepare for extra 6830 val = parseFloat( val ) || 0; 6831 6832 // Add padding, border, margin 6833 if ( extra ) { 6834 for ( ; i < len; i += 2 ) { 6835 val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; 6836 if ( extra !== "padding" ) { 6837 val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; 6838 } 6839 if ( extra === "margin" ) { 6840 val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0; 6841 } 6842 } 6843 } 6844 6845 return val + "px"; 6846} 6847 6848jQuery.each([ "height", "width" ], function( i, name ) { 6849 jQuery.cssHooks[ name ] = { 6850 get: function( elem, computed, extra ) { 6851 if ( computed ) { 6852 if ( elem.offsetWidth !== 0 ) { 6853 return getWidthOrHeight( elem, name, extra ); 6854 } else { 6855 return jQuery.swap( elem, cssShow, function() { 6856 return getWidthOrHeight( elem, name, extra ); 6857 }); 6858 } 6859 } 6860 }, 6861 6862 set: function( elem, value ) { 6863 return rnum.test( value ) ? 6864 value + "px" : 6865 value; 6866 } 6867 }; 6868}); 6869 6870if ( !jQuery.support.opacity ) { 6871 jQuery.cssHooks.opacity = { 6872 get: function( elem, computed ) { 6873 // IE uses filters for opacity 6874 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? 6875 ( parseFloat( RegExp.$1 ) / 100 ) + "" : 6876 computed ? "1" : ""; 6877 }, 6878 6879 set: function( elem, value ) { 6880 var style = elem.style, 6881 currentStyle = elem.currentStyle, 6882 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", 6883 filter = currentStyle && currentStyle.filter || style.filter || ""; 6884 6885 // IE has trouble with opacity if it does not have layout 6886 // Force it by setting the zoom level 6887 style.zoom = 1; 6888 6889 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 6890 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) { 6891 6892 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText 6893 // if "filter:" is present at all, clearType is disabled, we want to avoid this 6894 // style.removeAttribute is IE Only, but so apparently is this code path... 6895 style.removeAttribute( "filter" ); 6896 6897 // if there there is no filter style applied in a css rule, we are done 6898 if ( currentStyle && !currentStyle.filter ) { 6899 return; 6900 } 6901 } 6902 6903 // otherwise, set new filter values 6904 style.filter = ralpha.test( filter ) ? 6905 filter.replace( ralpha, opacity ) : 6906 filter + " " + opacity; 6907 } 6908 }; 6909} 6910 6911jQuery(function() { 6912 // This hook cannot be added until DOM ready because the support test 6913 // for it is not run until after DOM ready 6914 if ( !jQuery.support.reliableMarginRight ) { 6915 jQuery.cssHooks.marginRight = { 6916 get: function( elem, computed ) { 6917 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 6918 // Work around by temporarily setting element display to inline-block 6919 return jQuery.swap( elem, { "display": "inline-block" }, function() { 6920 if ( computed ) { 6921 return curCSS( elem, "margin-right" ); 6922 } else { 6923 return elem.style.marginRight; 6924 } 6925 }); 6926 } 6927 }; 6928 } 6929}); 6930 6931if ( jQuery.expr && jQuery.expr.filters ) { 6932 jQuery.expr.filters.hidden = function( elem ) { 6933 var width = elem.offsetWidth, 6934 height = elem.offsetHeight; 6935 6936 return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "dis
vendor: 23,952 bytes, lines 6936-7813
6936play" )) === "none"); 6937 }; 6938 6939 jQuery.expr.filters.visible = function( elem ) { 6940 return !jQuery.expr.filters.hidden( elem ); 6941 }; 6942} 6943 6944// These hooks are used by animate to expand properties 6945jQuery.each({ 6946 margin: "", 6947 padding: "", 6948 border: "Width" 6949}, function( prefix, suffix ) { 6950 6951 jQuery.cssHooks[ prefix + suffix ] = { 6952 expand: function( value ) { 6953 var i, 6954 6955 // assumes a single number if not a string 6956 parts = typeof value === "string" ? value.split(" ") : [ value ], 6957 expanded = {}; 6958 6959 for ( i = 0; i < 4; i++ ) { 6960 expanded[ prefix + cssExpand[ i ] + suffix ] = 6961 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6962 } 6963 6964 return expanded; 6965 } 6966 }; 6967}); 6968 6969 6970 6971 6972var r20 = /%20/g, 6973 rbracket = /\[\]$/, 6974 rCRLF = /\r?\n/g, 6975 rhash = /#.*$/, 6976 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL 6977 rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, 6978 // #7653, #8125, #8152: local protocol detection 6979 rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, 6980 rnoContent = /^(?:GET|HEAD)$/, 6981 rprotocol = /^\/\//, 6982 rquery = /\?/, 6983 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 6984 rselectTextarea = /^(?:select|textarea)/i, 6985 rspacesAjax = /\s+/, 6986 rts = /([?&])_=[^&]*/, 6987 rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, 6988 6989 // Keep a copy of the old load method 6990 _load = jQuery.fn.load, 6991 6992 /* Prefilters 6993 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 6994 * 2) These are called: 6995 * - BEFORE asking for a transport 6996 * - AFTER param serialization (s.data is a string if s.processData is true) 6997 * 3) key is the dataType 6998 * 4) the catchall symbol "*" can be used 6999 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 7000 */ 7001 prefilters = {}, 7002 7003 /* Transports bindings 7004 * 1) key is the dataType 7005 * 2) the catchall symbol "*" can be used 7006 * 3) selection will start with transport dataType and THEN go to "*" if needed 7007 */ 7008 transports = {}, 7009 7010 // Document location 7011 ajaxLocation, 7012 7013 // Document location segments 7014 ajaxLocParts, 7015 7016 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 7017 allTypes = ["*/"] + ["*"]; 7018 7019// #8138, IE may throw an exception when accessing 7020// a field from window.location if document.domain has been set 7021try { 7022 ajaxLocation = location.href; 7023} catch( e ) { 7024 // Use the href attribute of an A element 7025 // since IE will modify it given document.location 7026 ajaxLocation = document.createElement( "a" ); 7027 ajaxLocation.href = ""; 7028 ajaxLocation = ajaxLocation.href; 7029} 7030 7031// Segment location into parts 7032ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 7033 7034// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 7035function addToPrefiltersOrTransports( structure ) { 7036 7037 // dataTypeExpression is optional and defaults to "*" 7038 return function( dataTypeExpression, func ) { 7039 7040 if ( typeof dataTypeExpression !== "string" ) { 7041 func = dataTypeExpression; 7042 dataTypeExpression = "*"; 7043 } 7044 7045 if ( jQuery.isFunction( func ) ) { 7046 var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), 7047 i = 0, 7048 length = dataTypes.length, 7049 dataType, 7050 list, 7051 placeBefore; 7052 7053 // For each dataType in the dataTypeExpression 7054 for ( ; i < length; i++ ) { 7055 dataType = dataTypes[ i ]; 7056 // We control if we're asked to add before 7057 // any existing element 7058 placeBefore = /^\+/.test( dataType ); 7059 if ( placeBefore ) { 7060 dataType = dataType.substr( 1 ) || "*"; 7061 } 7062 list = structure[ dataType ] = structure[ dataType ] || []; 7063 // then we add to the structure accordingly 7064 list[ placeBefore ? "unshift" : "push" ]( func ); 7065 } 7066 } 7067 }; 7068} 7069 7070// Base inspection function for prefilters and transports 7071function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, 7072 dataType /* internal */, inspected /* internal */ ) { 7073 7074 dataType = dataType || options.dataTypes[ 0 ]; 7075 inspected = inspected || {}; 7076 7077 inspected[ dataType ] = true; 7078 7079 var list = structure[ dataType ], 7080 i = 0, 7081 length = list ? list.length : 0, 7082 executeOnly = ( structure === prefilters ), 7083 selection; 7084 7085 for ( ; i < length && ( executeOnly || !selection ); i++ ) { 7086 selection = list[ i ]( options, originalOptions, jqXHR ); 7087 // If we got redirected to another dataType 7088 // we try there if executing only and not done already 7089 if ( typeof selection === "string" ) { 7090 if ( !executeOnly || inspected[ selection ] ) { 7091 selection = undefined; 7092 } else { 7093 options.dataTypes.unshift( selection ); 7094 selection = inspectPrefiltersOrTransports( 7095 structure, options, originalOptions, jqXHR, selection, inspected ); 7096 } 7097 } 7098 } 7099 // If we're only executing or nothing was selected 7100 // we try the catchall dataType if not done already 7101 if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { 7102 selection = inspectPrefiltersOrTransports( 7103 structure, options, originalOptions, jqXHR, "*", inspected ); 7104 } 7105 // unnecessary when only executing (prefilters) 7106 // but it'll be ignored by the caller in that case 7107 return selection; 7108} 7109 7110// A special extend for ajax options 7111// that takes "flat" options (not to be deep extended) 7112// Fixes #9887 7113function ajaxExtend( target, src ) { 7114 var key, deep, 7115 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 7116 for ( key in src ) { 7117 if ( src[ key ] !== undefined ) { 7118 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 7119 } 7120 } 7121 if ( deep ) { 7122 jQuery.extend( true, target, deep ); 7123 } 7124} 7125 7126jQuery.fn.extend({ 7127 load: function( url, params, callback ) { 7128 if ( typeof url !== "string" && _load ) { 7129 return _load.apply( this, arguments ); 7130 7131 // Don't do a request if no elements are being requested 7132 } else if ( !this.length ) { 7133 return this; 7134 } 7135 7136 var off = url.indexOf( " " ); 7137 if ( off >= 0 ) { 7138 var selector = url.slice( off, url.length ); 7139 url = url.slice( 0, off ); 7140 } 7141 7142 // Default to a GET request 7143 var type = "GET"; 7144 7145 // If the second parameter was provided 7146 if ( params ) { 7147 // If it's a function 7148 if ( jQuery.isFunction( params ) ) { 7149 // We assume that it's the callback 7150 callback = params; 7151 params = undefined; 7152 7153 // Otherwise, build a param string 7154 } else if ( typeof params === "object" ) { 7155 params = jQuery.param( params, jQuery.ajaxSettings.traditional ); 7156 type = "POST"; 7157 } 7158 } 7159 7160 var self = this; 7161 7162 // Request the remote document 7163 jQuery.ajax({ 7164 url: url, 7165 type: type, 7166 dataType: "html", 7167 data: params, 7168 // Complete callback (responseText is used internally) 7169 complete: function( jqXHR, status, responseText ) { 7170 // Store the response as specified by the jqXHR object 7171 responseText = jqXHR.responseText; 7172 // If successful, inject the HTML into all the matched elements 7173 if ( jqXHR.isResolved() ) { 7174 // #4825: Get the actual response in case 7175 // a dataFilter is present in ajaxSettings 7176 jqXHR.done(function( r ) { 7177 responseText = r; 7178 }); 7179 // See if a selector was specified 7180 self.html( selector ? 7181 // Create a dummy div to hold the results 7182 jQuery("<div>") 7183 // inject the contents of the document in, removing the scripts 7184 // to avoid any 'Permission Denied' errors in IE 7185 .append(responseText.replace(rscript, "")) 7186 7187 // Locate the specified elements 7188 .find(selector) : 7189 7190 // If not, just inject the full result 7191 responseText ); 7192 } 7193 7194 if ( callback ) { 7195 self.each( callback, [ responseText, status, jqXHR ] ); 7196 } 7197 } 7198 }); 7199 7200 return this; 7201 }, 7202 7203 serialize: function() { 7204 return jQuery.param( this.serializeArray() ); 7205 }, 7206 7207 serializeArray: function() { 7208 return this.map(function(){ 7209 return this.elements ? jQuery.makeArray( this.elements ) : this; 7210 }) 7211 .filter(function(){ 7212 return this.name && !this.disabled && 7213 ( this.checked || rselectTextarea.test( this.nodeName ) || 7214 rinput.test( this.type ) ); 7215 }) 7216 .map(function( i, elem ){ 7217 var val = jQuery( this ).val(); 7218 7219 return val == null ? 7220 null : 7221 jQuery.isArray( val ) ? 7222 jQuery.map( val, function( val, i ){ 7223 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7224 }) : 7225 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 7226 }).get(); 7227 } 7228}); 7229 7230// Attach a bunch of functions for handling common AJAX events 7231jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ 7232 jQuery.fn[ o ] = function( f ){ 7233 return this.on( o, f ); 7234 }; 7235}); 7236 7237jQuery.each( [ "get", "post" ], function( i, method ) { 7238 jQuery[ method ] = function( url, data, callback, type ) { 7239 // shift arguments if data argument was omitted 7240 if ( jQuery.isFunction( data ) ) { 7241 type = type || callback; 7242 callback = data; 7243 data = undefined; 7244 } 7245 7246 return jQuery.ajax({ 7247 type: method, 7248 url: url, 7249 data: data, 7250 success: callback, 7251 dataType: type 7252 }); 7253 }; 7254}); 7255 7256jQuery.extend({ 7257 7258 getScript: function( url, callback ) { 7259 return jQuery.get( url, undefined, callback, "script" ); 7260 }, 7261 7262 getJSON: function( url, data, callback ) { 7263 return jQuery.get( url, data, callback, "json" ); 7264 }, 7265 7266 // Creates a full fledged settings object into target 7267 // with both ajaxSettings and settings fields. 7268 // If target is omitted, writes into ajaxSettings. 7269 ajaxSetup: function( target, settings ) { 7270 if ( settings ) { 7271 // Building a settings object 7272 ajaxExtend( target, jQuery.ajaxSettings ); 7273 } else { 7274 // Extending ajaxSettings 7275 settings = target; 7276 target = jQuery.ajaxSettings; 7277 } 7278 ajaxExtend( target, settings ); 7279 return target; 7280 }, 7281 7282 ajaxSettings: { 7283 url: ajaxLocation, 7284 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 7285 global: true, 7286 type: "GET", 7287 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 7288 processData: true, 7289 async: true, 7290 /* 7291 timeout: 0, 7292 data: null, 7293 dataType: null, 7294 username: null, 7295 password: null, 7296 cache: null, 7297 traditional: false, 7298 headers: {}, 7299 */ 7300 7301 accepts: { 7302 xml: "application/xml, text/xml", 7303 html: "text/html", 7304 text: "text/plain", 7305 json: "application/json, text/javascript", 7306 "*": allTypes 7307 }, 7308 7309 contents: { 7310 xml: /xml/, 7311 html: /html/, 7312 json: /json/ 7313 }, 7314 7315 responseFields: { 7316 xml: "responseXML", 7317 text: "responseText" 7318 }, 7319 7320 // List of data converters 7321 // 1) key format is "source_type destination_type" (a single space in-between) 7322 // 2) the catchall symbol "*" can be used for source_type 7323 converters: { 7324 7325 // Convert anything to text 7326 "* text": window.String, 7327 7328 // Text to html (true = no transformation) 7329 "text html": true, 7330 7331 // Evaluate text as a json expression 7332 "text json": jQuery.parseJSON, 7333 7334 // Parse text as xml 7335 "text xml": jQuery.parseXML 7336 }, 7337 7338 // For options that shouldn't be deep extended: 7339 // you can add your own custom options here if 7340 // and when you create one that shouldn't be 7341 // deep extended (see ajaxExtend) 7342 flatOptions: { 7343 context: true, 7344 url: true 7345 } 7346 }, 7347 7348 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 7349 ajaxTransport: addToPrefiltersOrTransports( transports ), 7350 7351 // Main method 7352 ajax: function( url, options ) { 7353 7354 // If url is an object, simulate pre-1.5 signature 7355 if ( typeof url === "object" ) { 7356 options = url; 7357 url = undefined; 7358 } 7359 7360 // Force options to be an object 7361 options = options || {}; 7362 7363 var // Create the final options object 7364 s = jQuery.ajaxSetup( {}, options ), 7365 // Callbacks context 7366 callbackContext = s.context || s, 7367 // Context for global events 7368 // It's the callbackContext if one was provided in the options 7369 // and if it's a DOM node or a jQuery collection 7370 globalEventContext = callbackContext !== s && 7371 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? 7372 jQuery( callbackContext ) : jQuery.event, 7373 // Deferreds 7374 deferred = jQuery.Deferred(), 7375 completeDeferred = jQuery.Callbacks( "once memory" ), 7376 // Status-dependent callbacks 7377 statusCode = s.statusCode || {}, 7378 // ifModified key 7379 ifModifiedKey, 7380 // Headers (they are sent all at once) 7381 requestHeaders = {}, 7382 requestHeadersNames = {}, 7383 // Response headers 7384 responseHeadersString, 7385 responseHeaders, 7386 // transport 7387 transport, 7388 // timeout handle 7389 timeoutTimer, 7390 // Cross-domain detection vars 7391 parts, 7392 // The jqXHR state 7393 state = 0, 7394 // To know if global events are to be dispatched 7395 fireGlobals, 7396 // Loop variable 7397 i, 7398 // Fake xhr 7399 jqXHR = { 7400 7401 readyState: 0, 7402 7403 // Caches the header 7404 setRequestHeader: function( name, value ) { 7405 if ( !state ) { 7406 var lname = name.toLowerCase(); 7407 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 7408 requestHeaders[ name ] = value; 7409 } 7410 return this; 7411 }, 7412 7413 // Raw string 7414 getAllResponseHeaders: function() { 7415 return state === 2 ? responseHeadersString : null; 7416 }, 7417 7418 // Builds headers hashtable if needed 7419 getResponseHeader: function( key ) { 7420 var match; 7421 if ( state === 2 ) { 7422 if ( !responseHeaders ) { 7423 responseHeaders = {}; 7424 while( ( match = rheaders.exec( responseHeadersString ) ) ) { 7425 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; 7426 } 7427 } 7428 match = responseHeaders[ key.toLowerCase() ]; 7429 } 7430 return match === undefined ? null : match; 7431 }, 7432 7433 // Overrides response content-type header 7434 overrideMimeType: function( type ) { 7435 if ( !state ) { 7436 s.mimeType = type; 7437 } 7438 return this; 7439 }, 7440 7441 // Cancel the request 7442 abort: function( statusText ) { 7443 statusText = statusText || "abort"; 7444 if ( transport ) { 7445 transport.abort( statusText ); 7446 } 7447 done( 0, statusText ); 7448 return this; 7449 } 7450 }; 7451 7452 // Callback for when everything is done 7453 // It is defined here because jslint complains if it is declared 7454 // at the end of the function (which would be more logical and readable) 7455 function done( status, nativeStatusText, responses, headers ) { 7456 7457 // Called once 7458 if ( state === 2 ) { 7459 return; 7460 } 7461 7462 // State is "done" now 7463 state = 2; 7464 7465 // Clear timeout if it exists 7466 if ( timeoutTimer ) { 7467 clearTimeout( timeoutTimer ); 7468 } 7469 7470 // Dereference transport for early garbage collection 7471 // (no matter how long the jqXHR object will be used) 7472 transport = undefined; 7473 7474 // Cache response headers 7475 responseHeadersString = headers || ""; 7476 7477 // Set readyState 7478 jqXHR.readyState = status > 0 ? 4 : 0; 7479 7480 var isSuccess, 7481 success, 7482 error, 7483 statusText = nativeStatusText, 7484 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, 7485 lastModified, 7486 etag; 7487 7488 // If successful, handle type chaining 7489 if ( status >= 200 && status < 300 || status === 304 ) { 7490 7491 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7492 if ( s.ifModified ) { 7493 7494 if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { 7495 jQuery.lastModified[ ifModifiedKey ] = lastModified; 7496 } 7497 if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { 7498 jQuery.etag[ ifModifiedKey ] = etag; 7499 } 7500 } 7501 7502 // If not modified 7503 if ( status === 304 ) { 7504 7505 statusText = "notmodified"; 7506 isSuccess = true; 7507 7508 // If we have data 7509 } else { 7510 7511 try { 7512 success = ajaxConvert( s, response ); 7513 statusText = "success"; 7514 isSuccess = true; 7515 } catch(e) { 7516 // We have a parsererror 7517 statusText = "parsererror"; 7518 error = e; 7519 } 7520 } 7521 } else { 7522 // We extract error from statusText 7523 // then normalize statusText and status for non-aborts 7524 error = statusText; 7525 if ( !statusText || status ) { 7526 statusText = "error"; 7527 if ( status < 0 ) { 7528 status = 0; 7529 } 7530 } 7531 } 7532 7533 // Set data for the fake xhr object 7534 jqXHR.status = status; 7535 jqXHR.statusText = "" + ( nativeStatusText || statusText ); 7536 7537 // Success/Error 7538 if ( isSuccess ) { 7539 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 7540 } else { 7541 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 7542 } 7543 7544 // Status-dependent callbacks 7545 jqXHR.statusCode( statusCode ); 7546 statusCode = undefined; 7547 7548 if ( fireGlobals ) { 7549 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), 7550 [ jqXHR, s, isSuccess ? success : error ] ); 7551 } 7552 7553 // Complete 7554 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 7555 7556 if ( fireGlobals ) { 7557 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 7558 // Handle the global AJAX counter 7559 if ( !( --jQuery.active ) ) { 7560 jQuery.event.trigger( "ajaxStop" ); 7561 } 7562 } 7563 } 7564 7565 // Attach deferreds 7566 deferred.promise( jqXHR ); 7567 jqXHR.success = jqXHR.done; 7568 jqXHR.error = jqXHR.fail; 7569 jqXHR.complete = completeDeferred.add; 7570 7571 // Status-dependent callbacks 7572 jqXHR.statusCode = function( map ) { 7573 if ( map ) { 7574 var tmp; 7575 if ( state < 2 ) { 7576 for ( tmp in map ) { 7577 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; 7578 } 7579 } else { 7580 tmp = map[ jqXHR.status ]; 7581 jqXHR.then( tmp, tmp ); 7582 } 7583 } 7584 return this; 7585 }; 7586 7587 // Remove hash character (#7531: and string promotion) 7588 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 7589 // We also use the url parameter if available 7590 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 7591 7592 // Extract dataTypes list 7593 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); 7594 7595 // Determine if a cross-domain request is in order 7596 if ( s.crossDomain == null ) { 7597 parts = rurl.exec( s.url.toLowerCase() ); 7598 s.crossDomain = !!( parts && 7599 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || 7600 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != 7601 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) 7602 ); 7603 } 7604 7605 // Convert data if not already a string 7606 if ( s.data && s.processData && typeof s.data !== "string" ) { 7607 s.data = jQuery.param( s.data, s.traditional ); 7608 } 7609 7610 // Apply prefilters 7611 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 7612 7613 // If request was aborted inside a prefilter, stop there 7614 if ( state === 2 ) { 7615 return false; 7616 } 7617 7618 // We can fire global events as of now if asked to 7619 fireGlobals = s.global; 7620 7621 // Uppercase the type 7622 s.type = s.type.toUpperCase(); 7623 7624 // Determine if request has content 7625 s.hasContent = !rnoContent.test( s.type ); 7626 7627 // Watch for a new set of requests 7628 if ( fireGlobals && jQuery.active++ === 0 ) { 7629 jQuery.event.trigger( "ajaxStart" ); 7630 } 7631 7632 // More options handling for requests with no content 7633 if ( !s.hasContent ) { 7634 7635 // If data is available, append data to url 7636 if ( s.data ) { 7637 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; 7638 // #9682: remove data so that it's not used in an eventual retry 7639 delete s.data; 7640 } 7641 7642 // Get ifModifiedKey before adding the anti-cache parameter 7643 ifModifiedKey = s.url; 7644 7645 // Add anti-cache in url if needed 7646 if ( s.cache === false ) { 7647 7648 var ts = jQuery.now(), 7649 // try replacing _= if it is there 7650 ret = s.url.replace( rts, "$1_=" + ts ); 7651 7652 // if nothing was replaced, add timestamp to the end 7653 s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); 7654 } 7655 } 7656 7657 // Set the correct header, if data is being sent 7658 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 7659 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 7660 } 7661 7662 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 7663 if ( s.ifModified ) { 7664 ifModifiedKey = ifModifiedKey || s.url; 7665 if ( jQuery.lastModified[ ifModifiedKey ] ) { 7666 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); 7667 } 7668 if ( jQuery.etag[ ifModifiedKey ] ) { 7669 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); 7670 } 7671 } 7672 7673 // Set the Accepts header for the server, depending on the dataType 7674 jqXHR.setRequestHeader( 7675 "Accept", 7676 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? 7677 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 7678 s.accepts[ "*" ] 7679 ); 7680 7681 // Check for headers option 7682 for ( i in s.headers ) { 7683 jqXHR.setRequestHeader( i, s.headers[ i ] ); 7684 } 7685 7686 // Allow custom headers/mimetypes and early abort 7687 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 7688 // Abort if not done already 7689 jqXHR.abort(); 7690 return false; 7691 7692 } 7693 7694 // Install callbacks on deferreds 7695 for ( i in { success: 1, error: 1, complete: 1 } ) { 7696 jqXHR[ i ]( s[ i ] ); 7697 } 7698 7699 // Get transport 7700 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 7701 7702 // If no transport, we auto-abort 7703 if ( !transport ) { 7704 done( -1, "No Transport" ); 7705 } else { 7706 jqXHR.readyState = 1; 7707 // Send global event 7708 if ( fireGlobals ) { 7709 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 7710 } 7711 // Timeout 7712 if ( s.async && s.timeout > 0 ) { 7713 timeoutTimer = setTimeout( function(){ 7714 jqXHR.abort( "timeout" ); 7715 }, s.timeout ); 7716 } 7717 7718 try { 7719 state = 1; 7720 transport.send( requestHeaders, done ); 7721 } catch (e) { 7722 // Propagate exception as error if not done 7723 if ( state < 2 ) { 7724 done( -1, e ); 7725 // Simply rethrow otherwise 7726 } else { 7727 throw e; 7728 } 7729 } 7730 } 7731 7732 return jqXHR; 7733 }, 7734 7735 // Serialize an array of form elements or a set of 7736 // key/values into a query string 7737 param: function( a, traditional ) { 7738 var s = [], 7739 add = function( key, value ) { 7740 // If value is a function, invoke it and return its value 7741 value = jQuery.isFunction( value ) ? value() : value; 7742 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 7743 }; 7744 7745 // Set traditional to true for jQuery <= 1.3.2 behavior. 7746 if ( traditional === undefined ) { 7747 traditional = jQuery.ajaxSettings.traditional; 7748 } 7749 7750 // If an array was passed in, assume that it is an array of form elements. 7751 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 7752 // Serialize the form elements 7753 jQuery.each( a, function() { 7754 add( this.name, this.value ); 7755 }); 7756 7757 } else { 7758 // If traditional, encode the "old" way (the way 1.3.2 or older 7759 // did it), otherwise encode params recursively. 7760 for ( var prefix in a ) { 7761 buildParams( prefix, a[ prefix ], traditional, add ); 7762 } 7763 } 7764 7765 // Return the resulting serialization 7766 return s.join( "&" ).replace( r20, "+" ); 7767 } 7768}); 7769 7770function buildParams( prefix, obj, traditional, add ) { 7771 if ( jQuery.isArray( obj ) ) { 7772 // Serialize array item. 7773 jQuery.each( obj, function( i, v ) { 7774 if ( traditional || rbracket.test( prefix ) ) { 7775 // Treat each array item as a scalar. 7776 add( prefix, v ); 7777 7778 } else { 7779 // If array item is non-scalar (array or object), encode its 7780 // numeric index to resolve deserialization ambiguity issues. 7781 // Note that rack (as of 1.0.0) can't currently deserialize 7782 // nested arrays properly, and attempting to do so may cause 7783 // a server error. Possible fixes are to modify rack's 7784 // deserialization algorithm or to provide an option or flag 7785 // to force array serialization to be shallow. 7786 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); 7787 } 7788 }); 7789 7790 } else if ( !traditional && jQuery.type( obj ) === "object" ) { 7791 // Serialize object item. 7792 for ( var name in obj ) { 7793 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 7794 } 7795 7796 } else { 7797 // Serialize scalar item. 7798 add( prefix, obj ); 7799 } 7800} 7801 7802// This is still on the jQuery object... for now 7803// Want to move this to jQuery.ajax some day 7804jQuery.extend({ 7805 7806 // Counter for holding the number of active queries 7807 active: 0, 7808 7809 // Last-Modified header cache for next request 7810 lastModified: {}, 7811 etag: {} 7812 7813}
7813); 7814 7815/* Handles responses to an ajax request: 7816 * - sets all responseXXX fields accordingly 7817 * - finds the right dataType (mediates between content-type and expected dataType) 7818 * - returns the corresponding response 7819 */ 7820function ajaxHandleResponses( s, jqXHR, responses ) { 7821 7822 var contents = s.contents, 7823 dataTypes = s.dataTypes, 7824 responseFields = s.responseFields, 7825 ct, 7826 type, 7827 finalDataType, 7828 firstDataType; 7829 7830 // Fill responseXXX fields 7831 for ( type in responseFields ) { 7832 if ( type in responses ) { 7833 jqXHR[ responseFields[type] ] = responses[ type ]; 7834 } 7835 } 7836 7837 // Remove auto dataType and get content-type in the process 7838 while( dataTypes[ 0 ] === "*" ) { 7839 dataTypes.shift(); 7840 if ( ct === undefined ) { 7841 ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); 7842 } 7843 } 7844 7845 // Check if we're dealing with a known content-type 7846 if ( ct ) { 7847 for ( type in contents ) { 7848 if ( contents[ type ] && contents[ type ].test( ct ) ) { 7849 dataTypes.unshift( type ); 7850 break; 7851 } 7852 } 7853 } 7854 7855 // Check to see if we have a response for the expected dataType 7856 if ( dataTypes[ 0 ] in responses ) { 7857 finalDataType = dataTypes[ 0 ]; 7858 } else { 7859 // Try convertible dataTypes 7860 for ( type in responses ) { 7861 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { 7862 finalDataType = type; 7863 break; 7864 } 7865 if ( !firstDataType ) { 7866 firstDataType = type; 7867 } 7868 } 7869 // Or just use first one 7870 finalDataType = finalDataType || firstDataType; 7871 } 7872 7873 // If we found a dataType 7874 // We add the dataType to the list if needed 7875 // and return the corresponding response 7876 if ( finalDataType ) { 7877 if ( finalDataType !== dataTypes[ 0 ] ) { 7878 dataTypes.unshift( finalDataType ); 7879 } 7880 return responses[ finalDataType ]; 7881 } 7882} 7883 7884// Chain conversions given the request and the original response 7885function ajaxConvert( s, response ) { 7886 7887 // Apply the dataFilter if provided 7888 if ( s.dataFilter ) { 7889 response = s.dataFilter( response, s.dataType ); 7890 } 7891 7892 var dataTypes = s.dataTypes, 7893 converters = {}, 7894 i, 7895 key, 7896 length = dataTypes.length, 7897 tmp, 7898 // Current and previous dataTypes 7899 current = dataTypes[ 0 ], 7900 prev, 7901 // Conversion expression 7902 conversion, 7903 // Conversion function 7904 conv, 7905 // Conversion functions (transitive conversion) 7906 conv1, 7907 conv2; 7908 7909 // For each dataType in the chain 7910 for ( i = 1; i < length; i++ ) { 7911 7912 // Create converters map 7913 // with lowercased keys 7914 if ( i === 1 ) { 7915 for ( key in s.converters ) { 7916 if ( typeof key === "string" ) { 7917 converters[ key.toLowerCase() ] = s.converters[ key ]; 7918 } 7919 } 7920 } 7921 7922 // Get the dataTypes 7923 prev = current; 7924 current = dataTypes[ i ]; 7925 7926 // If current is auto dataType, update it to prev 7927 if ( current === "*" ) { 7928 current = prev; 7929 // If no auto and dataTypes are actually different 7930 } else if ( prev !== "*" && prev !== current ) { 7931 7932 // Get the converter 7933 conversion = prev + " " + current; 7934 conv = converters[ conversion ] || converters[ "* " + current ]; 7935 7936 // If there is no direct converter, search transitively 7937 if ( !conv ) { 7938 conv2 = undefined; 7939 for ( conv1 in converters ) { 7940 tmp = conv1.split( " " ); 7941 if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { 7942 conv2 = converters[ tmp[1] + " " + current ]; 7943 if ( conv2 ) { 7944 conv1 = converters[ conv1 ]; 7945 if ( conv1 === true ) { 7946 conv = conv2; 7947 } else if ( conv2 === true ) { 7948 conv = conv1; 7949 } 7950 break; 7951 } 7952 } 7953 } 7954 } 7955 // If we found no converter, dispatch an error 7956 if ( !( conv || conv2 ) ) { 7957 jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); 7958 } 7959 // If found converter is not an equivalence 7960 if ( conv !== true ) { 7961 // Convert with 1 or 2 converters accordingly 7962 response = conv ? conv( response ) : conv2( conv1(response) ); 7963 } 7964 } 7965 } 7966 return response; 7967} 7968 7969 7970 7971 7972var jsc = jQuery.now(), 7973 jsre = /(\=)\?(&|$)|\?\?/i; 7974 7975// Default jsonp settings 7976jQuery.ajaxSetup({ 7977 jsonp: "callback", 7978 jsonpCallback: function() { 7979 return jQuery.expando + "_" + ( jsc++ ); 7980 } 7981}); 7982 7983// Detect, normalize options and install callbacks for jsonp requests 7984jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 7985 7986 var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType ); 7987 7988 if ( s.dataTypes[ 0 ] === "jsonp" || 7989 s.jsonp !== false && ( jsre.test( s.url ) || 7990 inspectData && jsre.test( s.data ) ) ) { 7991 7992 var responseContainer, 7993 jsonpCallback = s.jsonpCallback = 7994 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, 7995 previous = window[ jsonpCallback ], 7996 url = s.url, 7997 data = s.data, 7998 replace = "$1" + jsonpCallback + "$2"; 7999 8000 if ( s.jsonp !== false ) { 8001 url = url.replace( jsre, replace ); 8002 if ( s.url === url ) { 8003 if ( inspectData ) { 8004 data = data.replace( jsre, replace ); 8005 } 8006 if ( s.data === data ) { 8007 // Add callback manually 8008 url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; 8009 } 8010 } 8011 } 8012 8013 s.url = url; 8014 s.data = data; 8015 8016 // Install callback 8017 window[ jsonpCallback ] = function( response ) { 8018 responseContainer = [ response ]; 8019 }; 8020 8021 // Clean-up function 8022 jqXHR.always(function() { 8023 // Set callback back to previous value 8024 window[ jsonpCallback ] = previous; 8025 // Call if it was a function and we have a response 8026 if ( responseContainer && jQuery.isFunction( previous ) ) { 8027 window[ jsonpCallback ]( responseContainer[ 0 ] ); 8028 } 8029 }); 8030 8031 // Use data converter to retrieve json after script execution 8032 s.converters["script json"] = function() { 8033 if ( !responseContainer ) { 8034 jQuery.error( jsonpCallback + " was not called" ); 8035 } 8036 return responseContainer[ 0 ]; 8037 }; 8038 8039 // force json dataType 8040 s.dataTypes[ 0 ] = "json"; 8041 8042 // Delegate to script 8043 return "script"; 8044 } 8045}); 8046 8047 8048 8049 8050// Install script dataType 8051jQuery.ajaxSetup({ 8052 accepts: { 8053 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 8054 }, 8055 contents: { 8056 script: /javascript|ecmascript/ 8057 }, 8058 converters: { 8059 "text script": function( text ) { 8060 jQuery.globalEval( text ); 8061 return text; 8062 } 8063 } 8064}); 8065 8066// Handle cache's special case and global 8067jQuery.ajaxPrefilter( "script", function( s ) { 8068 if ( s.cache === undefined ) { 8069 s.cache = false;
vendor: 3,904 bytes, lines 8070-8225
8070 } 8071 if ( s.crossDomain ) { 8072 s.type = "GET"; 8073 s.global = false; 8074 } 8075}); 8076 8077// Bind script tag hack transport 8078jQuery.ajaxTransport( "script", function(s) { 8079 8080 // This transport only deals with cross domain requests 8081 if ( s.crossDomain ) { 8082 8083 var script, 8084 head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; 8085 8086 return { 8087 8088 send: function( _, callback ) { 8089 8090 script = document.createElement( "script" ); 8091 8092 script.async = "async"; 8093 8094 if ( s.scriptCharset ) { 8095 script.charset = s.scriptCharset; 8096 } 8097 8098 script.src = s.url; 8099 8100 // Attach handlers for all browsers 8101 script.onload = script.onreadystatechange = function( _, isAbort ) { 8102 8103 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { 8104 8105 // Handle memory leak in IE 8106 script.onload = script.onreadystatechange = null; 8107 8108 // Remove the script 8109 if ( head && script.parentNode ) { 8110 head.removeChild( script ); 8111 } 8112 8113 // Dereference the script 8114 script = undefined; 8115 8116 // Callback if not abort 8117 if ( !isAbort ) { 8118 callback( 200, "success" ); 8119 } 8120 } 8121 }; 8122 // Use insertBefore instead of appendChild to circumvent an IE6 bug. 8123 // This arises when a base node is used (#2709 and #4378). 8124 head.insertBefore( script, head.firstChild ); 8125 }, 8126 8127 abort: function() { 8128 if ( script ) { 8129 script.onload( 0, 1 ); 8130 } 8131 } 8132 }; 8133 } 8134}); 8135 8136 8137 8138 8139var // #5280: Internet Explorer will keep connections alive if we don't abort on unload 8140 xhrOnUnloadAbort = window.ActiveXObject ? function() { 8141 // Abort all pending requests 8142 for ( var key in xhrCallbacks ) { 8143 xhrCallbacks[ key ]( 0, 1 ); 8144 } 8145 } : false, 8146 xhrId = 0, 8147 xhrCallbacks; 8148 8149// Functions to create xhrs 8150function createStandardXHR() { 8151 try { 8152 return new window.XMLHttpRequest(); 8153 } catch( e ) {} 8154} 8155 8156function createActiveXHR() { 8157 try { 8158 return new window.ActiveXObject( "Microsoft.XMLHTTP" ); 8159 } catch( e ) {} 8160} 8161 8162// Create the request object 8163// (This is still attached to ajaxSettings for backward compatibility) 8164jQuery.ajaxSettings.xhr = window.ActiveXObject ? 8165 /* Microsoft failed to properly 8166 * implement the XMLHttpRequest in IE7 (can't request local files), 8167 * so we use the ActiveXObject when it is available 8168 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so 8169 * we need a fallback. 8170 */ 8171 function() { 8172 return !this.isLocal && createStandardXHR() || createActiveXHR(); 8173 } : 8174 // For all other browsers, use the standard XMLHttpRequest object 8175 createStandardXHR; 8176 8177// Determine support properties 8178(function( xhr ) { 8179 jQuery.extend( jQuery.support, { 8180 ajax: !!xhr, 8181 cors: !!xhr && ( "withCredentials" in xhr ) 8182 }); 8183})( jQuery.ajaxSettings.xhr() ); 8184 8185// Create transport if the browser can provide an xhr 8186if ( jQuery.support.ajax ) { 8187 8188 jQuery.ajaxTransport(function( s ) { 8189 // Cross domain only allowed if supported through XMLHttpRequest 8190 if ( !s.crossDomain || jQuery.support.cors ) { 8191 8192 var callback; 8193 8194 return { 8195 send: function( headers, complete ) { 8196 8197 // Get a new xhr 8198 var xhr = s.xhr(), 8199 handle, 8200 i; 8201 8202 // Open the socket 8203 // Passing null username, generates a login popup on Opera (#2865) 8204 if ( s.username ) { 8205 xhr.open( s.type, s.url, s.async, s.username, s.password ); 8206 } else { 8207 xhr.open( s.type, s.url, s.async ); 8208 } 8209 8210 // Apply custom fields if provided 8211 if ( s.xhrFields ) { 8212 for ( i in s.xhrFields ) { 8213 xhr[ i ] = s.xhrFields[ i ]; 8214 } 8215 } 8216 8217 // Override mime type if needed 8218 if ( s.mimeType && xhr.overrideMimeType ) { 8219 xhr.overrideMimeType( s.mimeType ); 8220 } 8221 8222 // X-Requested-With header 8223 // For cross-domain requests, seeing as conditions for a preflight are 8224 // akin to a jigsaw puzzle, we simply never set it to be sure. 8225 // (it can always be set on a per-request basis or even using ajaxSetup)
8226 // For same-domain requests, won't change header if already provided. 8227 if ( !s.crossDomain && !headers["X-Requested-With"] ) { 8228 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 8229 } 8230 8231 // Need an extra try/catch for cross domain requests in Firefox 3 8232 try { 8233 for ( i in headers ) { 8234 xhr.setRequestHeader( i, headers[ i ] ); 8235 } 8236 } catch( _ ) {} 8237 8238 // Do send the request 8239 // This may raise an exception which is actually 8240 // handled in jQuery.ajax (so no try/catch here) 8241 xhr.send( ( s.hasContent && s.data ) || null ); 8242 8243 // Listener 8244 callback = function( _, isAbort ) { 8245 8246 var status, 8247 statusText, 8248 responseHeaders, 8249 responses, 8250 xml; 8251 8252 // Firefox throws exceptions when accessing properties 8253 // of an xhr when a network error occured 8254 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) 8255 try { 8256 8257 // Was never called and is aborted or complete 8258 if ( callback && ( isAbort || xhr.readyState === 4 ) ) { 8259 8260 // Only called once 8261 callback = undefined; 8262 8263 // Do not keep as active anymore 8264 if ( handle ) { 8265 xhr.onreadystatechange = jQuery.noop; 8266 if ( xhrOnUnloadAbort ) { 8267 delete xhrCallbacks[ handle ]; 8268 } 8269 } 8270 8271 // If it's an abort 8272 if ( isAbort ) { 8273 // Abort it manually if needed 8274 if ( xhr.readyState !== 4 ) { 8275 xhr.abort(); 8276 } 8277 } else { 8278 status = xhr.status; 8279 responseHeaders = xhr.getAllResponseHeaders(); 8280 responses = {}; 8281 xml = xhr.responseXML; 8282 8283 // Construct response list 8284 if ( xml && xml.documentElement /* #4958 */ ) { 8285 responses.xml = xml; 8286 } 8287 8288 // When requesting binary data, IE6-9 will throw an exception 8289 // on any attempt to access responseText (#11426) 8290 try { 8291 responses.text = xhr.responseText; 8292 } catch( _ ) { 8293 } 8294 8295 // Firefox throws an exception when accessing 8296 // statusText for faulty cross-domain requests 8297 try { 8298 statusText = xhr.statusText; 8299 } catch( e ) { 8300 // We normalize with Webkit giving an empty statusText 8301 statusText = ""; 8302 } 8303 8304 // Filter status for non standard behaviors 8305 8306 // If the request is local and we have data: assume a success 8307 // (success with no data won't get notified, that's the best we 8308 // can do given current implementations) 8309 if ( !status && s.isLocal && !s.crossDomain ) { 8310 status = responses.text ? 200 : 404; 8311 // IE - #1450: sometimes returns 1223 when it should be 204 8312 } else if ( status === 1223 ) { 8313 status = 204; 8314 } 8315 } 8316 } 8317 } catch( firefoxAccessException ) { 8318 if ( !isAbort ) { 8319 complete( -1, firefoxAccessException ); 8320 } 8321 } 8322 8323 // Call complete if needed 8324 if ( responses ) { 8325 complete( status, statusText, responses, responseHeaders ); 8326 } 8327 }; 8328 8329 // if we're in sync mode or it's in cache 8330 // and has been retrieved directly (IE6 & IE7) 8331 // we need to manually fire the callback 8332 if ( !s.async || xhr.readyState === 4 ) { 8333 callback(); 8334 } else { 8335 handle = ++xhrId; 8336 if ( xhrOnUnloadAbort ) { 8337 // Create the active xhrs callbacks list if needed 8338 // and attach the unload handler 8339 if ( !xhrCallbacks ) { 8340 xhrCallbacks = {}; 8341 jQuery( window ).unload( xhrOnUnloadAbort ); 8342 } 8343 // Add to list of active xhrs callbacks 8344 xhrCallbacks[ handle ] = callback; 8345 } 8346 xhr.onreadystatechange = callback; 8347 } 8348 }, 8349 8350 abort: function() { 8351 if ( callback ) { 8352 callback(0,1); 8353 } 8354 } 8355 }; 8356 } 8357 }); 8358} 8359 8360 8361 8362 8363var elemdisplay = {}, 8364 iframe, iframeDoc, 8365 rfxtypes = /^(?:toggle|show|hide)$/, 8366 rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, 8367 timerId, 8368 fxAttrs = [ 8369 // height animations 8370 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ], 8371 // width animations 8372 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], 8373 // opacity animations 8374 [ "opacity" ] 8375 ], 8376 fxNow; 8377 8378jQuery.fn.extend({ 8379 show: function( speed, easing, callback ) { 8380 var elem, display; 8381 8382 if ( speed || speed === 0 ) { 8383 return this.animate( genFx("show", 3), speed, easing, callback ); 8384 8385 } else { 8386 for ( var i = 0, j = this.length; i < j; i++ ) { 8387 elem = this[ i ]; 8388 8389 if ( elem.style ) { 8390 display = elem.style.display; 8391 8392 // Reset the inline display of this element to learn if it is 8393 // being hidden by cascaded rules or not 8394 if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { 8395 display = elem.style.display = ""; 8396 } 8397 8398 // Set elements which have been overridden with display: none 8399 // in a stylesheet to whatever the default browser style is 8400 // for such an element
8401 if ( (display === "" && jQuery.css(elem, "display") === "none") || 8402 !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { 8403 jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); 8404 } 8405 } 8406 } 8407 8408 // Set the display of most of the elements in a second loop 8409 // to avoid the constant reflow 8410 for ( i = 0; i < j; i++ ) { 8411 elem = this[ i ]; 8412 8413 if ( elem.style ) { 8414 display = elem.style.display; 8415 8416 if ( display === "" || display === "none" ) { 8417 elem.style.display = jQuery._data( elem, "olddisplay" ) || ""; 8418 } 8419 } 8420 } 8421 8422 return this; 8423 } 8424 }, 8425 8426 hide: function( speed, easing, callback ) { 8427 if ( speed || speed === 0 ) { 8428 return this.animate( genFx("hide", 3), speed, easing, callback); 8429 8430 } else { 8431 var elem, display, 8432 i = 0, 8433 j = this.length; 8434 8435 for ( ; i < j; i++ ) { 8436 elem = this[i]; 8437 if ( elem.style ) { 8438 display = jQuery.css( elem, "display" ); 8439 8440 if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) { 8441 jQuery._data( elem, "olddisplay", display ); 8442 } 8443 } 8444 } 8445 8446 // Set the display of the elements in a second loop 8447 // to avoid the constant reflow 8448 for ( i = 0; i < j; i++ ) { 8449 if ( this[i].style ) { 8450 this[i].style.display = "none"; 8451 } 8452 } 8453 8454 return this; 8455 } 8456 }, 8457 8458 // Save the old toggle function 8459 _toggle: jQuery.fn.toggle, 8460 8461 toggle: function( fn, fn2, callback ) { 8462 var bool = typeof fn === "boolean"; 8463 8464 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) { 8465 this._toggle.apply( this, arguments ); 8466 8467 } else if ( fn == null || bool ) { 8468 this.each(function() { 8469 var state = bool ? fn : jQuery(this).is(":hidden"); 8470 jQuery(this)[ state ? "show" : "hide" ](); 8471 }); 8472 8473 } else { 8474 this.animate(genFx("toggle", 3), fn, fn2, callback); 8475 } 8476 8477 return this; 8478 }, 8479 8480 fadeTo: function( speed, to, easing, callback ) { 8481 return this.filter(":hidden").css("opacity", 0).show().end() 8482 .animate({opacity: to}, speed, easing, callback); 8483 }, 8484 8485 animate: function( prop, speed, easing, callback ) { 8486 var optall = jQuery.speed( speed, easing, callback ); 8487 8488 if ( jQuery.isEmptyObject( prop ) ) { 8489 return this.each( optall.complete, [ false ] ); 8490 } 8491 8492 // Do not change referenced properties as per-property easing will be lost 8493 prop = jQuery.extend( {}, prop ); 8494 8495 function doAnimation() { 8496 // XXX 'this' does not always have a nodeName when running the 8497 // test suite 8498 8499 if ( optall.queue === false ) { 8500 jQuery._mark( this ); 8501 } 8502 8503 var opt = jQuery.extend( {}, optall ), 8504 isElement = this.nodeType === 1, 8505 hidden = isElement && jQuery(this).is(":hidden"), 8506 name, val, p, e, hooks, replace, 8507 parts, start, end, unit, 8508 method; 8509 8510 // will store per property easing and be used to determine when an animation is complete 8511 opt.animatedProperties = {}; 8512 8513 // first pass over propertys to expand / normalize 8514 for ( p in prop ) { 8515 name = jQuery.camelCase( p ); 8516 if ( p !== name ) { 8517 prop[ name ] = prop[ p ]; 8518 delete prop[ p ]; 8519 } 8520 8521 if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) { 8522 replace = hooks.expand( prop[ name ] ); 8523 delete prop[ name ]; 8524 8525 // not quite $.extend, this wont overwrite keys already present. 8526 // also - reusing 'p' from above because we have the correct "name" 8527 for ( p in replace ) { 8528 if ( ! ( p in prop ) ) { 8529 prop[ p ] = replace[ p ]; 8530 } 8531 } 8532 } 8533 } 8534 8535 for ( name in prop ) { 8536 val = prop[ name ]; 8537 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) 8538 if ( jQuery.isArray( val ) ) { 8539 opt.animatedProperties[ name ] = val[ 1 ]; 8540 val = prop[ name ] = val[ 0 ]; 8541 } else { 8542 opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; 8543 } 8544 8545 if ( val === "hide" && hidden || val === "show" && !hidden ) { 8546 return opt.complete.call( this ); 8547 } 8548 8549 if ( isElement && ( name === "height" || name === "width" ) ) { 8550 // Make sure that nothing sneaks out 8551 // Record all 3 overflow attributes because IE does not 8552 // change the overflow attribute when overflowX and 8553 // overflowY are set to the same value 8554 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; 8555 8556 // Set display property to inline-block for height/width 8557 // animations on inline elements that are having width/height animated 8558 if ( jQuery.css( this, "display" ) === "inline" && 8559 jQuery.css( this, "float" ) === "none" ) { 8560 8561 // inline-level elements accept inline-block; 8562 // block-level elements need to be inline with layout 8563 if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { 8564 this.style.display = "inline-block"; 8565 8566 } else { 8567 this.style.zoom = 1; 8568 } 8569 } 8570 } 8571 } 8572 8573 if ( opt.overflow != null ) { 8574 this.style.overflow = "hidden"; 8575 } 8576 8577 for ( p in prop ) { 8578 e = new jQuery.fx( this, opt, p ); 8579 val = prop[ p ]; 8580 8581 if ( rfxtypes.test( val ) ) { 8582 8583 // Tracks whether to show or hide based on private 8584 // data attached to the element 8585 method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 ); 8586 if ( method ) { 8587 jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" ); 8588 e[ method ](); 8589 } else { 8590 e[ val ](); 8591 } 8592 8593 } else { 8594 parts = rfxnum.exec( val ); 8595 start = e.cur(); 8596 8597 if ( parts ) { 8598 end = parseFloat( parts[2] ); 8599 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); 8600 8601 // We need to compute starting value 8602 if ( unit !== "px" ) {
8603 jQuery.style( this, p, (end || 1) + unit); 8604 start = ( (end || 1) / e.cur() ) * start; 8605 jQuery.style( this, p, start + unit); 8606 } 8607 8608 // If a +=/-= token was provided, we're doing a relative animation 8609 if ( parts[1] ) { 8610 end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; 8611 } 8612 8613 e.custom( start, end, unit ); 8614 8615 } else { 8616 e.custom( start, val, "" ); 8617 } 8618 } 8619 } 8620 8621 // For JS strict compliance 8622 return true; 8623 } 8624 8625 return optall.queue === false ? 8626 this.each( doAnimation ) : 8627 this.queue( optall.queue, doAnimation ); 8628 }, 8629 8630 stop: function( type, clearQueue, gotoEnd ) { 8631 if ( typeof type !== "string" ) { 8632 gotoEnd = clearQueue; 8633 clearQueue = type; 8634 type = undefined; 8635 } 8636 if ( clearQueue && type !== false ) { 8637 this.queue( type || "fx", [] ); 8638 } 8639 8640 return this.each(function() { 8641 var index, 8642 hadTimers = false, 8643 timers = jQuery.timers, 8644 data = jQuery._data( this ); 8645 8646 // clear marker counters if we know they won't be 8647 if ( !gotoEnd ) { 8648 jQuery._unmark( true, this ); 8649 } 8650 8651 function stopQueue( elem, data, index ) { 8652 var hooks = data[ index ]; 8653 jQuery.removeData( elem, index, true ); 8654 hooks.stop( gotoEnd ); 8655 } 8656 8657 if ( type == null ) { 8658 for ( index in data ) { 8659 if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) { 8660 stopQueue( this, data, index ); 8661 } 8662 } 8663 } else if ( data[ index = type + ".run" ] && data[ index ].stop ){ 8664 stopQueue( this, data, index ); 8665 } 8666 8667 for ( index = timers.length; index--; ) { 8668 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { 8669 if ( gotoEnd ) { 8670 8671 // force the next step to be the last 8672 timers[ index ]( true ); 8673 } else { 8674 timers[ index ].saveState(); 8675 } 8676 hadTimers = true; 8677 timers.splice( index, 1 ); 8678 } 8679 } 8680 8681 // start the next in the queue if the last step wasn't forced 8682 // timers currently will call their complete callbacks, which will dequeue 8683 // but only if they were gotoEnd 8684 if ( !( gotoEnd && hadTimers ) ) { 8685 jQuery.dequeue( this, type ); 8686 } 8687 }); 8688 } 8689 8690}); 8691 8692// Animations created synchronously will run synchronously 8693function createFxNow() { 8694 setTimeout( clearFxNow, 0 ); 8695 return ( fxNow = jQuery.now() ); 8696} 8697 8698function clearFxNow() { 8699 fxNow = undefined; 8700} 8701 8702// Generate parameters to create a standard animation 8703function genFx( type, num ) { 8704 var obj = {}; 8705 8706 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() { 8707 obj[ this ] = type; 8708 }); 8709 8710 return obj; 8711} 8712 8713// Generate shortcuts for custom animations 8714jQuery.each({ 8715 slideDown: genFx( "show", 1 ), 8716 slideUp: genFx( "hide", 1 ), 8717 slideToggle: genFx( "toggle", 1 ), 8718 fadeIn: { opacity: "show" }, 8719 fadeOut: { opacity: "hide" }, 8720 fadeToggle: { opacity: "toggle" } 8721}, function( name, props ) { 8722 jQuery.fn[ name ] = function( speed, easing, callback ) { 8723 return this.animate( props, speed, easing, callback ); 8724 }; 8725}); 8726 8727jQuery.extend({ 8728 speed: function( speed, easing, fn ) { 8729 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 8730 complete: fn || !fn && easing || 8731 jQuery.isFunction( speed ) && speed, 8732 duration: speed, 8733 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 8734 }; 8735 8736 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 8737 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 8738 8739 // normalize opt.queue - true/undefined/null -> "fx" 8740 if ( opt.queue == null || opt.queue === true ) { 8741 opt.queue = "fx"; 8742 } 8743 8744 // Queueing 8745 opt.old = opt.complete; 8746 8747 opt.complete = function( noUnmark ) { 8748 if ( jQuery.isFunction( opt.old ) ) { 8749 opt.old.call( this ); 8750 } 8751 8752 if ( opt.queue ) { 8753 jQuery.dequeue( this, opt.queue ); 8754 } else if ( noUnmark !== false ) { 8755 jQuery._unmark( this ); 8756 } 8757 }; 8758 8759 return opt; 8760 }, 8761 8762 easing: { 8763 linear: function( p ) { 8764 return p; 8765 }, 8766 swing: function( p ) { 8767 return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5; 8768 } 8769 }, 8770 8771 timers: [], 8772 8773 fx: function( elem, options, prop ) { 8774 this.options = options; 8775 this.elem = elem; 8776 this.prop = prop; 8777 8778 options.orig = options.orig || {}; 8779 } 8780 8781}); 8782 8783jQuery.fx.prototype = { 8784 // Simple function for setting a style value 8785 update: function() { 8786 if ( this.options.step ) { 8787 this.options.step.call( this.elem, this.now, this ); 8788 } 8789 8790 ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this ); 8791 }, 8792 8793 // Get the current size 8794 cur: function() { 8795 if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) { 8796 return this.elem[ this.prop ]; 8797 } 8798 8799 var parsed, 8800 r = jQuery.css( this.elem, this.prop ); 8801 // Empty strings, null, undefined and "auto" are converted to 0, 8802 // complex values such as "rotate(1rad)" are returned as is, 8803 // simple values such as "10px" are parsed to Float. 8804 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; 8805 }, 8806 8807 // Start an animation from one number to another 8808 custom: function( from, to, unit ) { 8809 var self = this, 8810 fx = jQuery.fx; 8811 8812 this.startTime = fxNow || createFxNow(); 8813 this.end = to; 8814 this.now = this.start = from; 8815 this.pos = this.state = 0; 8816 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); 8817 8818 function t( gotoEnd ) { 8819 return self.step( gotoEnd ); 8820 } 8821 8822 t.queue = this.options.queue; 8823 t.elem = this.elem;
8824 t.saveState = function() { 8825 if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) { 8826 if ( self.options.hide ) { 8827 jQuery._data( self.elem, "fxshow" + self.prop, self.start ); 8828 } else if ( self.options.show ) { 8829 jQuery._data( self.elem, "fxshow" + self.prop, self.end ); 8830 } 8831 } 8832 }; 8833 8834 if ( t() && jQuery.timers.push(t) && !timerId ) { 8835 timerId = setInterval( fx.tick, fx.interval ); 8836 } 8837 }, 8838 8839 // Simple 'show' function 8840 show: function() { 8841 var dataShow = jQuery._data( this.elem, "fxshow" + this.prop ); 8842 8843 // Remember where we started, so that we can go back to it later 8844 this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop ); 8845 this.options.show = true; 8846 8847 // Begin the animation 8848 // Make sure that we start at a small width/height to avoid any flash of content 8849 if ( dataShow !== undefined ) { 8850 // This show is picking up where a previous hide or show left off 8851 this.custom( this.cur(), dataShow ); 8852 } else { 8853 this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() ); 8854 } 8855 8856 // Start by showing the element 8857 jQuery( this.elem ).show(); 8858 }, 8859 8860 // Simple 'hide' function 8861 hide: function() { 8862 // Remember where we started, so that we can go back to it later 8863 this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop ); 8864 this.options.hide = true; 8865 8866 // Begin the animation 8867 this.custom( this.cur(), 0 ); 8868 }, 8869 8870 // Each step of an animation 8871 step: function( gotoEnd ) { 8872 var p, n, complete, 8873 t = fxNow || createFxNow(), 8874 done = true, 8875 elem = this.elem, 8876 options = this.options; 8877 8878 if ( gotoEnd || t >= options.duration + this.startTime ) { 8879 this.now = this.end; 8880 this.pos = this.state = 1; 8881 this.update(); 8882 8883 options.animatedProperties[ this.prop ] = true; 8884 8885 for ( p in options.animatedProperties ) { 8886 if ( options.animatedProperties[ p ] !== true ) { 8887 done = false; 8888 } 8889 } 8890 8891 if ( done ) { 8892 // Reset the overflow 8893 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { 8894 8895 jQuery.each( [ "", "X", "Y" ], function( index, value ) { 8896 elem.style[ "overflow" + value ] = options.overflow[ index ]; 8897 }); 8898 } 8899 8900 // Hide the element if the "hide" operation was done 8901 if ( options.hide ) { 8902 jQuery( elem ).hide(); 8903 } 8904 8905 // Reset the properties, if the item has been hidden or shown 8906 if ( options.hide || options.show ) { 8907 for ( p in options.animatedProperties ) { 8908 jQuery.style( elem, p, options.orig[ p ] ); 8909 jQuery.removeData( elem, "fxshow" + p, true ); 8910 // Toggle data is no longer needed 8911 jQuery.removeData( elem, "toggle" + p, true ); 8912 } 8913 } 8914 8915 // Execute the complete function 8916 // in the event that the complete function throws an exception 8917 // we must ensure it won't be called twice. #5684 8918 8919 complete = options.complete; 8920 if ( complete ) { 8921 8922 options.complete = false; 8923 complete.call( elem ); 8924 } 8925 } 8926 8927 return false; 8928 8929 } else { 8930 // classical easing cannot be used with an Infinity duration 8931 if ( options.duration == Infinity ) { 8932 this.now = t; 8933 } else { 8934 n = t - this.startTime; 8935 this.state = n / options.duration; 8936 8937 // Perform the easing function, defaults to swing 8938 this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration ); 8939 this.now = this.start + ( (this.end - this.start) * this.pos ); 8940 } 8941 // Perform the next step of the animation 8942 this.update(); 8943 } 8944 8945 return true; 8946 } 8947}; 8948 8949jQuery.extend( jQuery.fx, { 8950 tick: function() { 8951 var timer, 8952 timers = jQuery.timers, 8953 i = 0; 8954 8955 for ( ; i < timers.length; i++ ) { 8956 timer = timers[ i ]; 8957 // Checks the timer has not already been removed 8958 if ( !timer() && timers[ i ] === timer ) { 8959 timers.splice( i--, 1 ); 8960 } 8961 } 8962 8963 if ( !timers.length ) { 8964 jQuery.fx.stop(); 8965 } 8966 }, 8967 8968 interval: 13, 8969 8970 stop: function() { 8971 clearInterval( timerId ); 8972 timerId = null; 8973 }, 8974 8975 speeds: { 8976 slow: 600, 8977 fast: 200, 8978 // Default speed 8979 _default: 400 8980 }, 8981 8982 step: { 8983 opacity: function( fx ) { 8984 jQuery.style( fx.elem, "opacity", fx.now ); 8985 }, 8986 8987 _default: function( fx ) { 8988 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { 8989 fx.elem.style[ fx.prop ] = fx.now + fx.unit; 8990 } else { 8991 fx.elem[ fx.prop ] = fx.now; 8992 } 8993 } 8994 } 8995}); 8996 8997// Ensure props that can't be negative don't go there on undershoot easing 8998jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) { 8999 // exclude marginTop, marginLeft, marginBottom and marginRight from this list 9000 if ( prop.indexOf( "margin" ) ) { 9001 jQuery.fx.step[ prop ] = function( fx ) { 9002 jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit ); 9003 }; 9004 } 9005}); 9006 9007if ( jQuery.expr && jQuery.expr.filters ) { 9008 jQuery.expr.filters.animated = function( elem ) { 9009 return jQuery.grep(jQuery.timers, function( fn ) { 9010 return elem === fn.elem; 9011 }).length; 9012 }; 9013} 9014 9015// Try to restore the default display value of an element 9016function defaultDisplay( nodeName ) { 9017 9018 if ( !elemdisplay[ nodeName ] ) { 9019 9020 var body = document.body, 9021 elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), 9022 display = elem.css( "display" ); 9023 elem.remove(); 9024 9025 // If the simple way fails, 9026 // get element's real default display by attaching it to a temp iframe 9027 if ( display === "none" || display === "" ) { 9028 // No iframe to use yet, so create it 9029 if ( !iframe ) { 9030 iframe = document.createElement( "iframe" ); 9031 iframe.frameBorder = iframe.width = iframe.height = 0; 9032 } 9033 9034 body.appendChild( iframe ); 9035 9036 // Create a cacheable copy of the iframe document on first call. 9037 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML 9038 // document to it; WebKit & Firefox won't allow reusing the iframe document. 9039 if ( !iframeDoc || !iframe.createElement ) { 9040 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; 9041 iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" ); 9042 iframeDoc.close(); 9043 } 9044 9045 elem = iframeDoc.createElement( nodeName ); 9046 9047 iframeDoc.body.appendChild( elem ); 9048
9049 display = jQuery.css( elem, "display" ); 9050 body.removeChild( iframe ); 9051 } 9052 9053 // Store the correct default display 9054 elemdisplay[ nodeName ] = display; 9055 } 9056 9057 return elemdisplay[ nodeName ]; 9058} 9059 9060 9061 9062 9063var getOffset, 9064 rtable = /^t(?:able|d|h)$/i, 9065 rroot = /^(?:body|html)$/i; 9066 9067if ( "getBoundingClientRect" in document.documentElement ) { 9068 getOffset = function( elem, doc, docElem, box ) { 9069 try { 9070 box = elem.getBoundingClientRect(); 9071 } catch(e) {} 9072 9073 // Make sure we're not dealing with a disconnected DOM node 9074 if ( !box || !jQuery.contains( docElem, elem ) ) { 9075 return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; 9076 } 9077 9078 var body = doc.body, 9079 win = getWindow( doc ), 9080 clientTop = docElem.clientTop || body.clientTop || 0, 9081 clientLeft = docElem.clientLeft || body.clientLeft || 0, 9082 scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, 9083 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, 9084 top = box.top + scrollTop - clientTop, 9085 left = box.left + scrollLeft - clientLeft; 9086 9087 return { top: top, left: left }; 9088 }; 9089 9090} else { 9091 getOffset = function( elem, doc, docElem ) { 9092 var computedStyle, 9093 offsetParent = elem.offsetParent, 9094 prevOffsetParent = elem, 9095 body = doc.body, 9096 defaultView = doc.defaultView, 9097 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, 9098 top = elem.offsetTop, 9099 left = elem.offsetLeft; 9100 9101 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { 9102 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { 9103 break; 9104 } 9105 9106 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; 9107 top -= elem.scrollTop; 9108 left -= elem.scrollLeft; 9109 9110 if ( elem === offsetParent ) { 9111 top += elem.offsetTop; 9112 left += elem.offsetLeft; 9113 9114 if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { 9115 top += parseFloat( computedStyle.borderTopWidth ) || 0; 9116 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 9117 } 9118 9119 prevOffsetParent = offsetParent; 9120 offsetParent = elem.offsetParent; 9121 } 9122 9123 if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { 9124 top += parseFloat( computedStyle.borderTopWidth ) || 0; 9125 left += parseFloat( computedStyle.borderLeftWidth ) || 0; 9126 } 9127 9128 prevComputedStyle = computedStyle; 9129 } 9130 9131 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { 9132 top += body.offsetTop; 9133 left += body.offsetLeft; 9134 } 9135 9136 if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { 9137 top += Math.max( docElem.scrollTop, body.scrollTop ); 9138 left += Math.max( docElem.scrollLeft, body.scrollLeft ); 9139 } 9140 9141 return { top: top, left: left }; 9142 }; 9143} 9144 9145jQuery.fn.offset = function( options ) { 9146 if ( arguments.length ) { 9147 return options === undefined ? 9148 this : 9149 this.each(function( i ) { 9150 jQuery.offset.setOffset( this, options, i ); 9151 }); 9152 } 9153 9154 var elem = this[0], 9155 doc = elem && elem.ownerDocument; 9156 9157 if ( !doc ) { 9158 return null; 9159 } 9160 9161 if ( elem === doc.body ) { 9162 return jQuery.offset.bodyOffset( elem ); 9163 } 9164 9165 return getOffset( elem, doc, doc.documentElement ); 9166}; 9167 9168jQuery.offset = { 9169 9170 bodyOffset: function( body ) { 9171 var top = body.offsetTop, 9172 left = body.offsetLeft; 9173 9174 if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { 9175 top += parseFloat( jQuery.css(body, "marginTop") ) || 0; 9176 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; 9177 } 9178 9179 return { top: top, left: left }; 9180 }, 9181 9182 setOffset: function( elem, options, i ) { 9183 var position = jQuery.css( elem, "position" ); 9184 9185 // set position first, in-case top/left are set even on static elem 9186 if ( position === "static" ) { 9187 elem.style.position = "relative"; 9188 } 9189 9190 var curElem = jQuery( elem ), 9191 curOffset = curElem.offset(), 9192 curCSSTop = jQuery.css( elem, "top" ), 9193 curCSSLeft = jQuery.css( elem, "left" ), 9194 calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, 9195 props = {}, curPosition = {}, curTop, curLeft; 9196 9197 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed 9198 if ( calculatePosition ) { 9199 curPosition = curElem.position(); 9200 curTop = curPosition.top; 9201 curLeft = curPosition.left; 9202 } else { 9203 curTop = parseFloat( curCSSTop ) || 0; 9204 curLeft = parseFloat( curCSSLeft ) || 0; 9205 } 9206 9207 if ( jQuery.isFunction( options ) ) { 9208 options = options.call( elem, i, curOffset ); 9209 } 9210 9211 if ( options.top != null ) { 9212 props.top = ( options.top - curOffset.top ) + curTop; 9213 } 9214 if ( options.left != null ) { 9215 props.left = ( options.left - curOffset.left ) + curLeft; 9216 } 9217 9218 if ( "using" in options ) { 9219 options.using.call( elem, props ); 9220 } else { 9221 curElem.css( props ); 9222 } 9223 } 9224}; 9225 9226 9227jQuery.fn.extend({ 9228 9229 position: function() { 9230 if ( !this[0] ) { 9231 return null; 9232 } 9233 9234 var elem = this[0], 9235 9236 // Get *real* offsetParent 9237 offsetParent = this.offsetParent(), 9238 9239 // Get correct offsets 9240 offset = this.offset(), 9241 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); 9242 9243 // Subtract element margins 9244 // note: when an element has margin: auto the offsetLeft and marginLeft 9245 // are the same in Safari causing offset.left to incorrectly be 0 9246 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; 9247 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; 9248 9249 // Add offsetParent borders 9250 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; 9251 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; 9252 9253 // Subtract the two offsets 9254 return { 9255 top: offset.top - parentOffset.top, 9256 left: offset.left - parentOffset.left 9257 }; 9258 }, 9259 9260 offsetParent: function() { 9261 return this.map(function() { 9262 var offsetParent = this.offsetParent || document.body;
9263 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { 9264 offsetParent = offsetParent.offsetParent; 9265 } 9266 return offsetParent; 9267 }); 9268 } 9269}); 9270 9271 9272// Create scrollLeft and scrollTop methods 9273jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { 9274 var top = /Y/.test( prop ); 9275 9276 jQuery.fn[ method ] = function( val ) { 9277 return jQuery.access( this, function( elem, method, val ) { 9278 var win = getWindow( elem ); 9279 9280 if ( val === undefined ) { 9281 return win ? (prop in win) ? win[ prop ] : 9282 jQuery.support.boxModel && win.document.documentElement[ method ] || 9283 win.document.body[ method ] : 9284 elem[ method ]; 9285 } 9286 9287 if ( win ) { 9288 win.scrollTo( 9289 !top ? val : jQuery( win ).scrollLeft(), 9290 top ? val : jQuery( win ).scrollTop() 9291 ); 9292 9293 } else { 9294 elem[ method ] = val; 9295 } 9296 }, method, val, arguments.length, null ); 9297 }; 9298}); 9299 9300function getWindow( elem ) { 9301 return jQuery.isWindow( elem ) ? 9302 elem : 9303 elem.nodeType === 9 ? 9304 elem.defaultView || elem.parentWindow : 9305 false; 9306} 9307 9308 9309 9310 9311// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods 9312jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 9313 var clientProp = "client" + name, 9314 scrollProp = "scroll" + name, 9315 offsetProp = "offset" + name; 9316 9317 // innerHeight and innerWidth 9318 jQuery.fn[ "inner" + name ] = function() { 9319 var elem = this[0]; 9320 return elem ? 9321 elem.style ? 9322 parseFloat( jQuery.css( elem, type, "padding" ) ) : 9323 this[ type ]() : 9324 null; 9325 }; 9326 9327 // outerHeight and outerWidth 9328 jQuery.fn[ "outer" + name ] = function( margin ) { 9329 var elem = this[0]; 9330 return elem ? 9331 elem.style ? 9332 parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : 9333 this[ type ]() : 9334 null; 9335 }; 9336 9337 jQuery.fn[ type ] = function( value ) { 9338 return jQuery.access( this, function( elem, type, value ) { 9339 var doc, docElemProp, orig, ret; 9340 9341 if ( jQuery.isWindow( elem ) ) { 9342 // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat 9343 doc = elem.document; 9344 docElemProp = doc.documentElement[ clientProp ]; 9345 return jQuery.support.boxModel && docElemProp || 9346 doc.body && doc.body[ clientProp ] || docElemProp; 9347 } 9348 9349 // Get document width or height 9350 if ( elem.nodeType === 9 ) { 9351 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater 9352 doc = elem.documentElement; 9353 9354 // when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height] 9355 // so we can't use max, as it'll choose the incorrect offset[Width/Height] 9356 // instead we use the correct client[Width/Height] 9357 // support:IE6 9358 if ( doc[ clientProp ] >= doc[ scrollProp ] ) { 9359 return doc[ clientProp ]; 9360 } 9361 9362 return Math.max( 9363 elem.body[ scrollProp ], doc[ scrollProp ], 9364 elem.body[ offsetProp ], doc[ offsetProp ] 9365 ); 9366 } 9367 9368 // Get width or height on the element 9369 if ( value === undefined ) { 9370 orig = jQuery.css( elem, type ); 9371 ret = parseFloat( orig ); 9372 return jQuery.isNumeric( ret ) ? ret : orig; 9373 } 9374 9375 // Set the width or height on the element 9376 jQuery( elem ).css( type, value ); 9377 }, type, value, arguments.length, null ); 9378 }; 9379}); 9380 9381 9382 9383 9384// Expose jQuery to the global object 9385window.jQuery = window.$ = jQuery; 9386 9387// Expose jQuery as an AMD module, but only for AMD loaders that 9388// understand the issues with loading multiple versions of jQuery 9389// in a page that all might call define(). The loader will indicate 9390// they have special allowances for multiple jQuery versions by 9391// specifying define.amd.jQuery = true. Register as a named module, 9392// since jQuery can be concatenated with other files that may use define, 9393// but not use a proper concatenation script that understands anonymous 9394// AMD modules. A named AMD is safest and most robust way to register. 9395// Lowercase jquery is used because AMD module names are derived from 9396// file names, and jQuery is normally delivered in a lowercase file name. 9397// Do this after creating the global so that if an AMD module wants to call
9398// noConflict to hide this version of jQuery, it will work. 9399if ( typeof define === "function" && define.amd && define.amd.jQuery ) { 9400 define( "jquery", [], function () { return jQuery; } ); 9401} 9402 9403 9404 9405})( window ); 9406(function($, undefined) { 9407 9408/** 9409 * Unobtrusive scripting adapter for jQuery 9410 * https://github.com/rails/jquery-ujs 9411 * 9412 * Requires jQuery 1.7.0 or later. 9413 * 9414 * Released under the MIT license 9415 * 9416 */ 9417 9418 // Cut down on the number of issues from people inadvertently including jquery_ujs twice 9419 // by detecting and raising an error when it happens. 9420 if ( $.rails !== undefined ) { 9421 $.error('jquery-ujs has already been loaded!'); 9422 } 9423 9424 // Shorthand to make it a little easier to call public rails functions from within rails.js 9425 var rails; 9426 9427 $.rails = rails = { 9428 // Link elements bound by jquery-ujs 9429 linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]', 9430 9431 // Button elements boud jquery-ujs 9432 buttonClickSelector: 'button[data-remote]', 9433 9434 // Select elements bound by jquery-ujs 9435 inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', 9436 9437 // Form elements bound by jquery-ujs 9438 formSubmitSelector: 'form', 9439 9440 // Form input elements bound by jquery-ujs 9441 formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])', 9442 9443 // Form input elements disabled during form submission 9444 disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]', 9445 9446 // Form input elements re-enabled after form submission 9447 enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', 9448 9449 // Form required input elements 9450 requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])', 9451 9452 // Form file input elements 9453 fileInputSelector: 'input[type=file]', 9454 9455 // Link onClick disable selector with possible reenable after remote submission 9456 linkDisableSelector: 'a[data-disable-with]', 9457 9458 // Make sure that every Ajax request sends the CSRF token 9459 CSRFProtection: function(xhr) { 9460 var token = $('meta[name="csrf-token"]').attr('content'); 9461 if (token) xhr.setRequestHeader('X-CSRF-Token', token); 9462 }, 9463 9464 // Triggers an event on an element and returns false if the event result is false 9465 fire: function(obj, name, data) { 9466 var event = $.Event(name); 9467 obj.trigger(event, data); 9468 return event.result !== false; 9469 }, 9470 9471 // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm 9472 confirm: function(message) { 9473 return confirm(message); 9474 }, 9475 9476 // Default ajax function, may be overridden with custom function in $.rails.ajax 9477 ajax: function(options) { 9478 return $.ajax(options); 9479 }, 9480 9481 // Default way to get an element's href. May be overridden at $.rails.href. 9482 href: function(element) { 9483 return element.attr('href'); 9484 }, 9485 9486 // Submits "remote" forms and links with ajax 9487 handleRemote: function(element) { 9488 var method, url, data, elCrossDomain, crossDomain, withCredentials, dataType, options; 9489 9490 if (rails.fire(element, 'ajax:before')) { 9491 elCrossDomain = element.data('cross-domain'); 9492 crossDomain = elCrossDomain === undefined ? null : elCrossDomain; 9493 withCredentials = element.data('with-credentials') || null; 9494 dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); 9495 9496 if (element.is('form')) { 9497 method = element.attr('method'); 9498 url = element.attr('action'); 9499 data = element.serializeArray(); 9500 // memoized value from clicked submit button 9501 var button = element.data('ujs:submit-button'); 9502 if (button) { 9503 data.push(button); 9504 element.data('ujs:submit-button', null); 9505 } 9506 } else if (element.is(rails.inputChangeSelector)) { 9507 method = element.data('method'); 9508 url = element.data('url'); 9509 data = element.serialize(); 9510 if (element.data('params')) data = data + "&" + element.data('params'); 9511 } else if (element.is(rails.buttonClickSelector)) { 9512 method = element.data('method') || 'get'; 9513 url = element.data('url'); 9514 data = element.serialize(); 9515 if (element.data('params')) data = data + "&" + element.data('params'); 9516 } else { 9517 method = element.data('method'); 9518 url = rails.href(element); 9519 data = element.data('params') || null; 9520 } 9521 9522 options = { 9523 type: method || 'GET', data: data, dataType: dataType, 9524 // stopping the "ajax:beforeSend" event will cancel the ajax request 9525 beforeSend: function(xhr, settings) { 9526 if (settings.dataType === undefined) { 9527 xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); 9528 } 9529 return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); 9530 }, 9531 success: function(data, status, xhr) {
9532 element.trigger('ajax:success', [data, status, xhr]); 9533 }, 9534 complete: function(xhr, status) { 9535 element.trigger('ajax:complete', [xhr, status]); 9536 }, 9537 error: function(xhr, status, error) { 9538 element.trigger('ajax:error', [xhr, status, error]); 9539 }, 9540 crossDomain: crossDomain 9541 }; 9542 9543 // There is no withCredentials for IE6-8 when 9544 // "Enable native XMLHTTP support" is disabled 9545 if (withCredentials) { 9546 options.xhrFields = { 9547 withCredentials: withCredentials 9548 }; 9549 } 9550 9551 // Only pass url to `ajax` options if not blank 9552 if (url) { options.url = url; } 9553 9554 var jqxhr = rails.ajax(options); 9555 element.trigger('ajax:send', jqxhr); 9556 return jqxhr; 9557 } else { 9558 return false; 9559 } 9560 }, 9561 9562 // Handles "data-method" on links such as: 9563 // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> 9564 handleMethod: function(link) { 9565 var href = rails.href(link), 9566 method = link.data('method'), 9567 target = link.attr('target'), 9568 csrf_token = $('meta[name=csrf-token]').attr('content'), 9569 csrf_param = $('meta[name=csrf-param]').attr('content'), 9570 form = $('<form method="post" action="' + href + '"></form>'), 9571 metadata_input = '<input name="_method" value="' + method + '" type="hidden" />'; 9572 9573 if (csrf_param !== undefined && csrf_token !== undefined) { 9574 metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />'; 9575 } 9576 9577 if (target) { form.attr('target', target); } 9578 9579 form.hide().append(metadata_input).appendTo('body'); 9580 form.submit(); 9581 }, 9582 9583 /* Disables form elements: 9584 - Caches element value in 'ujs:enable-with' data store 9585 - Replaces element text with value of 'data-disable-with' attribute 9586 - Sets disabled property to true 9587 */ 9588 disableFormElements: function(form) { 9589 form.find(rails.disableSelector).each(function() { 9590 var element = $(this), method = element.is('button') ? 'html' : 'val'; 9591 element.data('ujs:enable-with', element[method]()); 9592 element[method](element.data('disable-with')); 9593 element.prop('disabled', true); 9594 }); 9595 }, 9596 9597 /* Re-enables disabled form elements: 9598 - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) 9599 - Sets disabled property to false 9600 */ 9601 enableFormElements: function(form) { 9602 form.find(rails.enableSelector).each(function() { 9603 var element = $(this), method = element.is('button') ? 'html' : 'val'; 9604 if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with')); 9605 element.prop('disabled', false); 9606 }); 9607 }, 9608 9609 /* For 'data-confirm' attribute: 9610 - Fires `confirm` event 9611 - Shows the confirmation dialog 9612 - Fires the `confirm:complete` event 9613 9614 Returns `true` if no function stops the chain and user chose yes; `false` otherwise. 9615 Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. 9616 Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function 9617 return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. 9618 */ 9619 allowAction: function(element) { 9620 var message = element.data('confirm'), 9621 answer = false, callback; 9622 if (!message) { return true; } 9623 9624 if (rails.fire(element, 'confirm')) { 9625 answer = rails.confirm(message); 9626 callback = rails.fire(element, 'confirm:complete', [answer]); 9627 } 9628 return answer && callback; 9629 }, 9630 9631 // Helper function which checks for blank inputs in a form that match the specified CSS selector 9632 blankInputs: function(form, specifiedSelector, nonBlank) { 9633 var inputs = $(), input, valueToCheck, 9634 selector = specifiedSelector || 'input,textarea', 9635 allInputs = form.find(selector); 9636 9637 allInputs.each(function() { 9638 input = $(this); 9639 valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : input.val(); 9640 // If nonBlank and valueToCheck are both truthy, or nonBlank and valueToCheck are both falsey 9641 if (!valueToCheck === !nonBlank) { 9642 9643 // Don't count unchecked required radio if other radio with same name is checked 9644 if (input.is('input[type=radio]') && allInputs.filter('input[type=radio]:checked[name="' + input.attr('name') + '"]').length) { 9645 return true; // Skip to next input 9646 } 9647
9648 inputs = inputs.add(input); 9649 } 9650 }); 9651 return inputs.length ? inputs : false; 9652 }, 9653 9654 // Helper function which checks for non-blank inputs in a form that match the specified CSS selector 9655 nonBlankInputs: function(form, specifiedSelector) { 9656 return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank 9657 }, 9658 9659 // Helper function, needed to provide consistent behavior in IE 9660 stopEverything: function(e) { 9661 $(e.target).trigger('ujs:everythingStopped'); 9662 e.stopImmediatePropagation(); 9663 return false; 9664 }, 9665 9666 // replace element's html with the 'data-disable-with' after storing original html 9667 // and prevent clicking on it 9668 disableElement: function(element) { 9669 element.data('ujs:enable-with', element.html()); // store enabled state 9670 element.html(element.data('disable-with')); // set to disabled state 9671 element.bind('click.railsDisable', function(e) { // prevent further clicking 9672 return rails.stopEverything(e); 9673 }); 9674 }, 9675 9676 // restore element to its original state which was disabled by 'disableElement' above 9677 enableElement: function(element) { 9678 if (element.data('ujs:enable-with') !== undefined) { 9679 element.html(element.data('ujs:enable-with')); // set to old enabled state 9680 element.removeData('ujs:enable-with'); // clean up cache 9681 } 9682 element.unbind('click.railsDisable'); // enable element 9683 } 9684 9685 }; 9686 9687 if (rails.fire($(document), 'rails:attachBindings')) { 9688 9689 $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); 9690 9691 $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() { 9692 rails.enableElement($(this)); 9693 }); 9694 9695 $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) { 9696 var link = $(this), method = link.data('method'), data = link.data('params'); 9697 if (!rails.allowAction(link)) return rails.stopEverything(e); 9698 9699 if (link.is(rails.linkDisableSelector)) rails.disableElement(link); 9700 9701 if (link.data('remote') !== undefined) { 9702 if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; } 9703 9704 var handleRemote = rails.handleRemote(link); 9705 // response from rails.handleRemote() will either be false or a deferred object promise. 9706 if (handleRemote === false) { 9707 rails.enableElement(link); 9708 } else { 9709 handleRemote.error( function() { rails.enableElement(link); } ); 9710 } 9711 return false; 9712 9713 } else if (link.data('method')) { 9714 rails.handleMethod(link); 9715 return false; 9716 } 9717 }); 9718 9719 $(document).delegate(rails.buttonClickSelector, 'click.rails', function(e) { 9720 var button = $(this); 9721 if (!rails.allowAction(button)) return rails.stopEverything(e); 9722 9723 rails.handleRemote(button); 9724 return false; 9725 }); 9726 9727 $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) { 9728 var link = $(this); 9729 if (!rails.allowAction(link)) return rails.stopEverything(e); 9730 9731 rails.handleRemote(link); 9732 return false; 9733 }); 9734 9735 $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) { 9736 var form = $(this), 9737 remote = form.data('remote') !== undefined, 9738 blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector), 9739 nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); 9740 9741 if (!rails.allowAction(form)) return rails.stopEverything(e); 9742 9743 // skip other logic when required values are missing or file upload is present 9744 if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { 9745 return rails.stopEverything(e); 9746 } 9747 9748 if (remote) { 9749 if (nonBlankFileInputs) { 9750 // slight timeout so that the submit button gets properly serialized 9751 // (make it easy for event handler to serialize form without disabled values) 9752 setTimeout(function(){ rails.disableFormElements(form); }, 13); 9753 var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); 9754 9755 // re-enable form elements if event bindings return false (canceling normal form submission) 9756 if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } 9757 9758 return aborted; 9759 } 9760 9761 rails.handleRemote(form); 9762 return false;
9763 9764 } else { 9765 // slight timeout so that the submit button gets properly serialized 9766 setTimeout(function(){ rails.disableFormElements(form); }, 13); 9767 } 9768 }); 9769 9770 $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) { 9771 var button = $(this); 9772 9773 if (!rails.allowAction(button)) return rails.stopEverything(event); 9774 9775 // register the pressed submit button 9776 var name = button.attr('name'), 9777 data = name ? {name:name, value:button.val()} : null; 9778 9779 button.closest('form').data('ujs:submit-button', data); 9780 }); 9781 9782 $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) { 9783 if (this == event.target) rails.disableFormElements($(this)); 9784 }); 9785 9786 $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) { 9787 if (this == event.target) rails.enableFormElements($(this)); 9788 }); 9789 9790 $(function(){ 9791 // making sure that all forms have actual up-to-date token(cached forms contain old one) 9792 var csrf_token = $('meta[name=csrf-token]').attr('content'); 9793 var csrf_param = $('meta[name=csrf-param]').attr('content'); 9794 $('form input[name="' + csrf_param + '"]').val(csrf_token); 9795 }); 9796 } 9797 9798})( jQuery ); 9799/*! http://mths.be/placeholder v2.0.7 by @mathias */ 9800 9801;(function(window, document, $) { 9802 9803 var isInputSupported = 'placeholder' in document.createElement('input'), 9804 isTextareaSupported = 'placeholder' in document.createElement('textarea'), 9805 prototype = $.fn, 9806 valHooks = $.valHooks, 9807 hooks, 9808 placeholder; 9809 9810 if (isInputSupported && isTextareaSupported) { 9811 9812 placeholder = prototype.placeholder = function() { 9813 return this; 9814 }; 9815 9816 placeholder.input = placeholder.textarea = true; 9817 9818 } else { 9819 9820 placeholder = prototype.placeholder = function() { 9821 var $this = this; 9822 $this 9823 .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') 9824 .not('.placeholder') 9825 .bind({ 9826 'focus.placeholder': clearPlaceholder, 9827 'blur.placeholder': setPlaceholder 9828 }) 9829 .data('placeholder-enabled', true) 9830 .trigger('blur.placeholder'); 9831 return $this; 9832 }; 9833 9834 placeholder.input = isInputSupported; 9835 placeholder.textarea = isTextareaSupported; 9836 9837 hooks = { 9838 'get': function(element) { 9839 var $element = $(element); 9840 return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value; 9841 }, 9842 'set': function(element, value) { 9843 var $element = $(element); 9844 if (!$element.data('placeholder-enabled')) { 9845 return element.value = value; 9846 } 9847 if (value == '') { 9848 element.value = value; 9849 // Issue #56: Setting the placeholder causes problems if the element continues to have focus. 9850 if (element != document.activeElement) { 9851 // We can't use `triggerHandler` here because of dummy text/password inputs :( 9852 setPlaceholder.call(element); 9853 } 9854 } else if ($element.hasClass('placeholder')) { 9855 clearPlaceholder.call(element, true, value) || (element.value = value); 9856 } else { 9857 element.value = value; 9858 } 9859 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 9860 return $element; 9861 } 9862 }; 9863 9864 isInputSupported || (valHooks.input = hooks); 9865 isTextareaSupported || (valHooks.textarea = hooks); 9866 9867 $(function() { 9868 // Look for forms 9869 $(document).delegate('form', 'submit.placeholder', function() { 9870 // Clear the placeholder values so they don't get submitted 9871 var $inputs = $('.placeholder', this).each(clearPlaceholder); 9872 setTimeout(function() { 9873 $inputs.each(setPlaceholder); 9874 }, 10); 9875 }); 9876 }); 9877 9878 // Clear placeholder values upon page reload 9879 $(window).bind('beforeunload.placeholder', function() { 9880 $('.placeholder').each(function() { 9881 this.value = ''; 9882 }); 9883 }); 9884 9885 } 9886 9887 function args(elem) { 9888 // Return an object of element attributes 9889 var newAttrs = {}, 9890 rinlinejQuery = /^jQuery\d+$/; 9891 $.each(elem.attributes, function(i, attr) { 9892 if (attr.specified && !rinlinejQuery.test(attr.name)) { 9893 newAttrs[attr.name] = attr.value; 9894 } 9895 }); 9896 return newAttrs; 9897 } 9898 9899 function clearPlaceholder(event, value) { 9900 var input = this, 9901 $input = $(input); 9902 if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) { 9903 if ($input.data('placeholder-password')) { 9904 $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id')); 9905 // If `clearPlaceholder` was called from `$.valHooks.input.set` 9906 if (event === true) { 9907 return $input[0].value = value; 9908 } 9909 $input.focus(); 9910 } else { 9911 input.value = ''; 9912 $input.removeClass('placeholder'); 9913 input == document.activeElement && input.select(); 9914 } 9915 } 9916 } 9917 9918 function setPlaceholder() { 9919 var $replacement, 9920 input = this, 9921 $input = $(input), 9922 $origInput = $input, 9923 id = this.id; 9924 if (input.value == '') { 9925 if (input.type == 'password') { 9926 if (!$input.data('placeholder-textinput')) { 9927 try { 9928 $replacement = $input.clone().attr({ 'type': 'text' }); 9929 } catch(e) { 9930 $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' })); 9931 } 9932 $replacement 9933 .removeAttr('name') 9934 .data({ 9935 'placeholder-password': true, 9936 'placeholder-id': id 9937 }) 9938 .bind('focus.placeholder', clearPlaceholder); 9939 $input 9940 .data({ 9941 'placeholder-textinput': $replacement, 9942 'placeholder-id': id 9943 }) 9944 .before($replacement); 9945 } 9946 $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); 9947 // Note: `$input[0] != input` now! 9948 } 9949 $input.addClass('placeholder'); 9950 $input[0].value = $input.attr('placeholder'); 9951 } else { 9952 $input.removeClass('placeholder'); 9953 } 9954 } 9955 9956}(this, document, jQuery)); 9957/* 9958 * jQuery Orbit Plugin 1.4.0 9959 * www.ZURB.com/playground 9960 * Copyright 2010, ZURB 9961 * Free to use under the MIT license. 9962 * http://www.opensource.org/licenses/mit-license.php 9963*/ 9964 9965 9966 9967(function ($) { 9968 'use strict'; 9969 9970 $.fn.findFirstImage = function () { 9971 return this.first() 9972 .find('img') 9973 .andSelf().filter('img') 9974 .first(); 9975 }; 9976 9977 var ORBIT = { 9978 9979 defaults: { 9980 animation: 'horizontal-push', // fade, horizontal-slide, vertical-slide, horizontal-push, vertical-push 9981 animationSpeed: 600, // how fast animations are 9982 timer: true, // display timer? 9983 advanceSpeed: 4000, // if timer is enabled, time between transitions 9984 pauseOnHover: false, // if you hover pauses the slider 9985 startClockOnMouseOut: false, // if clock should start on MouseOut 9986 startClockOnMouseOutAfter: 1000, // how long after MouseOut should the timer start again 9987 directionalNav: true, // manual advancing directional navs 9988 directionalNavRightText: 'Right', // text of right directional element for accessibility 9989 directionalNavLeftText: 'Left', // text of left directional element for accessibility 9990 captions: true, // do you want captions? 9991 captionAnimation: 'fade', // fade, slideOpen, none 9992 captionAnimationSpeed: 600, // if so how quickly should they animate in 9993 resetTimerOnClick: false, // true resets the timer instead of pausing slideshow progress on manual navigation 9994 bullets: false, // true or false to activate the bullet navigation 9995 bulletThumbs: false, // thumbnails for the bullets 9996 bulletThumbLocation: '', // relative path to thumbnails from this file 9997 bulletThumbsHideOnSmall: true, // hide thumbs on small devices 9998 afterSlideChange: $.noop, // callback to execute after slide changes 9999 afterLoadComplete: $.noop, // callback to execute after everything has been loaded 10000 fluid: true, 10001 centerBullets: true, // center bullet nav with js, turn this off if you want to position the bullet nav manually 10002 singleCycle: false, // cycles through orbit slides only once 10003 slideNumber: false, // display slide numbers? 10004 stackOnSmall: false // stack slides on small devices (i.e. phones) 10005 }, 10006 10007 activeSlide: 0, 10008 numberSlides: 0, 10009 orbitWidth: null, 10010 orbitHeight: null, 10011 locked: null, 10012 timerRunning: null, 10013 degrees: 0, 10014 wrapperHTML: '<div class="orbit-wrapper" />', 10015 timerHTML: '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>', 10016 captionHTML: '<div class="orbit-caption"></div>', 10017 directionalNavHTML: '<div class="slider-nav hide-for-small"><span class="right"></span><span class="left"></span></div>', 10018 bulletHTML: '<ul class="orbit-bullets"></ul>', 10019 slideNumberHTML: '<span class="orbit-slide-counter"></span>', 10020 10021 init: function (element, options) { 10022 var $imageSlides, 10023 imagesLoadedCount = 0, 10024 self = this; 10025 10026 // Bind functions to correct context 10027 this.clickTimer = $.proxy(this.clickTimer, this); 10028 this.addBullet = $.proxy(this.addBullet, this); 10029 this.resetAndUnlock = $.proxy(this.resetAndUnlock, this); 10030 this.stopClock = $.proxy(this.stopClock, this); 10031 this.startTimerAfterMouseLeave = $.proxy(this.startTimerAfterMouseLeave, this); 10032 this.clearClockMouseLeaveTimer = $.proxy(this.clearClockMouseLeaveTimer, this); 10033 this.rotateTimer = $.proxy(this.rotateTimer, this); 10034 10035 this.options = $.extend({}, this.defaults, options); 10036 if (this.options.timer === 'false') this.options.timer = false;
10037 if (this.options.captions === 'false') this.options.captions = false; 10038 if (this.options.directionalNav === 'false') this.options.directionalNav = false; 10039 10040 this.$element = $(element); 10041 this.$wrapper = this.$element.wrap(this.wrapperHTML).parent(); 10042 this.$slides = this.$element.children('img, a, div, figure, li'); 10043 10044 this.$element.on('movestart', function(e) { 10045 // If the movestart is heading off in an upwards or downwards 10046 // direction, prevent it so that the browser scrolls normally. 10047 if ((e.distX > e.distY && e.distX < -e.distY) || 10048 (e.distX < e.distY && e.distX > -e.distY)) { 10049 e.preventDefault(); 10050 } 10051 }); 10052 10053 this.$element.bind('orbit.next', function () { 10054 self.shift('next'); 10055 }); 10056 10057 this.$element.bind('orbit.prev', function () { 10058 self.shift('prev'); 10059 }); 10060 10061 this.$element.bind('swipeleft', function () { 10062 $(this).trigger('orbit.next'); 10063 }); 10064 10065 this.$element.bind('swiperight', function () { 10066 $(this).trigger('orbit.prev'); 10067 }); 10068 10069 this.$element.bind('orbit.goto', function (event, index) { 10070 self.shift(index); 10071 }); 10072 10073 this.$element.bind('orbit.start', function (event, index) { 10074 self.startClock(); 10075 }); 10076 10077 this.$element.bind('orbit.stop', function (event, index) { 10078 self.stopClock(); 10079 }); 10080 10081 $imageSlides = this.$slides.filter('img'); 10082 10083 if ($imageSlides.length === 0) { 10084 this.loaded(); 10085 } else { 10086 $imageSlides.bind('imageready', function () { 10087 imagesLoadedCount += 1; 10088 if (imagesLoadedCount === $imageSlides.length) { 10089 self.loaded(); 10090 } 10091 }); 10092 } 10093 }, 10094 10095 loaded: function () { 10096 this.$element 10097 .addClass('orbit') 10098 .css({width: '1px', height: '1px'}); 10099 10100 if (this.options.stackOnSmall) { 10101 this.$element.addClass('orbit-stack-on-small'); 10102 } 10103 10104 this.$slides.addClass('orbit-slide').css({"opacity" : 0}); 10105 10106 this.setDimentionsFromLargestSlide(); 10107 this.updateOptionsIfOnlyOneSlide(); 10108 this.setupFirstSlide(); 10109 this.notifySlideChange(); 10110 10111 if (this.options.timer) { 10112 this.setupTimer(); 10113 this.startClock(); 10114 } 10115 10116 if (this.options.captions) { 10117 this.setupCaptions(); 10118 } 10119 10120 if (this.options.directionalNav) { 10121 this.setupDirectionalNav(); 10122 } 10123 10124 if (this.options.bullets) { 10125 this.setupBulletNav(); 10126 this.setActiveBullet(); 10127 } 10128 10129 this.options.afterLoadComplete.call(this); 10130 Holder.run(); 10131 }, 10132 10133 currentSlide: function () { 10134 return this.$slides.eq(this.activeSlide); 10135 }, 10136 10137 notifySlideChange: function() { 10138 if (this.options.slideNumber) { 10139 var txt = (this.activeSlide+1) + ' of ' + this.$slides.length; 10140 this.$element.trigger("orbit.change", {slideIndex: this.activeSlide, slideCount: this.$slides.length}); 10141 if (this.$counter === undefined) { 10142 var $counter = $(this.slideNumberHTML).html(txt); 10143 this.$counter = $counter; 10144 this.$wrapper.append(this.$counter); 10145 } else { 10146 this.$counter.html(txt); 10147 } 10148 } 10149 }, 10150 10151 setDimentionsFromLargestSlide: function () { 10152 //Collect all slides and set slider size of largest image 10153 var self = this, 10154 $fluidPlaceholder; 10155 10156 self.$element.add(self.$wrapper).width(this.$slides.first().outerWidth()); 10157 self.$element.add(self.$wrapper).height(this.$slides.first().height()); 10158 self.orbitWidth = this.$slides.first().outerWidth(); 10159 self.orbitHeight = this.$slides.first().height(); 10160 $fluidPlaceholder = this.$slides.first().findFirstImage().clone(); 10161 10162 10163 this.$slides.each(function () { 10164 var slide = $(this), 10165 slideWidth = slide.outerWidth(), 10166 slideHeight = slide.height(); 10167 10168 if (slideWidth > self.$element.outerWidth()) { 10169 self.$element.add(self.$wrapper).width(slideWidth); 10170 self.orbitWidth = self.$element.outerWidth(); 10171 } 10172 if (slideHeight > self.$element.height()) { 10173 self.$element.add(self.$wrapper).height(slideHeight); 10174 self.orbitHeight = self.$element.height(); 10175 $fluidPlaceholder = $(this).findFirstImage().clone(); 10176 } 10177 self.numberSlides += 1; 10178 }); 10179 10180 if (this.options.fluid) { 10181 if (typeof this.options.fluid === "string") { 10182 // $fluidPlaceholder = $("<img>").attr("src", "http://placehold.it/" + this.options.fluid); 10183 $fluidPlaceholder = $("<img>").attr("data-src", "holder.js/" + this.options.fluid); 10184 //var inner = $("<div/>").css({"display":"inline-block", "width":"2px", "height":"2px"}); 10185 //$fluidPlaceholder = $("<div/>").css({"float":"left"}); 10186 //$fluidPlaceholder.wrapInner(inner); 10187 10188 //$fluidPlaceholder = $("<div/>").css({"height":"1px", "width":"2px"}); 10189 //$fluidPlaceholder = $("<div style='display:inline-block;width:2px;height:1px;'></div>"); 10190 } 10191
10192 self.$element.prepend($fluidPlaceholder); 10193 $fluidPlaceholder.addClass('fluid-placeholder'); 10194 self.$element.add(self.$wrapper).css({width: 'inherit'}); 10195 self.$element.add(self.$wrapper).css({height: 'inherit'}); 10196 10197 $(window).bind('resize', function () { 10198 self.orbitWidth = self.$element.outerWidth(); 10199 self.orbitHeight = self.$element.height(); 10200 }); 10201 } 10202 }, 10203 10204 //Animation locking functions 10205 lock: function () { 10206 this.locked = true; 10207 }, 10208 10209 unlock: function () { 10210 this.locked = false; 10211 }, 10212 10213 updateOptionsIfOnlyOneSlide: function () { 10214 if(this.$slides.length === 1) { 10215 this.options.directionalNav = false; 10216 this.options.timer = false; 10217 this.options.bullets = false; 10218 } 10219 }, 10220 10221 setupFirstSlide: function () { 10222 //Set initial front photo z-index and fades it in 10223 var self = this; 10224 this.$slides.first() 10225 .css({"z-index" : 3, "opacity" : 1}) 10226 .fadeIn(function() { 10227 //brings in all other slides IF css declares a display: none 10228 self.$slides.css({"display":"block"}) 10229 }); 10230 }, 10231 10232 startClock: function () { 10233 var self = this; 10234 10235 if(!this.options.timer) { 10236 return false; 10237 } 10238 10239 if (this.$timer.is(':hidden')) { 10240 this.clock = setInterval(function () { 10241 self.$element.trigger('orbit.next'); 10242 }, this.options.advanceSpeed); 10243 } else { 10244 this.timerRunning = true; 10245 this.$pause.removeClass('active'); 10246 this.clock = setInterval(this.rotateTimer, this.options.advanceSpeed / 180, false); 10247 } 10248 }, 10249 10250 rotateTimer: function (reset) { 10251 var degreeCSS = "rotate(" + this.degrees + "deg)"; 10252 this.degrees += 2; 10253 this.$rotator.css({ 10254 "-webkit-transform": degreeCSS, 10255 "-moz-transform": degreeCSS, 10256 "-o-transform": degreeCSS, 10257 "-ms-transform": degreeCSS 10258 }); 10259 if (reset) { 10260 this.degrees = 0; 10261 this.$rotator.removeClass('move'); 10262 this.$mask.removeClass('move'); 10263 } 10264 if(this.degrees > 180) { 10265 this.$rotator.addClass('move'); 10266 this.$mask.addClass('move'); 10267 } 10268 if(this.degrees > 360) { 10269 this.$rotator.removeClass('move'); 10270 this.$mask.removeClass('move'); 10271 this.degrees = 0; 10272 this.$element.trigger('orbit.next'); 10273 } 10274 }, 10275 10276 stopClock: function () { 10277 if (!this.options.timer) { 10278 return false; 10279 } else { 10280 this.timerRunning = false; 10281 clearInterval(this.clock); 10282 this.$pause.addClass('active'); 10283 } 10284 }, 10285 10286 setupTimer: function () { 10287 this.$timer = $(this.timerHTML); 10288 this.$wrapper.append(this.$timer); 10289 10290 this.$rotator = this.$timer.find('.rotator'); 10291 this.$mask = this.$timer.find('.mask'); 10292 this.$pause = this.$timer.find('.pause'); 10293 10294 this.$timer.click(this.clickTimer); 10295 10296 if (this.options.startClockOnMouseOut) { 10297 this.$wrapper.mouseleave(this.startTimerAfterMouseLeave); 10298 this.$wrapper.mouseenter(this.clearClockMouseLeaveTimer); 10299 } 10300 10301 if (this.options.pauseOnHover) { 10302 this.$wrapper.mouseenter(this.stopClock); 10303 } 10304 }, 10305 10306 startTimerAfterMouseLeave: function () { 10307 var self = this; 10308 10309 this.outTimer = setTimeout(function() { 10310 if(!self.timerRunning){ 10311 self.startClock(); 10312 } 10313 }, this.options.startClockOnMouseOutAfter) 10314 }, 10315 10316 clearClockMouseLeaveTimer: function () { 10317 clearTimeout(this.outTimer); 10318 }, 10319 10320 clickTimer: function () { 10321 if(!this.timerRunning) { 10322 this.startClock(); 10323 } else { 10324 this.stopClock(); 10325 } 10326 }, 10327 10328 setupCaptions: function () { 10329 this.$caption = $(this.captionHTML); 10330 this.$wrapper.append(this.$caption); 10331 this.setCaption(); 10332 }, 10333 10334 setCaption: function () { 10335 var captionLocation = this.currentSlide().attr('data-caption'), 10336 captionHTML; 10337 10338 if (!this.options.captions) { 10339 return false; 10340 } 10341 10342 //Set HTML for the caption if it exists 10343 if (captionLocation) { 10344 //if caption text is blank, don't show captions 10345 if ($.trim($(captionLocation).text()).length < 1){ 10346 return false;
10347 } 10348 10349 // if location selector starts with '#', remove it so we don't see id="#selector" 10350 if (captionLocation.charAt(0) == '#') { 10351 captionLocation = captionLocation.substring(1, captionLocation.length); 10352 } 10353 captionHTML = $('#' + captionLocation).html(); //get HTML from the matching HTML entity 10354 this.$caption 10355 .attr('id', captionLocation) // Add ID caption TODO why is the id being set? 10356 .html(captionHTML); // Change HTML in Caption 10357 //Animations for Caption entrances 10358 switch (this.options.captionAnimation) { 10359 case 'none': 10360 this.$caption.show(); 10361 break; 10362 case 'fade': 10363 this.$caption.fadeIn(this.options.captionAnimationSpeed); 10364 break; 10365 case 'slideOpen': 10366 this.$caption.slideDown(this.options.captionAnimationSpeed); 10367 break; 10368 } 10369 } else { 10370 //Animations for Caption exits 10371 switch (this.options.captionAnimation) { 10372 case 'none': 10373 this.$caption.hide(); 10374 break; 10375 case 'fade': 10376 this.$caption.fadeOut(this.options.captionAnimationSpeed); 10377 break; 10378 case 'slideOpen': 10379 this.$caption.slideUp(this.options.captionAnimationSpeed); 10380 break; 10381 } 10382 } 10383 }, 10384 10385 setupDirectionalNav: function () { 10386 var self = this, 10387 $directionalNav = $(this.directionalNavHTML); 10388 10389 $directionalNav.find('.right').html(this.options.directionalNavRightText); 10390 $directionalNav.find('.left').html(this.options.directionalNavLeftText); 10391 10392 this.$wrapper.append($directionalNav); 10393 10394 this.$wrapper.find('.left').click(function () { 10395 self.stopClock(); 10396 if (self.options.resetTimerOnClick) { 10397 self.rotateTimer(true); 10398 self.startClock(); 10399 } 10400 self.$element.trigger('orbit.prev'); 10401 }); 10402 10403 this.$wrapper.find('.right').click(function () { 10404 self.stopClock(); 10405 if (self.options.resetTimerOnClick) { 10406 self.rotateTimer(true); 10407 self.startClock(); 10408 } 10409 self.$element.trigger('orbit.next'); 10410 }); 10411 }, 10412 10413 setupBulletNav: function () { 10414 this.$bullets = $(this.bulletHTML); 10415 this.$wrapper.append(this.$bullets); 10416 this.$slides.each(this.addBullet); 10417 this.$element.addClass('with-bullets'); 10418 if (this.options.centerBullets) this.$bullets.css('margin-left', -this.$bullets.outerWidth() / 2); 10419 if (this.options.bulletThumbsHideOnSmall) this.$bullets.addClass('hide-for-small'); 10420 }, 10421 10422 addBullet: function (index, slide) { 10423 var position = index + 1, 10424 $li = $('<li>' + (position) + '</li>'), 10425 thumbName, 10426 self = this; 10427 10428 if (this.options.bulletThumbs) { 10429 thumbName = $(slide).attr('data-thumb'); 10430 if (thumbName) { 10431 $li 10432 .addClass('has-thumb') 10433 .css({background: "url(" + this.options.bulletThumbLocation + thumb
10433Name + ") no-repeat"});; 10434 } 10435 } 10436 this.$bullets.append($li); 10437 $li.data('index', index); 10438 $li.click(function () { 10439 self.stopClock(); 10440 if (self.options.resetTimerOnClick) { 10441 self.rotateTimer(true); 10442 self.startClock(); 10443 } 10444 self.$element.trigger('orbit.goto', [$li.data('index')]) 10445 }); 10446 }, 10447 10448 setActiveBullet: function () { 10449 if(!this.options.bullets) { return false; } else { 10450 this.$bullets.find('li') 10451 .removeClass('active') 10452 .eq(this.activeSlide) 10453 .addClass('active'); 10454 } 10455 }, 10456 10457 resetAndUnlock: function () { 10458 this.$slides 10459 .eq(this.prevActiveSlide) 10460 .css({"z-index" : 1}); 10461 this.unlock(); 10462 this.options.afterSlideChange.call(this, this.$slides.eq(this.prevActiveSlide), this.$slides.eq(this.activeSlide)); 10463 }, 10464 10465 shift: function (direction) { 10466 var slideDirection = direction; 10467 10468 //remember previous activeSlide 10469 this.prevActiveSlide = this.activeSlide; 10470 10471 //exit function if bullet clicked is same as the current image 10472 if (this.prevActiveSlide == slideDirection) { return false; } 10473 10474 if (this.$slides.length == "1") { return false; } 10475 if (!this.locked) { 10476 this.lock(); 10477 //deduce the proper activeImage 10478 if (direction == "next") { 10479 this.activeSlide++; 10480 if (this.activeSlide == this.numberSlides) { 10481 this.activeSlide = 0; 10482 } 10483 } else if (direction == "prev") { 10484 this.activeSlide-- 10485 if (this.activeSlide < 0) { 10486 this.activeSlide = this.numberSlides - 1; 10487 } 10488 } else { 10489 this.activeSlide = direction; 10490 if (this.prevActiveSlide < this.activeSlide) { 10491 slideDirection = "next"; 10492 } else if (this.prevActiveSlide > this.activeSlide) { 10493 slideDirection = "prev" 10494 } 10495 } 10496 10497 //set to correct bullet 10498 this.setActiveBullet(); 10499 this.notifySlideChange(); 10500 10501 //set previous slide z-index to one below what new activeSlide will be 10502 this.$slides 10503 .eq(this.prevActiveSlide) 10504 .css({"z-index" : 2}); 10505 10506 //fade 10507 if (this.options.animation == "fade") { 10508 this.$slides 10509 .eq(this.activeSlide) 10510 .css({"opacity" : 0, "z-index" : 3}) 10511 .animate({"opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock); 10512 this.$slides 10513 .eq(this.prevActiveSlide) 10514 .animate({"opacity":0}, this.options.animationSpeed); 10515 } 10516 10517 //horizontal-slide 10518 if (this.options.animation == "horizontal-slide") { 10519 if (slideDirection == "next") { 10520 this.$slides 10521 .eq(this.activeSlide) 10522 .css({"left": this.orbitWidth, "z-index" : 3}) 10523 .css("opacity", 1) 10524 .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock); 10525 } 10526 if (slideDirection == "prev") { 10527 this.$slides 10528 .eq(this.activeSlide) 10529 .css({"left": -this.orbitWidth, "z-index" : 3}) 10530 .css("opacity", 1) 10531 .animate({"left" : 0}, this.options.animationSpeed, this.resetAndUnlock); 10532 } 10533 this.$slides 10534 .eq(this.prevActiveSlide) 10535 .css("opacity", 0); 10536 } 10537 10538 //vertical-slide 10539 if (this.options.animation == "vertical-slide") { 10540 if (slideDirection == "prev") { 10541 this.$slides 10542 .eq(this.activeSlide) 10543 .css({"top": this.orbitHeight, "z-index" : 3}) 10544 .css("opacity", 1) 10545 .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock); 10546 this.$slides 10547 .eq(this.prevActiveSlide) 10548 .css("opacity", 0); 10549 } 10550 if (slideDirection == "next") { 10551 this.$slides 10552 .eq(this.activeSlide) 10553 .css({"top": -this.orbitHeight, "z-index" : 3}) 10554 .css("opacity", 1) 10555 .animate({"top" : 0}, this.options.animationSpeed, this.resetAndUnlock); 10556 } 10557 this.$slides 10558 .eq(this.prevActiveSlide) 10559 .css("opacity", 0); 10560 } 10561 10562 //horizontal-push 10563 if (this.options.animation == "horizontal-push") { 10564 if (slideDirection == "next") { 10565 this.$slides 10566 .eq(this.activeSlide) 10567 .css({"left": this.orbitWidth, "z-index" : 3}) 10568 .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock); 10569 this.$slides 10570 .eq(this.prevActiveSlide) 10571 .animate({"left" : -this.orbitWidth}, this.options.animationSpeed, "", function(){ 10572 $(this).css({"opacity" : 0}); 10573 }); 10574 } 10575 if (slideDirection == "prev") { 10576 this.$slides 10577 .eq(this.activeSlide) 10578 .css({"left": -this.orbitWidth, "z-index" : 3}) 10579 .animate({"left" : 0, "opacity" : 1}, this.options.animationSpeed, this.resetAndUnlock); 10580 this.$slides 10581 .eq(this.prevActiveSlide) 10582 .animate({"left" : this.orbitWidth}, this.options.animationSpeed, "", function(){ 10583 $(this).css({"opacity" : 0}); 10584 }); 10585 } 10586 } 10587 10588 //vertical-push 10589 if (this.options.animation == "vertical-push") { 10590 if (slideDirection == "next") { 10591 this.$slides 10592 .eq(this.activeSlide) 10593 .css({top: -this.orbitHeight, "z-index" : 3}) 10594 .css("opacity", 1) 10595 .animate({top : 0, "opacity":1}, this.options.animationSpeed, this.resetAndUnlock); 10596 this.$slides 10597 .eq(this.prevActiveSlide) 10598 .css("opacity", 0) 10599 .animate({top : this.orbitHeight}, this.options.animationSpeed, ""); 10600 } 10601 if (slideDirection == "prev") { 10602 this.$slides 10603 .eq(this.activeSlide) 10604 .css({top: this.orbitHeight, "z-index" : 3}) 10605 .css("opacity", 1) 10606 .animate({top : 0}, this.options.animationSpeed, this.resetAndUnlock); 10607 this.$slides 10608 .eq(this.prevActiveSlide) 10609 .css("opacity", 0) 10610 .animate({top : -this.orbitHeight}, this.options.animationSpeed); 10611 } 10612 } 10613 10614 this.setCaption(); 10615 } 10616 10617 // if on last slide and singleCycle is true, don't loop through slides again 10618 // .length is zero based so must minus 1 to match activeSlide index 10619 if (this.activeSlide === this.$slides.length-1 && this.options.singleCycle) { 10620 this.stopClock(); 10621 } 10622 } 10623 }; 10624 10625 $.fn.orbit = function (options) { 10626 return this.each(function () { 10627 var orbit = $.extend({}, ORBIT); 10628 orbit.init(this, options); 10629 }); 10630 }; 10631 10632})(jQuery); 10633 10634/*! 10635 * jQuery imageready Plugin 10636 * http://www.zurb.com/playground/ 10637 * 10638 * Copyright 2011, ZURB 10639 * Released under the MIT License 10640 */ 10641(function ($) { 10642 10643 var options = {}; 10644 10645 $.event.special.imageready = { 10646 10647 setup: function (data, namespaces, eventHandle) { 10648 options = data || options; 10649 }, 10650 10651 add: function (handleObj) { 10652 var $this = $(this), 10653 src; 10654 10655 if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) { 10656 if (options.forceLoad) { 10657 src = $this.attr('src'); 10658 $this.attr('src', ''); 10659 bindToLoad(this, handleObj.handler); 10660 $this.attr('src', src); 10661 } else if ( this.complete || this.readyState === 4 ) { 10662 handleObj.handler.apply(this, arguments); 10663 } else { 10664 bindToLoad(this, handleObj.handler); 10665 } 10666 } 10667 }, 10668 10669 teardown: function (namespaces) { 10670 $(this).unbind('.imageready'); 10671 } 10672 }; 10673 10674 function bindToLoad(element, callback) { 10675 var $this = $(element); 10676 10677 $this.bind('load.imageready', function () { 10678 callback.apply(element, arguments); 10679 $this.unbind('load.imageready'); 10680 }); 10681 } 10682 10683}(jQuery)); 10684 10685/* 10686 10687Holder - 1.3 - client side image placeholders 10688(c) 2012 Ivan Malopinsky / http://imsky.co 10689 10690Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0 10691Commercial use requires attribution. 10692 10693*/ 10694 10695var Holder = Holder || {}; 10696(function (app, win) { 10697 10698var preempted = false, 10699fallback = false, 10700canvas = document.createElement('canvas'); 10701 10702//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications 10703function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}}; 10704 10705//https://gist.github.com/991057 by Jed Schmidt with modifications 10706function selector(a){
10707 a=a.match(/^(\W)?(.*)/);var b=document["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2]); 10708 var ret=[]; b!=null&&(b.length?ret=b:b.length==0?ret=b:ret=[b]); return ret; 10709} 10710 10711//shallow object property extend 10712function extend(a,b){var c={};for(var d in a)c[d]=a[d];for(var e in b)c[e]=b[e];return c} 10713 10714function draw(ctx, dimensions, template) { 10715 var dimension_arr = [dimensions.height, dimensions.width].sort(); 10716 var maxFactor = Math.round(dimension_arr[1] / 16), 10717 minFactor = Math.round(dimension_arr[0] / 16); 10718 var text_height = Math.max(template.size, maxFactor); 10719 canvas.width = dimensions.width; 10720 canvas.height = dimensions.height; 10721 ctx.textAlign = "center"; 10722 ctx.textBaseline = "middle"; 10723 ctx.fillStyle = template.background; 10724 ctx.fillRect(0, 0, dimensions.width, dimensions.height); 10725 ctx.fillStyle = template.foreground; 10726 ctx.font = "bold " + text_height + "px sans-serif"; 10727 var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height); 10728 if (Math.round(ctx.measureText(text).width) / dimensions.width > 1) { 10729 text_height = Math.max(minFactor, template.size); 10730 } 10731 ctx.font = "bold " + text_height + "px sans-serif"; 10732 ctx.fillText(text, (dimensions.width / 2), (dimensions.height / 2), dimensions.width); 10733 return canvas.toDataURL("image/png"); 10734} 10735 10736if (!canvas.getContext) { 10737 fallback = true; 10738} else { 10739 if (canvas.toDataURL("image/png").indexOf("data:image/png") < 0) { 10740 //Android doesn't support data URI 10741 fallback = true; 10742 } else { 10743 var ctx = canvas.getContext("2d"); 10744 } 10745} 10746 10747var settings = { 10748 domain: "holder.js", 10749 images: "img", 10750 themes: { 10751 "gray": { 10752 background: "#eee", 10753 foreground: "#aaa", 10754 size: 12 10755 }, 10756 "social": { 10757 background: "#3a5a97", 10758 foreground: "#fff", 10759 size: 12 10760 }, 10761 "industrial": { 10762 background: "#434A52", 10763 foreground: "#C2F200", 10764 size: 12 10765 } 10766 } 10767}; 10768 10769 10770 10771app.flags = { 10772 dimensions: { 10773 regex: /([0-9]+)x([0-9]+)/, 10774 output: function(val){ 10775 var exec = this.regex.exec(val); 10776 return { 10777 width: +exec[1], 10778 height: +exec[2] 10779 } 10780 } 10781 }, 10782 colors: { 10783 regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i, 10784 output: function(val){ 10785 var exec = this.regex.exec(val); 10786 return { 10787 size: settings.themes.gray.size, 10788 foreground: "#" + exec[2], 10789 background: "#" + exec[1] 10790 } 10791 } 10792 }, 10793 text: { 10794 regex: /text\:(.*)/, 10795 output: function(val){ 10796 return this.regex.exec(val)[1]; 10797 } 10798 } 10799} 10800 10801for(var flag in app.flags){ 10802 app.flags[flag].match = function (val){ 10803 return val.match(this.regex) 10804 } 10805} 10806 10807app.add_theme = function (name, theme) { 10808 name != null && theme != null && (settings.themes[name] = theme); 10809 return app; 10810}; 10811 10812app.add_image = function (src, el) { 10813 var node = selector(el); 10814 if (node.length) { 10815 for (var i = 0, l = node.length; i < l; i++) { 10816 var img = document.createElement("img") 10817 img.setAttribute("data-src", src); 10818 node[i].appendChild(img); 10819 } 10820 } 10821 return app; 10822}; 10823 10824app.run = function (o) { 10825 var options = extend(settings, o), 10826 images = selector(options.images), 10827 preempted = true; 10828 10829 for (var l = images.length, i = 0; i < l; i++) { 10830 var theme = settings.themes.gray; 10831 var src = images[i].getAttribute("data-src") || images[i].getAttribute("src"); 10832 if (src && !! ~src.indexOf(options.domain)) { 10833 var render = false, 10834 dimensions = null, 10835 text = null; 10836 var flags = src.substr(src.indexOf(options.domain) + options.domain.length + 1).split("/"); 10837 for (sl = flags.length, j = 0; j < sl; j++) { 10838 if (app.flags.dimensions.match(flags[j])) { 10839 render = true; 10840 dimensions = app.flags.dimensions.output(flags[j]); 10841 } else if (app.flags.colors.match(flags[j])) { 10842 theme = app.flags.colors.output(flags[j]); 10843 } else if (options.themes[flags[j]]) { 10844 //If a theme is specified, it will override custom colors 10845 theme = options.themes[flags[j]]; 10846 } else if (app.flags.text.match(flags[j])) { 10847 text = app.flags.text.output(flags[j]); 10848 } 10849 } 10850 if (render) { 10851 images[i].setAttribute("data-src", src); 10852 var dimensions_caption = dimensions.width + "x" + dimensions.height; 10853 images[i].setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); 10854 10855 // Fallback 10856 // images[i].style.width = dimensions.width + "px"; 10857 // images[i].style.height = dimensions.height + "px"; 10858 images[i].style.backgroundColor = theme.background; 10859 10860 var theme = (text ? extend(theme, { 10861 text: text 10862 }) : theme); 10863 10864 if (!fallback) { 10865 images[i].setAttribute("src", draw(ctx, dimensions, theme)); 10866 } 10867 } 10868 } 10869 } 10870 return app; 10871}; 10872contentLoaded(win, function () { 10873 preempted || app.run() 10874}) 10875 10876})(Holder, window); 10877;(function ($, window, undefined) { 10878 'use strict'; 10879 10880 $.fn.foundationMediaQueryViewer = function (options) { 10881 var settings = $.extend(options,{toggleKey:77}), // Press 'M' 10882 $doc = $(document); 10883 10884 $doc.on("keyup.mediaQueryViewer", ":input", function (e){ 10885 if (e.which === settings.toggleKey) { 10886 e.stopPropagation(); 10887 } 10888 }); 10889 $doc.on("keyup.mediaQueryViewer", function (e) { 10890 var $mqViewer = $('#fqv'); 10891 10892 if (e.which === settings.toggleKey) { 10893 if ($mqViewer.length > 0) { 10894 $mqViewer.remove(); 10895 } else { 10896 $('body').prepend('<div id="fqv" style="position:fixed;top:4px;left:4px;z-index:999;color:#fff;"><p style="font-size:12px;background:rgba(0,0,0,0.75);padding:5px;margin-bottom:1px;line-height:1.2;"><span class="left">Media:</span> <span style="font-weight:bold;" class="show-for-xlarge">Extra Large</span><span style="font-weight:bold;" class="show-for-large">Large</span><span style="font-weight:bold;" class="show-for-medium">Medium</span><span style="font-weight:bold;" class="show-for-small">Small</span><span style="font-weight:bold;" class="show-for-landscape">Landscape</span><span style="font-weight:bold;" class="show-for-portrait">Portrait</span><span style="font-weight:bold;" class="show-for-touch">Touch</span></p></div>'); 10897 } 10898 } 10899 }); 10900 10901 }; 10902 10903})(jQuery, this); 10904/* 10905********************************************************** 10906* prettyEmbed.js | https://github.com/mike-zarandona/prettyembed.js 10907* 10908* Version: v1.2.1 10909* Author: Mike Zarandona 10910* Release: July 31 2014 10911* 10912* Reqs: jQuery | http://jquery.com 10913* waitForImages | https://github.com/alexanderdickson/waitForImages 10914* 10915* Optional: FitVids.js | http://fitvidsjs.com 10916* 10917* Usage: $('#video-placeholder-element').prettyEmbed({ 10918* videoID: 'aBcDeFg12345', 10919* previewSize: '', 10920* customPreviewImage: '', 10921* 10922* showInfo: true, 10923* showControls: true, 10924* loop: false, 10925* closedCaptions: false, 10926* colorScheme: 'dark', 10927* showRelated: false, 10928* 10929* useFitVids: true 10930* }); 10931********************************************************** 10932*/ 10933 10934 10935(function ($, undefined) { 10936 $.fn.prettyEmbed = function (options) { 10937 10938 // Override defaults with specified options 10939 options = $.extend({}, $.fn.prettyEmbed.options, options); 10940 10941 // Test for mobile devices 10942 var mobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent))? true : false;
10943 10944 // Inject styles if not already present 10945 if ( $('#pretty-embed-style').length === 0 ) { 10946 var styles = $('<style />', { 10947 id: 'pretty-embed-style', 10948 html: '.pretty-embed{position:relative;cursor:pointer;display:block}.pretty-embed img{width:100%;height:auto}.pretty-embed iframe{border:0 solid transparent}.pretty-embed:after{display:block;content:"";position:absolute;top:50%;margin-top:-19px;left:50%;margin-left:-27px;width:54px;height:38px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABMCAYAAACIylL7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAABmxJREFUeF7t3W9MVlUcB3BNs3Kt1h/XC9eL6kWCAg6E8h/YMLKFm4v+GNZCfYHQnDoNVzjLYbZG8SLCVqSrHGgWtnDWbK1CK/sHi5oF8n+9IMcqiIqA6PT9Xs6Nx+tPAkSec+9zfu7zgnvuOffhfr3Avc997pk0XjUrahZNgytgJsyCRFgC6XAfZEEObIZ8KIBCeB5eglehHN6Cd+Bd+AA+huPwBXwF30At/KDVQ9P/OAXu+t8Cx/gaOOYnUAXc1ntQCRWwH16Dl6EYnoWdsA22QC6shvthOdwGSRAN18OVcAlM1rtpYgsbZiCLYRO8CIeBO7AZfoG/4B9QloP7gvvkV2iBGuB/Qv4HyINUmK537/gVBo2BV6ATpBdmjd0fwJ8qt4Le42MsDHA17IW/QdqYNX54NB6CmXr3j67QMQHaQBrcunA6IFXHMLJChxT4TQ9gTbxeyNBxDF9Y8Wawv6vCj3+sLNCxyIUVLoLPdAcr/BrgUh3P2YVGnitJHa3w2aTjObPQMBl4Iil1ssLnR7hYxzRUWMirElIHK/xW6JiGCguLPCtZ5jigYxosLKDGkBUss3TBNB2XE9hNIY2WmZJ1XE5gD3saLfPk67icwEo8jZZ53tZxOYF95Gm0zHNKx+UExjf4pJUsc/wOUxnWVP2FtJJllhkM7BrPQstcsQyM9x9IjZZ5bmdgvElGajTK7DmzVXxCvNgWQR5kYPd6FhppXuI8dfr0abVjxw4VFxcnrhMBNjIw3nYmNRqFgQ0MDChWU1OT2rxls5oTM0dcN8B2MjDeHyg1GiU0MFZfX5+qrq5WuY/kqujZ0WKfANrNwHhzpNRoFG9gbnV1damqqiq1Zu0aFRUdJfYNkP0MjDc1So1GOVdgLB5t7e3t6uj7R1Xmqkyxf0AcYWAHPAuNNFxgbvFoa2trU5WHK1XGPRniOD53nIHxdmup0SgjCYzlHm0tLS3q4JsHVfrydHE8n6phYB96FhpppIG55R5tDG7fvn0qLS1NHNdn6hmYL25rG21gLPdoa21tdU4FSktLVcqSFHF8n2hjYL64U2osgbnlHm0MrqGhQRUXF6uFixaK2zFcOwPj56SkRqOcT2Cs0KON6urqVGFhoUq6JUncnqE6IiYwtzo7O/872ujkyZOqYGeBX65TRl5gLO/RRrW1tSp/W76Km2v0dcrIDMyt0N9tLl7u4nXKmNgY8XWEWWQHxpKONjpx4oTKyc0RX0sY2cDcCj3ampubB8/d7jDu3M0GFlq9vb2qoqLC5KsjNjC3+CNw5QMrxW0bxAZWU1OjslZnids0UOQGxvOv7HXZKirKV++hRV5gjY2NasPGDX59lzpyAuNfgHlb85y7r6TxfcIJLNAXf3mOtf2J7aaeCI+Wc/E3kG+vdHR0qF1P7zL9UtNotTKwQL2ByYu7RUVFQb3p1HkDMxC3CHR3d6uS3SUqMSlR7B8Qzi0CfCag1GiUcwXW09Oj9uzdo+YvmC/2C5hjDMyXt7nxMlJZWZlKTkkW1w8o5zY3PhFUajSKG1h/f79zvS91aaq4XsCVM7DHPQuNlDAvwbnfcNmdy8T2CFHCwHzxYQjLUcDAfPFxI8vhfNzIFx/osxyrGBj/SY2WeZyPzPJBzPbR5f4Qw8CmgH3sgz9c6z5YxT7JzXyDD1bRgfniAnCEq3fCYuELzisirWSZ45COywnsIU+jZZ7HdFxOYDd4Gi3zLNJxOYERp2uSVrTCjxM/nPlkbSzwxVX7CFWuYxoqLIz3rGSZI13HNFRYSJytTupghU8rDJ5/eQsNd4esaJlhvY7n7EIjp/PgXJBSR2vicb7OoefVS4UV+Az7n3UHK3z+hEQdy/CFFTkfIychlQayLrweuEvHMbJCBz5a9ns9gDVx2mGxjmF0hY6XwZPAuT+kwa3xMwCcbfa6wb1/HoVBroL1cAz6QNqgNTa8isGZfOeC3uPjWBj0cuDk29nwDLwBnHybE5N1g51CeAj3Bd/H+gn4F9+nwBnYOTM8D4CFMPxfgReysHHOoTkdZsCNEAvzYSlw6nd3evt1sAG2wnZ4Ctwp7jkD+x54HfgsR36DnGr+CHDqeU47wiP9c/gS+Pm20GnuvVPau9z274B9qoEXCrgTOZ47rT0/a8D5lLltTmtfCi/Ac8DXydf7KHCHr4VMWAFpsAD4PfN75z7gvpiid8841KRJ/wIcsey9MCgPGwAAAABJRU5ErkJggg==);-webkit-background-size:cover;background-size:cover}.pretty-embed.play:after{display:none}.pretty-embed:hover:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABMCAYAAACIylL7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAABwhJREFUeF7t3GlsVFUYBuCDIi4xGreA1O6dmXbaYQ2oCAriGjUuRDSiETVRISGCu2BcAH8gagKKpnWJ5UcBFVQIGhMDFGwVGcqU0m2WtkPpIqNSbEHaQj/fM5yh9HLAAlP6TTlv8iSdc+899/a8PenMnxHRSp3LIQ2ASyAO0mEUjIe7YTJMhWnwAsyBebAQFkM2fAl58A18Dz/Az7ABNsFm2AIeKIZypRIC/8MLkfO3g5zDDXLOXyAf5L1+hNWwEpZBLuTAh/AezIfX4UWYDk/AQ3APTIDR4IR4uBTOh35qmc5sdmU5BsC4XS7HLPgE1sAWqIK/4QB0ABlhci3kmuyBaiiCHyAHXsZaToSL1PJGL5jUBZ9BE5ARVfsgD64DteKnmNos++W1WY4v4CCQ0aM6YBXEqeU/uaCskRAETGacQSGYqGroXnZm2m+Cf4CMXtEKk1QdJw5OdECTutDoPQdgjKpFn2Cm/RwoBDJY8MEFqp5jE3TaJ1suMHrfLFVP19Q47f3ADWSwUgvnqZo6g8FRR51k8HKfqqkz1U77B0AGS8tVTYdTnWGT/EAGS3thgKpLiKoMWyqQwdqNqq5wYY9bDhr8zFF1CRHIsC0BMlj7VtWFwtJt64EM1ryqLiH86bYAkMFaC/SXZfVXL3QnGbxcJXyOtCuAjJgwRBbmtAwafN0qvI608UDc+ZwO8g8fqj12FnlUFvagZZAl/8hh1PZHI9W99Sb5XJnac84CM0WlPW0aEHe+EcOIDh0imWa/n2qen0VeZ7r23D5svixsjmWQpaMLk2lva6PQVjdVTXuWKtPt2mv6oI9FhT3tPSDuvJbCItm3dy/V5+dT4ImpVOGwaa/tQ5aJCltaDhB33uH6wmTkbvuroYHqfvqJ/A8/pL2+j1grym2py4G4q8Q7xOMVFkkLdtsfwSDtWv09+e6/VztPjNskC1tjGWSpO4XJRHZbY3U11X61grx33qGdL0YVibK01HVA3FV0s7BIIrtNFrdzaS5VTpygnTfGVMrCCi2DLFUMO7nCZI7stpoaagwEKJidTRVjb9DOHyOCojQt1Q3E3akUFsmR3SaL8/moZtEiKr92tPY+zDXIwjyWQZbKT6MwmS67DRoqKqh6wQIqGzFcez+mQmJHaqoHiLuyoadXWCQtTU2du00WV1pKVW+/TaUul/a+zMjCUlBYCl7wVjZ0SFQKk7HuNqne46HAq69SqTNDe38mQqIEhQFxF83CIunyvy1SnNtN/pkzaUe6Q/scvQyFpaCwFLxgrrQHCpPR7TaprrCQvE8/rX2WXhQS21EYEHelQ3qmsEi67LaqKgrm5lLZhAnaZ+lFsVPYjh4uTKa9tZV2ff01ld1+u/YZGAiJYhQGxF1PF9ZcUEC+SZO092YEhSWjsGS8YG6Hq2cK2+feSoEpU7T3ZCgkPCgMiLuSKBe2v6SEqp58ijz4y9XdjylZWDIKS8YL3krwwTYahf3r9VLN9OnkwQd
10948R3X2YC4ltSckeIO62Z51eYQfw7i8463kUlaadP0aEC3NbBlk61cLa6utp5+zZ5LHZtfPGmAZRlJRcCMRd8UkW1rZ7N9XOnUvbHOna+WJUjSxsnWWQpe4W1r5nD9UteJc8zkztPDGuUmxNTF4DxJ0n88SFHWxupvpFi8njGqq9vo8okoUtswyydLzCDu3fT43ZOVQ8fKT2uj5mo3AnJuUAcbfNUlhHayvtzl1KxaOv1Z7fR60V7oSkhUDcbcvMChfW0d5OoRVf0fYxY7Xn9XF5YktC0mwg7orwJuLPb7+jkvE3a4+fJZbIwqZZBg2+5onf45MeBDJiwkxZ2HjLoMHXFLE5PikDyIgJt8rCLoeOowYNvlzit2sSz4UWIIO9K8NfrIIf/JYDBj9yU/UPF/brNYnrgAzWKsNlyfwal/ghkMHaKlWXEIVxiY8BGay9puoKF5ZsOWjwM1bVFS5MFMQleoEMlpqg6zdrFwxOXAhksJSnaurML4MTRgAZLN2tauoMBqXNR51k8FADhz9/WbNpcMIDm65OIIORwQkzVD3HBif0g/wuFxi9qRw6v69el41XJ6TCX0BGr9oPo1QtJw5OvA7+VhcaZ96/cJeqo3vJH5TghDIg44xqgHGqhpMLLrwwf1D8W7AXMJnRgw5BHtZ8oFr+U8+GQfGXwQzYCG1ARtQ0wRcwDNSKRzGY9GIYB89sGBi/AFbAFqiFZjgIZITJtWiBRiiHAlgJi0FugBvgxO8CezLrB8afAxfBVZACQ+B6uAXugckwFZ6F5+AVeAPegYWwGD6Bz2EpLIeVsBrWws+wHjbCb/A7eKAYypXAcUSOl4C8ZitshgKQ88m5f4Q1sArkvXPhU/gI3gf5nPJ5X4IZ8BQ8AvfBbTAG5O8sf3e5BnItzlXLE4UI8R86m8y4ltOs9gAAAABJRU5ErkJggg==)}' 10949 }).appendTo('head'); 10950 } 10951 10952 // Error Checking 10953 if (options.useFitVids) { 10954 if (!$.isFunction($.fn.fitVids)) { 10955 console.error('PrettyEmbed.js Error: options.useFitVids is set to true; FitVids not found!'); 10956 } 10957 } 10958 10959 // Store $('this') in a variable to minimize DOM searches 10960 var elem; 10961 10962 // if no selector, only fire on .pretty-embed 10963 if ( $(this).length === 0 ) { elem = $('.pretty-embed'); } 10964 else { elem = $(this); } 10965 10966 // Main setup loop 10967 elem.each(function() { 10968 10969 // Tag the selected elements 10970 $(this).addClass('pretty-embed'); 10971 10972 var $newDOMElement, 10973 thisVideoID = '', 10974 thisPreviewSize = '', 10975 thisCustomPreviewImage = '', 10976 thisShowInfo, 10977 thisShowControls, 10978 thisLoop, 10979 thisClosedCaptions, 10980 thisLocalization, 10981 thisColorScheme, 10982 thisShowRelated, 10983 thisAllowFullScreen, 10984 fullScreenFlag; 10985 10986 // videoID 10987 if ( $(this).attr('data-pe-videoid') !== undefined ) { thisVideoID = $(this).attr('data-pe-videoid'); } 10988 else if ( $(this).attr('href') !== undefined ) { thisVideoID = youtube_parser( $(this).attr('href') ); } 10989 else { thisVideoID = options.videoID; } 10990 10991 // previewsize 10992 if ( $(this).attr('data-pe-preview-size') !== undefined ) { thisPreviewSize = $(this).attr('data-pe-preview-size'); } 10993 else if ( options.previewSize !== undefined ) { thisPreviewSize = options.previewSize; } 10994 else { thisPreviewSize = undefined; } 10995 10996 // custom placeholder 10997 if ( $(this).attr('data-pe-custom-preview-image') !== undefined ) { thisCustomPreviewImage = $(this).attr('data-pe-custom-preview-image'); } 10998 else if ( options.customPreviewImage !== undefined ) { thisCustomPreviewImage = options.customPreviewImage; } 10999 else { thisCustomPreviewImage = undefined; } 11000 11001 // showinfo 11002 if ( $(this).attr('data-pe-show-info') !== undefined ) { thisShowInfo = $(this).attr('data-pe-show-info'); } 11003 else if ( options.showInfo !== undefined ) { thisShowInfo = options.showInfo; } 11004 else { thisShowInfo = undefined; } 11005 11006 // show controls 11007 if ( $(this).attr('data-pe-show-controls') !== undefined ) { thisShowControls = $(this).attr('data-pe-show-controls'); } 11008 else if ( options.showControls !== undefined ) { thisShowControls = options.showControls; } 11009 else { thisShowControls = undefined; } 11010 11011 // loop 11012 if ( $(this).attr('data-pe-loop') !== undefined ) { thisLoop = $(this).attr('data-pe-loop'); } 11013 else if ( options.loop !== undefined ) { thisLoop = options.loop; } 11014 else { thisLoop = undefined; } 11015 11016 // closed captions 11017 if ( $(this).attr('data-pe-closed-captions') !== undefined ) { thisClosedCaptions = $(this).attr('data-pe-closed-captions'); } 11018 else if ( options.closedCaptions !== undefined ) { thisClosedCaptions = options.closedCaptions; } 11019 else { thisClosedCaptions = undefined; } 11020 11021 // localization 11022 if ( $(this).attr('data-pe-localization') !== undefined ) { thisLocalization = $(this).attr('data-pe-localization'); } 11023 else if ( options.localization !== undefined ) { thisLocalization = options.localization; } 11024 else { thisLocalization = undefined; } 11025 11026 // color scheme 11027 if ( $(this).attr('data-pe-color-scheme') !== undefined ) { thisColorScheme = $(this).attr('data-pe-color-scheme'); } 11028 else if ( options.colorScheme !== undefined ) { thisColorScheme = options.colorScheme; } 11029 else { thisColorScheme = undefined; } 11030 11031 // show related 11032 if ( $(this).attr('data-pe-show-related') !== undefined ) { thisShowRelated = $(this).attr('data-pe-show-related'); } 11033 else if ( options.showRelated !== undefined ) { thisShowRelated = options.showRelated; } 11034 else { thisShowRelated = undefined; } 11035 11036 // allow full screen 11037 if ( $(this).attr('data-pe-allow-fullscreen') !== undefined ) { thisAllowFullScreen = $(this).attr('data-pe-allow-fullscreen'); } 11038 else if ( options.allowFullScreen !== undefined ) { thisAllowFullScreen = options.allowFullScreen; } 11039 else { thisAllowFullScreen = undefined; } 11040 11041 11042 // If this element is an <a/>, create a placeholder replacement 11043 if ( $(this).is('a') ) { 11044 11045 // build the DOM structure 11046 $newDOMElement = $('<div />').addClass('pretty-embed'); 11047 11048 // rebuild the data-pe- attributes 11049 $newDOMElement.attr('data-pe-videoid', thisVideoID) 11050 .attr('data-pe-preview-size', thisPreviewSize) 11051 .attr('data-pe-custom-preview-image', thisCustomPreviewImage) 11052 .attr('data-pe-show-info', thisShowInfo) 11053 .attr('data-pe-show-controls', thisShowControls) 11054 .attr('data-pe-loop', thisLoop) 11055 .attr('data-pe-closed-captions', thisClosedCaptions) 11056 .attr('data-pe-localization', thisLocalization) 11057 .attr('data-pe-color-scheme', thisColorScheme) 11058 .attr('data-pe-show-related', thisShowRelated) 11059 .attr('data-pe-allow-fullscreen', thisAllowFullScreen); 11060 11061 // append the new element, and remove the <a/> 11062 $(this).after($newDOMElement); 11063 } 11064 11065 // Write the options.customPreviewImage OR choose a size 11066 if ( thisCustomPreviewImage !== undefined && thisCustomPreviewImage !== '' ) {
11067 $(this).html('<img src="' + thisCustomPreviewImage + '" width="100%" alt="YouTube Video Preview" />'); 11068 } 11069 else { 11070 var previewSizePrefix = ''; 11071 11072 switch (thisPreviewSize) { 11073 case 'thumb-default': 11074 previewSizePrefix = 'default'; 11075 break; 11076 case 'thumb-1': 11077 previewSizePrefix = '1'; 11078 break; 11079 case 'thumb-2': 11080 previewSizePrefix = '2'; 11081 break; 11082 case 'thumb-3': 11083 previewSizePrefix = '3'; 11084 break; 11085 case 'default': 11086 previewSizePrefix = 'mqdefault'; 11087 break; 11088 case 'medium': 11089 previewSizePrefix = '0'; 11090 break; 11091 case 'high': 11092 previewSizePrefix = 'hqdefault'; 11093 break; 11094 default: // 'hd' or max-resolution quality 11095 previewSizePrefix = 'maxresdefault'; 11096 break; 11097 } 11098 11099 // Write the <img/> element 11100 $(this).html('<img src="//img.youtube.com/vi/' + thisVideoID + '/' + previewSizePrefix + '.jpg" width="100%" alt="YouTube Video Preview" />'); 11101 } 11102 11103 if ( $(this).is('a') ) { 11104 $newDOMElement.html( $(this).html() ); 11105 $(this).remove(); 11106 } 11107 11108 // if mobile, go straight to iframe 11109 if (mobile) { 11110 $(window).on('load', function() { 11111 $('.pretty-embed').trigger('click'); 11112 }); 11113 } 11114 }); 11115 11116 11117 11118 // Click handler: load the video 11119 $('body').on('click', '.pretty-embed', function(e) { 11120 e.preventDefault(); 11121 11122 clickEventRunner( $(this) ); 11123 }); 11124 11125 11126 11127 /** 11128 * Function: clickEventRunner(obj) 11129 * Contains the functionality for .on('click') events 11130 * obj = the current object referenced passed from $(this) 11131 */ 11132 function clickEventRunner(obj) { 11133 var wrapperWidth = obj.find('img').outerWidth(true), 11134 wrapperHeight = obj.find('img').outerHeight(true), 11135 playerOptions = '', 11136 thisVideoID = ''; 11137 11138 // videoid - set from data-pe- attribute or options 11139 if ( obj.attr('data-pe-videoid') !== undefined ) { thisVideoID = obj.attr('data-pe-videoid'); } 11140 else if ( options.videoID !== undefined ) { thisVideoID = options.videoID; } 11141 else { 11142 thisVideoID = undefined; 11143 console.error('PrettyEmbed.js Error: Misformed or missing video ID.'); 11144 } 11145 11146 11147 // Assemble the player options string 11148 // showInfo 11149 if ( (obj.attr('data-pe-show-info') === 'false') || (options.showInfo === false) ) { playerOptions += '&showinfo=0'; } 11150 11151 // showControls 11152 if ( (obj.attr('data-pe-show-controls') === 'false') || (options.showControls === false) ) { playerOptions += '&controls=0'; } 11153 11154 // loop 11155 if ( (obj.attr('data-pe-loop') === 'true') || (options.loop === true) ) { playerOptions += '&loop=1'; } 11156 11157 // closed captions 11158 if ( (obj.attr('data-pe-closed-captions') === 'true') || (options.closedCaptions === true) ) { playerOptions += '&cc_load_policy=1'; } 11159 11160 // localization 11161 if ( (obj.attr('data-pe-localization') !== undefined) || (options.localization !== undefined) ) { 11162 if ( obj.attr('data-pe-localization') !== undefined ) { 11163 playerOptions += '&hl=' + obj.attr('data-pe-localization'); 11164 } 11165 else if ( options.localization !== undefined ) { 11166 playerOptions += '&hl=' + options.localization; 11167 } 11168 } 11169 11170 // colorScheme 11171 if ( (obj.attr('data-pe-color-scheme') == 'light') || (options.colorScheme == 'light') ) { playerOptions += '&theme=light'; } 11172 11173 // showRelated 11174 if ( (obj.attr('data-pe-show-related') === 'false') || (options.showRelated === false) ) { playerOptions += '&rel=0'; } else { playerOptions += '&rel=1'; } 11175 11176 // allow full screen 11177 if ( (obj.attr('data-pe-allow-fullscreen') === 'false') || (options.allowFullScreen === false) ) { fullScreenFlag = ''; } else { fullScreenFlag = 'allowfullscreen '; } 11178 11179 // Write the YouTube video iFrame into the element at the exact dimensions it is now 11180 obj.html('<iframe width="' + wrapperWidth + '" height="' + wrapperHeight + '" ' + fullScreenFlag + 'style="border:none;" src="//www.youtube.com/embed/' + thisVideoID + '?autoplay=1' + playerOptions + '"></iframe>') 11181 // Remove the YouTube 'play' button using a CSS class 11182 .addClass('play'); 11183 11184 // If we're using FitVids, call it now 11185 if (options.useFitVids) { 11186 if ( $.isFunction($.fn.fitVids) ) { 11187 obj.parent().fitVids(); 11188 } 11189 } 11190 } 11191 11192 11193 11194 // Helper function: get video ID from youtube URLs 11195 function youtube_parser(url) { 11196 var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; 11197 var match = url.match(regExp); 11198 if (match && match[7].length == 11) { 11199 return match[7]; 11200 } else { 11201 console.error('PrettyEmbed.js Error: Bad URL.'); 11202 } 11203 } 11204 11205 11206 11207 // Default the defaults 11208 $.fn.prettyEmbed.options = { 11209 videoID: '', 11210 previewSize: '', 11211 customPreviewImage: '', 11212 11213 // Embed controls 11214 showInfo: true, 11215 showControls: true, 11216 loop: false, 11217 closedCaptions: false, 11218 11219 colorScheme: 'dark', 11220 showRelated: false, 11221 11222 // FitVids.js 11223 useFitVids: false 11224 }; 11225 }; 11226})(jQuery); 11227/*! 11228* jQuery Cycle2; version: 2.1.6 build: 20141007 11229* http://jquery.malsup.com/cycle2/ 11230* Copyright (c) 2014 M. Alsup; Dual licensed: MIT/GPL 11231*/ 11232 11233/* Cycle2 core engine */ 11234 11235;(function($) { 11236"use strict"; 11237 11238var version = '2.1.6'; 11239 11240$.fn.cycle = function( options ) { 11241 // fix mistakes with the ready state 11242 var o; 11243 if ( this.length === 0 && !$.isReady ) { 11244 o = { s: this.selector, c: this.context }; 11245 $.fn.cycle.log('requeuing slideshow (dom not ready)'); 11246 $(function() { 11247 $( o.s, o.c ).cycle(options); 11248 }); 11249 return this; 11250 } 11251 11252 return this.each(function() { 11253 var data, opts, shortName, val; 11254 var container = $(this); 11255 var log = $.fn.cycle.log; 11256 11257 if ( container.data('cycle.opts') ) 11258 return; // already initialized 11259 11260 if ( container.data('cycle-log') === false || 11261 ( options && options.log === false ) || 11262 ( opts && opts.log === false) ) { 11263 log = $.noop; 11264 } 11265 11266 log('--c2 init--'); 11267 data = container.data(); 11268 for (var p in data) { 11269 // allow props to be accessed sans 'cycle' prefix and log the overrides 11270 if (data.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) { 11271 val = data[p]; 11272 shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase); 11273 log(shortName+':', val, '('+typeof val +')'); 11274 data[shortName] = val; 11275 } 11276 } 11277 11278 opts = $.extend( {}, $.fn.cycle.defaults, data, options || {}); 11279 11280 opts.timeoutId = 0; 11281 opts.paused = opts.paused || false; // #57 11282 opts.container = container; 11283 opts._maxZ = opts.maxZ; 11284
11285 opts.API = $.extend ( { _container: container }, $.fn.cycle.API ); 11286 opts.API.log = log; 11287 opts.API.trigger = function( eventName, args ) { 11288 opts.container.trigger( eventName, args ); 11289 return opts.API; 11290 }; 11291 11292 container.data( 'cycle.opts', opts ); 11293 container.data( 'cycle.API', opts.API ); 11294 11295 // opportunity for plugins to modify opts and API 11296 opts.API.trigger('cycle-bootstrap', [ opts, opts.API ]); 11297 11298 opts.API.addInitialSlides(); 11299 opts.API.preInitSlideshow(); 11300 11301 if ( opts.slides.length ) 11302 opts.API.initSlideshow(); 11303 }); 11304}; 11305 11306$.fn.cycle.API = { 11307 opts: function() { 11308 return this._container.data( 'cycle.opts' ); 11309 }, 11310 addInitialSlides: function() { 11311 var opts = this.opts(); 11312 var slides = opts.slides; 11313 opts.slideCount = 0; 11314 opts.slides = $(); // empty set 11315 11316 // add slides that already exist 11317 slides = slides.jquery ? slides : opts.container.find( slides ); 11318 11319 if ( opts.random ) { 11320 slides.sort(function() {return Math.random() - 0.5;}); 11321 } 11322 11323 opts.API.add( slides ); 11324 }, 11325 11326 preInitSlideshow: function() { 11327 var opts = this.opts(); 11328 opts.API.trigger('cycle-pre-initialize', [ opts ]); 11329 var tx = $.fn.cycle.transitions[opts.fx]; 11330 if (tx && $.isFunction(tx.preInit)) 11331 tx.preInit( opts ); 11332 opts._preInitialized = true; 11333 }, 11334 11335 postInitSlideshow: function() { 11336 var opts = this.opts(); 11337 opts.API.trigger('cycle-post-initialize', [ opts ]); 11338 var tx = $.fn.cycle.transitions[opts.fx]; 11339 if (tx && $.isFunction(tx.postInit)) 11340 tx.postInit( opts ); 11341 }, 11342 11343 initSlideshow: function() { 11344 var opts = this.opts(); 11345 var pauseObj = opts.container; 11346 var slideOpts; 11347 opts.API.calcFirstSlide(); 11348 11349 if ( opts.container.css('position') == 'static' ) 11350 opts.container.css('position', 'relative'); 11351 11352 $(opts.slides[opts.currSlide]).css({ 11353 opacity: 1, 11354 display: 'block', 11355 visibility: 'visible' 11356 }); 11357 opts.API.stackSlides( opts.slides[opts.currSlide], opts.slides[opts.nextSlide], !opts.reverse ); 11358 11359 if ( opts.pauseOnHover ) { 11360 // allow pauseOnHover to specify an element 11361 if ( opts.pauseOnHover !== true ) 11362 pauseObj = $( opts.pauseOnHover ); 11363 11364 pauseObj.hover( 11365 function(){ opts.API.pause( true ); }, 11366 function(){ opts.API.resume( true ); } 11367 ); 11368 } 11369 11370 // stage initial transition 11371 if ( opts.timeout ) { 11372 slideOpts = opts.API.getSlideOpts( opts.currSlide ); 11373 opts.API.queueTransition( slideOpts, slideOpts.timeout + opts.delay ); 11374 } 11375 11376 opts._initialized = true; 11377 opts.API.updateView( true ); 11378 opts.API.trigger('cycle-initialized', [ opts ]); 11379 opts.API.postInitSlideshow(); 11380 }, 11381 11382 pause: function( hover ) { 11383 var opts = this.opts(), 11384 slideOpts = opts.API.getSlideOpts(), 11385 alreadyPaused = opts.hoverPaused || opts.paused; 11386 11387 if ( hover ) 11388 opts.hoverPaused = true; 11389 else 11390 opts.paused = true; 11391 11392 if ( ! alreadyPaused ) { 11393 opts.container.addClass('cycle-paused'); 11394 opts.API.trigger('cycle-paused', [ opts ]).log('cycle-paused'); 11395 11396 if ( slideOpts.timeout ) { 11397 clearTimeout( opts.timeoutId ); 11398 opts.timeoutId = 0; 11399 11400 // determine how much time is left for the current slide 11401 opts._remainingTimeout -= ( $.now() - opts._lastQueue ); 11402 if ( opts._remainingTimeout < 0 || isNaN(opts._remainingTimeout) ) 11403 opts._remainingTimeout = undefined; 11404 } 11405 } 11406 }, 11407 11408 resume: function( hover ) { 11409 var opts = this.opts(), 11410 alreadyResumed = !opts.hoverPaused && !opts.paused, 11411 remaining; 11412 11413 if ( hover ) 11414 opts.hoverPaused = false; 11415 else 11416 opts.paused = false;
11417 11418 11419 if ( ! alreadyResumed ) { 11420 opts.container.removeClass('cycle-paused'); 11421 // #gh-230; if an animation is in progress then don't queue a new transition; it will 11422 // happen naturally 11423 if ( opts.slides.filter(':animated').length === 0 ) 11424 opts.API.queueTransition( opts.API.getSlideOpts(), opts._remainingTimeout ); 11425 opts.API.trigger('cycle-resumed', [ opts, opts._remainingTimeout ] ).log('cycle-resumed'); 11426 } 11427 }, 11428 11429 add: function( slides, prepend ) { 11430 var opts = this.opts(); 11431 var oldSlideCount = opts.slideCount; 11432 var startSlideshow = false; 11433 var len; 11434 11435 if ( $.type(slides) == 'string') 11436 slides = $.trim( slides ); 11437 11438 $( slides ).each(function(i) { 11439 var slideOpts; 11440 var slide = $(this); 11441 11442 if ( prepend ) 11443 opts.container.prepend( slide ); 11444 else 11445 opts.container.append( slide ); 11446 11447 opts.slideCount++; 11448 slideOpts = opts.API.buildSlideOpts( slide ); 11449 11450 if ( prepend ) 11451 opts.slides = $( slide ).add( opts.slides ); 11452 else 11453 opts.slides = opts.slides.add( slide ); 11454 11455 opts.API.initSlide( slideOpts, slide, --opts._maxZ ); 11456 11457 slide.data('cycle.opts', slideOpts); 11458 opts.API.trigger('cycle-slide-added', [ opts, slideOpts, slide ]); 11459 }); 11460 11461 opts.API.updateView( true ); 11462 11463 startSlideshow = opts._preInitialized && (oldSlideCount < 2 && opts.slideCount >= 1); 11464 if ( startSlideshow ) { 11465 if ( !opts._initialized ) 11466 opts.API.initSlideshow(); 11467 else if ( opts.timeout ) { 11468 len = opts.slides.length; 11469 opts.nextSlide = opts.reverse ? len - 1 : 1; 11470 if ( !opts.timeoutId ) { 11471 opts.API.queueTransition( opts ); 11472 } 11473 } 11474 } 11475 }, 11476 11477 calcFirstSlide: function() { 11478 var opts = this.opts(); 11479 var firstSlideIndex; 11480 firstSlideIndex = parseInt( opts.startingSlide || 0, 10 ); 11481 if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0) 11482 firstSlideIndex = 0; 11483 11484 opts.currSlide = firstSlideIndex; 11485 if ( opts.reverse ) { 11486 opts.nextSlide = firstSlideIndex - 1; 11487 if (opts.nextSlide < 0) 11488 opts.nextSlide = opts.slides.length - 1; 11489 } 11490 else { 11491 opts.nextSlide = firstSlideIndex + 1; 11492 if (opts.nextSlide == opts.slides.length) 11493 opts.nextSlide = 0; 11494 } 11495 }, 11496 11497 calcNextSlide: function() { 11498 var opts = this.opts(); 11499 var roll; 11500 if ( opts.reverse ) { 11501 roll = (opts.nextSlide - 1) < 0; 11502 opts.nextSlide = roll ? opts.slideCount - 1 : opts.nextSlide-1; 11503 opts.currSlide = roll ? 0 : opts.nextSlide+1; 11504 } 11505 else { 11506 roll = (opts.nextSlide + 1) == opts.slides.length; 11507 opts.nextSlide = roll ? 0 : opts.nextSlide+1; 11508 opts.currSlide = roll ? opts.slides.length-1 : opts.nextSlide-1; 11509 } 11510 }, 11511 11512 calcTx: function( slideOpts, manual ) { 11513 var opts = slideOpts; 11514 var tx; 11515 11516 if ( opts._tempFx ) 11517 tx = $.fn.cycle.transitions[opts._tempFx]; 11518 else if ( manual && opts.manualFx ) 11519 tx = $.fn.cycle.transitions[opts.manualFx]; 11520 11521 if ( !tx ) 11522 tx = $.fn.cycle.transitions[opts.fx]; 11523 11524 opts._tempFx = null; 11525 this.opts()._tempFx = null; 11526 11527 if (!tx) { 11528 tx = $.fn.cycle.transitions.fade; 11529 opts.API.log('Transition "' + opts.fx + '" not found. Using fade.'); 11530 } 11531 return tx; 11532 }, 11533 11534 prepareTx: function( manual, fwd ) { 11535 var opts = this.opts(); 11536 var after, curr, next, slideOpts, tx; 11537 11538 if ( opts.slideCount < 2 ) { 11539 opts.timeoutId = 0; 11540 return; 11541 } 11542 if ( manual && ( !opts.busy || opts.manualTrump ) ) { 11543 opts.API.stopTransition(); 11544 opts.busy = false;
11545 clearTimeout(opts.timeoutId); 11546 opts.timeoutId = 0; 11547 } 11548 if ( opts.busy ) 11549 return; 11550 if ( opts.timeoutId === 0 && !manual ) 11551 return; 11552 11553 curr = opts.slides[opts.currSlide]; 11554 next = opts.slides[opts.nextSlide]; 11555 slideOpts = opts.API.getSlideOpts( opts.nextSlide ); 11556 tx = opts.API.calcTx( slideOpts, manual ); 11557 11558 opts._tx = tx; 11559 11560 if ( manual && slideOpts.manualSpeed !== undefined ) 11561 slideOpts.speed = slideOpts.manualSpeed; 11562 11563 // if ( opts.nextSlide === opts.currSlide ) 11564 // opts.API.calcNextSlide(); 11565 11566 // ensure that: 11567 // 1. advancing to a different slide 11568 // 2. this is either a manual event (prev/next, pager, cmd) or 11569 // a timer event and slideshow is not paused 11570 if ( opts.nextSlide != opts.currSlide && 11571 (manual || (!opts.paused && !opts.hoverPaused && opts.timeout) )) { // #62 11572 11573 opts.API.trigger('cycle-before', [ slideOpts, curr, next, fwd ]); 11574 if ( tx.before ) 11575 tx.before( slideOpts, curr, next, fwd ); 11576 11577 after = function() { 11578 opts.busy = false; 11579 // #76; bail if slideshow has been destroyed 11580 if (! opts.container.data( 'cycle.opts' ) ) 11581 return; 11582 11583 if (tx.after) 11584 tx.after( slideOpts, curr, next, fwd ); 11585 opts.API.trigger('cycle-after', [ slideOpts, curr, next, fwd ]); 11586 opts.API.queueTransition( slideOpts); 11587 opts.API.updateView( true ); 11588 }; 11589 11590 opts.busy = true; 11591 if (tx.transition) 11592 tx.transition(slideOpts, curr, next, fwd, after); 11593 else 11594 opts.API.doTransition( slideOpts, curr, next, fwd, after); 11595 11596 opts.API.calcNextSlide(); 11597 opts.API.updateView(); 11598 } else { 11599 opts.API.queueTransition( slideOpts ); 11600 } 11601 }, 11602 11603 // perform the actual animation 11604 doTransition: function( slideOpts, currEl, nextEl, fwd, callback) { 11605 var opts = slideOpts; 11606 var curr = $(currEl), next = $(nextEl); 11607 var fn = function() { 11608 // make sure animIn has something so that callback doesn't trigger immediately 11609 next.animate(opts.animIn || { opacity: 1}, opts.speed, opts.easeIn || opts.easing, callback); 11610 }; 11611 11612 next.css(opts.cssBefore || {}); 11613 curr.animate(opts.animOut || {}, opts.speed, opts.easeOut || opts.easing, function() { 11614 curr.css(opts.cssAfter || {}); 11615 if (!opts.sync) { 11616 fn(); 11617 } 11618 }); 11619 if (opts.sync) { 11620 fn(); 11621 } 11622 }, 11623 11624 queueTransition: function( slideOpts, specificTimeout ) { 11625 var opts = this.opts(); 11626 var timeout = specificTimeout !== undefined ? specificTimeout : slideOpts.timeout; 11627 if (opts.nextSlide === 0 && --opts.loop === 0) { 11628 opts.API.log('terminating; loop=0'); 11629 opts.timeout = 0; 11630 if ( timeout ) { 11631 setTimeout(function() { 11632 opts.API.trigger('cycle-finished', [ opts ]); 11633 }, timeout); 11634 } 11635 else { 11636 opts.API.trigger('cycle-finished', [ opts ]); 11637 } 11638 // reset nextSlide 11639 opts.nextSlide = opts.currSlide; 11640 return; 11641 } 11642 if ( opts.continueAuto !== undefined ) { 11643 if ( opts.continueAuto === false || 11644 ($.isFunction(opts.continueAuto) && opts.continueAuto() === false )) { 11645 opts.API.log('terminating automatic transitions'); 11646 opts.timeout = 0; 11647 if ( opts.timeoutId ) 11648 clearTimeout(opts.timeoutId); 11649 return; 11650 } 11651 } 11652 if ( timeout ) { 11653 opts._lastQueue = $.now(); 11654 if ( specificTimeout === undefined ) 11655 opts._remainingTimeout = slideOpts.timeout; 11656 11657 if ( !opts.paused && ! opts.hoverPaused ) { 11658 opts.timeoutId = setTimeout(function() { 11659 opts.API.prepareTx( false, !opts.reverse ); 11660 }, timeout ); 11661 } 11662 } 11663 }, 11664 11665 stopTransition: function() { 11666 var opts = this.opts(); 11667 if ( opts.slides.filter(':animated').length ) { 11668 opts.slides.stop(false, true); 11669 opts.API.trigger('cycle-transition-stopped', [ opts ]); 11670 } 11671 11672 if ( opts._tx && opts._tx.stopTransition ) 11673 opts._tx.stopTransition( opts ); 11674 }, 11675 11676 // advance slide forward or back 11677 advanceSlide: function( val ) { 11678 var opts = this.opts(); 11679 clearTimeout(opts.timeoutId); 11680 opts.timeoutId = 0; 11681 opts.nextSlide = opts.currSlide + val; 11682 11683 if (opts.nextSlide < 0) 11684 opts.nextSlide = opts.slides.length - 1; 11685 else if (opts.nextSlide >= opts.slides.length) 11686 opts.nextSlide = 0; 11687 11688 opts.API.prepareTx( true, val >= 0 ); 11689 return false;
11690 }, 11691 11692 buildSlideOpts: function( slide ) { 11693 var opts = this.opts(); 11694 var val, shortName; 11695 var slideOpts = slide.data() || {}; 11696 for (var p in slideOpts) { 11697 // allow props to be accessed sans 'cycle' prefix and log the overrides 11698 if (slideOpts.hasOwnProperty(p) && /^cycle[A-Z]+/.test(p) ) { 11699 val = slideOpts[p]; 11700 shortName = p.match(/^cycle(.*)/)[1].replace(/^[A-Z]/, lowerCase); 11701 opts.API.log('['+(opts.slideCount-1)+']', shortName+':', val, '('+typeof val +')'); 11702 slideOpts[shortName] = val; 11703 } 11704 } 11705 11706 slideOpts = $.extend( {}, $.fn.cycle.defaults, opts, slideOpts ); 11707 slideOpts.slideNum = opts.slideCount; 11708 11709 try { 11710 // these props should always be read from the master state object 11711 delete slideOpts.API; 11712 delete slideOpts.slideCount; 11713 delete slideOpts.currSlide; 11714 delete slideOpts.nextSlide; 11715 delete slideOpts.slides; 11716 } catch(e) { 11717 // no op 11718 } 11719 return slideOpts; 11720 }, 11721 11722 getSlideOpts: function( index ) { 11723 var opts = this.opts(); 11724 if ( index === undefined ) 11725 index = opts.currSlide; 11726 11727 var slide = opts.slides[index]; 11728 var slideOpts = $(slide).data('cycle.opts'); 11729 return $.extend( {}, opts, slideOpts ); 11730 }, 11731 11732 initSlide: function( slideOpts, slide, suggestedZindex ) { 11733 var opts = this.opts(); 11734 slide.css( slideOpts.slideCss || {} ); 11735 if ( suggestedZindex > 0 ) 11736 slide.css( 'zIndex', suggestedZindex ); 11737 11738 // ensure that speed settings are sane 11739 if ( isNaN( slideOpts.speed ) ) 11740 slideOpts.speed = $.fx.speeds[slideOpts.speed] || $.fx.speeds._default; 11741 if ( !slideOpts.sync ) 11742 slideOpts.speed = slideOpts.speed / 2; 11743 11744 slide.addClass( opts.slideClass ); 11745 }, 11746 11747 updateView: function( isAfter, isDuring, forceEvent ) { 11748 var opts = this.opts(); 11749 if ( !opts._initialized ) 11750 return; 11751 var slideOpts = opts.API.getSlideOpts(); 11752 var currSlide = opts.slides[ opts.currSlide ]; 11753 11754 if ( ! isAfter && isDuring !== true ) { 11755 opts.API.trigger('cycle-update-view-before', [ opts, slideOpts, currSlide ]); 11756 if ( opts.updateView < 0 ) 11757 return; 11758 } 11759 11760 if ( opts.slideActiveClass ) { 11761 opts.slides.removeClass( opts.slideActiveClass ) 11762 .eq( opts.currSlide ).addClass( opts.slideActiveClass ); 11763 } 11764 11765 if ( isAfter && opts.hideNonActive ) 11766 opts.slides.filter( ':not(.' + opts.slideActiveClass + ')' ).css('visibility', 'hidden'); 11767 11768 if ( opts.updateView === 0 ) { 11769 setTimeout(function() { 11770 opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]); 11771 }, slideOpts.speed / (opts.sync ? 2 : 1) ); 11772 } 11773 11774 if ( opts.updateView !== 0 ) 11775 opts.API.trigger('cycle-update-view', [ opts, slideOpts, currSlide, isAfter ]); 11776 11777 if ( isAfter ) 11778 opts.API.trigger('cycle-update-view-after', [ opts, slideOpts, currSlide ]); 11779 }, 11780 11781 getComponent: function( name ) { 11782 var opts = this.opts(); 11783 var selector = opts[name]; 11784 if (typeof selector === 'string') { 11785 // if selector is a child, sibling combinator, adjancent selector then use find, otherwise query full dom 11786 return (/^\s*[\>|\+|~]/).test( selector ) ? opts.container.find( selector ) : $( selector ); 11787 } 11788 if (selector.jquery) 11789 return selector; 11790 11791 return $(selector); 11792 }, 11793 11794 stackSlides: function( curr, next, fwd ) { 11795 var opts = this.opts(); 11796 if ( !curr ) { 11797 curr = opts.slides[opts.currSlide]; 11798 next = opts.slides[opts.nextSlide]; 11799 fwd = !opts.reverse; 11800 } 11801 11802 // reset the zIndex for the common case: 11803 // curr slide on top, next slide beneath, and the rest in order to be shown 11804 $(curr).css('zIndex', opts.maxZ); 11805 11806 var i; 11807 var z = opts.maxZ - 2; 11808 var len = opts.slideCount; 11809 if (fwd) { 11810 for ( i = opts.currSlide + 1; i < len; i++ ) 11811 $( opts.slides[i] ).css( 'zIndex', z-- ); 11812 for ( i = 0; i < opts.currSlide; i++ ) 11813 $( opts.slides[i] ).css( 'zIndex', z-- ); 11814 } 11815 else { 11816 for ( i = opts.currSlide - 1; i >= 0; i-- ) 11817 $( opts.slides[i] ).css( 'zIndex', z-- ); 11818 for ( i = len - 1; i > opts.currSlide; i-- ) 11819 $( opts.slides[i] ).css( 'zIndex', z-- ); 11820 } 11821 11822 $(next).css('zIndex', opts.maxZ - 1); 11823 }, 11824 11825 getSlideIndex: function( el ) { 11826 return this.opts().slides.index( el ); 11827 } 11828 11829}; // API 11830 11831// default logger 11832$.fn.cycle.log = function log() { 11833 /*global console:true */ 11834 if (window.console && console.log) 11835 console.log('[cycle2] ' + Array.prototype.join.call(arguments, ' ') ); 11836}; 11837 11838$.fn.cycle.version = function() { return 'Cycle2: ' + version; }; 11839 11840// helper functions 11841 11842function lowerCase(s) { 11843 return (s || '').toLowerCase(); 11844} 11845 11846// expose transition object 11847$.fn.cycle.transitions = { 11848 custom: { 11849 }, 11850 none: { 11851 before: function( opts, curr, next, fwd ) { 11852 opts.API.stackSlides( next, curr, fwd ); 11853 opts.cssBefore = { opacity: 1, visibility: 'visible', display: 'block' }; 11854 } 11855 }, 11856 fade: { 11857 before: function( opts, curr, next, fwd ) {
11858 var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {}; 11859 opts.API.stackSlides( curr, next, fwd ); 11860 opts.cssBefore = $.extend(css, { opacity: 0, visibility: 'visible', display: 'block' }); 11861 opts.animIn = { opacity: 1 }; 11862 opts.animOut = { opacity: 0 }; 11863 } 11864 }, 11865 fadeout: { 11866 before: function( opts , curr, next, fwd ) { 11867 var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {}; 11868 opts.API.stackSlides( curr, next, fwd ); 11869 opts.cssBefore = $.extend(css, { opacity: 1, visibility: 'visible', display: 'block' }); 11870 opts.animOut = { opacity: 0 }; 11871 } 11872 }, 11873 scrollHorz: { 11874 before: function( opts, curr, next, fwd ) { 11875 opts.API.stackSlides( curr, next, fwd ); 11876 var w = opts.container.css('overflow','hidden').width(); 11877 opts.cssBefore = { left: fwd ? w : - w, top: 0, opacity: 1, visibility: 'visible', display: 'block' }; 11878 opts.cssAfter = { zIndex: opts._maxZ - 2, left: 0 }; 11879 opts.animIn = { left: 0 }; 11880 opts.animOut = { left: fwd ? -w : w }; 11881 } 11882 } 11883}; 11884 11885// @see: http://jquery.malsup.com/cycle2/api 11886$.fn.cycle.defaults = { 11887 allowWrap: true, 11888 autoSelector: '.cycle-slideshow[data-cycle-auto-init!=false]', 11889 delay: 0, 11890 easing: null, 11891 fx: 'fade', 11892 hideNonActive: true, 11893 loop: 0, 11894 manualFx: undefined, 11895 manualSpeed: undefined, 11896 manualTrump: true, 11897 maxZ: 100, 11898 pauseOnHover: false, 11899 reverse: false, 11900 slideActiveClass: 'cycle-slide-active', 11901 slideClass: 'cycle-slide', 11902 slideCss: { position: 'absolute', top: 0, left: 0 }, 11903 slides: '> img', 11904 speed: 500, 11905 startingSlide: 0, 11906 sync: true, 11907 timeout: 4000, 11908 updateView: 0 11909}; 11910 11911// automatically find and run slideshows 11912$(document).ready(function() { 11913 $( $.fn.cycle.defaults.autoSelector ).cycle(); 11914}); 11915 11916})(jQuery); 11917 11918/*! Cycle2 autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130913 */ 11919(function($) { 11920"use strict"; 11921 11922$.extend($.fn.cycle.defaults, { 11923 autoHeight: 0, // setting this option to false disables autoHeight logic 11924 autoHeightSpeed: 250, 11925 autoHeightEasing: null 11926}); 11927 11928$(document).on( 'cycle-initialized', function( e, opts ) { 11929 var autoHeight = opts.autoHeight; 11930 var t = $.type( autoHeight ); 11931 var resizeThrottle = null; 11932 var ratio; 11933 11934 if ( t !== 'string' && t !== 'number' ) 11935 return; 11936 11937 // bind events 11938 opts.container.on( 'cycle-slide-added cycle-slide-removed', initAutoHeight ); 11939 opts.container.on( 'cycle-destroyed', onDestroy ); 11940 11941 if ( autoHeight == 'container' ) { 11942 opts.container.on( 'cycle-before', onBefore ); 11943 } 11944 else if ( t === 'string' && /\d+\:\d+/.test( autoHeight ) ) { 11945 // use ratio 11946 ratio = autoHeight.match(/(\d+)\:(\d+)/); 11947 ratio = ratio[1] / ratio[2]; 11948 opts._autoHeightRatio = ratio; 11949 } 11950 11951 // if autoHeight is a number then we don't need to recalculate the sentinel 11952 // index on resize 11953 if ( t !== 'number' ) { 11954 // bind unique resize handler per slideshow (so it can be 'off-ed' in onDestroy) 11955 opts._autoHeightOnResize = function () { 11956 clearTimeout( resizeThrottle ); 11957 resizeThrottle = setTimeout( onResize, 50 ); 11958 }; 11959 11960 $(window).on( 'resize orientationchange', opts._autoHeightOnResize ); 11961 } 11962 11963 setTimeout( onResize, 30 ); 11964 11965 function onResize() { 11966 initAutoHeight( e, opts ); 11967 } 11968}); 11969 11970function initAutoHeight( e, opts ) { 11971 var clone, height, sentinelIndex; 11972 var autoHeight = opts.autoHeight; 11973 11974 if ( autoHeight == 'container' ) { 11975 height = $( opts.slides[ opts.currSlide ] ).outerHeight(); 11976 opts.container.height( height ); 11977 } 11978 else if ( opts._autoHeightRatio ) { 11979 opts.container.height( opts.container.width() / opts._autoHeightRatio ); 11980 } 11981 else if ( autoHeight === 'calc' || ( $.type( autoHeight ) == 'number' && autoHeight >= 0 ) ) { 11982 if ( autoHeight === 'calc' ) 11983 sentinelIndex = calcSentinelIndex( e, opts ); 11984 else if ( autoHeight >= opts.slides.length ) 11985 sentinelIndex = 0; 11986 else 11987 sentinelIndex = autoHeight; 11988 11989 // only recreate sentinel if index is different 11990 if ( sentinelIndex == opts._sentinelIndex ) 11991 return; 11992 11993 opts._sentinelIndex = sentinelIndex; 11994 if ( opts._sentinel ) 11995 opts._sentinel.remove(); 11996 11997 // clone existing slide as sentinel 11998 clone = $( opts.slides[ sentinelIndex ].cloneNode(true) ); 11999 12000 // #50; remove special attributes from cloned content
12001 clone.removeAttr( 'id name rel' ).find( '[id],[name],[rel]' ).removeAttr( 'id name rel' ); 12002 12003 clone.css({ 12004 position: 'static', 12005 visibility: 'hidden', 12006 display: 'block' 12007 }).prependTo( opts.container ).addClass('cycle-sentinel cycle-slide').removeClass('cycle-slide-active'); 12008 clone.find( '*' ).css( 'visibility', 'hidden' ); 12009 12010 opts._sentinel = clone; 12011 } 12012} 12013 12014function calcSentinelIndex( e, opts ) { 12015 var index = 0, max = -1; 12016 12017 // calculate tallest slide index 12018 opts.slides.each(function(i) { 12019 var h = $(this).height(); 12020 if ( h > max ) { 12021 max = h; 12022 index = i; 12023 } 12024 }); 12025 return index; 12026} 12027 12028function onBefore( e, opts, outgoing, incoming, forward ) { 12029 var h = $(incoming).outerHeight(); 12030 opts.container.animate( { height: h }, opts.autoHeightSpeed, opts.autoHeightEasing ); 12031} 12032 12033function onDestroy( e, opts ) { 12034 if ( opts._autoHeightOnResize ) { 12035 $(window).off( 'resize orientationchange', opts._autoHeightOnResize ); 12036 opts._autoHeightOnResize = null; 12037 } 12038 opts.container.off( 'cycle-slide-added cycle-slide-removed', initAutoHeight ); 12039 opts.container.off( 'cycle-destroyed', onDestroy ); 12040 opts.container.off( 'cycle-before', onBefore ); 12041 12042 if ( opts._sentinel ) { 12043 opts._sentinel.remove(); 12044 opts._sentinel = null; 12045 } 12046} 12047 12048})(jQuery); 12049 12050/*! caption plugin for Cycle2; version: 20130306 */ 12051(function($) { 12052"use strict"; 12053 12054$.extend($.fn.cycle.defaults, { 12055 caption: '> .cycle-caption', 12056 captionTemplate: '{{slideNum}} / {{slideCount}}', 12057 overlay: '> .cycle-overlay', 12058 overlayTemplate: '<div>{{title}}</div><div>{{desc}}</div>', 12059 captionModule: 'caption' 12060}); 12061 12062$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) { 12063 if ( opts.captionModule !== 'caption' ) 12064 return; 12065 var el; 12066 $.each(['caption','overlay'], function() { 12067 var name = this; 12068 var template = slideOpts[name+'Template']; 12069 var el = opts.API.getComponent( name ); 12070 if( el.length && template ) { 12071 el.html( opts.API.tmpl( template, slideOpts, opts, currSlide ) ); 12072 el.show(); 12073 } 12074 else { 12075 el.hide(); 12076 } 12077 }); 12078}); 12079 12080$(document).on( 'cycle-destroyed', function( e, opts ) { 12081 var el; 12082 $.each(['caption','overlay'], function() { 12083 var name = this, template = opts[name+'Template']; 12084 if ( opts[name] && template ) { 12085 el = opts.API.getComponent( 'caption' ); 12086 el.empty(); 12087 } 12088 }); 12089}); 12090 12091})(jQuery); 12092 12093/*! command plugin for Cycle2; version: 20140415 */ 12094(function($) { 12095"use strict"; 12096 12097var c2 = $.fn.cycle; 12098 12099$.fn.cycle = function( options ) { 12100 var cmd, cmdFn, opts; 12101 var args = $.makeArray( arguments ); 12102 12103 if ( $.type( options ) == 'number' ) { 12104 return this.cycle( 'goto', options ); 12105 } 12106 12107 if ( $.type( options ) == 'string' ) { 12108 return this.each(function() { 12109 var cmdArgs; 12110 cmd = options; 12111 opts = $(this).data('cycle.opts'); 12112 12113 if ( opts === undefined ) { 12114 c2.log('slideshow must be initialized before sending commands; "' + cmd + '" ignored'); 12115 return; 12116 } 12117 else { 12118 cmd = cmd == 'goto' ? 'jump' : cmd; // issue #3; change 'goto' to 'jump' internally 12119 cmdFn = opts.API[ cmd ]; 12120 if ( $.isFunction( cmdFn )) { 12121 cmdArgs = $.makeArray( args ); 12122 cmdArgs.shift(); 12123 return cmdFn.apply( opts.API, cmdArgs ); 12124 } 12125 else { 12126 c2.log( 'unknown command: ', cmd ); 12127 } 12128 } 12129 }); 12130 } 12131 else { 12132 return c2.apply( this, arguments ); 12133 } 12134}; 12135 12136// copy props 12137$.extend( $.fn.cycle, c2 ); 12138 12139$.extend( c2.API, { 12140 next: function() { 12141 var opts = this.opts(); 12142 if ( opts.busy && ! opts.manualTrump ) 12143 return; 12144 12145 var count = opts.reverse ? -1 : 1; 12146 if ( opts.allowWrap === false && ( opts.currSlide + count ) >= opts.slideCount ) 12147 return; 12148 12149 opts.API.advanceSlide( count );
12150 opts.API.trigger('cycle-next', [ opts ]).log('cycle-next'); 12151 }, 12152 12153 prev: function() { 12154 var opts = this.opts(); 12155 if ( opts.busy && ! opts.manualTrump ) 12156 return; 12157 var count = opts.reverse ? 1 : -1; 12158 if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 ) 12159 return; 12160 12161 opts.API.advanceSlide( count ); 12162 opts.API.trigger('cycle-prev', [ opts ]).log('cycle-prev'); 12163 }, 12164 12165 destroy: function() { 12166 this.stop(); //#204 12167 12168 var opts = this.opts(); 12169 var clean = $.isFunction( $._data ) ? $._data : $.noop; // hack for #184 and #201 12170 clearTimeout(opts.timeoutId); 12171 opts.timeoutId = 0; 12172 opts.API.stop(); 12173 opts.API.trigger( 'cycle-destroyed', [ opts ] ).log('cycle-destroyed'); 12174 opts.container.removeData(); 12175 clean( opts.container[0], 'parsedAttrs', false ); 12176 12177 // #75; remove inline styles 12178 if ( ! opts.retainStylesOnDestroy ) { 12179 opts.container.removeAttr( 'style' ); 12180 opts.slides.removeAttr( 'style' ); 12181 opts.slides.removeClass( opts.slideActiveClass ); 12182 } 12183 opts.slides.each(function() { 12184 var slide = $(this); 12185 slide.removeData(); 12186 slide.removeClass( opts.slideClass ); 12187 clean( this, 'parsedAttrs', false ); 12188 }); 12189 }, 12190 12191 jump: function( index, fx ) { 12192 // go to the requested slide 12193 var fwd; 12194 var opts = this.opts(); 12195 if ( opts.busy && ! opts.manualTrump ) 12196 return; 12197 var num = parseInt( index, 10 ); 12198 if (isNaN(num) || num < 0 || num >= opts.slides.length) { 12199 opts.API.log('goto: invalid slide index: ' + num); 12200 return; 12201 } 12202 if (num == opts.currSlide) { 12203 opts.API.log('goto: skipping, already on slide', num); 12204 return; 12205 } 12206 opts.nextSlide = num; 12207 clearTimeout(opts.timeoutId); 12208 opts.timeoutId = 0; 12209 opts.API.log('goto: ', num, ' (zero-index)'); 12210 fwd = opts.currSlide < opts.nextSlide; 12211 opts._tempFx = fx; 12212 opts.API.prepareTx( true, fwd ); 12213 }, 12214 12215 stop: function() { 12216 var opts = this.opts(); 12217 var pauseObj = opts.container; 12218 clearTimeout(opts.timeoutId); 12219 opts.timeoutId = 0; 12220 opts.API.stopTransition(); 12221 if ( opts.pauseOnHover ) { 12222 if ( opts.pauseOnHover !== true ) 12223 pauseObj = $( opts.pauseOnHover ); 12224 pauseObj.off('mouseenter mouseleave'); 12225 } 12226 opts.API.trigger('cycle-stopped', [ opts ]).log('cycle-stopped'); 12227 }, 12228 12229 reinit: function() { 12230 var opts = this.opts(); 12231 opts.API.destroy(); 12232 opts.container.cycle(); 12233 }, 12234 12235 remove: function( index ) { 12236 var opts = this.opts(); 12237 var slide, slideToRemove, slides = [], slideNum = 1; 12238 for ( var i=0; i < opts.slides.length; i++ ) { 12239 slide = opts.slides[i]; 12240 if ( i == index ) { 12241 slideToRemove = slide; 12242 } 12243 else { 12244 slides.push( slide ); 12245 $( slide ).data('cycle.opts').slideNum = slideNum; 12246 slideNum++; 12247 } 12248 } 12249 if ( slideToRemove ) { 12250 opts.slides = $( slides ); 12251 opts.slideCount--; 12252 $( slideToRemove ).remove(); 12253 if (index == opts.currSlide) 12254 opts.API.advanceSlide( 1 ); 12255 else if ( index < opts.currSlide ) 12256 opts.currSlide--; 12257 else 12258 opts.currSlide++; 12259 12260 opts.API.trigger('cycle-slide-removed', [ opts, index, slideToRemove ]).log('cycle-slide-removed'); 12261 opts.API.updateView(); 12262 } 12263 } 12264 12265}); 12266 12267// listen for clicks on elements with data-cycle-cmd attribute 12268$(document).on('click.cycle', '[data-cycle-cmd]', function(e) { 12269 // issue cycle command 12270 e.preventDefault(); 12271 var el = $(this); 12272 var command = el.data('cycle-cmd'); 12273 var context = el.data('cycle-context') || '.cycle-slideshow'; 12274 $(context).cycle(command, el.data('cycle-arg')); 12275}); 12276 12277 12278})(jQuery); 12279 12280/*! hash plugin for Cycle2; version: 20130905 */ 12281(function($) { 12282"use strict"; 12283 12284$(document).on( 'cycle-pre-initialize', function( e, opts ) { 12285 onHashChange( opts, true ); 12286 12287 opts._onHashChange = function() { 12288 onHashChange( opts, false ); 12289 }; 12290
12291 $( window ).on( 'hashchange', opts._onHashChange); 12292}); 12293 12294$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) { 12295 if ( slideOpts.hash && ( '#' + slideOpts.hash ) != window.location.hash ) { 12296 opts._hashFence = true; 12297 window.location.hash = slideOpts.hash; 12298 } 12299}); 12300 12301$(document).on( 'cycle-destroyed', function( e, opts) { 12302 if ( opts._onHashChange ) { 12303 $( window ).off( 'hashchange', opts._onHashChange ); 12304 } 12305}); 12306 12307function onHashChange( opts, setStartingSlide ) { 12308 var hash; 12309 if ( opts._hashFence ) { 12310 opts._hashFence = false; 12311 return; 12312 } 12313 12314 hash = window.location.hash.substring(1); 12315 12316 opts.slides.each(function(i) { 12317 if ( $(this).data( 'cycle-hash' ) == hash ) { 12318 if ( setStartingSlide === true ) { 12319 opts.startingSlide = i; 12320 } 12321 else { 12322 var fwd = opts.currSlide < i; 12323 opts.nextSlide = i; 12324 opts.API.prepareTx( true, fwd ); 12325 } 12326 return false; 12327 } 12328 }); 12329} 12330 12331})(jQuery); 12332 12333/*! loader plugin for Cycle2; version: 20131121 */ 12334(function($) { 12335"use strict"; 12336 12337$.extend($.fn.cycle.defaults, { 12338 loader: false 12339}); 12340 12341$(document).on( 'cycle-bootstrap', function( e, opts ) { 12342 var addFn; 12343 12344 if ( !opts.loader ) 12345 return; 12346 12347 // override API.add for this slideshow 12348 addFn = opts.API.add; 12349 opts.API.add = add; 12350 12351 function add( slides, prepend ) { 12352 var slideArr = []; 12353 if ( $.type( slides ) == 'string' ) 12354 slides = $.trim( slides ); 12355 else if ( $.type( slides) === 'array' ) { 12356 for (var i=0; i < slides.length; i++ ) 12357 slides[i] = $(slides[i])[0]; 12358 } 12359 12360 slides = $( slides ); 12361 var slideCount = slides.length; 12362 12363 if ( ! slideCount ) 12364 return; 12365 12366 slides.css('visibility','hidden').appendTo('body').each(function(i) { // appendTo fixes #56 12367 var count = 0; 12368 var slide = $(this); 12369 var images = slide.is('img') ? slide : slide.find('img'); 12370 slide.data('index', i); 12371 // allow some images to be marked as unimportant (and filter out images w/o src value) 12372 images = images.filter(':not(.cycle-loader-ignore)').filter(':not([src=""])'); 12373 if ( ! images.length ) { 12374 --slideCount; 12375 slideArr.push( slide ); 12376 return; 12377 } 12378 12379 count = images.length; 12380 images.each(function() { 12381 // add images that are already loaded 12382 if ( this.complete ) { 12383 imageLoaded(); 12384 } 12385 else { 12386 $(this).load(function() { 12387 imageLoaded(); 12388 }).on("error", function() { 12389 if ( --count === 0 ) { 12390 // ignore this slide 12391 opts.API.log('slide skipped; img not loaded:', this.src); 12392 if ( --slideCount === 0 && opts.loader == 'wait') { 12393 addFn.apply( opts.API, [ slideArr, prepend ] ); 12394 } 12395 } 12396 }); 12397 } 12398 }); 12399 12400 function imageLoaded() { 12401 if ( --count === 0 ) { 12402 --slideCount; 12403 addSlide( slide ); 12404 } 12405 } 12406 }); 12407 12408 if ( slideCount ) 12409 opts.container.addClass('cycle-loading'); 12410 12411 12412 function addSlide( slide ) { 12413 var curr; 12414 if ( opts.loader == 'wait' ) { 12415 slideArr.push( slide ); 12416 if ( slideCount === 0 ) { 12417 // #59; sort slides into original markup order 12418 slideArr.sort( sorter ); 12419 addFn.apply( opts.API, [ slideArr, prepend ] ); 12420 opts.container.removeClass('cycle-loading'); 12421 } 12422 } 12423 else { 12424 curr = $(opts.slides[opts.currSlide]); 12425 addFn.apply( opts.API, [ slide, prepend ] ); 12426 curr.show(); 12427 opts.container.removeClass('cycle-loading'); 12428 } 12429 } 12430 12431 function sorter(a, b) { 12432 return a.data('index') - b.data('index'); 12433 } 12434 } 12435}); 12436 12437})(jQuery); 12438 12439/*! pager plugin for Cycle2; version: 20140415 */ 12440(function($) { 12441"use strict"; 12442 12443$.extend($.fn.cycle.defaults, { 12444 pager: '> .cycle-pager', 12445 pagerActiveClass: 'cycle-pager-active', 12446 pagerEvent: 'click.cycle', 12447 pagerEventBubble: undefined, 12448 pagerTemplate: '<span>•</span>' 12449}); 12450 12451$(document).on( 'cycle-bootstrap', function( e, opts, API ) { 12452 // add method to API 12453 API.buildPagerLink = buildPagerLink; 12454}); 12455 12456$(document).on( 'cycle-slide-added', function( e, opts, slideOpts, slideAdded ) { 12457 if ( opts.pager ) { 12458 opts.API.buildPagerLink ( opts, slideOpts, slideAdded ); 12459 opts.API.page = page; 12460 } 12461}); 12462 12463$(document).on( 'cycle-slide-removed', function( e, opts, index, slideRemoved ) { 12464 if ( opts.pager ) { 12465 var pagers = opts.API.getComponent( 'pager' ); 12466 pagers.each(function() { 12467 var pager = $(this); 12468 $( pager.children()[index] ).remove(); 12469 }); 12470 } 12471}); 12472 12473$(document).on( 'cycle-update-view', function( e, opts, slideOpts ) { 12474 var pagers; 12475 12476 if ( opts.pager ) { 12477 pagers = opts.API.getComponent( 'pager' ); 12478 pagers.each(function() { 12479 $(this).children().removeClass( opts.pagerActiveClass )
12480 .eq( opts.currSlide ).addClass( opts.pagerActiveClass ); 12481 }); 12482 } 12483}); 12484 12485$(document).on( 'cycle-destroyed', function( e, opts ) { 12486 var pager = opts.API.getComponent( 'pager' ); 12487 12488 if ( pager ) { 12489 pager.children().off( opts.pagerEvent ); // #202 12490 if ( opts.pagerTemplate ) 12491 pager.empty(); 12492 } 12493}); 12494 12495function buildPagerLink( opts, slideOpts, slide ) { 12496 var pagerLink; 12497 var pagers = opts.API.getComponent( 'pager' ); 12498 pagers.each(function() { 12499 var pager = $(this); 12500 if ( slideOpts.pagerTemplate ) { 12501 var markup = opts.API.tmpl( slideOpts.pagerTemplate, slideOpts, opts, slide[0] ); 12502 pagerLink = $( markup ).appendTo( pager ); 12503 } 12504 else { 12505 pagerLink = pager.children().eq( opts.slideCount - 1 ); 12506 } 12507 pagerLink.on( opts.pagerEvent, function(e) { 12508 if ( ! opts.pagerEventBubble ) 12509 e.preventDefault(); 12510 opts.API.page( pager, e.currentTarget); 12511 }); 12512 }); 12513} 12514 12515function page( pager, target ) { 12516 /*jshint validthis:true */ 12517 var opts = this.opts(); 12518 if ( opts.busy && ! opts.manualTrump ) 12519 return; 12520 12521 var index = pager.children().index( target ); 12522 var nextSlide = index; 12523 var fwd = opts.currSlide < nextSlide; 12524 if (opts.currSlide == nextSlide) { 12525 return; // no op, clicked pager for the currently displayed slide 12526 } 12527 opts.nextSlide = nextSlide; 12528 opts._tempFx = opts.pagerFx; 12529 opts.API.prepareTx( true, fwd ); 12530 opts.API.trigger('cycle-pager-activated', [opts, pager, target ]); 12531} 12532 12533})(jQuery); 12534 12535/*! prevnext plugin for Cycle2; version: 20140408 */ 12536(function($) { 12537"use strict"; 12538 12539$.extend($.fn.cycle.defaults, { 12540 next: '> .cycle-next', 12541 nextEvent: 'click.cycle', 12542 disabledClass: 'disabled', 12543 prev: '> .cycle-prev', 12544 prevEvent: 'click.cycle', 12545 swipe: false 12546}); 12547 12548$(document).on( 'cycle-initialized', function( e, opts ) { 12549 opts.API.getComponent( 'next' ).on( opts.nextEvent, function(e) { 12550 e.preventDefault(); 12551 opts.API.next(); 12552 }); 12553 12554 opts.API.getComponent( 'prev' ).on( opts.prevEvent, function(e) { 12555 e.preventDefault(); 12556 opts.API.prev(); 12557 }); 12558 12559 if ( opts.swipe ) { 12560 var nextEvent = opts.swipeVert ? 'swipeUp.cycle' : 'swipeLeft.cycle swipeleft.cycle'; 12561 var prevEvent = opts.swipeVert ? 'swipeDown.cycle' : 'swipeRight.cycle swiperight.cycle'; 12562 opts.container.on( nextEvent, function(e) { 12563 opts._tempFx = opts.swipeFx; 12564 opts.API.next(); 12565 }); 12566 opts.container.on( prevEvent, function() { 12567 opts._tempFx = opts.swipeFx; 12568 opts.API.prev(); 12569 }); 12570 } 12571}); 12572 12573$(document).on( 'cycle-update-view', function( e, opts, slideOpts, currSlide ) { 12574 if ( opts.allowWrap ) 12575 return; 12576 12577 var cls = opts.disabledClass; 12578 var next = opts.API.getComponent( 'next' ); 12579 var prev = opts.API.getComponent( 'prev' ); 12580 var prevBoundry = opts._prevBoundry || 0; 12581 var nextBoundry = (opts._nextBoundry !== undefined)?opts._nextBoundry:opts.slideCount - 1; 12582 12583 if ( opts.currSlide == nextBoundry ) 12584 next.addClass( cls ).prop( 'disabled', true ); 12585 else 12586 next.removeClass( cls ).prop( 'disabled', false ); 12587 12588 if ( opts.currSlide === prevBoundry ) 12589 prev.addClass( cls ).prop( 'disabled', true ); 12590 else 12591 prev.removeClass( cls ).prop( 'disabled', false ); 12592}); 12593 12594 12595$(document).on( 'cycle-destroyed', function( e, opts ) { 12596 opts.API.getComponent( 'prev' ).off( opts.nextEvent ); 12597 opts.API.getComponent( 'next' ).off( opts.prevEvent ); 12598 opts.container.off( 'swipeleft.cycle swiperight.cycle swipeLeft.cycle swipeRight.cycle swipeUp.cycle swipeDown.cycle' ); 12599}); 12600 12601})(jQuery); 12602 12603/*! progressive loader plugin for Cycle2; version: 20130315 */ 12604(function($) { 12605"use strict"; 12606 12607$.extend($.fn.cycle.defaults, { 12608 progressive: false 12609}); 12610 12611$(document).on( 'cycle-pre-initialize', function( e, opts ) { 12612 if ( !opts.progressive ) 12613 return; 12614 12615 var API = opts.API; 12616 var nextFn = API.next; 12617 var prevFn = API.prev; 12618 var prepareTxFn = API.prepareTx; 12619 var type = $.type( opts.progressive ); 12620 var slides, scriptEl; 12621 12622 if ( type == 'array' ) { 12623 slides = opts.progressive; 12624 } 12625 else if ($.isFunction( opts.progressive ) ) { 12626 slides = opts.progressive( opts ); 12627 } 12628 else if ( type == 'string' ) { 12629 scriptEl = $( opts.progressive ); 12630 slides = $.trim( scriptEl.html() ); 12631 if ( !slides ) 12632 return; 12633 // is it json array? 12634 if ( /^(\[)/.test( slides ) ) { 12635 try { 12636 slides = $.parseJSON( slides ); 12637 } 12638 catch(err) { 12639 API.log( 'error parsing progressive slides', err ); 12640 return; 12641 } 12642 } 12643 else { 12644 // plain text, split on delimeter 12645 slides = slides.split( new RegExp( scriptEl.data('cycle-split') || '\n') ); 12646 12647 // #95; look for empty slide 12648 if ( ! slides[ slides.length - 1 ] ) 12649 slides.pop(); 12650 } 12651 } 12652 12653 12654 12655 if ( prepareTxFn ) { 12656 API.prepareTx = function( manual, fwd ) { 12657 var index, slide; 12658 12659 if ( manual || slides.length === 0 ) { 12660 prepareTxFn.apply( opts.API, [ manual, fwd ] ); 12661 return; 12662 } 12663 12664 if ( fwd && opts.currSlide == ( opts.slideCount-1) ) { 12665 slide = slides[ 0 ]; 12666 slides = slides.slice( 1 ); 12667 opts.container.one('cycle-slide-added', function(e, opts ) { 12668 setTimeout(function() { 12669 opts.API.advanceSlide( 1 ); 12670 },50); 12671 }); 12672 opts.API.add( slide ); 12673 } 12674 else if ( !fwd && opts.currSlide === 0 ) { 12675 index = slides.length-1; 12676 slide = slides[ index ]; 12677 slides = slides.slice( 0, index ); 12678 opts.container.one('cycle-slide-added', function(e, opts ) { 12679 setTimeout(function() { 12680 opts.currSlide = 1; 12681 opts.API.advanceSlide( -1 ); 12682 },50); 12683 }); 12684 opts.API.add( slide, true ); 12685 } 12686 else { 12687 prepareTxFn.apply( opts.API, [ manual, fwd ] ); 12688 } 12689 }; 12690 } 12691 12692 if ( nextFn ) { 12693 API.next = function() { 12694 var opts = this.opts(); 12695 if ( slides.length && opts.currSlide == ( opts.slideCount - 1 ) ) { 12696 var slide = slides[ 0 ]; 12697 slides = slides.slice( 1 ); 12698 opts.container.one('cycle-slide-added', function(e, opts ) { 12699 nextFn.apply( opts.API ); 12700 opts.container.removeClass('cycle-loading'); 12701 }); 12702 opts.container.addClass('cycle-loading'); 12703 opts.API.add( slide ); 12704 } 12705 else { 12706 nextFn.apply( opts.API ); 12707 } 12708 }; 12709 } 12710 12711 if ( prevFn ) { 12712 API.prev = function() { 12713 var opts = this.opts(); 12714 if ( slides.length && opts.currSlide === 0 ) { 12715 var index = slides.length-1; 12716 var slide = slides[ index ]; 12717 slides = slides.slice( 0, index ); 12718 opts.container.one('cycle-slide-added', function(e, opts ) { 12719 opts.currSlide = 1; 12720 opts.API.advanceSlide( -1 ); 12721 opts.container.removeClass('cycle-loading'); 12722 }); 12723 opts.container.addClass('cycle-loading'); 12724 opts.API.add( slide, true ); 12725 } 12726 else { 12727 prevFn.apply( opts.API ); 12728 } 12729 }; 12730 } 12731}); 12732 12733})(jQuery); 12734 12735/*! tmpl plugin for Cycle2; version: 20121227 */ 12736(function($) { 12737"use strict"; 12738 12739$.extend($.fn.cycle.defaults, { 12740 tmplRegex: '{{((.)?.*?)}}' 12741}); 12742 12743$.extend($.fn.cycle.API, { 12744 tmpl: function( str, opts /*, ... */) { 12745 var regex = new RegExp( opts.tmplRegex || $.fn.cycle.defaults.tmplRegex, 'g' ); 12746 var args = $.makeArray( arguments ); 12747 args.shift(); 12748 return str.replace(regex, function(_, str) { 12749 var i, j, obj, prop, names = str.split('.'); 12750 for (i=0; i < args.length; i++) { 12751 obj = args[i]; 12752 if ( ! obj ) 12753 continue; 12754 if (names.length > 1) { 12755 prop = obj; 12756 for (j=0; j < names.length; j++) { 12757 obj = prop; 12758 prop = prop[ names[j] ] || str; 12759 } 12760 } else { 12761 prop = obj[str]; 12762 } 12763 12764 if ($.isFunction(prop)) 12765 return prop.apply(obj, args); 12766 if (prop !== undefined && prop !== null && prop != str) 12767 return prop; 12768 } 12769 return str; 12770 }); 12771 } 12772}); 12773 12774})(jQuery); 12775;(function ($, window, undefined) { 12776 'use strict'; 12777 12778 var $doc = $(document), 12779 Modernizr = window.Modernizr; 12780 12781 $(document).ready(function() { 12782 $.fn.foundationAlerts ? $doc.foundationAlerts() : null; 12783 $.fn.foundationButtons ? $doc.foundationButtons() : null; 12784 $.fn.foundationAccordion ? $doc.foundationAccordion() : null; 12785 $.fn.foundationNavigation ? $doc.foundationNavigation() : null; 12786 $.fn.foundationTopBar ? $doc.foundationTopBar() : null; 12787 $.fn.foundationCustomForms ? $doc.foundationCustomForms() : null; 12788 $.fn.foundationMediaQueryViewer ? $doc.foundationMediaQueryViewer() : null; 12789 $.fn.foundationTabs ? $doc.foundationTabs({callback : $.foundation.customForms.appendCustomMarkup}) : null; 12790 $.fn.foundationTooltips ? $doc.foundationTooltips() : null; 12791 $.fn.foundationMagellan ? $doc.foundationMagellan() : null; 12792 $.fn.foundationClearing ? $doc.foundationClearing() : null; 12793 12794 $.fn.placeholder ? $('input, textarea').placeholder() : null; 12795 }); 12796 12797 // UNCOMMENT THE LINE YOU WANT BELOW IF YOU WANT IE8 SUPPORT AND ARE USING .block-grids 12798 // $('.block-grid.two-up>li:nth-child(2n+1)').css({clear: 'both'}); 12799 // $('.block-grid.three-up>li:nth-child(3n+1)').css({clear: 'both'}); 12800 // $('.block-grid.four-up>li:nth-child(4n+1)').css({clear: 'both'}); 12801 // $('.block-grid.five-up>li:nth-child(5n+1)').css({clear: 'both'}); 12802 12803 // Hide address bar on mobile devices (except if #hash present, so we don't mess up deep linking). 12804 if (Modernizr.touch && !window.location.hash) { 12805 $(window).load(function () { 12806 setTimeout(function () { 12807 // At load, if user hasn't scrolled more than 20px or so... 12808 if( $(window).scrollTop() < 20 ) { 12809 window.scrollTo(0, 1); 12810 } 12811 }, 0); 12812 }); 12813 } 12814 12815})(jQuery, this); 12816/* Modernizr 2.6.2 (Custom Build) | MIT & BSD 12817 * Build: http://modernizr.com/download/#-inlinesvg-svg-svgclippaths-touch-shiv-mq-cssclasses-teststyles-prefixes-ie8compat-load 12818 */ 12819 12820;window.Modernizr=function(a,b,c){function y(a){j.cssText=a}function z(a,b){return y(m.join(a+";")+(b||""))}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={svg:"http://www.w3.org/2000/svg"},o={},p={},q={},r=[],s=r.slice,t,u=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},v=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return u("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},w={}.hasOwnProperty,x;!A(w,"undefined")&&!A(w.call,"undefined")?x=function(a,b){return w.call(a,b)}:x=function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;
vendor: 8,261 bytes, lines 12820-12847
12820var d=s.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(s.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(s.call(arguments)))};return e}),o.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:u(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},o.svg=function(){return!!b.createElementNS&&!!b.createElementNS(n.svg,"svg").createSVGRect},o.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="<svg/>",(a.firstChild&&a.firstChild.namespaceURI)==n.svg},o.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(l.call(b.createElementNS(n.svg,"clipPath")))};for(var D in o)x(o,D)&&(t=D.toLowerCase(),e[t]=o[D](),r.push((e[t]?"":"no-")+t));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^(?: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,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=m,e.mq=v,e.testStyles=u,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+r.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))},Modernizr.addTest("ie8compat",function(){return!window.addEventListener&&document.documentMode&&document.documentMode===7}); 12821/*! http://mths.be/placeholder v2.0.7 by @mathias */ 12822 12823;(function(window, document, $) { 12824 12825 var isInputSupported = 'placeholder' in document.createElement('input'), 12826 isTextareaSupported = 'placeholder' in document.createElement('textarea'), 12827 prototype = $.fn, 12828 valHooks = $.valHooks, 12829 hooks, 12830 placeholder; 12831 12832 if (isInputSupported && isTextareaSupported) { 12833 12834 placeholder = prototype.placeholder = function() { 12835 return this; 12836 }; 12837 12838 placeholder.input = placeholder.textarea = true; 12839 12840 } else { 12841 12842 placeholder = prototype.placeholder = function() { 12843 var $this = this; 12844 $this 12845 .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') 12846 .not('.placeholder') 12847 .bind({
12848 'focus.placeholder': clearPlaceholder, 12849 'blur.placeholder': setPlaceholder 12850 }) 12851 .data('placeholder-enabled', true) 12852 .trigger('blur.placeholder'); 12853 return $this; 12854 }; 12855 12856 placeholder.input = isInputSupported; 12857 placeholder.textarea = isTextareaSupported; 12858 12859 hooks = { 12860 'get': function(element) { 12861 var $element = $(element); 12862 return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value; 12863 }, 12864 'set': function(element, value) { 12865 var $element = $(element); 12866 if (!$element.data('placeholder-enabled')) { 12867 return element.value = value; 12868 } 12869 if (value == '') { 12870 element.value = value; 12871 // Issue #56: Setting the placeholder causes problems if the element continues to have focus. 12872 if (element != document.activeElement) { 12873 // We can't use `triggerHandler` here because of dummy text/password inputs :( 12874 setPlaceholder.call(element); 12875 } 12876 } else if ($element.hasClass('placeholder')) { 12877 clearPlaceholder.call(element, true, value) || (element.value = value); 12878 } else { 12879 element.value = value; 12880 } 12881 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 12882 return $element; 12883 } 12884 }; 12885 12886 isInputSupported || (valHooks.input = hooks); 12887 isTextareaSupported || (valHooks.textarea = hooks); 12888 12889 $(function() { 12890 // Look for forms 12891 $(document).delegate('form', 'submit.placeholder', function() { 12892 // Clear the placeholder values so they don't get submitted 12893 var $inputs = $('.placeholder', this).each(clearPlaceholder); 12894 setTimeout(function() { 12895 $inputs.each(setPlaceholder); 12896 }, 10); 12897 }); 12898 }); 12899 12900 // Clear placeholder values upon page reload 12901 $(window).bind('beforeunload.placeholder', function() { 12902 $('.placeholder').each(function() { 12903 this.value = ''; 12904 }); 12905 }); 12906 12907 } 12908 12909 function args(elem) { 12910 // Return an object of element attributes 12911 var newAttrs = {}, 12912 rinlinejQuery = /^jQuery\d+$/; 12913 $.each(elem.attributes, function(i, attr) { 12914 if (attr.specified && !rinlinejQuery.test(attr.name)) { 12915 newAttrs[attr.name] = attr.value; 12916 } 12917 }); 12918 return newAttrs; 12919 } 12920 12921 function clearPlaceholder(event, value) { 12922 var input = this, 12923 $input = $(input); 12924 if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) { 12925 if ($input.data('placeholder-password')) { 12926 $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id')); 12927 // If `clearPlaceholder` was called from `$.valHooks.input.set` 12928 if (event === true) { 12929 return $input[0].value = value; 12930 } 12931 $input.focus(); 12932 } else { 12933 input.value = ''; 12934 $input.removeClass('placeholder'); 12935 input == document.activeElement && input.select(); 12936 } 12937 } 12938 } 12939 12940 function setPlaceholder() { 12941 var $replacement, 12942 input = this, 12943 $input = $(input), 12944 $origInput = $input, 12945 id = this.id; 12946 if (input.value == '') { 12947 if (input.type == 'password') { 12948 if (!$input.data('placeholder-textinput')) { 12949 try { 12950 $replacement = $input.clone().attr({ 'type': 'text' }); 12951 } catch(e) { 12952 $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' })); 12953 } 12954 $replacement 12955 .removeAttr('name') 12956 .data({ 12957 'placeholder-password': true, 12958 'placeholder-id': id 12959 }) 12960 .bind('focus.placeholder', clearPlaceholder); 12961 $input 12962 .data({ 12963 'placeholder-textinput': $replacement, 12964 'placeholder-id': id 12965 }) 12966 .before($replacement); 12967 } 12968 $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); 12969 // Note: `$input[0] != input` now! 12970 } 12971 $input.addClass('placeholder'); 12972 $input[0].value = $input.attr('placeholder'); 12973 } else { 12974 $input.removeClass('placeholder'); 12975 } 12976 } 12977 12978}(this, document, jQuery)); 12979;(function ($, window, undefined) { 12980 'use strict'; 12981 12982 $.fn.foundationAlerts = function (options) { 12983 var settings = $.extend({ 12984 callback: $.noop 12985 }, options); 12986 12987 $(document).on("click", ".alert-box a.close", function (e) { 12988 e.preventDefault(); 12989 $(this).closest(".alert-box").fadeOut(function () { 12990 $(this).remove(); 12991 // Do something else after the alert closes 12992 settings.callback(); 12993 }); 12994 }); 12995 12996 }; 12997 12998})(jQuery, this); 12999;(function ($, window, undefined){ 13000 'use strict'; 13001 13002 $.fn.foundationAccordion = function (options) { 13003 13004 // DRY up the logic used to determine if the event logic should execute. 13005 var hasHover = function(accordion) { 13006 return accordion.hasClass('hover') && !Modernizr.touch 13007 }; 13008 13009 $(document).on('mouseenter', '.accordion li', function () { 13010 var p = $(this).parent(); 13011 13012 if (hasHover(p)) { 13013 var flyout = $(this).children('.content').first(); 13014 13015 $('.content', p).not(flyout).hide().parent('li').removeClass('active'); 13016 flyout.show(0, function () { 13017 flyout.parent('li').addClass('active'); 13018 }); 13019 } 13020 } 13021 ); 13022 13023 $(document).on('click.fndtn', '.accordion li .title', function () { 13024 var li = $(this).closest('li'), 13025 p = li.parent(); 13026 13027 if(!hasHover(p)) { 13028 var flyout = li.children('.content').first(); 13029 13030 if (li.hasClass('active')) { 13031 p.find('li').removeClass('active').end().find('.content').hide(); 13032 } else { 13033 $('.content', p).not(flyout).hide().parent('li').removeClass('active'); 13034 flyout.show(0, function () { 13035 flyout.parent('li').addClass('active'); 13036 }); 13037 } 13038 } 13039 } 13040 ); 13041 13042 }; 13043 13044})( jQuery, this ); 13045 13046;(function ($, window, undefined) { 13047 'use strict'; 13048 13049 $.fn.foundationButtons = function (options) { 13050 var $doc = $(document), 13051 config = $.extend({ 13052 dropdownAsToggle:false, 13053 activeClass:'active' 13054 }, options), 13055 13056 // close all dropdowns except for the dropdown passed 13057 closeDropdowns = function (dropdown) { 13058 // alert(dropdown.html()); 13059 $('.button.dropdown').find('ul').not(dropdown).removeClass('show-dropdown'); 13060 }, 13061 // reset all toggle states except for the button passed 13062 resetToggles = function (button) { 13063 // alert(button.html()); 13064 var buttons = $('.button.dropdown').not(button); 13065 buttons.add($('> span.' + config.activeClass, buttons)).removeClass(config.activeClass); 13066 }; 13067 13068 // Prevent event propagation on disabled buttons 13069 $doc.on('click.fndtn', '.button.disabled', function (e) { 13070 e.preventDefault(); 13071 }); 13072 13073 $('.button.dropdown > ul', this).addClass('no-hover'); 13074 13075 // reset other active states 13076 $doc.on('click.fndtn', '.button.dropdown:not(.split), .button.dropdown.split span', function (e) { 13077 var $el = $(this), 13078 button = $el.closest('.button.dropdown'), 13079 dropdown = $('> ul', button); 13080 13081 // If the click is registered on an actual link or on button element then do not preventDefault which stops the browser from following the link 13082 if ($.inArray(e.target.nodeName, ['A', 'BUTTON'])){ 13083 e.preventDefault(); 13084 } 13085 13086 // close other dropdowns 13087 setTimeout(function () { 13088 closeDropdowns(config.dropdownAsToggle ? '' : dropdown); 13089 dropdown.toggleClass('show-dropdown'); 13090 13091 if (config.dropdownAsToggle) { 13092 resetToggles(button); 13093 $el.toggleClass(config.activeClass); 13094 } 13095 }, 0); 13096 }); 13097 13098 // close all dropdowns and deactivate all buttons 13099 $doc.on('click.fndtn', 'body, html', function (e) { 13100 if (undefined == e.originalEvent) { return; } 13101 // check original target instead of stopping event propagation to play nice with other events 13102 if (!$(e.originalEvent.target).is('.button.dropdown:not(.split), .button.dropdown.split span')) { 13103 closeDropdowns(); 13104 if (config.dropdownAsToggle) { 13105 resetToggles(); 13106 } 13107 } 13108 }); 13109 13110 // Positioning the Flyout List 13111 var normalButtonHeight = $('.button.dropdown:not(.large):not(.small):not(.tiny):visible', this).outerHeight() - 1, 13112 largeButtonHeight = $('.button.large.dropdown:visible', this).outerHeight() - 1, 13113 smallButtonHeight = $('.button.small.dropdown:visible', this).outerHeight() - 1, 13114 tinyButtonHeight = $('.button.tiny.dropdown:visible', this).outerHeight() - 1; 13115 13116 $('.button.dropdown:not(.large):not(.small):not(.tiny) > ul', this).css('top', normalButtonHeight); 13117 $('.button.dropdown.large > ul', this).css('top', largeButtonHeight); 13118 $('.button.dropdown.small > ul', this).css('top', smallButtonHeight); 13119 $('.button.dropdown.tiny > ul', this).css('top', tinyButtonHeight); 13120 13121 $('.button.dropdown.up:not(.large):not(.small):not(.tiny) > ul', this).css('top', 'auto').css('bottom', normalButtonHeight - 2); 13122 $('.button.dropdown.up.large > ul', this).css('top', 'auto').css('bottom', largeButtonHeight - 2); 13123 $('.button.dropdown.up.small > ul', this).css('top', 'auto').css('bottom', smallButtonHeight - 2); 13124 $('.button.dropdown.up.tiny > ul', this).css('top', 'auto').css('bottom', tinyButtonHeight - 2); 13125 13126 }; 13127 13128})( jQuery, this ); 13129/* 13130 * jQuery Foundation Tooltips 2.0.2 13131 * http://foundation.zurb.com
13132 * Copyright 2012, ZURB 13133 * Free to use under the MIT license. 13134 * http://www.opensource.org/licenses/mit-license.php 13135*/ 13136 13137/*jslint unparam: true, browser: true, indent: 2 */ 13138 13139 13140;(function ($, window, undefined) { 13141 'use strict'; 13142 13143 var settings = { 13144 bodyHeight : 0, 13145 selector : '.has-tip', 13146 additionalInheritableClasses : [], 13147 tooltipClass : '.tooltip', 13148 tipTemplate : function (selector, content) { 13149 return '<span data-selector="' + selector + '" class="' + settings.tooltipClass.substring(1) + '">' + content + '<span class="nub"></span></span>'; 13150 } 13151 }, 13152 methods = { 13153 init : function (options) { 13154 settings = $.extend(settings, options); 13155 13156 // alias the old targetClass option 13157 settings.selector = settings.targetClass ? settings.targetClass : settings.selector; 13158 13159 return this.each(function () { 13160 var $body = $('body'); 13161 13162 if (Modernizr.touch) { 13163 $body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.selector, function (e) { 13164 e.preventDefault(); 13165 $(settings.tooltipClass).hide(); 13166 methods.showOrCreateTip($(this)); 13167 }); 13168 $body.on('click.tooltip touchstart.tooltip touchend.tooltip', settings.tooltipClass, function (e) { 13169 e.preventDefault(); 13170 $(this).fadeOut(150); 13171 }); 13172 } else { 13173 $body.on('mouseenter.tooltip mouseleave.tooltip', settings.selector, function (e) { 13174 var $this = $(this); 13175 13176 if (e.type === 'mouseenter') { 13177 methods.showOrCreateTip($this); 13178 } else if (e.type === 'mouseleave') { 13179 methods.hide($this); 13180 } 13181 }); 13182 } 13183 13184 $(this).data('tooltips', true); 13185 13186 }); 13187 }, 13188 showOrCreateTip : function ($target, content) { 13189 var $tip = methods.getTip($target); 13190 13191 if ($tip && $tip.length > 0) { 13192 methods.show($target); 13193 } else { 13194 methods.create($target, content); 13195 } 13196 }, 13197 getTip : function ($target) { 13198 var selector = methods.selector($target), 13199 tip = null; 13200 13201 if (selector) { 13202 tip = $('span[data-selector=' + selector + ']' + settings.tooltipClass); 13203 } 13204 return (tip.length > 0) ? tip : false; 13205 }, 13206 selector : function ($target) { 13207 var id = $target.attr('id'), 13208 dataSelector = $target.data('selector'); 13209 13210 if (id === undefined && dataSelector === undefined) { 13211 dataSelector = 'tooltip' + Math.random().toString(36).substring(7); 13212 $target.attr('data-selector', dataSelector); 13213 } 13214 return (id) ? id : dataSelector; 13215 }, 13216 create : function ($target, content) { 13217 var $tip = $(settings.tipTemplate(methods.selector($target), 13218 $('<div>').html(content ? content : $target.attr('title')).html())), 13219 classes = methods.inheritable_classes($target); 13220
13221 $tip.addClass(classes).appendTo('body'); 13222 if (Modernizr.touch) { 13223 $tip.append('<span class="tap-to-close">tap to close </span>'); 13224 } 13225 $target.removeAttr('title'); 13226 methods.show($target); 13227 }, 13228 reposition : function (target, tip, classes) { 13229 var width, nub, nubHeight, nubWidth, column, objPos; 13230 13231 tip.css('visibility', 'hidden').show(); 13232 13233 width = target.data('width'); 13234 nub = tip.children('.nub'); 13235 nubHeight = nub.outerHeight(); 13236 nubWidth = nub.outerWidth(); 13237 13238 objPos = function (obj, top, right, bottom, left, width) { 13239 return obj.css({ 13240 'top' : top, 13241 'bottom' : bottom, 13242 'left' : left, 13243 'right' : right, 13244 'max-width' : (width) ? width : 'auto' 13245 }).end(); 13246 }; 13247 13248 objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width); 13249 objPos(nub, -nubHeight, 'auto', 'auto', 10); 13250 13251 if ($(window).width() < 767) { 13252 if (target.data('mobile-width')) { 13253 tip.width(target.data('mobile-width')).css('left', 15).addClass('tip-override'); 13254 } else { 13255 column = target.closest('.columns'); 13256 if (column.length < 0) { 13257 // if not using Foundation 13258 column = $('body'); 13259 } 13260 if (column.outerWidth()) { 13261 tip.width(column.outerWidth() - 25).css('left', 15).addClass('tip-override'); 13262 } else { 13263 var tmp_width = Math.ceil($(window).width() * 0.9); 13264 tip.width(tmp_width).css('left', 15).addClass('tip-override'); 13265 } 13266 } 13267 objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left); 13268 } else { 13269 if (classes && classes.indexOf('tip-top') > -1) { 13270 objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', target.offset().left, width) 13271 .removeClass('tip-override'); 13272 objPos(nub, 'auto', 'auto', -nubHeight, 'auto'); 13273 } else if (classes && classes.indexOf('tip-left') > -1) { 13274 objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left - tip.outerWidth() - 10), width) 13275 .removeClass('tip-override'); 13276 objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -nubHeight, 'auto', 'auto'); 13277 } else if (classes && classes.indexOf('tip-right') > -1) { 13278 objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width) 13279 .removeClass('tip-override'); 13280 objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -nubHeight); 13281 } else if (classes && classes.indexOf('tip-centered-top') > -1) { 13282 objPos(tip, (target.offset().top - tip.outerHeight() - nubHeight), 'auto', 'auto', (target.offset().left + ((target.outerWidth() - tip.outerWidth()) / 2) ), width) 13283 .removeClass('tip-override'); 13284 objPos(nub, 'auto', ((tip.outerWidth() / 2) -(nubHeight / 2)), -nubHeight, 'auto'); 13285 } else if (classes && classes.indexOf('tip-centered-bottom') > -1) { 13286 objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', (target.offset().left + ((target.outerWidth() - tip.outerWidth()) / 2) ), width) 13287 .removeClass('tip-override'); 13288 objPos(nub, -nubHeight, ((tip.outerWidth() / 2) -(nubHeight / 2)), 'auto', 'auto'); 13289 } 13290 } 13291 tip.css('visibility', 'visible').hide(); 13292 }, 13293 inheritable_classes : function (target) { 13294 var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'tip-centered-top', 'tip-centered-bottom', 'noradius'].concat(settings.additionalInheritableClasses), 13295 classes = target.attr('class'), 13296 filtered = classes ? $.map(classes.split(' '), function (el, i) { 13297 if ($.inArray(el, inheritables) !== -1) { 13298 return el; 13299 } 13300 }).join(' ') : ''; 13301 13302 return $.trim(filtered); 13303 }, 13304 show : function ($target) { 13305 var $tip = methods.getTip($target); 13306 13307 methods.reposition($target, $tip, $target.attr('class')); 13308 $tip.fadeIn(150); 13309 }, 13310 hide : function ($target) { 13311 var $tip = methods.getTip($target); 13312 13313 $tip.fadeOut(150); 13314 }, 13315 reload : function () { 13316 var $self = $(this); 13317 13318 return ($self.data('tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init'); 13319 }, 13320 destroy : function () { 13321 return this.each(function () { 13322 $(window).off('.tooltip'); 13323 $(settings.selector).off('.tooltip'); 13324 $(settings.tooltipClass).each(function (i) { 13325 $($(settings.selector).get(i)).attr('title', $(this).text()); 13326 }).remove(); 13327 }); 13328 } 13329 }; 13330 13331 $.fn.foundationTooltips = function (method) { 13332 if (methods[method]) { 13333 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 13334 } else if (typeof method === 'object' || !method) { 13335 return methods.init.apply(this, arguments); 13336 } else { 13337 $.error('Method ' + method + ' does not exist on jQuery.foundationTooltips'); 13338 } 13339 }; 13340}(jQuery, this)); 13341/* 13342 * jQuery Custom Forms Plugin 1.0 13343 * www.ZURB.com 13344 * Copyright 2010, ZURB 13345 * Free to use under the MIT license. 13346 * http://www.opensource.org/licenses/mit-license.php 13347*/ 13348 13349 13350(function( $ ){ 13351 13352 /** 13353 * Helper object used to quickly adjust all hidden parent element's, display and visibility properties. 13354 * This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal 13355 * we cannot accurately determine the list-item elements width property, since the modal'
13355s display property is set 13356 * to 'none'. 13357 * 13358 * This object will help us work around that problem. 13359 * 13360 * NOTE: This could also be plugin. 13361 * 13362 * @function hiddenFix 13363 */ 13364 var hiddenFix = function() { 13365 13366 return { 13367 /** 13368 * Sets all hidden parent elements and self to visibile. 13369 * 13370 * @method adjust 13371 * @param {jQuery Object} $child 13372 */ 13373 13374 // We'll use this to temporarily store style properties. 13375 tmp : [], 13376 13377 // We'll use this to set hidden parent elements. 13378 hidden : null, 13379 13380 adjust : function( $child ) { 13381 // Internal reference. 13382 var _self = this; 13383 13384 // Set all hidden parent elements, including this element. 13385 _self.hidden = $child.parents().andSelf().filter( ":hidden" ); 13386 13387 // Loop through all hidden elements. 13388 _self.hidden.each( function() { 13389 13390 // Cache the element. 13391 var $elem = $( this ); 13392 13393 // Store the style attribute. 13394 // Undefined if element doesn't have a style attribute. 13395 _self.tmp.push( $elem.attr( 'style' ) ); 13396 13397 // Set the element's display property to block, 13398 // but ensure it's visibility is hidden. 13399 $elem.css( { 'visibility' : 'hidden', 'display' : 'block' } ); 13400 }); 13401 13402 }, // end adjust 13403 13404 /** 13405 * Resets the elements previous state. 13406 * 13407 * @method reset 13408 */ 13409 reset : function() { 13410 // Internal reference. 13411 var _self = this; 13412 // Loop through our hidden element collection. 13413 _self.hidden.each( function( i ) { 13414 // Cache this element. 13415 var $elem = $( this ), 13416 _tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element. 13417 13418 // If the stored value is undefined. 13419 if( _tmp === undefined ) 13420 // Remove the style attribute. 13421 $elem.removeAttr( 'style' ); 13422 else 13423 // Otherwise, reset the element style attribute. 13424 $elem.attr( 'style', _tmp ); 13425 13426 }); 13427 // Reset the tmp array. 13428 _self.tmp = []; 13429 // Reset the hidden elements variable. 13430 _self.hidden = null; 13431 13432 } // end reset 13433 13434 }; // end return 13435 13436 }; 13437 13438 jQuery.foundation = jQuery.foundation || {}; 13439 jQuery.foundation.customForms = jQuery.foundation.customForms || {}; 13440 13441 $.foundation.customForms.appendCustomMarkup = function ( options ) { 13442 13443 var defaults = { 13444 disable_class: "no-custom" 13445 }; 13446 13447 options = $.extend( defaults, options ); 13448 13449 function appendCustomMarkup(idx, sel) { 13450 var $this = $(sel).hide(), 13451 type = $this.attr('type'), 13452 $span = $this.next('span.custom.' + type); 13453 13454 if ($span.length === 0) { 13455 $span = $('<span class="custom ' + type + '"></span>').insertAfter($this); 13456 } 13457 13458 $span.toggleClass('checked', $this.is(':checked')); 13459 $span.toggleClass('disabled', $this.is(':disabled')); 13460 } 13461 13462 function appendCustomSelect(idx, sel) { 13463 var hiddenFixObj = hiddenFix(); 13464 // 13465 // jQueryify the <select> element and cache it. 13466 // 13467 var $this = $( sel ), 13468 // 13469 // Find the custom drop down element. 13470 // 13471 $customSelect = $this.next( 'div.custom.dropdown' ), 13472 // 13473 // Find the custom select element within the custom drop down. 13474 // 13475 $customList = $customSelect.find( 'ul' ), 13476 // 13477 // Find the custom a.current element. 13478 // 13479 $selectCurrent = $customSelect.find( ".current" ), 13480 // 13481 // Find the custom a.selector element (the drop-down icon). 13482 // 13483 $selector = $customSelect.find( ".selector" ), 13484 // 13485 // Get the <options> from the <select> element. 13486 // 13487 $options = $this.find( 'option' ), 13488 // 13489 // Filter down the selected options 13490 // 13491 $selectedOption = $options.filter( ':selected' ), 13492 // 13493 // Initial max width. 13494 // 13495 maxWidth = 0, 13496 // 13497 // We'll use this variable to create the <li> elements for our custom select. 13498 // 13499 liHtml = '', 13500 // 13501 // We'll use this to cache the created <li> elements within our custom select. 13502 // 13503 $listItems 13504 ; 13505 var $currentSelect = false;
13506 // 13507 // Should we not create a custom list? 13508 // 13509 if ( $this.hasClass( options.disable_class ) ) return; 13510 13511 // 13512 // Did we not create a custom select element yet? 13513 // 13514 if ( $customSelect.length === 0 ) { 13515 // 13516 // Let's create our custom select element! 13517 // 13518 13519 // 13520 // Determine what select size to use. 13521 // 13522 var customSelectSize = $this.hasClass( 'small' ) ? 'small' : 13523 $this.hasClass( 'medium' ) ? 'medium' : 13524 $this.hasClass( 'large' ) ? 'large' : 13525 $this.hasClass( 'expand' ) ? 'expand' : '' 13526 ; 13527 // 13528 // Build our custom list. 13529 // 13530 $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>'); 13531 // 13532 // Grab the selector element 13533 // 13534 $selector = $customSelect.find( ".selector" ); 13535 // 13536 // Grab the unordered list element from the custom list. 13537 // 13538 $customList = $customSelect.find( "ul" ); 13539 // 13540 // Build our <li> elements. 13541 // 13542 liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' ); 13543 // 13544 // Append our <li> elements to the custom list (<ul>). 13545 // 13546 $customList.append( liHtml ); 13547 // 13548 // Insert the the currently selected list item before all other elements. 13549 // Then, find the element and assign it to $currentSelect. 13550 // 13551 13552 $currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" ); 13553 // 13554 // Add the custom select element after the <select> element. 13555 // 13556 $this.after( $customSelect ) 13557 // 13558 //then hide the <select> element. 13559 // 13560 .hide(); 13561 13562 } else { 13563 // 13564 // Create our list item <li> elements. 13565 // 13566 liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' ); 13567 // 13568 // Refresh the ul with options from the select in case the supplied markup doesn't match. 13569 // Clear what's currently in the <ul> element. 13570 // 13571 $customList.html( '' ) 13572 // 13573 // Populate the list item <li> elements. 13574 // 13575 .append( liHtml ); 13576 13577 } // endif $customSelect.length === 0 13578 13579 // 13580 // Determine whether or not the custom select element should be disabled. 13581 // 13582 $customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) ); 13583 // 13584 // Cache our List item elements. 13585 // 13586 $listItems = $customList.find( 'li' ); 13587 13588 // 13589 // Determine which elements to select in our custom list. 13590 // 13591 $options.each( function ( index ) { 13592 13593 if ( this.selected ) { 13594 // 13595 // Add the selected class to the current li element 13596 // 13597 $listItems.eq( index ).addClass( 'selected' ); 13598 // 13599 // Update the current element with the option value. 13600 // 13601 if ($currentSelect) { 13602 $currentSelect.html( $( this ).html() ); 13603 } 13604 13605 } 13606 13607 }); 13608 13609 // 13610 // Update the custom <ul> list width property. 13611 // 13612 $customList.css( 'width', 'auto' ); 13613 // 13614 // Set the custom select width property. 13615 // 13616 $customSelect.css( 'width', 'auto' ); 13617 13618 // 13619 // If we're not specifying a predetermined form size. 13620 // 13621 if ( !$customSelect.is( '.small, .medium, .large, .expand' ) ) { 13622 13623 // ------------------------------------------------------------------------------------ 13624 // This is a work-around for when elements are contained within hidden parents. 13625 // For example, when custom-form elements are inside of a hidden reveal modal. 13626 // 13627 // We need to display the current custom list element as well as hidden parent elements 13628 // in order to properly calculate the list item element's width property. 13629 // ------------------------------------------------------------------------------------- 13630 13631 // 13632 // Show the drop down. 13633 // This should ensure that the list item's width values are properly calculated. 13634 // 13635 $customSelect.addClass( 'open' ); 13636 // 13637 // Quickly, display all parent elements. 13638 // This should help us calcualate the width of the list item's within the drop down. 13639 // 13640 hiddenFixObj.adjust( $customList ); 13641 // 13642 // Grab the largest list item width. 13643 // 13644 maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth; 13645 // 13646 // Okay, now reset the parent elements. 13647 // This will hide them again. 13648 // 13649 hiddenFixObj.reset(); 13650 // 13651 // Finally, hide the drop down. 13652 // 13653 $customSelect.removeClass( 'open' ); 13654 // 13655 // Set the custom list width. 13656 // 13657 $customSelect.width( maxWidth + 18); 13658 // 13659 // Set the custom list element (<ul />) width. 13660 // 13661 $customList.width( maxWidth + 16 ); 13662 13663 } // endif 13664 13665 } 13666 13667 $('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup); 13668 $('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup); 13669 $('form.custom select[data-customforms!=disabled]').each(appendCustomSelect); 13670 }; 13671 13672 var refreshCustomSelect = function($select) { 13673 var maxWidth = 0, 13674 $customSelect = $select.next(); 13675 $options = $select.find('option'); 13676 $customSelect.find('ul').html(''); 13677 13678 $options.each(function () { 13679 $li = $('<li>' + $(this).html() + '</li>'); 13680 $customSelect.find('ul').append($li); 13681 }); 13682 13683 // re-populate 13684 $options.each(function (index) { 13685 if (this.selected) { 13686 $customSelect.find('li').eq(index).addClass('selected'); 13687 $customSelect.find('.current').html($(this).html()); 13688 } 13689 }); 13690 13691 // fix width 13692 $customSelect.removeAttr('style') 13693 .find('ul').removeAttr('style'); 13694 $customSelect.find('li').each(function () { 13695 $customSelect.addClass('open'); 13696 if ($(this).outerWidth() > maxWidth) { 13697 maxWidth = $(this).outerWidth(); 13698 } 13699 $customSelect.removeClass('open'); 13700 }); 13701 $customSelect.css('width', maxWidth + 18 + 'px'); 13702 $customSelect.find('ul').css('width', maxWidth + 16 + 'px'); 13703 13704 }; 13705 13706 var toggleCheckbox = function($element) { 13707 var $input = $element.prev(), 13708 input = $input[0]; 13709 13710 if (false === $input.is(':disabled')) { 13711 input.checked = ((input.checked) ? false : true); 13712 $element.toggleClass('checked'); 13713 13714 $input.trigger('change'); 13715 } 13716 }; 13717 13718 var toggleRadio = function($element) { 13719 var $input = $element.prev(), 13720 $form = $input.closest('form.custom'), 13721 input = $input[0]; 13722 13723 if (false === $input.is(':disabled')) {
13724 $form.find('input:radio[name="' + $input.attr('name') + '"]').next().not($element).removeClass('checked'); 13725 if ( !$element.hasClass('checked') ) { 13726 $element.toggleClass('checked'); 13727 } 13728 input.checked = $element.hasClass('checked'); 13729 13730 $input.trigger('change'); 13731 } 13732 }; 13733 13734 $(document).on('click', 'form.custom span.custom.checkbox', function (event) { 13735 event.preventDefault(); 13736 event.stopPropagation(); 13737 13738 toggleCheckbox($(this)); 13739 }); 13740 13741 $(document).on('click', 'form.custom span.custom.radio', function (event) { 13742 event.preventDefault(); 13743 event.stopPropagation(); 13744 13745 toggleRadio($(this)); 13746 }); 13747 13748 $(document).on('change', 'form.custom select[data-customforms!=disabled]', function (event) { 13749 refreshCustomSelect($(this)); 13750 }); 13751 13752 $(document).on('click', 'form.custom label', function (event) { 13753 var $associatedElement = $('#' + $(this).attr('for') + '[data-customforms!=disabled]'), 13754 $customCheckbox, 13755 $customRadio; 13756 if ($associatedElement.length !== 0) { 13757 if ($associatedElement.attr('type') === 'checkbox') { 13758 event.preventDefault(); 13759 $customCheckbox = $(this).find('span.custom.checkbox'); 13760 //the checkbox might be outside after the label 13761 if ($customCheckbox.length == 0) { 13762 $customCheckbox = $(this).next('span.custom.checkbox'); 13763 } 13764 //the checkbox might be outside before the label 13765 if ($customCheckbox.length == 0) { 13766 $customCheckbox = $(this).prev('span.custom.checkbox'); 13767 } 13768 toggleCheckbox($customCheckbox); 13769 } else if ($associatedElement.attr('type') === 'radio') { 13770 event.preventDefault(); 13771 $customRadio = $(this).find('span.custom.radio'); 13772 //the radio might be outside after the label 13773 if ($customRadio.length == 0) { 13774 $customRadio = $(this).next('span.custom.radio'); 13775 } 13776 //the radio might be outside before the label 13777 if ($customRadio.length == 0) { 13778 $customRadio = $(this).prev('span.custom.radio'); 13779 } 13780 toggleRadio($customRadio); 13781 } 13782 } 13783 }); 13784 13785 $(document).on('click', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (event) { 13786 var $this = $(this), 13787 $dropdown = $this.closest('div.custom.dropdown'), 13788 $select = $dropdown.prev(); 13789 13790 event.preventDefault(); 13791 $('div.dropdown').removeClass('open'); 13792 13793 if (false === $select.is(':disabled')) { 13794 $dropdown.toggleClass('open'); 13795 13796 if ($dropdown.hasClass('open')) { 13797 $(document).bind('click.customdropdown', function (event) { 13798 $dropdown.removeClass('open'); 13799 $(document).unbind('.customdropdown'); 13800 }); 13801 } else { 13802 $(document).unbind('.customdropdown'); 13803 } 13804 return false; 13805 } 13806 }); 13807 13808 $(document).on('click', 'form.custom div.custom.dropdown li', function (event) { 13809 var $this = $(this), 13810 $customDropdown = $this.closest('div.custom.dropdown'), 13811 $select = $customDropdown.prev(), 13812 selectedIndex = 0; 13813 13814 event.preventDefault(); 13815 event.stopPropagation(); 13816 $('div.dropdown').removeClass('open'); 13817 13818 $this 13819 .closest('ul') 13820 .find('li') 13821 .removeClass('selected'); 13822 $this.addClass('selected'); 13823 13824 $customDropdown 13825 .removeClass('open') 13826 .find('a.current') 13827 .html($this.html()); 13828 13829 $this.closest('ul').find('li').each(function (index) { 13830 if ($this[0] == this) { 13831 selectedIndex = index; 13832 } 13833 13834 }); 13835 $select[0].selectedIndex = selectedIndex; 13836 13837 $select.trigger('change'); 13838 }); 13839 13840 13841 $.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup; 13842 13843})( jQuery ); 13844;(function ($, window, document, undefined) { 13845 'use strict'; 13846 13847 var settings = { 13848 callback: $.noop, 13849 deep_linking: true, 13850 init: false 13851 }, 13852 13853 methods = { 13854 init : function (options) { 13855 settings = $.extend({}, settings, options); 13856 13857 return this.each(function () { 13858 if (!settings.init) methods.events(); 13859 13860 if (settings.deep_linking) methods.from_hash(); 13861 }); 13862 }, 13863 13864 events : function () { 13865 $(document).on('click.fndtn', '.tabs a', function (e) { 13866 methods.set_tab($(this).parent('dd, li'), e); 13867 }); 13868 13869 settings.init = true; 13870 }, 13871 13872 set_tab : function ($tab, e) { 13873 var $activeTab = $tab.closest('dl, ul').find('.active'), 13874 target = $tab.children('a').attr("href"), 13875 hasHash = /^#/.test(target), 13876 $content = $(target + 'Tab'); 13877 13878 if (hasHash && $content.length > 0) { 13879 // Show tab content
13880 if (e && !settings.deep_linking) e.preventDefault(); 13881 $content.closest('.tabs-content').children('li').removeClass('active').hide(); 13882 $content.css('display', 'block').addClass('active'); 13883 } 13884 13885 // Make active tab 13886 $activeTab.removeClass('active'); 13887 $tab.addClass('active'); 13888 13889 settings.callback(); 13890 }, 13891 13892 from_hash : function () { 13893 var hash = window.location.hash, 13894 $tab = $('a[href="' + hash + '"]'); 13895 13896 $tab.trigger('click.fndtn'); 13897 } 13898 } 13899 13900 $.fn.foundationTabs = function (method) { 13901 if (methods[method]) { 13902 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 13903 } else if (typeof method === 'object' || !method) { 13904 return methods.init.apply(this, arguments); 13905 } else { 13906 $.error('Method ' + method + ' does not exist on jQuery.foundationTabs'); 13907 } 13908 }; 13909}(jQuery, this, this.document)); 13910;(function ($, window, undefined) { 13911 'use strict'; 13912 13913 $.fn.foundationNavigation = function (options) { 13914 13915 var lockNavBar = false; 13916 // Windows Phone, sadly, does not register touch events :( 13917 if (Modernizr.touch || navigator.userAgent.match(/Windows Phone/i)) { 13918 $(document).on('click.fndtn touchstart.fndtn', '.nav-bar a.flyout-toggle', function (e) { 13919 e.preventDefault(); 13920 var flyout = $(this).siblings('.flyout').first(); 13921 if (lockNavBar === false) { 13922 $('.nav-bar .flyout').not(flyout).slideUp(500); 13923 flyout.slideToggle(500, function () { 13924 lockNavBar = false; 13925 }); 13926 } 13927 lockNavBar = true; 13928 }); 13929 $('.nav-bar>li.has-flyout', this).addClass('is-touch'); 13930 } else { 13931 $('.nav-bar>li.has-flyout', this).on('mouseenter mouseleave', function (e) { 13932 if (e.type == 'mouseenter') { 13933 $('.nav-bar').find('.flyout').hide(); 13934 $(this).children('.flyout').show(); 13935 } 13936 13937 if (e.type == 'mouseleave') { 13938 var flyout = $(this).children('.flyout'), 13939 inputs = flyout.find('input'), 13940 hasFocus = function (inputs) { 13941 var focus; 13942 if (inputs.length > 0) { 13943 inputs.each(function () { 13944 if ($(this).is(":focus")) { 13945 focus = true; 13946 } 13947 }); 13948 return focus; 13949 } 13950 13951 return false; 13952 }; 13953 13954 if (!hasFocus(inputs)) { 13955 $(this).children('.flyout').hide(); 13956 } 13957 } 13958 13959 }); 13960 } 13961 13962 }; 13963 13964})( jQuery, this ); 13965/* 13966 * jQuery Foundation Top Bar 2.0.4 13967 * http://foundation.zurb.com 13968 * Copyright 2012, ZURB 13969 * Free to use under the MIT license. 13970 * http://www.opensource.org/licenses/mit-license.php 13971*/ 13972 13973/*jslint unparam: true, browser: true, indent: 2 */ 13974 13975 13976;(function ($, window, undefined) { 13977 'use strict'; 13978 13979 var settings = { 13980 index : 0, 13981 initialized : false 13982 }, 13983 13984 methods = { 13985 init : function (options) { 13986 return this.each(function () { 13987 settings = $.extend(settings, options); 13988 settings.$w = $(window), 13989 settings.$topbar = $('nav.top-bar'), 13990 settings.$section = settings.$topbar.find('section'), 13991 settings.$titlebar = settings.$topbar.children('ul:first'); 13992 13993 var breakpoint = $("<div class='top-bar-js-breakpoint'/>").appendTo("body"); 13994 settings.breakPoint = breakpoint.width(); 13995 breakpoint.remove(); 13996 13997 if (!settings.initialized) { 13998 methods.assemble(); 13999 settings.initialized = true; 14000 } 14001 14002 if (!settings.height) { 14003 methods.largestUL(); 14004 } 14005 14006 if (settings.$topbar.parent().hasClass('fixed')) { 14007 $('body').css('padding-top',settings.$topbar.outerHeight()) 14008 } 14009 14010 $('.top-bar .toggle-topbar').off('click.fndtn').on('click.fndtn', function (e) { 14011 e.preventDefault(); 14012 14013 if (methods.breakpoint()) { 14014 settings.$topbar.toggleClass('expanded'); 14015 settings.$topbar.css('min-height', ''); 14016 } 14017 14018 if (!settings.$topbar.hasClass('expanded')) { 14019 settings.$section.css({left: '0%'}); 14020 settings.$section.find('>.name').css({left: '100%'}); 14021 settings.$section.find('li.moved').removeClass('moved'); 14022 settings.index = 0; 14023 } 14024 }); 14025 14026 // Show the Dropdown Levels on Click 14027 $('.top-bar .has-dropdown>a').off('click.fndtn').on('click.fndtn', function (e) { 14028 if (Modernizr.touch || methods.breakpoint()) 14029 e.preventDefault(); 14030 14031 if (methods.breakpoint()) { 14032 var $this = $(this), 14033 $selectedLi = $this.closest('li'); 14034 14035 settings.index += 1; 14036 $selectedLi.addClass('moved'); 14037 settings.$section.css({left: -(100 * settings.index) + '%'}); 14038 settings.$section.find('>.name').css({left: 100 * settings.index + '%'}); 14039 14040 $this.siblings('ul').height(settings.height + settings.$titlebar.outerHeight(true)); 14041 settings.$topbar.css('min-height', settings.height + settings.$titlebar.outerHeight(true) * 2) 14042 } 14043 }); 14044 14045 $(window).on('resize.fndtn.topbar',function() { 14046 if (!methods.breakpoint()) { 14047 settings.$topbar.css('min-height', ''); 14048 } 14049 }); 14050 14051 // Go up a level on Click 14052 $('.top-bar .has-dropdown .back').off('click.fndtn').on('click.fndtn', function (e) { 14053 e.preventDefault(); 14054 14055 var $this = $(this), 14056 $movedLi = $this.closest('li.moved'), 14057 $previousLevelUl = $movedLi.parent(); 14058 14059 settings.index -= 1; 14060 settings.$section.css({left: -(100 * settings.index) + '%'}); 14061 settings.$section.find('>.name').css({'left': 100 * settings.index + '%'}); 14062 14063 if (settings.index === 0) { 14064 settings.$topbar.css('min-height', 0); 14065 } 14066 14067 setTimeout(function () { 14068 $movedLi.removeClass('moved'); 14069 }, 300); 14070 }); 14071 }); 14072 }, 14073 14074 breakpoint : function () { 14075 return settings.$w.width() < settings.breakPoint; 14076 }, 14077 14078 assemble : function () { 14079 // Pull element out of the DOM for manipulation 14080 settings.$section.detach(); 14081 14082 settings.$section.find('.has-dropdown>a').each(function () { 14083 var $link = $(this), 14084 $dropdown = $link.siblings('.dropdown'), 14085 $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li>'); 14086 14087 // Copy link to subnav 14088 $titleLi.find('h5>a').html($link.html()); 14089 $dropdown.prepend($titleLi); 14090 }); 14091 14092 // Put element back in the DOM 14093 settings.$section.appendTo(settings.$topbar); 14094 }, 14095 14096 largestUL : function () { 14097 var uls = settings.$topbar.find('section ul ul'), 14098 largest = uls.first(), 14099 total = 0; 14100 14101 uls.each(function () { 14102 if ($(this).children('li').length > largest.children('li').length) { 14103 largest = $(this); 14104 } 14105 }); 14106 14107 largest.children('li').each(function () { total += $(this).outerHeight(true); }); 14108 14109 settings.height = total; 14110 } 14111 }; 14112 14113 $.fn.foundationTopBar = function (method) { 14114 if (methods[method]) { 14115 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 14116 } else if (typeof method === 'object' || !method) { 14117 return methods.init.apply(this, arguments); 14118 } else { 14119 $.error('Method ' + method + ' does not exist on jQuery.foundationTopBar'); 14120 } 14121 }; 14122 14123 // Monitor scroll position for sticky 14124 if ($('.sticky').length > 0) { 14125 var distance = $('.sticky').length ? $('.sticky').offset().top: 0, 14126 $window = $(window); 14127 14128 $window.scroll(function() { 14129 if ( $window.scrollTop() >= distance ) { 14130 $(".sticky").addClass("fixed"); 14131 } 14132 14133 else if ( $window.scrollTop() < distance ) { 14134 $(".sticky").removeClass("fixed"); 14135 } 14136 }); 14137 } 14138 14139}(jQuery, this)); 14140/* 14141 * jQuery Reveal Plugin 1.1 14142 * www.ZURB.com 14143 * Copyright 2010, ZURB 14144 * Free to use under the MIT license. 14145 * http://www.opensource.org/licenses/mit-license.php 14146*/ 14147/*globals jQuery */ 14148 14149 14150(function ($) { 14151 'use strict'; 14152 // 14153 // Global variable. 14154 // Helps us determine if the current modal is being queued for display. 14155 // 14156 var modalQueued = false;
14157 14158 // 14159 // Bind the live 'click' event to all anchor elemnets with the data-reveal-id attribute. 14160 // 14161 $(document).on('click', 'a[data-reveal-id]', function ( event ) { 14162 // 14163 // Prevent default action of the event. 14164 // 14165 event.preventDefault(); 14166 // 14167 // Get the clicked anchor data-reveal-id attribute value. 14168 // 14169 var modalLocation = $( this ).attr( 'data-reveal-id' ); 14170 // 14171 // Find the element with that modalLocation id and call the reveal plugin. 14172 // 14173 $( '#' + modalLocation ).reveal( $( this ).data() ); 14174 14175 }); 14176 14177 /** 14178 * @module reveal 14179 * @property {Object} [options] Reveal options 14180 */ 14181 $.fn.reveal = function ( options ) { 14182 /* 14183 * Cache the document object. 14184 */ 14185 var $doc = $( document ), 14186 /* 14187 * Default property values. 14188 */ 14189 defaults = { 14190 /** 14191 * Possible options: fade, fadeAndPop, none 14192 * 14193 * @property animation 14194 * @type {String} 14195 * @default fadeAndPop 14196 */ 14197 animation: 'fadeAndPop', 14198 /** 14199 * Speed at which the reveal should show. How fast animtions are. 14200 * 14201 * @property animationSpeed 14202 * @type {Integer} 14203 * @default 300 14204 */ 14205 animationSpeed: 300, 14206 /** 14207 * Should the modal close when the background is clicked? 14208 * 14209 * @property closeOnBackgroundClick 14210 * @type {Boolean} 14211 * @default true 14212 */ 14213 closeOnBackgroundClick: true, 14214 /** 14215 * Specify a class name for the 'close modal' element. 14216 * This element will close an open modal. 14217 * 14218 @example 14219 <a href='#close' class='close-reveal-modal'>Close Me</a> 14220 * 14221 * @property dismissModalClass 14222 * @type {String} 14223 * @default close-reveal-modal 14224 */ 14225 dismissModalClass: 'close-reveal-modal', 14226 /** 14227 * Specify a callback function that triggers 'before' the modal opens. 14228 * 14229 * @property open 14230 * @type {Function} 14231 * @default function(){} 14232 */ 14233 open: $.noop, 14234 /** 14235 * Specify a callback function that triggers 'after' the modal is opened. 14236 * 14237 * @property opened 14238 * @type {Function} 14239 * @default function(){} 14240 */ 14241 opened: $.noop, 14242 /** 14243 * Specify a callback function that triggers 'before' the modal prepares to close. 14244 * 14245 * @property close 14246 * @type {Function} 14247 * @default function(){} 14248 */ 14249 close: $.noop, 14250 /** 14251 * Specify a callback function that triggers 'after' the modal is closed. 14252 * 14253 * @property closed 14254 * @type {Function} 14255 * @default function(){} 14256 */ 14257 closed: $.noop 14258 } 14259 ; 14260 // 14261 // Extend the default options. 14262 // This replaces the passed in option (options) values with default values. 14263 // 14264 options = $.extend( {}, defaults, options ); 14265 14266 // 14267 // Apply the plugin functionality to each element in the jQuery collection. 14268 // 14269 return this.not('.reveal-modal.open').each( function () { 14270 // 14271 // Cache the modal element 14272 // 14273 var modal = $( this ), 14274 // 14275 // Get the current css 'top' property value in decimal format. 14276 // 14277 topMeasure = parseInt( modal.css( 'top' ), 10 ), 14278 // 14279 // Calculate the top offset. 14280 // 14281 topOffset = modal.height() + topMeasure, 14282 // 14283 // Helps determine if the modal is locked. 14284 // This way we keep the modal from triggering while it's in the middle of animating. 14285 // 14286 locked = false, 14287 // 14288 // Get the modal background element. 14289 // 14290 modalBg = $( '.reveal-modal-bg' ), 14291 // 14292 // Show modal properties 14293 // 14294 cssOpts = { 14295 // 14296 // Used, when we show the modal. 14297 // 14298 open : { 14299 // 14300 // Set the 'top' property to the document scroll minus the calculated top offset. 14301 // 14302 'top': 0, 14303 // 14304 // Opacity gets set to 0. 14305 // 14306 'opacity': 0, 14307 // 14308 // Show the modal 14309 // 14310 'visibility': 'visible', 14311 // 14312 // Ensure it's displayed as a block element. 14313 // 14314 'display': 'block' 14315 }, 14316 // 14317 // Used, when we hide the modal. 14318 // 14319 close : { 14320 // 14321 // Set the default 'top' property value. 14322 // 14323 'top': topMeasure, 14324 // 14325 // Has full opacity. 14326 // 14327 'opacity': 1, 14328 // 14329 // Hide the modal 14330 // 14331 'visibility': 'hidden', 14332 // 14333 // Ensure the elment is hidden. 14334 // 14335 'display': 'none' 14336 } 14337 14338 }, 14339 // 14340 // Initial closeButton variable. 14341 // 14342 $closeButton 14343 ; 14344 14345 // 14346 // Do we have a modal background element? 14347 // 14348 if ( modalBg.length === 0 ) { 14349 // 14350 // No we don't. So, let's create one. 14351 // 14352 modalBg = $( '<div />', { 'class' : 'reveal-modal-bg' } ) 14353 // 14354 // Then insert it after the modal element. 14355 // 14356 .insertAfter( modal ); 14357 // 14358 // Now, fade it out a bit. 14359 // 14360 modalBg.fadeTo( 'fast', 0.8 ); 14361 } 14362 14363 // 14364 // Helper Methods 14365 // 14366 14367 /** 14368 * Unlock the modal for animation. 14369 * 14370 * @method unlockModal 14371 */ 14372 function unlockModal() { 14373 locked = false;
14374 } 14375 14376 /** 14377 * Lock the modal to prevent further animation. 14378 * 14379 * @method lockModal 14380 */ 14381 function lockModal() { 14382 locked = true; 14383 } 14384 14385 /** 14386 * Closes all open modals. 14387 * 14388 * @method closeOpenModal 14389 */ 14390 function closeOpenModals() { 14391 // 14392 // Get all reveal-modal elements with the .open class. 14393 // 14394 var $openModals = $( ".reveal-modal.open" ); 14395 // 14396 // Do we have modals to close? 14397 // 14398 if ( $openModals.length === 1 ) { 14399 // 14400 // Set the modals for animation queuing. 14401 // 14402 modalQueued = true; 14403 // 14404 // Trigger the modal close event. 14405 // 14406 $openModals.trigger( "reveal:close" ); 14407 } 14408 14409 } 14410 /** 14411 * Animates the modal opening. 14412 * Handles the modal 'open' event. 14413 * 14414 * @method openAnimation 14415 */ 14416 function openAnimation() { 14417 // 14418 // First, determine if we're in the middle of animation. 14419 // 14420 if ( !locked ) { 14421 // 14422 // We're not animating, let's lock the modal for animation. 14423 // 14424 lockModal(); 14425 // 14426 // Close any opened modals. 14427 // 14428 closeOpenModals(); 14429 // 14430 // Now, add the open class to this modal. 14431 // 14432 modal.addClass( "open" ); 14433 14434 // 14435 // Are we executing the 'fadeAndPop' animation? 14436 // 14437 if ( options.animation === "fadeAndPop" ) { 14438 // 14439 // Yes, we're doing the 'fadeAndPop' animation. 14440 // Okay, set the modal css properties. 14441 // 14442 // 14443 // Set the 'top' property to the document scroll minus the calculated top offset. 14444 // 14445 cssOpts.open.top = $doc.scrollTop() - topOffset; 14446 // 14447 // Flip the opacity to 0. 14448 // 14449 cssOpts.open.opacity = 0; 14450 // 14451 // Set the css options. 14452 // 14453 modal.css( cssOpts.open ); 14454 // 14455 // Fade in the background element, at half the speed of the modal element. 14456 // So, faster than the modal element. 14457 // 14458 modalBg.fadeIn( options.animationSpeed / 2 ); 14459 14460 // 14461 // Let's delay the next animation queue. 14462 // We'll wait until the background element is faded in. 14463 // 14464 modal.delay( options.animationSpeed / 2 ) 14465 // 14466 // Animate the following css properties. 14467 // 14468 .animate( { 14469 // 14470 // Set the 'top' property to the document scroll plus the calculated top measure. 14471 // 14472 "top": $doc.scrollTop() + topMeasure + 'px', 14473 // 14474 // Set it to full opacity. 14475 // 14476 "opacity": 1 14477 14478 }, 14479 /* 14480 * Fade speed. 14481 */ 14482 options.animationSpeed, 14483 /* 14484 * End of animation callback. 14485 */ 14486 function () { 14487 // 14488 // Trigger the modal reveal:opened event. 14489 // This should trigger the functions set in the options.opened property. 14490 // 14491 modal.trigger( 'reveal:opened' ); 14492 14493 }); // end of animate. 14494 14495 } // end if 'fadeAndPop' 14496 14497 // 14498 // Are executing the 'fade' animation? 14499 // 14500 if ( options.animation === "fade" ) { 14501 // 14502 // Yes, were executing 'fade'. 14503 // Okay, let's set the modal properties. 14504 // 14505 cssOpts.open.top = $doc.scrollTop() + topMeasure; 14506 // 14507 // Flip the opacity to 0. 14508 // 14509 cssOpts.open.opacity = 0; 14510 // 14511 // Set the css options. 14512 // 14513 modal.css( cssOpts.open ); 14514 // 14515 // Fade in the modal background at half the speed of the modal. 14516 // So, faster than modal. 14517 //
14518 modalBg.fadeIn( options.animationSpeed / 2 ); 14519 14520 // 14521 // Delay the modal animation. 14522 // Wait till the modal background is done animating. 14523 // 14524 modal.delay( options.animationSpeed / 2 ) 14525 // 14526 // Now animate the modal. 14527 // 14528 .animate( { 14529 // 14530 // Set to full opacity. 14531 // 14532 "opacity": 1 14533 }, 14534 14535 /* 14536 * Animation speed. 14537 */ 14538 options.animationSpeed, 14539 14540 /* 14541 * End of animation callback. 14542 */ 14543 function () { 14544 // 14545 // Trigger the modal reveal:opened event. 14546 // This should trigger the functions set in the options.opened property. 14547 // 14548 modal.trigger( 'reveal:opened' ); 14549 14550 }); 14551 14552 } // end if 'fade' 14553 14554 // 14555 // Are we not animating? 14556 // 14557 if ( options.animation === "none" ) { 14558 // 14559 // We're not animating. 14560 // Okay, let's set the modal css properties. 14561 // 14562 // 14563 // Set the top property. 14564 // 14565 cssOpts.open.top = $doc.scrollTop() + topMeasure; 14566 // 14567 // Set the opacity property to full opacity, since we're not fading (animating). 14568 // 14569 cssOpts.open.opacity = 1; 14570 // 14571 // Set the css property. 14572 // 14573 modal.css( cssOpts.open ); 14574 // 14575 // Show the modal Background. 14576 // 14577 modalBg.css( { "display": "block" } ); 14578 // 14579 // Trigger the modal opened event. 14580 // 14581 modal.trigger( 'reveal:opened' ); 14582 14583 } // end if animating 'none' 14584 14585 }// end if !locked 14586 14587 }// end openAnimation 14588 14589 14590 function openVideos() { 14591 var video = modal.find('.flex-video'), 14592 iframe = video.find('iframe'); 14593 if (iframe.length > 0) { 14594 iframe.attr("src", iframe.data("src")); 14595 video.fadeIn(100); 14596 } 14597 } 14598 14599 // 14600 // Bind the reveal 'open' event. 14601 // When the event is triggered, openAnimation is called 14602 // along with any function set in the options.open property. 14603 // 14604 modal.bind( 'reveal:open.reveal', openAnimation ); 14605 modal.bind( 'reveal:open.reveal', openVideos); 14606 14607 /** 14608 * Closes the modal element(s) 14609 * Handles the modal 'close' event. 14610 * 14611 * @method closeAnimation 14612 */ 14613 function closeAnimation() { 14614 // 14615 // First, determine if we're in the middle of animation. 14616 // 14617 if ( !locked ) { 14618 // 14619 // We're not animating, let's lock the modal for animation. 14620 // 14621 lockModal(); 14622 // 14623 // Clear the modal of the open class. 14624 // 14625 modal.removeClass( "open" ); 14626 14627 // 14628 // Are we using the 'fadeAndPop' animation? 14629 // 14630 if ( options.animation === "fadeAndPop" ) { 14631 // 14632 // Yes, okay, let's set the animation properties. 14633 // 14634 modal.animate( { 14635 // 14636 // Set the top property to the document scrollTop minus calculated topOffset. 14637 // 14638 "top": $doc.scrollTop() - topOffset + 'px', 14639 // 14640 // Fade the modal out, by using the opacity property. 14641 // 14642 "opacity": 0 14643 14644 }, 14645 /* 14646 * Fade speed. 14647 */ 14648 options.animationSpeed / 2, 14649 /* 14650 * End of animation callback. 14651 */ 14652 function () { 14653 // 14654 // Set the css hidden options. 14655 // 14656 modal.css( cssOpts.close ); 14657 14658 }); 14659 // 14660 // Is the modal animation queued? 14661 // 14662 if ( !modalQueued ) { 14663 // 14664 // Oh, the modal(s) are mid animating. 14665 // Let's delay the animation queue. 14666 // 14667 modalBg.delay( options.animationSpeed ) 14668 // 14669 // Fade out the modal background. 14670 // 14671 .fadeOut( 14672 /* 14673 * Animation speed. 14674 */ 14675 options.animationSpeed, 14676 /* 14677 * End of animation callback. 14678 */ 14679 function () { 14680 // 14681 // Trigger the modal 'closed' event. 14682 // This should trigger any method set in the options.closed property. 14683 // 14684 modal.trigger( 'reveal:closed' ); 14685 14686 }); 14687 14688 } else { 14689 // 14690 // We're not mid queue. 14691 // Trigger the modal 'closed' event. 14692 // This should trigger any method set in the options.closed propety. 14693 // 14694 modal.trigger( 'reveal:closed' ); 14695 14696 } // end if !modalQueued 14697 14698 } // end if animation 'fadeAndPop' 14699 14700 // 14701 // Are we using the 'fade' animation. 14702 // 14703 if ( options.animation === "fade" ) { 14704 // 14705 // Yes, we're using the 'fade' animation. 14706 // 14707 modal.animate( { "opacity" : 0 }, 14708 /* 14709 * Animation speed. 14710 */ 14711 options.animationSpeed, 14712 /* 14713 * End of animation callback. 14714 */ 14715 function () { 14716 // 14717 // Set the css close options. 14718 // 14719 modal.css( cssOpts.close ); 14720 14721 }); // end animate 14722 14723 // 14724 // Are we mid animating the modal(s)? 14725 // 14726 if ( !modalQueued ) { 14727 // 14728 // Oh, the modal(s) are mid animating. 14729 // Let's delay the animation queue. 14730 // 14731 modalBg.delay( options.animationSpeed ) 14732 // 14733 // Let's fade out the modal background element. 14734 // 14735 .fadeOut( 14736 /* 14737 * Animation speed. 14738 */ 14739 options.animationSpeed, 14740 /* 14741 * End of animation callback. 14742 */ 14743 function () { 14744 // 14745 // Trigger the modal 'closed' event. 14746 // This should trigger any method set in the options.closed propety. 14747 // 14748 modal.trigger( 'reveal:closed' ); 14749 14750 }); // end fadeOut 14751 14752 } else { 14753 // 14754 // We're not mid queue. 14755 // Trigger the modal 'closed' event. 14756 // This should trigger any method set in the options.closed propety. 14757 // 14758 modal.trigger( 'reveal:closed' ); 14759 14760 } // end if !modalQueued 14761 14762 } // end if animation 'fade' 14763 14764 // 14765 // Are we not animating? 14766 // 14767 if ( options.animation === "none" ) { 14768 // 14769 // We're not animating. 14770 // Set the modal close css options. 14771 // 14772 modal.css( cssOpts.close ); 14773 // 14774 // Is the modal in the middle of an animation queue? 14775 // 14776 if ( !modalQueued ) { 14777 // 14778 // It's not mid queueu. Just hide it. 14779 // 14780 modalBg.css( { 'display': 'none' } ); 14781 } 14782 // 14783 // Trigger the modal 'closed' event. 14784 // This should trigger any method set in the options.closed propety. 14785 // 14786 modal.trigger( 'reveal:closed' ); 14787 14788 } // end if not animating 14789 // 14790 // Reset the modalQueued variable. 14791 // 14792 modalQueued = false;
14793 } // end if !locked 14794 14795 } // end closeAnimation 14796 14797 /** 14798 * Destroys the modal and it's events. 14799 * 14800 * @method destroy 14801 */ 14802 function destroy() { 14803 // 14804 // Unbind all .reveal events from the modal. 14805 // 14806 modal.unbind( '.reveal' ); 14807 // 14808 // Unbind all .reveal events from the modal background. 14809 // 14810 modalBg.unbind( '.reveal' ); 14811 // 14812 // Unbind all .reveal events from the modal 'close' button. 14813 // 14814 $closeButton.unbind( '.reveal' ); 14815 // 14816 // Unbind all .reveal events from the body. 14817 // 14818 $( 'body' ).unbind( '.reveal' ); 14819 14820 } 14821 14822 function closeVideos() { 14823 var video = modal.find('.flex-video'), 14824 iframe = video.find('iframe'); 14825 if (iframe.length > 0) { 14826 iframe.data("src", iframe.attr("src")); 14827 iframe.attr("src", ""); 14828 video.fadeOut(100); 14829 } 14830 } 14831 14832 // 14833 // Bind the modal 'close' event 14834 // 14835 modal.bind( 'reveal:close.reveal', closeAnimation ); 14836 modal.bind( 'reveal:closed.reveal', closeVideos ); 14837 // 14838 // Bind the modal 'opened' + 'closed' event 14839 // Calls the unlockModal method. 14840 // 14841 modal.bind( 'reveal:opened.reveal reveal:closed.reveal', unlockModal ); 14842 // 14843 // Bind the modal 'closed' event. 14844 // Calls the destroy method. 14845 // 14846 modal.bind( 'reveal:closed.reveal', destroy ); 14847 // 14848 // Bind the modal 'open' event 14849 // Handled by the options.open property function. 14850 // 14851 modal.bind( 'reveal:open.reveal', options.open ); 14852 // 14853 // Bind the modal 'opened' event. 14854 // Handled by the options.opened property function. 14855 // 14856 modal.bind( 'reveal:opened.reveal', options.opened ); 14857 // 14858 // Bind the modal 'close' event. 14859 // Handled by the options.close property function. 14860 // 14861 modal.bind( 'reveal:close.reveal', options.close ); 14862 // 14863 // Bind the modal 'closed' event. 14864 // Handled by the options.closed property function. 14865 // 14866 modal.bind( 'reveal:closed.reveal', options.closed ); 14867 14868 // 14869 // We're running this for the first time. 14870 // Trigger the modal 'open' event. 14871 // 14872 modal.trigger( 'reveal:open' ); 14873 14874 // 14875 // Get the closeButton variable element(s). 14876 // 14877 $closeButton = $( '.' + options.dismissModalClass ) 14878 // 14879 // Bind the element 'click' event and handler. 14880 // 14881 .bind( 'click.reveal', function () { 14882 // 14883 // Trigger the modal 'close' event. 14884 // 14885 modal.trigger( 'reveal:close' ); 14886 14887 }); 14888 14889 // 14890 // Should we close the modal background on click? 14891 // 14892 if ( options.closeOnBackgroundClick ) { 14893 // 14894 // Yes, close the modal background on 'click' 14895 // Set the modal background css 'cursor' propety to pointer. 14896 // Adds a pointer symbol when you mouse over the modal background. 14897 // 14898 modalBg.css( { "cursor": "pointer" } ); 14899 // 14900 // Bind a 'click' event handler to the modal background. 14901 // 14902 modalBg.bind( 'click.reveal', function () { 14903 // 14904 // Trigger the modal 'close' event. 14905 // 14906 modal.trigger( 'reveal:close' ); 14907 14908 }); 14909 14910 } 14911 14912 // 14913 // Bind keyup functions on the body element. 14914 // We'll want to close the modal when the 'escape' key is hit. 14915 // 14916 $( 'body' ).bind( 'keyup.reveal', function ( event ) { 14917 // 14918 // Did the escape key get triggered? 14919 // 14920 if ( event.which === 27 ) { // 27 is the keycode for the Escape key 14921 // 14922 // Escape key was triggered. 14923 // Trigger the modal 'close' event. 14924 // 14925 modal.trigger( 'reveal:close' ); 14926 } 14927 14928 }); // end $(body) 14929 14930 }); // end this.each 14931 14932 }; // end $.fn 14933 14934} ( jQuery ) ); 14935/* 14936 * jQuery Foundation Magellan 0.1.0 14937 * http://foundation.zurb.com 14938 * Copyright 2012, ZURB 14939 * Free to use under the MIT license. 14940 * http://www.opensource.org/licenses/mit-license.php 14941*/ 14942 14943/*jslint unparam: true, browser: true, indent: 2 */ 14944 14945 14946;(function ($, window, undefined) { 14947 'use strict'; 14948 14949 $.fn.foundationMagellan = function(options) { 14950 var $window = $(window), 14951 $document = $(document), 14952 $fixedMagellan = $('[data-magellan-expedition=fixed]'), 14953 defaults = { 14954 threshold: ($fixedMagellan.length) ? $fixedMagellan.outerHeight(true) : 0, 14955 activeClass: 'active' 14956 }, 14957 options = $.extend({}, defaults, options); 14958 14959 // Indicate we have arrived at a destination 14960 $document.on('magellan.arrival', '[data-magellan-arrival]', function(e) { 14961 var $destination = $(this), 14962 $expedition = $destination.closest('[data-magellan-expedition]'), 14963 activeClass = $expedition.attr('data-magellan-active-class') || options.activeClass; 14964 $destination 14965 .closest('[data-magellan-expedition]') 14966 .find('[data-magellan-arrival]') 14967 .not(this) 14968 .removeClass(activeClass); 14969 $destination.addClass(activeClass); 14970 }); 14971 14972 // Set starting point as the current destination 14973 var $expedition = $('[data-magellan-expedition]'); 14974 $expedition.find('[data-magellan-arrival]:first') 14975 .addClass($expedition.attr('data-magellan-active-class') || options.activeClass); 14976 14977 // Update fixed position 14978 $fixedMagellan.on('magellan.update-position', function(){ 14979 var $el = $(this); 14980 $el.data("magellan-fixed-position",""); 14981 $el.data("magellan-top-offset", ""); 14982 }) 14983 .trigger('magellan.update-position'); 14984 14985 $window.on('resize.magellan', function() { 14986 $fixedMagellan.trigger('magellan.update-position'); 14987 }); 14988 14989 $window.on('scroll.magellan', function() { 14990 var windowScrollTop = $window.scrollTop(); 14991 $fixedMagellan.each(function() { 14992 var $expedition = $(this); 14993 if ($expedition.data("magellan-top-offset") === "") { 14994 $expedition.data("magellan-top-offset", $expedition.offset().top); 14995 } 14996 var fixed_position = (windowScrollTop + options.threshold) > $expedition.data("magellan-top-offset"); 14997 if ($expedition.data("magellan-fixed-position") != fixed_position) { 14998 $expedition.data("magellan-fixed-position", fixed_position); 14999 if (fixed_position) { 15000 $expedition.css({position:"fixed", top:0}); 15001 } else { 15002 $expedition.css({position:"", top:""}); 15003 } 15004 } 15005 }); 15006 }); 15007
15008 // Determine when a destination has been reached, ah0y! 15009 var $lastDestination = $('[data-magellan-destination]:last'); 15010 // Determine if a destination has been set 15011 if ($lastDestination.length > 0) { 15012 $window.on('scroll.magellan', function (e) { 15013 var windowScrollTop = $window.scrollTop(), 15014 scrolltopPlusHeight = windowScrollTop + $window.outerHeight(true), 15015 lastDestinationTop = Math.ceil($lastDestination.offset().top); 15016 $('[data-magellan-destination]').each(function () { 15017 var $destination = $(this), 15018 destination_name = $destination.attr('data-magellan-destination'), 15019 topOffset = $destination.offset().top - windowScrollTop; 15020 if (topOffset <= options.threshold) { 15021 $('[data-magellan-arrival=' + destination_name + ']').trigger('magellan.arrival'); 15022 } 15023 // In large screens we may hit the bottom of the page and dont reach the top of the last magellan-destination, so lets force it 15024 if (scrolltopPlusHeight >= $document.outerHeight(true) && lastDestinationTop > windowScrollTop && lastDestinationTop < scrolltopPlusHeight) { 15025 $('[data-magellan-arrival]:last').trigger('magellan.arrival'); 15026 } 15027 }); 15028 }); 15029 } 15030 }; 15031}(jQuery, this)); 15032/* 15033 * jQuery Foundation Joyride Plugin 2.0.3 15034 * http://foundation.zurb.com 15035 * Copyright 2012, ZURB 15036 * Free to use under the MIT license. 15037 * http://www.opensource.org/licenses/mit-license.php 15038*/ 15039 15040/*jslint unparam: true, browser: true, indent: 2 */ 15041 15042 15043;(function ($, window, undefined) { 15044 'use strict'; 15045 15046 var defaults = { 15047 'version' : '2.0.3', 15048 'tipLocation' : 'bottom', // 'top' or 'bottom' in relation to parent 15049 'nubPosition' : 'auto', // override on a per tooltip bases 15050 'scrollSpeed' : 300, // Page scrolling speed in milliseconds 15051 'timer' : 0, // 0 = no timer , all other numbers = timer in milliseconds 15052 'startTimerOnClick' : true, // true or false - true requires clicking the first button start the timer 15053 'startOffset' : 0, // the index of the tooltip you want to start on (index of the li) 15054 'nextButton' : true, // true or false to control whether a next button is used 15055 'tipAnimation' : 'fade', // 'pop' or 'fade' in each tip 15056 'pauseAfter' : [], // array of indexes where to pause the tour after 15057 'tipAnimationFadeSpeed': 300, // when tipAnimation = 'fade' this is speed in milliseconds for the transition 15058 'cookieMonster' : false, // true or false to control whether cookies are used 15059 'cookieName' : 'joyride', // Name the cookie you'll use
15060 'cookieDomain' : false, // Will this cookie be attached to a domain, ie. '.notableapp.com' 15061 'tipContainer' : 'body', // Where will the tip be attached 15062 'postRideCallback' : $.noop, // A method to call once the tour closes (canceled or complete) 15063 'postStepCallback' : $.noop, // A method to call after each step 15064 'template' : { // HTML segments for tip layout 15065 'link' : '<a href="#close" class="joyride-close-tip">X</a>', 15066 'timer' : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>', 15067 'tip' : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>', 15068 'wrapper' : '<div class="joyride-content-wrapper"></div>', 15069 'button' : '<a href="#" class="small button joyride-next-tip"></a>' 15070 } 15071 }, 15072 15073 Modernizr = Modernizr || false, 15074 15075 settings = {}, 15076 15077 methods = { 15078 15079 init : function (opts) { 15080 return this.each(function () { 15081 15082 if ($.isEmptyObject(settings)) { 15083 settings = $.extend(true, defaults, opts); 15084 15085 // non configurable settings 15086 settings.document = window.document; 15087 settings.$document = $(settings.document); 15088 settings.$window = $(window); 15089 settings.$content_el = $(this); 15090 settings.body_offset = $(settings.tipContainer).position(); 15091 settings.$tip_content = $('> li', settings.$content_el); 15092 settings.paused = false; 15093 settings.attempts = 0; 15094 15095 settings.tipLocationPatterns = { 15096 top: ['bottom'], 15097 bottom: [], // bottom should not need to be repositioned 15098 left: ['right', 'top', 'bottom'], 15099 right: ['left', 'top', 'bottom'] 15100 }; 15101 15102 // are we using jQuery 1.7+ 15103 methods.jquery_check(); 15104 15105 // can we create cookies? 15106 if (!$.isFunction($.cookie)) { 15107 settings.cookieMonster = false; 15108 } 15109 15110 // generate the tips and insert into dom. 15111 if (!settings.cookieMonster || !$.cookie(settings.cookieName)) { 15112 15113 settings.$tip_content.each(function (index) { 15114 methods.create({$li : $(this), index : index}); 15115 }); 15116 15117 // show first tip 15118 if (!settings.startTimerOnClick && settings.timer > 0) { 15119 methods.show('init'); 15120 methods.startTimer(); 15121 } else { 15122 methods.show('init'); 15123 } 15124 15125 } 15126 15127 settings.$document.on('click.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) { 15128 e.preventDefault(); 15129 15130 if (settings.$li.next().length < 1) { 15131 methods.end(); 15132 } else if (settings.timer > 0) { 15133 clearTimeout(settings.automate); 15134 methods.hide(); 15135 methods.show(); 15136 methods.startTimer(); 15137 } else { 15138 methods.hide(); 15139 methods.show(); 15140 } 15141 15142 }); 15143 15144 settings.$document.on('click.joyride', '.joyride-close-tip', function (e) { 15145 e.preventDefault(); 15146 methods.end(); 15147 }); 15148 15149 settings.$window.bind('resize.joyride', function (e) { 15150 if (methods.is_phone()) { 15151 methods.pos_phone(); 15152 } else { 15153 methods.pos_default(); 15154 } 15155 }); 15156 } else { 15157 methods.restart(); 15158 } 15159 15160 }); 15161 }, 15162 15163 // call this method when you want to resume the tour 15164 resume : function () { 15165 methods.set_li(); 15166 methods.show(); 15167 }, 15168 15169 tip_template : function (opts) { 15170 var $blank, content; 15171 15172 opts.tip_class = opts.tip_class || ''; 15173 15174 $blank = $(settings.template.tip).addClass(opts.tip_class); 15175 content = $.trim($(opts.li).html()) + 15176 methods.button_text(opts.button_text) + 15177 settings.template.link + 15178 methods.timer_instance(opts.index); 15179 15180 $blank.append($(settings.template.wrapper)); 15181 $blank.first().attr('data-index', opts.index); 15182 $('.joyride-content-wrapper', $blank).append(content); 15183 15184 return $blank[0]; 15185 }, 15186 15187 timer_instance : function (index) { 15188 var txt; 15189 15190 if ((index === 0 && settings.startTimerOnClick && settings.timer > 0) || settings.timer === 0) { 15191 txt = ''; 15192 } else {
15193 txt = methods.outerHTML($(settings.template.timer)[0]); 15194 } 15195 return txt; 15196 }, 15197 15198 button_text : function (txt) { 15199 if (settings.nextButton) { 15200 txt = $.trim(txt) || 'Next'; 15201 txt = methods.outerHTML($(settings.template.button).append(txt)[0]); 15202 } else { 15203 txt = ''; 15204 } 15205 return txt; 15206 }, 15207 15208 create : function (opts) { 15209 // backwards compatibility with data-text attribute 15210 var buttonText = opts.$li.attr('data-button') || opts.$li.attr('data-text'), 15211 tipClass = opts.$li.attr('class'), 15212 $tip_content = $(methods.tip_template({ 15213 tip_class : tipClass, 15214 index : opts.index, 15215 button_text : buttonText, 15216 li : opts.$li 15217 })); 15218 15219 $(settings.tipContainer).append($tip_content); 15220 }, 15221 15222 show : function (init) { 15223 var opts = {}, ii, opts_arr = [], opts_len = 0, p, 15224 $timer = null; 15225 15226 // are we paused? 15227 if (settings.$li === undefined || ($.inArray(settings.$li.index(), settings.pauseAfter) === -1)) { 15228 15229 // don't go to the next li if the tour was paused 15230 if (settings.paused) { 15231 settings.paused = false; 15232 } else { 15233 methods.set_li(init); 15234 } 15235 15236 settings.attempts = 0; 15237 15238 if (settings.$li.length && settings.$target.length > 0) { 15239 opts_arr = (settings.$li.data('options') || ':').split(';'); 15240 opts_len = opts_arr.length; 15241 15242 // parse options 15243 for (ii = opts_len - 1; ii >= 0; ii--) { 15244 p = opts_arr[ii].split(':'); 15245 15246 if (p.length === 2) { 15247 opts[$.trim(p[0])] = $.trim(p[1]); 15248 } 15249 } 15250 15251 settings.tipSettings = $.extend({}, settings, opts); 15252 15253 settings.tipSettings.tipLocationPattern = settings.tipLocationPatterns[settings.tipSettings.tipLocation]; 15254 15255 // scroll if not modal 15256 if (!/body/i.test(settings.$target.selector)) { 15257 methods.scroll_to(); 15258 } 15259 15260 if (methods.is_phone()) { 15261 methods.pos_phone(true); 15262 } else { 15263 methods.pos_default(true); 15264 } 15265 15266 $timer = $('.joyride-timer-indicator', settings.$next_tip); 15267 15268 if (/pop/i.test(settings.tipAnimation)) { 15269 15270 $timer.outerWidth(0); 15271 15272 if (settings.timer > 0) { 15273 15274 settings.$next_tip.show(); 15275 $timer.animate({ 15276 width: $('.joyride-timer-indicator-wrap', settings.$next_tip).outerWidth() 15277 }, settings.timer); 15278 15279 } else { 15280 15281 settings.$next_tip.show(); 15282 15283 } 15284 15285 15286 } else if (/fade/i.test(settings.tipAnimation)) { 15287 15288 $timer.outerWidth(0); 15289 15290 if (settings.timer > 0) { 15291 15292 settings.$next_tip.fadeIn(settings.tipAnimationFadeSpeed); 15293 15294 settings.$next_tip.show(); 15295 $timer.animate({ 15296 width: $('.joyride-timer-indicator-wrap', settings.$next_tip).outerWidth() 15297 }, settings.timer); 15298 15299 } else { 15300 15301 settings.$next_tip.fadeIn(settings.tipAnimationFadeSpeed); 15302 15303 } 15304 } 15305 15306 settings.$current_tip = settings.$next_tip; 15307 15308 // skip non-existent targets 15309 } else if (settings.$li && settings.$target.length < 1) { 15310 15311 methods.show(); 15312 15313 } else { 15314 15315 methods.end(); 15316 15317 } 15318 } else { 15319 15320 settings.paused = true; 15321 15322 } 15323 15324 }, 15325 15326 // detect phones with media queries if supported. 15327 is_phone : function () { 15328 if (Modernizr) { 15329 return Modernizr.mq('only screen and (max-width: 767px)'); 15330 } 15331 15332 return (settings.$window.width() < 767) ? true : false; 15333 }, 15334 15335 hide : function () { 15336 settings.postStepCallback(settings.$li.index(), settings.$current_tip); 15337 $('.joyride-modal-bg').hide(); 15338 settings.$current_tip.hide(); 15339 }, 15340 15341 set_li : function (init) { 15342 if (init) { 15343 settings.$li = settings.$tip_content.eq(settings.startOffset); 15344 methods.set_next_tip(); 15345 settings.$current_tip = settings.$next_tip; 15346 } else { 15347 settings.$li = settings.$li.next(); 15348 methods.set_next_tip(); 15349 } 15350 15351 methods.set_target(); 15352 }, 15353 15354 set_next_tip : function () { 15355 settings.$next_tip = $('.joyride-tip-guide[data-index=' + settings.$li.index() + ']'); 15356 }, 15357 15358 set_target : function () { 15359 var cl = settings.$li.attr('data-class'),
15360 id = settings.$li.attr('data-id'), 15361 $sel = function () { 15362 if (id) { 15363 return $(settings.document.getElementById(id)); 15364 } else if (cl) { 15365 return $('.' + cl).first(); 15366 } else { 15367 return $('body'); 15368 } 15369 }; 15370 15371 settings.$target = $sel(); 15372 }, 15373 15374 scroll_to : function () { 15375 var window_half, tipOffset; 15376 15377 window_half = settings.$window.height() / 2; 15378 tipOffset = Math.ceil(settings.$target.offset().top - window_half + settings.$next_tip.outerHeight()); 15379 15380 $("html, body").stop().animate({ 15381 scrollTop: tipOffset 15382 }, settings.scrollSpeed); 15383 }, 15384 15385 paused : function () { 15386 if (($.inArray((settings.$li.index() + 1), settings.pauseAfter) === -1)) { 15387 return true; 15388 } 15389 15390 return false; 15391 }, 15392 15393 destroy : function () { 15394 settings.$document.off('.joyride'); 15395 $(window).off('.joyride'); 15396 $('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride'); 15397 $('.joyride-tip-guide, .joyride-modal-bg').remove(); 15398 clearTimeout(settings.automate); 15399 settings = {}; 15400 }, 15401 15402 restart : function () { 15403 methods.hide(); 15404 settings.$li = undefined; 15405 methods.show('init'); 15406 }, 15407 15408 pos_default : function (init) { 15409 var half_fold = Math.ceil(settings.$window.height() / 2), 15410 tip_position = settings.$next_tip.offset(), 15411 $nub = $('.joyride-nub', settings.$next_tip), 15412 nub_height = Math.ceil($nub.outerHeight() / 2), 15413 toggle = init || false; 15414 15415 // tip must not be "display: none" to calculate position 15416 if (toggle) { 15417 settings.$next_tip.css('visibility', 'hidden'); 15418 settings.$next_tip.show(); 15419 } 15420 15421 if (!/body/i.test(settings.$target.selector)) { 15422 15423 if (methods.bottom()) { 15424 settings.$next_tip.css({ 15425 top: (settings.$target.offset().top + nub_height + settings.$target.outerHeight()), 15426 left: settings.$target.offset().left}); 15427 15428 methods.nub_position($nub, settings.tipSettings.nubPosition, 'top'); 15429 15430 } else if (methods.top()) { 15431 15432 settings.$next_tip.css({ 15433 top: (settings.$target.offset().top - settings.$next_tip.outerHeight() - nub_height), 15434 left: settings.$target.offset().left}); 15435 15436 methods.nub_position($nub, settings.tipSettings.nubPosition, 'bottom'); 15437 15438 } else if (methods.right()) { 15439 15440 settings.$next_tip.css({ 15441 top: settings.$target.offset().top, 15442 left: (settings.$target.outerWidth() + settings.$target.offset().left)}); 15443 15444 methods.nub_position($nub, settings.tipSettings.nubPosition, 'left'); 15445 15446 } else if (methods.left()) { 15447 15448 settings.$next_tip.css({ 15449 top: settings.$target.offset().top, 15450 left: (settings.$target.offset().left - settings.$next_tip.outerWidth() - nub_height)}); 15451 15452 methods.nub_position($nub, settings.tipSettings.nubPosition, 'right'); 15453 15454 } 15455 15456 if (!methods.visible(methods.corners(settings.$next_tip)) && settings.attempts < settings.tipSettings.tipLocationPattern.length) { 15457 15458 $nub.removeClass('bottom') 15459 .removeClass('top') 15460 .removeClass('right') 15461 .removeClass('left'); 15462 15463 settings.tipSettings.tipLocation = settings.tipSettings.tipLocationPattern[settings.attempts]; 15464 15465 settings.attempts++; 15466 15467 methods.pos_default(true); 15468 15469 } 15470 15471 } else if (settings.$li.length) { 15472 15473 methods.pos_modal($nub); 15474 15475 } 15476 15477 if (toggle) { 15478 settings.$next_tip.hide(); 15479 settings.$next_tip.css('visibility', 'visible'); 15480 } 15481 15482 }, 15483 15484 pos_phone : function (init) { 15485 var tip_height = settings.$next_tip.outerHeight(), 15486 tip_offset = settings.$next_tip.offset(), 15487 target_height = settings.$target.outerHeight(), 15488 $nub = $('.joyride-nub', settings.$next_tip),
15489 nub_height = Math.ceil($nub.outerHeight() / 2), 15490 toggle = init || false; 15491 15492 $nub.removeClass('bottom') 15493 .removeClass('top') 15494 .removeClass('right') 15495 .removeClass('left'); 15496 15497 if (toggle) { 15498 settings.$next_tip.css('visibility', 'hidden'); 15499 settings.$next_tip.show(); 15500 } 15501 15502 if (!/body/i.test(settings.$target.selector)) { 15503 15504 if (methods.top()) { 15505 15506 settings.$next_tip.offset({top: settings.$target.offset().top - tip_height - nub_height}); 15507 $nub.addClass('bottom'); 15508 15509 } else { 15510 15511 settings.$next_tip.offset({top: settings.$target.offset().top + target_height + nub_height}); 15512 $nub.addClass('top'); 15513 15514 } 15515 15516 } else if (settings.$li.length) { 15517 15518 methods.pos_modal($nub); 15519 15520 } 15521 15522 if (toggle) { 15523 settings.$next_tip.hide(); 15524 settings.$next_tip.css('visibility', 'visible'); 15525 } 15526 }, 15527 15528 pos_modal : function ($nub) { 15529 methods.center(); 15530 $nub.hide(); 15531 15532 if ($('.joyride-modal-bg').length < 1) { 15533 $('body').append('<div class="joyride-modal-bg">').show(); 15534 } 15535 15536 if (/pop/i.test(settings.tipAnimation)) { 15537 $('.joyride-modal-bg').show(); 15538 } else { 15539 $('.joyride-modal-bg').fadeIn(settings.tipAnimationFadeSpeed); 15540 } 15541 }, 15542 15543 center : function () { 15544 var $w = settings.$window; 15545 15546 settings.$next_tip.css({ 15547 top : ((($w.height() - settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()), 15548 left : ((($w.width() - settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft()) 15549 }); 15550 15551 return true; 15552 }, 15553 15554 bottom : function () { 15555 return /bottom/i.test(settings.tipSettings.tipLocation); 15556 }, 15557 15558 top : function () { 15559 return /top/i.test(settings.tipSettings.tipLocation); 15560 }, 15561 15562 right : function () { 15563 return /right/i.test(settings.tipSettings.tipLocation); 15564 }, 15565 15566 left : function () { 15567 return /left/i.test(settings.tipSettings.tipLocation); 15568 }, 15569 15570 corners : function (el) { 15571 var w = settings.$window, 15572 right = w.width() + w.scrollLeft(), 15573 bottom = w.width() + w.scrollTop(); 15574 15575 return [ 15576 el.offset().top <= w.scrollTop(), 15577 right <= el.offset().left + el.outerWidth(), 15578 bottom <= el.offset().top + el.outerHeight(), 15579 w.scrollLeft() >= el.offset().left 15580 ]; 15581 }, 15582 15583 visible : function (hidden_corners) { 15584 var i = hidden_corners.length; 15585 15586 while (i--) { 15587 if (hidden_corners[i]) return false; 15588 } 15589 15590 return true; 15591 }, 15592 15593 nub_position : function (nub, pos, def) { 15594 if (pos === 'auto') { 15595 nub.addClass(def); 15596 } else { 15597 nub.addClass(pos); 15598 } 15599 }, 15600 15601 startTimer : function () { 15602 if (settings.$li.length) { 15603 settings.automate = setTimeout(function () { 15604 methods.hide(); 15605 methods.show(); 15606 methods.startTimer(); 15607 }, settings.timer); 15608 } else { 15609 clearTimeout(settings.automate); 15610 } 15611 }, 15612 15613 end : function () { 15614 if (settings.cookieMonster) { 15615 $.cookie(settings.cookieName, 'ridden', { expires: 365, domain: settings.cookieDomain }); 15616 } 15617 15618 if (settings.timer > 0) { 15619 clearTimeout(settings.automate); 15620 } 15621 15622 $('.joyride-modal-bg').hide(); 15623 settings.$current_tip.hide(); 15624 settings.postStepCallback(settings.$li.index(), settings.$current_tip); 15625 settings.postRideCallback(settings.$li.index(), settings.$current_tip); 15626 }, 15627 15628 jquery_check : function () { 15629 // define on() and off() for older jQuery 15630 if (!$.isFunction($.fn.on)) { 15631 15632 $.fn.on = function (types, sel, fn) { 15633 15634 return this.delegate(sel, types, fn); 15635 15636 }; 15637 15638 $.fn.off = function (types, sel, fn) { 15639 15640 return this.undelegate(sel, types, fn); 15641 15642 }; 15643 15644 return false;
15645 } 15646 15647 return true; 15648 }, 15649 15650 outerHTML : function (el) { 15651 // support FireFox < 11 15652 return el.outerHTML || new XMLSerializer().serializeToString(el); 15653 }, 15654 15655 version : function () { 15656 return settings.version; 15657 } 15658 15659 }; 15660 15661 $.fn.joyride = function (method) { 15662 if (methods[method]) { 15663 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 15664 } else if (typeof method === 'object' || !method) { 15665 return methods.init.apply(this, arguments); 15666 } else { 15667 $.error('Method ' + method + ' does not exist on jQuery.joyride'); 15668 } 15669 }; 15670 15671}(jQuery, this)); 15672/* 15673 * jQuery Foundation Clearing 1.2.1 15674 * http://foundation.zurb.com 15675 * Copyright 2012, ZURB 15676 * Free to use under the MIT license. 15677 * http://www.opensource.org/licenses/mit-license.php 15678*/ 15679 15680/*jslint unparam: true, browser: true, indent: 2 */ 15681 15682 15683;(function ($, window, document, undefined) { 15684 'use strict'; 15685 15686 var defaults = { 15687 templates : { 15688 viewing : '<a href="#" class="clearing-close">×</a>' + 15689 '<div class="visible-img" style="display: none"><img src="#">' + 15690 '<p class="clearing-caption"></p><a href="#" class="clearing-main-left"></a>' + 15691 '<a href="#" class="clearing-main-right"></a></div>' 15692 }, 15693 15694 // comma delimited list of selectors that, on click, will close clearing, 15695 // add 'div.clearing-blackout, div.visible-img' to close on background click 15696 close_selectors : 'a.clearing-close', 15697 15698 // event initializers and locks 15699 initialized : false, 15700 locked : false 15701 }, 15702 15703 cl = { 15704 init : function (options, extendMethods) { 15705 return this.find('ul[data-clearing]').each(function () { 15706 var doc = $(document), 15707 $el = $(this), 15708 options = options || {}, 15709 extendMethods = extendMethods || {}, 15710 settings = $el.data('fndtn.clearing.settings'); 15711 15712 if (!settings) { 15713 options.$parent = $el.parent(); 15714 15715 $el.data('fndtn.clearing.settings', $.extend({}, defaults, options)); 15716 15717 cl.assemble($el.find('li')); 15718 15719 if (!defaults.initialized) { 15720 cl.events($el); 15721 if (Modernizr.touch) cl.swipe_events(); 15722 } 15723 15724 } 15725 }); 15726 }, 15727 15728 events : function (el) { 15729 var settings = el.data('fndtn.clearing.settings'); 15730 15731 $(document) 15732 .on('click.fndtn.clearing', 'ul[data-clearing] li', function (e, current, target) { 15733 var current = current || $(this), 15734 target = target || current, 15735 settings = current.parent().data('fndtn.clearing.settings'); 15736 15737 e.preventDefault(); 15738 15739 if (!settings) { 15740 current.parent().foundationClearing(); 15741 } 15742 15743 // set current and target to the clicked li if not otherwise defined. 15744 cl.open($(e.target), current, target); 15745 cl.update_paddles(target); 15746 }) 15747 15748 .on('click.fndtn.clearing', '.clearing-main-right', function (e) { cl.nav(e, 'next') }) 15749 .on('click.fndtn.clearing', '.clearing-main-left', function (e) { cl.nav(e, 'prev') }) 15750 .on('click.fndtn.clearing', settings.close_selectors, this.close) 15751 .on('keydown.fndtn.clearing', this.keydown); 15752 15753 $(window).on('resize.fndtn.clearing', this.resize); 15754 15755 defaults.initialized = true; 15756 }, 15757 15758 swipe_events : function () { 15759 $(document) 15760 .bind('swipeleft', 'ul[data-clearing]', function (e) { cl.nav(e, 'next') }) 15761 .bind('swiperight', 'ul[data-clearing]', function (e) { cl.nav(e, 'prev') }) 15762 .bind('movestart', 'ul[data-clearing]', function (e) { 15763 if ((e.distX > e.distY && e.distX < -e.distY) || 15764 (e.distX < e.distY && e.distX > -e.distY)) { 15765 e.preventDefault(); 15766 } 15767 }); 15768 }, 15769 15770 assemble : function ($li) { 15771 var $el = $li.parent(), 15772 settings = $el.data('fndtn.clearing.settings'), 15773 grid = $el.detach(), 15774 data = { 15775 grid: '<div class="carousel">' + this.outerHTML(grid[0]) + '</div>', 15776 viewing: settings.templates.viewing 15777 }, 15778 wrapper = '<div class="clearing-assembled"><div>' + data.viewing + data.grid + '</div></div>'; 15779 15780 return settings.$parent.append(wrapper); 15781 }, 15782 15783 open : function ($image, current, target) { 15784 var root = target.closest('.clearing-assembled'), 15785 container = root.find('div:first'), 15786 visible_image = container.find('.visible-img'), 15787 image = visible_image.find('img').not($image); 15788 15789 if (!cl.locked()) { 15790 15791 // set the image to the selected thumbnail 15792 image.attr('src', this.load($image)); 15793 15794 image.loaded(function () { 15795 // toggle the gallery if not visible 15796 root.addClass('clearing-blackout'); 15797 container.addClass('clearing-container'); 15798 this.caption(visible_image.find('.clearing-caption'), $image); 15799 visible_image.show(); 15800 this.fix_height(target); 15801 this.center(image); 15802 15803 // shift the thumbnails if necessary 15804 this.shift(current, target, function () { 15805 target.siblings().removeClass('visible'); 15806 target.addClass('visible'); 15807 }); 15808 }.bind(this)); 15809 } 15810 }, 15811 15812 close : function (e) { 15813 e.preventDefault(); 15814 15815 var root = (function (target) { 15816 if (/blackout/.test(target.selector)) { 15817 return target; 15818 } else { 15819 return target.closest('.clearing-blackout'); 15820 } 15821 }($(this))), container, visible_image; 15822 15823 if (this === e.target && root) { 15824 container = root.find('div:first'), 15825 visible_image = container.find('.visible-img'); 15826 15827 defaults.prev_index = 0; 15828 15829 root.find('ul[data-clearing]').attr('style', '') 15830 root.removeClass('clearing-blackout'); 15831 container.removeClass('clearing-container'); 15832 visible_image.hide(); 15833 } 15834 15835 return false;
15836 }, 15837 15838 keydown : function (e) { 15839 var clearing = $('.clearing-blackout').find('ul[data-clearing]'); 15840 15841 if (e.which === 39) cl.go(clearing, 'next'); 15842 if (e.which === 37) cl.go(clearing, 'prev'); 15843 if (e.which === 27) $('a.clearing-close').trigger('click'); 15844 }, 15845 15846 nav : function (e, direction) { 15847 var clearing = $('.clearing-blackout').find('ul[data-clearing]'); 15848 15849 e.preventDefault(); 15850 this.go(clearing, direction); 15851 }, 15852 15853 resize : function () { 15854 var image = $('.clearing-blackout .visible-img').find('img'); 15855 15856 if (image.length > 0) { 15857 cl.center(image); 15858 } 15859 }, 15860 15861 fix_height : function (target) { 15862 var lis = target.siblings(); 15863 15864 lis.each(function () { 15865 var li = $(this), 15866 image = li.find('img'); 15867 15868 if (li.height() > image.outerHeight()) { 15869 li.addClass('fix-height'); 15870 } 15871 }) 15872 .closest('ul').width(lis.length * 100 + '%'); 15873 }, 15874 15875 update_paddles : function (target) { 15876 var visible_image = target.closest('.carousel').siblings('.visible-img'); 15877 15878 if (target.next().length > 0) { 15879 visible_image.find('.clearing-main-right').removeClass('disabled'); 15880 } else { 15881 visible_image.find('.clearing-main-right').addClass('disabled'); 15882 } 15883 15884 if (target.prev().length > 0) { 15885 visible_image.find('.clearing-main-left').removeClass('disabled'); 15886 } else { 15887 visible_image.find('.clearing-main-left').addClass('disabled'); 15888 } 15889 }, 15890 15891 load : function ($image) { 15892 var href = $image.parent().attr('href'); 15893 15894 this.preload($image); 15895 15896 if (href) return href; 15897 return $image.attr('src'); 15898 }, 15899 15900 preload : function ($image) { 15901 this.img($image.closest('li').next()); 15902 this.img($image.closest('li').prev()); 15903 }, 15904 15905 img : function (img) { 15906 if (img.length > 0) { 15907 var new_img = new Image(), 15908 new_a = img.find('a'); 15909 15910 if (new_a.length > 0) { 15911 new_img.src = new_a.attr('href'); 15912 } else { 15913 new_img.src = img.find('img').attr('src'); 15914 } 15915 } 15916 }, 15917 15918 caption : function (container, $image) { 15919 var caption = $image.data('caption'); 15920 15921 if (caption) { 15922 container.text(caption).show(); 15923 } else { 15924 container.text('').hide(); 15925 } 15926 }, 15927 15928 go : function ($ul, direction) { 15929 var current = $ul.find('.visible'), 15930 target = current[direction](); 15931 15932 if (target.length > 0) { 15933 target.find('img').trigger('click', [current, target]); 15934 } 15935 }, 15936 15937 shift : function (current, target, callback) { 15938 var clearing = target.parent(), 15939 old_index = defaults.prev_index, 15940 direction = this.direction(clearing, current, target), 15941 left = parseInt(clearing.css('left'), 10), 15942 width = target.outerWidth(), 15943 skip_shift; 15944 15945 // we use jQuery animate instead of CSS transitions because we 15946 // need a callback to unlock the next animation 15947 if (target.index() !== old_index && !/skip/.test(direction)){ 15948 if (/left/.test(direction)) { 15949 this.lock(); 15950 clearing.animate({left : left + width}, 300, this.unlock); 15951 } else if (/right/.test(direction)) { 15952 this.lock(); 15953 clearing.animate({left : left - width}, 300, this.unlock); 15954 } 15955 } else if (/skip/.test(direction)) { 15956 15957 // the target image is not adjacent to the current image, so 15958 // do we scroll right or not 15959 skip_shift = target.index() - defaults.up_count; 15960 this.lock(); 15961 15962 if (skip_shift > 0) { 15963 clearing.animate({left : -(skip_shift * width)}, 300, this.unlock); 15964 } else { 15965 clearing.animate({left : 0}, 300, this.unlock); 15966 } 15967 } 15968 15969 callback(); 15970 }, 15971 15972 lock : function () { 15973 defaults.locked = true; 15974 }, 15975 15976 unlock : function () { 15977 defaults.locked = false;
15978 }, 15979 15980 locked : function () { 15981 return defaults.locked; 15982 }, 15983 15984 direction : function ($el, current, target) { 15985 var lis = $el.find('li'), 15986 li_width = lis.outerWidth() + (lis.outerWidth() / 4), 15987 up_count = Math.floor($('.clearing-container').outerWidth() / li_width) - 1, 15988 target_index = lis.index(target), 15989 response; 15990 15991 defaults.up_count = up_count; 15992 15993 if (this.adjacent(defaults.prev_index, target_index)) { 15994 if ((target_index > up_count) && target_index > defaults.prev_index) { 15995 response = 'right'; 15996 } else if ((target_index > up_count - 1) && target_index <= defaults.prev_index) { 15997 response = 'left'; 15998 } else { 15999 response = false; 16000 } 16001 } else { 16002 response = 'skip'; 16003 } 16004 16005 defaults.prev_index = target_index; 16006 16007 return response; 16008 }, 16009 16010 adjacent : function (current_index, target_index) { 16011 for (var i = target_index + 1; i >= target_index - 1; i--) { 16012 if (i === current_index) return true; 16013 } 16014 return false; 16015 }, 16016 16017 center : function (target) { 16018 target.css({ 16019 marginLeft : -(target.outerWidth() / 2), 16020 marginTop : -(target.outerHeight() / 2) 16021 }); 16022 }, 16023 16024 outerHTML : function (el) { 16025 // support FireFox < 11 16026 return el.outerHTML || new XMLSerializer().serializeToString(el); 16027 } 16028 16029 }; 16030 16031 $.fn.foundationClearing = function (method) { 16032 if (cl[method]) { 16033 return cl[method].apply(this, Array.prototype.slice.call(arguments, 1)); 16034 } else if (typeof method === 'object' || !method) { 16035 return cl.init.apply(this, arguments); 16036 } else { 16037 $.error('Method ' + method + ' does not exist on jQuery.foundationClearing'); 16038 } 16039 }; 16040 16041 // jquery.imageready.js 16042 // @weblinc, @jsantell, (c) 2012 16043 16044 (function( $ ) { 16045 $.fn.loaded = function ( callback, userSettings ) { 16046 var 16047 options = $.extend( {}, $.fn.loaded.defaults, userSettings ), 16048 $images = this.find( 'img' ).add( this.filter( 'img' ) ), 16049 unloadedImages = $images.length; 16050 16051 function loaded () { 16052 unloadedImages -= 1; 16053 !unloadedImages && callback(); 16054 } 16055 16056 function bindLoad () { 16057 this.one( 'load', loaded ); 16058 if ( $.browser.msie ) { 16059 var 16060 src = this.attr( 'src' ), 16061 param = src.match( /\?/ ) ? '&' : '?'; 16062 param += options.cachePrefix + '=' + ( new Date() ).getTime(); 16063 this.attr( 'src', src + param ); 16064 } 16065 } 16066 16067 return $images.each(function () { 16068 var $this = $( this ); 16069 if ( !$this.attr( 'src' ) ) { 16070 loaded(); 16071 return; 16072 } 16073 this.complete || this.readyState === 4 ? 16074 loaded() : 16075 bindLoad.call( $this ); 16076 }); 16077 }; 16078 16079 $.fn.loaded.defaults = { 16080 cachePrefix: 'random' 16081 }; 16082 16083 }(jQuery)); 16084 16085}(jQuery, this, this.document)); 16086/* 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104*/ 16105; 16106/** 16107 * Overscroll v1.7.1 16108 * A jQuery Plugin that emulates the iPhone scrolling experience in a browser. 16109 * http://azoffdesign.com/overscroll 16110 * 16111 * Intended for use with the latest jQuery 16112 * http://code.jquery.com/jquery-latest.js 16113 * 16114 * Copyright 2013, Jonathan Azoff 16115 * Licensed under the MIT license. 16116 * https://github.com/azoff/overscroll/blob/master/mit.license 16117 * 16118 * For API documentation, see the README file 16119 * http://azof.fr/pYCzuM 16120 * 16121 * Date: Monday, February 4th 2013 16122 */ 16123 16124(function(global, dom, browser, math, wait, cancel, namespace, $, none){ 16125 16126 // We want to run this plug-in in strict-mode 16127 // so that we may benefit from its optimizations 16128 'use strict'; 16129 16130 // The key used to bind-instance specific data to an object 16131 var datakey = 'overscroll'; 16132 16133 // runs feature detection for overscroll 16134 var compat = { 16135 animate: (function(){ 16136 var fn = global.requestAnimationFrame || 16137 global.webkitRequestAnimationFrame || 16138 global.mozRequestAnimationFrame || 16139 global.oRequestAnimationFrame || 16140 global.msRequestAnimationFrame || 16141 function(callback) { wait(callback, 1000/60); }; 16142 return function(callback) { 16143 fn.call(global, callback); 16144 }; 16145 })(), 16146 overflowScrolling: (function(){ 16147 var style = ''; 16148 var div = dom.createElement('div'); 16149 var prefixes = ['webkit', 'moz', 'o', 'ms']; 16150 dom.body.appendChild(div); 16151 $.each(prefixes, function(i, prefix){ 16152 div.style[prefix + 'OverflowScrolling'] = 'touch'; 16153 }); 16154 div.style.overflowScrolling = 'touch'; 16155 var computedStyle = global.getComputedStyle(div); 16156 if (!!computedStyle.overflowScrolling) { 16157 style = 'overflow-scrolling';
16158 } else { 16159 $.each(prefixes, function(i, prefix){ 16160 if (!!computedStyle[prefix + 'OverflowScrolling']) { 16161 style = '-' + prefix + '-overflow-scrolling'; 16162 } 16163 return !style; 16164 }); 16165 } 16166 div.parentNode.removeChild(div); 16167 return style; 16168 })(), 16169 cursor: (function() { 16170 var div = dom.createElement('div'); 16171 var prefixes = ['webkit', 'moz']; 16172 var gmail = 'https://mail.google.com/mail/images/2/'; 16173 var style = { 16174 grab: 'url('+gmail+'openhand.cur), move', 16175 grabbing: 'url('+gmail+'closedhand.cur), move' 16176 }; 16177 dom.body.appendChild(div); 16178 $.each(prefixes, function(i, prefix){ 16179 var found, cursor = '-' + prefix + '-grab'; 16180 div.style.cursor = cursor; 16181 var computedStyle = global.getComputedStyle(div); 16182 found = computedStyle.cursor === cursor; 16183 if (found) { 16184 style = { 16185 grab: '-' + prefix + '-grab', 16186 grabbing: '-' + prefix + '-grabbing' 16187 }; 16188 } 16189 return !found; 16190 }); 16191 div.parentNode.removeChild(div); 16192 return style; 16193 })() 16194 }; 16195 16196 // These are all the events that could possibly 16197 // be used by the plug-in 16198 var events = { 16199 drag: 'mousemove touchmove', 16200 end: 'mouseup mouseleave click touchend touchcancel', 16201 hover: 'mouseenter mouseleave', 16202 ignored: 'select dragstart drag', 16203 scroll: 'scroll', 16204 start: 'mousedown touchstart', 16205 wheel: 'mousewheel DOMMouseScroll' 16206 }; 16207 16208 // These settings are used to tweak drift settings 16209 // for the plug-in 16210 var settings = { 16211 captureThreshold: 3, 16212 driftDecay: 1.1, 16213 driftSequences: 22, 16214 driftTimeout: 100, 16215 scrollDelta: 15, 16216 thumbOpacity: 0.7, 16217 thumbThickness: 6, 16218 thumbTimeout: 400, 16219 wheelDelta: 20, 16220 wheelTicks: 120 16221 }; 16222 16223 // These defaults are used to complement any options 16224 // passed into the plug-in entry point 16225 var defaults = { 16226 cancelOn: 'select,input,textarea', 16227 direction: 'multi', 16228 dragHold: false, 16229 hoverThumbs: false, 16230 scrollDelta: settings.scrollDelta, 16231 showThumbs: true, 16232 persistThumbs: false, 16233 captureWheel: true, 16234 wheelDelta: settings.wheelDelta, 16235 wheelDirection: 'multi', 16236 zIndex: 999 16237 }; 16238 16239 // Triggers a DOM event on the overscrolled element. 16240 // All events are namespaced under the overscroll name 16241 function triggerEvent(event, target) { 16242 target.trigger('overscroll:' + event); 16243 } 16244 16245 // Utility function to return a timestamp 16246 function time() { 16247 return (new Date()).getTime(); 16248 } 16249 16250 // Captures the position from an event, modifies the properties 16251 // of the second argument to persist the position, and then 16252 // returns the modified object 16253 function capturePosition(event, position, index) { 16254 position.x = event.pageX; 16255 position.y = event.pageY; 16256 position.time = time(); 16257 position.index = index; 16258 return position; 16259 } 16260 16261 // Used to move the thumbs around an overscrolled element 16262 function moveThumbs(thumbs, sizing, left, top) { 16263 16264 var ml, mt; 16265 16266 if (thumbs && thumbs.added) { 16267 if (thumbs.horizontal) { 16268 ml = left * (1 + sizing.container.width / sizing.container.scrollWidth); 16269 mt = top + sizing.thumbs.horizontal.top; 16270 thumbs.horizontal.css('margin', mt + 'px 0 0 ' + ml + 'px'); 16271 } 16272 if (thumbs.vertical) { 16273 ml = left + sizing.thumbs.vertical.left; 16274 mt = top * (1 + sizing.container.height / sizing.container.scrollHeight); 16275 thumbs.vertical.css('margin', mt + 'px 0 0 ' + ml + 'px'); 16276 } 16277 } 16278 16279 } 16280 16281 // Used to toggle the thumbs on and off 16282 // of an overscrolled element 16283 function toggleThumbs(thumbs, options, dragging) { 16284 if (thumbs && thumbs.added && !options.persistThumbs) { 16285 if (dragging) { 16286 if (thumbs.vertical) { 16287 thumbs.vertical.stop(true, true).fadeTo('fast', settings.thumbOpacity); 16288 } 16289 if (thumbs.horizontal) { 16290 thumbs.horizontal.stop(true, true).fadeTo('fast', settings.thumbOpacity); 16291 } 16292 } else { 16293 if (thumbs.vertical) { 16294 thumbs.vertical.fadeTo('fast', 0); 16295 } 16296 if (thumbs.horizontal) { 16297 thumbs.horizontal.fadeTo('fast', 0); 16298 } 16299 } 16300 } 16301 } 16302 16303 // Defers click event listeners to after a mouseup event. 16304 // Used to avoid unintentional clicks 16305 function deferClick(target) { 16306 var clicks, key = 'events'; 16307 var events = $._data ? $._data(target[0], key) : target.data(key); 16308 if (events && events.click) { 16309 clicks = events.click.slice(); 16310 target.off('click').one('click', function(){ 16311 $.each(clicks, function(i, click){ 16312 target.click(click); 16313 }); return false;
16314 }); 16315 } 16316 } 16317 16318 // Toggles thumbs on hover. This event is only triggered 16319 // if the hoverThumbs option is set 16320 function hover(event) { 16321 var data = event.data, 16322 thumbs = data.thumbs, 16323 options = data.options, 16324 dragging = event.type === 'mouseenter'; 16325 toggleThumbs(thumbs, options, dragging); 16326 } 16327 16328 // This function is only ever used when the overscrolled element 16329 // scrolled outside of the scope of this plugin. 16330 function scroll(event) { 16331 var data = event.data; 16332 if (!data.flags.dragged) { 16333 moveThumbs(data.thumbs, data.sizing, this.scrollLeft, this.scrollTop); 16334 } 16335 } 16336 16337 // handles mouse wheel scroll events 16338 function wheel(event) { 16339 16340 // prevent any default wheel behavior 16341 event.preventDefault(); 16342 16343 var data = event.data, 16344 options = data.options, 16345 sizing = data.sizing, 16346 thumbs = data.thumbs, 16347 dwheel = data.wheel, 16348 flags = data.flags, 16349 original = event.originalEvent, 16350 delta = 0, deltaX = 0, deltaY = 0; 16351 16352 // stop any drifts 16353 flags.drifting = false; 16354 16355 // normalize the wheel ticks 16356 if (original.detail) { 16357 delta = -original.detail; 16358 if (original.detailX) { 16359 deltaX = -original.detailX; 16360 } 16361 if (original.detailY) { 16362 deltaY = -original.detailY; 16363 } 16364 } else if (original.wheelDelta) { 16365 delta = original.wheelDelta / settings.wheelTicks; 16366 if (original.wheelDeltaX) { 16367 deltaX = original.wheelDeltaX / settings.wheelTicks; 16368 } 16369 if (original.wheelDeltaY) { 16370 deltaY = original.wheelDeltaY / settings.wheelTicks; 16371 } 16372 } 16373 16374 // apply a pixel delta to each tick 16375 delta *= options.wheelDelta; 16376 deltaX *= options.wheelDelta; 16377 deltaY *= options.wheelDelta; 16378 16379 // initialize flags if this is the first tick 16380 if (!dwheel) { 16381 data.target.data(datakey).dragging = flags.dragging = true; 16382 data.wheel = dwheel = { timeout: null }; 16383 toggleThumbs(thumbs, options, true); 16384 } 16385 16386 // actually modify scroll offsets 16387 if (options.wheelDirection === 'vertical'){ 16388 this.scrollTop -= delta; 16389 } else if ( options.wheelDirection === 'horizontal') { 16390 this.scrollLeft -= delta; 16391 } else { 16392 this.scrollLeft -= deltaX; 16393 this.scrollTop -= deltaY || delta; 16394 } 16395 16396 if (dwheel.timeout) { cancel(dwheel.timeout); } 16397 16398 moveThumbs(thumbs, sizing, this.scrollLeft, this.scrollTop); 16399 16400 dwheel.timeout = wait(function() { 16401 data.target.data(datakey).dragging = flags.dragging = false; 16402 toggleThumbs(thumbs, options, data.wheel = null); 16403 }, settings.thumbTimeout); 16404 16405 } 16406 16407 // updates the current scroll offset during a mouse move 16408 function drag(event) { 16409 16410 event.preventDefault(); 16411 16412 var data = event.data, 16413 touches = event.originalEvent.touches, 16414 options = data.options, 16415 sizing = data.sizing, 16416 thumbs = data.thumbs, 16417 position = data.position, 16418 flags = data.flags, 16419 target = data.target.get(0); 16420 16421 16422 // correct page coordinates for touch devices 16423 if (touches && touches.length) { 16424 event = touches[0]; 16425 } 16426 16427 if (!flags.dragged) { 16428 toggleThumbs(thumbs, options, true); 16429 } 16430 16431 flags.dragged = true; 16432 16433 if (options.direction !== 'vertical') { 16434 target.scrollLeft -= (event.pageX - position.x); 16435 } 16436 16437 if (data.options.direction !== 'horizontal') { 16438 target.scrollTop -= (event.pageY - position.y); 16439 } 16440 16441 capturePosition(event, data.position); 16442 16443 if (--data.capture.index <= 0) { 16444 data.target.data(datakey).dragging = flags.dragging = true; 16445 capturePosition(event, data.capture, settings.captureThreshold); 16446 } 16447 16448 moveThumbs(thumbs, sizing, target.scrollLeft, target.scrollTop); 16449 16450 } 16451 16452 // sends the overscrolled element into a drift 16453 function drift(target, event, callback) { 16454 16455 var data = event.data, dx, dy, xMod, yMod, 16456 capture = data.capture, 16457 options = data.options, 16458 sizing = data.sizing, 16459 thumbs = data.thumbs, 16460 elapsed = time() - capture.time, 16461 scrollLeft = target.scrollLeft, 16462 scrollTop = target.scrollTop, 16463 decay = settings.driftDecay; 16464 16465 // only drift if enough time has passed since 16466 // the last capture event 16467 if (elapsed > settings.driftTimeout) { 16468 callback(data); return; 16469 } 16470 16471 // determine offset between last capture and current time 16472 dx = options.scrollDelta * (event.pageX - capture.x); 16473 dy = options.scrollDelta * (event.pageY - capture.y); 16474 16475 // update target scroll offsets 16476 if (options.direction !== 'vertical') { 16477 scrollLeft -= dx; 16478 } if (options.direction !== 'horizontal') { 16479 scrollTop -= dy; 16480 } 16481 16482 // split the distance to travel into a set of sequences 16483 xMod = dx / settings.driftSequences;
16484 yMod = dy / settings.driftSequences; 16485 16486 triggerEvent('driftstart', data.target); 16487 16488 data.drifting = true; 16489 16490 // animate the drift sequence 16491 compat.animate(function render() { 16492 if (data.drifting) { 16493 var min = 1, max = -1; 16494 data.drifting = false; 16495 if (yMod > min && target.scrollTop > scrollTop || yMod < max && target.scrollTop < scrollTop) { 16496 data.drifting = true; 16497 target.scrollTop -= yMod; 16498 yMod /= decay; 16499 } 16500 if (xMod > min && target.scrollLeft > scrollLeft || xMod < max && target.scrollLeft < scrollLeft) { 16501 data.drifting = true; 16502 target.scrollLeft -= xMod; 16503 xMod /= decay; 16504 } 16505 moveThumbs(thumbs, sizing, target.scrollLeft, target.scrollTop); 16506 compat.animate(render); 16507 } else { 16508 triggerEvent('driftend', data.target); 16509 callback(data); 16510 } 16511 }); 16512 16513 } 16514 16515 // starts the drag operation and binds the mouse move handler 16516 function start(event) { 16517 16518 var data = event.data, 16519 touches = event.originalEvent.touches, 16520 target = data.target, 16521 dstart = data.start = $(event.target), 16522 flags = data.flags; 16523 16524 // stop any drifts 16525 flags.drifting = false; 16526 16527 // only start drag if the user has not explictly banned it. 16528 if (dstart.size() && !dstart.is(data.options.cancelOn)) { 16529 16530 // without this the simple "click" event won't be recognized on touch clients 16531 if (!touches) { event.preventDefault(); } 16532 16533 if (!compat.overflowScrolling) { 16534 target.css('cursor', compat.cursor.grabbing); 16535 target.data(datakey).dragging = flags.dragging = flags.dragged = false; 16536 16537 // apply the drag listeners to the doc or target 16538 if(data.options.dragHold) { 16539 $(document).on(events.drag, data, drag); 16540 } else { 16541 target.on(events.drag, data, drag); 16542 } 16543 } 16544 16545 data.position = capturePosition(event, {}); 16546 data.capture = capturePosition(event, {}, settings.captureThreshold); 16547 triggerEvent('dragstart', target); 16548 16549 } 16550 16551 } 16552 16553 // ends the drag operation and unbinds the mouse move handler 16554 function stop(event) { 16555 16556 var data = event.data, 16557 target = data.target, 16558 options = data.options, 16559 flags = data.flags, 16560 thumbs = data.thumbs, 16561 16562 // hides the thumbs after the animation is done 16563 done = function () { 16564 if (thumbs && !options.hoverThumbs) { 16565 toggleThumbs(thumbs, options, false); 16566 } 16567 }; 16568 16569 // remove drag listeners from doc or target 16570 if(options.dragHold) { 16571 $(document).unbind(events.drag, drag); 16572 } else { 16573 target.unbind(events.drag, drag); 16574 } 16575 16576 // only fire events and drift if we started with a 16577 // valid position 16578 if (data.position) { 16579 16580 triggerEvent('dragend', target); 16581 16582 // only drift if a drag passed our threshold 16583 if (flags.dragging && !compat.overflowScrolling) { 16584 drift(target.get(0), event, done); 16585 } else { 16586 done(); 16587 } 16588 16589 } 16590 16591 // only if we moved, and the mouse down is the same as 16592 // the mouse up target do we defer the event 16593 if (flags.dragging && !compat.overflowScrolling && data.start && data.start.is(event.target)) { 16594 deferClick(data.start); 16595 } 16596 16597 // clear all internal flags and settings 16598 target.data(datakey).dragging = 16599 data.start = 16600 data.capture = 16601 data.position = 16602 flags.dragged = 16603 flags.dragging = false; 16604 16605 // set the cursor back to normal 16606 target.css('cursor', compat.cursor.grab); 16607 16608 } 16609 16610 // Ensures that a full set of options are provided 16611 // for the plug-in. Also does some validation 16612 function getOptions(options) { 16613 16614 // fill in missing values with defaults 16615 options = $.extend({}, defaults, options); 16616 16617 // check for inconsistent directional restrictions 16618 if (options.direction !== 'multi' && options.direction !== options.wheelDirection) { 16619 options.wheelDirection = options.direction; 16620 } 16621 16622 // ensure positive values for deltas 16623 options.scrollDelta = math.abs(parseFloat(options.scrollDelta)); 16624 options.wheelDelta = math.abs(parseFloat(options.wheelDelta)); 16625 16626 // fix values for scroll offset 16627 options.scrollLeft = options.scrollLeft === none ? null : math.abs(parseFloat(options.scrollLeft)); 16628 options.scrollTop = options.scrollTop === none ? null : math.abs(parseFloat(options.scrollTop)); 16629 16630 return options; 16631 16632 } 16633 16634 // Returns the sizing information (bounding box) for the 16635 // target DOM element 16636 function getSizing(target) { 16637 16638 var $target = $(target), 16639 width = $target.width(), 16640 height = $target.height(), 16641 scrollWidth = width >= target.scrollWidth ? width : target.scrollWidth, 16642 scrollHeight = height >= target.scrollHeight ? height : target.scrollHeight, 16643 hasScroll = scrollWidth > width || scrollHeight > height; 16644 16645 return { 16646 valid: hasScroll, 16647 container: { 16648 width: width, 16649 height: height,
16650 scrollWidth: scrollWidth, 16651 scrollHeight: scrollHeight 16652 }, 16653 thumbs: { 16654 horizontal: { 16655 width: width * width / scrollWidth, 16656 height: settings.thumbThickness, 16657 corner: settings.thumbThickness / 2, 16658 left: 0, 16659 top: height - settings.thumbThickness 16660 }, 16661 vertical: { 16662 width: settings.thumbThickness, 16663 height: height * height / scrollHeight, 16664 corner: settings.thumbThickness / 2, 16665 left: width - settings.thumbThickness, 16666 top: 0 16667 } 16668 } 16669 }; 16670 16671 } 16672 16673 // Attempts to get (or implicitly creates) the 16674 // remover function for the target passed 16675 // in as an argument 16676 function getRemover(target, orCreate) { 16677 16678 var $target = $(target), thumbs, 16679 data = $target.data(datakey) || {}, 16680 style = $target.attr('style'), 16681 fallback = orCreate ? function () { 16682 16683 data = $target.data(datakey); 16684 thumbs = data.thumbs; 16685 16686 // restore original styles (if any) 16687 if (style) { 16688 $target.attr('style', style); 16689 } else { 16690 $target.removeAttr('style'); 16691 } 16692 16693 // remove any created thumbs 16694 if (thumbs) { 16695 if (thumbs.horizontal) { thumbs.horizontal.remove(); } 16696 if (thumbs.vertical) { thumbs.vertical.remove(); } 16697 } 16698 16699 // remove any bound overscroll events and data 16700 $target 16701 .removeData(datakey) 16702 .off(events.wheel, wheel) 16703 .off(events.start, start) 16704 .off(events.end, stop) 16705 .off(events.ignored, ignore); 16706 16707 } : $.noop; 16708 16709 return $.isFunction(data.remover) ? data.remover : fallback; 16710 16711 } 16712 16713 // Genterates CSS specific to a particular thumb. 16714 // It requires sizing data and options 16715 function getThumbCss(size, options) { 16716 return { 16717 position: 'absolute', 16718 opacity: options.persistThumbs ? settings.thumbOpacity : 0, 16719 'background-color': 'black', 16720 width: size.width + 'px', 16721 height: size.height + 'px', 16722 'border-radius': size.corner + 'px', 16723 'margin': size.top + 'px 0 0 ' + size.left + 'px', 16724 'z-index': options.zIndex 16725 }; 16726 } 16727 16728 // Creates the DOM elements used as "thumbs" within 16729 // the target container. 16730 function createThumbs(target, sizing, options) { 16731 16732 var div = '<div/>', 16733 thumbs = {}, 16734 css = false; 16735 16736 if (sizing.container.scrollWidth > 0 && options.direction !== 'vertical') { 16737 css = getThumbCss(sizing.thumbs.horizontal, options); 16738 thumbs.horizontal = $(div).css(css).prependTo(target); 16739 } 16740 16741 if (sizing.container.scrollHeight > 0 && options.direction !== 'horizontal') { 16742 css = getThumbCss(sizing.thumbs.vertical, options); 16743 thumbs.vertical = $(div).css(css).prependTo(target); 16744 } 16745 16746 thumbs.added = !!css; 16747 16748 return thumbs; 16749 16750 } 16751 16752 // ignores events on the overscroll element 16753 function ignore(event) { 16754 event.preventDefault(); 16755 } 16756 16757 // This function takes a jQuery element, some 16758 // (optional) options, and sets up event metadata 16759 // for each instance the plug-in affects 16760 function setup(target, options) { 16761 16762 // create initial data properties for this instance 16763 options = getOptions(options); 16764 var sizing = getSizing(target), 16765 thumbs, data = { 16766 options: options, sizing: sizing, 16767 flags: { dragging: false }, 16768 remover: getRemover(target, true) 16769 }; 16770 16771 // only apply handlers if the overscrolled element 16772 // actually has an area to scroll 16773 if (sizing.valid) { 16774 // provide a circular-reference, enable events, and 16775 // apply any required CSS 16776 data.target = target = $(target).css({ 16777 position: 'relative', 16778 cursor: compat.cursor.grab 16779 }).on(events.start, data, start) 16780 .on(events.end, data, stop) 16781 .on(events.ignored, data, ignore); 16782 16783 // apply the stop listeners for drag end 16784 if(options.dragHold) { 16785 $(document).on(events.end, data, stop); 16786 } else { 16787 data.target.on(events.end, data, stop); 16788 } 16789 16790 // apply any user-provided scroll offsets 16791 if (options.scrollLeft !== null) { 16792 target.scrollLeft(options.scrollLeft); 16793 } if (options.scrollTop !== null) { 16794 target.scrollTop(options.scrollTop); 16795 } 16796 16797 // use native oversroll, if it exists 16798 if (compat.overflowScrolling) { 16799 target.css(compat.overflowScrolling, 'touch'); 16800 } else { 16801 target.on(events.scroll, data, scroll); 16802 } 16803 16804 // check to see if the user would like mousewheel support 16805 if (options.captureWheel) { 16806 target.on(events.wheel, data, wheel); 16807 } 16808 16809 // add thumbs and listeners (if we're showing them) 16810 if (options.showThumbs) { 16811 if (compat.overflowScrolling) { 16812 target.css('overflow', 'scroll'); 16813 } else { 16814 target.css('overflow', 'hidden'); 16815 data.thumbs = thumbs = createThumbs(target, sizing, options); 16816 if (thumbs.added) { 16817 moveThumbs(thumbs, sizing, target.scrollLeft(), target.scrollTop()); 16818 if (options.hoverThumbs) { 16819 target.on(events.hover, data, hover); 16820 } 16821 } 16822 } 16823 } else { 16824 target.css('overflow', 'hidden'); 16825 } 16826 16827 target.data(datakey, data); 16828 } 16829 16830 } 16831 16832 // Removes any event listeners and other instance-specific 16833 // data from the target. It attempts to leave the target 16834 // at the state it found it. 16835 function teardown(target) { 16836 getRemover(target)(); 16837 } 16838 16839 // This is the entry-point for enabling the plug-in;
vendor: 6,514 bytes, lines 16840-17080
16840 // You can find it's exposure point at the end 16841 // of this closure 16842 function overscroll(options) { 16843 return this.removeOverscroll().each(function() { 16844 setup(this, options); 16845 }); 16846 } 16847 16848 // This is the entry-point for disabling the plug-in; 16849 // You can find it's exposure point at the end 16850 // of this closure 16851 function removeOverscroll() { 16852 return this.each(function () { 16853 teardown(this); 16854 }); 16855 } 16856 16857 // Extend overscroll to expose settings to the user 16858 overscroll.settings = settings; 16859 16860 // Extend jQuery's prototype to expose the plug-in. 16861 // If the supports native overflowScrolling, overscroll will not 16862 // attempt to override the browser's built in support 16863 $.extend(namespace, { 16864 overscroll: overscroll, 16865 removeOverscroll: removeOverscroll 16866 }); 16867 16868})(window, document, navigator, Math, setTimeout, clearTimeout, jQuery.fn, jQuery); 16869/*! 16870 * fancyBox - jQuery Plugin 16871 * version: 2.1.4 (Thu, 10 Jan 2013) 16872 * @requires jQuery v1.6 or later 16873 * 16874 * Examples at http://fancyapps.com/fancybox/ 16875 * License: www.fancyapps.com/fancybox/#license 16876 * 16877 * Copyright 2012 Janis Skarnelis - [email protected] 16878 * 16879 */ 16880 16881 16882(function (window, document, $, undefined) { 16883 "use strict"; 16884 16885 var W = $(window), 16886 D = $(document), 16887 F = $.fancybox = function () { 16888 F.open.apply( this, arguments ); 16889 }, 16890 IE = navigator.userAgent.match(/msie/), 16891 didUpdate = null, 16892 isTouch = document.createTouch !== undefined, 16893 16894 isQuery = function(obj) { 16895 return obj && obj.hasOwnProperty && obj instanceof $; 16896 }, 16897 isString = function(str) { 16898 return str && $.type(str) === "string"; 16899 }, 16900 isPercentage = function(str) { 16901 return isString(str) && str.indexOf('%') > 0; 16902 }, 16903 isScrollable = function(el) { 16904 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 16905 }, 16906 getScalar = function(orig, dim) { 16907 var value = parseInt(orig, 10) || 0; 16908 16909 if (dim && isPercentage(orig)) { 16910 value = F.getViewport()[ dim ] / 100 * value; 16911 } 16912 16913 return Math.ceil(value); 16914 }, 16915 getValue = function(value, dim) { 16916 return getScalar(value, dim) + 'px'; 16917 }; 16918 16919 $.extend(F, { 16920 // The current version of fancyBox 16921 version: '2.1.4', 16922 16923 defaults: { 16924 padding : 15, 16925 margin : 20, 16926 16927 width : 800, 16928 height : 600, 16929 minWidth : 100, 16930 minHeight : 100, 16931 maxWidth : 9999, 16932 maxHeight : 9999, 16933 16934 autoSize : true, 16935 autoHeight : false, 16936 autoWidth : false, 16937 16938 autoResize : true, 16939 autoCenter : !isTouch, 16940 fitToView : true, 16941 aspectRatio : false, 16942 topRatio : 0.5, 16943 leftRatio : 0.5, 16944 16945 scrolling : 'auto', // 'auto', 'yes' or 'no' 16946 wrapCSS : '', 16947 16948 arrows : true, 16949 closeBtn : true, 16950 closeClick : false, 16951 nextClick : false, 16952 mouseWheel : true, 16953 autoPlay : false, 16954 playSpeed : 3000, 16955 preload : 3, 16956 modal : false, 16957 loop : true, 16958 16959 ajax : { 16960 dataType : 'html', 16961 headers : { 'X-fancyBox': true } 16962 }, 16963 iframe : { 16964 scrolling : 'auto', 16965 preload : true 16966 }, 16967 swf : { 16968 wmode: 'transparent', 16969 allowfullscreen : 'true', 16970 allowscriptaccess : 'always' 16971 }, 16972 16973 keys : { 16974 next : { 16975 13 : 'left', // enter 16976 34 : 'up', // page down 16977 39 : 'left', // right arrow 16978 40 : 'up' // down arrow 16979 }, 16980 prev : { 16981 8 : 'right', // backspace 16982 33 : 'down', // page up 16983 37 : 'right', // left arrow 16984 38 : 'down' // up arrow 16985 }, 16986 close : [27], // escape key 16987 play : [32], // space - start/stop slideshow 16988 toggle : [70] // letter "f" - toggle fullscreen 16989 }, 16990 16991 direction : { 16992 next : 'left', 16993 prev : 'right' 16994 }, 16995 16996 scrollOutside : true, 16997 16998 // Override some properties 16999 index : 0, 17000 type : null, 17001 href : null, 17002 content : null, 17003 title : null, 17004 17005 // HTML templates 17006 tpl: { 17007 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 17008 image : '<img class="fancybox-image" src="{href}" alt="" />', 17009 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 17010 error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 17011 closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 17012 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 17013 prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 17014 }, 17015 17016 // Properties for each animation type 17017 // Opening fancyBox 17018 openEffect : 'fade', // 'elastic', 'fade' or 'none' 17019 openSpeed : 250, 17020 openEasing : 'swing', 17021 openOpacity : true, 17022 openMethod : 'zoomIn', 17023 17024 // Closing fancyBox 17025 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 17026 closeSpeed : 250, 17027 closeEasing : 'swing', 17028 closeOpacity : true, 17029 closeMethod : 'zoomOut', 17030 17031 // Changing next gallery item 17032 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 17033 nextSpeed : 250, 17034 nextEasing : 'swing', 17035 nextMethod : 'changeIn', 17036 17037 // Changing previous gallery item 17038 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 17039 prevSpeed : 250, 17040 prevEasing : 'swing', 17041 prevMethod : 'changeOut', 17042 17043 // Enable default helpers 17044 helpers : { 17045 overlay : true, 17046 title : true 17047 }, 17048 17049 // Callbacks 17050 onCancel : $.noop, // If canceling 17051 beforeLoad : $.noop, // Before loading 17052 afterLoad : $.noop, // After loading 17053 beforeShow : $.noop, // Before changing in current item 17054 afterShow : $.noop, // After opening 17055 beforeChange : $.noop, // Before changing gallery item 17056 beforeClose : $.noop, // Before closing 17057 afterClose : $.noop // After closing 17058 }, 17059 17060 //Current state 17061 group : {}, // Selected group 17062 opts : {}, // Group options 17063 previous : null, // Previous element 17064 coming : null, // Element being loaded 17065 current : null, // Currently loaded element 17066 isActive : false, // Is activated 17067 isOpen : false, // Is currently open 17068 isOpened : false, // Have been fully opened at least once 17069 17070 wrap : null, 17071 skin : null, 17072 outer : null, 17073 inner : null, 17074 17075 player : { 17076 timer : null, 17077 isActive : false 17078 }, 17079 17080 // Loaders
vendor: 34,999 bytes, lines 17081-18558
17081 ajaxLoad : null, 17082 imgPreload : null, 17083 17084 // Some collections 17085 transitions : {}, 17086 helpers : {}, 17087 17088 /* 17089 * Static methods 17090 */ 17091 17092 open: function (group, opts) { 17093 if (!group) { 17094 return; 17095 } 17096 17097 if (!$.isPlainObject(opts)) { 17098 opts = {}; 17099 } 17100 17101 // Close if already active 17102 if (false === F.close(true)) { 17103 return; 17104 } 17105 17106 // Normalize group 17107 if (!$.isArray(group)) { 17108 group = isQuery(group) ? $(group).get() : [group]; 17109 } 17110 17111 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 17112 $.each(group, function(i, element) { 17113 var obj = {}, 17114 href, 17115 title, 17116 content, 17117 type, 17118 rez, 17119 hrefParts, 17120 selector; 17121 17122 if ($.type(element) === "object") { 17123 // Check if is DOM element 17124 if (element.nodeType) { 17125 element = $(element); 17126 } 17127 17128 if (isQuery(element)) { 17129 obj = { 17130 href : element.data('fancybox-href') || element.attr('href'), 17131 title : element.data('fancybox-title') || element.attr('title'), 17132 isDom : true, 17133 element : element 17134 }; 17135 17136 if ($.metadata) { 17137 $.extend(true, obj, element.metadata()); 17138 } 17139 17140 } else { 17141 obj = element; 17142 } 17143 } 17144 17145 href = opts.href || obj.href || (isString(element) ? element : null); 17146 title = opts.title !== undefined ? opts.title : obj.title || ''; 17147 17148 content = opts.content || obj.content; 17149 type = content ? 'html' : (opts.type || obj.type); 17150 17151 if (!type && obj.isDom) { 17152 type = element.data('fancybox-type'); 17153 17154 if (!type) { 17155 rez = element.prop('class').match(/fancybox\.(\w+)/); 17156 type = rez ? rez[1] : null; 17157 } 17158 } 17159 17160 if (isString(href)) { 17161 // Try to guess the content type 17162 if (!type) { 17163 if (F.isImage(href)) { 17164 type = 'image'; 17165 17166 } else if (F.isSWF(href)) { 17167 type = 'swf'; 17168 17169 } else if (href.charAt(0) === '#') { 17170 type = 'inline'; 17171 17172 } else if (isString(element)) { 17173 type = 'html'; 17174 content = element; 17175 } 17176 } 17177 17178 // Split url into two pieces with source url and content selector, e.g, 17179 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 17180 if (type === 'ajax') { 17181 hrefParts = href.split(/\s+/, 2); 17182 href = hrefParts.shift(); 17183 selector = hrefParts.shift(); 17184 } 17185 } 17186 17187 if (!content) { 17188 if (type === 'inline') { 17189 if (href) { 17190 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 17191 17192 } else if (obj.isDom) { 17193 content = element; 17194 } 17195 17196 } else if (type === 'html') { 17197 content = href; 17198 17199 } else if (!type && !href && obj.isDom) { 17200 type = 'inline'; 17201 content = element; 17202 } 17203 } 17204 17205 $.extend(obj, { 17206 href : href, 17207 type : type, 17208 content : content, 17209 title : title, 17210 selector : selector 17211 }); 17212 17213 group[ i ] = obj; 17214 }); 17215 17216 // Extend the defaults 17217 F.opts = $.extend(true, {}, F.defaults, opts); 17218 17219 // All options are merged recursive except keys 17220 if (opts.keys !== undefined) { 17221 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 17222 } 17223 17224 F.group = group; 17225 17226 return F._start(F.opts.index); 17227 }, 17228 17229 // Cancel image loading or abort ajax request 17230 cancel: function () { 17231 var coming = F.coming; 17232 17233 if (!coming || false === F.trigger('onCancel')) { 17234 return; 17235 } 17236 17237 F.hideLoading(); 17238 17239 if (F.ajaxLoad) { 17240 F.ajaxLoad.abort(); 17241 } 17242 17243 F.ajaxLoad = null; 17244 17245 if (F.imgPreload) { 17246 F.imgPreload.onload = F.imgPreload.onerror = null; 17247 } 17248 17249 if (coming.wrap) { 17250 coming.wrap.stop(true, true).trigger('onReset').remove(); 17251 } 17252 17253 F.coming = null; 17254 17255 // If the first item has been canceled, then clear everything 17256 if (!F.current) { 17257 F._afterZoomOut( coming ); 17258 } 17259 }, 17260 17261 // Start closing animation if is open; remove immediately if opening/closing 17262 close: function (event) { 17263 F.cancel(); 17264 17265 if (false === F.trigger('beforeClose')) { 17266 return; 17267 } 17268 17269 F.unbindEvents(); 17270 17271 if (!F.isActive) { 17272 return; 17273 } 17274 17275 if (!F.isOpen || event === true) { 17276 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 17277 17278 F._afterZoomOut(); 17279 17280 } else { 17281 F.isOpen = F.isOpened = false; 17282 F.isClosing = true; 17283 17284 $('.fancybox-item, .fancybox-nav').remove(); 17285 17286 F.wrap.stop(true, true).removeClass('fancybox-opened'); 17287 17288 F.transitions[ F.current.closeMethod ](); 17289 } 17290 }, 17291 17292 // Manage slideshow: 17293 // $.fancybox.play(); - toggle slideshow 17294 // $.fancybox.play( true ); - start 17295 // $.fancybox.play( false ); - stop 17296 play: function ( action ) { 17297 var clear = function () { 17298 clearTimeout(F.player.timer); 17299 }, 17300 set = function () { 17301 clear(); 17302 17303 if (F.current && F.player.isActive) { 17304 F.player.timer = setTimeout(F.next, F.current.playSpeed); 17305 } 17306 }, 17307 stop = function () { 17308 clear(); 17309 17310 $('body').unbind('.player'); 17311 17312 F.player.isActive = false; 17313 17314 F.trigger('onPlayEnd'); 17315 }, 17316 start = function () { 17317 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 17318 F.player.isActive = true; 17319 17320 $('body').bind({ 17321 'afterShow.player onUpdate.player' : set, 17322 'onCancel.player beforeClose.player' : stop, 17323 'beforeLoad.player' : clear 17324 }); 17325 17326 set(); 17327 17328 F.trigger('onPlayStart'); 17329 } 17330 }; 17331 17332 if (action === true || (!F.player.isActive && action !== false)) { 17333 start(); 17334 } else { 17335 stop(); 17336 } 17337 }, 17338 17339 // Navigate to next gallery item 17340 next: function ( direction ) { 17341 var current = F.current; 17342 17343 if (current) { 17344 if (!isString(direction)) { 17345 direction = current.direction.next; 17346 } 17347 17348 F.jumpto(current.index + 1, direction, 'next'); 17349 } 17350 }, 17351 17352 // Navigate to previous gallery item 17353 prev: function ( direction ) { 17354 var current = F.current; 17355 17356 if (current) { 17357 if (!isString(direction)) { 17358 direction = current.direction.prev; 17359 } 17360 17361 F.jumpto(current.index - 1, direction, 'prev'); 17362 } 17363 }, 17364 17365 // Navigate to gallery item by index 17366 jumpto: function ( index, direction, router ) { 17367 var current = F.current; 17368 17369 if (!current) { 17370 return; 17371 } 17372 17373 index = getScalar(index); 17374 17375 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 17376 F.router = router || 'jumpto'; 17377 17378 if (current.loop) { 17379 if (index < 0) { 17380 index = current.group.length + (index % current.group.length); 17381 } 17382 17383 index = index % current.group.length; 17384 } 17385 17386 if (current.group[ index ] !== undefined) { 17387 F.cancel(); 17388 17389 F._start(index); 17390 } 17391 }, 17392 17393 // Center inside viewport and toggle position type to fixed or absolute if needed 17394 reposition: function (e, onlyAbsolute) { 17395 var current = F.current, 17396 wrap = current ? current.wrap : null, 17397 pos; 17398 17399 if (wrap) { 17400 pos = F._getPosition(onlyAbsolute); 17401 17402 if (e && e.type === 'scroll') { 17403 delete pos.position; 17404 17405 wrap.stop(true, true).animate(pos, 200); 17406 17407 } else { 17408 wrap.css(pos); 17409 17410 current.pos = $.extend({}, current.dim, pos); 17411 } 17412 } 17413 }, 17414 17415 update: function (e) { 17416 var type = (e && e.type), 17417 anyway = !type || type === 'orientationchange'; 17418 17419 if (anyway) { 17420 clearTimeout(didUpdate); 17421 17422 didUpdate = null; 17423 } 17424 17425 if (!F.isOpen || didUpdate) { 17426 return; 17427 } 17428 17429 didUpdate = setTimeout(function() { 17430 var current = F.current; 17431 17432 if (!current || F.isClosing) { 17433 return; 17434 } 17435 17436 F.wrap.removeClass('fancybox-tmp'); 17437 17438 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 17439 F._setDimension(); 17440 } 17441 17442 if (!(type === 'scroll' && current.canShrink)) { 17443 F.reposition(e); 17444 } 17445 17446 F.trigger('onUpdate'); 17447 17448 didUpdate = null; 17449 17450 }, (anyway && !isTouch ? 0 : 300)); 17451 }, 17452 17453 // Shrink content to fit inside viewport or restore if resized 17454 toggle: function ( action ) { 17455 if (F.isOpen) { 17456 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 17457 17458 // Help browser to restore document dimensions 17459 if (isTouch) { 17460 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 17461 17462 F.trigger('onUpdate'); 17463 } 17464 17465 F.update(); 17466 } 17467 }, 17468 17469 hideLoading: function () { 17470 D.unbind('.loading'); 17471 17472 $('#fancybox-loading').remove(); 17473 }, 17474 17475 showLoading: function () { 17476 var el, viewport; 17477 17478 F.hideLoading(); 17479 17480 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body'); 17481 17482 // If user will press the escape-button, the request will be canceled 17483 D.bind('keydown.loading', function(e) { 17484 if ((e.which || e.keyCode) === 27) { 17485 e.preventDefault(); 17486 17487 F.cancel(); 17488 } 17489 }); 17490 17491 if (!F.defaults.fixed) { 17492 viewport = F.getViewport(); 17493 17494 el.css({ 17495 position : 'absolute', 17496 top : (viewport.h * 0.5) + viewport.y, 17497 left : (viewport.w * 0.5) + viewport.x 17498 }); 17499 } 17500 }, 17501 17502 getViewport: function () { 17503 var locked = (F.current && F.current.locked) || false, 17504 rez = { 17505 x: W.scrollLeft(), 17506 y: W.scrollTop() 17507 }; 17508 17509 if (locked) { 17510 rez.w = locked[0].clientWidth; 17511 rez.h = locked[0].clientHeight; 17512 17513 } else { 17514 // See http://bugs.jquery.com/ticket/6724 17515 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 17516 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 17517 } 17518 17519 return rez; 17520 }, 17521 17522 // Unbind the keyboard / clicking actions 17523 unbindEvents: function () { 17524 if (F.wrap && isQuery(F.wrap)) { 17525 F.wrap.unbind('.fb'); 17526 } 17527 17528 D.unbind('.fb'); 17529 W.unbind('.fb'); 17530 }, 17531 17532 bindEvents: function () { 17533 var current = F.current, 17534 keys; 17535 17536 if (!current) { 17537 return; 17538 } 17539 17540 // Changing document height on iOS devices triggers a 'resize' event, 17541 // that can change document height... repeating infinitely 17542 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 17543 17544 keys = current.keys; 17545 17546 if (keys) { 17547 D.bind('keydown.fb', function (e) { 17548 var code = e.which || e.keyCode, 17549 target = e.target || e.srcElement; 17550 17551 // Skip esc key if loading, because showLoading will cancel preloading 17552 if (code === 27 && F.coming) { 17553 return false; 17554 } 17555 17556 // Ignore key combinations and key events within form elements 17557 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 17558 $.each(keys, function(i, val) { 17559 if (current.group.length > 1 && val[ code ] !== undefined) { 17560 F[ i ]( val[ code ] ); 17561 17562 e.preventDefault(); 17563 return false; 17564 } 17565 17566 if ($.inArray(code, val) > -1) { 17567 F[ i ] (); 17568 17569 e.preventDefault(); 17570 return false; 17571 } 17572 }); 17573 } 17574 }); 17575 } 17576 17577 if ($.fn.mousewheel && current.mouseWheel) { 17578 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { 17579 var target = e.target || null, 17580 parent = $(target), 17581 canScroll = false; 17582 17583 while (parent.length) { 17584 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 17585 break; 17586 } 17587 17588 canScroll = isScrollable( parent[0] ); 17589 parent = $(parent).parent(); 17590 } 17591 17592 if (delta !== 0 && !canScroll) { 17593 if (F.group.length > 1 && !current.canShrink) { 17594 if (deltaY > 0 || deltaX > 0) { 17595 F.prev( deltaY > 0 ? 'down' : 'left' ); 17596 17597 } else if (deltaY < 0 || deltaX < 0) { 17598 F.next( deltaY < 0 ? 'up' : 'right' ); 17599 } 17600 17601 e.preventDefault(); 17602 } 17603 } 17604 }); 17605 } 17606 }, 17607 17608 trigger: function (event, o) { 17609 var ret, obj = o || F.coming || F.current; 17610 17611 if (!obj) { 17612 return; 17613 } 17614 17615 if ($.isFunction( obj[event] )) { 17616 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 17617 } 17618 17619 if (ret === false) { 17620 return false; 17621 } 17622 17623 if (obj.helpers) { 17624 $.each(obj.helpers, function (helper, opts) { 17625 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 17626 opts = $.extend(true, {}, F.helpers[helper].defaults, opts); 17627 17628 F.helpers[helper][event](opts, obj); 17629 } 17630 }); 17631 } 17632 17633 $.event.trigger(event + '.fb'); 17634 }, 17635 17636 isImage: function (str) { 17637 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i); 17638 }, 17639 17640 isSWF: function (str) { 17641 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); 17642 }, 17643 17644 _start: function (index) { 17645 var coming = {}, 17646 obj, 17647 href, 17648 type, 17649 margin, 17650 padding; 17651 17652 index = getScalar( index ); 17653 obj = F.group[ index ] || null; 17654 17655 if (!obj) { 17656 return false; 17657 } 17658 17659 coming = $.extend(true, {}, F.opts, obj); 17660 17661 // Convert margin and padding properties to array - top, right, bottom, left 17662 margin = coming.margin; 17663 padding = coming.padding; 17664 17665 if ($.type(margin) === 'number') { 17666 coming.margin = [margin, margin, margin, margin]; 17667 } 17668 17669 if ($.type(padding) === 'number') { 17670 coming.padding = [padding, padding, padding, padding]; 17671 } 17672 17673 // 'modal' propery is just a shortcut 17674 if (coming.modal) { 17675 $.extend(true, coming, { 17676 closeBtn : false, 17677 closeClick : false, 17678 nextClick : false, 17679 arrows : false, 17680 mouseWheel : false, 17681 keys : null, 17682 helpers: { 17683 overlay : { 17684 closeClick : false 17685 } 17686 } 17687 }); 17688 } 17689 17690 // 'autoSize' property is a shortcut, too 17691 if (coming.autoSize) { 17692 coming.autoWidth = coming.autoHeight = true; 17693 } 17694 17695 if (coming.width === 'auto') { 17696 coming.autoWidth = true; 17697 } 17698 17699 if (coming.height === 'auto') { 17700 coming.autoHeight = true; 17701 } 17702 17703 /* 17704 * Add reference to the group, so it`s possible to access from callbacks, example: 17705 * afterLoad : function() { 17706 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 17707 * } 17708 */ 17709 17710 coming.group = F.group; 17711 coming.index = index; 17712 17713 // Give a chance for callback or helpers to update coming item (type, title, etc) 17714 F.coming = coming; 17715 17716 if (false === F.trigger('beforeLoad')) { 17717 F.coming = null; 17718 17719 return; 17720 } 17721 17722 type = coming.type; 17723 href = coming.href; 17724 17725 if (!type) { 17726 F.coming = null; 17727 17728 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 17729 if (F.current && F.router && F.router !== 'jumpto') { 17730 F.current.index = index; 17731 17732 return F[ F.router ]( F.direction ); 17733 } 17734 17735 return false; 17736 } 17737 17738 F.isActive = true; 17739 17740 if (type === 'image' || type === 'swf') { 17741 coming.autoHeight = coming.autoWidth = false; 17742 coming.scrolling = 'visible'; 17743 } 17744 17745 if (type === 'image') { 17746 coming.aspectRatio = true; 17747 } 17748 17749 if (type === 'iframe' && isTouch) { 17750 coming.scrolling = 'scroll'; 17751 } 17752 17753 // Build the neccessary markup 17754 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 17755 17756 $.extend(coming, { 17757 skin : $('.fancybox-skin', coming.wrap), 17758 outer : $('.fancybox-outer', coming.wrap), 17759 inner : $('.fancybox-inner', coming.wrap) 17760 }); 17761 17762 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 17763 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 17764 }); 17765 17766 F.trigger('onReady'); 17767 17768 // Check before try to load; 'inline' and 'html' types need content, others - href 17769 if (type === 'inline' || type === 'html') { 17770 if (!coming.content || !coming.content.length) { 17771 return F._error( 'content' ); 17772 } 17773 17774 } else if (!href) { 17775 return F._error( 'href' ); 17776 } 17777 17778 if (type === 'image') { 17779 F._loadImage(); 17780 17781 } else if (type === 'ajax') { 17782 F._loadAjax(); 17783 17784 } else if (type === 'iframe') { 17785 F._loadIframe(); 17786 17787 } else { 17788 F._afterLoad(); 17789 } 17790 }, 17791 17792 _error: function ( type ) { 17793 $.extend(F.coming, { 17794 type : 'html', 17795 autoWidth : true, 17796 autoHeight : true, 17797 minWidth : 0, 17798 minHeight : 0, 17799 scrolling : 'no', 17800 hasError : type, 17801 content : F.coming.tpl.error 17802 }); 17803 17804 F._afterLoad(); 17805 }, 17806 17807 _loadImage: function () { 17808 // Reset preload image so it is later possible to check "complete" property 17809 var img = F.imgPreload = new Image(); 17810 17811 img.onload = function () { 17812 this.onload = this.onerror = null; 17813 17814 F.coming.width = this.width; 17815 F.coming.height = this.height; 17816 17817 F._afterLoad(); 17818 }; 17819 17820 img.onerror = function () { 17821 this.onload = this.onerror = null; 17822 17823 F._error( 'image' ); 17824 }; 17825 17826 img.src = F.coming.href; 17827 17828 if (img.complete !== true) { 17829 F.showLoading(); 17830 } 17831 }, 17832 17833 _loadAjax: function () { 17834 var coming = F.coming; 17835 17836 F.showLoading(); 17837 17838 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 17839 url: coming.href, 17840 error: function (jqXHR, textStatus) { 17841 if (F.coming && textStatus !== 'abort') { 17842 F._error( 'ajax', jqXHR ); 17843 17844 } else { 17845 F.hideLoading(); 17846 } 17847 }, 17848 success: function (data, textStatus) { 17849 if (textStatus === 'success') { 17850 coming.content = data; 17851 17852 F._afterLoad(); 17853 } 17854 } 17855 })); 17856 }, 17857 17858 _loadIframe: function() { 17859 var coming = F.coming, 17860 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 17861 .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) 17862 .attr('src', coming.href); 17863 17864 // This helps IE 17865 $(coming.wrap).bind('onReset', function () { 17866 try { 17867 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 17868 } catch (e) {} 17869 }); 17870 17871 if (coming.iframe.preload) { 17872 F.showLoading(); 17873 17874 iframe.one('load', function() { 17875 $(this).data('ready', 1); 17876 17877 // iOS will lose scrolling if we resize 17878 if (!isTouch) { 17879 $(this).bind('load.fb', F.update); 17880 } 17881 17882 // Without this trick: 17883 // - iframe won't scroll on iOS devices 17884 // - IE7 sometimes displays empty iframe 17885 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 17886 17887 F._afterLoad(); 17888 }); 17889 } 17890 17891 coming.content = iframe.appendTo( coming.inner ); 17892 17893 if (!coming.iframe.preload) { 17894 F._afterLoad(); 17895 } 17896 }, 17897 17898 _preloadImages: function() { 17899 var group = F.group, 17900 current = F.current, 17901 len = group.length, 17902 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 17903 item, 17904 i; 17905 17906 for (i = 1; i <= cnt; i += 1) { 17907 item = group[ (current.index + i ) % len ]; 17908 17909 if (item.type === 'image' && item.href) { 17910 new Image().src = item.href; 17911 } 17912 } 17913 }, 17914 17915 _afterLoad: function () { 17916 var coming = F.coming, 17917 previous = F.current, 17918 placeholder = 'fancybox-placeholder', 17919 current, 17920 content, 17921 type, 17922 scrolling, 17923 href, 17924 embed; 17925 17926 F.hideLoading(); 17927 17928 if (!coming || F.isActive === false) { 17929 return; 17930 } 17931 17932 if (false === F.trigger('afterLoad', coming, previous)) { 17933 coming.wrap.stop(true).trigger('onReset').remove(); 17934 17935 F.coming = null; 17936 17937 return; 17938 } 17939 17940 if (previous) { 17941 F.trigger('beforeChange', previous); 17942 17943 previous.wrap.stop(true).removeClass('fancybox-opened') 17944 .find('.fancybox-item, .fancybox-nav') 17945 .remove(); 17946 } 17947 17948 F.unbindEvents(); 17949 17950 current = coming; 17951 content = coming.content; 17952 type = coming.type; 17953 scrolling = coming.scrolling; 17954 17955 $.extend(F, { 17956 wrap : current.wrap, 17957 skin : current.skin, 17958 outer : current.outer, 17959 inner : current.inner, 17960 current : current, 17961 previous : previous 17962 }); 17963 17964 href = current.href; 17965 17966 switch (type) { 17967 case 'inline': 17968 case 'ajax': 17969 case 'html': 17970 if (current.selector) { 17971 content = $('<div>').html(content).find(current.selector); 17972 17973 } else if (isQuery(content)) { 17974 if (!content.data(placeholder)) { 17975 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); 17976 } 17977 17978 content = content.show().detach(); 17979 17980 current.wrap.bind('onReset', function () { 17981 if ($(this).find(content).length) { 17982 content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); 17983 } 17984 }); 17985 } 17986 break; 17987 17988 case 'image': 17989 content = current.tpl.image.replace('{href}', href); 17990 break; 17991 17992 case 'swf': 17993 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; 17994 embed = ''; 17995 17996 $.each(current.swf, function(name, val) { 17997 content += '<param name="' + name + '" value="' + val + '"></param>'; 17998 embed += ' ' + name + '="' + val + '"'; 17999 }); 18000 18001 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; 18002 break; 18003 } 18004 18005 if (!(isQuery(content) && content.parent().is(current.inner))) { 18006 current.inner.append( content ); 18007 } 18008 18009 // Give a chance for helpers or callbacks to update elements 18010 F.trigger('beforeShow'); 18011 18012 // Set scrolling before calculating dimensions 18013 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 18014 18015 // Set initial dimensions and start position 18016 F._setDimension(); 18017 18018 F.reposition(); 18019 18020 F.isOpen = false; 18021 F.coming = null; 18022 18023 F.bindEvents(); 18024 18025 if (!F.isOpened) { 18026 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 18027 18028 } else if (previous.prevMethod) { 18029 F.transitions[ previous.prevMethod ](); 18030 } 18031 18032 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 18033 18034 F._preloadImages(); 18035 }, 18036 18037 _setDimension: function () { 18038 var viewport = F.getViewport(), 18039 steps = 0, 18040 canShrink = false, 18041 canExpand = false, 18042 wrap = F.wrap, 18043 skin = F.skin, 18044 inner = F.inner, 18045 current = F.current, 18046 width = current.width, 18047 height = current.height, 18048 minWidth = current.minWidth, 18049 minHeight = current.minHeight, 18050 maxWidth = current.maxWidth, 18051 maxHeight = current.maxHeight, 18052 scrolling = current.scrolling, 18053 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 18054 margin = current.margin, 18055 wMargin = getScalar(margin[1] + margin[3]), 18056 hMargin = getScalar(margin[0] + margin[2]), 18057 wPadding, 18058 hPadding, 18059 wSpace, 18060 hSpace, 18061 origWidth, 18062 origHeight, 18063 origMaxWidth, 18064 origMaxHeight, 18065 ratio, 18066 width_, 18067 height_, 18068 maxWidth_, 18069 maxHeight_, 18070 iframe, 18071 body; 18072 18073 // Reset dimensions so we could re-check actual size 18074 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 18075 18076 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 18077 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 18078 18079 // Any space between content and viewport (margin, padding, border, title) 18080 wSpace = wMargin + wPadding; 18081 hSpace = hMargin + hPadding; 18082 18083 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 18084 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 18085 18086 if (current.type === 'iframe') { 18087 iframe = current.content; 18088 18089 if (current.autoHeight && iframe.data('ready') === 1) { 18090 try { 18091 if (iframe[0].contentWindow.document.location) { 18092 inner.width( origWidth ).height(9999); 18093 18094 body = iframe.contents().find('body'); 18095 18096 if (scrollOut) { 18097 body.css('overflow-x', 'hidden'); 18098 } 18099 18100 origHeight = body.height(); 18101 } 18102 18103 } catch (e) {} 18104 } 18105 18106 } else if (current.autoWidth || current.autoHeight) { 18107 inner.addClass( 'fancybox-tmp' ); 18108 18109 // Set width or height in case we need to calculate only one dimension 18110 if (!current.autoWidth) { 18111 inner.width( origWidth ); 18112 } 18113 18114 if (!current.autoHeight) { 18115 inner.height( origHeight ); 18116 } 18117 18118 if (current.autoWidth) { 18119 origWidth = inner.width(); 18120 } 18121 18122 if (current.autoHeight) { 18123 origHeight = inner.height(); 18124 } 18125 18126 inner.removeClass( 'fancybox-tmp' ); 18127 } 18128 18129 width = getScalar( origWidth ); 18130 height = getScalar( origHeight ); 18131 18132 ratio = origWidth / origHeight; 18133 18134 // Calculations for the content 18135 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 18136 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 18137 18138 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 18139 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 18140 18141 // These will be used to determine if wrap can fit in the viewport 18142 origMaxWidth = maxWidth; 18143 origMaxHeight = maxHeight; 18144 18145 if (current.fitToView) { 18146 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 18147 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 18148 } 18149 18150 maxWidth_ = viewport.w - wMargin; 18151 maxHeight_ = viewport.h - hMargin; 18152 18153 if (current.aspectRatio) { 18154 if (width > maxWidth) { 18155 width = maxWidth; 18156 height = getScalar(width / ratio); 18157 } 18158 18159 if (height > maxHeight) { 18160 height = maxHeight; 18161 width = getScalar(height * ratio); 18162 } 18163 18164 if (width < minWidth) { 18165 width = minWidth; 18166 height = getScalar(width / ratio); 18167 } 18168 18169 if (height < minHeight) { 18170 height = minHeight; 18171 width = getScalar(height * ratio); 18172 } 18173 18174 } else { 18175 width = Math.max(minWidth, Math.min(width, maxWidth)); 18176 18177 if (current.autoHeight && current.type !== 'iframe') { 18178 inner.width( width ); 18179 18180 height = inner.height(); 18181 } 18182 18183 height = Math.max(minHeight, Math.min(height, maxHeight)); 18184 } 18185 18186 // Try to fit inside viewport (including the title) 18187 if (current.fitToView) { 18188 inner.width( width ).height( height ); 18189 18190 wrap.width( width + wPadding ); 18191 18192 // Real wrap dimensions 18193 width_ = wrap.width(); 18194 height_ = wrap.height(); 18195 18196 if (current.aspectRatio) { 18197 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 18198 if (steps++ > 19) { 18199 break; 18200 } 18201 18202 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 18203 width = getScalar(height * ratio); 18204 18205 if (width < minWidth) { 18206 width = minWidth; 18207 height = getScalar(width / ratio); 18208 } 18209 18210 if (width > maxWidth) { 18211 width = maxWidth; 18212 height = getScalar(width / ratio); 18213 } 18214 18215 inner.width( width ).height( height ); 18216 18217 wrap.width( width + wPadding ); 18218 18219 width_ = wrap.width(); 18220 height_ = wrap.height(); 18221 } 18222 18223 } else { 18224 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 18225 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 18226 } 18227 } 18228 18229 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 18230 width += scrollOut; 18231 } 18232 18233 inner.width( width ).height( height ); 18234 18235 wrap.width( width + wPadding ); 18236 18237 width_ = wrap.width(); 18238 height_ = wrap.height(); 18239 18240 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 18241 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 18242 18243 $.extend(current, { 18244 dim : { 18245 width : getValue( width_ ), 18246 height : getValue( height_ ) 18247 }, 18248 origWidth : origWidth, 18249 origHeight : origHeight, 18250 canShrink : canShrink, 18251 canExpand : canExpand, 18252 wPadding : wPadding, 18253 hPadding : hPadding, 18254 wrapSpace : height_ - skin.outerHeight(true), 18255 skinSpace : skin.height() - height 18256 }); 18257 18258 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 18259 inner.height('auto'); 18260 } 18261 }, 18262 18263 _getPosition: function (onlyAbsolute) { 18264 var current = F.current, 18265 viewport = F.getViewport(), 18266 margin = current.margin, 18267 width = F.wrap.width() + margin[1] + margin[3], 18268 height = F.wrap.height() + margin[0] + margin[2], 18269 rez = { 18270 position: 'absolute', 18271 top : margin[0], 18272 left : margin[3] 18273 }; 18274 18275 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 18276 rez.position = 'fixed'; 18277 18278 } else if (!current.locked) { 18279 rez.top += viewport.y; 18280 rez.left += viewport.x; 18281 } 18282 18283 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 18284 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 18285 18286 return rez; 18287 }, 18288 18289 _afterZoomIn: function () { 18290 var current = F.current; 18291 18292 if (!current) { 18293 return; 18294 } 18295 18296 F.isOpen = F.isOpened = true; 18297 18298 F.wrap.css('overflow', 'visible').addClass('fancybox-opened'); 18299 18300 F.update(); 18301 18302 // Assign a click event 18303 if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { 18304 F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { 18305 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 18306 e.preventDefault(); 18307 18308 F[ current.closeClick ? 'close' : 'next' ](); 18309 } 18310 }); 18311 } 18312 18313 // Create a close button 18314 if (current.closeBtn) { 18315 $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { 18316 e.preventDefault(); 18317 18318 F.close(); 18319 }); 18320 } 18321 18322 // Create navigation arrows 18323 if (current.arrows && F.group.length > 1) { 18324 if (current.loop || current.index > 0) { 18325 $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); 18326 } 18327 18328 if (current.loop || current.index < F.group.length - 1) { 18329 $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); 18330 } 18331 } 18332 18333 F.trigger('afterShow'); 18334 18335 // Stop the slideshow if this is the last item 18336 if (!current.loop && current.index === current.group.length - 1) { 18337 F.play( false ); 18338 18339 } else if (F.opts.autoPlay && !F.player.isActive) { 18340 F.opts.autoPlay = false; 18341 18342 F.play(); 18343 } 18344 }, 18345 18346 _afterZoomOut: function ( obj ) { 18347 obj = obj || F.current; 18348 18349 $('.fancybox-wrap').trigger('onReset').remove(); 18350 18351 $.extend(F, { 18352 group : {}, 18353 opts : {}, 18354 router : false, 18355 current : null, 18356 isActive : false, 18357 isOpened : false, 18358 isOpen : false, 18359 isClosing : false, 18360 wrap : null, 18361 skin : null, 18362 outer : null, 18363 inner : null 18364 }); 18365 18366 F.trigger('afterClose', obj); 18367 } 18368 }); 18369 18370 /* 18371 * Default transitions 18372 */ 18373 18374 F.transitions = { 18375 getOrigPosition: function () { 18376 var current = F.current, 18377 element = current.element, 18378 orig = current.orig, 18379 pos = {}, 18380 width = 50, 18381 height = 50, 18382 hPadding = current.hPadding, 18383 wPadding = current.wPadding, 18384 viewport = F.getViewport(); 18385 18386 if (!orig && current.isDom && element.is(':visible')) { 18387 orig = element.find('img:first'); 18388 18389 if (!orig.length) { 18390 orig = element; 18391 } 18392 } 18393 18394 if (isQuery(orig)) { 18395 pos = orig.offset(); 18396 18397 if (orig.is('img')) { 18398 width = orig.outerWidth(); 18399 height = orig.outerHeight(); 18400 } 18401 18402 } else { 18403 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 18404 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 18405 } 18406 18407 if (F.wrap.css('position') === 'fixed' || current.locked) { 18408 pos.top -= viewport.y; 18409 pos.left -= viewport.x; 18410 } 18411 18412 pos = { 18413 top : getValue(pos.top - hPadding * current.topRatio), 18414 left : getValue(pos.left - wPadding * current.leftRatio), 18415 width : getValue(width + wPadding), 18416 height : getValue(height + hPadding) 18417 }; 18418 18419 return pos; 18420 }, 18421 18422 step: function (now, fx) { 18423 var ratio, 18424 padding, 18425 value, 18426 prop = fx.prop, 18427 current = F.current, 18428 wrapSpace = current.wrapSpace, 18429 skinSpace = current.skinSpace; 18430 18431 if (prop === 'width' || prop === 'height') { 18432 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 18433 18434 if (F.isClosing) { 18435 ratio = 1 - ratio; 18436 } 18437 18438 padding = prop === 'width' ? current.wPadding : current.hPadding; 18439 value = now - padding; 18440 18441 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 18442 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 18443 } 18444 }, 18445 18446 zoomIn: function () { 18447 var current = F.current, 18448 startPos = current.pos, 18449 effect = current.openEffect, 18450 elastic = effect === 'elastic', 18451 endPos = $.extend({opacity : 1}, startPos); 18452 18453 // Remove "position" property that breaks older IE 18454 delete endPos.position; 18455 18456 if (elastic) { 18457 startPos = this.getOrigPosition(); 18458 18459 if (current.openOpacity) { 18460 startPos.opacity = 0.1; 18461 } 18462 18463 } else if (effect === 'fade') { 18464 startPos.opacity = 0.1; 18465 } 18466 18467 F.wrap.css(startPos).animate(endPos, { 18468 duration : effect === 'none' ? 0 : current.openSpeed, 18469 easing : current.openEasing, 18470 step : elastic ? this.step : null, 18471 complete : F._afterZoomIn 18472 }); 18473 }, 18474 18475 zoomOut: function () { 18476 var current = F.current, 18477 effect = current.closeEffect, 18478 elastic = effect === 'elastic', 18479 endPos = {opacity : 0.1}; 18480 18481 if (elastic) { 18482 endPos = this.getOrigPosition(); 18483 18484 if (current.closeOpacity) { 18485 endPos.opacity = 0.1; 18486 } 18487 } 18488 18489 F.wrap.animate(endPos, { 18490 duration : effect === 'none' ? 0 : current.closeSpeed, 18491 easing : current.closeEasing, 18492 step : elastic ? this.step : null, 18493 complete : F._afterZoomOut 18494 }); 18495 }, 18496 18497 changeIn: function () { 18498 var current = F.current, 18499 effect = current.nextEffect, 18500 startPos = current.pos, 18501 endPos = { opacity : 1 }, 18502 direction = F.direction, 18503 distance = 200, 18504 field; 18505 18506 startPos.opacity = 0.1; 18507 18508 if (effect === 'elastic') { 18509 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 18510 18511 if (direction === 'down' || direction === 'right') { 18512 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 18513 endPos[ field ] = '+=' + distance + 'px'; 18514 18515 } else { 18516 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 18517 endPos[ field ] = '-=' + distance + 'px'; 18518 } 18519 } 18520 18521 // Workaround for http://bugs.jquery.com/ticket/12273 18522 if (effect === 'none') { 18523 F._afterZoomIn(); 18524 18525 } else { 18526 F.wrap.css(startPos).animate(endPos, { 18527 duration : current.nextSpeed, 18528 easing : current.nextEasing, 18529 complete : F._afterZoomIn 18530 }); 18531 } 18532 }, 18533 18534 changeOut: function () { 18535 var previous = F.previous, 18536 effect = previous.prevEffect, 18537 endPos = { opacity : 0.1 }, 18538 direction = F.direction, 18539 distance = 200; 18540 18541 if (effect === 'elastic') { 18542 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 18543 } 18544 18545 previous.wrap.animate(endPos, { 18546 duration : effect === 'none' ? 0 : previous.prevSpeed, 18547 easing : previous.prevEasing, 18548 complete : function () { 18549 $(this).trigger('onReset').remove(); 18550 } 18551 }); 18552 } 18553 }; 18554 18555 /* 18556 * Overlay helper 18557 */ 18558
18559 F.helpers.overlay = { 18560 defaults : { 18561 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 18562 speedOut : 200, // duration of fadeOut animation 18563 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 18564 css : {}, // custom CSS properties 18565 locked : !isTouch, // if true, the content will be locked into overlay 18566 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 18567 }, 18568 18569 overlay : null, // current handle 18570 fixed : false, // indicates if the overlay has position "fixed" 18571 18572 // Public methods 18573 create : function(opts) { 18574 opts = $.extend({}, this.defaults, opts); 18575 18576 if (this.overlay) { 18577 this.close(); 18578 } 18579 18580 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( 'body' ); 18581 this.fixed = false; 18582 18583 if (opts.fixed && F.defaults.fixed) { 18584 this.overlay.addClass('fancybox-overlay-fixed'); 18585 18586 this.fixed = true; 18587 } 18588 }, 18589 18590 open : function(opts) { 18591 var that = this; 18592 18593 opts = $.extend({}, this.defaults, opts); 18594 18595 if (this.overlay) { 18596 this.overlay.unbind('.overlay').width('auto').height('auto'); 18597 18598 } else { 18599 this.create(opts); 18600 } 18601 18602 if (!this.fixed) { 18603 W.bind('resize.overlay', $.proxy( this.update, this) ); 18604 18605 this.update(); 18606 } 18607 18608 if (opts.closeClick) { 18609 this.overlay.bind('click.overlay', function(e) { 18610 if ($(e.target).hasClass('fancybox-overlay')) { 18611 if (F.isActive) { 18612 F.close(); 18613 } else { 18614 that.close(); 18615 } 18616 } 18617 }); 18618 } 18619 18620 this.overlay.css( opts.css ).show(); 18621 }, 18622 18623 close : function() { 18624 $('.fancybox-overlay').remove(); 18625 18626 W.unbind('resize.overlay'); 18627 18628 this.overlay = null; 18629 18630 if (this.margin !== false) { 18631 $('body').css('margin-right', this.margin); 18632 18633 this.margin = false; 18634 } 18635 18636 if (this.el) { 18637 this.el.removeClass('fancybox-lock'); 18638 } 18639 }, 18640 18641 // Private, callbacks 18642 18643 update : function () { 18644 var width = '100%', offsetWidth; 18645 18646 // Reset width/height so it will not mess 18647 this.overlay.width(width).height('100%'); 18648 18649 // jQuery does not return reliable result for IE 18650 if (IE) { 18651 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 18652 18653 if (D.width() > offsetWidth) { 18654 width = D.width(); 18655 } 18656 18657 } else if (D.width() > W.width()) { 18658 width = D.width(); 18659 } 18660 18661 this.overlay.width(width).height(D.height()); 18662 }, 18663 18664 // This is where we can manipulate DOM, because later it would cause iframes to reload 18665 onReady : function (opts, obj) { 18666 $('.fancybox-overlay').stop(true, true); 18667 18668 if (!this.overlay) { 18669 this.margin = D.height() > W.height() || $('body').css('overflow-y') === 'scroll' ? $('body').css('margin-right') : false; 18670 this.el = document.all && !document.querySelector ? $('html') : $('body'); 18671 18672 this.create(opts); 18673 } 18674 18675 if (opts.locked && this.fixed) { 18676 obj.locked = this.overlay.append( obj.wrap ); 18677 obj.fixed = false; 18678 } 18679 18680 if (opts.showEarly === true) { 18681 this.beforeShow.apply(this, arguments); 18682 } 18683 }, 18684 18685 beforeShow : function(opts, obj) { 18686 if (obj.locked) { 18687 this.el.addClass('fancybox-lock'); 18688 18689 if (this.margin !== false) { 18690 $('body').css('margin-right', getScalar( this.margin ) + obj.scrollbarWidth); 18691 } 18692 } 18693 18694 this.open(opts); 18695 }, 18696 18697 onUpdate : function() { 18698 if (!this.fixed) { 18699 this.update(); 18700 } 18701 }, 18702 18703 afterClose: function (opts) { 18704 // Remove overlay if exists and fancyBox is not opening 18705 // (e.g., it is not being open using afterClose callback) 18706 if (this.overlay && !F.isActive) { 18707 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 18708 } 18709 } 18710 }; 18711 18712 /* 18713 * Title helper 18714 */ 18715 18716 F.helpers.title = { 18717 defaults : { 18718 type : 'float', // 'float', 'inside', 'outside' or 'over', 18719 position : 'bottom' // 'top' or 'bottom' 18720 }, 18721 18722 beforeShow: function (opts) { 18723 var current = F.current, 18724 text = current.title, 18725 type = opts.type, 18726 title, 18727 target; 18728 18729 if ($.isFunction(text)) { 18730 text = text.call(current.element, current); 18731 } 18732 18733 if (!isString(text) || $.trim(text) === '') { 18734 return; 18735 } 18736 18737 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
18737' + text + '</div>'); 18738 18739 switch (type) { 18740 case 'inside': 18741 target = F.skin; 18742 break; 18743 18744 case 'outside': 18745 target = F.wrap; 18746 break; 18747 18748 case 'over': 18749 target = F.inner; 18750 break; 18751 18752 default: // 'float' 18753 target = F.skin; 18754 18755 title.appendTo('body'); 18756 18757 if (IE) { 18758 title.width( title.width() ); 18759 } 18760 18761 title.wrapInner('<span class="child"></span>'); 18762 18763 //Increase bottom margin so this title will also fit into viewport 18764 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 18765 break; 18766 } 18767 18768 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 18769 } 18770 }; 18771 18772 // jQuery plugin initialization 18773 $.fn.fancybox = function (options) { 18774 var index, 18775 that = $(this), 18776 selector = this.selector || '', 18777 run = function(e) { 18778 var what = $(this).blur(), idx = index, relType, relVal; 18779 18780 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 18781 relType = options.groupAttr || 'data-fancybox-group'; 18782 relVal = what.attr(relType); 18783 18784 if (!relVal) { 18785 relType = 'rel'; 18786 relVal = what.get(0)[ relType ]; 18787 } 18788 18789 if (relVal && relVal !== '' && relVal !== 'nofollow') { 18790 what = selector.length ? $(selector) : that; 18791 what = what.filter('[' + relType + '="' + relVal + '"]'); 18792 idx = what.index(this); 18793 } 18794 18795 options.index = idx; 18796 18797 // Stop an event from bubbling if everything is fine 18798 if (F.open(what, options) !== false) { 18799 e.preventDefault(); 18800 } 18801 } 18802 }; 18803 18804 options = options || {}; 18805 index = options.index || 0; 18806 18807 if (!selector || options.live === false) { 18808 that.unbind('click.fb-start').bind('click.fb-start', run); 18809 18810 } else { 18811 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 18812 } 18813 18814 this.filter('[data-fancybox-start=1]').trigger('click'); 18815 18816 return this; 18817 }; 18818 18819 // Tests that need a body at doc ready 18820 D.ready(function() { 18821 if ( $.scrollbarWidth === undefined ) { 18822 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 18823 $.scrollbarWidth = function() { 18824 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 18825 child = parent.children(), 18826 width = child.innerWidth() - child.height( 99 ).innerWidth(); 18827 18828 parent.remove(); 18829 18830 return width; 18831 }; 18832 } 18833 18834 if ( $.support.fixedPosition === undefined ) { 18835 $.support.fixedPosition = (function() { 18836 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 18837 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 18838 18839 elem.remove(); 18840 18841 return fixed; 18842 }()); 18843 } 18844 18845 $.extend(F.defaults, { 18846 scrollbarWidth : $.scrollbarWidth(), 18847 fixed : $.support.fixedPosition, 18848 parent : $('body') 18849 }); 18850 }); 18851 18852}(window, document, jQuery)); 18853(function(c){function g(b,a){this.element=b;this.options=c.extend({},h,a);c(this.element).data("max-height",this.options.maxHeight);c(this.element).data("height-margin",this.options.heightMargin);delete this.options.maxHeight;if(this.options.embedCSS&&!k){var d=".readmore-js-toggle, .readmore-js-section { "+this.options.sectionCSS+" } .readmore-js-section { overflow: hidden; }",e=document.createElement("style");e.type="text/css";e.styleSheet?e.styleSheet.cssText=d:e.appendChild(document.createTextNode(d)); 18854document.getElementsByTagName("head")[0].appendChild(e);k=!0}this._defaults=h;this._name=f;this.init()}var f="readmore",h={speed:100,maxHeight:200,heightMargin:16,moreLink:'<a href="#">Read More</a>',lessLink:'<a href="#">Close</a>',embedCSS:!0,sectionCSS:"display: block; width: 100%;",startOpen:!1,expandedClass:"readmore-js-expanded",collapsedClass:"readmore-js-collapsed",beforeToggle:function(){},afterToggle:function(){}},k=!1;g.prototype={init:function(){var b=this;c(this.element).each(function(){var a= 18855c(this),d=a.css("max-height").replace(/[^-\d\.]/g,"")>a.data("max-height")?a.css("max-height").replace(/[^-\d\.]/g,""):a.data("max-height"),e=a.data("height-margin");"none"!=a.css("max-height")&&a.css("max-height","none");b.setBoxHeight(a);if(a.outerHeight(!0)<=d+e)return!0;a.addClass("readmore-js-section "+b.options.collapsedClass).data("c
18855ollapsedHeight",d);a.after(c(b.options.startOpen?b.options.lessLink:b.options.moreLink).on("click",function(c){b.toggleSlider(this,a,c)}).addClass("readmore-js-toggle")); 18856b.options.startOpen||a.css({height:d})});c(window).on("resize",function(a){b.resizeBoxes()})},toggleSlider:function(b,a,d){d.preventDefault();var e=this;d=newLink=sectionClass="";var f=!1;d=c(a).data("collapsedHeight");c(a).height()<=d?(d=c(a).data("expandedHeight")+"px",newLink="lessLink",f=!0,sectionClass=e.options.expandedClass):(newLink="moreLink",sectionClass=e.options.collapsedClass);e.options.beforeToggle(b,a,f);c(a).animate({height:d},{duration:e.options.speed,complete:function(){e.options.afterToggle(b, 18857a,f);c(b).replaceWith(c(e.options[newLink]).on("click",function(b){e.toggleSlider(this,a,b)}).addClass("readmore-js-toggle"));c(this).removeClass(e.options.collapsedClass+" "+e.options.expandedClass).addClass(sectionClass)}})},setBoxHeight:function(b){var a=b.clone().css({height:"auto",width:b.width(),overflow:"hidden"}).insertAfter(b),c=a.outerHeight(!0);a.remove();b.data("expandedHeight",c)},resizeBoxes:function(){var b=this;c(".readmore-js-section").each(function(){var a=c(this);b.setBoxHeight(a); 18858(a.height()>a.data("expandedHeight")||a.hasClass(b.options.expandedClass)&&a.height()<a.data("expandedHeight"))&&a.css("height",a.data("expandedHeight"))})},destroy:function(){var b=this;c(this.element).each(function(){var a=c(this);a.removeClass("readmore-js-section "+b.options.collapsedClass+" "+b.options.expandedClass).css({"max-height":"",height:"auto"}).next(".readmore-js-toggle").remove();a.removeData()})}};c.fn[f]=function(b){var a=arguments;if(void 0===b||"object"===typeof b)return this.each(function(){if(c.data(this, 18859"plugin_"+f)){var a=c.data(this,"plugin_"+f);a.destroy.apply(a)}c.data(this,"plugin_"+f,new g(this,b))});if("string"===typeof b&&"_"!==b[0]&&"init"!==b)return this.each(function(){var d=c.data(this,"plugin_"+f);d instanceof g&&"function"===typeof d[b]&&d[b].apply(d,Array.prototype.slice.call(a,1))})}})(jQuery); 18860Rcms = { 18861 navigation: { 18862 highlightCurrent: function() { 18863 $('[data-nav]').each(function() { 18864 var type = $(this).attr('data-type'); 18865 var id = $(this).attr('data-id'); 18866 var link = $('li[data-type="' + type + '"][data-id="' + id + '"]', this); 18867 if (link.length > 0) { 18868 link.addClass('active'); 18869 Rcms.navigation.highlightParents(link); 18870 } 18871 }); 18872 }, 18873 highlightParents: function(current) { 18874 _self = this; 18875 $(current).parents('li').each(function() { 18876 $(this).addClass('active'); 18877 _self.highlightParents(this); 18878 }); 18879 } 18880 } 18881} 18882; 18883function formFieldsToObj(selector) { 18884 return $('.filter').serializeArray().filter(function(item){ return item.value !== ""; }).reduce(function(m,o){ m[o.name] = o.value; return m; }, {}); 18885} 18886 18887// highlight the current page 18888Rcms.navigation.highlightCurrent(); 18889$().prettyEmbed(); 18890$(document).ready(function() { 18891 $('.fancybox-video').fancybox({ 18892 minWidth: 560, 18893 minHeight: 330, 18894 padding: 20 18895 }); 18896 18897 $('.fancybox-overlay').click(function() { 18898 $.fancybox.close(); 18899 }); 18900 18901 $('#featuredContent').orbit({ 18902 animation: 'horizontal-push', 18903 timer: true, 18904 advanceSpeed: 6000 18905 }); 18906 18907 var $slideshow = $("#programSlideshow"); 18908 var $dragged = $("#programSlideshow ul"); 18909 18910 // narrows program slideshow width to content 18911 var comP = 0; 18912 $dragged.find("img").each(function() { 18913 comP += parseInt($(this).attr('width')); 18914 }); 18915 $dragged.css("width", comP); 18916 18917 $slideshow.overscroll({ 18918 scrollLeft: 0, 18919 scrollTop: 0, 18920 direction: "horizontal", 18921 wheelDirection: "horizontal", 18922 wheelDelta: 80, 18923 scrollDelta: 5.7 18924 }); 18925 18926 $("#grab").fadeTo(250,1); 18927 18928 $("#programSlideshow ul, #grab").mousedown(function(){ 18929 $("#grab").fadeTo(200,0, function(){$(this).css("top","-5000px");}); 18930 }); 18931 18932 if ($("body").hasClass("mobile")) { 18933 $("#grab").hide(); 18934 } 18935 18936 $('.expandable').readmore({ 18937 maxHeight: 198, 18938 lessLink: '<a href="#">Show Less</a>' 18939 }); 18940 18941}); 18942 18943// filter 18944var $filter = $('.filter'); 18945function catchClicksToRemoveFilterMenus() { 18946 $('.filter__values.active').removeClass('active'); 18947 document.removeEventListener('click', catchClicksToRemoveFilterMenus); 18948 document.removeEventListener('touchstart', catchClicksToRemoveFilterMenus); 18949} 18950 18951function handleFilterValueChoice(evt) { 18952 var $this = $(this); 18953 var $currentVal = $this.parents('.filter__option').find('.filter__current-value'); 18954 var $input = $this.parents('.filter__option').find('.filter__input'); 18955 18956 if ($currentVal.html() === $this.html()) { 18957 catchClicksToRemoveFilterMenus(); 18958 return false;
18959 } 18960 18961 $currentVal.html($this.html()); 18962 $input.val($this.attr('data-value')); 18963 catchClicksToRemoveFilterMenus(); 18964 $filter.submit(); 18965 $('.filter :input[value=""]').removeAttr('disabled'); 18966 evt.stopPropagation(); 18967} 18968 18969if ($filter) { 18970 $filter.submit(function () { 18971 $(this).find(':input[value=""]').attr('disabled', 'disabled'); 18972 return true; 18973 }); 18974 18975 $('.filter__current-value').click(function (evt) { 18976 var $this = $(this); 18977 var $values = $this.find('~ .filter__values'); 18978 if ($values.hasClass('active')) { 18979 catchClicksToRemoveFilterMenus(); 18980 } else { 18981 $filter.find('.filter__values').each(function () { 18982 $(this).removeClass('active'); 18983 }); 18984 $values.addClass('active'); 18985 document.addEventListener('click', catchClicksToRemoveFilterMenus); 18986 document.addEventListener('touchstart', catchClicksToRemoveFilterMenus); 18987 evt.stopPropagation(); 18988 } 18989 }); 18990 18991 $('.filter__value').bind('click', handleFilterValueChoice); 18992 $('.filter__value').bind('touchstart', handleFilterValueChoice); 18993 18994 $('.filter__values__content').each(function () { 18995 if (parseInt($(this).css('height')) >= parseInt($(this).css('max-height'))) { 18996 $(this).parent().append('<div class="filter__more active"></div>'); 18997 } 18998 18999 $(this).bind('scroll', function () { 19000 $arrow = $(this).parent().find('.filter__more'); 19001 19002 if (this.offsetHeight + this.scrollTop >= this.scrollHeight) { 19003 $arrow.removeClass('active'); 19004 } else { 19005 if (!$arrow.hasClass('active')) { 19006 $arrow.addClass('active'); 19007 } 19008 } 19009 }); 19010 }); 19011} 19012; 19013// This is a manifest file that'll be compiled into application.js, which will include all the files 19014// listed below. 19015// 19016// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 19017// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. 19018// 19019// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 19020// the compiled file. 19021// 19022// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD 19023// GO AFTER THE REQUIRES BELOW. 19024// 19025 19026 19027 19028 19029 19030 19031 19032 19033 19034 19035 19036 19037 19038 19039 19040 19041 19042;
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.