vendor: 4,698 bytes, lines 1-182
1/*! 2 * jQuery JavaScript Library v2.1.4 3 * http://jquery.com/ 4 * 5 * Includes Sizzle.js 6 * http://sizzlejs.com/ 7 * 8 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors 9 * Released under the MIT license 10 * http://jquery.org/license 11 * 12 * Date: 2015-04-28T16:01Z 13 */ 14 15(function( global, factory ) { 16 17 if ( typeof module === "object" && typeof module.exports === "object" ) { 18 // For CommonJS and CommonJS-like environments where a proper `window` 19 // is present, execute the factory and get jQuery. 20 // For environments that do not have a `window` with a `document` 21 // (such as Node.js), expose a factory as module.exports. 22 // This accentuates the need for the creation of a real `window`. 23 // e.g. var jQuery = require("jquery")(window); 24 // See ticket #14549 for more info. 25 module.exports = global.document ? 26 factory( global, true ) : 27 function( w ) { 28 if ( !w.document ) { 29 throw new Error( "jQuery requires a window with a document" ); 30 } 31 return factory( w ); 32 }; 33 } else { 34 factory( global ); 35 } 36 37// Pass this if window is not defined yet 38}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 39 40// Support: Firefox 18+ 41// Can't be in strict mode, several libs including ASP.NET trace 42// the stack via arguments.caller.callee and Firefox dies if 43// you try to trace through "use strict" call chains. (#13335) 44// 45 46var arr = []; 47 48var slice = arr.slice; 49 50var concat = arr.concat; 51 52var push = arr.push; 53 54var indexOf = arr.indexOf; 55 56var class2type = {}; 57 58var toString = class2type.toString; 59 60var hasOwn = class2type.hasOwnProperty; 61 62var support = {}; 63 64 65 66var 67 // Use the correct document accordingly with window argument (sandbox) 68 document = window.document, 69 70 version = "2.1.4", 71 72 // Define a local copy of jQuery 73 jQuery = function( selector, context ) { 74 // The jQuery object is actually just the init constructor 'enhanced' 75 // Need init if jQuery is called (just allow error to be thrown if not included) 76 return new jQuery.fn.init( selector, context ); 77 }, 78 79 // Support: Android<4.1 80 // Make sure we trim BOM and NBSP 81 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, 82 83 // Matches dashed string for camelizing 84 rmsPrefix = /^-ms-/, 85 rdashAlpha = /-([\da-z])/gi, 86 87 // Used by jQuery.camelCase as callback to replace() 88 fcamelCase = function( all, letter ) { 89 return letter.toUpperCase(); 90 }; 91 92jQuery.fn = jQuery.prototype = { 93 // The current version of jQuery being used 94 jquery: version, 95 96 constructor: jQuery, 97 98 // Start with an empty selector 99 selector: "", 100 101 // The default length of a jQuery object is 0 102 length: 0, 103 104 toArray: function() { 105 return slice.call( this ); 106 }, 107 108 // Get the Nth element in the matched element set OR 109 // Get the whole matched element set as a clean array 110 get: function( num ) { 111 return num != null ? 112 113 // Return just the one element from the set 114 ( num < 0 ? this[ num + this.length ] : this[ num ] ) : 115 116 // Return all the elements in a clean array 117 slice.call( this ); 118 }, 119 120 // Take an array of elements and push it onto the stack 121 // (returning the new matched element set) 122 pushStack: function( elems ) { 123 124 // Build a new jQuery matched element set 125 var ret = jQuery.merge( this.constructor(), elems ); 126 127 // Add the old object onto the stack (as a reference) 128 ret.prevObject = this; 129 ret.context = this.context; 130 131 // Return the newly-formed element set 132 return ret; 133 }, 134 135 // Execute a callback for every element in the matched set. 136 // (You can seed the arguments with an array of args, but this is 137 // only used internally.) 138 each: function( callback, args ) { 139 return jQuery.each( this, callback, args ); 140 }, 141 142 map: function( callback ) { 143 return this.pushStack( jQuery.map(this, function( elem, i ) { 144 return callback.call( elem, i, elem ); 145 })); 146 }, 147 148 slice: function() { 149 return this.pushStack( slice.apply( this, arguments ) ); 150 }, 151 152 first: function() { 153 return this.eq( 0 ); 154 }, 155 156 last: function() { 157 return this.eq( -1 ); 158 }, 159 160 eq: function( i ) { 161 var len = this.length, 162 j = +i + ( i < 0 ? len : 0 ); 163 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); 164 }, 165 166 end: function() { 167 return this.prevObject || this.constructor(null); 168 }, 169 170 // For internal use only. 171 // Behaves like an Array's method, not like a jQuery method. 172 push: push, 173 sort: arr.sort, 174 splice: arr.splice 175}; 176 177jQuery.extend = jQuery.fn.extend = function() { 178 var options, name, src, copy, copyIsArray, clone, 179 target = arguments[0] || {}, 180 i = 1, 181 length = arguments.length, 182 deep = false;
183 184 // Handle a deep copy situation 185 if ( typeof target === "boolean" ) { 186 deep = target; 187 188 // Skip the boolean and the target 189 target = arguments[ i ] || {}; 190 i++; 191 } 192 193 // Handle case when target is a string or something (possible in deep copy) 194 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 195 target = {}; 196 } 197 198 // Extend jQuery itself if only one argument is passed 199 if ( i === length ) { 200 target = this; 201 i--; 202 } 203 204 for ( ; i < length; i++ ) { 205 // Only deal with non-null/undefined values 206 if ( (options = arguments[ i ]) != null ) { 207 // Extend the base object 208 for ( name in options ) { 209 src = target[ name ]; 210 copy = options[ name ]; 211 212 // Prevent never-ending loop 213 if ( target === copy ) { 214 continue; 215 } 216 217 // Recurse if we're merging plain objects or arrays 218 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 219 if ( copyIsArray ) { 220 copyIsArray = false; 221 clone = src && jQuery.isArray(src) ? src : []; 222 223 } else { 224 clone = src && jQuery.isPlainObject(src) ? src : {}; 225 } 226 227 // Never move original objects, clone them 228 target[ name ] = jQuery.extend( deep, clone, copy ); 229 230 // Don't bring in undefined values 231 } else if ( copy !== undefined ) { 232 target[ name ] = copy; 233 } 234 } 235 } 236 } 237 238 // Return the modified object 239 return target; 240}; 241 242jQuery.extend({ 243 // Unique for each copy of jQuery on the page 244 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 245 246 // Assume jQuery is ready without the ready module 247 isReady: true, 248 249 error: function( msg ) { 250 throw new Error( msg ); 251 }, 252 253 noop: function() {}, 254 255 isFunction: function( obj ) { 256 return jQuery.type(obj) === "function"; 257 }, 258 259 isArray: Array.isArray, 260 261 isWindow: function( obj ) { 262 return obj != null && obj === obj.window; 263 }, 264 265 isNumeric: function( obj ) { 266 // parseFloat NaNs numeric-cast false positives (null|true|false|"") 267 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 268 // subtraction forces infinities to NaN 269 // adding 1 corrects loss of precision from parseFloat (#15100) 270 return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; 271 }, 272 273 isPlainObject: function( obj ) { 274 // Not plain objects: 275 // - Any object or value whose internal [[Class]] property is not "[object Object]" 276 // - DOM nodes 277 // - window 278 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { 279 return false; 280 } 281 282 if ( obj.constructor && 283 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { 284 return false; 285 } 286 287 // If the function hasn't returned already, we're confident that 288 // |obj| is a plain object, created by {} or constructed with new Object 289 return true; 290 }, 291 292 isEmptyObject: function( obj ) { 293 var name; 294 for ( name in obj ) { 295 return false; 296 } 297 return true; 298 }, 299 300 type: function( obj ) { 301 if ( obj == null ) { 302 return obj + ""; 303 } 304 // Support: Android<4.0, iOS<6 (functionish RegExp) 305 return typeof obj === "object" || typeof obj === "function" ? 306 class2type[ toString.call(obj) ] || "object" : 307 typeof obj; 308 }, 309 310 // Evaluates a script in a global context 311 globalEval: function( code ) { 312 var script, 313 indirect = eval; 314 315 code = jQuery.trim( code ); 316 317 if ( code ) { 318 // If the code includes a valid, prologue position 319 // strict mode pragma, execute code by injecting a 320 // script tag into the document. 321 if ( code.indexOf("use strict") === 1 ) { 322 script = document.createElement("script"); 323 script.text = code; 324 document.head.appendChild( script ).parentNode.removeChild( script ); 325 } else { 326 // Otherwise, avoid the DOM node creation, insertion 327 // and removal by using an indirect global eval 328 indirect( code ); 329 } 330 } 331 }, 332 333 // Convert dashed to camelCase; used by the css and data modules
334 // Support: IE9-11+ 335 // Microsoft forgot to hump their vendor prefix (#9572) 336 camelCase: function( string ) { 337 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 338 }, 339 340 nodeName: function( elem, name ) { 341 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 342 }, 343 344 // args is for internal usage only 345 each: function( obj, callback, args ) { 346 var value, 347 i = 0, 348 length = obj.length, 349 isArray = isArraylike( obj ); 350 351 if ( args ) { 352 if ( isArray ) { 353 for ( ; i < length; i++ ) { 354 value = callback.apply( obj[ i ], args ); 355 356 if ( value === false ) { 357 break; 358 } 359 } 360 } else { 361 for ( i in obj ) { 362 value = callback.apply( obj[ i ], args ); 363 364 if ( value === false ) { 365 break; 366 } 367 } 368 } 369 370 // A special, fast, case for the most common use of each 371 } else { 372 if ( isArray ) { 373 for ( ; i < length; i++ ) { 374 value = callback.call( obj[ i ], i, obj[ i ] ); 375 376 if ( value === false ) { 377 break; 378 } 379 } 380 } else { 381 for ( i in obj ) { 382 value = callback.call( obj[ i ], i, obj[ i ] ); 383 384 if ( value === false ) { 385 break; 386 } 387 } 388 } 389 } 390 391 return obj; 392 }, 393 394 // Support: Android<4.1 395 trim: function( text ) { 396 return text == null ? 397 "" : 398 ( text + "" ).replace( rtrim, "" ); 399 }, 400 401 // results is for internal usage only 402 makeArray: function( arr, results ) { 403 var ret = results || []; 404 405 if ( arr != null ) { 406 if ( isArraylike( Object(arr) ) ) { 407 jQuery.merge( ret, 408 typeof arr === "string" ? 409 [ arr ] : arr 410 ); 411 } else { 412 push.call( ret, arr ); 413 } 414 } 415 416 return ret; 417 }, 418 419 inArray: function( elem, arr, i ) { 420 return arr == null ? -1 : indexOf.call( arr, elem, i ); 421 }, 422 423 merge: function( first, second ) { 424 var len = +second.length, 425 j = 0, 426 i = first.length; 427 428 for ( ; j < len; j++ ) { 429 first[ i++ ] = second[ j ]; 430 } 431 432 first.length = i; 433 434 return first; 435 }, 436 437 grep: function( elems, callback, invert ) { 438 var callbackInverse, 439 matches = [], 440 i = 0, 441 length = elems.length, 442 callbackExpect = !invert; 443 444 // Go through the array, only saving the items 445 // that pass the validator function 446 for ( ; i < length; i++ ) { 447 callbackInverse = !callback( elems[ i ], i ); 448 if ( callbackInverse !== callbackExpect ) { 449 matches.push( elems[ i ] ); 450 } 451 } 452 453 return matches; 454 }, 455 456 // arg is for internal usage only 457 map: function( elems, callback, arg ) { 458 var value, 459 i = 0, 460 length = elems.length, 461 isArray = isArraylike( elems ), 462 ret = []; 463 464 // Go through the array, translating each of the items to their new values 465 if ( isArray ) { 466 for ( ; i < length; i++ ) { 467 value = callback( elems[ i ], i, arg ); 468 469 if ( value != null ) { 470 ret.push( value ); 471 } 472 } 473 474 // Go through every key on the object, 475 } else { 476 for ( i in elems ) { 477 value = callback( elems[ i ], i, arg ); 478 479 if ( value != null ) { 480 ret.push( value ); 481 } 482 } 483 } 484 485 // Flatten any nested arrays 486 return concat.apply( [], ret ); 487 }, 488 489 // A global GUID counter for objects 490 guid: 1, 491 492 // Bind a function to a context, optionally partially applying any 493 // arguments. 494 proxy: function( fn, context ) { 495 var tmp, args, proxy; 496 497 if ( typeof context === "string" ) { 498 tmp = fn[ context ]; 499 context = fn; 500 fn = tmp; 501 } 502 503 // Quick check to determine if target is callable, in the spec 504 // this throws a TypeError, but we will just return undefined. 505 if ( !jQuery.isFunction( fn ) ) { 506 return undefined; 507 } 508 509 // Simulated bind 510 args = slice.call( arguments, 2 ); 511 proxy = function() { 512 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 513 }; 514 515 // Set the guid of unique handler to the same of original handler, so it can be removed 516 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 517 518 return proxy; 519 }, 520 521 now: Date.now, 522 523 // jQuery.support is not used in Core but other projects attach their 524 // properties to it so it needs to exist. 525 support: support 526}); 527 528// Populate the class2type map 529jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 530 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 531}); 532 533function isArraylike( obj ) { 534
vendor: 5,493 bytes, lines 535-701
535 // Support: iOS 8.2 (not reproducible in simulator) 536 // `in` check used to prevent JIT error (gh-2145) 537 // hasOwn isn't used here due to false negatives 538 // regarding Nodelist length in IE 539 var length = "length" in obj && obj.length, 540 type = jQuery.type( obj ); 541 542 if ( type === "function" || jQuery.isWindow( obj ) ) { 543 return false; 544 } 545 546 if ( obj.nodeType === 1 && length ) { 547 return true; 548 } 549 550 return type === "array" || length === 0 || 551 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 552} 553var Sizzle = 554/*! 555 * Sizzle CSS Selector Engine v2.2.0-pre 556 * http://sizzlejs.com/ 557 * 558 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors 559 * Released under the MIT license 560 * http://jquery.org/license 561 * 562 * Date: 2014-12-16 563 */ 564(function( window ) { 565 566var i, 567 support, 568 Expr, 569 getText, 570 isXML, 571 tokenize, 572 compile, 573 select, 574 outermostContext, 575 sortInput, 576 hasDuplicate, 577 578 // Local document vars 579 setDocument, 580 document, 581 docElem, 582 documentIsHTML, 583 rbuggyQSA, 584 rbuggyMatches, 585 matches, 586 contains, 587 588 // Instance-specific data 589 expando = "sizzle" + 1 * new Date(), 590 preferredDoc = window.document, 591 dirruns = 0, 592 done = 0, 593 classCache = createCache(), 594 tokenCache = createCache(), 595 compilerCache = createCache(), 596 sortOrder = function( a, b ) { 597 if ( a === b ) { 598 hasDuplicate = true; 599 } 600 return 0; 601 }, 602 603 // General-purpose constants 604 MAX_NEGATIVE = 1 << 31, 605 606 // Instance methods 607 hasOwn = ({}).hasOwnProperty, 608 arr = [], 609 pop = arr.pop, 610 push_native = arr.push, 611 push = arr.push, 612 slice = arr.slice, 613 // Use a stripped-down indexOf as it's faster than native 614 // http://jsperf.com/thor-indexof-vs-for/5 615 indexOf = function( list, elem ) { 616 var i = 0, 617 len = list.length; 618 for ( ; i < len; i++ ) { 619 if ( list[i] === elem ) { 620 return i; 621 } 622 } 623 return -1; 624 }, 625 626 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 627 628 // Regular expressions 629 630 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace 631 whitespace = "[\\x20\\t\\r\\n\\f]", 632 // http://www.w3.org/TR/css3-syntax/#characters 633 characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", 634 635 // Loosely modeled on CSS identifier characters 636 // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors 637 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 638 identifier = characterEncoding.replace( "w", "w#" ), 639 640 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 641 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + 642 // Operator (capture 2) 643 "*([*^$|!~]?=)" + whitespace + 644 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 645 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 646 "*\\]", 647 648 pseudos = ":(" + characterEncoding + ")(?:\\((" + 649 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 650 // 1. quoted (capture 3; capture 4 or capture 5) 651 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 652 // 2. simple (capture 6) 653 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 654 // 3. anything else (capture 2) 655 ".*" + 656 ")\\)|)", 657 658 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 659 rwhitespace = new RegExp( whitespace + "+", "g" ), 660 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 661 662 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 663 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 664 665 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), 666 667 rpseudo = new RegExp( pseudos ), 668 ridentifier = new RegExp( "^" + identifier + "$" ), 669 670 matchExpr = { 671 "ID": new RegExp( "^#(" + characterEncoding + ")" ), 672 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), 673 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), 674 "ATTR": new RegExp( "^" + attributes ), 675 "PSEUDO": new RegExp( "^" + pseudos ), 676 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 677 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 678 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 679 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 680 // For use in libraries implementing .is() 681 // We use this for POS matching in `select` 682 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 683 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 684 }, 685 686 rinputs = /^(?:input|select|textarea|button)$/i, 687 rheader = /^h\d$/i, 688 689 rnative = /^[^{]+\{\s*\[native \w/, 690 691 // Easily-parseable/retrievable ID or TAG or CLASS selectors 692 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 693 694 rsibling = /[+~]/, 695 rescape = /'|\\/g, 696 697 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 698 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 699 funescape = function( _, escaped, escapedWhitespace ) { 700 var high = "0x" + escaped - 0x10000; 701 // NaN means non-codepoint
702 // Support: Firefox<24 703 // Workaround erroneous numeric interpretation of +"0x" 704 return high !== high || escapedWhitespace ? 705 escaped : 706 high < 0 ? 707 // BMP codepoint 708 String.fromCharCode( high + 0x10000 ) : 709 // Supplemental Plane codepoint (surrogate pair) 710 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 711 }, 712 713 // Used for iframes 714 // See setDocument() 715 // Removing the function wrapper causes a "Permission Denied" 716 // error in IE 717 unloadHandler = function() { 718 setDocument(); 719 }; 720 721// Optimize for push.apply( _, NodeList ) 722try { 723 push.apply( 724 (arr = slice.call( preferredDoc.childNodes )), 725 preferredDoc.childNodes 726 ); 727 // Support: Android<4.0 728 // Detect silently failing push.apply 729 arr[ preferredDoc.childNodes.length ].nodeType; 730} catch ( e ) { 731 push = { apply: arr.length ? 732 733 // Leverage slice if possible 734 function( target, els ) { 735 push_native.apply( target, slice.call(els) ); 736 } : 737 738 // Support: IE<9 739 // Otherwise append directly 740 function( target, els ) { 741 var j = target.length, 742 i = 0; 743 // Can't trust NodeList.length 744 while ( (target[j++] = els[i++]) ) {} 745 target.length = j - 1; 746 } 747 }; 748} 749 750function Sizzle( selector, context, results, seed ) { 751 var match, elem, m, nodeType, 752 // QSA vars 753 i, groups, old, nid, newContext, newSelector; 754 755 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 756 setDocument( context ); 757 } 758 759 context = context || document; 760 results = results || []; 761 nodeType = context.nodeType; 762 763 if ( typeof selector !== "string" || !selector || 764 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 765 766 return results; 767 } 768 769 if ( !seed && documentIsHTML ) { 770 771 // Try to shortcut find operations when possible (e.g., not under DocumentFragment) 772 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 773 // Speed-up: Sizzle("#ID") 774 if ( (m = match[1]) ) { 775 if ( nodeType === 9 ) { 776 elem = context.getElementById( m ); 777 // Check parentNode to catch when Blackberry 4.6 returns 778 // nodes that are no longer in the document (jQuery #6963) 779 if ( elem && elem.parentNode ) { 780 // Handle the case where IE, Opera, and Webkit return items 781 // by name instead of ID 782 if ( elem.id === m ) { 783 results.push( elem ); 784 return results; 785 } 786 } else { 787 return results; 788 } 789 } else { 790 // Context is not a document 791 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && 792 contains( context, elem ) && elem.id === m ) { 793 results.push( elem ); 794 return results; 795 } 796 } 797 798 // Speed-up: Sizzle("TAG") 799 } else if ( match[2] ) { 800 push.apply( results, context.getElementsByTagName( selector ) ); 801 return results; 802 803 // Speed-up: Sizzle(".CLASS") 804 } else if ( (m = match[3]) && support.getElementsByClassName ) { 805 push.apply( results, context.getElementsByClassName( m ) ); 806 return results; 807 } 808 } 809 810 // QSA path 811 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { 812 nid = old = expando; 813 newContext = context; 814 newSelector = nodeType !== 1 && selector; 815 816 // qSA works strangely on Element-rooted queries 817 // We can work around this by specifying an extra ID on the root 818 // and working up from there (Thanks to Andrew Dupont for the technique) 819 // IE 8 doesn't work on object elements 820 if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { 821 groups = tokenize( selector ); 822 823 if ( (old = context.getAttribute("id")) ) { 824 nid = old.replace( rescape, "\\$&" ); 825 } else { 826 context.setAttribute( "id", nid ); 827 } 828 nid = "[id='" + nid + "'] "; 829 830 i = groups.length; 831 while ( i-- ) { 832 groups[i] = nid + toSelector( groups[i] ); 833 }
vendor: 56,408 bytes, lines 834-2684
834 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; 835 newSelector = groups.join(","); 836 } 837 838 if ( newSelector ) { 839 try { 840 push.apply( results, 841 newContext.querySelectorAll( newSelector ) 842 ); 843 return results; 844 } catch(qsaError) { 845 } finally { 846 if ( !old ) { 847 context.removeAttribute("id"); 848 } 849 } 850 } 851 } 852 } 853 854 // All others 855 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 856} 857 858/** 859 * Create key-value caches of limited size 860 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with 861 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 862 * deleting the oldest entry 863 */ 864function createCache() { 865 var keys = []; 866 867 function cache( key, value ) { 868 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 869 if ( keys.push( key + " " ) > Expr.cacheLength ) { 870 // Only keep the most recent entries 871 delete cache[ keys.shift() ]; 872 } 873 return (cache[ key + " " ] = value); 874 } 875 return cache; 876} 877 878/** 879 * Mark a function for special use by Sizzle 880 * @param {Function} fn The function to mark 881 */ 882function markFunction( fn ) { 883 fn[ expando ] = true; 884 return fn; 885} 886 887/** 888 * Support testing using an element 889 * @param {Function} fn Passed the created div and expects a boolean result 890 */ 891function assert( fn ) { 892 var div = document.createElement("div"); 893 894 try { 895 return !!fn( div ); 896 } catch (e) { 897 return false; 898 } finally { 899 // Remove from its parent by default 900 if ( div.parentNode ) { 901 div.parentNode.removeChild( div ); 902 } 903 // release memory in IE 904 div = null; 905 } 906} 907 908/** 909 * Adds the same handler for all of the specified attrs 910 * @param {String} attrs Pipe-separated list of attributes 911 * @param {Function} handler The method that will be applied 912 */ 913function addHandle( attrs, handler ) { 914 var arr = attrs.split("|"), 915 i = attrs.length; 916 917 while ( i-- ) { 918 Expr.attrHandle[ arr[i] ] = handler; 919 } 920} 921 922/** 923 * Checks document order of two siblings 924 * @param {Element} a 925 * @param {Element} b 926 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 927 */ 928function siblingCheck( a, b ) { 929 var cur = b && a, 930 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 931 ( ~b.sourceIndex || MAX_NEGATIVE ) - 932 ( ~a.sourceIndex || MAX_NEGATIVE ); 933 934 // Use IE sourceIndex if available on both nodes 935 if ( diff ) { 936 return diff; 937 } 938 939 // Check if b follows a 940 if ( cur ) { 941 while ( (cur = cur.nextSibling) ) { 942 if ( cur === b ) { 943 return -1; 944 } 945 } 946 } 947 948 return a ? 1 : -1; 949} 950 951/** 952 * Returns a function to use in pseudos for input types 953 * @param {String} type 954 */ 955function createInputPseudo( type ) { 956 return function( elem ) { 957 var name = elem.nodeName.toLowerCase(); 958 return name === "input" && elem.type === type; 959 }; 960} 961 962/** 963 * Returns a function to use in pseudos for buttons 964 * @param {String} type 965 */ 966function createButtonPseudo( type ) { 967 return function( elem ) { 968 var name = elem.nodeName.toLowerCase(); 969 return (name === "input" || name === "button") && elem.type === type; 970 }; 971} 972 973/** 974 * Returns a function to use in pseudos for positionals 975 * @param {Function} fn 976 */ 977function createPositionalPseudo( fn ) { 978 return markFunction(function( argument ) { 979 argument = +argument; 980 return markFunction(function( seed, matches ) { 981 var j, 982 matchIndexes = fn( [], seed.length, argument ), 983 i = matchIndexes.length; 984 985 // Match elements found at the specified indexes 986 while ( i-- ) { 987 if ( seed[ (j = matchIndexes[i]) ] ) { 988 seed[j] = !(matches[j] = seed[j]); 989 } 990 } 991 }); 992 }); 993} 994 995/** 996 * Checks a node for validity as a Sizzle context 997 * @param {Element|Object=} context 998 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 999 */ 1000function testContext( context ) { 1001 return context && typeof context.getElementsByTagName !== "undefined" && context; 1002} 1003 1004// Expose support vars for convenience 1005support = Sizzle.support = {}; 1006 1007/** 1008 * Detects XML nodes 1009 * @param {Element|Object} elem An element or a document 1010 * @returns {Boolean} True iff elem is a non-HTML XML node 1011 */ 1012isXML = Sizzle.isXML = function( elem ) { 1013 // documentElement is verified for cases where it doesn't yet exist 1014 // (such as loading iframes in IE - #4833) 1015 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 1016 return documentElement ? documentElement.nodeName !== "HTML" : false; 1017}; 1018 1019/** 1020 * Sets document-related variables once based on the current document 1021 * @param {Element|Object} [doc] An element or document object to use to set the document 1022 * @returns {Object} Returns the current document 1023 */ 1024setDocument = Sizzle.setDocument = function( node ) { 1025 var hasCompare, parent, 1026 doc = node ? node.ownerDocument || node : preferredDoc; 1027 1028 // If no document and documentElement is available, return 1029 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 1030 return document; 1031 } 1032 1033 // Set our document 1034 document = doc; 1035 docElem = doc.documentElement; 1036 parent = doc.defaultView; 1037 1038 // Support: IE>8 1039 // If iframe document is assigned to "document" variable and if iframe has been reloaded, 1040 // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 1041 // IE6-8 do not support the defaultView property so parent will be undefined 1042 if ( parent && parent !== parent.top ) { 1043 // IE11 does not have attachEvent, so all must suffer 1044 if ( parent.addEventListener ) { 1045 parent.addEventListener( "unload", unloadHandler, false ); 1046 } else if ( parent.attachEvent ) { 1047 parent.attachEvent( "onunload", unloadHandler ); 1048 } 1049 } 1050 1051 /* Support tests 1052 ---------------------------------------------------------------------- */ 1053 documentIsHTML = !isXML( doc ); 1054 1055 /* Attributes 1056 ---------------------------------------------------------------------- */ 1057 1058 // Support: IE<8 1059 // Verify that getAttribute really returns attributes and not properties 1060 // (excepting IE8 booleans) 1061 support.attributes = assert(function( div ) { 1062 div.className = "i"; 1063 return !div.getAttribute("className"); 1064 }); 1065 1066 /* getElement(s)By* 1067 ---------------------------------------------------------------------- */ 1068 1069 // Check if getElementsByTagName("*") returns only elements 1070 support.getElementsByTagName = assert(function( div ) { 1071 div.appendChild( doc.createComment("") ); 1072 return !div.getElementsByTagName("*").length; 1073 }); 1074 1075 // Support: IE<9 1076 support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); 1077 1078 // Support: IE<10 1079 // Check if getElementById returns elements by name 1080 // The broken getElementById methods don't pick up programatically-set names, 1081 // so use a roundabout getElementsByName test 1082 support.getById = assert(function( div ) { 1083 docElem.appendChild( div ).id = expando; 1084 return !doc.getElementsByName || !doc.getElementsByName( expando ).length; 1085 }); 1086 1087 // ID find and filter 1088 if ( support.getById ) { 1089 Expr.find["ID"] = function( id, context ) { 1090 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1091 var m = context.getElementById( id ); 1092 // Check parentNode to catch when Blackberry 4.6 returns 1093 // nodes that are no longer in the document #6963 1094 return m && m.parentNode ? [ m ] : []; 1095 } 1096 }; 1097 Expr.filter["ID"] = function( id ) { 1098 var attrId = id.replace( runescape, funescape ); 1099 return function( elem ) { 1100 return elem.getAttribute("id") === attrId; 1101 }; 1102 }; 1103 } else { 1104 // Support: IE6/7 1105 // getElementById is not reliable as a find shortcut 1106 delete Expr.find["ID"]; 1107 1108 Expr.filter["ID"] = function( id ) { 1109 var attrId = id.replace( runescape, funescape ); 1110 return function( elem ) { 1111 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 1112 return node && node.value === attrId; 1113 }; 1114 }; 1115 } 1116 1117 // Tag 1118 Expr.find["TAG"] = support.getElementsByTagName ? 1119 function( tag, context ) { 1120 if ( typeof context.getElementsByTagName !== "undefined" ) { 1121 return context.getElementsByTagName( tag ); 1122 1123 // DocumentFragment nodes don't have gEBTN 1124 } else if ( support.qsa ) { 1125 return context.querySelectorAll( tag ); 1126 } 1127 } : 1128 1129 function( tag, context ) { 1130 var elem, 1131 tmp = [], 1132 i = 0, 1133 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1134 results = context.getElementsByTagName( tag ); 1135 1136 // Filter out possible comments 1137 if ( tag === "*" ) { 1138 while ( (elem = results[i++]) ) { 1139 if ( elem.nodeType === 1 ) { 1140 tmp.push( elem ); 1141 } 1142 } 1143 1144 return tmp; 1145 } 1146 return results; 1147 }; 1148 1149 // Class 1150 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 1151 if ( documentIsHTML ) { 1152 return context.getElementsByClassName( className ); 1153 } 1154 }; 1155 1156 /* QSA/matchesSelector 1157 ---------------------------------------------------------------------- */ 1158 1159 // QSA and matchesSelector support 1160 1161 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1162 rbuggyMatches = []; 1163 1164 // qSa(:focus) reports false when true (Chrome 21) 1165 // We allow this because of a bug in IE8/9 that throws an error 1166 // whenever `document.activeElement` is accessed on an iframe 1167 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1168 // See http://bugs.jquery.com/ticket/13378 1169 rbuggyQSA = []; 1170 1171 if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { 1172 // Build QSA regex 1173 // Regex strategy adopted from Diego Perini 1174 assert(function( div ) { 1175 // Select is set to empty string on purpose 1176 // This is to test IE's treatment of not explicitly 1177 // setting a boolean content attribute, 1178 // since its presence should be enough 1179 // http://bugs.jquery.com/ticket/12359 1180 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + 1181 "<select id='" + expando + "-\f]' msallowcapture=''>" + 1182 "<option selected=''></option></select>"; 1183 1184 // Support: IE8, Opera 11-12.16 1185 // Nothing should be selected when empty strings follow ^= or $= or *= 1186 // The test attribute must be unknown in Opera but "safe" for WinRT 1187 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1188 if ( div.querySelectorAll("[msallowcapture^='']").length ) { 1189 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 1190 } 1191 1192 // Support: IE8 1193 // Boolean attributes and "value" are not treated correctly 1194 if ( !div.querySelectorAll("[selected]").length ) { 1195 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1196 } 1197 1198 // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ 1199 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1200 rbuggyQSA.push("~="); 1201 } 1202 1203 // Webkit/Opera - :checked should return selected option elements 1204 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1205 // IE8 throws error here and will not see later tests 1206 if ( !div.querySelectorAll(":checked").length ) { 1207 rbuggyQSA.push(":checked"); 1208 } 1209 1210 // Support: Safari 8+, iOS 8+ 1211 // https://bugs.webkit.org/show_bug.cgi?id=136851 1212 // In-page `selector#id sibing-combinator selector` fails 1213 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { 1214 rbuggyQSA.push(".#.+[+~]"); 1215 } 1216 }); 1217 1218 assert(function( div ) { 1219 // Support: Windows 8 Native Apps 1220 // The type and name attributes are restricted during .innerHTML assignment 1221 var input = doc.createElement("input"); 1222 input.setAttribute( "type", "hidden" ); 1223 div.appendChild( input ).setAttribute( "name", "D" ); 1224 1225 // Support: IE8 1226 // Enforce case-sensitivity of name attribute 1227 if ( div.querySelectorAll("[name=d]").length ) { 1228 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 1229 } 1230 1231 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1232 // IE8 throws error here and will not see later tests 1233 if ( !div.querySelectorAll(":enabled").length ) { 1234 rbuggyQSA.push( ":enabled", ":disabled" ); 1235 } 1236 1237 // Opera 10-11 does not throw on post-comma invalid pseudos 1238 div.querySelectorAll("*,:x"); 1239 rbuggyQSA.push(",.*:"); 1240 }); 1241 } 1242 1243 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 1244 docElem.webkitMatchesSelector || 1245 docElem.mozMatchesSelector || 1246 docElem.oMatchesSelector || 1247 docElem.msMatchesSelector) )) ) { 1248 1249 assert(function( div ) { 1250 // Check to see if it's possible to do matchesSelector 1251 // on a disconnected node (IE 9) 1252 support.disconnectedMatch = matches.call( div, "div" ); 1253 1254 // This should fail with an exception 1255 // Gecko does not error, returns false instead 1256 matches.call( div, "[s!='']:x" ); 1257 rbuggyMatches.push( "!=", pseudos ); 1258 }); 1259 } 1260 1261 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 1262 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 1263 1264 /* Contains 1265 ---------------------------------------------------------------------- */ 1266 hasCompare = rnative.test( docElem.compareDocumentPosition ); 1267 1268 // Element contains another 1269 // Purposefully does not implement inclusive descendent 1270 // As in, an element does not contain itself 1271 contains = hasCompare || rnative.test( docElem.contains ) ? 1272 function( a, b ) { 1273 var adown = a.nodeType === 9 ? a.documentElement : a, 1274 bup = b && b.parentNode; 1275 return a === bup || !!( bup && bup.nodeType === 1 && ( 1276 adown.contains ? 1277 adown.contains( bup ) : 1278 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1279 )); 1280 } : 1281 function( a, b ) { 1282 if ( b ) { 1283 while ( (b = b.parentNode) ) { 1284 if ( b === a ) { 1285 return true; 1286 } 1287 } 1288 } 1289 return false; 1290 }; 1291 1292 /* Sorting 1293 ---------------------------------------------------------------------- */ 1294 1295 // Document order sorting 1296 sortOrder = hasCompare ? 1297 function( a, b ) { 1298 1299 // Flag for duplicate removal 1300 if ( a === b ) { 1301 hasDuplicate = true; 1302 return 0; 1303 } 1304 1305 // Sort on method existence if only one input has compareDocumentPosition 1306 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1307 if ( compare ) { 1308 return compare; 1309 } 1310 1311 // Calculate position if both inputs belong to the same document 1312 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 1313 a.compareDocumentPosition( b ) : 1314 1315 // Otherwise we know they are disconnected 1316 1; 1317 1318 // Disconnected nodes 1319 if ( compare & 1 || 1320 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 1321 1322 // Choose the first element that is related to our preferred document 1323 if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 1324 return -1; 1325 } 1326 if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 1327 return 1; 1328 } 1329 1330 // Maintain original order 1331 return sortInput ? 1332 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1333 0; 1334 } 1335 1336 return compare & 4 ? -1 : 1; 1337 } : 1338 function( a, b ) { 1339 // Exit early if the nodes are identical 1340 if ( a === b ) { 1341 hasDuplicate = true; 1342 return 0; 1343 } 1344 1345 var cur, 1346 i = 0, 1347 aup = a.parentNode, 1348 bup = b.parentNode, 1349 ap = [ a ], 1350 bp = [ b ]; 1351 1352 // Parentless nodes are either documents or disconnected 1353 if ( !aup || !bup ) { 1354 return a === doc ? -1 : 1355 b === doc ? 1 : 1356 aup ? -1 : 1357 bup ? 1 : 1358 sortInput ? 1359 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1360 0; 1361 1362 // If the nodes are siblings, we can do a quick check 1363 } else if ( aup === bup ) { 1364 return siblingCheck( a, b ); 1365 } 1366 1367 // Otherwise we need full lists of their ancestors for comparison 1368 cur = a; 1369 while ( (cur = cur.parentNode) ) { 1370 ap.unshift( cur ); 1371 } 1372 cur = b; 1373 while ( (cur = cur.parentNode) ) { 1374 bp.unshift( cur ); 1375 } 1376 1377 // Walk down the tree looking for a discrepancy 1378 while ( ap[i] === bp[i] ) { 1379 i++; 1380 } 1381 1382 return i ? 1383 // Do a sibling check if the nodes have a common ancestor 1384 siblingCheck( ap[i], bp[i] ) : 1385 1386 // Otherwise nodes in our document sort first 1387 ap[i] === preferredDoc ? -1 : 1388 bp[i] === preferredDoc ? 1 : 1389 0; 1390 }; 1391 1392 return doc; 1393}; 1394 1395Sizzle.matches = function( expr, elements ) { 1396 return Sizzle( expr, null, null, elements ); 1397}; 1398 1399Sizzle.matchesSelector = function( elem, expr ) { 1400 // Set document vars if needed 1401 if ( ( elem.ownerDocument || elem ) !== document ) { 1402 setDocument( elem ); 1403 } 1404 1405 // Make sure that attribute selectors are quoted 1406 expr = expr.replace( rattributeQuotes, "='$1']" ); 1407 1408 if ( support.matchesSelector && documentIsHTML && 1409 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 1410 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1411 1412 try { 1413 var ret = matches.call( elem, expr ); 1414 1415 // IE 9's matchesSelector returns false on disconnected nodes 1416 if ( ret || support.disconnectedMatch || 1417 // As well, disconnected nodes are said to be in a document 1418 // fragment in IE 9 1419 elem.document && elem.document.nodeType !== 11 ) { 1420 return ret; 1421 } 1422 } catch (e) {} 1423 } 1424 1425 return Sizzle( expr, document, null, [ elem ] ).length > 0; 1426}; 1427 1428Sizzle.contains = function( context, elem ) { 1429 // Set document vars if needed 1430 if ( ( context.ownerDocument || context ) !== document ) { 1431 setDocument( context ); 1432 } 1433 return contains( context, elem ); 1434}; 1435 1436Sizzle.attr = function( elem, name ) { 1437 // Set document vars if needed 1438 if ( ( elem.ownerDocument || elem ) !== document ) { 1439 setDocument( elem ); 1440 } 1441 1442 var fn = Expr.attrHandle[ name.toLowerCase() ], 1443 // Don't get fooled by Object.prototype properties (jQuery #13807) 1444 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1445 fn( elem, name, !documentIsHTML ) : 1446 undefined; 1447 1448 return val !== undefined ? 1449 val : 1450 support.attributes || !documentIsHTML ? 1451 elem.getAttribute( name ) : 1452 (val = elem.getAttributeNode(name)) && val.specified ? 1453 val.value : 1454 null; 1455}; 1456 1457Sizzle.error = function( msg ) { 1458 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1459}; 1460 1461/** 1462 * Document sorting and removing duplicates 1463 * @param {ArrayLike} results 1464 */ 1465Sizzle.uniqueSort = function( results ) { 1466 var elem, 1467 duplicates = [], 1468 j = 0, 1469 i = 0; 1470 1471 // Unless we *know* we can detect duplicates, assume their presence 1472 hasDuplicate = !support.detectDuplicates; 1473 sortInput = !support.sortStable && results.slice( 0 ); 1474 results.sort( sortOrder ); 1475 1476 if ( hasDuplicate ) { 1477 while ( (elem = results[i++]) ) { 1478 if ( elem === results[ i ] ) { 1479 j = duplicates.push( i ); 1480 } 1481 } 1482 while ( j-- ) { 1483 results.splice( duplicates[ j ], 1 ); 1484 } 1485 } 1486 1487 // Clear input after sorting to release objects 1488 // See https://github.com/jquery/sizzle/pull/225 1489 sortInput = null; 1490 1491 return results; 1492}; 1493 1494/** 1495 * Utility function for retrieving the text value of an array of DOM nodes 1496 * @param {Array|Element} elem 1497 */ 1498getText = Sizzle.getText = function( elem ) { 1499 var node, 1500 ret = "", 1501 i = 0, 1502 nodeType = elem.nodeType; 1503 1504 if ( !nodeType ) { 1505 // If no nodeType, this is expected to be an array 1506 while ( (node = elem[i++]) ) { 1507 // Do not traverse comment nodes 1508 ret += getText( node ); 1509 } 1510 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 1511 // Use textContent for elements 1512 // innerText usage removed for consistency of new lines (jQuery #11153) 1513 if ( typeof elem.textContent === "string" ) { 1514 return elem.textContent; 1515 } else { 1516 // Traverse its children 1517 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1518 ret += getText( elem ); 1519 } 1520 } 1521 } else if ( nodeType === 3 || nodeType === 4 ) { 1522 return elem.nodeValue; 1523 } 1524 // Do not include comment or processing instruction nodes 1525 1526 return ret; 1527}; 1528 1529Expr = Sizzle.selectors = { 1530 1531 // Can be adjusted by the user 1532 cacheLength: 50, 1533 1534 createPseudo: markFunction, 1535 1536 match: matchExpr, 1537 1538 attrHandle: {}, 1539 1540 find: {}, 1541 1542 relative: { 1543 ">": { dir: "parentNode", first: true }, 1544 " ": { dir: "parentNode" }, 1545 "+": { dir: "previousSibling", first: true }, 1546 "~": { dir: "previousSibling" } 1547 }, 1548 1549 preFilter: { 1550 "ATTR": function( match ) { 1551 match[1] = match[1].replace( runescape, funescape ); 1552 1553 // Move the given value to match[3] whether quoted or unquoted 1554 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 1555 1556 if ( match[2] === "~=" ) { 1557 match[3] = " " + match[3] + " "; 1558 } 1559 1560 return match.slice( 0, 4 ); 1561 }, 1562 1563 "CHILD": function( match ) { 1564 /* matches from matchExpr["CHILD"] 1565 1 type (only|nth|...) 1566 2 what (child|of-type) 1567 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1568 4 xn-component of xn+y argument ([+-]?\d*n|) 1569 5 sign of xn-component 1570 6 x of xn-component 1571 7 sign of y-component 1572 8 y of y-component 1573 */ 1574 match[1] = match[1].toLowerCase(); 1575 1576 if ( match[1].slice( 0, 3 ) === "nth" ) { 1577 // nth-* requires argument 1578 if ( !match[3] ) { 1579 Sizzle.error( match[0] ); 1580 } 1581 1582 // numeric x and y parameters for Expr.filter.CHILD 1583 // remember that false/true cast respectively to 0/1 1584 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 1585 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 1586 1587 // other types prohibit arguments 1588 } else if ( match[3] ) { 1589 Sizzle.error( match[0] ); 1590 } 1591 1592 return match; 1593 }, 1594 1595 "PSEUDO": function( match ) { 1596 var excess, 1597 unquoted = !match[6] && match[2]; 1598 1599 if ( matchExpr["CHILD"].test( match[0] ) ) { 1600 return null; 1601 } 1602 1603 // Accept quoted arguments as-is 1604 if ( match[3] ) { 1605 match[2] = match[4] || match[5] || ""; 1606 1607 // Strip excess characters from unquoted arguments 1608 } else if ( unquoted && rpseudo.test( unquoted ) && 1609 // Get excess from tokenize (recursively) 1610 (excess = tokenize( unquoted, true )) && 1611 // advance to the next closing parenthesis 1612 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 1613 1614 // excess is a negative index 1615 match[0] = match[0].slice( 0, excess ); 1616 match[2] = unquoted.slice( 0, excess ); 1617 } 1618 1619 // Return only captures needed by the pseudo filter method (type and argument) 1620 return match.slice( 0, 3 ); 1621 } 1622 }, 1623 1624 filter: { 1625 1626 "TAG": function( nodeNameSelector ) { 1627 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1628 return nodeNameSelector === "*" ? 1629 function() { return true; } : 1630 function( elem ) { 1631 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1632 }; 1633 }, 1634 1635 "CLASS": function( className ) { 1636 var pattern = classCache[ className + " " ]; 1637 1638 return pattern || 1639 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 1640 classCache( className, function( elem ) { 1641 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 1642 }); 1643 }, 1644 1645 "ATTR": function( name, operator, check ) { 1646 return function( elem ) { 1647 var result = Sizzle.attr( elem, name ); 1648 1649 if ( result == null ) { 1650 return operator === "!="; 1651 } 1652 if ( !operator ) { 1653 return true; 1654 } 1655 1656 result += ""; 1657 1658 return operator === "=" ? result === check : 1659 operator === "!=" ? result !== check : 1660 operator === "^=" ? check && result.indexOf( check ) === 0 : 1661 operator === "*=" ? check && result.indexOf( check ) > -1 : 1662 operator === "$=" ? check && result.slice( -check.length ) === check : 1663 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 1664 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 1665 false; 1666 }; 1667 }, 1668 1669 "CHILD": function( type, what, argument, first, last ) { 1670 var simple = type.slice( 0, 3 ) !== "nth", 1671 forward = type.slice( -4 ) !== "last", 1672 ofType = what === "of-type"; 1673 1674 return first === 1 && last === 0 ? 1675 1676 // Shortcut for :nth-*(n) 1677 function( elem ) { 1678 return !!elem.parentNode; 1679 } : 1680 1681 function( elem, context, xml ) { 1682 var cache, outerCache, node, diff, nodeIndex, start, 1683 dir = simple !== forward ? "nextSibling" : "previousSibling", 1684 parent = elem.parentNode, 1685 name = ofType && elem.nodeName.toLowerCase(), 1686 useCache = !xml && !ofType; 1687 1688 if ( parent ) { 1689 1690 // :(first|last|only)-(child|of-type) 1691 if ( simple ) { 1692 while ( dir ) { 1693 node = elem; 1694 while ( (node = node[ dir ]) ) { 1695 if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { 1696 return false; 1697 } 1698 } 1699 // Reverse direction for :only-* (if we haven't yet done so) 1700 start = dir = type === "only" && !start && "nextSibling"; 1701 } 1702 return true; 1703 } 1704 1705 start = [ forward ? parent.firstChild : parent.lastChild ]; 1706 1707 // non-xml :nth-child(...) stores cache data on `parent` 1708 if ( forward && useCache ) { 1709 // Seek `elem` from a previously-cached index 1710 outerCache = parent[ expando ] || (parent[ expando ] = {}); 1711 cache = outerCache[ type ] || []; 1712 nodeIndex = cache[0] === dirruns && cache[1]; 1713 diff = cache[0] === dirruns && cache[2]; 1714 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1715 1716 while ( (node = ++nodeIndex && node && node[ dir ] || 1717 1718 // Fallback to seeking `elem` from the start 1719 (diff = nodeIndex = 0) || start.pop()) ) { 1720 1721 // When found, cache indexes on `parent` and break 1722 if ( node.nodeType === 1 && ++diff && node === elem ) { 1723 outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 1724 break; 1725 } 1726 } 1727 1728 // Use previously-cached element index if available 1729 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { 1730 diff = cache[1]; 1731 1732 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) 1733 } else { 1734 // Use the same loop as above to seek `elem` from the start 1735 while ( (node = ++nodeIndex && node && node[ dir ] || 1736 (diff = nodeIndex = 0) || start.pop()) ) { 1737 1738 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { 1739 // Cache the index of each encountered element 1740 if ( useCache ) { 1741 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; 1742 } 1743 1744 if ( node === elem ) { 1745 break; 1746 } 1747 } 1748 } 1749 } 1750 1751 // Incorporate the offset, then check against cycle size 1752 diff -= last; 1753 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1754 } 1755 }; 1756 }, 1757 1758 "PSEUDO": function( pseudo, argument ) { 1759 // pseudo-class names are case-insensitive 1760 // http://www.w3.org/TR/selectors/#pseudo-classes 1761 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1762 // Remember that setFilters inherits from pseudos 1763 var args, 1764 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1765 Sizzle.error( "unsupported pseudo: " + pseudo ); 1766 1767 // The user may use createPseudo to indicate that 1768 // arguments are needed to create the filter function 1769 // just as Sizzle does 1770 if ( fn[ expando ] ) { 1771 return fn( argument ); 1772 } 1773 1774 // But maintain support for old signatures 1775 if ( fn.length > 1 ) { 1776 args = [ pseudo, pseudo, "", argument ]; 1777 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1778 markFunction(function( seed, matches ) { 1779 var idx, 1780 matched = fn( seed, argument ), 1781 i = matched.length; 1782 while ( i-- ) { 1783 idx = indexOf( seed, matched[i] ); 1784 seed[ idx ] = !( matches[ idx ] = matched[i] ); 1785 } 1786 }) : 1787 function( elem ) { 1788 return fn( elem, 0, args ); 1789 }; 1790 } 1791 1792 return fn; 1793 } 1794 }, 1795 1796 pseudos: { 1797 // Potentially complex pseudos 1798 "not": markFunction(function( selector ) { 1799 // Trim the selector passed to compile 1800 // to avoid treating leading and trailing 1801 // spaces as combinators 1802 var input = [], 1803 results = [], 1804 matcher = compile( selector.replace( rtrim, "$1" ) ); 1805 1806 return matcher[ expando ] ? 1807 markFunction(function( seed, matches, context, xml ) { 1808 var elem, 1809 unmatched = matcher( seed, null, xml, [] ), 1810 i = seed.length; 1811 1812 // Match elements unmatched by `matcher` 1813 while ( i-- ) { 1814 if ( (elem = unmatched[i]) ) { 1815 seed[i] = !(matches[i] = elem); 1816 } 1817 } 1818 }) : 1819 function( elem, context, xml ) { 1820 input[0] = elem; 1821 matcher( input, null, xml, results ); 1822 // Don't keep the element (issue #299) 1823 input[0] = null; 1824 return !results.pop(); 1825 }; 1826 }), 1827 1828 "has": markFunction(function( selector ) { 1829 return function( elem ) { 1830 return Sizzle( selector, elem ).length > 0; 1831 }; 1832 }), 1833 1834 "contains": markFunction(function( text ) { 1835 text = text.replace( runescape, funescape ); 1836 return function( elem ) { 1837 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; 1838 }; 1839 }), 1840 1841 // "Whether an element is represented by a :lang() selector 1842 // is based solely on the element's language value 1843 // being equal to the identifier C, 1844 // or beginning with the identifier C immediately followed by "-". 1845 // The matching of C against the element's language value is performed case-insensitively. 1846 // The identifier C does not have to be a valid language name." 1847 // http://www.w3.org/TR/selectors/#lang-pseudo 1848 "lang": markFunction( function( lang ) { 1849 // lang value must be a valid identifier 1850 if ( !ridentifier.test(lang || "") ) { 1851 Sizzle.error( "unsupported lang: " + lang ); 1852 } 1853 lang = lang.replace( runescape, funescape ).toLowerCase(); 1854 return function( elem ) { 1855 var elemLang; 1856 do { 1857 if ( (elemLang = documentIsHTML ? 1858 elem.lang : 1859 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 1860 1861 elemLang = elemLang.toLowerCase(); 1862 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1863 } 1864 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 1865 return false; 1866 }; 1867 }), 1868 1869 // Miscellaneous 1870 "target": function( elem ) { 1871 var hash = window.location && window.location.hash; 1872 return hash && hash.slice( 1 ) === elem.id; 1873 }, 1874 1875 "root": function( elem ) { 1876 return elem === docElem; 1877 }, 1878 1879 "focus": function( elem ) { 1880 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 1881 }, 1882 1883 // Boolean properties 1884 "enabled": function( elem ) { 1885 return elem.disabled === false; 1886 }, 1887 1888 "disabled": function( elem ) { 1889 return elem.disabled === true; 1890 }, 1891 1892 "checked": function( elem ) { 1893 // In CSS3, :checked should return both checked and selected elements 1894 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1895 var nodeName = elem.nodeName.toLowerCase(); 1896 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 1897 }, 1898 1899 "selected": function( elem ) { 1900 // Accessing this property makes selected-by-default 1901 // options in Safari work properly 1902 if ( elem.parentNode ) { 1903 elem.parentNode.selectedIndex; 1904 } 1905 1906 return elem.selected === true; 1907 }, 1908 1909 // Contents 1910 "empty": function( elem ) { 1911 // http://www.w3.org/TR/selectors/#empty-pseudo 1912 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1913 // but not by others (comment: 8; processing instruction: 7; etc.) 1914 // nodeType < 6 works because attributes (2) do not appear as children 1915 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1916 if ( elem.nodeType < 6 ) { 1917 return false; 1918 } 1919 } 1920 return true; 1921 }, 1922 1923 "parent": function( elem ) { 1924 return !Expr.pseudos["empty"]( elem ); 1925 }, 1926 1927 // Element/input types 1928 "header": function( elem ) { 1929 return rheader.test( elem.nodeName ); 1930 }, 1931 1932 "input": function( elem ) { 1933 return rinputs.test( elem.nodeName ); 1934 }, 1935 1936 "button": function( elem ) { 1937 var name = elem.nodeName.toLowerCase(); 1938 return name === "input" && elem.type === "button" || name === "button"; 1939 }, 1940 1941 "text": function( elem ) { 1942 var attr; 1943 return elem.nodeName.toLowerCase() === "input" && 1944 elem.type === "text" && 1945 1946 // Support: IE<8 1947 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 1948 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 1949 }, 1950 1951 // Position-in-collection 1952 "first": createPositionalPseudo(function() { 1953 return [ 0 ]; 1954 }), 1955 1956 "last": createPositionalPseudo(function( matchIndexes, length ) { 1957 return [ length - 1 ]; 1958 }), 1959 1960 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 1961 return [ argument < 0 ? argument + length : argument ]; 1962 }), 1963 1964 "even": createPositionalPseudo(function( matchIndexes, length ) { 1965 var i = 0; 1966 for ( ; i < length; i += 2 ) { 1967 matchIndexes.push( i ); 1968 } 1969 return matchIndexes; 1970 }), 1971 1972 "odd": createPositionalPseudo(function( matchIndexes, length ) { 1973 var i = 1; 1974 for ( ; i < length; i += 2 ) { 1975 matchIndexes.push( i ); 1976 } 1977 return matchIndexes; 1978 }), 1979 1980 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 1981 var i = argument < 0 ? argument + length : argument; 1982 for ( ; --i >= 0; ) { 1983 matchIndexes.push( i ); 1984 } 1985 return matchIndexes; 1986 }), 1987 1988 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 1989 var i = argument < 0 ? argument + length : argument; 1990 for ( ; ++i < length; ) { 1991 matchIndexes.push( i ); 1992 } 1993 return matchIndexes; 1994 }) 1995 } 1996}; 1997 1998Expr.pseudos["nth"] = Expr.pseudos["eq"]; 1999 2000// Add button/input type pseudos 2001for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2002 Expr.pseudos[ i ] = createInputPseudo( i ); 2003} 2004for ( i in { submit: true, reset: true } ) { 2005 Expr.pseudos[ i ] = createButtonPseudo( i ); 2006} 2007 2008// Easy API for creating new setFilters 2009function setFilters() {} 2010setFilters.prototype = Expr.filters = Expr.pseudos; 2011Expr.setFilters = new setFilters(); 2012 2013tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 2014 var matched, match, tokens, type, 2015 soFar, groups, preFilters, 2016 cached = tokenCache[ selector + " " ]; 2017 2018 if ( cached ) { 2019 return parseOnly ? 0 : cached.slice( 0 ); 2020 } 2021 2022 soFar = selector; 2023 groups = []; 2024 preFilters = Expr.preFilter; 2025 2026 while ( soFar ) { 2027 2028 // Comma and first run 2029 if ( !matched || (match = rcomma.exec( soFar )) ) { 2030 if ( match ) { 2031 // Don't consume trailing commas as valid 2032 soFar = soFar.slice( match[0].length ) || soFar; 2033 } 2034 groups.push( (tokens = []) ); 2035 } 2036 2037 matched = false; 2038 2039 // Combinators 2040 if ( (match = rcombinators.exec( soFar )) ) { 2041 matched = match.shift(); 2042 tokens.push({ 2043 value: matched, 2044 // Cast descendant combinators to space 2045 type: match[0].replace( rtrim, " " ) 2046 }); 2047 soFar = soFar.slice( matched.length ); 2048 } 2049 2050 // Filters 2051 for ( type in Expr.filter ) { 2052 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 2053 (match = preFilters[ type ]( match ))) ) { 2054 matched = match.shift(); 2055 tokens.push({ 2056 value: matched, 2057 type: type, 2058 matches: match 2059 }); 2060 soFar = soFar.slice( matched.length ); 2061 } 2062 } 2063 2064 if ( !matched ) { 2065 break; 2066 } 2067 } 2068 2069 // Return the length of the invalid excess 2070 // if we're just parsing 2071 // Otherwise, throw an error or return tokens 2072 return parseOnly ? 2073 soFar.length : 2074 soFar ? 2075 Sizzle.error( selector ) : 2076 // Cache the tokens 2077 tokenCache( selector, groups ).slice( 0 ); 2078}; 2079 2080function toSelector( tokens ) { 2081 var i = 0, 2082 len = tokens.length, 2083 selector = ""; 2084 for ( ; i < len; i++ ) { 2085 selector += tokens[i].value; 2086 } 2087 return selector; 2088} 2089 2090function addCombinator( matcher, combinator, base ) { 2091 var dir = combinator.dir, 2092 checkNonElements = base && dir === "parentNode", 2093 doneName = done++; 2094 2095 return combinator.first ? 2096 // Check against closest ancestor/preceding element 2097 function( elem, context, xml ) { 2098 while ( (elem = elem[ dir ]) ) { 2099 if ( elem.nodeType === 1 || checkNonElements ) { 2100 return matcher( elem, context, xml ); 2101 } 2102 } 2103 } : 2104 2105 // Check against all ancestor/preceding elements 2106 function( elem, context, xml ) { 2107 var oldCache, outerCache, 2108 newCache = [ dirruns, doneName ]; 2109 2110 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching 2111 if ( xml ) { 2112 while ( (elem = elem[ dir ]) ) { 2113 if ( elem.nodeType === 1 || checkNonElements ) { 2114 if ( matcher( elem, context, xml ) ) { 2115 return true; 2116 } 2117 } 2118 } 2119 } else { 2120 while ( (elem = elem[ dir ]) ) { 2121 if ( elem.nodeType === 1 || checkNonElements ) { 2122 outerCache = elem[ expando ] || (elem[ expando ] = {}); 2123 if ( (oldCache = outerCache[ dir ]) && 2124 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2125 2126 // Assign to newCache so results back-propagate to previous elements 2127 return (newCache[ 2 ] = oldCache[ 2 ]); 2128 } else { 2129 // Reuse newcache so results back-propagate to previous elements 2130 outerCache[ dir ] = newCache; 2131 2132 // A match means we're done; a fail means we have to keep checking 2133 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 2134 return true; 2135 } 2136 } 2137 } 2138 } 2139 } 2140 }; 2141} 2142 2143function elementMatcher( matchers ) { 2144 return matchers.length > 1 ? 2145 function( elem, context, xml ) { 2146 var i = matchers.length; 2147 while ( i-- ) { 2148 if ( !matchers[i]( elem, context, xml ) ) { 2149 return false; 2150 } 2151 } 2152 return true; 2153 } : 2154 matchers[0]; 2155} 2156 2157function multipleContexts( selector, contexts, results ) { 2158 var i = 0, 2159 len = contexts.length; 2160 for ( ; i < len; i++ ) { 2161 Sizzle( selector, contexts[i], results ); 2162 } 2163 return results; 2164} 2165 2166function condense( unmatched, map, filter, context, xml ) { 2167 var elem, 2168 newUnmatched = [], 2169 i = 0, 2170 len = unmatched.length, 2171 mapped = map != null; 2172 2173 for ( ; i < len; i++ ) { 2174 if ( (elem = unmatched[i]) ) { 2175 if ( !filter || filter( elem, context, xml ) ) { 2176 newUnmatched.push( elem ); 2177 if ( mapped ) { 2178 map.push( i ); 2179 } 2180 } 2181 } 2182 } 2183 2184 return newUnmatched; 2185} 2186 2187function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2188 if ( postFilter && !postFilter[ expando ] ) { 2189 postFilter = setMatcher( postFilter ); 2190 } 2191 if ( postFinder && !postFinder[ expando ] ) { 2192 postFinder = setMatcher( postFinder, postSelector ); 2193 } 2194 return markFunction(function( seed, results, context, xml ) { 2195 var temp, i, elem, 2196 preMap = [], 2197 postMap = [], 2198 preexisting = results.length, 2199 2200 // Get initial elements from seed or context 2201 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 2202 2203 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2204 matcherIn = preFilter && ( seed || !selector ) ? 2205 condense( elems, preMap, preFilter, context, xml ) : 2206 elems, 2207 2208 matcherOut = matcher ? 2209 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2210 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2211 2212 // ...intermediate processing is necessary 2213 [] : 2214 2215 // ...otherwise use results directly 2216 results : 2217 matcherIn; 2218 2219 // Find primary matches 2220 if ( matcher ) { 2221 matcher( matcherIn, matcherOut, context, xml ); 2222 } 2223 2224 // Apply postFilter 2225 if ( postFilter ) { 2226 temp = condense( matcherOut, postMap ); 2227 postFilter( temp, [], context, xml ); 2228 2229 // Un-match failing elements by moving them back to matcherIn 2230 i = temp.length; 2231 while ( i-- ) { 2232 if ( (elem = temp[i]) ) { 2233 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 2234 } 2235 } 2236 } 2237 2238 if ( seed ) { 2239 if ( postFinder || preFilter ) { 2240 if ( postFinder ) { 2241 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2242 temp = []; 2243 i = matcherOut.length; 2244 while ( i-- ) { 2245 if ( (elem = matcherOut[i]) ) { 2246 // Restore matcherIn since elem is not yet a final match 2247 temp.push( (matcherIn[i] = elem) ); 2248 } 2249 } 2250 postFinder( null, (matcherOut = []), temp, xml ); 2251 } 2252 2253 // Move matched elements from seed to results to keep them synchronized 2254 i = matcherOut.length; 2255 while ( i-- ) { 2256 if ( (elem = matcherOut[i]) && 2257 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 2258 2259 seed[temp] = !(results[temp] = elem); 2260 } 2261 } 2262 } 2263 2264 // Add elements to results, through postFinder if defined 2265 } else { 2266 matcherOut = condense( 2267 matcherOut === results ? 2268 matcherOut.splice( preexisting, matcherOut.length ) : 2269 matcherOut 2270 ); 2271 if ( postFinder ) { 2272 postFinder( null, results, matcherOut, xml ); 2273 } else { 2274 push.apply( results, matcherOut ); 2275 } 2276 } 2277 }); 2278} 2279 2280function matcherFromTokens( tokens ) { 2281 var checkContext, matcher, j, 2282 len = tokens.length, 2283 leadingRelative = Expr.relative[ tokens[0].type ], 2284 implicitRelative = leadingRelative || Expr.relative[" "], 2285 i = leadingRelative ? 1 : 0, 2286 2287 // The foundational matcher ensures that elements are reachable from top-level context(s) 2288 matchContext = addCombinator( function( elem ) { 2289 return elem === checkContext; 2290 }, implicitRelative, true ), 2291 matchAnyContext = addCombinator( function( elem ) { 2292 return indexOf( checkContext, elem ) > -1; 2293 }, implicitRelative, true ), 2294 matchers = [ function( elem, context, xml ) { 2295 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 2296 (checkContext = context).nodeType ? 2297 matchContext( elem, context, xml ) : 2298 matchAnyContext( elem, context, xml ) ); 2299 // Avoid hanging onto element (issue #299) 2300 checkContext = null; 2301 return ret; 2302 } ]; 2303 2304 for ( ; i < len; i++ ) { 2305 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 2306 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 2307 } else { 2308 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 2309 2310 // Return special upon seeing a positional matcher 2311 if ( matcher[ expando ] ) { 2312 // Find the next relative operator (if any) for proper handling 2313 j = ++i; 2314 for ( ; j < len; j++ ) { 2315 if ( Expr.relative[ tokens[j].type ] ) { 2316 break; 2317 } 2318 } 2319 return setMatcher( 2320 i > 1 && elementMatcher( matchers ), 2321 i > 1 && toSelector( 2322 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2323 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 2324 ).replace( rtrim, "$1" ), 2325 matcher, 2326 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2327 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 2328 j < len && toSelector( tokens ) 2329 ); 2330 } 2331 matchers.push( matcher ); 2332 } 2333 } 2334 2335 return elementMatcher( matchers ); 2336} 2337 2338function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2339 var bySet = setMatchers.length > 0, 2340 byElement = elementMatchers.length > 0, 2341 superMatcher = function( seed, context, xml, results, outermost ) { 2342 var elem, j, matcher, 2343 matchedCount = 0, 2344 i = "0", 2345 unmatched = seed && [], 2346 setMatched = [], 2347 contextBackup = outermostContext, 2348 // We must always have either seed elements or outermost context 2349 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 2350 // Use integer dirruns iff this is the outermost matcher 2351 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 2352 len = elems.length; 2353 2354 if ( outermost ) { 2355 outermostContext = context !== document && context; 2356 } 2357 2358 // Add elements passing elementMatchers directly to results 2359 // Keep `i` a string if there are no elements so `matchedCount` will be "00" below 2360 // Support: IE<9, Safari 2361 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2362 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 2363 if ( byElement && elem ) { 2364 j = 0; 2365 while ( (matcher = elementMatchers[j++]) ) { 2366 if ( matcher( elem, context, xml ) ) { 2367 results.push( elem ); 2368 break; 2369 } 2370 } 2371 if ( outermost ) { 2372 dirruns = dirrunsUnique; 2373 } 2374 } 2375 2376 // Track unmatched elements for set filters 2377 if ( bySet ) { 2378 // They will have gone through all possible matchers 2379 if ( (elem = !matcher && elem) ) { 2380 matchedCount--; 2381 } 2382 2383 // Lengthen the array for every element, matched or not 2384 if ( seed ) { 2385 unmatched.push( elem ); 2386 } 2387 } 2388 } 2389 2390 // Apply set filters to unmatched elements 2391 matchedCount += i; 2392 if ( bySet && i !== matchedCount ) { 2393 j = 0; 2394 while ( (matcher = setMatchers[j++]) ) { 2395 matcher( unmatched, setMatched, context, xml ); 2396 } 2397 2398 if ( seed ) { 2399 // Reintegrate element matches to eliminate the need for sorting 2400 if ( matchedCount > 0 ) { 2401 while ( i-- ) { 2402 if ( !(unmatched[i] || setMatched[i]) ) { 2403 setMatched[i] = pop.call( results ); 2404 } 2405 } 2406 } 2407 2408 // Discard index placeholder values to get only actual matches 2409 setMatched = condense( setMatched ); 2410 } 2411 2412 // Add matches to results 2413 push.apply( results, setMatched ); 2414 2415 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2416 if ( outermost && !seed && setMatched.length > 0 && 2417 ( matchedCount + setMatchers.length ) > 1 ) { 2418 2419 Sizzle.uniqueSort( results ); 2420 } 2421 } 2422 2423 // Override manipulation of globals by nested matchers 2424 if ( outermost ) { 2425 dirruns = dirrunsUnique; 2426 outermostContext = contextBackup; 2427 } 2428 2429 return unmatched; 2430 }; 2431 2432 return bySet ? 2433 markFunction( superMatcher ) : 2434 superMatcher; 2435} 2436 2437compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 2438 var i, 2439 setMatchers = [], 2440 elementMatchers = [], 2441 cached = compilerCache[ selector + " " ]; 2442 2443 if ( !cached ) { 2444 // Generate a function of recursive functions that can be used to check each element 2445 if ( !match ) { 2446 match = tokenize( selector ); 2447 } 2448 i = match.length; 2449 while ( i-- ) { 2450 cached = matcherFromTokens( match[i] ); 2451 if ( cached[ expando ] ) { 2452 setMatchers.push( cached ); 2453 } else { 2454 elementMatchers.push( cached ); 2455 } 2456 } 2457 2458 // Cache the compiled function 2459 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2460 2461 // Save selector and tokenization 2462 cached.selector = selector; 2463 } 2464 return cached; 2465}; 2466 2467/** 2468 * A low-level selection function that works with Sizzle's compiled 2469 * selector functions 2470 * @param {String|Function} selector A selector or a pre-compiled 2471 * selector function built with Sizzle.compile 2472 * @param {Element} context 2473 * @param {Array} [results] 2474 * @param {Array} [seed] A set of elements to match against 2475 */ 2476select = Sizzle.select = function( selector, context, results, seed ) { 2477 var i, tokens, token, type, find, 2478 compiled = typeof selector === "function" && selector, 2479 match = !seed && tokenize( (selector = compiled.selector || selector) ); 2480 2481 results = results || []; 2482 2483 // Try to minimize operations if there is no seed and only one group 2484 if ( match.length === 1 ) { 2485 2486 // Take a shortcut and set the context if the root selector is an ID 2487 tokens = match[0] = match[0].slice( 0 ); 2488 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 2489 support.getById && context.nodeType === 9 && documentIsHTML && 2490 Expr.relative[ tokens[1].type ] ) { 2491 2492 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 2493 if ( !context ) { 2494 return results; 2495 2496 // Precompiled matchers will still verify ancestry, so step up a level 2497 } else if ( compiled ) { 2498 context = context.parentNode; 2499 } 2500 2501 selector = selector.slice( tokens.shift().value.length ); 2502 } 2503 2504 // Fetch a seed set for right-to-left matching 2505 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 2506 while ( i-- ) { 2507 token = tokens[i]; 2508 2509 // Abort if we hit a combinator 2510 if ( Expr.relative[ (type = token.type) ] ) { 2511 break; 2512 } 2513 if ( (find = Expr.find[ type ]) ) { 2514 // Search, expanding context for leading sibling combinators 2515 if ( (seed = find( 2516 token.matches[0].replace( runescape, funescape ), 2517 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 2518 )) ) { 2519 2520 // If seed is empty or no tokens remain, we can return early 2521 tokens.splice( i, 1 ); 2522 selector = seed.length && toSelector( tokens ); 2523 if ( !selector ) { 2524 push.apply( results, seed ); 2525 return results; 2526 } 2527 2528 break; 2529 } 2530 } 2531 } 2532 } 2533 2534 // Compile and execute a filtering function if one is not provided 2535 // Provide `match` to avoid retokenization if we modified the selector above 2536 ( compiled || compile( selector, match ) )( 2537 seed, 2538 context, 2539 !documentIsHTML, 2540 results, 2541 rsibling.test( selector ) && testContext( context.parentNode ) || context 2542 ); 2543 return results; 2544}; 2545 2546// One-time assignments 2547 2548// Sort stability 2549support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 2550 2551// Support: Chrome 14-35+ 2552// Always assume duplicates if they aren't passed to the comparison function 2553support.detectDuplicates = !!hasDuplicate; 2554 2555// Initialize against the default document 2556setDocument(); 2557 2558// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 2559// Detached nodes confoundingly follow *each other* 2560support.sortDetached = assert(function( div1 ) { 2561 // Should return 1, but returns 4 (following) 2562 return div1.compareDocumentPosition( document.createElement("div") ) & 1; 2563}); 2564 2565// Support: IE<8 2566// Prevent attribute/property "interpolation" 2567// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 2568if ( !assert(function( div ) { 2569 div.innerHTML = "<a href='#'></a>"; 2570 return div.firstChild.getAttribute("href") === "#" ; 2571}) ) { 2572 addHandle( "type|href|height|width", function( elem, name, isXML ) { 2573 if ( !isXML ) { 2574 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 2575 } 2576 }); 2577} 2578 2579// Support: IE<9 2580// Use defaultValue in place of getAttribute("value") 2581if ( !support.attributes || !assert(function( div ) { 2582 div.innerHTML = "<input/>"; 2583 div.firstChild.setAttribute( "value", "" ); 2584 return div.firstChild.getAttribute( "value" ) === ""; 2585}) ) { 2586 addHandle( "value", function( elem, name, isXML ) { 2587 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 2588 return elem.defaultValue; 2589 } 2590 }); 2591} 2592 2593// Support: IE<9 2594// Use getAttributeNode to fetch booleans when getAttribute lies 2595if ( !assert(function( div ) { 2596 return div.getAttribute("disabled") == null; 2597}) ) { 2598 addHandle( booleans, function( elem, name, isXML ) { 2599 var val; 2600 if ( !isXML ) { 2601 return elem[ name ] === true ? name.toLowerCase() : 2602 (val = elem.getAttributeNode( name )) && val.specified ? 2603 val.value : 2604 null; 2605 } 2606 }); 2607} 2608 2609return Sizzle; 2610 2611})( window ); 2612 2613 2614 2615jQuery.find = Sizzle; 2616jQuery.expr = Sizzle.selectors; 2617jQuery.expr[":"] = jQuery.expr.pseudos; 2618jQuery.unique = Sizzle.uniqueSort; 2619jQuery.text = Sizzle.getText; 2620jQuery.isXMLDoc = Sizzle.isXML; 2621jQuery.contains = Sizzle.contains; 2622 2623 2624 2625var rneedsContext = jQuery.expr.match.needsContext; 2626 2627var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); 2628 2629 2630 2631var risSimple = /^.[^:#\[\.,]*$/; 2632 2633// Implement the identical functionality for filter and not 2634function winnow( elements, qualifier, not ) { 2635 if ( jQuery.isFunction( qualifier ) ) { 2636 return jQuery.grep( elements, function( elem, i ) { 2637 /* jshint -W018 */ 2638 return !!qualifier.call( elem, i, elem ) !== not; 2639 }); 2640 2641 } 2642 2643 if ( qualifier.nodeType ) { 2644 return jQuery.grep( elements, function( elem ) { 2645 return ( elem === qualifier ) !== not; 2646 }); 2647 2648 } 2649 2650 if ( typeof qualifier === "string" ) { 2651 if ( risSimple.test( qualifier ) ) { 2652 return jQuery.filter( qualifier, elements, not ); 2653 } 2654 2655 qualifier = jQuery.filter( qualifier, elements ); 2656 } 2657 2658 return jQuery.grep( elements, function( elem ) { 2659 return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; 2660 }); 2661} 2662 2663jQuery.filter = function( expr, elems, not ) { 2664 var elem = elems[ 0 ]; 2665 2666 if ( not ) { 2667 expr = ":not(" + expr + ")"; 2668 } 2669 2670 return elems.length === 1 && elem.nodeType === 1 ? 2671 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : 2672 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2673 return elem.nodeType === 1; 2674 })); 2675}; 2676 2677jQuery.fn.extend({ 2678 find: function( selector ) { 2679 var i, 2680 len = this.length, 2681 ret = [], 2682 self = this; 2683 2684 if ( typeof selector !== "string" ) {
2685 return this.pushStack( jQuery( selector ).filter(function() { 2686 for ( i = 0; i < len; i++ ) { 2687 if ( jQuery.contains( self[ i ], this ) ) { 2688 return true; 2689 } 2690 } 2691 }) ); 2692 } 2693 2694 for ( i = 0; i < len; i++ ) { 2695 jQuery.find( selector, self[ i ], ret ); 2696 } 2697 2698 // Needed because $( selector, context ) becomes $( context ).find( selector ) 2699 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); 2700 ret.selector = this.selector ? this.selector + " " + selector : selector; 2701 return ret; 2702 }, 2703 filter: function( selector ) { 2704 return this.pushStack( winnow(this, selector || [], false) ); 2705 }, 2706 not: function( selector ) { 2707 return this.pushStack( winnow(this, selector || [], true) ); 2708 }, 2709 is: function( selector ) { 2710 return !!winnow( 2711 this, 2712 2713 // If this is a positional/relative selector, check membership in the returned set 2714 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2715 typeof selector === "string" && rneedsContext.test( selector ) ? 2716 jQuery( selector ) : 2717 selector || [], 2718 false 2719 ).length; 2720 } 2721}); 2722 2723 2724// Initialize a jQuery object 2725 2726 2727// A central reference to the root jQuery(document) 2728var rootjQuery, 2729 2730 // A simple way to check for HTML strings 2731 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 2732 // Strict HTML recognition (#11290: must start with <) 2733 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, 2734 2735 init = jQuery.fn.init = function( selector, context ) { 2736 var match, elem; 2737 2738 // HANDLE: $(""), $(null), $(undefined), $(false) 2739 if ( !selector ) { 2740 return this; 2741 } 2742 2743 // Handle HTML strings 2744 if ( typeof selector === "string" ) { 2745 if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { 2746 // Assume that strings that start and end with <> are HTML and skip the regex check 2747 match = [ null, selector, null ]; 2748 2749 } else { 2750 match = rquickExpr.exec( selector ); 2751 } 2752 2753 // Match html or make sure no context is specified for #id 2754 if ( match && (match[1] || !context) ) { 2755 2756 // HANDLE: $(html) -> $(array) 2757 if ( match[1] ) { 2758 context = context instanceof jQuery ? context[0] : context; 2759 2760 // Option to run scripts is true for back-compat 2761 // Intentionally let the error be thrown if parseHTML is not present 2762 jQuery.merge( this, jQuery.parseHTML( 2763 match[1], 2764 context && context.nodeType ? context.ownerDocument || context : document, 2765 true 2766 ) ); 2767 2768 // HANDLE: $(html, props) 2769 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { 2770 for ( match in context ) { 2771 // Properties of context are called as methods if possible 2772 if ( jQuery.isFunction( this[ match ] ) ) { 2773 this[ match ]( context[ match ] ); 2774 2775 // ...and otherwise set as attributes 2776 } else { 2777 this.attr( match, context[ match ] ); 2778 } 2779 } 2780 } 2781 2782 return this; 2783 2784 // HANDLE: $(#id) 2785 } else { 2786 elem = document.getElementById( match[2] ); 2787 2788 // Support: Blackberry 4.6 2789 // gEBID returns nodes no longer in the document (#6963) 2790 if ( elem && elem.parentNode ) { 2791 // Inject the element directly into the jQuery object 2792 this.length = 1; 2793 this[0] = elem; 2794 } 2795 2796 this.context = document; 2797 this.selector = selector; 2798 return this; 2799 } 2800 2801 // HANDLE: $(expr, $(...)) 2802 } else if ( !context || context.jquery ) { 2803 return ( context || rootjQuery ).find( selector ); 2804 2805 // HANDLE: $(expr, context) 2806 // (which is just equivalent to: $(context).find(expr) 2807 } else { 2808 return this.constructor( context ).find( selector ); 2809 } 2810 2811 // HANDLE: $(DOMElement) 2812 } else if ( selector.nodeType ) { 2813 this.context = this[0] = selector; 2814 this.length = 1; 2815 return this; 2816 2817 // HANDLE: $(function) 2818 // Shortcut for document ready 2819 } else if ( jQuery.isFunction( selector ) ) { 2820 return typeof rootjQuery.ready !== "undefined" ? 2821 rootjQuery.ready( selector ) : 2822 // Execute immediately if ready is not present 2823 selector( jQuery ); 2824 } 2825 2826 if ( selector.selector !== undefined ) { 2827 this.selector = selector.selector; 2828 this.context = selector.context; 2829 } 2830 2831 return jQuery.makeArray( selector, this ); 2832 }; 2833 2834// Give the init function the jQuery prototype for later instantiation 2835init.prototype = jQuery.fn; 2836 2837// Initialize central reference 2838rootjQuery = jQuery( document ); 2839 2840 2841var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2842 // Methods guaranteed to produce a unique set when starting from a unique set 2843 guaranteedUnique = { 2844 children: true, 2845 contents: true, 2846 next: true, 2847 prev: true 2848 }; 2849 2850jQuery.extend({ 2851 dir: function( elem, dir, until ) { 2852 var matched = [], 2853 truncate = until !== undefined; 2854 2855 while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { 2856 if ( elem.nodeType === 1 ) { 2857 if ( truncate && jQuery( elem ).is( until ) ) { 2858 break; 2859 } 2860 matched.push( elem ); 2861 } 2862 } 2863 return matched; 2864 }, 2865 2866 sibling: function( n, elem ) { 2867 var matched = []; 2868 2869 for ( ; n; n = n.nextSibling ) { 2870 if ( n.nodeType === 1 && n !== elem ) { 2871 matched.push( n ); 2872 } 2873 } 2874 2875 return matched; 2876 } 2877}); 2878 2879jQuery.fn.extend({ 2880 has: function( target ) { 2881 var targets = jQuery( target, this ), 2882 l = targets.length; 2883 2884 return this.filter(function() { 2885 var i = 0; 2886 for ( ; i < l; i++ ) { 2887 if ( jQuery.contains( this, targets[i] ) ) { 2888 return true; 2889 } 2890 } 2891 }); 2892 }, 2893 2894 closest: function( selectors, context ) { 2895 var cur, 2896 i = 0, 2897 l = this.length, 2898 matched = [], 2899 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
vendor: 5,295 bytes, lines 2900-3087
2900 jQuery( selectors, context || this.context ) : 2901 0; 2902 2903 for ( ; i < l; i++ ) { 2904 for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { 2905 // Always skip document fragments 2906 if ( cur.nodeType < 11 && (pos ? 2907 pos.index(cur) > -1 : 2908 2909 // Don't pass non-elements to Sizzle 2910 cur.nodeType === 1 && 2911 jQuery.find.matchesSelector(cur, selectors)) ) { 2912 2913 matched.push( cur ); 2914 break; 2915 } 2916 } 2917 } 2918 2919 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); 2920 }, 2921 2922 // Determine the position of an element within the set 2923 index: function( elem ) { 2924 2925 // No argument, return index in parent 2926 if ( !elem ) { 2927 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 2928 } 2929 2930 // Index in selector 2931 if ( typeof elem === "string" ) { 2932 return indexOf.call( jQuery( elem ), this[ 0 ] ); 2933 } 2934 2935 // Locate the position of the desired element 2936 return indexOf.call( this, 2937 2938 // If it receives a jQuery object, the first element is used 2939 elem.jquery ? elem[ 0 ] : elem 2940 ); 2941 }, 2942 2943 add: function( selector, context ) { 2944 return this.pushStack( 2945 jQuery.unique( 2946 jQuery.merge( this.get(), jQuery( selector, context ) ) 2947 ) 2948 ); 2949 }, 2950 2951 addBack: function( selector ) { 2952 return this.add( selector == null ? 2953 this.prevObject : this.prevObject.filter(selector) 2954 ); 2955 } 2956}); 2957 2958function sibling( cur, dir ) { 2959 while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} 2960 return cur; 2961} 2962 2963jQuery.each({ 2964 parent: function( elem ) { 2965 var parent = elem.parentNode; 2966 return parent && parent.nodeType !== 11 ? parent : null; 2967 }, 2968 parents: function( elem ) { 2969 return jQuery.dir( elem, "parentNode" ); 2970 }, 2971 parentsUntil: function( elem, i, until ) { 2972 return jQuery.dir( elem, "parentNode", until ); 2973 }, 2974 next: function( elem ) { 2975 return sibling( elem, "nextSibling" ); 2976 }, 2977 prev: function( elem ) { 2978 return sibling( elem, "previousSibling" ); 2979 }, 2980 nextAll: function( elem ) { 2981 return jQuery.dir( elem, "nextSibling" ); 2982 }, 2983 prevAll: function( elem ) { 2984 return jQuery.dir( elem, "previousSibling" ); 2985 }, 2986 nextUntil: function( elem, i, until ) { 2987 return jQuery.dir( elem, "nextSibling", until ); 2988 }, 2989 prevUntil: function( elem, i, until ) { 2990 return jQuery.dir( elem, "previousSibling", until ); 2991 }, 2992 siblings: function( elem ) { 2993 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); 2994 }, 2995 children: function( elem ) { 2996 return jQuery.sibling( elem.firstChild ); 2997 }, 2998 contents: function( elem ) { 2999 return elem.contentDocument || jQuery.merge( [], elem.childNodes ); 3000 } 3001}, function( name, fn ) { 3002 jQuery.fn[ name ] = function( until, selector ) { 3003 var matched = jQuery.map( this, fn, until ); 3004 3005 if ( name.slice( -5 ) !== "Until" ) { 3006 selector = until; 3007 } 3008 3009 if ( selector && typeof selector === "string" ) { 3010 matched = jQuery.filter( selector, matched ); 3011 } 3012 3013 if ( this.length > 1 ) { 3014 // Remove duplicates 3015 if ( !guaranteedUnique[ name ] ) { 3016 jQuery.unique( matched ); 3017 } 3018 3019 // Reverse order for parents* and prev-derivatives 3020 if ( rparentsprev.test( name ) ) { 3021 matched.reverse(); 3022 } 3023 } 3024 3025 return this.pushStack( matched ); 3026 }; 3027}); 3028var rnotwhite = (/\S+/g); 3029 3030 3031 3032// String to Object options format cache 3033var optionsCache = {}; 3034 3035// Convert String-formatted options into Object-formatted ones and store in cache 3036function createOptions( options ) { 3037 var object = optionsCache[ options ] = {}; 3038 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { 3039 object[ flag ] = true; 3040 }); 3041 return object; 3042} 3043 3044/* 3045 * Create a callback list using the following parameters: 3046 * 3047 * options: an optional list of space-separated options that will change how 3048 * the callback list behaves or a more traditional option object 3049 * 3050 * By default a callback list will act like an event callback list and can be 3051 * "fired" multiple times. 3052 * 3053 * Possible options: 3054 * 3055 * once: will ensure the callback list can only be fired once (like a Deferred) 3056 * 3057 * memory: will keep track of previous values and will call any callback added 3058 * after the list has been fired right away with the latest "memorized" 3059 * values (like a Deferred) 3060 * 3061 * unique: will ensure a callback can only be added once (no duplicate in the list) 3062 * 3063 * stopOnFalse: interrupt callings when a callback returns false 3064 * 3065 */ 3066jQuery.Callbacks = function( options ) { 3067 3068 // Convert options from String-formatted to Object-formatted if needed 3069 // (we check in cache first) 3070 options = typeof options === "string" ? 3071 ( optionsCache[ options ] || createOptions( options ) ) : 3072 jQuery.extend( {}, options ); 3073 3074 var // Last fire value (for non-forgettable lists) 3075 memory, 3076 // Flag to know if list was already fired 3077 fired, 3078 // Flag to know if list is currently firing 3079 firing, 3080 // First callback to fire (used internally by add and fireWith) 3081 firingStart, 3082 // End of the loop when firing 3083 firingLength, 3084 // Index of currently firing callback (modified by remove if needed) 3085 firingIndex, 3086 // Actual callback list 3087 list = [],
3088 // Stack of fire calls for repeatable lists 3089 stack = !options.once && [], 3090 // Fire callbacks 3091 fire = function( data ) { 3092 memory = options.memory && data; 3093 fired = true; 3094 firingIndex = firingStart || 0; 3095 firingStart = 0; 3096 firingLength = list.length; 3097 firing = true; 3098 for ( ; list && firingIndex < firingLength; firingIndex++ ) { 3099 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { 3100 memory = false; // To prevent further calls using add 3101 break; 3102 } 3103 } 3104 firing = false; 3105 if ( list ) { 3106 if ( stack ) { 3107 if ( stack.length ) { 3108 fire( stack.shift() ); 3109 } 3110 } else if ( memory ) { 3111 list = []; 3112 } else { 3113 self.disable(); 3114 } 3115 } 3116 }, 3117 // Actual Callbacks object 3118 self = { 3119 // Add a callback or a collection of callbacks to the list 3120 add: function() { 3121 if ( list ) { 3122 // First, we save the current length 3123 var start = list.length; 3124 (function add( args ) { 3125 jQuery.each( args, function( _, arg ) { 3126 var type = jQuery.type( arg ); 3127 if ( type === "function" ) { 3128 if ( !options.unique || !self.has( arg ) ) { 3129 list.push( arg ); 3130 } 3131 } else if ( arg && arg.length && type !== "string" ) { 3132 // Inspect recursively 3133 add( arg ); 3134 } 3135 }); 3136 })( arguments ); 3137 // Do we need to add the callbacks to the 3138 // current firing batch? 3139 if ( firing ) { 3140 firingLength = list.length;
3141 // With memory, if we're not firing then 3142 // we should call right away 3143 } else if ( memory ) { 3144 firingStart = start; 3145 fire( memory ); 3146 } 3147 } 3148 return this; 3149 }, 3150 // Remove a callback from the list 3151 remove: function() { 3152 if ( list ) { 3153 jQuery.each( arguments, function( _, arg ) { 3154 var index; 3155 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3156 list.splice( index, 1 ); 3157 // Handle firing indexes 3158 if ( firing ) { 3159 if ( index <= firingLength ) { 3160 firingLength--; 3161 } 3162 if ( index <= firingIndex ) { 3163 firingIndex--; 3164 } 3165 } 3166 } 3167 }); 3168 } 3169 return this; 3170 }, 3171 // Check if a given callback is in the list. 3172 // If no argument is given, return whether or not list has callbacks attached. 3173 has: function( fn ) { 3174 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); 3175 }, 3176 // Remove all callbacks from the list 3177 empty: function() { 3178 list = []; 3179 firingLength = 0; 3180 return this; 3181 }, 3182 // Have the list do nothing anymore 3183 disable: function() { 3184 list = stack = memory = undefined; 3185 return this; 3186 }, 3187 // Is it disabled? 3188 disabled: function() { 3189 return !list; 3190 }, 3191 // Lock the list in its current state 3192 lock: function() { 3193 stack = undefined; 3194 if ( !memory ) { 3195 self.disable(); 3196 } 3197 return this; 3198 }, 3199 // Is it locked? 3200 locked: function() { 3201 return !stack; 3202 }, 3203 // Call all callbacks with the given context and arguments 3204 fireWith: function( context, args ) { 3205 if ( list && ( !fired || stack ) ) { 3206 args = args || []; 3207 args = [ context, args.slice ? args.slice() : args ]; 3208 if ( firing ) { 3209 stack.push( args ); 3210 } else { 3211 fire( args ); 3212 } 3213 } 3214 return this; 3215 }, 3216 // Call all the callbacks with the given arguments 3217 fire: function() { 3218 self.fireWith( this, arguments ); 3219 return this; 3220 }, 3221 // To know if the callbacks have already been called at least once 3222 fired: function() { 3223 return !!fired; 3224 } 3225 }; 3226 3227 return self; 3228}; 3229 3230 3231jQuery.extend({ 3232 3233 Deferred: function( func ) { 3234 var tuples = [ 3235 // action, add listener, listener list, final state 3236 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], 3237 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], 3238 [ "notify", "progress", jQuery.Callbacks("memory") ] 3239 ], 3240 state = "pending", 3241 promise = { 3242 state: function() { 3243 return state; 3244 }, 3245 always: function() { 3246 deferred.done( arguments ).fail( arguments ); 3247 return this; 3248 }, 3249 then: function( /* fnDone, fnFail, fnProgress */ ) { 3250 var fns = arguments; 3251 return jQuery.Deferred(function( newDefer ) { 3252 jQuery.each( tuples, function( i, tuple ) { 3253 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; 3254 // deferred[ done | fail | progress ] for forwarding actions to newDefer 3255 deferred[ tuple[1] ](function() { 3256 var returned = fn && fn.apply( this, arguments ); 3257 if ( returned && jQuery.isFunction( returned.promise ) ) { 3258 returned.promise() 3259 .done( newDefer.resolve ) 3260 .fail( newDefer.reject ) 3261 .progress( newDefer.notify ); 3262 } else { 3263 newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); 3264 } 3265 }); 3266 }); 3267 fns = null; 3268 }).promise(); 3269 }, 3270 // Get a promise for this deferred 3271 // If obj is provided, the promise aspect is added to the object 3272 promise: function( obj ) { 3273 return obj != null ? jQuery.extend( obj, promise ) : promise; 3274 } 3275 }, 3276 deferred = {}; 3277 3278 // Keep pipe for back-compat 3279 promise.pipe = promise.then; 3280 3281 // Add list-specific methods 3282 jQuery.each( tuples, function( i, tuple ) { 3283 var list = tuple[ 2 ], 3284 stateString = tuple[ 3 ]; 3285 3286 // promise[ done | fail | progress ] = list.add 3287 promise[ tuple[1] ] = list.add; 3288 3289 // Handle state 3290 if ( stateString ) { 3291 list.add(function() { 3292 // state = [ resolved | rejected ] 3293 state = stateString; 3294 3295 // [ reject_list | resolve_list ].disable; progress_list.lock 3296 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); 3297 } 3298 3299 // deferred[ resolve | reject | notify ] 3300 deferred[ tuple[0] ] = function() { 3301 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); 3302 return this; 3303 }; 3304 deferred[ tuple[0] + "With" ] = list.fireWith; 3305 }); 3306 3307 // Make the deferred a promise 3308 promise.promise( deferred ); 3309 3310 // Call given func if any 3311 if ( func ) { 3312 func.call( deferred, deferred ); 3313 } 3314 3315 // All done! 3316 return deferred; 3317 }, 3318 3319 // Deferred helper 3320 when: function( subordinate /* , ..., subordinateN */ ) { 3321 var i = 0, 3322 resolveValues = slice.call( arguments ), 3323 length = resolveValues.length, 3324 3325 // the count of uncompleted subordinates 3326 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, 3327 3328 // the master Deferred. If resolveValues consist of only a single Deferred, just use that. 3329 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 3330 3331 // Update function for both resolve and progress values 3332 updateFunc = function( i, contexts, values ) { 3333 return function( value ) { 3334 contexts[ i ] = this; 3335 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3336 if ( values === progressValues ) { 3337 deferred.notifyWith( contexts, values ); 3338 } else if ( !( --remaining ) ) { 3339 deferred.resolveWith( contexts, values ); 3340 } 3341 }; 3342 }, 3343 3344 progressValues, progressContexts, resolveContexts; 3345 3346 // Add listeners to Deferred subordinates; treat others as resolved 3347 if ( length > 1 ) { 3348 progressValues = new Array( length ); 3349 progressContexts = new Array( length ); 3350 resolveContexts = new Array( length ); 3351 for ( ; i < length; i++ ) { 3352 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { 3353 resolveValues[ i ].promise() 3354 .done( updateFunc( i, resolveContexts, resolveValues ) ) 3355 .fail( deferred.reject ) 3356 .progress( updateFunc( i, progressContexts, progressValues ) ); 3357 } else { 3358 --remaining; 3359 } 3360 } 3361 } 3362 3363 // If we're not waiting on anything, resolve the master 3364 if ( !remaining ) {
3365 deferred.resolveWith( resolveContexts, resolveValues ); 3366 } 3367 3368 return deferred.promise(); 3369 } 3370}); 3371 3372 3373// The deferred used on DOM ready 3374var readyList; 3375 3376jQuery.fn.ready = function( fn ) { 3377 // Add the callback 3378 jQuery.ready.promise().done( fn ); 3379 3380 return this; 3381}; 3382 3383jQuery.extend({ 3384 // Is the DOM ready to be used? Set to true once it occurs. 3385 isReady: false, 3386 3387 // A counter to track how many items to wait for before 3388 // the ready event fires. See #6781 3389 readyWait: 1, 3390 3391 // Hold (or release) the ready event 3392 holdReady: function( hold ) { 3393 if ( hold ) { 3394 jQuery.readyWait++; 3395 } else { 3396 jQuery.ready( true ); 3397 } 3398 }, 3399 3400 // Handle when the DOM is ready 3401 ready: function( wait ) { 3402 3403 // Abort if there are pending holds or we're already ready 3404 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3405 return; 3406 } 3407 3408 // Remember that the DOM is ready 3409 jQuery.isReady = true; 3410 3411 // If a normal DOM Ready event fired, decrement, and wait if need be 3412 if ( wait !== true && --jQuery.readyWait > 0 ) { 3413 return; 3414 } 3415 3416 // If there are functions bound, to execute 3417 readyList.resolveWith( document, [ jQuery ] ); 3418 3419 // Trigger any bound ready events 3420 if ( jQuery.fn.triggerHandler ) { 3421 jQuery( document ).triggerHandler( "ready" ); 3422 jQuery( document ).off( "ready" ); 3423 } 3424 } 3425}); 3426 3427/** 3428 * The ready event handler and self cleanup method 3429 */ 3430function completed() { 3431 document.removeEventListener( "DOMContentLoaded", completed, false ); 3432 window.removeEventListener( "load", completed, false ); 3433 jQuery.ready(); 3434} 3435 3436jQuery.ready.promise = function( obj ) { 3437 if ( !readyList ) { 3438 3439 readyList = jQuery.Deferred(); 3440 3441 // Catch cases where $(document).ready() is called after the browser event has already occurred. 3442 // We once tried to use readyState "interactive" here, but it caused issues like the one 3443 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 3444 if ( document.readyState === "complete" ) { 3445 // Handle it asynchronously to allow scripts the opportunity to delay ready 3446 setTimeout( jQuery.ready ); 3447 3448 } else { 3449 3450 // Use the handy event callback 3451 document.addEventListener( "DOMContentLoaded", completed, false ); 3452 3453 // A fallback to window.onload, that will always work 3454 window.addEventListener( "load", completed, false ); 3455 } 3456 } 3457 return readyList.promise( obj ); 3458}; 3459 3460// Kick off the DOM ready check even if the user does not 3461jQuery.ready.promise(); 3462 3463 3464 3465 3466// Multifunctional method to get and set values of a collection 3467// The value/s can optionally be executed if it's a function 3468var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 3469 var i = 0, 3470 len = elems.length, 3471 bulk = key == null; 3472 3473 // Sets many values 3474 if ( jQuery.type( key ) === "object" ) { 3475 chainable = true; 3476 for ( i in key ) { 3477 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); 3478 } 3479 3480 // Sets one value 3481 } else if ( value !== undefined ) { 3482 chainable = true; 3483 3484 if ( !jQuery.isFunction( value ) ) { 3485 raw = true; 3486 } 3487 3488 if ( bulk ) { 3489 // Bulk operations run against the entire set 3490 if ( raw ) { 3491 fn.call( elems, value ); 3492 fn = null; 3493 3494 // ...except when executing function values 3495 } else { 3496 bulk = fn; 3497 fn = function( elem, key, value ) { 3498 return bulk.call( jQuery( elem ), value ); 3499 }; 3500 } 3501 } 3502 3503 if ( fn ) { 3504 for ( ; i < len; i++ ) { 3505 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); 3506 } 3507 } 3508 } 3509 3510 return chainable ? 3511 elems : 3512 3513 // Gets 3514 bulk ? 3515 fn.call( elems ) : 3516 len ? fn( elems[0], key ) : emptyGet; 3517}; 3518 3519 3520/** 3521 * Determines whether an object can have data 3522 */ 3523jQuery.acceptData = function( owner ) { 3524 // Accepts only: 3525 // - Node 3526 // - Node.ELEMENT_NODE 3527 // - Node.DOCUMENT_NODE 3528 // - Object 3529 // - Any 3530 /* jshint -W018 */ 3531 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 3532}; 3533 3534 3535function Data() {
3536 // Support: Android<4, 3537 // Old WebKit does not have Object.preventExtensions/freeze method, 3538 // return new empty object instead with no [[set]] accessor 3539 Object.defineProperty( this.cache = {}, 0, { 3540 get: function() { 3541 return {}; 3542 } 3543 }); 3544 3545 this.expando = jQuery.expando + Data.uid++; 3546} 3547 3548Data.uid = 1; 3549Data.accepts = jQuery.acceptData; 3550 3551Data.prototype = { 3552 key: function( owner ) { 3553 // We can accept data for non-element nodes in modern browsers, 3554 // but we should not, see #8335. 3555 // Always return the key for a frozen object. 3556 if ( !Data.accepts( owner ) ) { 3557 return 0; 3558 } 3559 3560 var descriptor = {}, 3561 // Check if the owner object already has a cache key 3562 unlock = owner[ this.expando ]; 3563 3564 // If not, create one 3565 if ( !unlock ) { 3566 unlock = Data.uid++; 3567 3568 // Secure it in a non-enumerable, non-writable property 3569 try { 3570 descriptor[ this.expando ] = { value: unlock }; 3571 Object.defineProperties( owner, descriptor ); 3572 3573 // Support: Android<4 3574 // Fallback to a less secure definition 3575 } catch ( e ) { 3576 descriptor[ this.expando ] = unlock; 3577 jQuery.extend( owner, descriptor ); 3578 } 3579 } 3580 3581 // Ensure the cache object 3582 if ( !this.cache[ unlock ] ) { 3583 this.cache[ unlock ] = {}; 3584 } 3585 3586 return unlock; 3587 }, 3588 set: function( owner, data, value ) { 3589 var prop, 3590 // There may be an unlock assigned to this node, 3591 // if there is no entry for this "owner", create one inline 3592 // and set the unlock as though an owner entry had always existed 3593 unlock = this.key( owner ), 3594 cache = this.cache[ unlock ]; 3595 3596 // Handle: [ owner, key, value ] args 3597 if ( typeof data === "string" ) { 3598 cache[ data ] = value; 3599 3600 // Handle: [ owner, { properties } ] args 3601 } else { 3602 // Fresh assignments by object are shallow copied 3603 if ( jQuery.isEmptyObject( cache ) ) { 3604 jQuery.extend( this.cache[ unlock ], data ); 3605 // Otherwise, copy the properties one-by-one to the cache object 3606 } else { 3607 for ( prop in data ) { 3608 cache[ prop ] = data[ prop ]; 3609 } 3610 } 3611 } 3612 return cache; 3613 }, 3614 get: function( owner, key ) { 3615 // Either a valid cache is found, or will be created. 3616 // New caches will be created and the unlock returned, 3617 // allowing direct access to the newly created 3618 // empty data object. A valid owner object must be provided. 3619 var cache = this.cache[ this.key( owner ) ]; 3620 3621 return key === undefined ? 3622 cache : cache[ key ]; 3623 }, 3624 access: function( owner, key, value ) { 3625 var stored; 3626 // In cases where either: 3627 // 3628 // 1. No key was specified 3629 // 2. A string key was specified, but no value provided 3630 // 3631 // Take the "read" path and allow the get method to determine 3632 // which value to return, respectively either: 3633 // 3634 // 1. The entire cache object 3635 // 2. The data stored at the key 3636 // 3637 if ( key === undefined || 3638 ((key && typeof key === "string") && value === undefined) ) { 3639 3640 stored = this.get( owner, key ); 3641 3642 return stored !== undefined ? 3643 stored : this.get( owner, jQuery.camelCase(key) ); 3644 } 3645 3646 // [*]When the key is not a string, or both a key and value 3647 // are specified, set or extend (existing objects) with either: 3648 // 3649 // 1. An object of properties 3650 // 2. A key and value 3651 // 3652 this.set( owner, key, value ); 3653 3654 // Since the "set" path can have two possible entry points 3655 // return the expected data based on which path was taken[*] 3656 return value !== undefined ? value : key; 3657 }, 3658 remove: function( owner, key ) { 3659 var i, name, camel, 3660 unlock = this.key( owner ), 3661 cache = this.cache[ unlock ]; 3662 3663 if ( key === undefined ) { 3664 this.cache[ unlock ] = {}; 3665 3666 } else { 3667 // Support array or space separated string of keys 3668 if ( jQuery.isArray( key ) ) { 3669 // If "name" is an array of keys... 3670 // When data is initially created, via ("key", "val") signature, 3671 // keys will be converted to camelCase. 3672 // Since there is no way to tell _how_ a key was added, remove 3673 // both plain key and camelCase key. #12786 3674 // This will only penalize the array argument path. 3675 name = key.concat( key.map( jQuery.camelCase ) ); 3676 } else { 3677 camel = jQuery.camelCase( key ); 3678 // Try the string as a key before any manipulation 3679 if ( key in cache ) { 3680 name = [ key, camel ]; 3681 } else { 3682 // If a key with the spaces exists, use it. 3683 // Otherwise, create an array by matching non-whitespace 3684 name = camel; 3685 name = name in cache ? 3686 [ name ] : ( name.match( rnotwhite ) || [] ); 3687 } 3688 } 3689 3690 i = name.length; 3691 while ( i-- ) { 3692 delete cache[ name[ i ] ]; 3693 } 3694 } 3695 }, 3696 hasData: function( owner ) { 3697 return !jQuery.isEmptyObject( 3698 this.cache[ owner[ this.expando ] ] || {} 3699 ); 3700 }, 3701 discard: function( owner ) { 3702 if ( owner[ this.expando ] ) { 3703 delete this.cache[ owner[ this.expando ] ]; 3704 } 3705 } 3706}; 3707var data_priv = new Data(); 3708 3709var data_user = new Data(); 3710 3711 3712 3713// Implementation Summary 3714// 3715// 1. Enforce API surface and semantic compatibility with 1.9.x branch 3716// 2. Improve the module's maintainability by reducing the storage 3717// paths to a single mechanism.
vendor: 4,560 bytes, lines 3718-3864
3718// 3. Use the same single mechanism to support "private" and "user" data. 3719// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 3720// 5. Avoid exposing implementation details on user objects (eg. expando properties) 3721// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 3722 3723var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 3724 rmultiDash = /([A-Z])/g; 3725 3726function dataAttr( elem, key, data ) { 3727 var name; 3728 3729 // If nothing was found internally, try to fetch any 3730 // data from the HTML5 data-* attribute 3731 if ( data === undefined && elem.nodeType === 1 ) { 3732 name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); 3733 data = elem.getAttribute( name ); 3734 3735 if ( typeof data === "string" ) { 3736 try { 3737 data = data === "true" ? true : 3738 data === "false" ? false : 3739 data === "null" ? null : 3740 // Only convert to a number if it doesn't change the string 3741 +data + "" === data ? +data : 3742 rbrace.test( data ) ? jQuery.parseJSON( data ) : 3743 data; 3744 } catch( e ) {} 3745 3746 // Make sure we set the data so it isn't changed later 3747 data_user.set( elem, key, data ); 3748 } else { 3749 data = undefined; 3750 } 3751 } 3752 return data; 3753} 3754 3755jQuery.extend({ 3756 hasData: function( elem ) { 3757 return data_user.hasData( elem ) || data_priv.hasData( elem ); 3758 }, 3759 3760 data: function( elem, name, data ) { 3761 return data_user.access( elem, name, data ); 3762 }, 3763 3764 removeData: function( elem, name ) { 3765 data_user.remove( elem, name ); 3766 }, 3767 3768 // TODO: Now that all calls to _data and _removeData have been replaced 3769 // with direct calls to data_priv methods, these can be deprecated. 3770 _data: function( elem, name, data ) { 3771 return data_priv.access( elem, name, data ); 3772 }, 3773 3774 _removeData: function( elem, name ) { 3775 data_priv.remove( elem, name ); 3776 } 3777}); 3778 3779jQuery.fn.extend({ 3780 data: function( key, value ) { 3781 var i, name, data, 3782 elem = this[ 0 ], 3783 attrs = elem && elem.attributes; 3784 3785 // Gets all values 3786 if ( key === undefined ) { 3787 if ( this.length ) { 3788 data = data_user.get( elem ); 3789 3790 if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { 3791 i = attrs.length; 3792 while ( i-- ) { 3793 3794 // Support: IE11+ 3795 // The attrs elements can be null (#14894) 3796 if ( attrs[ i ] ) { 3797 name = attrs[ i ].name; 3798 if ( name.indexOf( "data-" ) === 0 ) { 3799 name = jQuery.camelCase( name.slice(5) ); 3800 dataAttr( elem, name, data[ name ] ); 3801 } 3802 } 3803 } 3804 data_priv.set( elem, "hasDataAttrs", true ); 3805 } 3806 } 3807 3808 return data; 3809 } 3810 3811 // Sets multiple values 3812 if ( typeof key === "object" ) { 3813 return this.each(function() { 3814 data_user.set( this, key ); 3815 }); 3816 } 3817 3818 return access( this, function( value ) { 3819 var data, 3820 camelKey = jQuery.camelCase( key ); 3821 3822 // The calling jQuery object (element matches) is not empty 3823 // (and therefore has an element appears at this[ 0 ]) and the 3824 // `value` parameter was not undefined. An empty jQuery object 3825 // will result in `undefined` for elem = this[ 0 ] which will 3826 // throw an exception if an attempt to read a data cache is made. 3827 if ( elem && value === undefined ) { 3828 // Attempt to get data from the cache 3829 // with the key as-is 3830 data = data_user.get( elem, key ); 3831 if ( data !== undefined ) { 3832 return data; 3833 } 3834 3835 // Attempt to get data from the cache 3836 // with the key camelized 3837 data = data_user.get( elem, camelKey ); 3838 if ( data !== undefined ) { 3839 return data; 3840 } 3841 3842 // Attempt to "discover" the data in 3843 // HTML5 custom data-* attrs 3844 data = dataAttr( elem, camelKey, undefined ); 3845 if ( data !== undefined ) { 3846 return data; 3847 } 3848 3849 // We tried really hard, but the data doesn't exist. 3850 return; 3851 } 3852 3853 // Set the data... 3854 this.each(function() { 3855 // First, attempt to store a copy or reference of any 3856 // data that might've been store with a camelCased key. 3857 var data = data_user.get( this, camelKey ); 3858 3859 // For HTML5 data-* attribute interop, we have to 3860 // store property names with dashes in a camelCase form. 3861 // This might not apply to all properties...* 3862 data_user.set( this, camelKey, value ); 3863 3864 // *... In the case of properties that might _actually_
vendor: 4,251 bytes, lines 3865-4033
3865 // have dashes, we need to also store a copy of that 3866 // unchanged property. 3867 if ( key.indexOf("-") !== -1 && data !== undefined ) { 3868 data_user.set( this, key, value ); 3869 } 3870 }); 3871 }, null, value, arguments.length > 1, null, true ); 3872 }, 3873 3874 removeData: function( key ) { 3875 return this.each(function() { 3876 data_user.remove( this, key ); 3877 }); 3878 } 3879}); 3880 3881 3882jQuery.extend({ 3883 queue: function( elem, type, data ) { 3884 var queue; 3885 3886 if ( elem ) { 3887 type = ( type || "fx" ) + "queue"; 3888 queue = data_priv.get( elem, type ); 3889 3890 // Speed up dequeue by getting out quickly if this is just a lookup 3891 if ( data ) { 3892 if ( !queue || jQuery.isArray( data ) ) { 3893 queue = data_priv.access( elem, type, jQuery.makeArray(data) ); 3894 } else { 3895 queue.push( data ); 3896 } 3897 } 3898 return queue || []; 3899 } 3900 }, 3901 3902 dequeue: function( elem, type ) { 3903 type = type || "fx"; 3904 3905 var queue = jQuery.queue( elem, type ), 3906 startLength = queue.length, 3907 fn = queue.shift(), 3908 hooks = jQuery._queueHooks( elem, type ), 3909 next = function() { 3910 jQuery.dequeue( elem, type ); 3911 }; 3912 3913 // If the fx queue is dequeued, always remove the progress sentinel 3914 if ( fn === "inprogress" ) { 3915 fn = queue.shift(); 3916 startLength--; 3917 } 3918 3919 if ( fn ) { 3920 3921 // Add a progress sentinel to prevent the fx queue from being 3922 // automatically dequeued 3923 if ( type === "fx" ) { 3924 queue.unshift( "inprogress" ); 3925 } 3926 3927 // Clear up the last queue stop function 3928 delete hooks.stop; 3929 fn.call( elem, next, hooks ); 3930 } 3931 3932 if ( !startLength && hooks ) { 3933 hooks.empty.fire(); 3934 } 3935 }, 3936 3937 // Not public - generate a queueHooks object, or return the current one 3938 _queueHooks: function( elem, type ) { 3939 var key = type + "queueHooks"; 3940 return data_priv.get( elem, key ) || data_priv.access( elem, key, { 3941 empty: jQuery.Callbacks("once memory").add(function() { 3942 data_priv.remove( elem, [ type + "queue", key ] ); 3943 }) 3944 }); 3945 } 3946}); 3947 3948jQuery.fn.extend({ 3949 queue: function( type, data ) { 3950 var setter = 2; 3951 3952 if ( typeof type !== "string" ) { 3953 data = type; 3954 type = "fx"; 3955 setter--; 3956 } 3957 3958 if ( arguments.length < setter ) { 3959 return jQuery.queue( this[0], type ); 3960 } 3961 3962 return data === undefined ? 3963 this : 3964 this.each(function() { 3965 var queue = jQuery.queue( this, type, data ); 3966 3967 // Ensure a hooks for this queue 3968 jQuery._queueHooks( this, type ); 3969 3970 if ( type === "fx" && queue[0] !== "inprogress" ) { 3971 jQuery.dequeue( this, type ); 3972 } 3973 }); 3974 }, 3975 dequeue: function( type ) { 3976 return this.each(function() { 3977 jQuery.dequeue( this, type ); 3978 }); 3979 }, 3980 clearQueue: function( type ) { 3981 return this.queue( type || "fx", [] ); 3982 }, 3983 // Get a promise resolved when queues of a certain type 3984 // are emptied (fx is the type by default) 3985 promise: function( type, obj ) { 3986 var tmp, 3987 count = 1, 3988 defer = jQuery.Deferred(), 3989 elements = this, 3990 i = this.length, 3991 resolve = function() { 3992 if ( !( --count ) ) { 3993 defer.resolveWith( elements, [ elements ] ); 3994 } 3995 }; 3996 3997 if ( typeof type !== "string" ) { 3998 obj = type; 3999 type = undefined; 4000 } 4001 type = type || "fx"; 4002 4003 while ( i-- ) { 4004 tmp = data_priv.get( elements[ i ], type + "queueHooks" ); 4005 if ( tmp && tmp.empty ) { 4006 count++; 4007 tmp.empty.add( resolve ); 4008 } 4009 } 4010 resolve(); 4011 return defer.promise( obj ); 4012 } 4013}); 4014var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; 4015 4016var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4017 4018var isHidden = function( elem, el ) { 4019 // isHidden might be called from jQuery#filter function; 4020 // in that case, element will be second argument 4021 elem = el || elem; 4022 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); 4023 }; 4024 4025var rcheckableType = (/^(?:checkbox|radio)$/i); 4026 4027 4028 4029(function() { 4030 var fragment = document.createDocumentFragment(), 4031 div = fragment.appendChild( document.createElement( "div" ) ), 4032 input = document.createElement( "input" ); 4033
vendor: 14,010 bytes, lines 4034-4462
4034 // Support: Safari<=5.1 4035 // Check state lost if the name is set (#11217) 4036 // Support: Windows Web Apps (WWA) 4037 // `name` and `type` must use .setAttribute for WWA (#14901) 4038 input.setAttribute( "type", "radio" ); 4039 input.setAttribute( "checked", "checked" ); 4040 input.setAttribute( "name", "t" ); 4041 4042 div.appendChild( input ); 4043 4044 // Support: Safari<=5.1, Android<4.2 4045 // Older WebKit doesn't clone checked state correctly in fragments 4046 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4047 4048 // Support: IE<=11+ 4049 // Make sure textarea (and checkbox) defaultValue is properly cloned 4050 div.innerHTML = "<textarea>x</textarea>"; 4051 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4052})(); 4053var strundefined = typeof undefined; 4054 4055 4056 4057support.focusinBubbles = "onfocusin" in window; 4058 4059 4060var 4061 rkeyEvent = /^key/, 4062 rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, 4063 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 4064 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; 4065 4066function returnTrue() { 4067 return true; 4068} 4069 4070function returnFalse() { 4071 return false; 4072} 4073 4074function safeActiveElement() { 4075 try { 4076 return document.activeElement; 4077 } catch ( err ) { } 4078} 4079 4080/* 4081 * Helper functions for managing events -- not part of the public interface. 4082 * Props to Dean Edwards' addEvent library for many of the ideas. 4083 */ 4084jQuery.event = { 4085 4086 global: {}, 4087 4088 add: function( elem, types, handler, data, selector ) { 4089 4090 var handleObjIn, eventHandle, tmp, 4091 events, t, handleObj, 4092 special, handlers, type, namespaces, origType, 4093 elemData = data_priv.get( elem ); 4094 4095 // Don't attach events to noData or text/comment nodes (but allow plain objects) 4096 if ( !elemData ) { 4097 return; 4098 } 4099 4100 // Caller can pass in an object of custom data in lieu of the handler 4101 if ( handler.handler ) { 4102 handleObjIn = handler; 4103 handler = handleObjIn.handler; 4104 selector = handleObjIn.selector; 4105 } 4106 4107 // Make sure that the handler has a unique ID, used to find/remove it later 4108 if ( !handler.guid ) { 4109 handler.guid = jQuery.guid++; 4110 } 4111 4112 // Init the element's event structure and main handler, if this is the first 4113 if ( !(events = elemData.events) ) { 4114 events = elemData.events = {}; 4115 } 4116 if ( !(eventHandle = elemData.handle) ) { 4117 eventHandle = elemData.handle = function( e ) { 4118 // Discard the second event of a jQuery.event.trigger() and 4119 // when an event is called after a page has unloaded 4120 return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? 4121 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 4122 }; 4123 } 4124 4125 // Handle multiple events separated by a space 4126 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4127 t = types.length; 4128 while ( t-- ) { 4129 tmp = rtypenamespace.exec( types[t] ) || []; 4130 type = origType = tmp[1]; 4131 namespaces = ( tmp[2] || "" ).split( "." ).sort(); 4132 4133 // There *must* be a type, no attaching namespace-only handlers 4134 if ( !type ) { 4135 continue; 4136 } 4137 4138 // If event changes its type, use the special event handlers for the changed type 4139 special = jQuery.event.special[ type ] || {}; 4140 4141 // If selector defined, determine special event api type, otherwise given type 4142 type = ( selector ? special.delegateType : special.bindType ) || type; 4143 4144 // Update special based on newly reset type 4145 special = jQuery.event.special[ type ] || {}; 4146 4147 // handleObj is passed to all event handlers 4148 handleObj = jQuery.extend({ 4149 type: type, 4150 origType: origType, 4151 data: data, 4152 handler: handler, 4153 guid: handler.guid, 4154 selector: selector, 4155 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 4156 namespace: namespaces.join(".") 4157 }, handleObjIn ); 4158 4159 // Init the event handler queue if we're the first 4160 if ( !(handlers = events[ type ]) ) { 4161 handlers = events[ type ] = []; 4162 handlers.delegateCount = 0; 4163 4164 // Only use addEventListener if the special events handler returns false 4165 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 4166 if ( elem.addEventListener ) { 4167 elem.addEventListener( type, eventHandle, false ); 4168 } 4169 } 4170 } 4171 4172 if ( special.add ) { 4173 special.add.call( elem, handleObj ); 4174 4175 if ( !handleObj.handler.guid ) { 4176 handleObj.handler.guid = handler.guid; 4177 } 4178 } 4179 4180 // Add to the element's handler list, delegates in front 4181 if ( selector ) { 4182 handlers.splice( handlers.delegateCount++, 0, handleObj ); 4183 } else { 4184 handlers.push( handleObj ); 4185 } 4186 4187 // Keep track of which events have ever been used, for event optimization 4188 jQuery.event.global[ type ] = true; 4189 } 4190 4191 }, 4192 4193 // Detach an event or set of events from an element 4194 remove: function( elem, types, handler, selector, mappedTypes ) { 4195 4196 var j, origCount, tmp, 4197 events, t, handleObj, 4198 special, handlers, type, namespaces, origType, 4199 elemData = data_priv.hasData( elem ) && data_priv.get( elem ); 4200 4201 if ( !elemData || !(events = elemData.events) ) { 4202 return; 4203 } 4204 4205 // Once for each type.namespace in types; type may be omitted 4206 types = ( types || "" ).match( rnotwhite ) || [ "" ]; 4207 t = types.length; 4208 while ( t-- ) { 4209 tmp = rtypenamespace.exec( types[t] ) || []; 4210 type = origType = tmp[1]; 4211 namespaces = ( tmp[2] || "" ).split( "." ).sort(); 4212 4213 // Unbind all events (on this namespace, if provided) for the element 4214 if ( !type ) { 4215 for ( type in events ) { 4216 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 4217 } 4218 continue; 4219 } 4220 4221 special = jQuery.event.special[ type ] || {}; 4222 type = ( selector ? special.delegateType : special.bindType ) || type; 4223 handlers = events[ type ] || []; 4224 tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); 4225 4226 // Remove matching events 4227 origCount = j = handlers.length; 4228 while ( j-- ) { 4229 handleObj = handlers[ j ]; 4230 4231 if ( ( mappedTypes || origType === handleObj.origType ) && 4232 ( !handler || handler.guid === handleObj.guid ) && 4233 ( !tmp || tmp.test( handleObj.namespace ) ) && 4234 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { 4235 handlers.splice( j, 1 ); 4236 4237 if ( handleObj.selector ) { 4238 handlers.delegateCount--; 4239 } 4240 if ( special.remove ) { 4241 special.remove.call( elem, handleObj ); 4242 } 4243 } 4244 } 4245 4246 // Remove generic event handler if we removed something and no more handlers exist 4247 // (avoids potential for endless recursion during removal of special event handlers) 4248 if ( origCount && !handlers.length ) { 4249 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 4250 jQuery.removeEvent( elem, type, elemData.handle ); 4251 } 4252 4253 delete events[ type ]; 4254 } 4255 } 4256 4257 // Remove the expando if it's no longer used 4258 if ( jQuery.isEmptyObject( events ) ) { 4259 delete elemData.handle; 4260 data_priv.remove( elem, "events" ); 4261 } 4262 }, 4263 4264 trigger: function( event, data, elem, onlyHandlers ) { 4265 4266 var i, cur, tmp, bubbleType, ontype, handle, special, 4267 eventPath = [ elem || document ], 4268 type = hasOwn.call( event, "type" ) ? event.type : event, 4269 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; 4270 4271 cur = tmp = elem = elem || document; 4272 4273 // Don't do events on text and comment nodes 4274 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 4275 return; 4276 } 4277 4278 // focus/blur morphs to focusin/out; ensure we're not firing them right now 4279 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 4280 return; 4281 } 4282 4283 if ( type.indexOf(".") >= 0 ) { 4284 // Namespaced trigger; create a regexp to match event type in handle() 4285 namespaces = type.split("."); 4286 type = namespaces.shift(); 4287 namespaces.sort(); 4288 } 4289 ontype = type.indexOf(":") < 0 && "on" + type; 4290 4291 // Caller can pass in a jQuery.Event object, Object, or just an event type string 4292 event = event[ jQuery.expando ] ? 4293 event : 4294 new jQuery.Event( type, typeof event === "object" && event ); 4295 4296 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 4297 event.isTrigger = onlyHandlers ? 2 : 3; 4298 event.namespace = namespaces.join("."); 4299 event.namespace_re = event.namespace ? 4300 new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : 4301 null; 4302 4303 // Clean up the event in case it is being reused 4304 event.result = undefined; 4305 if ( !event.target ) { 4306 event.target = elem; 4307 } 4308 4309 // Clone any incoming data and prepend the event, creating the handler arg list 4310 data = data == null ? 4311 [ event ] : 4312 jQuery.makeArray( data, [ event ] ); 4313 4314 // Allow special events to draw outside the lines 4315 special = jQuery.event.special[ type ] || {}; 4316 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 4317 return; 4318 } 4319 4320 // Determine event propagation path in advance, per W3C events spec (#9951) 4321 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 4322 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { 4323 4324 bubbleType = special.delegateType || type; 4325 if ( !rfocusMorph.test( bubbleType + type ) ) { 4326 cur = cur.parentNode; 4327 } 4328 for ( ; cur; cur = cur.parentNode ) { 4329 eventPath.push( cur ); 4330 tmp = cur; 4331 } 4332 4333 // Only add window if we got to document (e.g., not plain obj or detached DOM) 4334 if ( tmp === (elem.ownerDocument || document) ) { 4335 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 4336 } 4337 } 4338 4339 // Fire handlers on the event path 4340 i = 0; 4341 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { 4342 4343 event.type = i > 1 ? 4344 bubbleType : 4345 special.bindType || type; 4346 4347 // jQuery handler 4348 handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); 4349 if ( handle ) { 4350 handle.apply( cur, data ); 4351 } 4352 4353 // Native handler 4354 handle = ontype && cur[ ontype ]; 4355 if ( handle && handle.apply && jQuery.acceptData( cur ) ) { 4356 event.result = handle.apply( cur, data ); 4357 if ( event.result === false ) { 4358 event.preventDefault(); 4359 } 4360 } 4361 } 4362 event.type = type; 4363 4364 // If nobody prevented the default action, do it now 4365 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 4366 4367 if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && 4368 jQuery.acceptData( elem ) ) { 4369 4370 // Call a native DOM method on the target with the same name name as the event. 4371 // Don't do default actions on window, that's where global variables be (#6170) 4372 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { 4373 4374 // Don't re-trigger an onFOO event when we call its FOO() method 4375 tmp = elem[ ontype ]; 4376 4377 if ( tmp ) { 4378 elem[ ontype ] = null; 4379 } 4380 4381 // Prevent re-triggering of the same event, since we already bubbled it above 4382 jQuery.event.triggered = type; 4383 elem[ type ](); 4384 jQuery.event.triggered = undefined; 4385 4386 if ( tmp ) { 4387 elem[ ontype ] = tmp; 4388 } 4389 } 4390 } 4391 } 4392 4393 return event.result; 4394 }, 4395 4396 dispatch: function( event ) { 4397 4398 // Make a writable jQuery.Event from the native event object 4399 event = jQuery.event.fix( event ); 4400 4401 var i, j, ret, matched, handleObj, 4402 handlerQueue = [], 4403 args = slice.call( arguments ), 4404 handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], 4405 special = jQuery.event.special[ event.type ] || {}; 4406 4407 // Use the fix-ed jQuery.Event rather than the (read-only) native event 4408 args[0] = event; 4409 event.delegateTarget = this; 4410 4411 // Call the preDispatch hook for the mapped type, and let it bail if desired 4412 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 4413 return; 4414 } 4415 4416 // Determine handlers 4417 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 4418 4419 // Run delegates first; they may want to stop propagation beneath us 4420 i = 0; 4421 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { 4422 event.currentTarget = matched.elem; 4423 4424 j = 0; 4425 while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { 4426 4427 // Triggered event must either 1) have no namespace, or 2) have namespace(s) 4428 // a subset or equal to those in the bound event (both can have no namespace). 4429 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { 4430 4431 event.handleObj = handleObj; 4432 event.data = handleObj.data; 4433 4434 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) 4435 .apply( matched.elem, args ); 4436 4437 if ( ret !== undefined ) { 4438 if ( (event.result = ret) === false ) { 4439 event.preventDefault(); 4440 event.stopPropagation(); 4441 } 4442 } 4443 } 4444 } 4445 } 4446 4447 // Call the postDispatch hook for the mapped type 4448 if ( special.postDispatch ) { 4449 special.postDispatch.call( this, event ); 4450 } 4451 4452 return event.result; 4453 }, 4454 4455 handlers: function( event, handlers ) { 4456 var i, matches, sel, handleObj, 4457 handlerQueue = [], 4458 delegateCount = handlers.delegateCount, 4459 cur = event.target; 4460 4461 // Find delegate handlers 4462 // Black-hole SVG <use> instance trees (#13180)
4463 // Avoid non-left-click bubbling in Firefox (#3861) 4464 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { 4465 4466 for ( ; cur !== this; cur = cur.parentNode || this ) { 4467 4468 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 4469 if ( cur.disabled !== true || event.type !== "click" ) { 4470 matches = []; 4471 for ( i = 0; i < delegateCount; i++ ) { 4472 handleObj = handlers[ i ]; 4473 4474 // Don't conflict with Object.prototype properties (#13203) 4475 sel = handleObj.selector + " "; 4476 4477 if ( matches[ sel ] === undefined ) { 4478 matches[ sel ] = handleObj.needsContext ? 4479 jQuery( sel, this ).index( cur ) >= 0 : 4480 jQuery.find( sel, this, null, [ cur ] ).length; 4481 } 4482 if ( matches[ sel ] ) { 4483 matches.push( handleObj ); 4484 } 4485 } 4486 if ( matches.length ) { 4487 handlerQueue.push({ elem: cur, handlers: matches }); 4488 } 4489 } 4490 } 4491 } 4492 4493 // Add the remaining (directly-bound) handlers 4494 if ( delegateCount < handlers.length ) { 4495 handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); 4496 } 4497 4498 return handlerQueue; 4499 }, 4500 4501 // Includes some event props shared by KeyEvent and MouseEvent 4502 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), 4503 4504 fixHooks: {}, 4505 4506 keyHooks: { 4507 props: "char charCode key keyCode".split(" "), 4508 filter: function( event, original ) { 4509 4510 // Add which for key events 4511 if ( event.which == null ) { 4512 event.which = original.charCode != null ? original.charCode : original.keyCode; 4513 } 4514 4515 return event; 4516 } 4517 }, 4518 4519 mouseHooks: { 4520 props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), 4521 filter: function( event, original ) { 4522 var eventDoc, doc, body, 4523 button = original.button; 4524 4525 // Calculate pageX/Y if missing and clientX/Y available 4526 if ( event.pageX == null && original.clientX != null ) { 4527 eventDoc = event.target.ownerDocument || document; 4528 doc = eventDoc.documentElement; 4529 body = eventDoc.body; 4530 4531 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); 4532 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); 4533 } 4534 4535 // Add which for click: 1 === left; 2 === middle; 3 === right 4536 // Note: button is not normalized, so don't use it 4537 if ( !event.which && button !== undefined ) { 4538 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); 4539 } 4540 4541 return event; 4542 } 4543 }, 4544 4545 fix: function( event ) { 4546 if ( event[ jQuery.expando ] ) { 4547 return event; 4548 } 4549 4550 // Create a writable copy of the event object and normalize some properties 4551 var i, prop, copy, 4552 type = event.type, 4553 originalEvent = event, 4554 fixHook = this.fixHooks[ type ]; 4555 4556 if ( !fixHook ) { 4557 this.fixHooks[ type ] = fixHook = 4558 rmouseEvent.test( type ) ? this.mouseHooks : 4559 rkeyEvent.test( type ) ? this.keyHooks : 4560 {}; 4561 } 4562 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; 4563 4564 event = new jQuery.Event( originalEvent ); 4565 4566 i = copy.length; 4567 while ( i-- ) { 4568 prop = copy[ i ]; 4569 event[ prop ] = originalEvent[ prop ]; 4570 } 4571 4572 // Support: Cordova 2.5 (WebKit) (#13255) 4573 // All events should have a target; Cordova deviceready doesn't 4574 if ( !event.target ) { 4575 event.target = document; 4576 } 4577 4578 // Support: Safari 6.0+, Chrome<28 4579 // Target should not be a text node (#504, #13143) 4580 if ( event.target.nodeType === 3 ) { 4581 event.target = event.target.parentNode; 4582 } 4583 4584 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; 4585 }, 4586 4587 special: { 4588 load: { 4589 // Prevent triggered image.load events from bubbling to window.load 4590 noBubble: true 4591 }, 4592 focus: { 4593 // Fire native event if possible so blur/focus sequence is correct 4594 trigger: function() { 4595 if ( this !== safeActiveElement() && this.focus ) { 4596 this.focus(); 4597 return false;
4598 } 4599 }, 4600 delegateType: "focusin" 4601 }, 4602 blur: { 4603 trigger: function() { 4604 if ( this === safeActiveElement() && this.blur ) { 4605 this.blur(); 4606 return false; 4607 } 4608 }, 4609 delegateType: "focusout" 4610 }, 4611 click: { 4612 // For checkbox, fire native event so checked state will be right 4613 trigger: function() { 4614 if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { 4615 this.click(); 4616 return false; 4617 } 4618 }, 4619 4620 // For cross-browser consistency, don't fire native .click() on links 4621 _default: function( event ) { 4622 return jQuery.nodeName( event.target, "a" ); 4623 } 4624 }, 4625 4626 beforeunload: { 4627 postDispatch: function( event ) { 4628 4629 // Support: Firefox 20+ 4630 // Firefox doesn't alert if the returnValue field is not set. 4631 if ( event.result !== undefined && event.originalEvent ) { 4632 event.originalEvent.returnValue = event.result; 4633 } 4634 } 4635 } 4636 }, 4637 4638 simulate: function( type, elem, event, bubble ) { 4639 // Piggyback on a donor event to simulate a different one. 4640 // Fake originalEvent to avoid donor's stopPropagation, but if the 4641 // simulated event prevents default then we do the same on the donor. 4642 var e = jQuery.extend( 4643 new jQuery.Event(), 4644 event, 4645 { 4646 type: type, 4647 isSimulated: true, 4648 originalEvent: {} 4649 } 4650 ); 4651 if ( bubble ) { 4652 jQuery.event.trigger( e, null, elem ); 4653 } else { 4654 jQuery.event.dispatch.call( elem, e ); 4655 } 4656 if ( e.isDefaultPrevented() ) { 4657 event.preventDefault(); 4658 } 4659 } 4660}; 4661 4662jQuery.removeEvent = function( elem, type, handle ) { 4663 if ( elem.removeEventListener ) { 4664 elem.removeEventListener( type, handle, false ); 4665 } 4666}; 4667 4668jQuery.Event = function( src, props ) { 4669 // Allow instantiation without the 'new' keyword 4670 if ( !(this instanceof jQuery.Event) ) { 4671 return new jQuery.Event( src, props ); 4672 } 4673 4674 // Event object 4675 if ( src && src.type ) { 4676 this.originalEvent = src; 4677 this.type = src.type; 4678 4679 // Events bubbling up the document may have been marked as prevented 4680 // by a handler lower down the tree; reflect the correct value. 4681 this.isDefaultPrevented = src.defaultPrevented || 4682 src.defaultPrevented === undefined && 4683 // Support: Android<4.0 4684 src.returnValue === false ? 4685 returnTrue : 4686 returnFalse; 4687 4688 // Event type 4689 } else { 4690 this.type = src; 4691 } 4692 4693 // Put explicitly provided properties onto the event object 4694 if ( props ) { 4695 jQuery.extend( this, props ); 4696 } 4697 4698 // Create a timestamp if incoming event doesn't have one 4699 this.timeStamp = src && src.timeStamp || jQuery.now(); 4700 4701 // Mark it as fixed 4702 this[ jQuery.expando ] = true; 4703}; 4704 4705// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 4706// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 4707jQuery.Event.prototype = { 4708 isDefaultPrevented: returnFalse, 4709 isPropagationStopped: returnFalse, 4710 isImmediatePropagationStopped: returnFalse, 4711 4712 preventDefault: function() { 4713 var e = this.originalEvent; 4714 4715 this.isDefaultPrevented = returnTrue; 4716 4717 if ( e && e.preventDefault ) { 4718 e.preventDefault(); 4719 } 4720 }, 4721 stopPropagation: function() { 4722 var e = this.originalEvent; 4723 4724 this.isPropagationStopped = returnTrue; 4725 4726 if ( e && e.stopPropagation ) { 4727 e.stopPropagation(); 4728 } 4729 }, 4730 stopImmediatePropagation: function() { 4731 var e = this.originalEvent; 4732 4733 this.isImmediatePropagationStopped = returnTrue; 4734 4735 if ( e && e.stopImmediatePropagation ) { 4736 e.stopImmediatePropagation(); 4737 } 4738 4739 this.stopPropagation(); 4740 } 4741}; 4742 4743// Create mouseenter/leave events using mouseover/out and event-time checks 4744// Support: Chrome 15+ 4745jQuery.each({ 4746 mouseenter: "mouseover", 4747 mouseleave: "mouseout", 4748 pointerenter: "pointerover", 4749 pointerleave: "pointerout" 4750}, function( orig, fix ) { 4751 jQuery.event.special[ orig ] = { 4752 delegateType: fix, 4753 bindType: fix, 4754 4755 handle: function( event ) { 4756 var ret, 4757 target = this, 4758 related = event.relatedTarget, 4759 handleObj = event.handleObj; 4760 4761 // For mousenter/leave call the handler if related is outside the target. 4762 // NB: No relatedTarget if the mouse left/entered the browser window 4763 if ( !related || (related !== target && !jQuery.contains( target, related )) ) { 4764 event.type = handleObj.origType; 4765 ret = handleObj.handler.apply( this, arguments ); 4766 event.type = fix; 4767 } 4768 return ret; 4769 } 4770 }; 4771}); 4772 4773// Support: Firefox, Chrome, Safari 4774// Create "bubbling" focus and blur events 4775if ( !support.focusinBubbles ) { 4776 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { 4777 4778 // Attach a single capturing handler on the document while someone wants focusin/focusout 4779 var handler = function( event ) { 4780 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); 4781 }; 4782 4783 jQuery.event.special[ fix ] = { 4784 setup: function() { 4785 var doc = this.ownerDocument || this, 4786 attaches = data_priv.access( doc, fix ); 4787 4788 if ( !attaches ) { 4789 doc.addEventListener( orig, handler, true ); 4790 } 4791 data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); 4792 }, 4793 teardown: function() { 4794 var doc = this.ownerDocument || this, 4795 attaches = data_priv.access( doc, fix ) - 1; 4796 4797 if ( !attaches ) { 4798 doc.removeEventListener( orig, handler, true ); 4799 data_priv.remove( doc, fix ); 4800 4801 } else { 4802 data_priv.access( doc, fix, attaches ); 4803 } 4804 } 4805 }; 4806 }); 4807} 4808 4809jQuery.fn.extend({ 4810 4811 on: function( types, selector, data, fn, /*INTERNAL*/ one ) { 4812 var origFn, type; 4813 4814 // Types can be a map of types/handlers 4815 if ( typeof types === "object" ) { 4816 // ( types-Object, selector, data ) 4817 if ( typeof selector !== "string" ) { 4818 // ( types-Object, data ) 4819 data = data || selector; 4820 selector = undefined; 4821 } 4822 for ( type in types ) { 4823 this.on( type, selector, data, types[ type ], one ); 4824 } 4825 return this; 4826 } 4827 4828 if ( data == null && fn == null ) { 4829 // ( types, fn ) 4830 fn = selector; 4831 data = selector = undefined; 4832 } else if ( fn == null ) { 4833 if ( typeof selector === "string" ) { 4834 // ( types, selector, fn ) 4835 fn = data; 4836 data = undefined; 4837 } else { 4838 // ( types, data, fn ) 4839 fn = data; 4840 data = selector; 4841 selector = undefined; 4842 } 4843 } 4844 if ( fn === false ) { 4845 fn = returnFalse; 4846 } else if ( !fn ) { 4847 return this; 4848 } 4849 4850 if ( one === 1 ) { 4851 origFn = fn; 4852 fn = function( event ) { 4853 // Can use an empty set, since event contains the info 4854 jQuery().off( event ); 4855 return origFn.apply( this, arguments ); 4856 }; 4857 // Use same guid so caller can remove using origFn 4858 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4859 } 4860 return this.each( function() { 4861 jQuery.event.add( this, types, fn, data, selector ); 4862 }); 4863 }, 4864 one: function( types, selector, data, fn ) { 4865 return this.on( types, selector, data, fn, 1 ); 4866 }, 4867 off: function( types, selector, fn ) { 4868 var handleObj, type; 4869 if ( types && types.preventDefault && types.handleObj ) { 4870 // ( event ) dispatched jQuery.Event 4871 handleObj = types.handleObj; 4872 jQuery( types.delegateTarget ).off( 4873 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, 4874 handleObj.selector, 4875 handleObj.handler 4876 ); 4877 return this; 4878 } 4879 if ( typeof types === "object" ) { 4880 // ( types-object [, selector] ) 4881 for ( type in types ) { 4882 this.off( type, selector, types[ type ] ); 4883 } 4884 return this; 4885 } 4886 if ( selector === false || typeof selector === "function" ) { 4887 // ( types [, fn] ) 4888 fn = selector; 4889 selector = undefined; 4890 } 4891 if ( fn === false ) { 4892 fn = returnFalse; 4893 } 4894 return this.each(function() { 4895 jQuery.event.remove( this, types, fn, selector ); 4896 }); 4897 }, 4898 4899 trigger: function( type, data ) { 4900 return this.each(function() { 4901 jQuery.event.trigger( type, data, this ); 4902 }); 4903 }, 4904 triggerHandler: function( type, data ) { 4905 var elem = this[0]; 4906 if ( elem ) { 4907 return jQuery.event.trigger( type, data, elem, true ); 4908 } 4909 } 4910}); 4911 4912 4913var 4914 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, 4915 rtagName = /<([\w:]+)/,
vendor: 12,395 bytes, lines 4916-5352
4916 rhtml = /<|&#?\w+;/, 4917 rnoInnerhtml = /<(?:script|style|link)/i, 4918 // checked="checked" or checked 4919 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 4920 rscriptType = /^$|\/(?:java|ecma)script/i, 4921 rscriptTypeMasked = /^true\/(.*)/, 4922 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, 4923 4924 // We have to close these tags to support XHTML (#13200) 4925 wrapMap = { 4926 4927 // Support: IE9 4928 option: [ 1, "<select multiple='multiple'>", "</select>" ], 4929 4930 thead: [ 1, "<table>", "</table>" ], 4931 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 4932 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4933 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4934 4935 _default: [ 0, "", "" ] 4936 }; 4937 4938// Support: IE9 4939wrapMap.optgroup = wrapMap.option; 4940 4941wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4942wrapMap.th = wrapMap.td; 4943 4944// Support: 1.x compatibility 4945// Manipulating tables requires a tbody 4946function manipulationTarget( elem, content ) { 4947 return jQuery.nodeName( elem, "table" ) && 4948 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? 4949 4950 elem.getElementsByTagName("tbody")[0] || 4951 elem.appendChild( elem.ownerDocument.createElement("tbody") ) : 4952 elem; 4953} 4954 4955// Replace/restore the type attribute of script elements for safe DOM manipulation 4956function disableScript( elem ) { 4957 elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; 4958 return elem; 4959} 4960function restoreScript( elem ) { 4961 var match = rscriptTypeMasked.exec( elem.type ); 4962 4963 if ( match ) { 4964 elem.type = match[ 1 ]; 4965 } else { 4966 elem.removeAttribute("type"); 4967 } 4968 4969 return elem; 4970} 4971 4972// Mark scripts as having already been evaluated 4973function setGlobalEval( elems, refElements ) { 4974 var i = 0, 4975 l = elems.length; 4976 4977 for ( ; i < l; i++ ) { 4978 data_priv.set( 4979 elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) 4980 ); 4981 } 4982} 4983 4984function cloneCopyEvent( src, dest ) { 4985 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; 4986 4987 if ( dest.nodeType !== 1 ) { 4988 return; 4989 } 4990 4991 // 1. Copy private data: events, handlers, etc. 4992 if ( data_priv.hasData( src ) ) { 4993 pdataOld = data_priv.access( src ); 4994 pdataCur = data_priv.set( dest, pdataOld ); 4995 events = pdataOld.events; 4996 4997 if ( events ) { 4998 delete pdataCur.handle; 4999 pdataCur.events = {}; 5000 5001 for ( type in events ) { 5002 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5003 jQuery.event.add( dest, type, events[ type ][ i ] ); 5004 } 5005 } 5006 } 5007 } 5008 5009 // 2. Copy user data 5010 if ( data_user.hasData( src ) ) { 5011 udataOld = data_user.access( src ); 5012 udataCur = jQuery.extend( {}, udataOld ); 5013 5014 data_user.set( dest, udataCur ); 5015 } 5016} 5017 5018function getAll( context, tag ) { 5019 var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : 5020 context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : 5021 []; 5022 5023 return tag === undefined || tag && jQuery.nodeName( context, tag ) ? 5024 jQuery.merge( [ context ], ret ) : 5025 ret; 5026} 5027 5028// Fix IE bugs, see support tests 5029function fixInput( src, dest ) { 5030 var nodeName = dest.nodeName.toLowerCase(); 5031 5032 // Fails to persist the checked state of a cloned checkbox or radio button. 5033 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5034 dest.checked = src.checked; 5035 5036 // Fails to return the selected option to the default selected state when cloning options 5037 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5038 dest.defaultValue = src.defaultValue; 5039 } 5040} 5041 5042jQuery.extend({ 5043 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5044 var i, l, srcElements, destElements, 5045 clone = elem.cloneNode( true ), 5046 inPage = jQuery.contains( elem.ownerDocument, elem ); 5047 5048 // Fix IE cloning issues 5049 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 5050 !jQuery.isXMLDoc( elem ) ) { 5051 5052 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 5053 destElements = getAll( clone ); 5054 srcElements = getAll( elem ); 5055 5056 for ( i = 0, l = srcElements.length; i < l; i++ ) { 5057 fixInput( srcElements[ i ], destElements[ i ] ); 5058 } 5059 } 5060 5061 // Copy the events from the original to the clone 5062 if ( dataAndEvents ) { 5063 if ( deepDataAndEvents ) { 5064 srcElements = srcElements || getAll( elem ); 5065 destElements = destElements || getAll( clone ); 5066 5067 for ( i = 0, l = srcElements.length; i < l; i++ ) { 5068 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 5069 } 5070 } else { 5071 cloneCopyEvent( elem, clone ); 5072 } 5073 } 5074 5075 // Preserve script evaluation history 5076 destElements = getAll( clone, "script" ); 5077 if ( destElements.length > 0 ) { 5078 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 5079 } 5080 5081 // Return the cloned set 5082 return clone; 5083 }, 5084 5085 buildFragment: function( elems, context, scripts, selection ) { 5086 var elem, tmp, tag, wrap, contains, j, 5087 fragment = context.createDocumentFragment(), 5088 nodes = [], 5089 i = 0, 5090 l = elems.length; 5091 5092 for ( ; i < l; i++ ) { 5093 elem = elems[ i ]; 5094 5095 if ( elem || elem === 0 ) { 5096 5097 // Add nodes directly 5098 if ( jQuery.type( elem ) === "object" ) { 5099 // Support: QtWebKit, PhantomJS 5100 // push.apply(_, arraylike) throws on ancient WebKit 5101 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 5102 5103 // Convert non-html into a text node 5104 } else if ( !rhtml.test( elem ) ) { 5105 nodes.push( context.createTextNode( elem ) ); 5106 5107 // Convert html into DOM nodes 5108 } else { 5109 tmp = tmp || fragment.appendChild( context.createElement("div") ); 5110 5111 // Deserialize a standard representation 5112 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 5113 wrap = wrapMap[ tag ] || wrapMap._default; 5114 tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; 5115 5116 // Descend through wrappers to the right content 5117 j = wrap[ 0 ]; 5118 while ( j-- ) { 5119 tmp = tmp.lastChild; 5120 } 5121 5122 // Support: QtWebKit, PhantomJS 5123 // push.apply(_, arraylike) throws on ancient WebKit 5124 jQuery.merge( nodes, tmp.childNodes ); 5125 5126 // Remember the top-level container 5127 tmp = fragment.firstChild; 5128 5129 // Ensure the created nodes are orphaned (#12392) 5130 tmp.textContent = ""; 5131 } 5132 } 5133 } 5134 5135 // Remove wrapper from fragment 5136 fragment.textContent = ""; 5137 5138 i = 0; 5139 while ( (elem = nodes[ i++ ]) ) { 5140 5141 // #4087 - If origin and destination elements are the same, and this is 5142 // that element, do not do anything 5143 if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { 5144 continue; 5145 } 5146 5147 contains = jQuery.contains( elem.ownerDocument, elem ); 5148 5149 // Append to fragment 5150 tmp = getAll( fragment.appendChild( elem ), "script" ); 5151 5152 // Preserve script evaluation history 5153 if ( contains ) { 5154 setGlobalEval( tmp ); 5155 } 5156 5157 // Capture executables 5158 if ( scripts ) { 5159 j = 0; 5160 while ( (elem = tmp[ j++ ]) ) { 5161 if ( rscriptType.test( elem.type || "" ) ) { 5162 scripts.push( elem ); 5163 } 5164 } 5165 } 5166 } 5167 5168 return fragment; 5169 }, 5170 5171 cleanData: function( elems ) { 5172 var data, elem, type, key, 5173 special = jQuery.event.special, 5174 i = 0; 5175 5176 for ( ; (elem = elems[ i ]) !== undefined; i++ ) { 5177 if ( jQuery.acceptData( elem ) ) { 5178 key = elem[ data_priv.expando ]; 5179 5180 if ( key && (data = data_priv.cache[ key ]) ) { 5181 if ( data.events ) { 5182 for ( type in data.events ) { 5183 if ( special[ type ] ) { 5184 jQuery.event.remove( elem, type ); 5185 5186 // This is a shortcut to avoid jQuery.event.remove's overhead 5187 } else { 5188 jQuery.removeEvent( elem, type, data.handle ); 5189 } 5190 } 5191 } 5192 if ( data_priv.cache[ key ] ) { 5193 // Discard any remaining `private` data 5194 delete data_priv.cache[ key ]; 5195 } 5196 } 5197 } 5198 // Discard any remaining `user` data 5199 delete data_user.cache[ elem[ data_user.expando ] ]; 5200 } 5201 } 5202}); 5203 5204jQuery.fn.extend({ 5205 text: function( value ) { 5206 return access( this, function( value ) { 5207 return value === undefined ? 5208 jQuery.text( this ) : 5209 this.empty().each(function() { 5210 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5211 this.textContent = value; 5212 } 5213 }); 5214 }, null, value, arguments.length ); 5215 }, 5216 5217 append: function() { 5218 return this.domManip( arguments, function( elem ) { 5219 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5220 var target = manipulationTarget( this, elem ); 5221 target.appendChild( elem ); 5222 } 5223 }); 5224 }, 5225 5226 prepend: function() { 5227 return this.domManip( arguments, function( elem ) { 5228 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 5229 var target = manipulationTarget( this, elem ); 5230 target.insertBefore( elem, target.firstChild ); 5231 } 5232 }); 5233 }, 5234 5235 before: function() { 5236 return this.domManip( arguments, function( elem ) { 5237 if ( this.parentNode ) { 5238 this.parentNode.insertBefore( elem, this ); 5239 } 5240 }); 5241 }, 5242 5243 after: function() { 5244 return this.domManip( arguments, function( elem ) { 5245 if ( this.parentNode ) { 5246 this.parentNode.insertBefore( elem, this.nextSibling ); 5247 } 5248 }); 5249 }, 5250 5251 remove: function( selector, keepData /* Internal Use Only */ ) { 5252 var elem, 5253 elems = selector ? jQuery.filter( selector, this ) : this, 5254 i = 0; 5255 5256 for ( ; (elem = elems[i]) != null; i++ ) { 5257 if ( !keepData && elem.nodeType === 1 ) { 5258 jQuery.cleanData( getAll( elem ) ); 5259 } 5260 5261 if ( elem.parentNode ) { 5262 if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { 5263 setGlobalEval( getAll( elem, "script" ) ); 5264 } 5265 elem.parentNode.removeChild( elem ); 5266 } 5267 } 5268 5269 return this; 5270 }, 5271 5272 empty: function() { 5273 var elem, 5274 i = 0; 5275 5276 for ( ; (elem = this[i]) != null; i++ ) { 5277 if ( elem.nodeType === 1 ) { 5278 5279 // Prevent memory leaks 5280 jQuery.cleanData( getAll( elem, false ) ); 5281 5282 // Remove any remaining nodes 5283 elem.textContent = ""; 5284 } 5285 } 5286 5287 return this; 5288 }, 5289 5290 clone: function( dataAndEvents, deepDataAndEvents ) { 5291 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 5292 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 5293 5294 return this.map(function() { 5295 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 5296 }); 5297 }, 5298 5299 html: function( value ) { 5300 return access( this, function( value ) { 5301 var elem = this[ 0 ] || {}, 5302 i = 0, 5303 l = this.length; 5304 5305 if ( value === undefined && elem.nodeType === 1 ) { 5306 return elem.innerHTML; 5307 } 5308 5309 // See if we can take a shortcut and just use innerHTML 5310 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 5311 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 5312 5313 value = value.replace( rxhtmlTag, "<$1></$2>" ); 5314 5315 try { 5316 for ( ; i < l; i++ ) { 5317 elem = this[ i ] || {}; 5318 5319 // Remove element nodes and prevent memory leaks 5320 if ( elem.nodeType === 1 ) { 5321 jQuery.cleanData( getAll( elem, false ) ); 5322 elem.innerHTML = value; 5323 } 5324 } 5325 5326 elem = 0; 5327 5328 // If using innerHTML throws an exception, use the fallback method 5329 } catch( e ) {} 5330 } 5331 5332 if ( elem ) { 5333 this.empty().append( value ); 5334 } 5335 }, null, value, arguments.length ); 5336 }, 5337 5338 replaceWith: function() { 5339 var arg = arguments[ 0 ]; 5340 5341 // Make the changes, replacing each context element with the new content 5342 this.domManip( arguments, function( elem ) { 5343 arg = this.parentNode; 5344 5345 jQuery.cleanData( getAll( this ) ); 5346 5347 if ( arg ) { 5348 arg.replaceChild( elem, this ); 5349 } 5350 }); 5351 5352 // Force removal if there was no new content (e.g., from empty arguments)
5353 return arg && (arg.length || arg.nodeType) ? this : this.remove(); 5354 }, 5355 5356 detach: function( selector ) { 5357 return this.remove( selector, true ); 5358 }, 5359 5360 domManip: function( args, callback ) { 5361 5362 // Flatten any nested arrays 5363 args = concat.apply( [], args ); 5364 5365 var fragment, first, scripts, hasScripts, node, doc, 5366 i = 0, 5367 l = this.length, 5368 set = this, 5369 iNoClone = l - 1, 5370 value = args[ 0 ], 5371 isFunction = jQuery.isFunction( value ); 5372 5373 // We can't cloneNode fragments that contain checked, in WebKit 5374 if ( isFunction || 5375 ( l > 1 && typeof value === "string" && 5376 !support.checkClone && rchecked.test( value ) ) ) { 5377 return this.each(function( index ) { 5378 var self = set.eq( index ); 5379 if ( isFunction ) { 5380 args[ 0 ] = value.call( this, index, self.html() ); 5381 } 5382 self.domManip( args, callback ); 5383 }); 5384 } 5385 5386 if ( l ) { 5387 fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); 5388 first = fragment.firstChild; 5389 5390 if ( fragment.childNodes.length === 1 ) { 5391 fragment = first; 5392 } 5393 5394 if ( first ) { 5395 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 5396 hasScripts = scripts.length; 5397 5398 // Use the original fragment for the last item instead of the first because it can end up 5399 // being emptied incorrectly in certain situations (#8070). 5400 for ( ; i < l; i++ ) { 5401 node = fragment; 5402 5403 if ( i !== iNoClone ) { 5404 node = jQuery.clone( node, true, true ); 5405 5406 // Keep references to cloned scripts for later restoration 5407 if ( hasScripts ) { 5408 // Support: QtWebKit 5409 // jQuery.merge because push.apply(_, arraylike) throws 5410 jQuery.merge( scripts, getAll( node, "script" ) ); 5411 } 5412 } 5413 5414 callback.call( this[ i ], node, i ); 5415 } 5416 5417 if ( hasScripts ) { 5418 doc = scripts[ scripts.length - 1 ].ownerDocument; 5419 5420 // Reenable scripts 5421 jQuery.map( scripts, restoreScript ); 5422 5423 // Evaluate executable scripts on first document insertion 5424 for ( i = 0; i < hasScripts; i++ ) { 5425 node = scripts[ i ]; 5426 if ( rscriptType.test( node.type || "" ) && 5427 !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { 5428 5429 if ( node.src ) { 5430 // Optional AJAX dependency, but won't run scripts if not present 5431 if ( jQuery._evalUrl ) { 5432 jQuery._evalUrl( node.src ); 5433 } 5434 } else { 5435 jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); 5436 } 5437 } 5438 } 5439 } 5440 } 5441 } 5442 5443 return this; 5444 } 5445}); 5446 5447jQuery.each({ 5448 appendTo: "append", 5449 prependTo: "prepend", 5450 insertBefore: "before", 5451 insertAfter: "after", 5452 replaceAll: "replaceWith" 5453}, function( name, original ) { 5454 jQuery.fn[ name ] = function( selector ) { 5455 var elems, 5456 ret = [], 5457 insert = jQuery( selector ), 5458 last = insert.length - 1, 5459 i = 0; 5460 5461 for ( ; i <= last; i++ ) { 5462 elems = i === last ? this : this.clone( true ); 5463 jQuery( insert[ i ] )[ original ]( elems ); 5464 5465 // Support: QtWebKit 5466 // .get() because push.apply(_, arraylike) throws 5467 push.apply( ret, elems.get() ); 5468 } 5469 5470 return this.pushStack( ret ); 5471 }; 5472}); 5473 5474 5475var iframe, 5476 elemdisplay = {}; 5477 5478/** 5479 * Retrieve the actual display of a element 5480 * @param {String} name nodeName of the element 5481 * @param {Object} doc Document object 5482 */ 5483// Called only from within defaultDisplay 5484function actualDisplay( name, doc ) { 5485 var style, 5486 elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), 5487 5488 // getDefaultComputedStyle might be reliably used only on attached element 5489 display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? 5490 5491 // Use of this method is a temporary fix (more like optimization) until something better comes along, 5492 // since it was removed from specification and supported only in FF 5493 style.display : jQuery.css( elem[ 0 ], "display" ); 5494 5495 // We don't have any data stored on the element, 5496 // so use "detach" method as fast way to get rid of the element 5497 elem.detach(); 5498
5499 return display; 5500} 5501 5502/** 5503 * Try to determine the default display value of an element 5504 * @param {String} nodeName 5505 */ 5506function defaultDisplay( nodeName ) { 5507 var doc = document, 5508 display = elemdisplay[ nodeName ]; 5509 5510 if ( !display ) { 5511 display = actualDisplay( nodeName, doc ); 5512 5513 // If the simple way fails, read from inside an iframe 5514 if ( display === "none" || !display ) { 5515 5516 // Use the already-created iframe if possible 5517 iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); 5518 5519 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse 5520 doc = iframe[ 0 ].contentDocument; 5521 5522 // Support: IE 5523 doc.write(); 5524 doc.close(); 5525 5526 display = actualDisplay( nodeName, doc ); 5527 iframe.detach(); 5528 } 5529 5530 // Store the correct default display 5531 elemdisplay[ nodeName ] = display; 5532 } 5533 5534 return display; 5535} 5536var rmargin = (/^margin/); 5537 5538var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 5539 5540var getStyles = function( elem ) { 5541 // Support: IE<=11+, Firefox<=30+ (#15098, #14150) 5542 // IE throws on elements created in popups 5543 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 5544 if ( elem.ownerDocument.defaultView.opener ) { 5545 return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); 5546 } 5547 5548 return window.getComputedStyle( elem, null ); 5549 }; 5550 5551 5552 5553function curCSS( elem, name, computed ) { 5554 var width, minWidth, maxWidth, ret, 5555 style = elem.style; 5556 5557 computed = computed || getStyles( elem ); 5558 5559 // Support: IE9 5560 // getPropertyValue is only needed for .css('filter') (#12537) 5561 if ( computed ) { 5562 ret = computed.getPropertyValue( name ) || computed[ name ]; 5563 } 5564 5565 if ( computed ) { 5566 5567 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { 5568 ret = jQuery.style( elem, name ); 5569 } 5570 5571 // Support: iOS < 6 5572 // A tribute to the "awesome hack by Dean Edwards" 5573 // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels 5574 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values 5575 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { 5576 5577 // Remember the original values 5578 width = style.width; 5579 minWidth = style.minWidth; 5580 maxWidth = style.maxWidth; 5581 5582 // Put in the new values to get a computed value out 5583 style.minWidth = style.maxWidth = style.width = ret; 5584 ret = computed.width; 5585 5586 // Revert the changed values 5587 style.width = width; 5588 style.minWidth = minWidth; 5589 style.maxWidth = maxWidth; 5590 } 5591 } 5592 5593 return ret !== undefined ? 5594 // Support: IE 5595 // IE returns zIndex value as an integer. 5596 ret + "" : 5597 ret; 5598} 5599 5600 5601function addGetHookIf( conditionFn, hookFn ) { 5602 // Define the hook, we'll check on the first run if it's really needed. 5603 return { 5604 get: function() { 5605 if ( conditionFn() ) { 5606 // Hook not needed (or it's not possible to use it due 5607 // to missing dependency), remove it. 5608 delete this.get; 5609 return; 5610 } 5611 5612 // Hook needed; redefine it so that the support test is not executed again. 5613 return (this.get = hookFn).apply( this, arguments ); 5614 } 5615 }; 5616} 5617 5618 5619(function() { 5620 var pixelPositionVal, boxSizingReliableVal, 5621 docElem = document.documentElement, 5622 container = document.createElement( "div" ), 5623 div = document.createElement( "div" ); 5624 5625 if ( !div.style ) { 5626 return; 5627 } 5628 5629 // Support: IE9-11+ 5630 // Style of cloned element affects source element cloned (#8908) 5631 div.style.backgroundClip = "content-box"; 5632 div.cloneNode( true ).style.backgroundClip = ""; 5633 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 5634 5635 container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + 5636 "position:absolute"; 5637 container.appendChild( div ); 5638 5639 // Executing both pixelPosition & boxSizingReliable tests require only one layout 5640 // so they're executed at the same time to save the second computation. 5641 function computePixelPositionAndBoxSizingReliable() { 5642 div.style.cssText =
5643 // Support: Firefox<29, Android 2.3 5644 // Vendor-prefix box-sizing 5645 "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + 5646 "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + 5647 "border:1px;padding:1px;width:4px;position:absolute"; 5648 div.innerHTML = ""; 5649 docElem.appendChild( container ); 5650 5651 var divStyle = window.getComputedStyle( div, null ); 5652 pixelPositionVal = divStyle.top !== "1%"; 5653 boxSizingReliableVal = divStyle.width === "4px"; 5654 5655 docElem.removeChild( container ); 5656 } 5657 5658 // Support: node.js jsdom 5659 // Don't assume that getComputedStyle is a property of the global object 5660 if ( window.getComputedStyle ) { 5661 jQuery.extend( support, { 5662 pixelPosition: function() { 5663 5664 // This test is executed only once but we still do memoizing 5665 // since we can use the boxSizingReliable pre-computing. 5666 // No need to check if the test was already performed, though. 5667 computePixelPositionAndBoxSizingReliable(); 5668 return pixelPositionVal; 5669 }, 5670 boxSizingReliable: function() { 5671 if ( boxSizingReliableVal == null ) { 5672 computePixelPositionAndBoxSizingReliable(); 5673 } 5674 return boxSizingReliableVal; 5675 }, 5676 reliableMarginRight: function() { 5677 5678 // Support: Android 2.3 5679 // Check if div with explicit width and no margin-right incorrectly 5680 // gets computed margin-right based on width of container. (#3333) 5681 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 5682 // This support function is only executed once so no memoizing is needed. 5683 var ret, 5684 marginDiv = div.appendChild( document.createElement( "div" ) ); 5685 5686 // Reset CSS: box-sizing; display; margin; border; padding 5687 marginDiv.style.cssText = div.style.cssText = 5688 // Support: Firefox<29, Android 2.3 5689 // Vendor-prefix box-sizing 5690 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + 5691 "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; 5692 marginDiv.style.marginRight = marginDiv.style.width = "0"; 5693 div.style.width = "1px"; 5694 docElem.appendChild( container ); 5695 5696 ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); 5697 5698 docElem.removeChild( container ); 5699 div.removeChild( marginDiv ); 5700 5701 return ret; 5702 } 5703 }); 5704 } 5705})(); 5706 5707 5708// A method for quickly swapping in/out CSS properties to get correct calculations. 5709jQuery.swap = function( elem, options, callback, args ) { 5710 var ret, name, 5711 old = {}; 5712 5713 // Remember the old values, and insert the new ones 5714 for ( name in options ) { 5715 old[ name ] = elem.style[ name ]; 5716 elem.style[ name ] = options[ name ]; 5717 } 5718 5719 ret = callback.apply( elem, args || [] ); 5720 5721 // Revert the old values 5722 for ( name in options ) { 5723 elem.style[ name ] = old[ name ]; 5724 } 5725 5726 return ret; 5727}; 5728 5729 5730var 5731 // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption" 5732 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 5733 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 5734 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), 5735 rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), 5736 5737 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 5738 cssNormalTransform = { 5739 letterSpacing: "0", 5740 fontWeight: "400" 5741 }, 5742 5743 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; 5744 5745// Return a css property mapped to a potentially vendor prefixed property 5746function vendorPropName( style, name ) { 5747 5748 // Shortcut for names that are not vendor prefixed 5749 if ( name in style ) { 5750 return name; 5751 } 5752 5753 // Check for vendor prefixed names 5754 var capName = name[0].toUpperCase() + name.slice(1), 5755 origName = name, 5756 i = cssPrefixes.length; 5757 5758 while ( i-- ) { 5759 name = cssPrefixes[ i ] + capName; 5760 if ( name in style ) { 5761 return name; 5762 } 5763 } 5764 5765 return origName; 5766} 5767 5768function setPositiveNumber( elem, value, subtract ) { 5769 var matches = rnumsplit.exec( value ); 5770 return matches ? 5771 // Guard against undefined "subtract", e.g., when used as in cssHooks 5772 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : 5773 value; 5774} 5775 5776function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { 5777 var i = extra === ( isBorderBox ? "border" : "content" ) ? 5778 // If we already have the right measurement, avoid augmentation 5779 4 : 5780 // Otherwise initialize for horizontal or vertical properties 5781 name === "width" ? 1 : 0, 5782 5783 val = 0; 5784 5785 for ( ; i < 4; i += 2 ) { 5786 // Both box models exclude margin, so add it if we want it 5787 if ( extra === "margin" ) { 5788 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); 5789 } 5790 5791 if ( isBorderBox ) { 5792 // border-box includes padding, so remove it if we want content 5793 if ( extra === "content" ) { 5794 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 5795 } 5796 5797 // At this point, extra isn't border nor margin, so remove border 5798 if ( extra !== "margin" ) { 5799 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 5800 } 5801 } else { 5802 // At this point, extra isn't content, so add padding 5803 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 5804 5805 // At this point, extra isn't content nor padding, so add border 5806 if ( extra !== "padding" ) { 5807 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 5808 } 5809 } 5810 } 5811 5812 return val; 5813} 5814 5815function getWidthOrHeight( elem, name, extra ) { 5816 5817 // Start with offset property, which is equivalent to the border-box value 5818 var valueIsBorderBox = true, 5819 val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 5820 styles = getStyles( elem ), 5821 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 5822 5823 // Some non-html elements return undefined for offsetWidth, so check for null/undefined 5824 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 5825 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 5826 if ( val <= 0 || val == null ) { 5827 // Fall back to computed then uncomputed css if necessary 5828 val = curCSS( elem, name, styles ); 5829 if ( val < 0 || val == null ) { 5830 val = elem.style[ name ]; 5831 } 5832 5833 // Computed unit is not pixels. Stop here and return. 5834 if ( rnumnonpx.test(val) ) { 5835 return val; 5836 } 5837 5838 // Check for style in case a browser which returns unreliable values 5839 // for getComputedStyle silently falls back to the reliable elem.style 5840 valueIsBorderBox = isBorderBox && 5841 ( support.boxSizingReliable() || val === elem.style[ name ] ); 5842 5843 // Normalize "", auto, and prepare for extra 5844 val = parseFloat( val ) || 0; 5845 } 5846 5847 // Use the active box-sizing model to add/subtract irrelevant styles 5848 return ( val + 5849 augmentWidthOrHeight( 5850 elem, 5851 name, 5852 extra || ( isBorderBox ? "border" : "content" ), 5853 valueIsBorderBox, 5854 styles 5855 ) 5856 ) + "px"; 5857} 5858 5859function showHide( elements, show ) { 5860 var display, elem, hidden, 5861 values = [], 5862 index = 0, 5863 length = elements.length; 5864 5865 for ( ; index < length; index++ ) { 5866 elem = elements[ index ]; 5867 if ( !elem.style ) { 5868 continue; 5869 } 5870 5871 values[ index ] = data_priv.get( elem, "olddisplay" ); 5872 display = elem.style.display; 5873 if ( show ) { 5874 // Reset the inline display of this element to learn if it is 5875 // being hidden by cascaded rules or not 5876 if ( !values[ index ] && display === "none" ) { 5877 elem.style.display = ""; 5878 } 5879 5880 // Set elements which have been overridden with display: none 5881 // in a stylesheet to whatever the default browser style is 5882 // for such an element 5883 if ( elem.style.display === "" && isHidden( elem ) ) { 5884 values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) ); 5885 } 5886 } else { 5887 hidden = isHidden( elem ); 5888 5889 if ( display !== "none" || !hidden ) { 5890 data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "dis
5890play" ) ); 5891 } 5892 } 5893 } 5894 5895 // Set the display of most of the elements in a second loop 5896 // to avoid the constant reflow 5897 for ( index = 0; index < length; index++ ) { 5898 elem = elements[ index ]; 5899 if ( !elem.style ) { 5900 continue; 5901 } 5902 if ( !show || elem.style.display === "none" || elem.style.display === "" ) { 5903 elem.style.display = show ? values[ index ] || "" : "none"; 5904 } 5905 } 5906 5907 return elements; 5908} 5909 5910jQuery.extend({ 5911 5912 // Add in style property hooks for overriding the default 5913 // behavior of getting and setting a style property 5914 cssHooks: { 5915 opacity: { 5916 get: function( elem, computed ) { 5917 if ( computed ) { 5918 5919 // We should always get a number back from opacity 5920 var ret = curCSS( elem, "opacity" ); 5921 return ret === "" ? "1" : ret; 5922 } 5923 } 5924 } 5925 }, 5926 5927 // Don't automatically add "px" to these possibly-unitless properties 5928 cssNumber: { 5929 "columnCount": true, 5930 "fillOpacity": true, 5931 "flexGrow": true, 5932 "flexShrink": true, 5933 "fontWeight": true, 5934 "lineHeight": true, 5935 "opacity": true, 5936 "order": true, 5937 "orphans": true, 5938 "widows": true, 5939 "zIndex": true, 5940 "zoom": true 5941 }, 5942 5943 // Add in properties whose names you wish to fix before 5944 // setting or getting the value 5945 cssProps: { 5946 "float": "cssFloat" 5947 }, 5948 5949 // Get and set the style property on a DOM Node 5950 style: function( elem, name, value, extra ) { 5951 5952 // Don't set styles on text and comment nodes 5953 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 5954 return; 5955 } 5956 5957 // Make sure that we're working with the right name 5958 var ret, type, hooks, 5959 origName = jQuery.camelCase( name ), 5960 style = elem.style; 5961 5962 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); 5963 5964 // Gets hook for the prefixed version, then unprefixed version 5965 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 5966 5967 // Check if we're setting a value 5968 if ( value !== undefined ) { 5969 type = typeof value; 5970 5971 // Convert "+=" or "-=" to relative numbers (#7345) 5972 if ( type === "string" && (ret = rrelNum.exec( value )) ) { 5973 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); 5974 // Fixes bug #9237 5975 type = "number"; 5976 } 5977 5978 // Make sure that null and NaN values aren't set (#7116) 5979 if ( value == null || value !== value ) { 5980 return; 5981 } 5982 5983 // If a number, add 'px' to the (except for certain CSS properties) 5984 if ( type === "number" && !jQuery.cssNumber[ origName ] ) { 5985 value += "px"; 5986 } 5987 5988 // Support: IE9-11+ 5989 // background-* props affect original clone's values 5990 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 5991 style[ name ] = "inherit"; 5992 } 5993 5994 // If a hook was provided, use that value, otherwise just set the specified value 5995 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { 5996 style[ name ] = value; 5997 } 5998 5999 } else { 6000 // If a hook was provided get the non-computed value from there 6001 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { 6002 return ret; 6003 } 6004 6005 // Otherwise just get the value from the style object 6006 return style[ name ]; 6007 } 6008 }, 6009 6010 css: function( elem, name, extra, styles ) { 6011 var val, num, hooks, 6012 origName = jQuery.camelCase( name ); 6013 6014 // Make sure that we're working with the right name 6015 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); 6016 6017 // Try prefixed name followed by the unprefixed name 6018 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6019 6020 // If a hook was provided get the computed value from there 6021 if ( hooks && "get" in hooks ) { 6022 val = hooks.get( elem, true, extra ); 6023 } 6024 6025 // Otherwise, if a way to get the computed value exists, use that 6026 if ( val === undefined ) { 6027 val = curCSS( elem, name, styles ); 6028 } 6029 6030 // Convert "normal" to computed value 6031 if ( val === "normal" && name in cssNormalTransform ) { 6032 val = cssNormalTransform[ name ]; 6033 } 6034 6035 // Make numeric if forced or a qualifier was provided and val looks numeric 6036 if ( extra === "" || extra ) { 6037 num = parseFloat( val ); 6038 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; 6039 } 6040 return val; 6041 } 6042}); 6043 6044jQuery.each([ "height", "width" ], function( i, name ) { 6045 jQuery.cssHooks[ name ] = { 6046 get: function( elem, computed, extra ) { 6047 if ( computed ) { 6048 6049 // Certain elements can have dimension info if we invisibly show them 6050 // but it must have a current display style that would benefit
6051 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? 6052 jQuery.swap( elem, cssShow, function() { 6053 return getWidthOrHeight( elem, name, extra ); 6054 }) : 6055 getWidthOrHeight( elem, name, extra ); 6056 } 6057 }, 6058 6059 set: function( elem, value, extra ) { 6060 var styles = extra && getStyles( elem ); 6061 return setPositiveNumber( elem, value, extra ? 6062 augmentWidthOrHeight( 6063 elem, 6064 name, 6065 extra, 6066 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6067 styles 6068 ) : 0 6069 ); 6070 } 6071 }; 6072}); 6073 6074// Support: Android 2.3 6075jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, 6076 function( elem, computed ) { 6077 if ( computed ) { 6078 return jQuery.swap( elem, { "display": "inline-block" }, 6079 curCSS, [ elem, "marginRight" ] ); 6080 } 6081 } 6082); 6083 6084// These hooks are used by animate to expand properties 6085jQuery.each({ 6086 margin: "", 6087 padding: "", 6088 border: "Width" 6089}, function( prefix, suffix ) { 6090 jQuery.cssHooks[ prefix + suffix ] = { 6091 expand: function( value ) { 6092 var i = 0, 6093 expanded = {}, 6094 6095 // Assumes a single number if not a string 6096 parts = typeof value === "string" ? value.split(" ") : [ value ]; 6097 6098 for ( ; i < 4; i++ ) { 6099 expanded[ prefix + cssExpand[ i ] + suffix ] = 6100 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6101 } 6102 6103 return expanded; 6104 } 6105 }; 6106 6107 if ( !rmargin.test( prefix ) ) { 6108 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 6109 } 6110}); 6111 6112jQuery.fn.extend({ 6113 css: function( name, value ) { 6114 return access( this, function( elem, name, value ) { 6115 var styles, len, 6116 map = {}, 6117 i = 0; 6118 6119 if ( jQuery.isArray( name ) ) { 6120 styles = getStyles( elem ); 6121 len = name.length; 6122 6123 for ( ; i < len; i++ ) { 6124 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 6125 } 6126 6127 return map; 6128 } 6129 6130 return value !== undefined ? 6131 jQuery.style( elem, name, value ) : 6132 jQuery.css( elem, name ); 6133 }, name, value, arguments.length > 1 ); 6134 }, 6135 show: function() { 6136 return showHide( this, true ); 6137 }, 6138 hide: function() { 6139 return showHide( this ); 6140 }, 6141 toggle: function( state ) { 6142 if ( typeof state === "boolean" ) { 6143 return state ? this.show() : this.hide(); 6144 } 6145 6146 return this.each(function() { 6147 if ( isHidden( this ) ) { 6148 jQuery( this ).show(); 6149 } else { 6150 jQuery( this ).hide(); 6151 } 6152 }); 6153 } 6154}); 6155 6156 6157function Tween( elem, options, prop, end, easing ) { 6158 return new Tween.prototype.init( elem, options, prop, end, easing ); 6159} 6160jQuery.Tween = Tween; 6161 6162Tween.prototype = { 6163 constructor: Tween, 6164 init: function( elem, options, prop, end, easing, unit ) { 6165 this.elem = elem; 6166 this.prop = prop; 6167 this.easing = easing || "swing"; 6168 this.options = options; 6169 this.start = this.now = this.cur(); 6170 this.end = end; 6171 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 6172 }, 6173 cur: function() { 6174 var hooks = Tween.propHooks[ this.prop ]; 6175 6176 return hooks && hooks.get ? 6177 hooks.get( this ) : 6178 Tween.propHooks._default.get( this ); 6179 }, 6180 run: function( percent ) { 6181 var eased, 6182 hooks = Tween.propHooks[ this.prop ]; 6183 6184 if ( this.options.duration ) { 6185 this.pos = eased = jQuery.easing[ this.easing ]( 6186 percent, this.options.duration * percent, 0, 1, this.options.duration 6187 ); 6188 } else { 6189 this.pos = eased = percent; 6190 } 6191 this.now = ( this.end - this.start ) * eased + this.start; 6192 6193 if ( this.options.step ) { 6194 this.options.step.call( this.elem, this.now, this ); 6195 } 6196 6197 if ( hooks && hooks.set ) { 6198 hooks.set( this ); 6199 } else { 6200 Tween.propHooks._default.set( this ); 6201 } 6202 return this; 6203 } 6204}; 6205 6206Tween.prototype.init.prototype = Tween.prototype; 6207 6208Tween.propHooks = { 6209 _default: { 6210 get: function( tween ) { 6211 var result; 6212 6213 if ( tween.elem[ tween.prop ] != null && 6214 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { 6215 return tween.elem[ tween.prop ]; 6216 } 6217 6218 // Passing an empty string as a 3rd parameter to .css will automatically 6219 // attempt a parseFloat and fallback to a string if the parse fails. 6220 // Simple values such as "10px" are parsed to Float; 6221 // complex values such as "rotate(1rad)" are returned as-is. 6222 result = jQuery.css( tween.elem, tween.prop, "" ); 6223 // Empty strings, null, undefined and "auto" are converted to 0. 6224 return !result || result === "auto" ? 0 : result; 6225 }, 6226 set: function( tween ) { 6227 // Use step hook for back compat. 6228 // Use cssHook if its there. 6229 // Use .style if available and use plain properties where available. 6230 if ( jQuery.fx.step[ tween.prop ] ) { 6231 jQuery.fx.step[ tween.prop ]( tween ); 6232 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { 6233 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 6234 } else { 6235 tween.elem[ tween.prop ] = tween.now; 6236 } 6237 } 6238 } 6239}; 6240 6241// Support: IE9
6242// Panic based approach to setting things on disconnected nodes 6243Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 6244 set: function( tween ) { 6245 if ( tween.elem.nodeType && tween.elem.parentNode ) { 6246 tween.elem[ tween.prop ] = tween.now; 6247 } 6248 } 6249}; 6250 6251jQuery.easing = { 6252 linear: function( p ) { 6253 return p; 6254 }, 6255 swing: function( p ) { 6256 return 0.5 - Math.cos( p * Math.PI ) / 2; 6257 } 6258}; 6259 6260jQuery.fx = Tween.prototype.init; 6261 6262// Back Compat <1.8 extension point 6263jQuery.fx.step = {}; 6264 6265 6266 6267 6268var 6269 fxNow, timerId, 6270 rfxtypes = /^(?:toggle|show|hide)$/, 6271 rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), 6272 rrun = /queueHooks$/, 6273 animationPrefilters = [ defaultPrefilter ], 6274 tweeners = { 6275 "*": [ function( prop, value ) { 6276 var tween = this.createTween( prop, value ), 6277 target = tween.cur(), 6278 parts = rfxnum.exec( value ), 6279 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 6280 6281 // Starting value computation is required for potential unit mismatches 6282 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && 6283 rfxnum.exec( jQuery.css( tween.elem, prop ) ), 6284 scale = 1, 6285 maxIterations = 20; 6286 6287 if ( start && start[ 3 ] !== unit ) { 6288 // Trust units reported by jQuery.css 6289 unit = unit || start[ 3 ]; 6290 6291 // Make sure we update the tween properties later on 6292 parts = parts || []; 6293 6294 // Iteratively approximate from a nonzero starting point 6295 start = +target || 1; 6296 6297 do { 6298 // If previous iteration zeroed out, double until we get *something*. 6299 // Use string for doubling so we don't accidentally see scale as unchanged below 6300 scale = scale || ".5"; 6301 6302 // Adjust and apply 6303 start = start / scale; 6304 jQuery.style( tween.elem, prop, start + unit ); 6305 6306 // Update scale, tolerating zero or NaN from tween.cur(), 6307 // break the loop if scale is unchanged or perfect, or if we've just had enough 6308 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); 6309 } 6310 6311 // Update tween properties 6312 if ( parts ) { 6313 start = tween.start = +start || +target || 0; 6314 tween.unit = unit; 6315 // If a +=/-= token was provided, we're doing a relative animation 6316 tween.end = parts[ 1 ] ? 6317 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : 6318 +parts[ 2 ]; 6319 } 6320 6321 return tween; 6322 } ] 6323 }; 6324 6325// Animations created synchronously will run synchronously 6326function createFxNow() { 6327 setTimeout(function() { 6328 fxNow = undefined; 6329 }); 6330 return ( fxNow = jQuery.now() ); 6331} 6332 6333// Generate parameters to create a standard animation 6334function genFx( type, includeWidth ) { 6335 var which, 6336 i = 0, 6337 attrs = { height: type }; 6338 6339 // If we include width, step value is 1 to do all cssExpand values, 6340 // otherwise step value is 2 to skip over Left and Right 6341 includeWidth = includeWidth ? 1 : 0; 6342 for ( ; i < 4 ; i += 2 - includeWidth ) { 6343 which = cssExpand[ i ]; 6344 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 6345 } 6346 6347 if ( includeWidth ) { 6348 attrs.opacity = attrs.width = type; 6349 } 6350 6351 return attrs; 6352} 6353 6354function createTween( value, prop, animation ) { 6355 var tween, 6356 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), 6357 index = 0, 6358 length = collection.length; 6359 for ( ; index < length; index++ ) { 6360 if ( (tween = collection[ index ].call( animation, prop, value )) ) { 6361 6362 // We're done with this property 6363 return tween; 6364 } 6365 } 6366} 6367 6368function defaultPrefilter( elem, props, opts ) { 6369 /* jshint validthis: true */ 6370 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, 6371 anim = this, 6372 orig = {}, 6373 style = elem.style, 6374 hidden = elem.nodeType && isHidden( elem ), 6375 dataShow = data_priv.get( elem, "fxshow" ); 6376 6377 // Handle queue: false promises 6378 if ( !opts.queue ) { 6379 hooks = jQuery._queueHooks( elem, "fx" ); 6380 if ( hooks.unqueued == null ) { 6381 hooks.unqueued = 0; 6382 oldfire = hooks.empty.fire; 6383 hooks.empty.fire = function() { 6384 if ( !hooks.unqueued ) { 6385 oldfire(); 6386 } 6387 }; 6388 } 6389 hooks.unqueued++; 6390 6391 anim.always(function() { 6392 // Ensure the complete handler is called before this completes 6393 anim.always(function() { 6394 hooks.unqueued--; 6395 if ( !jQuery.queue( elem, "fx" ).length ) { 6396 hooks.empty.fire(); 6397 } 6398 }); 6399 }); 6400 } 6401 6402 // Height/width overflow pass 6403 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { 6404 // Make sure that nothing sneaks out
6405 // Record all 3 overflow attributes because IE9-10 do not 6406 // change the overflow attribute when overflowX and 6407 // overflowY are set to the same value 6408 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 6409 6410 // Set display property to inline-block for height/width 6411 // animations on inline elements that are having width/height animated 6412 display = jQuery.css( elem, "display" ); 6413 6414 // Test default display if display is currently "none" 6415 checkDisplay = display === "none" ? 6416 data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; 6417 6418 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { 6419 style.display = "inline-block"; 6420 } 6421 } 6422 6423 if ( opts.overflow ) { 6424 style.overflow = "hidden"; 6425 anim.always(function() { 6426 style.overflow = opts.overflow[ 0 ]; 6427 style.overflowX = opts.overflow[ 1 ]; 6428 style.overflowY = opts.overflow[ 2 ]; 6429 }); 6430 } 6431 6432 // show/hide pass 6433 for ( prop in props ) { 6434 value = props[ prop ]; 6435 if ( rfxtypes.exec( value ) ) { 6436 delete props[ prop ]; 6437 toggle = toggle || value === "toggle"; 6438 if ( value === ( hidden ? "hide" : "show" ) ) { 6439 6440 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden 6441 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 6442 hidden = true; 6443 } else { 6444 continue; 6445 } 6446 } 6447 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 6448 6449 // Any non-fx value stops us from restoring the original display value 6450 } else { 6451 display = undefined; 6452 } 6453 } 6454 6455 if ( !jQuery.isEmptyObject( orig ) ) { 6456 if ( dataShow ) { 6457 if ( "hidden" in dataShow ) { 6458 hidden = dataShow.hidden; 6459 } 6460 } else { 6461 dataShow = data_priv.access( elem, "fxshow", {} ); 6462 } 6463 6464 // Store state if its toggle - enables .stop().toggle() to "reverse" 6465 if ( toggle ) { 6466 dataShow.hidden = !hidden; 6467 } 6468 if ( hidden ) { 6469 jQuery( elem ).show(); 6470 } else { 6471 anim.done(function() { 6472 jQuery( elem ).hide(); 6473 }); 6474 } 6475 anim.done(function() { 6476 var prop; 6477 6478 data_priv.remove( elem, "fxshow" ); 6479 for ( prop in orig ) { 6480 jQuery.style( elem, prop, orig[ prop ] ); 6481 } 6482 }); 6483 for ( prop in orig ) { 6484 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 6485 6486 if ( !( prop in dataShow ) ) { 6487 dataShow[ prop ] = tween.start; 6488 if ( hidden ) { 6489 tween.end = tween.start; 6490 tween.start = prop === "width" || prop === "height" ? 1 : 0; 6491 } 6492 } 6493 } 6494 6495 // If this is a noop like .hide().hide(), restore an overwritten display value 6496 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { 6497 style.display = display; 6498 } 6499} 6500 6501function propFilter( props, specialEasing ) { 6502 var index, name, easing, value, hooks; 6503 6504 // camelCase, specialEasing and expand cssHook pass 6505 for ( index in props ) { 6506 name = jQuery.camelCase( index ); 6507 easing = specialEasing[ name ]; 6508 value = props[ index ]; 6509 if ( jQuery.isArray( value ) ) { 6510 easing = value[ 1 ]; 6511 value = props[ index ] = value[ 0 ]; 6512 } 6513 6514 if ( index !== name ) { 6515 props[ name ] = value; 6516 delete props[ index ]; 6517 } 6518 6519 hooks = jQuery.cssHooks[ name ]; 6520 if ( hooks && "expand" in hooks ) { 6521 value = hooks.expand( value ); 6522 delete props[ name ]; 6523 6524 // Not quite $.extend, this won't overwrite existing keys. 6525 // Reusing 'index' because we have the correct "name" 6526 for ( index in value ) { 6527 if ( !( index in props ) ) { 6528 props[ index ] = value[ index ]; 6529 specialEasing[ index ] = easing; 6530 } 6531 } 6532 } else { 6533 specialEasing[ name ] = easing; 6534 } 6535 } 6536} 6537 6538function Animation( elem, properties, options ) { 6539 var result, 6540 stopped, 6541 index = 0, 6542 length = animationPrefilters.length, 6543 deferred = jQuery.Deferred().always( function() { 6544 // Don't match elem in the :animated selector 6545 delete tick.elem; 6546 }), 6547 tick = function() { 6548 if ( stopped ) { 6549 return false;
6550 } 6551 var currentTime = fxNow || createFxNow(), 6552 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 6553 // Support: Android 2.3 6554 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 6555 temp = remaining / animation.duration || 0, 6556 percent = 1 - temp, 6557 index = 0, 6558 length = animation.tweens.length; 6559 6560 for ( ; index < length ; index++ ) { 6561 animation.tweens[ index ].run( percent ); 6562 } 6563 6564 deferred.notifyWith( elem, [ animation, percent, remaining ]); 6565 6566 if ( percent < 1 && length ) { 6567 return remaining; 6568 } else { 6569 deferred.resolveWith( elem, [ animation ] ); 6570 return false; 6571 } 6572 }, 6573 animation = deferred.promise({ 6574 elem: elem, 6575 props: jQuery.extend( {}, properties ), 6576 opts: jQuery.extend( true, { specialEasing: {} }, options ), 6577 originalProperties: properties, 6578 originalOptions: options, 6579 startTime: fxNow || createFxNow(), 6580 duration: options.duration, 6581 tweens: [], 6582 createTween: function( prop, end ) { 6583 var tween = jQuery.Tween( elem, animation.opts, prop, end, 6584 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 6585 animation.tweens.push( tween ); 6586 return tween; 6587 }, 6588 stop: function( gotoEnd ) { 6589 var index = 0, 6590 // If we are going to the end, we want to run all the tweens 6591 // otherwise we skip this part 6592 length = gotoEnd ? animation.tweens.length : 0; 6593 if ( stopped ) { 6594 return this; 6595 } 6596 stopped = true; 6597 for ( ; index < length ; index++ ) { 6598 animation.tweens[ index ].run( 1 ); 6599 } 6600 6601 // Resolve when we played the last frame; otherwise, reject 6602 if ( gotoEnd ) { 6603 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 6604 } else { 6605 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 6606 } 6607 return this; 6608 } 6609 }), 6610 props = animation.props; 6611 6612 propFilter( props, animation.opts.specialEasing ); 6613 6614 for ( ; index < length ; index++ ) { 6615 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); 6616 if ( result ) { 6617 return result; 6618 } 6619 } 6620 6621 jQuery.map( props, createTween, animation ); 6622 6623 if ( jQuery.isFunction( animation.opts.start ) ) { 6624 animation.opts.start.call( elem, animation ); 6625 } 6626 6627 jQuery.fx.timer( 6628 jQuery.extend( tick, { 6629 elem: elem, 6630 anim: animation, 6631 queue: animation.opts.queue 6632 }) 6633 ); 6634 6635 // attach callbacks from options 6636 return animation.progress( animation.opts.progress ) 6637 .done( animation.opts.done, animation.opts.complete ) 6638 .fail( animation.opts.fail ) 6639 .always( animation.opts.always ); 6640} 6641 6642jQuery.Animation = jQuery.extend( Animation, { 6643 6644 tweener: function( props, callback ) { 6645 if ( jQuery.isFunction( props ) ) { 6646 callback = props; 6647 props = [ "*" ]; 6648 } else { 6649 props = props.split(" "); 6650 } 6651 6652 var prop, 6653 index = 0, 6654 length = props.length; 6655 6656 for ( ; index < length ; index++ ) { 6657 prop = props[ index ]; 6658 tweeners[ prop ] = tweeners[ prop ] || []; 6659 tweeners[ prop ].unshift( callback ); 6660 } 6661 }, 6662 6663 prefilter: function( callback, prepend ) { 6664 if ( prepend ) { 6665 animationPrefilters.unshift( callback ); 6666 } else { 6667 animationPrefilters.push( callback ); 6668 } 6669 } 6670}); 6671 6672jQuery.speed = function( speed, easing, fn ) { 6673 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 6674 complete: fn || !fn && easing || 6675 jQuery.isFunction( speed ) && speed, 6676 duration: speed, 6677 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing 6678 }; 6679 6680 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : 6681 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; 6682 6683 // Normalize opt.queue - true/undefined/null -> "fx" 6684 if ( opt.queue == null || opt.queue === true ) { 6685 opt.queue = "fx"; 6686 } 6687 6688 // Queueing 6689 opt.old = opt.complete; 6690 6691 opt.complete = function() { 6692 if ( jQuery.isFunction( opt.old ) ) { 6693 opt.old.call( this ); 6694 } 6695 6696 if ( opt.queue ) { 6697 jQuery.dequeue( this, opt.queue ); 6698 } 6699 }; 6700 6701 return opt; 6702}; 6703 6704jQuery.fn.extend({ 6705 fadeTo: function( speed, to, easing, callback ) { 6706 6707 // Show any hidden elements after setting opacity to 0 6708 return this.filter( isHidden ).css( "opacity", 0 ).show() 6709 6710 // Animate to the value specified 6711 .end().animate({ opacity: to }, speed, easing, callback ); 6712 }, 6713 animate: function( prop, speed, easing, callback ) { 6714 var empty = jQuery.isEmptyObject( prop ), 6715 optall = jQuery.speed( speed, easing, callback ), 6716 doAnimation = function() { 6717 // Operate on a copy of prop so per-property easing won't be lost 6718 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 6719 6720 // Empty animations, or finishing resolves immediately 6721 if ( empty || data_priv.get( this, "finish" ) ) { 6722 anim.stop( true ); 6723 } 6724 }; 6725 doAnimation.finish = doAnimation; 6726 6727 return empty || optall.queue === false ? 6728 this.each( doAnimation ) : 6729 this.queue( optall.queue, doAnimation ); 6730 }, 6731 stop: function( type, clearQueue, gotoEnd ) { 6732 var stopQueue = function( hooks ) { 6733 var stop = hooks.stop; 6734 delete hooks.stop; 6735 stop( gotoEnd ); 6736 }; 6737 6738 if ( typeof type !== "string" ) { 6739 gotoEnd = clearQueue; 6740 clearQueue = type; 6741 type = undefined; 6742 } 6743 if ( clearQueue && type !== false ) { 6744 this.queue( type || "fx", [] ); 6745 } 6746 6747 return this.each(function() { 6748 var dequeue = true, 6749 index = type != null && type + "queueHooks", 6750 timers = jQuery.timers, 6751 data = data_priv.get( this ); 6752 6753 if ( index ) { 6754 if ( data[ index ] && data[ index ].stop ) { 6755 stopQueue( data[ index ] ); 6756 } 6757 } else { 6758 for ( index in data ) { 6759 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 6760 stopQueue( data[ index ] ); 6761 } 6762 } 6763 } 6764 6765 for ( index = timers.length; index--; ) { 6766 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { 6767 timers[ index ].anim.stop( gotoEnd ); 6768 dequeue = false;
vendor: 3,243 bytes, lines 6769-6900
6769 timers.splice( index, 1 ); 6770 } 6771 } 6772 6773 // Start the next in the queue if the last step wasn't forced. 6774 // Timers currently will call their complete callbacks, which 6775 // will dequeue but only if they were gotoEnd. 6776 if ( dequeue || !gotoEnd ) { 6777 jQuery.dequeue( this, type ); 6778 } 6779 }); 6780 }, 6781 finish: function( type ) { 6782 if ( type !== false ) { 6783 type = type || "fx"; 6784 } 6785 return this.each(function() { 6786 var index, 6787 data = data_priv.get( this ), 6788 queue = data[ type + "queue" ], 6789 hooks = data[ type + "queueHooks" ], 6790 timers = jQuery.timers, 6791 length = queue ? queue.length : 0; 6792 6793 // Enable finishing flag on private data 6794 data.finish = true; 6795 6796 // Empty the queue first 6797 jQuery.queue( this, type, [] ); 6798 6799 if ( hooks && hooks.stop ) { 6800 hooks.stop.call( this, true ); 6801 } 6802 6803 // Look for any active animations, and finish them 6804 for ( index = timers.length; index--; ) { 6805 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 6806 timers[ index ].anim.stop( true ); 6807 timers.splice( index, 1 ); 6808 } 6809 } 6810 6811 // Look for any animations in the old queue and finish them 6812 for ( index = 0; index < length; index++ ) { 6813 if ( queue[ index ] && queue[ index ].finish ) { 6814 queue[ index ].finish.call( this ); 6815 } 6816 } 6817 6818 // Turn off finishing flag 6819 delete data.finish; 6820 }); 6821 } 6822}); 6823 6824jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { 6825 var cssFn = jQuery.fn[ name ]; 6826 jQuery.fn[ name ] = function( speed, easing, callback ) { 6827 return speed == null || typeof speed === "boolean" ? 6828 cssFn.apply( this, arguments ) : 6829 this.animate( genFx( name, true ), speed, easing, callback ); 6830 }; 6831}); 6832 6833// Generate shortcuts for custom animations 6834jQuery.each({ 6835 slideDown: genFx("show"), 6836 slideUp: genFx("hide"), 6837 slideToggle: genFx("toggle"), 6838 fadeIn: { opacity: "show" }, 6839 fadeOut: { opacity: "hide" }, 6840 fadeToggle: { opacity: "toggle" } 6841}, function( name, props ) { 6842 jQuery.fn[ name ] = function( speed, easing, callback ) { 6843 return this.animate( props, speed, easing, callback ); 6844 }; 6845}); 6846 6847jQuery.timers = []; 6848jQuery.fx.tick = function() { 6849 var timer, 6850 i = 0, 6851 timers = jQuery.timers; 6852 6853 fxNow = jQuery.now(); 6854 6855 for ( ; i < timers.length; i++ ) { 6856 timer = timers[ i ]; 6857 // Checks the timer has not already been removed 6858 if ( !timer() && timers[ i ] === timer ) { 6859 timers.splice( i--, 1 ); 6860 } 6861 } 6862 6863 if ( !timers.length ) { 6864 jQuery.fx.stop(); 6865 } 6866 fxNow = undefined; 6867}; 6868 6869jQuery.fx.timer = function( timer ) { 6870 jQuery.timers.push( timer ); 6871 if ( timer() ) { 6872 jQuery.fx.start(); 6873 } else { 6874 jQuery.timers.pop(); 6875 } 6876}; 6877 6878jQuery.fx.interval = 13; 6879 6880jQuery.fx.start = function() { 6881 if ( !timerId ) { 6882 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); 6883 } 6884}; 6885 6886jQuery.fx.stop = function() { 6887 clearInterval( timerId ); 6888 timerId = null; 6889}; 6890 6891jQuery.fx.speeds = { 6892 slow: 600, 6893 fast: 200, 6894 // Default speed 6895 _default: 400 6896}; 6897 6898 6899// Based off of the plugin by Clint Helfers, with permission. 6900// http://blindsignals.com/index.php/2009/07/jquery-delay/
6901jQuery.fn.delay = function( time, type ) { 6902 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 6903 type = type || "fx"; 6904 6905 return this.queue( type, function( next, hooks ) { 6906 var timeout = setTimeout( next, time ); 6907 hooks.stop = function() { 6908 clearTimeout( timeout ); 6909 }; 6910 }); 6911}; 6912 6913 6914(function() { 6915 var input = document.createElement( "input" ), 6916 select = document.createElement( "select" ), 6917 opt = select.appendChild( document.createElement( "option" ) ); 6918 6919 input.type = "checkbox"; 6920 6921 // Support: iOS<=5.1, Android<=4.2+ 6922 // Default value for a checkbox should be "on" 6923 support.checkOn = input.value !== ""; 6924 6925 // Support: IE<=11+ 6926 // Must access selectedIndex to make default options select 6927 support.optSelected = opt.selected; 6928 6929 // Support: Android<=2.3 6930 // Options inside disabled selects are incorrectly marked as disabled 6931 select.disabled = true; 6932 support.optDisabled = !opt.disabled; 6933 6934 // Support: IE<=11+ 6935 // An input loses its value after becoming a radio 6936 input = document.createElement( "input" ); 6937 input.value = "t"; 6938 input.type = "radio"; 6939 support.radioValue = input.value === "t"; 6940})(); 6941 6942 6943var nodeHook, boolHook, 6944 attrHandle = jQuery.expr.attrHandle; 6945 6946jQuery.fn.extend({ 6947 attr: function( name, value ) { 6948 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 6949 }, 6950 6951 removeAttr: function( name ) { 6952 return this.each(function() { 6953 jQuery.removeAttr( this, name ); 6954 }); 6955 } 6956}); 6957 6958jQuery.extend({ 6959 attr: function( elem, name, value ) { 6960 var hooks, ret, 6961 nType = elem.nodeType; 6962 6963 // don't get/set attributes on text, comment and attribute nodes 6964 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 6965 return; 6966 } 6967 6968 // Fallback to prop when attributes are not supported 6969 if ( typeof elem.getAttribute === strundefined ) { 6970 return jQuery.prop( elem, name, value ); 6971 } 6972 6973 // All attributes are lowercase 6974 // Grab necessary hook if one is defined 6975 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 6976 name = name.toLowerCase(); 6977 hooks = jQuery.attrHooks[ name ] || 6978 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); 6979 } 6980 6981 if ( value !== undefined ) { 6982 6983 if ( value === null ) { 6984 jQuery.removeAttr( elem, name ); 6985 6986 } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { 6987 return ret; 6988 6989 } else { 6990 elem.setAttribute( name, value + "" ); 6991 return value; 6992 } 6993 6994 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { 6995 return ret; 6996 6997 } else { 6998 ret = jQuery.find.attr( elem, name ); 6999 7000 // Non-existent attributes return null, we normalize to undefined 7001 return ret == null ? 7002 undefined : 7003 ret; 7004 } 7005 }, 7006 7007 removeAttr: function( elem, value ) { 7008 var name, propName, 7009 i = 0, 7010 attrNames = value && value.match( rnotwhite ); 7011 7012 if ( attrNames && elem.nodeType === 1 ) { 7013 while ( (name = attrNames[i++]) ) { 7014 propName = jQuery.propFix[ name ] || name; 7015 7016 // Boolean attributes get special treatment (#10870) 7017 if ( jQuery.expr.match.bool.test( name ) ) { 7018 // Set corresponding property to false 7019 elem[ propName ] = false; 7020 } 7021 7022 elem.removeAttribute( name ); 7023 } 7024 } 7025 }, 7026 7027 attrHooks: { 7028 type: { 7029 set: function( elem, value ) { 7030 if ( !support.radioValue && value === "radio" && 7031 jQuery.nodeName( elem, "input" ) ) { 7032 var val = elem.value; 7033 elem.setAttribute( "type", value ); 7034 if ( val ) { 7035 elem.value = val; 7036 } 7037 return value; 7038 } 7039 } 7040 } 7041 } 7042}); 7043 7044// Hooks for boolean attributes 7045boolHook = { 7046 set: function( elem, value, name ) { 7047 if ( value === false ) { 7048 // Remove boolean attributes when set to false 7049 jQuery.removeAttr( elem, name ); 7050 } else { 7051 elem.setAttribute( name, name ); 7052 } 7053 return name; 7054 } 7055}; 7056jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 7057 var getter = attrHandle[ name ] || jQuery.find.attr; 7058 7059 attrHandle[ name ] = function( elem, name, isXML ) { 7060 var ret, handle; 7061 if ( !isXML ) { 7062 // Avoid an infinite loop by temporarily removing this function from the getter 7063 handle = attrHandle[ name ]; 7064 attrHandle[ name ] = ret; 7065 ret = getter( elem, name, isXML ) != null ? 7066 name.toLowerCase() : 7067 null; 7068 attrHandle[ name ] = handle; 7069 } 7070 return ret; 7071 }; 7072}); 7073 7074 7075 7076 7077var rfocusable = /^(?:input|select|textarea|button)$/i; 7078 7079jQuery.fn.extend({ 7080 prop: function( name, value ) { 7081 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 7082 }, 7083 7084 removeProp: function( name ) { 7085 return this.each(function() { 7086 delete this[ jQuery.propFix[ name ] || name ]; 7087 }); 7088 } 7089}); 7090 7091jQuery.extend({ 7092 propFix: { 7093 "for": "htmlFor", 7094 "class": "className" 7095 }, 7096 7097 prop: function( elem, name, value ) { 7098 var ret, hooks, notxml, 7099 nType = elem.nodeType; 7100 7101 // Don't get/set properties on text, comment and attribute nodes 7102 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { 7103 return; 7104 } 7105 7106 notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); 7107 7108 if ( notxml ) { 7109 // Fix name and attach hooks 7110 name = jQuery.propFix[ name ] || name; 7111 hooks = jQuery.propHooks[ name ]; 7112 } 7113 7114 if ( value !== undefined ) { 7115 return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? 7116 ret : 7117 ( elem[ name ] = value ); 7118 7119 } else { 7120 return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? 7121 ret : 7122 elem[ name ]; 7123 } 7124 }, 7125 7126 propHooks: { 7127 tabIndex: { 7128 get: function( elem ) { 7129 return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? 7130 elem.tabIndex : 7131 -1; 7132 } 7133 } 7134 } 7135}); 7136 7137if ( !support.optSelected ) { 7138 jQuery.propHooks.selected = { 7139 get: function( elem ) { 7140 var parent = elem.parentNode; 7141 if ( parent && parent.parentNode ) { 7142 parent.parentNode.selectedIndex; 7143 } 7144 return null; 7145 } 7146 }; 7147} 7148 7149jQuery.each([ 7150 "tabIndex", 7151 "readOnly", 7152 "maxLength", 7153 "cellSpacing", 7154 "cellPadding", 7155 "rowSpan", 7156 "colSpan", 7157 "useMap", 7158 "frameBorder", 7159 "contentEditable" 7160], function() { 7161 jQuery.propFix[ this.toLowerCase() ] = this; 7162}); 7163 7164 7165 7166 7167var rclass = /[\t\r\n\f]/g; 7168 7169jQuery.fn.extend({ 7170 addClass: function( value ) { 7171 var classes, elem, cur, clazz, j, finalValue, 7172 proceed = typeof value === "string" && value, 7173 i = 0, 7174 len = this.length; 7175 7176 if ( jQuery.isFunction( value ) ) { 7177 return this.each(function( j ) { 7178 jQuery( this ).addClass( value.call( this, j, this.className ) ); 7179 }); 7180 } 7181 7182 if ( proceed ) { 7183 // The disjunction here is for better compressibility (see removeClass) 7184 classes = ( value || "" ).match( rnotwhite ) || []; 7185 7186 for ( ; i < len; i++ ) { 7187 elem = this[ i ]; 7188 cur = elem.nodeType === 1 && ( elem.className ? 7189 ( " " + elem.className + " " ).replace( rclass, " " ) : 7190 " " 7191 ); 7192 7193 if ( cur ) { 7194 j = 0; 7195 while ( (clazz = classes[j++]) ) { 7196 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 7197 cur += clazz + " "; 7198 } 7199 } 7200 7201 // only assign if different to avoid unneeded rendering. 7202 finalValue = jQuery.trim( cur ); 7203 if ( elem.className !== finalValue ) { 7204 elem.className = finalValue; 7205 } 7206 } 7207 } 7208 } 7209 7210 return this; 7211 }, 7212 7213 removeClass: function( value ) { 7214 var classes, elem, cur, clazz, j, finalValue, 7215 proceed = arguments.length === 0 || typeof value === "string" && value, 7216 i = 0, 7217 len = this.length; 7218 7219 if ( jQuery.isFunction( value ) ) { 7220 return this.each(function( j ) { 7221 jQuery( this ).removeClass( value.call( this, j, this.className ) ); 7222 }); 7223 } 7224 if ( proceed ) { 7225 classes = ( value || "" ).match( rnotwhite ) || []; 7226 7227 for ( ; i < len; i++ ) { 7228 elem = this[ i ]; 7229 // This expression is here for better compressibility (see addClass) 7230 cur = elem.nodeType === 1 && ( elem.className ? 7231 ( " " + elem.className + " " ).replace( rclass, " " ) : 7232 "" 7233 ); 7234 7235 if ( cur ) { 7236 j = 0; 7237 while ( (clazz = classes[j++]) ) {
7238 // Remove *all* instances 7239 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { 7240 cur = cur.replace( " " + clazz + " ", " " ); 7241 } 7242 } 7243 7244 // Only assign if different to avoid unneeded rendering. 7245 finalValue = value ? jQuery.trim( cur ) : ""; 7246 if ( elem.className !== finalValue ) { 7247 elem.className = finalValue; 7248 } 7249 } 7250 } 7251 } 7252 7253 return this; 7254 }, 7255 7256 toggleClass: function( value, stateVal ) { 7257 var type = typeof value; 7258 7259 if ( typeof stateVal === "boolean" && type === "string" ) { 7260 return stateVal ? this.addClass( value ) : this.removeClass( value ); 7261 } 7262 7263 if ( jQuery.isFunction( value ) ) { 7264 return this.each(function( i ) { 7265 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); 7266 }); 7267 } 7268 7269 return this.each(function() { 7270 if ( type === "string" ) { 7271 // Toggle individual class names 7272 var className, 7273 i = 0, 7274 self = jQuery( this ), 7275 classNames = value.match( rnotwhite ) || []; 7276 7277 while ( (className = classNames[ i++ ]) ) { 7278 // Check each className given, space separated list 7279 if ( self.hasClass( className ) ) { 7280 self.removeClass( className ); 7281 } else { 7282 self.addClass( className ); 7283 } 7284 } 7285 7286 // Toggle whole class name 7287 } else if ( type === strundefined || type === "boolean" ) { 7288 if ( this.className ) { 7289 // store className if set 7290 data_priv.set( this, "__className__", this.className ); 7291 } 7292 7293 // If the element has a class name or if we're passed `false`, 7294 // then remove the whole classname (if there was one, the above saved it). 7295 // Otherwise bring back whatever was previously saved (if anything), 7296 // falling back to the empty string if nothing was stored. 7297 this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; 7298 } 7299 }); 7300 }, 7301 7302 hasClass: function( selector ) { 7303 var className = " " + selector + " ", 7304 i = 0, 7305 l = this.length; 7306 for ( ; i < l; i++ ) { 7307 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { 7308 return true; 7309 } 7310 } 7311 7312 return false; 7313 } 7314}); 7315 7316 7317 7318 7319var rreturn = /\r/g; 7320 7321jQuery.fn.extend({ 7322 val: function( value ) { 7323 var hooks, ret, isFunction, 7324 elem = this[0]; 7325 7326 if ( !arguments.length ) { 7327 if ( elem ) { 7328 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 7329 7330 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { 7331 return ret; 7332 } 7333 7334 ret = elem.value; 7335 7336 return typeof ret === "string" ? 7337 // Handle most common string cases 7338 ret.replace(rreturn, "") : 7339 // Handle cases where value is null/undef or number 7340 ret == null ? "" : ret; 7341 } 7342 7343 return; 7344 } 7345 7346 isFunction = jQuery.isFunction( value ); 7347 7348 return this.each(function( i ) { 7349 var val; 7350 7351 if ( this.nodeType !== 1 ) { 7352 return; 7353 } 7354 7355 if ( isFunction ) { 7356 val = value.call( this, i, jQuery( this ).val() ); 7357 } else { 7358 val = value; 7359 } 7360 7361 // Treat null/undefined as ""; convert numbers to string 7362 if ( val == null ) { 7363 val = ""; 7364 7365 } else if ( typeof val === "number" ) { 7366 val += ""; 7367 7368 } else if ( jQuery.isArray( val ) ) { 7369 val = jQuery.map( val, function( value ) { 7370 return value == null ? "" : value + ""; 7371 }); 7372 } 7373 7374 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 7375 7376 // If set returns undefined, fall back to normal setting 7377 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { 7378 this.value = val; 7379 } 7380 }); 7381 } 7382}); 7383 7384jQuery.extend({ 7385 valHooks: { 7386 option: { 7387 get: function( elem ) { 7388 var val = jQuery.find.attr( elem, "value" ); 7389 return val != null ? 7390 val :
7391 // Support: IE10-11+ 7392 // option.text throws exceptions (#14686, #14858) 7393 jQuery.trim( jQuery.text( elem ) ); 7394 } 7395 }, 7396 select: { 7397 get: function( elem ) { 7398 var value, option, 7399 options = elem.options, 7400 index = elem.selectedIndex, 7401 one = elem.type === "select-one" || index < 0, 7402 values = one ? null : [], 7403 max = one ? index + 1 : options.length, 7404 i = index < 0 ? 7405 max : 7406 one ? index : 0; 7407 7408 // Loop through all the selected options 7409 for ( ; i < max; i++ ) { 7410 option = options[ i ]; 7411 7412 // IE6-9 doesn't update selected after form reset (#2551) 7413 if ( ( option.selected || i === index ) && 7414 // Don't return options that are disabled or in a disabled optgroup 7415 ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) && 7416 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { 7417 7418 // Get the specific value for the option 7419 value = jQuery( option ).val(); 7420 7421 // We don't need an array for one selects 7422 if ( one ) { 7423 return value; 7424 } 7425 7426 // Multi-Selects return an array 7427 values.push( value ); 7428 } 7429 } 7430 7431 return values; 7432 }, 7433 7434 set: function( elem, value ) { 7435 var optionSet, option, 7436 options = elem.options, 7437 values = jQuery.makeArray( value ), 7438 i = options.length; 7439 7440 while ( i-- ) { 7441 option = options[ i ]; 7442 if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) { 7443 optionSet = true; 7444 } 7445 } 7446 7447 // Force browsers to behave consistently when non-matching value is set 7448 if ( !optionSet ) { 7449 elem.selectedIndex = -1; 7450 } 7451 return values; 7452 } 7453 } 7454 } 7455}); 7456 7457// Radios and checkboxes getter/setter 7458jQuery.each([ "radio", "checkbox" ], function() { 7459 jQuery.valHooks[ this ] = { 7460 set: function( elem, value ) { 7461 if ( jQuery.isArray( value ) ) { 7462 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); 7463 } 7464 } 7465 }; 7466 if ( !support.checkOn ) { 7467 jQuery.valHooks[ this ].get = function( elem ) { 7468 return elem.getAttribute("value") === null ? "on" : elem.value; 7469 }; 7470 } 7471}); 7472 7473 7474 7475 7476// Return jQuery for attributes-only inclusion 7477 7478 7479jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + 7480 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 7481 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { 7482 7483 // Handle event binding 7484 jQuery.fn[ name ] = function( data, fn ) { 7485 return arguments.length > 0 ? 7486 this.on( name, null, data, fn ) : 7487 this.trigger( name ); 7488 }; 7489}); 7490 7491jQuery.fn.extend({ 7492 hover: function( fnOver, fnOut ) { 7493 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 7494 }, 7495 7496 bind: function( types, data, fn ) { 7497 return this.on( types, null, data, fn ); 7498 }, 7499 unbind: function( types, fn ) { 7500 return this.off( types, null, fn ); 7501 }, 7502 7503 delegate: function( selector, types, data, fn ) { 7504 return this.on( types, selector, data, fn ); 7505 }, 7506 undelegate: function( selector, types, fn ) { 7507 // ( namespace ) or ( selector, types [, fn] ) 7508 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); 7509 } 7510}); 7511 7512 7513var nonce = jQuery.now(); 7514 7515var rquery = (/\?/); 7516 7517 7518 7519// Support: Android 2.3 7520// Workaround failure to string-cast null input 7521jQuery.parseJSON = function( data ) { 7522 return JSON.parse( data + "" ); 7523}; 7524 7525 7526// Cross-browser xml parsing 7527jQuery.parseXML = function( data ) { 7528 var xml, tmp; 7529 if ( !data || typeof data !== "string" ) { 7530 return null; 7531 } 7532 7533 // Support: IE9 7534 try { 7535 tmp = new DOMParser(); 7536 xml = tmp.parseFromString( data, "text/xml" ); 7537 } catch ( e ) { 7538 xml = undefined; 7539 } 7540 7541 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 7542 jQuery.error( "Invalid XML: " + data ); 7543 } 7544 return xml; 7545}; 7546 7547 7548var 7549 rhash = /#.*$/, 7550 rts = /([?&])_=[^&]*/, 7551 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
vendor: 4,472 bytes, lines 7552-7692
7552 // #7653, #8125, #8152: local protocol detection 7553 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 7554 rnoContent = /^(?:GET|HEAD)$/, 7555 rprotocol = /^\/\//, 7556 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, 7557 7558 /* Prefilters 7559 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 7560 * 2) These are called: 7561 * - BEFORE asking for a transport 7562 * - AFTER param serialization (s.data is a string if s.processData is true) 7563 * 3) key is the dataType 7564 * 4) the catchall symbol "*" can be used 7565 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 7566 */ 7567 prefilters = {}, 7568 7569 /* Transports bindings 7570 * 1) key is the dataType 7571 * 2) the catchall symbol "*" can be used 7572 * 3) selection will start with transport dataType and THEN go to "*" if needed 7573 */ 7574 transports = {}, 7575 7576 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 7577 allTypes = "*/".concat( "*" ), 7578 7579 // Document location 7580 ajaxLocation = window.location.href, 7581 7582 // Segment location into parts 7583 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; 7584 7585// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 7586function addToPrefiltersOrTransports( structure ) { 7587 7588 // dataTypeExpression is optional and defaults to "*" 7589 return function( dataTypeExpression, func ) { 7590 7591 if ( typeof dataTypeExpression !== "string" ) { 7592 func = dataTypeExpression; 7593 dataTypeExpression = "*"; 7594 } 7595 7596 var dataType, 7597 i = 0, 7598 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; 7599 7600 if ( jQuery.isFunction( func ) ) { 7601 // For each dataType in the dataTypeExpression 7602 while ( (dataType = dataTypes[i++]) ) { 7603 // Prepend if requested 7604 if ( dataType[0] === "+" ) { 7605 dataType = dataType.slice( 1 ) || "*"; 7606 (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); 7607 7608 // Otherwise append 7609 } else { 7610 (structure[ dataType ] = structure[ dataType ] || []).push( func ); 7611 } 7612 } 7613 } 7614 }; 7615} 7616 7617// Base inspection function for prefilters and transports 7618function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 7619 7620 var inspected = {}, 7621 seekingTransport = ( structure === transports ); 7622 7623 function inspect( dataType ) { 7624 var selected; 7625 inspected[ dataType ] = true; 7626 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 7627 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 7628 if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 7629 options.dataTypes.unshift( dataTypeOrTransport ); 7630 inspect( dataTypeOrTransport ); 7631 return false; 7632 } else if ( seekingTransport ) { 7633 return !( selected = dataTypeOrTransport ); 7634 } 7635 }); 7636 return selected; 7637 } 7638 7639 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 7640} 7641 7642// A special extend for ajax options 7643// that takes "flat" options (not to be deep extended) 7644// Fixes #9887 7645function ajaxExtend( target, src ) { 7646 var key, deep, 7647 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 7648 7649 for ( key in src ) { 7650 if ( src[ key ] !== undefined ) { 7651 ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; 7652 } 7653 } 7654 if ( deep ) { 7655 jQuery.extend( true, target, deep ); 7656 } 7657 7658 return target; 7659} 7660 7661/* Handles responses to an ajax request: 7662 * - finds the right dataType (mediates between content-type and expected dataType) 7663 * - returns the corresponding response 7664 */ 7665function ajaxHandleResponses( s, jqXHR, responses ) { 7666 7667 var ct, type, finalDataType, firstDataType, 7668 contents = s.contents, 7669 dataTypes = s.dataTypes; 7670 7671 // Remove auto dataType and get content-type in the process 7672 while ( dataTypes[ 0 ] === "*" ) { 7673 dataTypes.shift(); 7674 if ( ct === undefined ) { 7675 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); 7676 } 7677 } 7678 7679 // Check if we're dealing with a known content-type 7680 if ( ct ) { 7681 for ( type in contents ) { 7682 if ( contents[ type ] && contents[ type ].test( ct ) ) { 7683 dataTypes.unshift( type ); 7684 break; 7685 } 7686 } 7687 } 7688 7689 // Check to see if we have a response for the expected dataType 7690 if ( dataTypes[ 0 ] in responses ) { 7691 finalDataType = dataTypes[ 0 ]; 7692 } else {
7693 // Try convertible dataTypes 7694 for ( type in responses ) { 7695 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { 7696 finalDataType = type; 7697 break; 7698 } 7699 if ( !firstDataType ) { 7700 firstDataType = type; 7701 } 7702 } 7703 // Or just use first one 7704 finalDataType = finalDataType || firstDataType; 7705 } 7706 7707 // If we found a dataType 7708 // We add the dataType to the list if needed 7709 // and return the corresponding response 7710 if ( finalDataType ) { 7711 if ( finalDataType !== dataTypes[ 0 ] ) { 7712 dataTypes.unshift( finalDataType ); 7713 } 7714 return responses[ finalDataType ]; 7715 } 7716} 7717 7718/* Chain conversions given the request and the original response 7719 * Also sets the responseXXX fields on the jqXHR instance 7720 */ 7721function ajaxConvert( s, response, jqXHR, isSuccess ) { 7722 var conv2, current, conv, tmp, prev, 7723 converters = {}, 7724 // Work with a copy of dataTypes in case we need to modify it for conversion 7725 dataTypes = s.dataTypes.slice(); 7726 7727 // Create converters map with lowercased keys 7728 if ( dataTypes[ 1 ] ) { 7729 for ( conv in s.converters ) { 7730 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 7731 } 7732 } 7733 7734 current = dataTypes.shift(); 7735 7736 // Convert to each sequential dataType 7737 while ( current ) { 7738 7739 if ( s.responseFields[ current ] ) { 7740 jqXHR[ s.responseFields[ current ] ] = response; 7741 } 7742 7743 // Apply the dataFilter if provided 7744 if ( !prev && isSuccess && s.dataFilter ) { 7745 response = s.dataFilter( response, s.dataType ); 7746 } 7747 7748 prev = current; 7749 current = dataTypes.shift(); 7750 7751 if ( current ) { 7752 7753 // There's only work to do if current dataType is non-auto 7754 if ( current === "*" ) { 7755 7756 current = prev; 7757 7758 // Convert response if prev dataType is non-auto and differs from current 7759 } else if ( prev !== "*" && prev !== current ) { 7760 7761 // Seek a direct converter 7762 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 7763 7764 // If none found, seek a pair 7765 if ( !conv ) { 7766 for ( conv2 in converters ) { 7767 7768 // If conv2 outputs current 7769 tmp = conv2.split( " " ); 7770 if ( tmp[ 1 ] === current ) { 7771 7772 // If prev can be converted to accepted input 7773 conv = converters[ prev + " " + tmp[ 0 ] ] || 7774 converters[ "* " + tmp[ 0 ] ]; 7775 if ( conv ) { 7776 // Condense equivalence converters 7777 if ( conv === true ) { 7778 conv = converters[ conv2 ]; 7779 7780 // Otherwise, insert the intermediate dataType 7781 } else if ( converters[ conv2 ] !== true ) { 7782 current = tmp[ 0 ]; 7783 dataTypes.unshift( tmp[ 1 ] ); 7784 } 7785 break; 7786 } 7787 } 7788 } 7789 } 7790 7791 // Apply converter (if not an equivalence) 7792 if ( conv !== true ) { 7793 7794 // Unless errors are allowed to bubble, catch and return them 7795 if ( conv && s[ "throws" ] ) { 7796 response = conv( response ); 7797 } else { 7798 try { 7799 response = conv( response ); 7800 } catch ( e ) { 7801 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; 7802 } 7803 } 7804 } 7805 } 7806 } 7807 } 7808 7809 return { state: "success", data: response }; 7810} 7811 7812jQuery.extend({ 7813 7814 // Counter for holding the number of active queries 7815 active: 0, 7816 7817 // Last-Modified header cache for next request 7818 lastModified: {}, 7819 etag: {}, 7820 7821 ajaxSettings: { 7822 url: ajaxLocation, 7823 type: "GET", 7824 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), 7825 global: true, 7826 processData: true, 7827 async: true, 7828 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 7829 /* 7830 timeout: 0, 7831 data: null, 7832 dataType: null, 7833 username: null, 7834 password: null, 7835 cache: null, 7836 throws: false, 7837 traditional: false, 7838 headers: {}, 7839 */ 7840 7841 accepts: { 7842 "*": allTypes, 7843 text: "text/plain", 7844 html: "text/html", 7845 xml: "application/xml, text/xml", 7846 json: "application/json, text/javascript" 7847 }, 7848 7849 contents: { 7850 xml: /xml/, 7851 html: /html/, 7852 json: /json/ 7853 }, 7854 7855 responseFields: { 7856 xml: "responseXML", 7857 text: "responseText", 7858 json: "responseJSON" 7859 }, 7860 7861 // Data converters 7862 // Keys separate source (or catchall "*") and destination types with a single space 7863 converters: { 7864 7865 // Convert anything to text 7866 "* text": String, 7867 7868 // Text to html (true = no transformation) 7869 "text html": true, 7870 7871 // Evaluate text as a json expression 7872 "text json": jQuery.parseJSON, 7873 7874 // Parse text as xml 7875 "text xml": jQuery.parseXML 7876 }, 7877 7878 // For options that shouldn't be deep extended: 7879 // you can add your own custom options here if 7880 // and when you create one that shouldn't be 7881 // deep extended (see ajaxExtend) 7882 flatOptions: { 7883 url: true, 7884 context: true 7885 } 7886 }, 7887 7888 // Creates a full fledged settings object into target 7889 // with both ajaxSettings and settings fields. 7890 // If target is omitted, writes into ajaxSettings. 7891 ajaxSetup: function( target, settings ) { 7892 return settings ? 7893 7894 // Building a settings object 7895 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 7896 7897 // Extending ajaxSettings 7898 ajaxExtend( jQuery.ajaxSettings, target ); 7899 }, 7900 7901 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 7902 ajaxTransport: addToPrefiltersOrTransports( transports ), 7903 7904 // Main method 7905 ajax: function( url, options ) { 7906 7907 // If url is an object, simulate pre-1.5 signature 7908 if ( typeof url === "object" ) { 7909 options = url; 7910 url = undefined; 7911 } 7912 7913 // Force options to be an object 7914 options = options || {}; 7915 7916 var transport, 7917 // URL without anti-cache param 7918 cacheURL, 7919 // Response headers 7920 responseHeadersString, 7921 responseHeaders, 7922 // timeout handle 7923 timeoutTimer, 7924 // Cross-domain detection vars 7925 parts, 7926 // To know if global events are to be dispatched 7927 fireGlobals, 7928 // Loop variable 7929 i, 7930 // Create the final options object 7931 s = jQuery.ajaxSetup( {}, options ), 7932 // Callbacks context 7933 callbackContext = s.context || s, 7934 // Context for global events is callbackContext if it is a DOM node or jQuery collection 7935 globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? 7936 jQuery( callbackContext ) : 7937 jQuery.event, 7938 // Deferreds 7939 deferred = jQuery.Deferred(), 7940 completeDeferred = jQuery.Callbacks("once memory"), 7941 // Status-dependent callbacks 7942 statusCode = s.statusCode || {}, 7943 // Headers (they are sent all at once) 7944 requestHeaders = {}, 7945 requestHeadersNames = {}, 7946 // The jqXHR state 7947 state = 0, 7948 // Default abort message 7949 strAbort = "canceled", 7950 // Fake xhr 7951 jqXHR = { 7952 readyState: 0, 7953 7954 // Builds headers hashtable if needed 7955 getResponseHeader: function( key ) { 7956 var match; 7957 if ( state === 2 ) { 7958 if ( !responseHeaders ) { 7959 responseHeaders = {}; 7960 while ( (match = rheaders.exec( responseHeadersString )) ) { 7961 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; 7962 } 7963 } 7964 match = responseHeaders[ key.toLowerCase() ]; 7965 } 7966 return match == null ? null : match; 7967 }, 7968 7969 // Raw string 7970 getAllResponseHeaders: function() { 7971 return state === 2 ? responseHeadersString : null; 7972 }, 7973 7974 // Caches the header 7975 setRequestHeader: function( name, value ) { 7976 var lname = name.toLowerCase(); 7977 if ( !state ) { 7978 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; 7979 requestHeaders[ name ] = value; 7980 } 7981 return this; 7982 }, 7983 7984 // Overrides response content-type header 7985 overrideMimeType: function( type ) { 7986 if ( !state ) { 7987 s.mimeType = type; 7988 } 7989 return this; 7990 }, 7991 7992 // Status-dependent callbacks 7993 statusCode: function( map ) { 7994 var code; 7995 if ( map ) { 7996 if ( state < 2 ) { 7997 for ( code in map ) { 7998 // Lazy-add the new callback in a way that preserves old ones 7999 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 8000 } 8001 } else { 8002 // Execute the appropriate callbacks 8003 jqXHR.always( map[ jqXHR.status ] ); 8004 } 8005 } 8006 return this; 8007 }, 8008 8009 // Cancel the request 8010 abort: function( statusText ) { 8011 var finalText = statusText || strAbort; 8012 if ( transport ) { 8013 transport.abort( finalText ); 8014 } 8015 done( 0, finalText ); 8016 return this; 8017 } 8018 }; 8019 8020 // Attach deferreds 8021 deferred.promise( jqXHR ).complete = completeDeferred.add; 8022 jqXHR.success = jqXHR.done; 8023 jqXHR.error = jqXHR.fail; 8024 8025 // Remove hash character (#7531: and string promotion) 8026 // Add protocol if not provided (prefilters might expect it) 8027 // Handle falsy url in the settings object (#10093: consistency with old signature) 8028 // We also use the url parameter if available 8029 s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) 8030 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 8031 8032 // Alias method option to type as per ticket #12004 8033 s.type = options.method || options.type || s.method || s.type; 8034 8035 // Extract dataTypes list 8036 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; 8037 8038 // A cross-domain request is in order when we have a protocol:host:port mismatch 8039 if ( s.crossDomain == null ) { 8040 parts = rurl.exec( s.url.toLowerCase() ); 8041 s.crossDomain = !!( parts && 8042 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || 8043 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== 8044 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) 8045 ); 8046 } 8047 8048 // Convert data if not already a string 8049 if ( s.data && s.processData && typeof s.data !== "string" ) { 8050 s.data = jQuery.param( s.data, s.traditional ); 8051 } 8052 8053 // Apply prefilters 8054 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 8055 8056 // If request was aborted inside a prefilter, stop there 8057 if ( state === 2 ) { 8058 return jqXHR; 8059 } 8060 8061 // We can fire global events as of now if asked to 8062 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 8063 fireGlobals = jQuery.event && s.global; 8064 8065 // Watch for a new set of requests 8066 if ( fireGlobals && jQuery.active++ === 0 ) { 8067 jQuery.event.trigger("ajaxStart"); 8068 } 8069 8070 // Uppercase the type 8071 s.type = s.type.toUpperCase(); 8072 8073 // Determine if request has content 8074 s.hasContent = !rnoContent.test( s.type ); 8075 8076 // Save the URL in case we're toying with the If-Modified-Since 8077 // and/or If-None-Match header later on 8078 cacheURL = s.url; 8079 8080 // More options handling for requests with no content 8081 if ( !s.hasContent ) { 8082 8083 // If data is available, append data to url 8084 if ( s.data ) {
8085 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); 8086 // #9682: remove data so that it's not used in an eventual retry 8087 delete s.data; 8088 } 8089 8090 // Add anti-cache in url if needed 8091 if ( s.cache === false ) { 8092 s.url = rts.test( cacheURL ) ? 8093 8094 // If there is already a '_' parameter, set its value 8095 cacheURL.replace( rts, "$1_=" + nonce++ ) : 8096 8097 // Otherwise add one to the end 8098 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; 8099 } 8100 } 8101 8102 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 8103 if ( s.ifModified ) { 8104 if ( jQuery.lastModified[ cacheURL ] ) { 8105 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 8106 } 8107 if ( jQuery.etag[ cacheURL ] ) { 8108 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 8109 } 8110 } 8111 8112 // Set the correct header, if data is being sent 8113 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 8114 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 8115 } 8116 8117 // Set the Accepts header for the server, depending on the dataType 8118 jqXHR.setRequestHeader( 8119 "Accept", 8120 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? 8121 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 8122 s.accepts[ "*" ] 8123 ); 8124 8125 // Check for headers option 8126 for ( i in s.headers ) { 8127 jqXHR.setRequestHeader( i, s.headers[ i ] ); 8128 } 8129 8130 // Allow custom headers/mimetypes and early abort 8131 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { 8132 // Abort if not done already and return 8133 return jqXHR.abort(); 8134 } 8135 8136 // Aborting is no longer a cancellation 8137 strAbort = "abort"; 8138 8139 // Install callbacks on deferreds 8140 for ( i in { success: 1, error: 1, complete: 1 } ) { 8141 jqXHR[ i ]( s[ i ] ); 8142 } 8143 8144 // Get transport 8145 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 8146 8147 // If no transport, we auto-abort 8148 if ( !transport ) { 8149 done( -1, "No Transport" ); 8150 } else { 8151 jqXHR.readyState = 1; 8152 8153 // Send global event 8154 if ( fireGlobals ) { 8155 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 8156 } 8157 // Timeout 8158 if ( s.async && s.timeout > 0 ) { 8159 timeoutTimer = setTimeout(function() { 8160 jqXHR.abort("timeout"); 8161 }, s.timeout ); 8162 } 8163 8164 try { 8165 state = 1; 8166 transport.send( requestHeaders, done ); 8167 } catch ( e ) { 8168 // Propagate exception as error if not done 8169 if ( state < 2 ) { 8170 done( -1, e ); 8171 // Simply rethrow otherwise 8172 } else { 8173 throw e; 8174 } 8175 } 8176 } 8177 8178 // Callback for when everything is done 8179 function done( status, nativeStatusText, responses, headers ) { 8180 var isSuccess, success, error, response, modified, 8181 statusText = nativeStatusText; 8182 8183 // Called once 8184 if ( state === 2 ) { 8185 return; 8186 } 8187 8188 // State is "done" now 8189 state = 2; 8190 8191 // Clear timeout if it exists 8192 if ( timeoutTimer ) { 8193 clearTimeout( timeoutTimer ); 8194 } 8195 8196 // Dereference transport for early garbage collection 8197 // (no matter how long the jqXHR object will be used) 8198 transport = undefined; 8199 8200 // Cache response headers 8201 responseHeadersString = headers || ""; 8202 8203 // Set readyState 8204 jqXHR.readyState = status > 0 ? 4 : 0; 8205 8206 // Determine if successful 8207 isSuccess = status >= 200 && status < 300 || status === 304; 8208 8209 // Get response data 8210 if ( responses ) { 8211 response = ajaxHandleResponses( s, jqXHR, responses ); 8212 } 8213 8214 // Convert no matter what (that way responseXXX fields are always set) 8215 response = ajaxConvert( s, response, jqXHR, isSuccess ); 8216 8217 // If successful, handle type chaining 8218 if ( isSuccess ) { 8219 8220 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 8221 if ( s.ifModified ) { 8222 modified = jqXHR.getResponseHeader("Last-Modified"); 8223 if ( modified ) { 8224 jQuery.lastModified[ cacheURL ] = modified; 8225 } 8226 modified = jqXHR.getResponseHeader("etag"); 8227 if ( modified ) { 8228 jQuery.etag[ cacheURL ] = modified; 8229 } 8230 } 8231 8232 // if no content 8233 if ( status === 204 || s.type === "HEAD" ) { 8234 statusText = "nocontent"; 8235 8236 // if not modified 8237 } else if ( status === 304 ) { 8238 statusText = "notmodified"; 8239 8240 // If we have data, let's convert it 8241 } else { 8242 statusText = response.state; 8243 success = response.data; 8244 error = response.error; 8245 isSuccess = !error; 8246 } 8247 } else { 8248 // Extract error from statusText and normalize for non-aborts 8249 error = statusText; 8250 if ( status || !statusText ) { 8251 statusText = "error"; 8252 if ( status < 0 ) { 8253 status = 0; 8254 } 8255 } 8256 } 8257 8258 // Set data for the fake xhr object 8259 jqXHR.status = status; 8260 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 8261 8262 // Success/Error 8263 if ( isSuccess ) { 8264 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 8265 } else { 8266 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 8267 } 8268 8269 // Status-dependent callbacks 8270 jqXHR.statusCode( statusCode ); 8271 statusCode = undefined; 8272 8273 if ( fireGlobals ) { 8274 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 8275 [ jqXHR, s, isSuccess ? success : error ] ); 8276 } 8277 8278 // Complete 8279 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 8280 8281 if ( fireGlobals ) { 8282 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 8283 // Handle the global AJAX counter 8284 if ( !( --jQuery.active ) ) { 8285 jQuery.event.trigger("ajaxStop"); 8286 } 8287 } 8288 } 8289 8290 return jqXHR; 8291 }, 8292 8293 getJSON: function( url, data, callback ) { 8294 return jQuery.get( url, data, callback, "json" ); 8295 }, 8296 8297 getScript: function( url, callback ) { 8298 return jQuery.get( url, undefined, callback, "script" ); 8299 } 8300}); 8301 8302jQuery.each( [ "get", "post" ], function( i, method ) { 8303 jQuery[ method ] = function( url, data, callback, type ) { 8304 // Shift arguments if data argument was omitted 8305 if ( jQuery.isFunction( data ) ) { 8306 type = type || callback; 8307 callback = data; 8308 data = undefined; 8309 } 8310 8311 return jQuery.ajax({ 8312 url: url, 8313 type: method, 8314 dataType: type, 8315 data: data, 8316 success: callback 8317 }); 8318 }; 8319}); 8320 8321 8322jQuery._evalUrl = function( url ) { 8323 return jQuery.ajax({ 8324 url: url, 8325 type: "GET", 8326 dataType: "script", 8327 async: false, 8328 global: false, 8329 "throws": true 8330 }); 8331}; 8332 8333 8334jQuery.fn.extend({ 8335 wrapAll: function( html ) { 8336 var wrap; 8337 8338 if ( jQuery.isFunction( html ) ) { 8339 return this.each(function( i ) { 8340 jQuery( this ).wrapAll( html.call(this, i) ); 8341 }); 8342 } 8343 8344 if ( this[ 0 ] ) { 8345 8346 // The elements to wrap the target around 8347 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 8348 8349 if ( this[ 0 ].parentNode ) { 8350 wrap.insertBefore( this[ 0 ] ); 8351 } 8352 8353 wrap.map(function() { 8354 var elem = this; 8355 8356 while ( elem.firstElementChild ) { 8357 elem = elem.firstElementChild; 8358 } 8359 8360 return elem; 8361 }).append( this ); 8362 } 8363 8364 return this; 8365 }, 8366 8367 wrapInner: function( html ) { 8368 if ( jQuery.isFunction( html ) ) { 8369 return this.each(function( i ) { 8370 jQuery( this ).wrapInner( html.call(this, i) ); 8371 }); 8372 } 8373 8374 return this.each(function() { 8375 var self = jQuery( this ), 8376 contents = self.contents(); 8377 8378 if ( contents.length ) { 8379 contents.wrapAll( html ); 8380 8381 } else { 8382 self.append( html ); 8383 } 8384 }); 8385 }, 8386 8387 wrap: function( html ) { 8388 var isFunction = jQuery.isFunction( html ); 8389 8390 return this.each(function( i ) { 8391 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); 8392 }); 8393 }, 8394 8395 unwrap: function() { 8396 return this.parent().each(function() { 8397 if ( !jQuery.nodeName( this, "body" ) ) { 8398 jQuery( this ).replaceWith( this.childNodes ); 8399 } 8400 }).end(); 8401 } 8402}); 8403 8404 8405jQuery.expr.filters.hidden = function( elem ) {
8406 // Support: Opera <= 12.12 8407 // Opera reports offsetWidths and offsetHeights less than zero on some elements 8408 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; 8409}; 8410jQuery.expr.filters.visible = function( elem ) { 8411 return !jQuery.expr.filters.hidden( elem ); 8412}; 8413 8414 8415 8416 8417var r20 = /%20/g, 8418 rbracket = /\[\]$/, 8419 rCRLF = /\r?\n/g, 8420 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8421 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8422 8423function buildParams( prefix, obj, traditional, add ) { 8424 var name; 8425 8426 if ( jQuery.isArray( obj ) ) { 8427 // Serialize array item. 8428 jQuery.each( obj, function( i, v ) { 8429 if ( traditional || rbracket.test( prefix ) ) { 8430 // Treat each array item as a scalar. 8431 add( prefix, v ); 8432 8433 } else { 8434 // Item is non-scalar (array or object), encode its numeric index. 8435 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); 8436 } 8437 }); 8438 8439 } else if ( !traditional && jQuery.type( obj ) === "object" ) { 8440 // Serialize object item. 8441 for ( name in obj ) { 8442 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 8443 } 8444 8445 } else { 8446 // Serialize scalar item. 8447 add( prefix, obj ); 8448 } 8449} 8450 8451// Serialize an array of form elements or a set of 8452// key/values into a query string 8453jQuery.param = function( a, traditional ) { 8454 var prefix, 8455 s = [], 8456 add = function( key, value ) { 8457 // If value is a function, invoke it and return its value 8458 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); 8459 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); 8460 }; 8461 8462 // Set traditional to true for jQuery <= 1.3.2 behavior. 8463 if ( traditional === undefined ) { 8464 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; 8465 } 8466 8467 // If an array was passed in, assume that it is an array of form elements. 8468 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 8469 // Serialize the form elements 8470 jQuery.each( a, function() { 8471 add( this.name, this.value ); 8472 }); 8473 8474 } else { 8475 // If traditional, encode the "old" way (the way 1.3.2 or older 8476 // did it), otherwise encode params recursively. 8477 for ( prefix in a ) { 8478 buildParams( prefix, a[ prefix ], traditional, add ); 8479 } 8480 } 8481 8482 // Return the resulting serialization 8483 return s.join( "&" ).replace( r20, "+" ); 8484}; 8485 8486jQuery.fn.extend({ 8487 serialize: function() { 8488 return jQuery.param( this.serializeArray() ); 8489 }, 8490 serializeArray: function() { 8491 return this.map(function() { 8492 // Can add propHook for "elements" to filter or add form elements 8493 var elements = jQuery.prop( this, "elements" ); 8494 return elements ? jQuery.makeArray( elements ) : this; 8495 }) 8496 .filter(function() { 8497 var type = this.type; 8498 8499 // Use .is( ":disabled" ) so that fieldset[disabled] works 8500 return this.name && !jQuery( this ).is( ":disabled" ) && 8501 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 8502 ( this.checked || !rcheckableType.test( type ) ); 8503 }) 8504 .map(function( i, elem ) { 8505 var val = jQuery( this ).val(); 8506 8507 return val == null ? 8508 null : 8509 jQuery.isArray( val ) ? 8510 jQuery.map( val, function( val ) { 8511 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8512 }) : 8513 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8514 }).get(); 8515 } 8516}); 8517 8518 8519jQuery.ajaxSettings.xhr = function() { 8520 try { 8521 return new XMLHttpRequest(); 8522 } catch( e ) {} 8523}; 8524 8525var xhrId = 0, 8526 xhrCallbacks = {}, 8527 xhrSuccessStatus = { 8528 // file protocol always yields status code 0, assume 200 8529 0: 200, 8530 // Support: IE9 8531 // #1450: sometimes IE returns 1223 when it should be 204 8532 1223: 204 8533 }, 8534 xhrSupported = jQuery.ajaxSettings.xhr(); 8535 8536// Support: IE9 8537// Open requests must be manually aborted on unload (#5280) 8538// See https://support.microsoft.com/kb/2856746 for more info 8539if ( window.attachEvent ) { 8540 window.attachEvent( "onunload", function() {
8541 for ( var key in xhrCallbacks ) { 8542 xhrCallbacks[ key ](); 8543 } 8544 }); 8545} 8546 8547support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 8548support.ajax = xhrSupported = !!xhrSupported; 8549 8550jQuery.ajaxTransport(function( options ) { 8551 var callback; 8552 8553 // Cross domain only allowed if supported through XMLHttpRequest 8554 if ( support.cors || xhrSupported && !options.crossDomain ) { 8555 return { 8556 send: function( headers, complete ) { 8557 var i, 8558 xhr = options.xhr(), 8559 id = ++xhrId; 8560 8561 xhr.open( options.type, options.url, options.async, options.username, options.password ); 8562 8563 // Apply custom fields if provided 8564 if ( options.xhrFields ) { 8565 for ( i in options.xhrFields ) { 8566 xhr[ i ] = options.xhrFields[ i ]; 8567 } 8568 } 8569 8570 // Override mime type if needed 8571 if ( options.mimeType && xhr.overrideMimeType ) { 8572 xhr.overrideMimeType( options.mimeType ); 8573 } 8574 8575 // X-Requested-With header 8576 // For cross-domain requests, seeing as conditions for a preflight are 8577 // akin to a jigsaw puzzle, we simply never set it to be sure. 8578 // (it can always be set on a per-request basis or even using ajaxSetup)
8579 // For same-domain requests, won't change header if already provided. 8580 if ( !options.crossDomain && !headers["X-Requested-With"] ) { 8581 headers["X-Requested-With"] = "XMLHttpRequest"; 8582 } 8583 8584 // Set headers 8585 for ( i in headers ) { 8586 xhr.setRequestHeader( i, headers[ i ] ); 8587 } 8588 8589 // Callback 8590 callback = function( type ) { 8591 return function() { 8592 if ( callback ) { 8593 delete xhrCallbacks[ id ]; 8594 callback = xhr.onload = xhr.onerror = null; 8595 8596 if ( type === "abort" ) { 8597 xhr.abort(); 8598 } else if ( type === "error" ) { 8599 complete( 8600 // file: protocol always yields status 0; see #8605, #14207 8601 xhr.status, 8602 xhr.statusText 8603 ); 8604 } else { 8605 complete( 8606 xhrSuccessStatus[ xhr.status ] || xhr.status, 8607 xhr.statusText, 8608 // Support: IE9 8609 // Accessing binary-data responseText throws an exception 8610 // (#11426) 8611 typeof xhr.responseText === "string" ? { 8612 text: xhr.responseText 8613 } : undefined, 8614 xhr.getAllResponseHeaders() 8615 ); 8616 } 8617 } 8618 }; 8619 }; 8620 8621 // Listen to events 8622 xhr.onload = callback(); 8623 xhr.onerror = callback("error"); 8624 8625 // Create the abort callback 8626 callback = xhrCallbacks[ id ] = callback("abort"); 8627 8628 try { 8629 // Do send the request (this may raise an exception) 8630 xhr.send( options.hasContent && options.data || null ); 8631 } catch ( e ) { 8632 // #14683: Only rethrow if this hasn't been notified as an error yet 8633 if ( callback ) { 8634 throw e; 8635 } 8636 } 8637 }, 8638 8639 abort: function() { 8640 if ( callback ) { 8641 callback(); 8642 } 8643 } 8644 }; 8645 } 8646}); 8647 8648 8649 8650 8651// Install script dataType 8652jQuery.ajaxSetup({ 8653 accepts: { 8654 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" 8655 }, 8656 contents: { 8657 script: /(?:java|ecma)script/ 8658 }, 8659 converters: { 8660 "text script": function( text ) { 8661 jQuery.globalEval( text ); 8662 return text; 8663 } 8664 } 8665}); 8666 8667// Handle cache's special case and crossDomain 8668jQuery.ajaxPrefilter( "script", function( s ) { 8669 if ( s.cache === undefined ) { 8670 s.cache = false; 8671 } 8672 if ( s.crossDomain ) { 8673 s.type = "GET"; 8674 } 8675}); 8676 8677// Bind script tag hack transport 8678jQuery.ajaxTransport( "script", function( s ) { 8679 // This transport only deals with cross domain requests 8680 if ( s.crossDomain ) { 8681 var script, callback; 8682 return { 8683 send: function( _, complete ) { 8684 script = jQuery("<script>").prop({ 8685 async: true, 8686 charset: s.scriptCharset, 8687 src: s.url 8688 }).on( 8689 "load error", 8690 callback = function( evt ) { 8691 script.remove(); 8692 callback = null; 8693 if ( evt ) { 8694 complete( evt.type === "error" ? 404 : 200, evt.type ); 8695 } 8696 } 8697 ); 8698 document.head.appendChild( script[ 0 ] ); 8699 }, 8700 abort: function() { 8701 if ( callback ) { 8702 callback(); 8703 } 8704 } 8705 }; 8706 } 8707}); 8708 8709 8710 8711 8712var oldCallbacks = [], 8713 rjsonp = /(=)\?(?=&|$)|\?\?/; 8714 8715// Default jsonp settings 8716jQuery.ajaxSetup({ 8717 jsonp: "callback", 8718 jsonpCallback: function() { 8719 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 8720 this[ callback ] = true; 8721 return callback; 8722 } 8723}); 8724 8725// Detect, normalize options and install callbacks for jsonp requests 8726jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 8727 8728 var callbackName, overwritten, responseContainer, 8729 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 8730 "url" : 8731 typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" 8732 ); 8733 8734 // Handle iff the expected data type is "jsonp" or we have a parameter to set 8735 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 8736 8737 // Get callback name, remembering preexisting value associated with it 8738 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? 8739 s.jsonpCallback() : 8740 s.jsonpCallback; 8741 8742 // Insert callback into url or form data 8743 if ( jsonProp ) { 8744 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 8745 } else if ( s.jsonp !== false ) { 8746 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 8747 } 8748 8749 // Use data converter to retrieve json after script execution 8750 s.converters["script json"] = function() { 8751 if ( !responseContainer ) { 8752 jQuery.error( callbackName + " was not called" ); 8753 } 8754 return responseContainer[ 0 ]; 8755 }; 8756 8757 // force json dataType 8758 s.dataTypes[ 0 ] = "json"; 8759 8760 // Install callback 8761 overwritten = window[ callbackName ]; 8762 window[ callbackName ] = function() { 8763 responseContainer = arguments; 8764 }; 8765 8766 // Clean-up function (fires after converters) 8767 jqXHR.always(function() { 8768 // Restore preexisting value 8769 window[ callbackName ] = overwritten; 8770 8771 // Save back as free 8772 if ( s[ callbackName ] ) { 8773 // make sure that re-using the options doesn't screw things around 8774 s.jsonpCallback = originalSettings.jsonpCallback; 8775 8776 // save the callback name for future use 8777 oldCallbacks.push( callbackName ); 8778 } 8779 8780 // Call if it was a function and we have a response 8781 if ( responseContainer && jQuery.isFunction( overwritten ) ) { 8782 overwritten( responseContainer[ 0 ] ); 8783 } 8784 8785 responseContainer = overwritten = undefined; 8786 }); 8787 8788 // Delegate to script 8789 return "script"; 8790 } 8791}); 8792 8793 8794 8795 8796// data: string of html 8797// context (optional): If specified, the fragment will be created in this context, defaults to document 8798// keepScripts (optional): If true, will include scripts passed in the html string 8799jQuery.parseHTML = function( data, context, keepScripts ) { 8800 if ( !data || typeof data !== "string" ) { 8801 return null; 8802 } 8803 if ( typeof context === "boolean" ) { 8804 keepScripts = context; 8805 context = false;
8806 } 8807 context = context || document; 8808 8809 var parsed = rsingleTag.exec( data ), 8810 scripts = !keepScripts && []; 8811 8812 // Single tag 8813 if ( parsed ) { 8814 return [ context.createElement( parsed[1] ) ]; 8815 } 8816 8817 parsed = jQuery.buildFragment( [ data ], context, scripts ); 8818 8819 if ( scripts && scripts.length ) { 8820 jQuery( scripts ).remove(); 8821 } 8822 8823 return jQuery.merge( [], parsed.childNodes ); 8824}; 8825 8826 8827// Keep a copy of the old load method 8828var _load = jQuery.fn.load; 8829 8830/** 8831 * Load a url into a page 8832 */ 8833jQuery.fn.load = function( url, params, callback ) { 8834 if ( typeof url !== "string" && _load ) { 8835 return _load.apply( this, arguments ); 8836 } 8837 8838 var selector, type, response, 8839 self = this, 8840 off = url.indexOf(" "); 8841 8842 if ( off >= 0 ) { 8843 selector = jQuery.trim( url.slice( off ) ); 8844 url = url.slice( 0, off ); 8845 } 8846 8847 // If it's a function 8848 if ( jQuery.isFunction( params ) ) { 8849 8850 // We assume that it's the callback 8851 callback = params; 8852 params = undefined; 8853 8854 // Otherwise, build a param string 8855 } else if ( params && typeof params === "object" ) { 8856 type = "POST"; 8857 } 8858 8859 // If we have elements to modify, make the request 8860 if ( self.length > 0 ) { 8861 jQuery.ajax({ 8862 url: url, 8863 8864 // if "type" variable is undefined, then "GET" method will be used 8865 type: type, 8866 dataType: "html", 8867 data: params 8868 }).done(function( responseText ) { 8869 8870 // Save response for use in complete callback 8871 response = arguments; 8872 8873 self.html( selector ? 8874 8875 // If a selector was specified, locate the right elements in a dummy div 8876 // Exclude scripts to avoid IE 'Permission Denied' errors 8877 jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : 8878 8879 // Otherwise use the full result 8880 responseText ); 8881 8882 }).complete( callback && function( jqXHR, status ) { 8883 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); 8884 }); 8885 } 8886 8887 return this; 8888}; 8889 8890 8891 8892 8893// Attach a bunch of functions for handling common AJAX events 8894jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { 8895 jQuery.fn[ type ] = function( fn ) { 8896 return this.on( type, fn ); 8897 }; 8898}); 8899 8900 8901 8902 8903jQuery.expr.filters.animated = function( elem ) { 8904 return jQuery.grep(jQuery.timers, function( fn ) { 8905 return elem === fn.elem; 8906 }).length; 8907}; 8908 8909 8910 8911 8912var docElem = window.document.documentElement; 8913 8914/** 8915 * Gets a window from an element 8916 */ 8917function getWindow( elem ) { 8918 return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; 8919} 8920 8921jQuery.offset = { 8922 setOffset: function( elem, options, i ) { 8923 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 8924 position = jQuery.css( elem, "position" ), 8925 curElem = jQuery( elem ), 8926 props = {}; 8927 8928 // Set position first, in-case top/left are set even on static elem 8929 if ( position === "static" ) { 8930 elem.style.position = "relative"; 8931 } 8932 8933 curOffset = curElem.offset(); 8934 curCSSTop = jQuery.css( elem, "top" ); 8935 curCSSLeft = jQuery.css( elem, "left" ); 8936 calculatePosition = ( position === "absolute" || position === "fixed" ) && 8937 ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; 8938 8939 // Need to be able to calculate position if either 8940 // top or left is auto and position is either absolute or fixed 8941 if ( calculatePosition ) { 8942 curPosition = curElem.position(); 8943 curTop = curPosition.top; 8944 curLeft = curPosition.left; 8945 8946 } else { 8947 curTop = parseFloat( curCSSTop ) || 0; 8948 curLeft = parseFloat( curCSSLeft ) || 0; 8949 } 8950 8951 if ( jQuery.isFunction( options ) ) { 8952 options = options.call( elem, i, curOffset ); 8953 } 8954 8955 if ( options.top != null ) { 8956 props.top = ( options.top - curOffset.top ) + curTop; 8957 } 8958 if ( options.left != null ) { 8959 props.left = ( options.left - curOffset.left ) + curLeft; 8960 } 8961 8962 if ( "using" in options ) { 8963 options.using.call( elem, props ); 8964 8965 } else { 8966 curElem.css( props ); 8967 } 8968 } 8969}; 8970 8971jQuery.fn.extend({ 8972 offset: function( options ) { 8973 if ( arguments.length ) { 8974 return options === undefined ? 8975 this : 8976 this.each(function( i ) { 8977 jQuery.offset.setOffset( this, options, i ); 8978 }); 8979 } 8980 8981 var docElem, win, 8982 elem = this[ 0 ], 8983 box = { top: 0, left: 0 }, 8984 doc = elem && elem.ownerDocument; 8985 8986 if ( !doc ) { 8987 return; 8988 } 8989 8990 docElem = doc.documentElement; 8991 8992 // Make sure it's not a disconnected DOM node 8993 if ( !jQuery.contains( docElem, elem ) ) { 8994 return box; 8995 } 8996
8997 // Support: BlackBerry 5, iOS 3 (original iPhone) 8998 // If we don't have gBCR, just use 0,0 rather than error 8999 if ( typeof elem.getBoundingClientRect !== strundefined ) { 9000 box = elem.getBoundingClientRect(); 9001 } 9002 win = getWindow( doc ); 9003 return { 9004 top: box.top + win.pageYOffset - docElem.clientTop, 9005 left: box.left + win.pageXOffset - docElem.clientLeft 9006 }; 9007 }, 9008 9009 position: function() { 9010 if ( !this[ 0 ] ) { 9011 return; 9012 } 9013 9014 var offsetParent, offset, 9015 elem = this[ 0 ], 9016 parentOffset = { top: 0, left: 0 }; 9017 9018 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent 9019 if ( jQuery.css( elem, "position" ) === "fixed" ) { 9020 // Assume getBoundingClientRect is there when computed position is fixed 9021 offset = elem.getBoundingClientRect(); 9022 9023 } else { 9024 // Get *real* offsetParent 9025 offsetParent = this.offsetParent(); 9026 9027 // Get correct offsets 9028 offset = this.offset(); 9029 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { 9030 parentOffset = offsetParent.offset(); 9031 } 9032 9033 // Add offsetParent borders 9034 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); 9035 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); 9036 } 9037 9038 // Subtract parent offsets and element margins 9039 return { 9040 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 9041 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 9042 }; 9043 }, 9044 9045 offsetParent: function() { 9046 return this.map(function() { 9047 var offsetParent = this.offsetParent || docElem; 9048 9049 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { 9050 offsetParent = offsetParent.offsetParent; 9051 } 9052 9053 return offsetParent || docElem; 9054 }); 9055 } 9056}); 9057 9058// Create scrollLeft and scrollTop methods 9059jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 9060 var top = "pageYOffset" === prop; 9061 9062 jQuery.fn[ method ] = function( val ) { 9063 return access( this, function( elem, method, val ) { 9064 var win = getWindow( elem ); 9065 9066 if ( val === undefined ) { 9067 return win ? win[ prop ] : elem[ method ]; 9068 } 9069 9070 if ( win ) { 9071 win.scrollTo( 9072 !top ? val : window.pageXOffset, 9073 top ? val : window.pageYOffset 9074 ); 9075 9076 } else { 9077 elem[ method ] = val; 9078 } 9079 }, method, val, arguments.length, null ); 9080 }; 9081}); 9082 9083// Support: Safari<7+, Chrome<37+ 9084// Add the top/left cssHooks using jQuery.fn.position 9085// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 9086// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 9087// getComputedStyle returns percent when specified for top/left/bottom/right; 9088// rather than make the css module depend on the offset module, just check for it here 9089jQuery.each( [ "top", "left" ], function( i, prop ) { 9090 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 9091 function( elem, computed ) { 9092 if ( computed ) { 9093 computed = curCSS( elem, prop ); 9094 // If curCSS returns percentage, fallback to offset 9095 return rnumnonpx.test( computed ) ? 9096 jQuery( elem ).position()[ prop ] + "px" : 9097 computed; 9098 } 9099 } 9100 ); 9101}); 9102 9103 9104// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 9105jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 9106 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { 9107 // Margin is only for outerHeight, outerWidth 9108 jQuery.fn[ funcName ] = function( margin, value ) { 9109 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 9110 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 9111 9112 return access( this, function( elem, type, value ) { 9113 var doc; 9114 9115 if ( jQuery.isWindow( elem ) ) { 9116 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there 9117 // isn't a whole lot we can do. See pull request at this URL for discussion: 9118 // https://github.com/jquery/jquery/pull/764 9119 return elem.document.documentElement[ "client" + name ]; 9120 } 9121 9122 // Get document width or height 9123 if ( elem.nodeType === 9 ) { 9124 doc = elem.documentElement; 9125 9126 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 9127 // whichever is greatest 9128 return Math.max( 9129 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 9130 elem.body[ "offset" + name ], doc[ "offset" + name ], 9131 doc[ "client" + name ] 9132 ); 9133 } 9134 9135 return value === undefined ? 9136 // Get width or height on the element, requesting but not forcing parseFloat 9137 jQuery.css( elem, type, extra ) : 9138 9139 // Set width or height on the element 9140 jQuery.style( elem, type, value, extra ); 9141 }, type, chainable ? margin : undefined, chainable, null ); 9142 }; 9143 }); 9144}); 9145 9146 9147// The number of elements contained in the matched element set 9148jQuery.fn.size = function() { 9149 return this.length; 9150}; 9151 9152jQuery.fn.andSelf = jQuery.fn.addBack; 9153 9154 9155 9156 9157// Register as a named AMD module, since jQuery can be concatenated with other 9158// files that may use define, but not via a proper concatenation script that 9159// understands anonymous AMD modules. A named AMD is safest and most robust 9160// way to register. Lowercase jquery is used because AMD module names are 9161// derived from file names, and jQuery is normally delivered in a lowercase 9162// file name. Do this after creating the global so that if an AMD module wants 9163// to call noConflict to hide this version of jQuery, it will work. 9164 9165// Note that for maximum portability, libraries that are not jQuery should 9166// declare themselves as anonymous modules, and avoid setting a global if an 9167// AMD loader is present. jQuery is a special case. For more information, see
9168// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 9169 9170if ( typeof define === "function" && define.amd ) { 9171 define( "jquery", [], function() { 9172 return jQuery; 9173 }); 9174} 9175 9176 9177 9178 9179var 9180 // Map over jQuery in case of overwrite 9181 _jQuery = window.jQuery, 9182 9183 // Map over the $ in case of overwrite 9184 _$ = window.$; 9185 9186jQuery.noConflict = function( deep ) { 9187 if ( window.$ === jQuery ) { 9188 window.$ = _$; 9189 } 9190 9191 if ( deep && window.jQuery === jQuery ) { 9192 window.jQuery = _jQuery; 9193 } 9194 9195 return jQuery; 9196}; 9197 9198// Expose jQuery and $ identifiers, even in AMD 9199// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 9200// and CommonJS for browser emulators (#13566) 9201if ( typeof noGlobal === strundefined ) { 9202 window.jQuery = window.$ = jQuery; 9203} 9204 9205 9206 9207 9208return jQuery; 9209 9210})); 9211/* jshint node: true */ 9212 9213/** 9214 * Unobtrusive scripting adapter for jQuery 9215 * https://github.com/rails/jquery-ujs 9216 * 9217 * Requires jQuery 1.8.0 or later. 9218 * 9219 * Released under the MIT license 9220 * 9221 */ 9222 9223(function() { 9224 'use strict'; 9225 9226 var jqueryUjsInit = function($, undefined) { 9227 9228 // Cut down on the number of issues from people inadvertently including jquery_ujs twice 9229 // by detecting and raising an error when it happens. 9230 if ( $.rails !== undefined ) { 9231 $.error('jquery-ujs has already been loaded!'); 9232 } 9233 9234 // Shorthand to make it a little easier to call public rails functions from within rails.js 9235 var rails; 9236 var $document = $(document); 9237 9238 $.rails = rails = { 9239 // Link elements bound by jquery-ujs 9240 linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]', 9241 9242 // Button elements bound by jquery-ujs 9243 buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)', 9244 9245 // Select elements bound by jquery-ujs 9246 inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', 9247 9248 // Form elements bound by jquery-ujs 9249 formSubmitSelector: 'form:not([data-turbo=true])', 9250 9251 // Form input elements bound by jquery-ujs 9252 formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])', 9253 9254 // Form input elements disabled during form submission 9255 disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled', 9256 9257 // Form input elements re-enabled after form submission 9258 enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled', 9259 9260 // Form required input elements 9261 requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])', 9262 9263 // Form file input elements 9264 fileInputSelector: 'input[name][type=file]:not([disabled])', 9265 9266 // Link onClick disable selector with possible reenable after remote submission 9267 linkDisableSelector: 'a[data-disable-with], a[data-disable]', 9268 9269 // Button onClick disable selector with possible reenable after remote submission 9270 buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]', 9271 9272 // Up-to-date Cross-Site Request Forgery token 9273 csrfToken: function() { 9274 return $('meta[name=csrf-token]').attr('content'); 9275 }, 9276 9277 // URL param that must contain the CSRF token 9278 csrfParam: function() { 9279 return $('meta[name=csrf-param]').attr('content'); 9280 }, 9281 9282 // Make sure that every Ajax request sends the CSRF token 9283 CSRFProtection: function(xhr) { 9284 var token = rails.csrfToken(); 9285 if (token) xhr.setRequestHeader('X-CSRF-Token', token); 9286 }, 9287 9288 // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones) 9289 refreshCSRFTokens: function(){ 9290 $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken()); 9291 }, 9292 9293 // Triggers an event on an element and returns false if the event result is false 9294 fire: function(obj, name, data) { 9295 var event = $.Event(name); 9296 obj.trigger(event, data); 9297 return event.result !== false; 9298 }, 9299 9300 // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm 9301 confirm: function(message) { 9302 return confirm(message); 9303 }, 9304 9305 // Default ajax function, may be overridden with custom function in $.rails.ajax 9306 ajax: function(options) { 9307 return $.ajax(options); 9308 }, 9309 9310 // Default way to get an element's href. May be overridden at $.rails.href. 9311 href: function(element) { 9312 return element[0].href; 9313 }, 9314 9315 // Checks "data-remote" if true to handle the request through a XHR request. 9316 isRemote: function(element) { 9317 return element.data('remote') !== undefined && element.data('remote') !== false; 9318 }, 9319 9320 // Submits "remote" forms and links with ajax 9321 handleRemote: function(element) { 9322 var method, url, data, withCredentials, dataType, options; 9323 9324 if (rails.fire(element, 'ajax:before')) { 9325 withCredentials = element.data('with-credentials') || null; 9326 dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); 9327 9328 if (element.is('form')) { 9329 method = element.data('ujs:submit-button-formmethod') || element.attr('method'); 9330 url = element.data('ujs:submit-button-formaction') || element.attr('action'); 9331 data = $(element[0]).serializeArray(); 9332 // memoized value from clicked submit button 9333 var button = element.data('ujs:submit-button'); 9334 if (button) { 9335 data.push(button); 9336 element.data('ujs:submit-button', null); 9337 } 9338 element.data('ujs:submit-button-formmethod', null); 9339 element.data('ujs:submit-button-formaction', null); 9340 } else if (element.is(rails.inputChangeSelector)) { 9341 method = element.data('method'); 9342 url = element.data('url'); 9343 data = element.serialize(); 9344 if (element.data('params')) data = data + '&' + element.data('params'); 9345 } else if (element.is(rails.buttonClickSelector)) { 9346 method = element.data('method') || 'get'; 9347 url = element.data('url'); 9348 data = element.serialize(); 9349 if (element.data('params')) data = data + '&' + element.data('params'); 9350 } else { 9351 method = element.data('method'); 9352 url = rails.href(element); 9353 data = element.data('params') || null; 9354 } 9355 9356 options = { 9357 type: method || 'GET', data: data, dataType: dataType, 9358 // stopping the "ajax:beforeSend" event will cancel the ajax request 9359 beforeSend: function(xhr, settings) { 9360 if (settings.dataType === undefined) { 9361 xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); 9362 } 9363 if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
9364 element.trigger('ajax:send', xhr); 9365 } else { 9366 return false; 9367 } 9368 }, 9369 success: function(data, status, xhr) { 9370 element.trigger('ajax:success', [data, status, xhr]); 9371 }, 9372 complete: function(xhr, status) { 9373 element.trigger('ajax:complete', [xhr, status]); 9374 }, 9375 error: function(xhr, status, error) { 9376 element.trigger('ajax:error', [xhr, status, error]); 9377 }, 9378 crossDomain: rails.isCrossDomain(url) 9379 }; 9380 9381 // There is no withCredentials for IE6-8 when 9382 // "Enable native XMLHTTP support" is disabled 9383 if (withCredentials) { 9384 options.xhrFields = { 9385 withCredentials: withCredentials 9386 }; 9387 } 9388 9389 // Only pass url to `ajax` options if not blank 9390 if (url) { options.url = url; } 9391 9392 return rails.ajax(options); 9393 } else { 9394 return false; 9395 } 9396 }, 9397 9398 // Determines if the request is a cross domain request. 9399 isCrossDomain: function(url) { 9400 var originAnchor = document.createElement('a'); 9401 originAnchor.href = location.href; 9402 var urlAnchor = document.createElement('a'); 9403 9404 try { 9405 urlAnchor.href = url; 9406 // This is a workaround to a IE bug. 9407 urlAnchor.href = urlAnchor.href; 9408 9409 // If URL protocol is false or is a string containing a single colon 9410 // *and* host are false, assume it is not a cross-domain request 9411 // (should only be the case for IE7 and IE compatibility mode). 9412 // Otherwise, evaluate protocol and host of the URL against the origin 9413 // protocol and host. 9414 return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || 9415 (originAnchor.protocol + '//' + originAnchor.host === 9416 urlAnchor.protocol + '//' + urlAnchor.host)); 9417 } catch (e) { 9418 // If there is an error parsing the URL, assume it is crossDomain. 9419 return true; 9420 } 9421 }, 9422 9423 // Handles "data-method" on links such as: 9424 // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a> 9425 handleMethod: function(link) { 9426 var href = rails.href(link), 9427 method = link.data('method'), 9428 target = link.attr('target'), 9429 csrfToken = rails.csrfToken(), 9430 csrfParam = rails.csrfParam(), 9431 form = $('<form method="post" action="' + href + '"></form>'), 9432 metadataInput = '<input name="_method" value="' + method + '" type="hidden" />'; 9433 9434 if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) { 9435 metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />'; 9436 } 9437 9438 if (target) { form.attr('target', target); } 9439 9440 form.hide().append(metadataInput).appendTo('body'); 9441 form.submit(); 9442 }, 9443 9444 // Helper function that returns form elements that match the specified CSS selector 9445 // If form is actually a "form" element this will return associated elements outside the from that have 9446 // the html form attribute set 9447 formElements: function(form, selector) { 9448 return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector); 9449 }, 9450 9451 /* Disables form elements: 9452 - Caches element value in 'ujs:enable-with' data store 9453 - Replaces element text with value of 'data-disable-with' attribute 9454 - Sets disabled property to true 9455 */ 9456 disableFormElements: function(form) { 9457 rails.formElements(form, rails.disableSelector).each(function() { 9458 rails.disableFormElement($(this)); 9459 }); 9460 }, 9461 9462 disableFormElement: function(element) { 9463 var method, replacement; 9464 9465 method = element.is('button') ? 'html' : 'val'; 9466 replacement = element.data('disable-with'); 9467 9468 if (replacement !== undefined) { 9469 element.data('ujs:enable-with', element[method]()); 9470 element[method](replacement); 9471 } 9472 9473 element.prop('disabled', true); 9474 element.data('ujs:disabled', true); 9475 }, 9476 9477 /* Re-enables disabled form elements: 9478 - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) 9479 - Sets disabled property to false 9480 */ 9481 enableFormElements: function(form) { 9482 rails.formElements(form, rails.enableSelector).each(function() { 9483 rails.enableFormElement($(this)); 9484 }); 9485 }, 9486 9487 enableFormElement: function(element) { 9488 var method = element.is('button') ? 'html' : 'val'; 9489 if (element.data('ujs:enable-with') !== undefined) { 9490 element[method](element.data('ujs:enable-with')); 9491 element.removeData('ujs:enable-with'); // clean up cache 9492 } 9493 element.prop('disabled', false); 9494 element.removeData('ujs:disabled'); 9495 }, 9496 9497 /* For 'data-confirm' attribute: 9498 - Fires `confirm` event 9499 - Shows the confirmation dialog 9500 - Fires the `confirm:complete` event 9501 9502 Returns `true` if no function stops the chain and user chose yes; `false` otherwise. 9503 Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog. 9504 Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
9505 return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog. 9506 */ 9507 allowAction: function(element) { 9508 var message = element.data('confirm'), 9509 answer = false, callback; 9510 if (!message) { return true; } 9511 9512 if (rails.fire(element, 'confirm')) { 9513 try { 9514 answer = rails.confirm(message); 9515 } catch (e) { 9516 (console.error || console.log).call(console, e.stack || e); 9517 } 9518 callback = rails.fire(element, 'confirm:complete', [answer]); 9519 } 9520 return answer && callback; 9521 }, 9522 9523 // Helper function which checks for blank inputs in a form that match the specified CSS selector 9524 blankInputs: function(form, specifiedSelector, nonBlank) { 9525 var foundInputs = $(), 9526 input, 9527 valueToCheck, 9528 radiosForNameWithNoneSelected, 9529 radioName, 9530 selector = specifiedSelector || 'input,textarea', 9531 requiredInputs = form.find(selector), 9532 checkedRadioButtonNames = {}; 9533 9534 requiredInputs.each(function() { 9535 input = $(this); 9536 if (input.is('input[type=radio]')) { 9537 9538 // Don't count unchecked required radio as blank if other radio with same name is checked, 9539 // regardless of whether same-name radio input has required attribute or not. The spec 9540 // states https://www.w3.org/TR/html5/forms.html#the-required-attribute 9541 radioName = input.attr('name'); 9542 9543 // Skip if we've already seen the radio with this name. 9544 if (!checkedRadioButtonNames[radioName]) { 9545 9546 // If none checked 9547 if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) { 9548 radiosForNameWithNoneSelected = form.find( 9549 'input[type=radio][name="' + radioName + '"]'); 9550 foundInputs = foundInputs.add(radiosForNameWithNoneSelected); 9551 } 9552 9553 // We only need to check each name once. 9554 checkedRadioButtonNames[radioName] = radioName; 9555 } 9556 } else { 9557 valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val(); 9558 if (valueToCheck === nonBlank) { 9559 foundInputs = foundInputs.add(input); 9560 } 9561 } 9562 }); 9563 return foundInputs.length ? foundInputs : false; 9564 }, 9565 9566 // Helper function which checks for non-blank inputs in a form that match the specified CSS selector 9567 nonBlankInputs: function(form, specifiedSelector) { 9568 return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank 9569 }, 9570 9571 // Helper function, needed to provide consistent behavior in IE 9572 stopEverything: function(e) { 9573 $(e.target).trigger('ujs:everythingStopped'); 9574 e.stopImmediatePropagation(); 9575 return false; 9576 }, 9577 9578 // Replace element's html with the 'data-disable-with' after storing original html 9579 // and prevent clicking on it 9580 disableElement: function(element) { 9581 var replacement = element.data('disable-with'); 9582 9583 if (replacement !== undefined) { 9584 element.data('ujs:enable-with', element.html()); // store enabled state 9585 element.html(replacement); 9586 } 9587 9588 element.on('click.railsDisable', function(e) { // prevent further clicking 9589 return rails.stopEverything(e); 9590 }); 9591 element.data('ujs:disabled', true); 9592 }, 9593 9594 // Restore element to its original state which was disabled by 'disableElement' above 9595 enableElement: function(element) { 9596 if (element.data('ujs:enable-with') !== undefined) { 9597 element.html(element.data('ujs:enable-with')); // set to old enabled state 9598 element.removeData('ujs:enable-with'); // clean up cache 9599 } 9600 element.off('click.railsDisable'); // enable element 9601 element.removeData('ujs:disabled'); 9602 } 9603 }; 9604 9605 if (rails.fire($document, 'rails:attachBindings')) { 9606 9607 $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }}); 9608 9609 // This event works the same as the load event, except that it fires every 9610 // time the page is loaded. 9611 // 9612 // See https://github.com/rails/jquery-ujs/issues/357 9613 // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching 9614 $(window).on('pageshow.rails', function () { 9615 $($.rails.enableSelector).each(function () { 9616 var element = $(this); 9617 9618 if (element.data('ujs:disabled')) { 9619 $.rails.enableFormElement(element); 9620 } 9621 }); 9622 9623 $($.rails.linkDisableSelector).each(function () { 9624 var element = $(this); 9625 9626 if (element.data('ujs:disabled')) { 9627 $.rails.enableElement(element); 9628 } 9629 }); 9630 }); 9631 9632 $document.on('ajax:complete', rails.linkDisableSelector, function() { 9633 rails.enableElement($(this)); 9634 }); 9635 9636 $document.on('ajax:complete', rails.buttonDisableSelector, function() { 9637 rails.enableFormElement($(this)); 9638 }); 9639 9640 $document.on('click.rails', rails.linkClickSelector, function(e) { 9641 var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey; 9642 if (!rails.allowAction(link)) return rails.stopEverything(e); 9643 9644 if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link); 9645 9646 if (rails.isRemote(link)) { 9647 if (metaClick && (!method || method === 'GET') && !data) { return true; } 9648 9649 var handleRemote = rails.handleRemote(link); 9650 // Response from rails.handleRemote() will either be false or a deferred object promise. 9651 if (handleRemote === false) { 9652 rails.enableElement(link); 9653 } else { 9654 handleRemote.fail( function() { rails.enableElement(link); } ); 9655 } 9656 return false;
9657 9658 } else if (method) { 9659 rails.handleMethod(link); 9660 return false; 9661 } 9662 }); 9663 9664 $document.on('click.rails', rails.buttonClickSelector, function(e) { 9665 var button = $(this); 9666 9667 if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e); 9668 9669 if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button); 9670 9671 var handleRemote = rails.handleRemote(button); 9672 // Response from rails.handleRemote() will either be false or a deferred object promise. 9673 if (handleRemote === false) { 9674 rails.enableFormElement(button); 9675 } else { 9676 handleRemote.fail( function() { rails.enableFormElement(button); } ); 9677 } 9678 return false; 9679 }); 9680 9681 $document.on('change.rails', rails.inputChangeSelector, function(e) { 9682 var link = $(this); 9683 if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e); 9684 9685 rails.handleRemote(link); 9686 return false; 9687 }); 9688 9689 $document.on('submit.rails', rails.formSubmitSelector, function(e) { 9690 var form = $(this), 9691 remote = rails.isRemote(form), 9692 blankRequiredInputs, 9693 nonBlankFileInputs; 9694 9695 if (!rails.allowAction(form)) return rails.stopEverything(e); 9696 9697 // Skip other logic when required values are missing or file upload is present 9698 if (form.attr('novalidate') === undefined) { 9699 if (form.data('ujs:formnovalidate-button') === undefined) { 9700 blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false); 9701 if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { 9702 return rails.stopEverything(e); 9703 } 9704 } else { 9705 // Clear the formnovalidate in case the next button click is not on a formnovalidate button 9706 // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain 9707 form.data('ujs:formnovalidate-button', undefined); 9708 } 9709 } 9710 9711 if (remote) { 9712 nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); 9713 if (nonBlankFileInputs) { 9714 // Slight timeout so that the submit button gets properly serialized 9715 // (make it easy for event handler to serialize form without disabled values) 9716 setTimeout(function(){ rails.disableFormElements(form); }, 13); 9717 var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); 9718 9719 // Re-enable form elements if event bindings return false (canceling normal form submission) 9720 if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); } 9721 9722 return aborted; 9723 } 9724 9725 rails.handleRemote(form); 9726 return false; 9727 9728 } else { 9729 // Slight timeout so that the submit button gets properly serialized 9730 setTimeout(function(){ rails.disableFormElements(form); }, 13); 9731 } 9732 }); 9733 9734 $document.on('click.rails', rails.formInputClickSelector, function(event) { 9735 var button = $(this); 9736 9737 if (!rails.allowAction(button)) return rails.stopEverything(event); 9738 9739 // Register the pressed submit button 9740 var name = button.attr('name'), 9741 data = name ? {name:name, value:button.val()} : null; 9742 9743 var form = button.closest('form'); 9744 if (form.length === 0) { 9745 form = $('#' + button.attr('form')); 9746 } 9747 form.data('ujs:submit-button', data); 9748 9749 // Save attributes from button 9750 form.data('ujs:formnovalidate-button', button.attr('formnovalidate')); 9751 form.data('ujs:submit-button-formaction', button.attr('formaction')); 9752 form.data('ujs:submit-button-formmethod', button.attr('formmethod')); 9753 }); 9754 9755 $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) { 9756 if (this === event.target) rails.disableFormElements($(this)); 9757 }); 9758 9759 $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) { 9760 if (this === event.target) rails.enableFormElements($(this)); 9761 }); 9762 9763 $(function(){ 9764 rails.refreshCSRFTokens(); 9765 }); 9766 } 9767 9768 }; 9769 9770 if (window.jQuery) { 9771 jqueryUjsInit(jQuery); 9772 } else if (typeof exports === 'object' && typeof module === 'object') { 9773 module.exports = jqueryUjsInit; 9774 } 9775})(); 9776/*! modulejs v2.2.0 - https://larsjung.de/modulejs/ */ 9777!function(n,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exp
9777orts.modulejs=r():n.modulejs=r()}(this,function(){return function(n){function r(t){if(e[t])return e[t].exports;var i=e[t]={exports:{},id:t,loaded:!1};return n[t].call(i.exports,i,i.exports,r),i.loaded=!0,i.exports}var e={};return r.m=n,r.c=e,r.p="",r(0)}([function(n,r,e){"use strict";var t=e(1),i=t.assert,o=t.forOwn,u=t.has,f=t.resolve,s=function n(){var r={},e={},t=function(n,e,t){if(void 0===t){var o=[[],e];e=o[0],t=o[1]}i("string"==typeof n,"id must be string: "+n),i(!u(r,n),"id already defined: "+n),i(Array.isArray(e),"deps must be array: "+n),r[n]={id:n,deps:e,fn:"function"==typeof t?t:function(){return t}}},s=function(n,t){return i("string"==typeof n,"id must be string: "+n),f(r,t||e,n)},c=function(){var n={};return o(r,function(t,i){n[i]={deps:t.deps.slice(),reqs:f(r,null,i),init:u(e,i)}}),o(r,function(e,t){var i=[];o(r,function(r,e){n[e].reqs.indexOf(t)>=0&&i.push(e)}),n[t].reqd=i}),n},a=function(n){var r="\n";return o(c(),function(e,t){var i=n?e.reqd:e.reqs;r+=(e.init?"*":" ")+" "+t+" -> [ "+i.join(", ")+" ]\n"}),r};return{create:n,define:t,log:a,require:s,state:c,_d:r,_i:e}};n.exports=s()},function(n,r){"use strict";var e=function(n,r){if(!n)throw new Error("[modulejs] "+r)},t=function(n,r){Object.keys(n).forEach(function(e){return r(n[e],e)})},i=function(n,r){return(n||{}).hasOwnProperty(r)},o=function(n){var r={};return n.filter(function(n){var e=!r[n];return r[n]=1,e})},u=function n(r,t,u,f){var s=!t;if(!s&&i(t,u))return t[u];var c=r[u];e(c,"id not defined: "+u),f=(f||[]).slice(),f.push(u);var a=[];if(c.deps.forEach(function(i){e(f.indexOf(i)<0,"circular dependencies: "+i+" in "+f);var o=n(r,t,i,f);s?(a=a.concat(o),a.push(i)):a.push(o)}),s)return o(a);var d=c.fn.apply(void 0,a);return t[u]=d,d};n.exports={assert:e,forOwn:t,has:i,resolve:u,uniq:o}}])}); 9778/*! 9779 * JavaScript Cookie v2.0.3 9780 * https://github.com/js-cookie/js-cookie 9781 * 9782 * Copyright 2006, 2015 Klaus Hartl & Fagner Brack 9783 * Released under the MIT license 9784 */ 9785(function (factory) { 9786 if (typeof define === 'function' && define.amd) { 9787 define(factory); 9788 } else if (typeof exports === 'object') { 9789 module.exports = factory(); 9790 } else { 9791 var _OldCookies = window.Cookies; 9792 var api = window.Cookies = factory(); 9793 api.noConflict = function () { 9794 window.Cookies = _OldCookies; 9795 return api; 9796 }; 9797 } 9798}(function () { 9799 function extend () { 9800 var i = 0; 9801 var result = {}; 9802 for (; i < arguments.length; i++) { 9803 var attributes = arguments[ i ]; 9804 for (var key in attributes) { 9805 result[key] = attributes[key]; 9806 } 9807 } 9808 return result; 9809 } 9810 9811 function init (converter) { 9812 function api (key, value, attributes) { 9813 var result; 9814 9815 // Write 9816 9817 if (arguments.length > 1) { 9818 attributes = extend({ 9819 path: '/' 9820 }, api.defaults, attributes); 9821 9822 if (typeof attributes.expires === 'number') { 9823 var expires = new Date(); 9824 expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); 9825 attributes.expires = expires; 9826 } 9827 9828 try { 9829 result = JSON.stringify(value); 9830 if (/^[\{\[]/.test(result)) { 9831 value = result; 9832 } 9833 } catch (e) {} 9834 9835 value = encodeURIComponent(String(value)); 9836 value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 9837 9838 key = encodeURIComponent(String(key)); 9839 key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); 9840 key = key.replace(/[\(\)]/g, escape); 9841 9842 return (document.cookie = [ 9843 key, '=', value, 9844 attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE 9845 attributes.path && '; path=' + attributes.path, 9846 attributes.domain && '; domain=' + attributes.domain, 9847 attributes.secure ? '; secure' : '' 9848 ].join('')); 9849 } 9850 9851 // Read 9852 9853 if (!key) { 9854 result = {}; 9855 } 9856 9857 // To prevent the for loop in the first place assign an empty array 9858 // in case there are no cookies at all. Also prevents odd result when 9859 // calling "get()" 9860 var cookies = document.cookie ? document.cookie.split('; ') : []; 9861 var rdecode = /(%[0-9A-Z]{2})+/g; 9862 var i = 0; 9863 9864 for (; i < cookies.length; i++) { 9865 var parts = cookies[i].split('='); 9866 var name = parts[0].replace(rdecode, decodeURIComponent); 9867 var cookie = parts.slice(1).join('='); 9868 9869 if (cookie.charAt(0) === '"') { 9870 cookie = cookie.slice(1, -1); 9871 } 9872 9873 try { 9874 cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent); 9875 9876 if (this.json) { 9877 try { 9878 cookie = JSON.parse(cookie); 9879 } catch (e) {} 9880 } 9881 9882 if (key === name) { 9883 result = cookie; 9884 break; 9885 } 9886 9887 if (!key) { 9888 result[name] = cookie; 9889 } 9890 } catch (e) {} 9891 } 9892 9893 return result; 9894 } 9895 9896 api.get = api.set = api; 9897 api.getJSON = function () { 9898 return api.apply({ 9899 json: true 9900 }, [].slice.call(arguments)); 9901 }; 9902 api.defaults = {}; 9903 9904 api.remove = function (key, attributes) { 9905 api(key, '', extend(attributes, { 9906 expires: -1 9907 })); 9908 }; 9909 9910 api.withConverter = init; 9911 9912 return api; 9913 } 9914 9915 return init(); 9916})); 9917/* 9918 * jQuery appear plugin 9919 * 9920 * Copyright (c) 2012 Andrey Sidorov 9921 * licensed under MIT license. 9922 * 9923 * https://github.com/morr/jquery.appear/ 9924 * 9925 * Version: 0.3.6 9926 */ 9927(function($) { 9928 var selectors = []; 9929 9930 var check_binded = false;
9931 var check_lock = false; 9932 var defaults = { 9933 interval: 250, 9934 force_process: false 9935 }; 9936 var $window = $(window); 9937 9938 var $prior_appeared = []; 9939 9940 function process() { 9941 check_lock = false; 9942 for (var index = 0, selectorsLength = selectors.length; index < selectorsLength; index++) { 9943 var $appeared = $(selectors[index]).filter(function() { 9944 return $(this).is(':appeared'); 9945 }); 9946 9947 $appeared.trigger('appear', [$appeared]); 9948 9949 if ($prior_appeared[index]) { 9950 var $disappeared = $prior_appeared[index].not($appeared); 9951 $disappeared.trigger('disappear', [$disappeared]); 9952 } 9953 $prior_appeared[index] = $appeared; 9954 } 9955 }; 9956 9957 function add_selector(selector) { 9958 selectors.push(selector); 9959 $prior_appeared.push(); 9960 } 9961 9962 // "appeared" custom filter 9963 $.expr[':']['appeared'] = function(element) { 9964 var $element = $(element); 9965 if (!$element.is(':visible')) { 9966 return false; 9967 } 9968 9969 var window_left = $window.scrollLeft(); 9970 var window_top = $window.scrollTop(); 9971 var offset = $element.offset(); 9972 var left = offset.left; 9973 var top = offset.top; 9974 9975 if (top + $element.height() >= window_top && 9976 top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() && 9977 left + $element.width() >= window_left && 9978 left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) { 9979 return true; 9980 } else { 9981 return false; 9982 } 9983 }; 9984 9985 $.fn.extend({ 9986 // watching for element's appearance in browser viewport 9987 appear: function(options) { 9988 var opts = $.extend({}, defaults, options || {}); 9989 var selector = this.selector || this; 9990 if (!check_binded) { 9991 var on_check = function() { 9992 if (check_lock) { 9993 return; 9994 } 9995 check_lock = true; 9996 9997 setTimeout(process, opts.interval); 9998 }; 9999 10000 $(window).scroll(on_check).resize(on_check); 10001 check_binded = true; 10002 } 10003 10004 if (opts.force_process) { 10005 setTimeout(process, opts.interval); 10006 } 10007 add_selector(selector); 10008 return $(selector); 10009 } 10010 }); 10011 10012 $.extend({ 10013 // force elements's appearance check 10014 force_appear: function() { 10015 if (check_binded) { 10016 process(); 10017 return true; 10018 } 10019 return false; 10020 } 10021 }); 10022})(function() { 10023 if (typeof module !== 'undefined') { 10024 // Node 10025 return require('jquery'); 10026 } else { 10027 return jQuery; 10028 } 10029}()); 10030/*! 10031 Autosize 3.0.5 10032 license: MIT 10033 http://www.jacklmoore.com/autosize 10034*/ 10035(function (global, factory) { 10036 if (typeof define === 'function' && define.amd) { 10037 define(['exports', 'module'], factory); 10038 } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { 10039 factory(exports, module); 10040 } else { 10041 var mod = { 10042 exports: {} 10043 }; 10044 factory(mod.exports, mod); 10045 global.autosize = mod.exports; 10046 } 10047})(this, function (exports, module) { 10048 'use strict'; 10049 10050 function assign(ta) { 10051 var _ref = arguments[1] === undefined ? {} : arguments[1]; 10052 10053 var _ref$setOverflowX = _ref.setOverflowX; 10054 var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX; 10055 var _ref$setOverflowY = _ref.setOverflowY; 10056 var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY; 10057 10058 if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || ta.hasAttribute('data-autosize-on')) return; 10059 10060 var heightOffset = null; 10061 var overflowY = 'hidden'; 10062 10063 function init() { 10064 var style = window.getComputedStyle(ta, null); 10065 10066 if (style.resize === 'vertical') { 10067 ta.style.resize = 'none'; 10068 } else if (style.resize === 'both') { 10069 ta.style.resize = 'horizontal'; 10070 } 10071 10072 if (style.boxSizing === 'content-box') { 10073 heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); 10074 } else { 10075 heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); 10076 } 10077 10078 update(); 10079 } 10080 10081 function changeOverflow(value) { 10082 { 10083 // Chrome/Safari-specific fix: 10084 // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space 10085 // made available by removing the scrollbar. The following forces the necessary text reflow. 10086 var width = ta.style.width; 10087 ta.style.width = '0px'; 10088 // Force reflow: 10089 /* jshint ignore:start */ 10090 ta.offsetWidth; 10091 /* jshint ignore:end */ 10092 ta.style.width = width; 10093 } 10094 10095 overflowY = value; 10096 10097 if (setOverflowY) { 10098 ta.style.overflowY = value; 10099 } 10100 10101 update(); 10102 } 10103
10104 function update() { 10105 var startHeight = ta.style.height; 10106 var htmlTop = document.documentElement.scrollTop; 10107 var bodyTop = document.body.scrollTop; 10108 var originalHeight = ta.style.height; 10109 10110 ta.style.height = 'auto'; 10111 10112 var endHeight = ta.scrollHeight + heightOffset; 10113 10114 if (ta.scrollHeight === 0) { 10115 // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. 10116 ta.style.height = originalHeight; 10117 return; 10118 } 10119 10120 ta.style.height = endHeight + 'px'; 10121 10122 // prevents scroll-position jumping 10123 document.documentElement.scrollTop = htmlTop; 10124 document.body.scrollTop = bodyTop; 10125 10126 var style = window.getComputedStyle(ta, null); 10127 10128 if (style.height !== ta.style.height) { 10129 if (overflowY !== 'visible') { 10130 changeOverflow('visible'); 10131 return; 10132 } 10133 } else { 10134 if (overflowY !== 'hidden') { 10135 changeOverflow('hidden'); 10136 return; 10137 } 10138 } 10139 10140 if (startHeight !== ta.style.height) { 10141 var evt = document.createEvent('Event'); 10142 evt.initEvent('autosize:resized', true, false); 10143 ta.dispatchEvent(evt); 10144 } 10145 } 10146 10147 var destroy = (function (style) { 10148 window.removeEventListener('resize', update); 10149 ta.removeEventListener('input', update); 10150 ta.removeEventListener('keyup', update); 10151 ta.removeAttribute('data-autosize-on'); 10152 ta.removeEventListener('autosize:destroy', destroy); 10153 10154 Object.keys(style).forEach(function (key) { 10155 ta.style[key] = style[key]; 10156 }); 10157 }).bind(ta, { 10158 height: ta.style.height, 10159 resize: ta.style.resize, 10160 overflowY: ta.style.overflowY, 10161 overflowX: ta.style.overflowX, 10162 wordWrap: ta.style.wordWrap }); 10163 10164 ta.addEventListener('autosize:destroy', destroy); 10165 10166 // IE9 does not fire onpropertychange or oninput for deletions, 10167 // so binding to onkeyup to catch most of those events. 10168 // There is no way that I know of to detect something like 'cut' in IE9. 10169 if ('onpropertychange' in ta && 'oninput' in ta) { 10170 ta.addEventListener('keyup', update); 10171 } 10172 10173 window.addEventListener('resize', update); 10174 ta.addEventListener('input', update); 10175 ta.addEventListener('autosize:update', update); 10176 ta.setAttribute('data-autosize-on', true); 10177 10178 if (setOverflowY) { 10179 ta.style.overflowY = 'hidden'; 10180 } 10181 if (setOverflowX) { 10182 ta.style.overflowX = 'hidden'; 10183 ta.style.wordWrap = 'break-word'; 10184 } 10185 10186 init(); 10187 } 10188 10189 function destroy(ta) { 10190 if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; 10191 var evt = document.createEvent('Event'); 10192 evt.initEvent('autosize:destroy', true, false); 10193 ta.dispatchEvent(evt); 10194 } 10195 10196 function update(ta) { 10197 if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; 10198 var evt = document.createEvent('Event'); 10199 evt.initEvent('autosize:update', true, false); 10200 ta.dispatchEvent(evt); 10201 } 10202 10203 var autosize = null; 10204 10205 // Do nothing in Node.js environment and IE8 (or lower) 10206 if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { 10207 autosize = function (el) { 10208 return el; 10209 }; 10210 autosize.destroy = function (el) { 10211 return el; 10212 }; 10213 autosize.update = function (el) { 10214 return el; 10215 }; 10216 } else { 10217 autosize = function (el, options) { 10218 if (el) { 10219 Array.prototype.forEach.call(el.length ? el : [el], function (x) { 10220 return assign(x, options); 10221 }); 10222 } 10223 return el; 10224 }; 10225 autosize.destroy = function (el) { 10226 if (el) { 10227 Array.prototype.forEach.call(el.length ? el : [el], destroy); 10228 } 10229 return el; 10230 }; 10231 autosize.update = function (el) { 10232 if (el) { 10233 Array.prototype.forEach.call(el.length ? el : [el], update); 10234 } 10235 return el; 10236 }; 10237 } 10238 10239 module.exports = autosize; 10240}); 10241// Generated by CoffeeScript 1.4.0 10242(function() { 10243 var $; 10244 10245 $ = window.jQuery || window.Zepto || window.$; 10246 10247 $.fn.fancySelect = function(opts) { 10248 var isiOS, settings; 10249 if (opts == null) { 10250 opts = {}; 10251 } 10252 settings = $.extend({ 10253 forceiOS: false, 10254 includeBlank: false, 10255 optionTemplate: function(optionEl) { 10256 return optionEl.text(); 10257 }, 10258 triggerTemplate: function(optionEl) { 10259 return optionEl.text(); 10260 } 10261 }, opts); 10262 isiOS = !!navigator.userAgent.match(/iP(hone|od|ad)/i); 10263 return this.each(function() { 10264 var copyOptionsToList, disabled, options, sel, trigger, updateTriggerText, wrapper; 10265 sel = $(this); 10266 if (sel.hasClass('fancified') || sel[0].tagName !== 'SELECT') { 10267 return; 10268 } 10269 sel.addClass('fancified'); 10270 sel.css({ 10271 width: 1, 10272 height: 1, 10273 display: 'block', 10274 position: 'absolute', 10275 top: 0, 10276 left: 0, 10277 opacity: 0 10278 }); 10279 sel.wrap('<div class="fancy-select">'); 10280 wrapper = sel.parent(); 10281 if (sel.data('class')) { 10282 wrapper.addClass(sel.data('class')); 10283 } 10284 wrapper.append('<div class="trigger">');
10285 if (!(isiOS && !settings.forceiOS)) { 10286 wrapper.append('<ul class="options">'); 10287 } 10288 trigger = wrapper.find('.trigger'); 10289 options = wrapper.find('.options'); 10290 disabled = sel.prop('disabled'); 10291 if (disabled) { 10292 wrapper.addClass('disabled'); 10293 } 10294 updateTriggerText = function() { 10295 var triggerHtml; 10296 triggerHtml = settings.triggerTemplate(sel.find(':selected')); 10297 return trigger.html(triggerHtml); 10298 }; 10299 sel.on('blur.fs', function() { 10300 if (trigger.hasClass('open')) { 10301 return setTimeout(function() { 10302 return trigger.trigger('close.fs'); 10303 }, 120); 10304 } 10305 }); 10306 trigger.on('close.fs', function() { 10307 trigger.removeClass('open'); 10308 return options.removeClass('open'); 10309 }); 10310 trigger.on('click.fs', function() { 10311 var offParent, parent; 10312 if (!disabled) { 10313 trigger.toggleClass('open'); 10314 if (isiOS && !settings.forceiOS) { 10315 if (trigger.hasClass('open')) { 10316 return sel.focus(); 10317 } 10318 } else { 10319 if (trigger.hasClass('open')) { 10320 parent = trigger.parent(); 10321 offParent = parent.offsetParent(); 10322 if ((parent.offset().top + parent.outerHeight() + options.outerHeight() + 20) > $(window).height() + $(window).scrollTop()) { 10323 options.addClass('overflowing'); 10324 } else { 10325 options.removeClass('overflowing'); 10326 } 10327 } 10328 options.toggleClass('open'); 10329 if (!isiOS) { 10330 return sel.focus(); 10331 } 10332 } 10333 } 10334 }); 10335 sel.on('enable', function() { 10336 sel.prop('disabled', false); 10337 wrapper.removeClass('disabled'); 10338 disabled = false; 10339 return copyOptionsToList(); 10340 }); 10341 sel.on('disable', function() { 10342 sel.prop('disabled', true); 10343 wrapper.addClass('disabled'); 10344 return disabled = true; 10345 }); 10346 sel.on('change.fs', function(e) { 10347 if (e.originalEvent && e.originalEvent.isTrusted) { 10348 return e.stopPropagation(); 10349 } else { 10350 return updateTriggerText(); 10351 } 10352 }); 10353 sel.on('keydown', function(e) { 10354 var hovered, newHovered, w; 10355 w = e.which; 10356 hovered = options.find('.hover'); 10357 hovered.removeClass('hover'); 10358 if (!options.hasClass('open')) { 10359 if (w === 13 || w === 32 || w === 38 || w === 40) { 10360 e.preventDefault(); 10361 return trigger.trigger('click.fs'); 10362 } 10363 } else { 10364 if (w === 38) { 10365 e.preventDefault(); 10366 if (hovered.length && hovered.index() > 0) { 10367 hovered.prev().addClass('hover'); 10368 } else { 10369 options.find('li:last-child').addClass('hover'); 10370 } 10371 } else if (w === 40) { 10372 e.preventDefault(); 10373 if (hovered.length && hovered.index() < options.find('li').length - 1) { 10374 hovered.next().addClass('hover'); 10375 } else { 10376 options.find('li:first-child').addClass('hover'); 10377 } 10378 } else if (w === 27) { 10379 e.preventDefault(); 10380 trigger.trigger('click.fs'); 10381 } else if (w === 13 || w === 32) { 10382 e.preventDefault(); 10383 hovered.trigger('click.fs'); 10384 } else if (w === 9) { 10385 if (trigger.hasClass('open')) { 10386 trigger.trigger('close.fs'); 10387 } 10388 } 10389 newHovered = options.find('.hover'); 10390 if (newHovered.length) { 10391 options.scrollTop(0); 10392 return options.scrollTop(newHovered.position().top - 12); 10393 } 10394 } 10395 }); 10396 options.on('click.fs', 'li', function(e) { 10397 var clicked; 10398 clicked = $(this); 10399 sel.val(clicked.data('raw-value')); 10400 if (!isiOS) { 10401 sel.trigger('blur.fs').trigger('focus.fs'); 10402 } 10403 options.find('.selected').removeClass('selected'); 10404 clicked.addClass('selected'); 10405 trigger.addClass('selected'); 10406 return sel.val(clicked.data('raw-value')).trigger('change.fs').trigger('blur.fs').trigger('focus.fs'); 10407 }); 10408 options.on('mouseenter.fs', 'li', function() { 10409 var hovered, nowHovered; 10410 nowHovered = $(this); 10411 hovered = options.find('.hover'); 10412 hovered.removeClass('hover'); 10413 return nowHovered.addClass('hover'); 10414 }); 10415 options.on('mouseleave.fs', 'li', function() { 10416 return options.find('.hover').removeClass('hover'); 10417 }); 10418 copyOptionsToList = function() { 10419 var selOpts; 10420 updateTriggerText();
10421 if (isiOS && !settings.forceiOS) { 10422 return; 10423 } 10424 selOpts = sel.find('option'); 10425 return sel.find('option').each(function(i, opt) { 10426 var optHtml; 10427 opt = $(opt); 10428 if (!opt.prop('disabled') && (opt.val() || settings.includeBlank)) { 10429 optHtml = settings.optionTemplate(opt); 10430 if (opt.prop('selected')) { 10431 return options.append("<li data-raw-value=\"" + (opt.val()) + "\" class=\"selected\">" + optHtml + "</li>"); 10432 } else { 10433 return options.append("<li data-raw-value=\"" + (opt.val()) + "\">" + optHtml + "</li>"); 10434 } 10435 } 10436 }); 10437 }; 10438 sel.on('update.fs', function() { 10439 wrapper.find('.options').empty(); 10440 return copyOptionsToList(); 10441 }); 10442 return copyOptionsToList(); 10443 }); 10444 }; 10445 10446}).call(this); 10447/*! 10448 * Flickity PACKAGED v2.3.0 10449 * Touch, responsive, flickable carousels 10450 * 10451 * Licensed GPLv3 for open source use 10452 * or Flickity Commercial License for commercial use 10453 * 10454 * https://flickity.metafizzy.co 10455 * Copyright 2015-2021 Metafizzy 10456 */ 10457(function(e,i){if(typeof define=="function"&&define.amd){define("jquery-bridget/jquery-bridget",["jquery"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("jquery"))}else{e.jQueryBridget=i(e,e.jQuery)}})(window,function t(e,r){"use strict";var o=Array.prototype.slice;var i=e.console;var u=typeof i=="undefined"?function(){}:function(t){i.error(t)};function n(h,s,c){c=c||r||e.jQuery;if(!c){return}if(!s.prototype.option){s.prototype.option=function(t){if(!c.isPlainObject(t)){return}this.options=c.extend(true,this.options,t)}}c.fn[h]=function(t){if(typeof t=="string"){var e=o.call(arguments,1);return i(this,t,e)}n(this,t);return this};function i(t,r,o){var a;var l="$()."+h+'("'+r+'")';t.each(function(t,e){var i=c.data(e,h);if(!i){u(h+" not initialized. Cannot call methods, i.e. "+l);return}var n=i[r];if(!n||r.charAt(0)=="_"){u(l+" is not a valid method");return}var s=n.apply(i,o);a=a===undefined?s:a});return a!==undefined?a:t}function n(t,n){t.each(function(t,e){var i=c.data(e,h);if(i){i.option(n);i._init()}else{i=new s(e,n);c.data(e,h,i)}})}a(c)}function a(t){if(!t||t&&t.bridget){return}t.bridget=n}a(r||e.jQuery);return n});(function(t,e){if(typeof define=="function"&&define.amd){define("ev-emitter/ev-emitter",e)}else if(typeof module=="object"&&module.exports){module.exports=e()}else{t.EvEmitter=e()}})(typeof window!="undefined"?window:this,function(){function t(){}var e=t.prototype;e.on=function(t,e){if(!t||!e){return}var i=this._events=this._events||{};var n=i[t]=i[t]||[];if(n.indexOf(e)==-1){n.push(e)}return this};e.once=function(t,e){if(!t||!e){return}this.on(t,e);var i=this._onceEvents=this._onceEvents||{};var n=i[t]=i[t]||{};n[e]=true;return this};e.off=function(t,e){var i=this._events&&this._events[t];if(!i||!i.length){return}var n=i.indexOf(e);if(n!=-1){i.splice(n,1)}return this};e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(!i||!i.length){return}i=i.slice(0);e=e||[];var n=this._onceEvents&&this._onceEvents[t];for(var s=0;s<i.length;s++){var r=i[s];var o=n&&n[r];if(o){this.off(t,r);delete n[r]}r.apply(this,e)}return this};e.allOff=function(){delete this._events;delete this._onceEvents};return t}); 10458/*! 10459 * getSize v2.0.3 10460 * measure size of elements 10461 * MIT license 10462 */ 10463(function(t,e){if(typeof define=="function"&&define.amd){define("get-size/get-size",e)}else if(typeof module=="object"&&module.exports){module.exports=e()}else{t.getSize=e()}})(window,function t(){"use strict";function m(t){var e=parseFloat(t);var i=t.indexOf("%")==-1&&!isNaN(e);return i&&e}function e(){}var i=typeof console=="undefined"?e:function(t){console.error(t)};var y=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];var b=y.length;function E(){var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0};for(var e=0;e<b;e++){var i=y[e];t[i]=0}return t}function S(t){var e=getComputedStyle(t);if(!e){i("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? "+"See https://bit.ly/getsizebug1")}return e}var n=false;var C;function x(){if(n){return}n=true;var t=document.createElement("div");t.style.width="200px";t.style.padding="1px 2px 3px 4px";t.style.borderStyle="solid";t.style.borderWidth="1px 2px 3px 4px";t.style.boxSizing="border-box";var e=document.body||document.documentElement;e.appendChild(t);var i=S(t);C=Math.round(m(i.width))==200;s.isBoxSizeOuter=C;e.removeChild(t)}function s(t){x();if(typeof t=="string"){t=document.querySelector(t)}if(!t||typeof t!="object"||!t.nodeType){return}var e=S(t);if(e.display=="none"){return E()}var i={};i.width=t.offsetWidth;i.height=t.offsetHeight;var n=i.isBorderBox=e.boxSizing=="border-box";for(var s=0;s<b;s++){var r=y[s];var o=e[r];var a=parseFloat(o);i[r]=!isNaN(a)?a:0}var l=i.paddingLeft+i.paddingRight;var h=i.paddingTop+i.paddingBottom;var c=i.marginLeft+i.marginRight;var u=i.marginTop+i.marginBottom;var d=i.borderLeftWidth+i.borderRightWidth;var f=i.borderTopWidth+i.borderBottomWidth;var p=n&&C;var v=m(e.width);if(v!==false){i.width=v+(p?0:l+d)}var g=m(e.height);if(g!==false){i.height=g+(p?0:h+f)}i.innerWidth=i.width-(l+d);i.innerHeight=i.height-(h+f);i.outerWidth=i.width+c;i.outerHeight=i.height+u;return i}return s});(function(t,e){"use strict";if(typeof define=="function"&&define.amd){define("desandro-matches-selector/matches-selector",e)}else if(typeof module=="object"&&module.exports){module.exports=e()}else{t.matchesSelector=e()}})(window,function t(){"use strict";var n=function(){var t=window.Element.prototype;if(t.matches){return"matches"}if(t.matchesSelector){return"matchesSelector"}var e=["webkit","moz","ms","o"];for(var i=0;i<e.length;i++){var n=e[i];var s=n+"MatchesSelector";if(t[s]){return s}}}();return function t(e,i){return e[n](i)}});(function(e,i){if(typeof define=="function"&&define.amd){define("fizzy-ui-utils/utils",["de
10463sandro-matches-selector/matches-selector"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("desandro-matches-selector"))}else{e.fizzyUIUtils=i(e,e.matchesSelector)}})(window,function t(h,r){var c={};c.extend=function(t,e){for(var i in e){t[i]=e[i]}return t};c.modulo=function(t,e){return(t%e+e)%e};var i=Array.prototype.slice;c.makeArray=function(t){if(Array.isArray(t)){return t}if(t===null||t===undefined){return[]}var e=typeof t=="object"&&typeof t.length=="number";if(e){return i.call(t)}return[t]};c.removeFrom=function(t,e){var i=t.indexOf(e);if(i!=-1){t.splice(i,1)}};c.getParent=function(t,e){while(t.parentNode&&t!=document.body){t=t.parentNode;if(r(t,e)){return t}}};c.getQueryElement=function(t){if(typeof t=="string"){return document.querySelector(t)}return t};c.handleEvent=function(t){var e="on"+t.type;if(this[e]){this[e](t)}};c.filterFindElements=function(t,n){t=c.makeArray(t);var s=[];t.forEach(function(t){if(!(t instanceof HTMLElement)){return}if(!n){s.push(t);return}if(r(t,n)){s.push(t)}var e=t.querySelectorAll(n);for(var i=0;i<e.length;i++){s.push(e[i])}});return s};c.debounceMethod=function(t,e,n){n=n||100;var s=t.prototype[e];var r=e+"Timeout";t.prototype[e]=function(){var t=this[r];clearTimeout(t);var e=arguments;var i=this;this[r]=setTimeout(function(){s.apply(i,e);delete i[r]},n)}};c.docReady=function(t){var e=document.readyState;if(e=="complete"||e=="interactive"){setTimeout(t)}else{document.addEventListener("DOMContentLoaded",t)}};c.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var u=h.console;c.htmlInit=function(a,l){c.docReady(function(){var t=c.toDashed(l);var s="data-"+t;var e=document.querySelectorAll("["+s+"]");var i=document.querySelectorAll(".js-"+t);var n=c.makeArray(e).concat(c.makeArray(i));var r=s+"-options";var o=h.jQuery;n.forEach(function(e){var t=e.getAttribute(s)||e.getAttribute(r);var i;try{i=t&&JSON.parse(t)}catch(t){if(u){u.error("Error parsing "+s+" on "+e.className+": "+t)}return}var n=new a(e,i);if(o){o.data(e,l,n)}})})};return c});(function(e,i){if(typeof define=="function"&&define.amd){define("flickity/js/cell",["get-size/get-size"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("get-size"))}else{e.Flickity=e.Flickity||{};e.Flickity.Cell=i(e,e.getSize)}})(window,function t(e,i){function n(t,e){this.element=t;this.parent=e;this.create()}var s=n.prototype;s.create=function(){this.element.style.position="absolute";this.element.setAttribute("aria-hidden","true");this.x=0;this.shift=0;this.element.style[this.parent.originSide]=0};s.destroy=function(){this.unselect();this.element.style.position="";var t=this.parent.originSide;this.element.style[t]="";this.element.style.transform="";this.element.removeAttribute("aria-hidden")};s.getSize=function(){this.size=i(this.element)};s.setPosition=function(t){this.x=t;this.updateTarget();this.renderPosition(t)};s.updateTarget=s.setDefaultTarget=function(){var t=this.parent.originSide=="left"?"marginLeft":"marginRight";this.target=this.x+this.size[t]+this.size.width*this.parent.cellAlign};s.renderPosition=function(t){var e=this.parent.originSide==="left"?1:-1;var i=this.parent.options.percentPosition?t*e*(this.parent.size.innerWidth/this.size.width):t*e;this.element.style.transform="translateX("+this.parent.getPositionValue(i)+")"};s.select=function(){this.element.classList.add("is-selected");this.element.removeAttribute("aria-hidden")};s.unselect=function(){this.element.classList.remove("is-selected");this.element.setAttribute("aria-hidden","true")};s.wrapShift=function(t){this.shift=t;this.renderPosition(this.x+this.parent.slideableWidth*t)};s.remove=function(){this.element.parentNode.removeChild(this.element)};return n});(function(t,e){if(typeof define=="function"&&define.amd){define("flickity/js/slide",e)}else if(typeof module=="object"&&module.exports){module.exports=e()}else{t.Flickity=t.Flickity||{};t.Flickity.Slide=e()}})(window,function t(){"use strict";function e(t){this.parent=t;this.isOriginLeft=t.originSide=="left";this.cells=[];this.outerWidth=0;this.height=0}var i=e.prototype;i.addCell=function(t){this.cells.push(t);this.outerWidth+=t.size.outerWidth;this.height=Math.max(t.size.outerHeight,this.height);if(this.cells.length==1){this.x=t.x;var e=this.isOriginLeft?"marginLeft":"marginRight";this.firstMargin=t.size[e]}};i.updateTarget=function(){var t=this.isOriginLeft?"marginRight":"marginLeft";var e=this.getLastCell();var i=e?e.size[t]:0;var n=this.outerWidth-(this.firstMargin+i);this.target=this.x+this.firstMargin+n*this.parent.cellAlign};i.getLastCell=function(){return this.cells[this.cells.length-1]};
10463i.select=function(){this.cells.forEach(function(t){t.select()})};i.unselect=function(){this.cells.forEach(function(t){t.unselect()})};i.getCellElements=function(){return this.cells.map(function(t){return t.element})};return e});(function(e,i){if(typeof define=="function"&&define.amd){define("flickity/js/animate",["fizzy-ui-utils/utils"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("fizzy-ui-utils"))}else{e.Flickity=e.Flickity||{};e.Flickity.animatePrototype=i(e,e.fizzyUIUtils)}})(window,function t(e,i){var n={};n.startAnimation=function(){if(this.isAnimating){return}this.isAnimating=true;this.restingFrames=0;this.animate()};n.animate=function(){this.applyDragForce();this.applySelectedAttraction();var t=this.x;this.integratePhysics();this.positionSlider();this.settle(t);if(this.isAnimating){var e=this;requestAnimationFrame(function t(){e.animate()})}};n.positionSlider=function(){var t=this.x;if(this.options.wrapAround&&this.cells.length>1){t=i.modulo(t,this.slideableWidth);t-=this.slideableWidth;this.shiftWrapCells(t)}this.setTranslateX(t,this.isAnimating);this.dispatchScrollEvent()};n.setTranslateX=function(t,e){t+=this.cursorPosition;t=this.options.rightToLeft?-t:t;var i=this.getPositionValue(t);this.slider.style.transform=e?"translate3d("+i+",0,0)":"translateX("+i+")"};n.dispatchScrollEvent=function(){var t=this.slides[0];if(!t){return}var e=-this.x-t.target;var i=e/this.slidesWidth;this.dispatchEvent("scroll",null,[i,e])};n.positionSliderAtSelected=function(){if(!this.cells.length){return}this.x=-this.selectedSlide.target;this.velocity=0;this.positionSlider()};n.getPositionValue=function(t){if(this.options.percentPosition){return Math.round(t/this.size.innerWidth*1e4)*.01+"%"}else{return Math.round(t)+"px"}};n.settle=function(t){var e=!this.isPointerDown&&Math.round(this.x*100)==Math.round(t*100);if(e){this.restingFrames++}if(this.restingFrames>2){this.isAnimating=false;delete this.isFreeScrolling;this.positionSlider();this.dispatchEvent("settle",null,[this.selectedIndex])}};n.shiftWrapCells=function(t){var e=this.cursorPosition+t;this._shiftCells(this.beforeShiftCells,e,-1);var i=this.size.innerWidth-(t+this.slideableWidth+this.cursorPosition);this._shiftCells(this.afterShiftCells,i,1)};n._shiftCells=function(t,e,i){for(var n=0;n<t.length;n++){var s=t[n];var r=e>0?i:0;s.wrapShift(r);e-=s.size.outerWidth}};n._unshiftCells=function(t){if(!t||!t.length){return}for(var e=0;e<t.length;e++){t[e].wrapShift(0)}};n.integratePhysics=function(){this.x+=this.velocity;this.velocity*=this.getFrictionFactor()};n.applyForce=function(t){this.velocity+=t};n.getFrictionFactor=function(){return 1-this.options[this.isFreeScrolling?"freeScrollFriction":"friction"]};n.getRestingPosition=function(){return this.x+this.velocity/(1-this.getFrictionFactor())};n.applyDragForce=function(){if(!this.isDraggable||!this.isPointerDown){return}var t=this.dragX-this.x;var e=t-this.velocity;this.applyForce(e)};n.applySelectedAttraction=function(){var t=this.isDraggable&&this.isPointerDown;if(t||this.isFreeScrolling||!this.slides.length){return}var e=this.selectedSlide.target*-1-this.x;var i=e*this.options.selectedAttraction;this.applyForce(i)};return n});(function(o,a){if(typeof define=="function"&&define.amd){define("flickity/js/flickity",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./cell","./slide","./animate"],function(t,e,i,n,s,r){return a(o,t,e,i,n,s,r)})}else if(typeof module=="object"&&module.exports){module.exports=a(o,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./cell"),require("./sli
10463de"),require("./animate"))}else{var t=o.Flickity;o.Flickity=a(o,o.EvEmitter,o.getSize,o.fizzyUIUtils,t.Cell,t.Slide,t.animatePrototype)}})(window,function t(n,e,i,a,s,o,r){var l=n.jQuery;var h=n.getComputedStyle;var c=n.console;function u(t,e){t=a.makeArray(t);while(t.length){e.appendChild(t.shift())}}var d=0;var f={};function p(t,e){var i=a.getQueryElement(t);if(!i){if(c){c.error("Bad element for Flickity: "+(i||t))}return}this.element=i;if(this.element.flickityGUID){var n=f[this.element.flickityGUID];if(n)n.option(e);return n}if(l){this.$element=l(this.element)}this.options=a.extend({},this.constructor.defaults);this.option(e);this._create()}p.defaults={accessibility:true,cellAlign:"center",freeScrollFriction:.075,friction:.28,namespaceJQueryEvents:true,percentPosition:true,resize:true,selectedAttraction:.025,setGallerySize:true};p.createMethods=[];var v=p.prototype;a.extend(v,e.prototype);v._create=function(){var t=this.guid=++d;this.element.flickityGUID=t;f[t]=this;this.selectedIndex=0;this.restingFrames=0;this.x=0;this.velocity=0;this.originSide=this.options.rightToLeft?"right":"left";this.viewport=document.createElement("div");this.viewport.className="flickity-viewport";this._createSlider();if(this.options.resize||this.options.watchCSS){n.addEventListener("resize",this)}for(var e in this.options.on){var i=this.options.on[e];this.on(e,i)}p.createMethods.forEach(function(t){this[t]()},this);if(this.options.watchCSS){this.watchCSS()}else{this.activate()}};v.option=function(t){a.extend(this.options,t)};v.activate=function(){if(this.isActive){return}this.isActive=true;this.element.classList.add("flickity-enabled");if(this.options.rightToLeft){this.element.classList.add("flickity-rtl")}this.getSize();var t=this._filterFindCellElements(this.element.children);u(t,this.slider);this.viewport.appendChild(this.slider);this.element.appendChild(this.viewport);this.reloadCells();if(this.options.accessibility){this.element.tabIndex=0;this.element.addEventListener("keydown",this)}this.emitEvent("activate");this.selectInitialIndex();this.isInitActivated=true;this.dispatchEvent("ready")};v._createSlider=function(){var t=document.createElement("div");t.className="flickity-slider";t.style[this.originSide]=0;this.slider=t};v._filterFindCellElements=function(t){return a.filterFindElements(t,this.options.cellSelector)};v.reloadCells=function(){this.cells=this._makeCells(this.slider.children);this.positionCells();this._getWrapShiftCells();this.setGallerySize()};v._makeCells=function(t){var e=this._filterFindCellElements(t);var i=e.map(function(t){return new s(t,this)},this);return i};v.getLastCell=function(){return this.cells[this.cells.length-1]};v.getLastSlide=function(){return this.slides[this.slides.length-1]};v.positionCells=function(){this._sizeCells(this.cells);this._positionCells(0)};v._positionCells=function(t){t=t||0;this.maxCellHeight=t?this.maxCellHeight||0:0;var e=0;if(t>0){var i=this.cells[t-1];e=i.x+i.size.outerWidth}var n=this.cells.length;for(var s=t;s<n;s++){var r=this.cells[s];r.setPosition(e);e+=r.size.outerWidth;this.maxCellHeight=Math.max(r.size.outerHeight,this.maxCellHeight)}this.slideableWidth=e;this.updateSlides();this._containSlides();this.slidesWidth=n?this.getLastSlide().target-this.slides[0].target:0};v._sizeCells=function(t){t.forEach(function(t){t.getSize()})};v.updateSlides=function(){this.slides=[];if(!this.cells.length){return}var n=new o(this);this.slides.push(n);var t=this.originSide=="left";var s=t?"marginRight":"marginLeft";var r=this._getCanCellFit();this.cells.forEach(function(t,e){if(!n.cells.length){n.addCell(t);return}var i=n.outerWidth-n.firstMargin+(t.size.outerWidth-t.size[s]);if(r.call(this,e,i)){n.addCell(t)}else{n.updateTarget();n=new o(this);this.slides.push(n);n.addCell(t)}},this);n.updateTarget();this.updateSelectedSlide()};v._getCanCellFit=function(){var t=this.options.groupCells;if(!t){return function(){return false}}else if(typeof t=="number"){var e=parseInt(t,10);return function(t){return t%e!==0}}var i=typeof t=="string"&&t.match(/^(\d+)%$/);var n=i?parseInt(i[1],10)/100:1;return function(t,e){return e<=(this.size.innerWidth+1)*n}};v._init=v.reposition=function(){this.positionCells();this.positionSliderAtSelected()};v.getSize=function(){this.size=i(this.element);this.setCellAlign();this.cursorPosition=this.size.innerWidth*this.cellAlign};var g={center:{left:.5,right:.5},left:{left:0,right:1},right:{right:0,left:1}};v.setCellAlign=function(){var t=g[this.options.cellAlign];this.cellAlign=t?t[this.originSide]:this.options.cellAlign};v.setGallerySize=function(){if(this.options.setGallerySize){var t=this.options.adaptiveHeight&&this.selectedSlide?this.selectedSlide.height:this.maxCellHeight;this.viewport.style.height=t+"px"}};v._getWrapShiftCells=function(){if(!this.options.wrapAround){return}this._unshiftCells(this.beforeShiftCells);this._unshiftCells(this.afterShiftCells);var t=this.cursorPosition;var e=this.cells.length-1;this.beforeShiftCells=this._getGapCells(t,e,-1);
10463t=this.size.innerWidth-this.cursorPosition;this.afterShiftCells=this._getGapCells(t,0,1)};v._getGapCells=function(t,e,i){var n=[];while(t>0){var s=this.cells[e];if(!s){break}n.push(s);e+=i;t-=s.size.outerWidth}return n};v._containSlides=function(){if(!this.options.contain||this.options.wrapAround||!this.cells.length){return}var t=this.options.rightToLeft;var e=t?"marginRight":"marginLeft";var i=t?"marginLeft":"marginRight";var n=this.slideableWidth-this.getLastCell().size[i];var s=n<this.size.innerWidth;var r=this.cursorPosition+this.cells[0].size[e];var o=n-this.size.innerWidth*(1-this.cellAlign);this.slides.forEach(function(t){if(s){t.target=n*this.cellAlign}else{t.target=Math.max(t.target,r);t.target=Math.min(t.target,o)}},this)};v.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;this.emitEvent(t,n);if(l&&this.$element){t+=this.options.namespaceJQueryEvents?".flickity":"";var s=t;if(e){var r=new l.Event(e);r.type=t;s=r}this.$element.trigger(s,i)}};v.select=function(t,e,i){if(!this.isActive){return}t=parseInt(t,10);this._wrapSelect(t);if(this.options.wrapAround||e){t=a.modulo(t,this.slides.length)}if(!this.slides[t]){return}var n=this.selectedIndex;this.selectedIndex=t;this.updateSelectedSlide();if(i){this.positionSliderAtSelected()}else{this.startAnimation()}if(this.options.adaptiveHeight){this.setGallerySize()}this.dispatchEvent("select",null,[t]);if(t!=n){this.dispatchEvent("change",null,[t])}this.dispatchEvent("cellSelect")};v._wrapSelect=function(t){var e=this.slides.length;var i=this.options.wrapAround&&e>1;if(!i){return t}var n=a.modulo(t,e);var s=Math.abs(n-this.selectedIndex);var r=Math.abs(n+e-this.selectedIndex);var o=Math.abs(n-e-this.selectedIndex);if(!this.isDragSelect&&r<s){t+=e}else if(!this.isDragSelect&&o<s){t-=e}if(t<0){this.x-=this.slideableWidth}else if(t>=e){this.x+=this.slideableWidth}};v.previous=function(t,e){this.select(this.selectedIndex-1,t,e)};v.next=function(t,e){this.select(this.selectedIndex+1,t,e)};v.updateSelectedSlide=function(){var t=this.slides[this.selectedIndex];if(!t){return}this.unselectSelectedSlide();this.selectedSlide=t;t.select();this.selectedCells=t.cells;this.selectedElements=t.getCellElements();this.selectedCell=t.cells[0];this.selectedElement=this.selectedElements[0]};v.unselectSelectedSlide=function(){if(this.selectedSlide){this.selectedSlide.unselect()}};v.selectInitialIndex=function(){var t=this.options.initialIndex;if(this.isInitActivated){this.select(this.selectedIndex,false,true);return}if(t&&typeof t=="string"){var e=this.queryCell(t);if(e){this.selectCell(t,false,true);return}}var i=0;if(t&&this.slides[t]){i=t}this.select(i,false,true)};v.selectCell=function(t,e,i){var n=this.queryCell(t);if(!n){return}var s=this.getCellSlideIndex(n);this.select(s,e,i)};v.getCellSlideIndex=function(t){for(var e=0;e<this.slides.length;e++){var i=this.slides[e];var n=i.cells.indexOf(t);if(n!=-1){return e}}};v.getCell=function(t){for(var e=0;e<this.cells.length;e++){var i=this.cells[e];if(i.element==t){return i}}};v.getCells=function(t){t=a.makeArray(t);var i=[];t.forEach(function(t){var e=this.getCell(t);if(e){i.push(e)}},this);return i};v.getCellElements=function(){return this.cells.map(function(t){return t.element})};v.getParentCell=function(t){var e=this.getCell(t);if(e){return e}t=a.getParent(t,".flickity-slider > *");return this.getCell(t)};v.getAdjacentCellElements=function(t,e){if(!t){return this.selectedSlide.getCellElements()}e=e===undefined?this.selectedIndex:e;var i=this.slides.length;if(1+t*2>=i){return this.getCellElements()}var n=[];for(var s=e-t;s<=e+t;s++){var r=this.options.wrapAround?a.modulo(s,i):s;var o=this.slides[r];if(o){n=n.concat(o.getCellElements())}}return n};v.queryCell=function(t){if(typeof t=="number"){return this.cells[t]}if(typeof t=="string"){if(t.match(/^[#.]?[\d/]/)){return}t=this.element.querySelector(t)}return this.getCell(t)};v.uiChange=function(){this.emitEvent("uiChange")};v.childUIPointerDown=function(t){if(t.type!="touchstart"){t.preventDefault()}this.focus()};v.onresize=function(){this.watchCSS();this.resize()};a.debounceMethod(p,"onresize",150);v.resize=function(){if(!this.isActive||this.isAnimating||this.isDragging){return}this.getSize();if(this.options.wrapAround){this.x=a.modulo(this.x,this.slideableWidth)}this.positionCells();this._getWrapShiftCells();this.setGallerySize();this.emitEvent("resize");var t=this.selectedElements&&this.selectedElements[0];this.selectCell(t,false,true)};v.watchCSS=function(){var t=this.options.watchCSS;if(!t){return}var e=h(this.element,":after").content;if(e.indexOf("flickity")!=-1){this.activate()}else{this.deactivate()}};v.onkeydown=function(t){var e=document.activeElement&&document.activeElement!=this.element;if(!this.options.accessibility||e){return}var i=p.keyboardHandlers[t.keyCode];if(i){i.call(this)}};p.keyboardHandlers={37:function(){var t=this.options.rightToLeft?"next":"previous";this.uiChange();this[t]()},39:function(){var t=this.options.rightToLeft?"previous":"next";this.uiChange();this[t]()}};v.focus=function(){var t=n.pageYOffset;this.element.focus({preventScroll:true});if(n.pageYOffset!=t){n.scrollTo(n.pageXOffset,t)}};v.deactivate=function(){if(!this.isActive){return}this.element.classList.remove("flickity-enabled");this.element.classList.remove("flickity-rtl");this.unselectSelectedSlide();
10463this.cells.forEach(function(t){t.destroy()});this.element.removeChild(this.viewport);u(this.slider.children,this.element);if(this.options.accessibility){this.element.removeAttribute("tabIndex");this.element.removeEventListener("keydown",this)}this.isActive=false;this.emitEvent("deactivate")};v.destroy=function(){this.deactivate();n.removeEventListener("resize",this);this.allOff();this.emitEvent("destroy");if(l&&this.$element){l.removeData(this.element,"flickity")}delete this.element.flickityGUID;delete f[this.guid]};a.extend(v,r);p.data=function(t){t=a.getQueryElement(t);var e=t&&t.flickityGUID;return e&&f[e]};a.htmlInit(p,"flickity");if(l&&l.bridget){l.bridget("flickity",p)}p.setJQuery=function(t){l=t};p.Cell=s;p.Slide=o;return p}); 10464/*! 10465 * Unipointer v2.4.0 10466 * base class for doing one thing with pointer event 10467 * MIT license 10468 */ 10469(function(e,i){if(typeof define=="function"&&define.amd){define("unipointer/unipointer",["ev-emitter/ev-emitter"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("ev-emitter"))}else{e.Unipointer=i(e,e.EvEmitter)}})(window,function t(s,e){function i(){}function n(){}var r=n.prototype=Object.create(e.prototype);r.bindStartEvent=function(t){this._bindStartEvent(t,true)};r.unbindStartEvent=function(t){this._bindStartEvent(t,false)};r._bindStartEvent=function(t,e){e=e===undefined?true:e;var i=e?"addEventListener":"removeEventListener";var n="mousedown";if("ontouchstart"in s){n="touchstart"}else if(s.PointerEvent){n="pointerdown"}t[i](n,this)};r.handleEvent=function(t){var e="on"+t.type;if(this[e]){this[e](t)}};r.getTouch=function(t){for(var e=0;e<t.length;e++){var i=t[e];if(i.identifier==this.pointerIdentifier){return i}}};r.onmousedown=function(t){var e=t.button;if(e&&(e!==0&&e!==1)){return}this._pointerDown(t,t)};r.ontouchstart=function(t){this._pointerDown(t,t.changedTouches[0])};r.onpointerdown=function(t){this._pointerDown(t,t)};r._pointerDown=function(t,e){if(t.button||this.isPointerDown){return}this.isPointerDown=true;this.pointerIdentifier=e.pointerId!==undefined?e.pointerId:e.identifier;this.pointerDown(t,e)};r.pointerDown=function(t,e){this._bindPostStartEvents(t);this.emitEvent("pointerDown",[t,e])};var o={mousedown:["mousemove","mouseup"],touchstart:["touchmove","touchend","touchcancel"],pointerdown:["pointermove","pointerup","pointercancel"]};r._bindPostStartEvents=function(t){if(!t){return}var e=o[t.type];e.forEach(function(t){s.addEventListener(t,this)},this);this._boundPointerEvents=e};r._unbindPostStartEvents=function(){if(!this._boundPointerEvents){return}this._boundPointerEvents.forEach(function(t){s.removeEventListener(t,this)},this);delete this._boundPointerEvents};r.onmousemove=function(t){this._pointerMove(t,t)};r.onpointermove=function(t){if(t.pointerId==this.pointerIdentifier){this._pointerMove(t,t)}};r.ontouchmove=function(t){var e=this.getTouch(t.changedTouches);if(e){this._pointerMove(t,e)}};r._pointerMove=function(t,e){this.pointerMove(t,e)};r.pointerMove=function(t,e){this.emitEvent("pointerMove",[t,e])};r.onmouseup=function(t){this._pointerUp(t,t)};r.onpointerup=function(t){if(t.pointerId==this.pointerIdentifier){this._pointerUp(t,t)}};r.ontouchend=function(t){var e=this.getTouch(t.changedTouches);if(e){this._pointerUp(t,e)}};r._pointerUp=function(t,e){this._pointerDone();this.pointerUp(t,e)};r.pointerUp=function(t,e){this.emitEvent("pointerUp",[t,e])};r._pointerDone=function(){this._pointerReset();this._unbindPostStartEvents();this.pointerDone()};r._pointerReset=function(){this.isPointerDown=false;delete this.pointerIdentifier};r.pointerDone=i;r.onpointercancel=function(t){if(t.pointerId==this.pointerIdentifier){this._pointerCancel(t,t)}};r.ontouchcancel=function(t){var e=this.getTouch(t.changedTouches);if(e){this._pointerCancel(t,e)}};r._pointerCancel=function(t,e){this._pointerDone();this.pointerCancel(t,e)};r.pointerCancel=function(t,e){this.emitEvent("pointerCancel",[t,e])};n.getPointerPoint=function(t){return{x:t.pageX,y:t.pageY}};return n}); 10470/*! 10471 * Unidragger v2.4.0 10472 * Draggable base class 10473 * MIT license 10474 */ 10475(function(e,i){if(typeof define=="function"&&define.amd){define("unidragger/unidragger",["unipointer/unipointer"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("unipointer"))}else{e.Unidragger=i(e,e.Unipointer)}})(window,function t(r,e){function i(){}var n=i.prototype=Object.create(e.prototype);n.bindHandles=function(){this._bindHandles(true)};n.unbindHandles=function(){this._bindHandles(false)};n._bindHandles=function(t){t=t===undefined?true:t;var e=t?"addEventListener":"removeEventListener";var i=t?this._touchActionValue:"";for(var n=0;n<this.handles.length;n++){var s=this.handles[n];this._bindStartEvent(s,t);s[e]("click",this);if(r.PointerEvent){s.style.touchAction=i}}};n._touchActionValue="none";n.pointerDown=function(t,e){var i=this.okayPointerDown(t);if(!i){return}this.pointerDownPointer={pageX:e.pageX,pageY:e.pageY};t.preventDefault();this.pointerDownBlur();this._bindPostStartEvents(t);this.emitEvent("pointerDown",[t,e])};var s={TEXTAREA:true,INPUT:true,SELECT:true,OPTION:true};var o={radio:true,checkbox:true,button:true,submit:true,image:true,file:true};n.okayPointerDown=function(t){var e=s[t.target.nodeName];var i=o[t.target.type];var n=!e||i;
10475if(!n){this._pointerReset()}return n};n.pointerDownBlur=function(){var t=document.activeElement;var e=t&&t.blur&&t!=document.body;if(e){t.blur()}};n.pointerMove=function(t,e){var i=this._dragPointerMove(t,e);this.emitEvent("pointerMove",[t,e,i]);this._dragMove(t,e,i)};n._dragPointerMove=function(t,e){var i={x:e.pageX-this.pointerDownPointer.pageX,y:e.pageY-this.pointerDownPointer.pageY};if(!this.isDragging&&this.hasDragStarted(i)){this._dragStart(t,e)}return i};n.hasDragStarted=function(t){return Math.abs(t.x)>3||Math.abs(t.y)>3};n.pointerUp=function(t,e){this.emitEvent("pointerUp",[t,e]);this._dragPointerUp(t,e)};n._dragPointerUp=function(t,e){if(this.isDragging){this._dragEnd(t,e)}else{this._staticClick(t,e)}};n._dragStart=function(t,e){this.isDragging=true;this.isPreventingClicks=true;this.dragStart(t,e)};n.dragStart=function(t,e){this.emitEvent("dragStart",[t,e])};n._dragMove=function(t,e,i){if(!this.isDragging){return}this.dragMove(t,e,i)};n.dragMove=function(t,e,i){t.preventDefault();this.emitEvent("dragMove",[t,e,i])};n._dragEnd=function(t,e){this.isDragging=false;
10475setTimeout(function(){delete this.isPreventingClicks}.bind(this));this.dragEnd(t,e)};n.dragEnd=function(t,e){this.emitEvent("dragEnd",[t,e])};n.onclick=function(t){if(this.isPreventingClicks){t.preventDefault()}};n._staticClick=function(t,e){if(this.isIgnoringMouseUp&&t.type=="mouseup"){return}this.staticClick(t,e);if(t.type!="mouseup"){this.isIgnoringMouseUp=true;setTimeout(function(){delete this.isIgnoringMouseUp}.bind(this),400)}};n.staticClick=function(t,e){this.emitEvent("staticClick",[t,e])};i.getPointerPoint=e.getPointerPoint;return i});(function(n,s){if(typeof define=="function"&&define.amd){define("flickity/js/drag",["./flickity","unidragger/unidragger","fizzy-ui-utils/utils"],function(t,e,i){return s(n,t,e,i)})}else if(typeof module=="object"&&module.exports){module.exports=s(n,require("./flickity"),require("unidragger"),require("fizzy-ui-utils"))}else{n.Flickity=s(n,n.Flickity,n.Unidragger,n.fizzyUIUtils)}})(window,function t(n,e,i,a){a.extend(e.defaults,{draggable:">1",dragThreshold:3});e.createMethods.push("_createDrag");var s=e.prototype;a.extend(s,i.prototype);s._touchActionValue="pan-y";s._createDrag=function(){this.on("activate",this.onActivateDrag);this.on("uiChange",this._uiChangeDrag);this.on("deactivate",this.onDeactivateDrag);this.on("cellChange",this.updateDraggable)};s.onActivateDrag=function(){this.handles=[this.viewport];this.bindHandles();this.updateDraggable()};s.onDeactivateDrag=function(){this.unbindHandles();this.element.classList.remove("is-draggable")};s.updateDraggable=function(){if(this.options.draggable==">1"){this.isDraggable=this.slides.length>1}else{this.isDraggable=this.options.draggable}if(this.isDraggable){this.element.classList.add("is-draggable")}else{this.element.classList.remove("is-draggable")}};s.bindDrag=function(){this.options.draggable=true;this.updateDraggable()};s.unbindDrag=function(){this.options.draggable=false;this.updateDraggable()};s._uiChangeDrag=function(){delete this.isFreeScrolling};s.pointerDown=function(t,e){if(!this.isDraggable){this._pointerDownDefault(t,e);return}var i=this.okayPointerDown(t);if(!i){return}this._pointerDownPreventDefault(t);this.pointerDownFocus(t);if(document.activeElement!=this.element){this.pointerDownBlur()}this.dragX=this.x;this.viewport.classList.add("is-pointer-down");this.pointerDownScroll=o();n.addEventListener("scroll",this);this._pointerDownDefault(t,e)};s._pointerDownDefault=function(t,e){this.pointerDownPointer={pageX:e.pageX,pageY:e.pageY};this._bindPostStartEvents(t);this.dispatchEvent("pointerDown",t,[e])};var r={INPUT:true,TEXTAREA:true,SELECT:true};s.pointerDownFocus=function(t){var e=r[t.target.nodeName];if(!e){this.focus()}};s._pointerDownPreventDefault=function(t){var e=t.type=="touchstart";var i=t.pointerType=="touch";var n=r[t.target.nodeName];if(!e&&!i&&!n){t.preventDefault()}};s.hasDragStarted=function(t){return Math.abs(t.x)>this.options.dragThreshold};s.pointerUp=function(t,e){delete this.isTouchScrolling;this.viewport.classList.remove("is-pointer-down");this.dispatchEvent("pointerUp",t,[e]);this._dragPointerUp(t,e)};s.pointerDone=function(){n.removeEventListener("scroll",this);delete this.pointerDownScroll};s.dragStart=function(t,e){if(!this.isDraggable){return}this.dragStartPosition=this.x;this.startAnimation();n.removeEventListener("scroll",this);this.dispatchEvent("dragStart",t,[e])};s.pointerMove=function(t,e){var i=this._dragPointerMove(t,e);this.dispatchEvent("pointerMove",t,[e,i]);this._dragMove(t,e,i)};s.dragMove=function(t,e,i){if(!this.isDraggable){return}t.preventDefault();this.previousDragX=this.dragX;var n=this.options.rightToLeft?-1:1;if(this.options.wrapAround){i.x%=this.slideableWidth}var s=this.dragStartPosition+i.x*n;if(!this.options.wrapAround&&this.slides.length){var r=Math.max(-this.slides[0].target,this.dragStartPosition);s=s>r?(s+r)*.5:s;var o=Math.min(-this.getLastSlide().target,this.dragStartPosition);s=s<o?(s+o)*.5:s}this.dragX=s;this.dragMoveTime=new Date;this.dispatchEvent("dragMove",t,[e,i])};s.dragEnd=function(t,e){if(!this.isDraggable){return}if(this.options.freeScroll){this.isFreeScrolling=true}var i=this.dragEndRestingSelect();if(this.options.freeScroll&&!this.options.wrapAround){var n=this.getRestingPosition();this.isFreeScrolling=-n>this.slides[0].target&&-n<this.getLastSlide().target}else if(!this.options.freeScroll&&i==this.selectedIndex){i+=this.dragEndBoostSelect()}delete this.previousDragX;this.isDragSelect=this.options.wrapAround;this.select(i);delete this.isDragSelect;this.dispatchEvent("dragEnd",t,[e])};s.dragEndRestingSelect=function(){var t=this.getRestingPosition();var e=Math.abs(this.getSlideDistance(-t,this.selectedIndex));var i=this._getClosestResting(t,e,1);var n=this._getClosestResting(t,e,-1);var s=i.distance<n.distance?i.index:n.index;return s};
10475s._getClosestResting=function(t,e,i){var n=this.selectedIndex;var s=Infinity;var r=this.options.contain&&!this.options.wrapAround?function(t,e){return t<=e}:function(t,e){return t<e};while(r(e,s)){n+=i;s=e;e=this.getSlideDistance(-t,n);if(e===null){break}e=Math.abs(e)}return{distance:s,index:n-i}};s.getSlideDistance=function(t,e){var i=this.slides.length;var n=this.options.wrapAround&&i>1;var s=n?a.modulo(e,i):e;var r=this.slides[s];if(!r){return null}var o=n?this.slideableWidth*Math.floor(e/i):0;return t-(r.target+o)};s.dragEndBoostSelect=function(){if(this.previousDragX===undefined||!this.dragMoveTime||new Date-this.dragMoveTime>100){return 0}var t=this.getSlideDistance(-this.dragX,this.selectedIndex);var e=this.previousDragX-this.dragX;if(t>0&&e>0){return 1}else if(t<0&&e<0){return-1}return 0};s.staticClick=function(t,e){var i=this.getParentCell(t.target);var n=i&&i.element;var s=i&&this.cells.indexOf(i);this.dispatchEvent("staticClick",t,[e,n,s])};s.onscroll=function(){var t=o();var e=this.pointerDownScroll.x-t.x;var i=this.pointerDownScroll.y-t.y;if(Math.abs(e)>3||Math.abs(i)>3){this._pointerDone()}};function o(){return{x:n.pageXOffset,y:n.pageYOffset}}return e});(function(n,s){if(typeof define=="function"&&define.amd){define("flickity/js/prev-next-button",["./flickity","unipointer/unipointer","fizzy-ui-utils/utils"],function(t,e,i){return s(n,t,e,i)})}else if(typeof module=="object"&&module.exports){module.exports=s(n,require("./flickity"),require("unipointer"),require("fizzy-ui-utils"))}else{s(n,n.Flickity,n.Unipointer,n.fizzyUIUtils)}})(window,function t(e,i,n,s){"use strict";var r="http://www.w3.org/2000/svg";function o(t,e){this.direction=t;this.parent=e;this._create()}o.prototype=Object.create(n.prototype);o.prototype._create=function(){this.isEnabled=true;this.isPrevious=this.direction==-1;var t=this.parent.options.rightToLeft?1:-1;this.isLeft=this.direction==t;var e=this.element=document.createElement("button");e.className="flickity-button flickity-prev-next-button";e.className+=this.isPrevious?" previous":" next";e.setAttribute("type","button");this.disable();e.setAttribute("aria-label",this.isPrevious?"Previous":"Next");var i=this.createSVG();e.appendChild(i);this.parent.on("select",this.update.bind(this));this.on("pointerDown",this.parent.childUIPointerDown.bind(this.parent))};o.prototype.activate=function(){this.bindStartEvent(this.element);this.element.addEventListener("click",this);this.parent.element.appendChild(this.element)};o.prototype.deactivate=function(){this.parent.element.removeChild(this.element);this.unbindStartEvent(this.element);this.element.removeEventListener("click",this)};o.prototype.createSVG=function(){var t=document.createElementNS(r,"svg");t.setAttribute("class","flickity-button-icon");t.setAttribute("viewBox","0 0 100 100");var e=document.createElementNS(r,"path");var i=a(this.parent.options.arrowShape);e.setAttribute("d",i);e.setAttribute("class","arrow");if(!this.isLeft){e.setAttribute("transform","translate(100, 100) rotate(180) ")}t.appendChild(e);return t};function a(t){if(typeof t=="string"){return t}return"M "+t.x0+",50"+" L "+t.x1+","+(t.y1+50)+" L "+t.x2+","+(t.y2+50)+" L "+t.x3+",50 "+" L "+t.x2+","+(50-t.y2)+" L "+t.x1+","+(50-t.y1)+" Z"}o.prototype.handleEvent=s.handleEvent;o.prototype.onclick=function(){if(!this.isEnabled){return}this.parent.uiChange();var t=this.isPrevious?"previous":"next";this.parent[t]()};o.prototype.enable=function(){if(this.isEnabled){return}this.element.disabled=false;this.isEnabled=true};o.prototype.disable=function(){if(!this.isEnabled){return}this.element.disabled=true;this.isEnabled=false};o.prototype.update=function(){var t=this.parent.slides;if(this.parent.options.wrapAround&&t.length>1){this.enable();return}var e=t.length?t.length-1:0;var i=this.isPrevious?0:e;var n=this.parent.selectedIndex==i?"disable":"enable";this[n]()};o.prototype.destroy=function(){this.deactivate();this.allOff()};s.extend(i.defaults,{prevNextButtons:true,arrowShape:{x0:10,x1:60,y1:50,x2:70,y2:40,x3:30}});i.createMethods.push("_createPrevNextButtons");var l=i.prototype;l._createPrevNextButtons=function(){if(!this.options.prevNextButtons){return}this.prevButton=new o(-1,this);this.nextButton=new o(1,this);this.on("activate",this.activatePrevNextButtons)};l.activatePrevNextButtons=function(){this.prevButton.activate();this.nextButton.activate();this.on("deactivate",this.deactivatePrevNextButtons)};l.deactivatePrevNextButtons=function(){this.prevButton.deactivate();this.nextButton.deactivate();this.off("deactivate",this.deactivatePrevNextButtons)};i.PrevNextButton=o;return i});(function(n,s){if(typeof define=="function"&&define.amd){define("flickity/js/page-dots",["./flickity","unipointer/unipointer","fizzy-ui-utils/utils"],function(t,e,
10475i){return s(n,t,e,i)})}else if(typeof module=="object"&&module.exports){module.exports=s(n,require("./flickity"),require("unipointer"),require("fizzy-ui-utils"))}else{s(n,n.Flickity,n.Unipointer,n.fizzyUIUtils)}})(window,function t(e,i,n,s){function r(t){this.parent=t;this._create()}r.prototype=Object.create(n.prototype);r.prototype._create=function(){this.holder=document.createElement("ol");this.holder.className="flickity-page-dots";this.dots=[];this.handleClick=this.onClick.bind(this);this.on("pointerDown",this.parent.childUIPointerDown.bind(this.parent))};r.prototype.activate=function(){this.setDots();this.holder.addEventListener("click",this.handleClick);this.bindStartEvent(this.holder);this.parent.element.appendChild(this.holder)};r.prototype.deactivate=function(){this.holder.removeEventListener("click",this.handleClick);this.unbindStartEvent(this.holder);this.parent.element.removeChild(this.holder)};r.prototype.setDots=function(){var t=this.parent.slides.length-this.dots.length;if(t>0){this.addDots(t)}else if(t<0){this.removeDots(-t)}};r.prototype.addDots=function(t){var e=document.createDocumentFragment();var i=[];var n=this.dots.length;var s=n+t;for(var r=n;r<s;r++){var o=document.createElement("li");o.className="dot";o.setAttribute("aria-label","Page dot "+(r+1));e.appendChild(o);i.push(o)}this.holder.appendChild(e);this.dots=this.dots.concat(i)};r.prototype.removeDots=function(t){var e=this.dots.splice(this.dots.length-t,t);e.forEach(function(t){this.holder.removeChild(t)},this)};r.prototype.updateSelected=function(){if(this.selectedDot){this.selectedDot.className="dot";this.selectedDot.removeAttribute("aria-current")}if(!this.dots.length){return}this.selectedDot=this.dots[this.parent.selectedIndex];this.selectedDot.className="dot is-selected";this.selectedDot.setAttribute("aria-current","step")};r.prototype.onTap=r.prototype.onClick=function(t){var e=t.target;if(e.nodeName!="LI"){return}this.parent.uiChange();var i=this.dots.indexOf(e);this.parent.select(i)};r.prototype.destroy=function(){this.deactivate();this.allOff()};i.PageDots=r;s.extend(i.defaults,{pageDots:true});i.createMethods.push("_createPageDots");var o=i.prototype;o._createPageDots=function(){if(!this.options.pageDots){return}this.pageDots=new r(this);this.on("activate",this.activatePageDots);this.on("select",this.updateSelectedPageDots);this.on("cellChange",this.updatePageDots);this.on("resize",this.updatePageDots);this.on("deactivate",this.deactivatePageDots)};o.activatePageDots=function(){this.pageDots.activate()};o.updateSelectedPageDots=function(){this.pageDots.updateSelected()};o.updatePageDots=function(){this.pageDots.setDots()};o.deactivatePageDots=function(){this.pageDots.deactivate()};i.PageDots=r;return i});(function(t,n){if(typeof define=="function"&&define.amd){define("flickity/js/player",["ev-emitter/ev-emitter","fizzy-ui-utils/utils","./flickity"],function(t,e,i){return n(t,e,i)})}else if(typeof module=="object"&&module.exports){module.exports=n(require("ev-emitter"),require("fizzy-ui-utils"),require("./flickity"))}else{n(t.EvEmitter,t.fizzyUIUtils,t.Flickity)}})(window,function t(e,i,n){function s(t){this.parent=t;this.state="stopped";this.onVisibilityChange=this.visibilityChange.bind(this);this.onVisibilityPlay=this.visibilityPlay.bind(this)}s.prototype=Object.create(e.prototype);s.prototype.play=function(){if(this.state=="playing"){return}var t=document.hidden;if(t){document.addEventListener("visibilitychange",this.onVisibilityPlay);return}this.state="playing";document.addEventListener("visibilitychange",this.onVisibilityChange);this.tick()};s.prototype.tick=function(){if(this.state!="playing"){return}var t=this.parent.options.autoPlay;t=typeof t=="number"?t:3e3;var e=this;this.clear();this.timeout=setTimeout(function(){e.parent.next(true);e.tick()},t)};s.prototype.stop=function(){this.state="stopped";this.clear();document.removeEventListener("visibilitychange",this.onVisibilityChange)};s.prototype.clear=function(){clearTimeout(this.timeout)};s.prototype.pause=function(){if(this.state=="playing"){this.state="paused";this.clear()}};s.prototype.unpause=function(){if(this.state=="paused"){this.play()}};s.prototype.visibilityChange=function(){var t=document.hidden;this[t?"pause":"unpause"]()};s.prototype.visibilityPlay=function(){this.play();document.removeEventListener("visibilitychange",this.onVisibilityPlay)};i.extend(n.defaults,{pauseAutoPlayOnHover:true});n.createMethods.push("_createPlayer");var r=n.prototype;r._createPlayer=function(){this.player=new s(this);this.on("activate",this.activatePlayer);this.on("uiChange",this.stopPlayer);this.on("pointerDown",this.stopPlayer);this.on("deactivate",this.deactivatePlayer)};r.activatePlayer=function(){if(!this.options.autoPlay){return}this.player.play();this.element.addEventListener("mouseenter",this)};r.playPlayer=function(){this.player.play()};r.stopPlayer=function(){this.player.stop()};r.pausePlayer=function(){this.player.pause()};r.unpausePlayer=function(){this.player.unpause()};r.deactivatePlayer=function(){this.player.stop();this.element.removeEventListener("mouseenter",this)};r.onmouseenter=function(){if(!this.options.pauseAutoPlayOnHover){return}this.player.pause();this.element.addEventListener("mouseleave",this)};r.onmouseleave=function(){this.player.unpause();this.element.removeEventListener("mouseleave",this)};n.Player=s;return n});(function(i,n){if(typeof define=="function"&&define.amd){define("flickity/js/add-remove-cell",["./flickity","fizzy-ui-utils/utils"],function(t,e){return n(i,t,e)})}else if(typeof module=="object"&&module.exports){module.exports=n(i,require("./flickity"),require("fizzy-ui-utils"))}else{n(i,i.Flickity,i.fizzyUIUtils)}})(window,function t(e,i,n){function l(t){var e=document.createDocumentFragment();t.forEach(function(t){e.appendChild(t.element)});return e}var s=i.prototype;s.insert=function(t,e){var i=this._makeCells(t);if(!i||!i.length){return}var n=this.cells.length;e=e===undefined?n:e;var s=l(i);var r=e==n;if(r){this.slider.appendChild(s)}else{var o=this.cells[e].element;this.slider.insertBefore(s,o)}if(e===0){this.cells=i.concat(this.cells)}else if(r){this.cells=this.cells.concat(i)}else{var a=this.cells.splice(e,n-e);
10475this.cells=this.cells.concat(i).concat(a)}this._sizeCells(i);this.cellChange(e,true)};s.append=function(t){this.insert(t,this.cells.length)};s.prepend=function(t){this.insert(t,0)};s.remove=function(t){var e=this.getCells(t);if(!e||!e.length){return}var i=this.cells.length-1;e.forEach(function(t){t.remove();var e=this.cells.indexOf(t);i=Math.min(e,i);n.removeFrom(this.cells,t)},this);this.cellChange(i,true)};s.cellSizeChange=function(t){var e=this.getCell(t);if(!e){return}e.getSize();var i=this.cells.indexOf(e);this.cellChange(i)};s.cellChange=function(t,e){var i=this.selectedElement;this._positionCells(t);this._getWrapShiftCells();this.setGallerySize();var n=this.getCell(i);if(n){this.selectedIndex=this.getCellSlideIndex(n)}this.selectedIndex=Math.min(this.slides.length-1,this.selectedIndex);this.emitEvent("cellChange",[t]);this.select(this.selectedIndex);if(e){this.positionSliderAtSelected()}};return i});(function(i,n){if(typeof define=="function"&&define.amd){define("flickity/js/lazyload",["./flickity","fizzy-ui-utils/utils"],function(t,e){return n(i,t,e)})}else if(typeof module=="object"&&module.exports){module.exports=n(i,require("./flickity"),require("fizzy-ui-utils"))}else{n(i,i.Flickity,i.fizzyUIUtils)}})(window,function t(e,i,o){"use strict";i.createMethods.push("_createLazyload");var n=i.prototype;n._createLazyload=function(){this.on("select",this.lazyLoad)};n.lazyLoad=function(){var t=this.options.lazyLoad;if(!t){return}var e=typeof t=="number"?t:0;var i=this.getAdjacentCellElements(e);var n=[];i.forEach(function(t){var e=s(t);n=n.concat(e)});n.forEach(function(t){new r(t,this)},this)};function s(t){if(t.nodeName=="IMG"){var e=t.getAttribute("data-flickity-lazyload");var i=t.getAttribute("data-flickity-lazyload-src");var n=t.getAttribute("data-flickity-lazyload-srcset");if(e||i||n){return[t]}}var s="img[data-flickity-lazyload], "+"img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]";var r=t.querySelectorAll(s);return o.makeArray(r)}function r(t,e){this.img=t;this.flickity=e;this.load()}r.prototype.handleEvent=o.handleEvent;r.prototype.load=function(){this.img.addEventListener("load",this);this.img.addEventListener("error",this);var t=this.img.getAttribute("data-flickity-lazyload")||this.img.getAttribute("data-flickity-lazyload-src");var e=this.img.getAttribute("data-flickity-lazyload-srcset");this.img.src=t;if(e){this.img.setAttribute("srcset",e)}this.img.removeAttribute("data-flickity-lazyload");this.img.removeAttribute("data-flickity-lazyload-src");this.img.removeAttribute("data-flickity-lazyload-srcset")};r.prototype.onload=function(t){this.complete(t,"flickity-lazyloaded")};r.prototype.onerror=function(t){this.complete(t,"flickity-lazyerror")};r.prototype.complete=function(t,e){this.img.removeEventListener("load",this);this.img.removeEventListener("error",this);var i=this.flickity.getParentCell(this.img);var n=i&&i.element;this.flickity.cellSizeChange(n);this.img.classList.add(e);this.flickity.dispatchEvent("lazyLoad",t,n)};i.LazyLoader=r;return i}); 10476/*! 10477 * Flickity v2.3.0 10478 * Touch, responsive, flickable carousels 10479 * 10480 * Licensed GPLv3 for open source use 10481 * or Flickity Commercial License for commercial use 10482 * 10483 * https://flickity.metafizzy.co 10484 * Copyright 2015-2021 Metafizzy 10485 */ 10486(function(t,e){if(typeof define=="function"&&define.amd){define("flickity/js/index",["./flickity","./drag","./prev-next-button","./page-dots","./player","./add-remove-cell","./lazyload"],e)}else if(typeof module=="object"&&module.exports){module.exports=e(require("./flickity"),require("./drag"),require("./prev-next-button"),require("./page-dots"),require("./player"),require("./add-remove-cell"),require("./lazyload"))}})(window,function t(e){return e}); 10487/*! 10488 * Flickity asNavFor v2.0.2 10489 * enable asNavFor for Flickity 10490 */ 10491(function(t,e){if(typeof define=="function"&&define.amd){define("flickity-as-nav-for/as-nav-for",["flickity/js/index","fizzy-ui-utils/utils"],e)}else if(typeof module=="object"&&module.exports){module.exports=e(require("flickity"),require("fizzy-ui-utils"))}else{t.Flickity=e(t.Flickity,t.fizzyUIUtils)}})(window,function t(n,s){n.createMethods.push("_createAsNavFor");var e=n.prototype;e._createAsNavFor=function(){this.on("activate",this.activateAsNavFor);this.on("deactivate",this.deactivateAsNavFor);this.on("destroy",this.destroyAsNavFor);var e=this.options.asNavFor;if(!e){return}var i=this;setTimeout(function t(){i.setNavCompanion(e)})};e.setNavCompanion=function(t){t=s.getQueryElement(t);var e=n.data(t);
10491if(!e||e==this){return}this.navCompanion=e;var i=this;this.onNavCompanionSelect=function(){i.navCompanionSelect()};e.on("select",this.onNavCompanionSelect);this.on("staticClick",this.onNavStaticClick);this.navCompanionSelect(true)};e.navCompanionSelect=function(t){var e=this.navCompanion&&this.navCompanion.selectedCells;if(!e){return}var i=e[0];var n=this.navCompanion.cells.indexOf(i);var s=n+e.length-1;var r=Math.floor(a(n,s,this.navCompanion.cellAlign));this.selectCell(r,false,t);this.removeNavSelectedElements();if(r>=this.cells.length){return}var o=this.cells.slice(n,s+1);this.navSelectedElements=o.map(function(t){return t.element});this.changeNavSelectedClass("add")};function a(t,e,i){return(e-t)*i+t}e.changeNavSelectedClass=function(e){this.navSelectedElements.forEach(function(t){t.classList[e]("is-nav-selected")})};e.activateAsNavFor=function(){this.navCompanionSelect(true)};e.removeNavSelectedElements=function(){if(!this.navSelectedElements){return}this.changeNavSelectedClass("remove");delete this.navSelectedElements};e.onNavStaticClick=function(t,e,i,n){if(typeof n=="number"){this.navCompanion.selectCell(n)}};e.deactivateAsNavFor=function(){this.removeNavSelectedElements()};e.destroyAsNavFor=function(){if(!this.navCompanion){return}this.navCompanion.off("select",this.onNavCompanionSelect);this.off("staticClick",this.onNavStaticClick);delete this.navCompanion};return n}); 10492/*! 10493 * imagesLoaded v4.1.4 10494 * JavaScript is all like "You images are done yet or what?" 10495 * MIT License 10496 */ 10497(function(e,i){"use strict";if(typeof define=="function"&&define.amd){define("imagesloaded/imagesloaded",["ev-emitter/ev-emitter"],function(t){return i(e,t)})}else if(typeof module=="object"&&module.exports){module.exports=i(e,require("ev-emitter"))}else{e.imagesLoaded=i(e,e.EvEmitter)}})(typeof window!=="undefined"?window:this,function t(e,i){var s=e.jQuery;var r=e.console;function o(t,e){for(var i in e){t[i]=e[i]}return t}var n=Array.prototype.slice;function a(t){if(Array.isArray(t)){return t}var e=typeof t=="object"&&typeof t.length=="number";if(e){return n.call(t)}return[t]}function l(t,e,i){if(!(this instanceof l)){return new l(t,e,i)}var n=t;if(typeof t=="string"){n=document.querySelectorAll(t)}if(!n){r.error("Bad element for imagesLoaded "+(n||t));return}this.elements=a(n);this.options=o({},this.options);if(typeof e=="function"){i=e}else{o(this.options,e)}if(i){this.on("always",i)}this.getImages();if(s){this.jqDeferred=new s.Deferred}setTimeout(this.check.bind(this))}l.prototype=Object.create(i.prototype);l.prototype.options={};l.prototype.getImages=function(){this.images=[];this.elements.forEach(this.addElementImages,this)};l.prototype.addElementImages=function(t){if(t.nodeName=="IMG"){this.addImage(t)}if(this.options.background===true){this.addElementBackgroundImages(t)}var e=t.nodeType;if(!e||!h[e]){return}var i=t.querySelectorAll("img");for(var n=0;n<i.length;n++){var s=i[n];this.addImage(s)}if(typeof this.options.background=="string"){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var o=r[n];this.addElementBackgroundImages(o)}}};var h={1:true,9:true,11:true};l.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(!e){return}var i=/url\((['"])?(.*?)\1\)/gi;var n=i.exec(e.backgroundImage);while(n!==null){var s=n&&n[2];if(s){this.addBackground(s,t)}n=i.exec(e.backgroundImage)}};l.prototype.addImage=function(t){var e=new c(t);this.images.push(e)};l.prototype.addBackground=function(t,e){var i=new u(t,e);this.images.push(i)};l.prototype.check=function(){var n=this;this.progressedCount=0;this.hasAnyBroken=false;if(!this.images.length){this.complete();return}function e(t,e,i){setTimeout(function(){n.progress(t,e,i)})}this.images.forEach(function(t){t.once("progress",e);t.check()})};l.prototype.progress=function(t,e,i){this.progressedCount++;this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded;this.emitEvent("progress",[this,t,e]);if(this.jqDeferred&&this.jqDeferred.notify){this.jqDeferred.notify(this,t)}if(this.progressedCount==this.images.length){this.complete()}if(this.options.debug&&r){r.log("progress: "+i,t,e)}};l.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";this.isComplete=true;this.emitEvent(t,[this]);this.emitEvent("always",[this]);if(this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}};function c(t){this.img=t}c.prototype=Object.create(i.prototype);c.prototype.check=function(){var t=this.getIsImageComplete();
10497if(t){this.confirm(this.img.naturalWidth!==0,"naturalWidth");return}this.proxyImage=new Image;this.proxyImage.addEventListener("load",this);this.proxyImage.addEventListener("error",this);this.img.addEventListener("load",this);this.img.addEventListener("error",this);this.proxyImage.src=this.img.src};c.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth};c.prototype.confirm=function(t,e){this.isLoaded=t;this.emitEvent("progress",[this,this.img,e])};c.prototype.handleEvent=function(t){var e="on"+t.type;if(this[e]){this[e](t)}};c.prototype.onload=function(){this.confirm(true,"onload");this.unbindEvents()};c.prototype.onerror=function(){this.confirm(false,"onerror");this.unbindEvents()};c.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this);this.proxyImage.removeEventListener("error",this);this.img.removeEventListener("load",this);this.img.removeEventListener("error",this)};function u(t,e){this.url=t;this.element=e;this.img=new Image}u.prototype=Object.create(c.prototype);u.prototype.check=function(){this.img.addEventListener("load",this);this.img.addEventListener("error",this);this.img.src=this.url;var t=this.getIsImageComplete();if(t){this.confirm(this.img.naturalWidth!==0,"naturalWidth");this.unbindEvents()}};u.prototype.unbindEvents=function(){this.img.removeEventListener("load",this);this.img.removeEventListener("error",this)};u.prototype.confirm=function(t,e){this.isLoaded=t;this.emitEvent("progress",[this,this.element,e])};l.makeJQueryPlugin=function(t){t=t||e.jQuery;if(!t){return}s=t;s.fn.imagesLoaded=function(t,e){var i=new l(this,t,e);return i.jqDeferred.promise(s(this))}};l.makeJQueryPlugin();return l}); 10498/*! 10499 * Flickity imagesLoaded v2.0.0 10500 * enables imagesLoaded option for Flickity 10501 */ 10502(function(i,n){if(typeof define=="function"&&define.amd){define(["flickity/js/index","imagesloaded/imagesloaded"],function(t,e){return n(i,t,e)})}else if(typeof module=="object"&&module.exports){module.exports=n(i,require("flickity"),require("imagesloaded"))}else{i.Flickity=n(i,i.Flickity,i.imagesLoaded)}})(window,function t(e,i,s){"use strict";i.createMethods.push("_createImagesLoaded");var n=i.prototype;n._createImagesLoaded=function(){this.on("activate",this.imagesLoaded)};n.imagesLoaded=function(){if(!this.options.imagesLoaded){return}var n=this;function t(t,e){var i=n.getParentCell(e.img);n.cellSizeChange(i&&i.element);if(!n.options.freeScroll){n.positionSliderAtSelected()}}s(this.slider).on("progress",t)};return i}); 10503/** 10504 * Flickity fade v1.0.0 10505 * Fade between Flickity slides 10506 */ 10507 10508/* jshint browser: true, undef: true, unused: true */ 10509 10510( function( window, factory ) { 10511 // universal module definition 10512 /*globals define, module, require */ 10513 if ( typeof define == 'function' && define.amd ) { 10514 // AMD 10515 define( [ 10516 'flickity/js/index', 10517 'fizzy-ui-utils/utils', 10518 ], factory ); 10519 } else if ( typeof module == 'object' && module.exports ) { 10520 // CommonJS 10521 module.exports = factory( 10522 require('flickity'), 10523 require('fizzy-ui-utils') 10524 ); 10525 } else { 10526 // browser global 10527 factory( 10528 window.Flickity, 10529 window.fizzyUIUtils 10530 ); 10531 } 10532 10533}( this, function factory( Flickity, utils ) { 10534 10535// ---- Slide ---- // 10536 10537var Slide = Flickity.Slide; 10538 10539var slideUpdateTarget = Slide.prototype.updateTarget; 10540Slide.prototype.updateTarget = function() { 10541 slideUpdateTarget.apply( this, arguments ); 10542 if ( !this.parent.options.fade ) { 10543 return; 10544 } 10545 // position cells at selected target 10546 var slideTargetX = this.target - this.x; 10547 var firstCellX = this.cells[0].x; 10548 this.cells.forEach( function( cell ) { 10549 var targetX = cell.x - firstCellX - slideTargetX; 10550 cell.renderPosition( targetX ); 10551 }); 10552}; 10553 10554Slide.prototype.setOpacity = function( alpha ) { 10555 this.cells.forEach( function( cell ) { 10556 cell.element.style.opacity = alpha; 10557 }); 10558}; 10559 10560// ---- Flickity ---- // 10561 10562var proto = Flickity.prototype; 10563 10564Flickity.createMethods.push('_createFade'); 10565 10566proto._createFade = function() { 10567 this.fadeIndex = this.selectedIndex; 10568 this.prevSelectedIndex = this.selectedIndex; 10569 this.on( 'select', this.onSelectFade ); 10570 this.on( 'dragEnd', this.onDragEndFade ); 10571 this.on( 'settle', this.onSettleFade ); 10572 this.on( 'activate', this.onActivateFade ); 10573 this.on( 'deactivate', this.onDeactivateFade ); 10574}; 10575 10576var updateSlides = proto.updateSlides; 10577proto.updateSlides = function() { 10578 updateSlides.apply( this, arguments ); 10579 if ( !this.options.fade ) { 10580 return; 10581 } 10582 // set initial opacity
10583 this.slides.forEach( function( slide, i ) { 10584 var alpha = i == this.selectedIndex ? 1 : 0; 10585 slide.setOpacity( alpha ); 10586 }, this ); 10587}; 10588 10589/* ---- events ---- */ 10590 10591proto.onSelectFade = function() { 10592 // in case of resize, keep fadeIndex within current count 10593 this.fadeIndex = Math.min( this.prevSelectedIndex, this.slides.length - 1 ); 10594 this.prevSelectedIndex = this.selectedIndex; 10595}; 10596 10597proto.onSettleFade = function() { 10598 delete this.didDragEnd; 10599 if ( !this.options.fade ) { 10600 return; 10601 } 10602 // set full and 0 opacity on selected & faded slides 10603 this.selectedSlide.setOpacity( 1 ); 10604 var fadedSlide = this.slides[ this.fadeIndex ]; 10605 if ( fadedSlide && this.fadeIndex != this.selectedIndex ) { 10606 this.slides[ this.fadeIndex ].setOpacity( 0 ); 10607 } 10608}; 10609 10610proto.onDragEndFade = function() { 10611 // set flag 10612 this.didDragEnd = true; 10613}; 10614 10615proto.onActivateFade = function() { 10616 if ( this.options.fade ) { 10617 this.element.classList.add('is-fade'); 10618 } 10619}; 10620 10621proto.onDeactivateFade = function() { 10622 if ( !this.options.fade ) { 10623 return; 10624 } 10625 this.element.classList.remove('is-fade'); 10626 // reset opacity 10627 this.slides.forEach( function( slide ) { 10628 slide.setOpacity(''); 10629 }); 10630}; 10631 10632/* ---- position & fading ---- */ 10633 10634var positionSlider = proto.positionSlider; 10635proto.positionSlider = function() { 10636 if ( !this.options.fade ) { 10637 positionSlider.apply( this, arguments ); 10638 return; 10639 } 10640 10641 this.fadeSlides(); 10642 this.dispatchScrollEvent(); 10643}; 10644 10645var positionSliderAtSelected = proto.positionSliderAtSelected; 10646proto.positionSliderAtSelected = function() { 10647 if ( this.options.fade ) { 10648 // position fade slider at origin 10649 this.setTranslateX( 0 ); 10650 } 10651 positionSliderAtSelected.apply( this, arguments ); 10652}; 10653 10654proto.fadeSlides = function() { 10655 if ( this.slides.length < 2 ) { 10656 return; 10657 } 10658 // get slides to fade-in & fade-out 10659 var indexes = this.getFadeIndexes(); 10660 var fadeSlideA = this.slides[ indexes.a ]; 10661 var fadeSlideB = this.slides[ indexes.b ]; 10662 var distance = this.wrapDifference( fadeSlideA.target, fadeSlideB.target ); 10663 var progress = this.wrapDifference( fadeSlideA.target, -this.x ); 10664 progress = progress / distance; 10665 10666 fadeSlideA.setOpacity( 1 - progress ); 10667 fadeSlideB.setOpacity( progress ); 10668 10669 // hide previous slide 10670 var fadeHideIndex = indexes.a; 10671 if ( this.isDragging ) { 10672 fadeHideIndex = progress > 0.5 ? indexes.a : indexes.b; 10673 } 10674 var isNewHideIndex = this.fadeHideIndex != undefined && 10675 this.fadeHideIndex != fadeHideIndex && 10676 this.fadeHideIndex != indexes.a && 10677 this.fadeHideIndex != indexes.b; 10678 if ( isNewHideIndex ) { 10679 // new fadeHideSlide set, hide previous 10680 this.slides[ this.fadeHideIndex ].setOpacity( 0 ); 10681 } 10682 this.fadeHideIndex = fadeHideIndex; 10683}; 10684 10685proto.getFadeIndexes = function() { 10686 if ( !this.isDragging && !this.didDragEnd ) { 10687 return { 10688 a: this.fadeIndex, 10689 b: this.selectedIndex, 10690 }; 10691 } 10692 if ( this.options.wrapAround ) { 10693 return this.getFadeDragWrapIndexes(); 10694 } else { 10695 return this.getFadeDragLimitIndexes(); 10696 } 10697}; 10698 10699proto.getFadeDragWrapIndexes = function() { 10700 var distances = this.slides.map( function( slide, i ) { 10701 return this.getSlideDistance( -this.x, i ); 10702 }, this ); 10703 var absDistances = distances.map( function( distance ) { 10704 return Math.abs( distance ); 10705 }); 10706 var minDistance = Math.min.apply( Math, absDistances ); 10707 var closestIndex = absDistances.indexOf( minDistance ); 10708 var distance = distances[ closestIndex ]; 10709 var len = this.slides.length; 10710 10711 var delta = distance >= 0 ? 1 : -1; 10712 return { 10713 a: closestIndex, 10714 b: utils.modulo( closestIndex + delta, len ), 10715 }; 10716}; 10717 10718proto.getFadeDragLimitIndexes = function() { 10719 // calculate closest previous slide 10720 var dragIndex = 0; 10721 for ( var i=0; i < this.slides.length - 1; i++ ) { 10722 var slide = this.slides[i]; 10723 if ( -this.x < slide.target ) { 10724 break; 10725 } 10726 dragIndex = i; 10727 } 10728 return { 10729 a: dragIndex, 10730 b: dragIndex + 1, 10731 }; 10732}; 10733 10734proto.wrapDifference = function( a, b ) { 10735 var diff = b - a; 10736 10737 if ( !this.options.wrapAround ) { 10738 return diff; 10739 } 10740 10741 var diffPlus = diff + this.slideableWidth; 10742 var diffMinus = diff - this.slideableWidth; 10743 if ( Math.abs( diffPlus ) < Math.abs( diff ) ) { 10744 diff = diffPlus; 10745 } 10746 if ( Math.abs( diffMinus ) < Math.abs( diff ) ) { 10747 diff = diffMinus; 10748 } 10749 return diff; 10750}; 10751 10752// ---- wrapAround ---- // 10753 10754var _getWrapShiftCells = proto._getWrapShiftCells; 10755proto._getWrapShiftCells = function() { 10756 if ( !this.options.fade ) { 10757 _getWrapShiftCells.apply( this, arguments ); 10758 } 10759}; 10760 10761var shiftWrapCells = proto.shiftWrapCells; 10762proto.shiftWrapCells = function() { 10763 if ( !this.options.fade ) { 10764 shiftWrapCells.apply( this, arguments ); 10765 } 10766}; 10767 10768return Flickity; 10769 10770})); 10771/** 10772 * Character Counter v1.5.1 10773 * ====================== 10774 * 10775 * Character Counter is a simple, Twitter style character counter. 10776 * 10777 * https://github.com/dtisgodsson/jquery-character-counter 10778 * 10779 * @author Darren Taylor 10780 * @author Email: [email protected] 10781 * @author Twitter: darrentaytay 10782 * @author Website: http://darrenonthe.net 10783 *
10784 * Block property added by Sergio Cerrutti 10785 * https://github.com/sergiocerrutti/jquery-character-counter 10786 * 10787 */ 10788(function($) { 10789 10790 $.fn.characterCounter = function(opts){ 10791 10792 var defaults = { 10793 exceeded: false, 10794 counterSelector: false, 10795 limit: 150, 10796 block: false, 10797 renderTotal: false, 10798 counterWrapper: 'span', 10799 counterCssClass: 'counter', 10800 counterFormat: '%1', 10801 counterExceededCssClass: 'exceeded', 10802 increaseCounting: false, 10803 onExceed: function(count) {}, 10804 onDeceed: function(count) {}, 10805 customFields: {} 10806 }; 10807 10808 var options = $.extend(defaults, opts); 10809 10810 return this.each(function() { 10811 var html5len = $(this).attr('maxlength'); 10812 if (typeof html5len !== typeof undefined && html5len !== false) { 10813 $.extend(defaults, { 10814 limit: parseInt($(this).attr('maxlength')) 10815 }); 10816 } 10817 if (!options.counterSelector) { 10818 $(this).after(generateCounter()); 10819 } 10820 bindEvents(this); 10821 checkCount(this); 10822 }); 10823 10824 function customFields(params) 10825 { 10826 var i, html=''; 10827 10828 for (i in params) 10829 { 10830 html += ' ' + i + '="' + params[i] + '"'; 10831 } 10832 10833 return html; 10834 } 10835 10836 function generateCounter() 10837 { 10838 var classString = options.counterCssClass; 10839 10840 if ( options.customFields['class'] ) 10841 { 10842 classString += " " + options.customFields['class']; 10843 delete options.customFields['class']; 10844 } 10845 10846 return '<'+ options.counterWrapper +customFields(options.customFields)+' class="' + classString + '"></'+ options.counterWrapper +'>'; 10847 } 10848 10849 function renderText(count) 10850 { 10851 var rendered_count = options.counterFormat.replace(/%1/, count); 10852 10853 if ( options.renderTotal ) 10854 { 10855 rendered_count += '/'+ options.limit; 10856 } 10857 10858 return rendered_count; 10859 } 10860 10861 function checkCount(element) 10862 { 10863 var characterCount = $(element).val().length; 10864 var counter = options.counterSelector ? $(options.counterSelector) : $(element).nextAll("." + options.counterCssClass).first(); 10865 var remaining = options.limit - characterCount; 10866 var condition = remaining < 0; 10867 var conditionBlock = options.block && condition; 10868 10869 if ( conditionBlock ) 10870 { 10871 remaining = 0; 10872 $(element).val($(element).val().substr(0, options.limit)); 10873 } else { 10874 if ( options.increaseCounting ) 10875 { 10876 remaining = characterCount; 10877 condition = remaining > options.limit; 10878 } 10879 10880 if ( condition ) 10881 { 10882 counter.addClass(options.counterExceededCssClass); 10883 options.exceeded = true; 10884 options.onExceed(characterCount); 10885 } 10886 else 10887 { 10888 if ( options.exceeded ) { 10889 counter.removeClass(options.counterExceededCssClass); 10890 options.onDeceed(characterCount); 10891 options.exceeded = false; 10892 } 10893 } 10894 } 10895 10896 counter.html(renderText(remaining)); 10897 } 10898 10899 function bindEvents(element) 10900 { 10901 $(element) 10902 .on("input change", function () { 10903 checkCount(element); 10904 }); 10905 } 10906 }; 10907 10908})(jQuery); 10909/*! 10910 * Bootstrap Colorpicker 10911 * http://mjolnic.github.io/bootstrap-colorpicker/ 10912 * 10913 * Originally written by (c) 2012 Stefan Petre 10914 * Licensed under the Apache License v2.0 10915 * http://www.apache.org/licenses/LICENSE-2.0.txt 10916 * 10917 * @todo Update DOCS 10918 */ 10919 10920(function(factory) { 10921 "use strict"; 10922 if (typeof exports === 'object') { 10923 module.exports = factory(window.jQuery); 10924 } else if (typeof define === 'function' && define.amd) { 10925 define(['jquery'], factory); 10926 } else if (window.jQuery && !window.jQuery.fn.colorpicker) { 10927 factory(window.jQuery); 10928 } 10929 } 10930 (function($) { 10931 'use strict'; 10932 10933 // Color object 10934 var Color = function(val, customColors) { 10935 this.value = { 10936 h: 0, 10937 s: 0, 10938 b: 0, 10939 a: 1 10940 }; 10941 this.origFormat = null; // original string format 10942 if (customColors) { 10943 $.extend(this.colors, customColors); 10944 } 10945 if (val) { 10946 if (val.toLowerCase !== undefined) { 10947 // cast to string 10948 val = val + ''; 10949 this.setColor(val); 10950 } else if (val.h !== undefined) { 10951 this.value = val; 10952 } 10953 } 10954 }; 10955 10956 Color.prototype = { 10957 constructor: Color, 10958 // 140 predefined colors from the HTML Colors spec 10959 colors: { 10960 "aliceblue": "#f0f8ff", 10961 "antiquewhite": "#faebd7", 10962 "aqua": "#00ffff", 10963 "aquamarine": "#7fffd4", 10964 "azure": "#f0ffff", 10965 "beige": "#f5f5dc", 10966 "bisque": "#ffe4c4", 10967 "black": "#000000", 10968 "blanchedalmond": "#ffebcd", 10969 "blue": "#0000ff", 10970 "blueviolet": "#8a2be2", 10971 "brown": "#a52a2a", 10972 "burlywood": "#deb887", 10973 "cadetblue": "#5f9ea0", 10974 "chartreuse": "#7fff00", 10975 "chocolate": "#d2691e", 10976 "coral": "#ff7f50", 10977 "cornflowerblue": "#6495ed", 10978 "cornsilk": "#fff8dc", 10979 "crimson": "#dc143c", 10980 "cyan": "#00ffff", 10981 "darkblue": "#00008b", 10982 "darkcyan": "#008b8b", 10983 "darkgoldenrod": "#b8860b", 10984 "darkgray": "#a9a9a9", 10985 "darkgreen": "#006400", 10986 "darkkhaki": "#bdb76b", 10987 "darkmagenta": "#8b008b", 10988 "darkolivegreen": "#556b2f", 10989 "darkorange": "#ff8c00", 10990 "darkorchid": "#9932cc", 10991 "darkred": "#8b0000", 10992 "darksalmon": "#e9967a", 10993 "darkseagreen": "#8fbc8f", 10994 "darkslateblue": "#483d8b", 10995 "darkslategray": "#2f4f4f",
10996 "darkturquoise": "#00ced1", 10997 "darkviolet": "#9400d3", 10998 "deeppink": "#ff1493", 10999 "deepskyblue": "#00bfff", 11000 "dimgray": "#696969", 11001 "dodgerblue": "#1e90ff", 11002 "firebrick": "#b22222", 11003 "floralwhite": "#fffaf0", 11004 "forestgreen": "#228b22", 11005 "fuchsia": "#ff00ff", 11006 "gainsboro": "#dcdcdc", 11007 "ghostwhite": "#f8f8ff", 11008 "gold": "#ffd700", 11009 "goldenrod": "#daa520", 11010 "gray": "#808080", 11011 "green": "#008000", 11012 "greenyellow": "#adff2f", 11013 "honeydew": "#f0fff0", 11014 "hotpink": "#ff69b4", 11015 "indianred": "#cd5c5c", 11016 "indigo": "#4b0082", 11017 "ivory": "#fffff0", 11018 "khaki": "#f0e68c", 11019 "lavender": "#e6e6fa", 11020 "lavenderblush": "#fff0f5", 11021 "lawngreen": "#7cfc00", 11022 "lemonchiffon": "#fffacd", 11023 "lightblue": "#add8e6", 11024 "lightcoral": "#f08080", 11025 "lightcyan": "#e0ffff", 11026 "lightgoldenrodyellow": "#fafad2", 11027 "lightgrey": "#d3d3d3", 11028 "lightgreen": "#90ee90", 11029 "lightpink": "#ffb6c1", 11030 "lightsalmon": "#ffa07a", 11031 "lightseagreen": "#20b2aa", 11032 "lightskyblue": "#87cefa", 11033 "lightslategray": "#778899", 11034 "lightsteelblue": "#b0c4de", 11035 "lightyellow": "#ffffe0", 11036 "lime": "#00ff00", 11037 "limegreen": "#32cd32", 11038 "linen": "#faf0e6", 11039 "magenta": "#ff00ff", 11040 "maroon": "#800000", 11041 "mediumaquamarine": "#66cdaa", 11042 "mediumblue": "#0000cd", 11043 "mediumorchid": "#ba55d3", 11044 "mediumpurple": "#9370d8", 11045 "mediumseagreen": "#3cb371", 11046 "mediumslateblue": "#7b68ee", 11047 "mediumspringgreen": "#00fa9a", 11048 "mediumturquoise": "#48d1cc", 11049 "mediumvioletred": "#c71585", 11050 "midnightblue": "#191970", 11051 "mintcream": "#f5fffa", 11052 "mistyrose": "#ffe4e1", 11053 "moccasin": "#ffe4b5", 11054 "navajowhite": "#ffdead", 11055 "navy": "#000080", 11056 "oldlace": "#fdf5e6", 11057 "olive": "#808000", 11058 "olivedrab": "#6b8e23", 11059 "orange": "#ffa500", 11060 "orangered": "#ff4500", 11061 "orchid": "#da70d6", 11062 "palegoldenrod": "#eee8aa", 11063 "palegreen": "#98fb98", 11064 "paleturquoise": "#afeeee", 11065 "palevioletred": "#d87093", 11066 "papayawhip": "#ffefd5", 11067 "peachpuff": "#ffdab9", 11068 "peru": "#cd853f", 11069 "pink": "#ffc0cb", 11070 "plum": "#dda0dd", 11071 "powderblue": "#b0e0e6", 11072 "purple": "#800080", 11073 "red": "#ff0000", 11074 "rosybrown": "#bc8f8f", 11075 "royalblue": "#4169e1", 11076 "saddlebrown": "#8b4513", 11077 "salmon": "#fa8072", 11078 "sandybrown": "#f4a460", 11079 "seagreen": "#2e8b57", 11080 "seashell": "#fff5ee", 11081 "sienna": "#a0522d", 11082 "silver": "#c0c0c0", 11083 "skyblue": "#87ceeb", 11084 "slateblue": "#6a5acd", 11085 "slategray": "#708090", 11086 "snow": "#fffafa", 11087 "springgreen": "#00ff7f", 11088 "steelblue": "#4682b4", 11089 "tan": "#d2b48c", 11090 "teal": "#008080", 11091 "thistle": "#d8bfd8", 11092 "tomato": "#ff6347", 11093 "turquoise": "#40e0d0", 11094 "violet": "#ee82ee", 11095 "wheat": "#f5deb3", 11096 "white": "#ffffff", 11097 "whitesmoke": "#f5f5f5", 11098 "yellow": "#ffff00", 11099 "yellowgreen": "#9acd32", 11100 "transparent": "transparent" 11101 }, 11102 _sanitizeNumber: function(val) { 11103 if (typeof val === 'number') { 11104 return val; 11105 } 11106 if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) { 11107 return 1; 11108 } 11109 if (val.toLowerCase !== undefined) { 11110 return parseFloat(val); 11111 } 11112 return 1; 11113 }, 11114 isTransparent: function(strVal) { 11115 if (!strVal) { 11116 return false; 11117 } 11118 strVal = strVal.toLowerCase().trim(); 11119 return (strVal === 'transparent') || (strVal.match(/#?00000000/)) || (strVal.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/)); 11120 }, 11121 rgbaIsTransparent: function(rgba) { 11122 return ((rgba.r === 0) && (rgba.g === 0) && (rgba.b === 0) && (rgba.a === 0)); 11123 }, 11124 //parse a string to HSB 11125 setColor: function(strVal) { 11126 strVal = strVal.toLowerCase().trim(); 11127 if (strVal) {
11128 if (this.isTransparent(strVal)) { 11129 this.value = { 11130 h: 0, 11131 s: 0, 11132 b: 0, 11133 a: 0 11134 }; 11135 } else { 11136 this.value = this.stringToHSB(strVal) || { 11137 h: 0, 11138 s: 0, 11139 b: 0, 11140 a: 1 11141 }; // if parser fails, defaults to black 11142 } 11143 } 11144 }, 11145 stringToHSB: function(strVal) { 11146 strVal = strVal.toLowerCase(); 11147 var alias; 11148 if (typeof this.colors[strVal] !== 'undefined') { 11149 strVal = this.colors[strVal]; 11150 alias = 'alias'; 11151 } 11152 var that = this, 11153 result = false; 11154 $.each(this.stringParsers, function(i, parser) { 11155 var match = parser.re.exec(strVal), 11156 values = match && parser.parse.apply(that, [match]), 11157 format = alias || parser.format || 'rgba'; 11158 if (values) { 11159 if (format.match(/hsla?/)) { 11160 result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values)); 11161 } else { 11162 result = that.RGBtoHSB.apply(that, values); 11163 } 11164 that.origFormat = format; 11165 return false; 11166 } 11167 return true; 11168 }); 11169 return result; 11170 }, 11171 setHue: function(h) { 11172 this.value.h = 1 - h; 11173 }, 11174 setSaturation: function(s) { 11175 this.value.s = s; 11176 }, 11177 setBrightness: function(b) { 11178 this.value.b = 1 - b; 11179 }, 11180 setAlpha: function(a) { 11181 this.value.a = parseInt((1 - a) * 100, 10) / 100; 11182 }, 11183 toRGB: function(h, s, b, a) { 11184 if (!h) { 11185 h = this.value.h; 11186 s = this.value.s; 11187 b = this.value.b; 11188 } 11189 h *= 360; 11190 var R, G, B, X, C; 11191 h = (h % 360) / 60; 11192 C = b * s; 11193 X = C * (1 - Math.abs(h % 2 - 1)); 11194 R = G = B = b - C; 11195 11196 h = ~~h; 11197 R += [C, X, 0, 0, X, C][h]; 11198 G += [X, C, C, X, 0, 0][h]; 11199 B += [0, 0, X, C, C, X][h]; 11200 return { 11201 r: Math.round(R * 255), 11202 g: Math.round(G * 255), 11203 b: Math.round(B * 255), 11204 a: a || this.value.a 11205 }; 11206 }, 11207 toHex: function(h, s, b, a) { 11208 var rgb = this.toRGB(h, s, b, a); 11209 if (this.rgbaIsTransparent(rgb)) { 11210 return 'transparent'; 11211 } 11212 return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1); 11213 }, 11214 toHSL: function(h, s, b, a) { 11215 h = h || this.value.h; 11216 s = s || this.value.s; 11217 b = b || this.value.b; 11218 a = a || this.value.a; 11219 11220 var H = h, 11221 L = (2 - s) * b, 11222 S = s * b; 11223 if (L > 0 && L <= 1) { 11224 S /= L; 11225 } else { 11226 S /= 2 - L; 11227 } 11228 L /= 2; 11229 if (S > 1) { 11230 S = 1; 11231 } 11232 return { 11233 h: isNaN(H) ? 0 : H, 11234 s: isNaN(S) ? 0 : S, 11235 l: isNaN(L) ? 0 : L, 11236 a: isNaN(a) ? 0 : a 11237 }; 11238 }, 11239 toAlias: function(r, g, b, a) { 11240 var rgb = this.toHex(r, g, b, a); 11241 for (var alias in this.colors) { 11242 if (this.colors[alias] === rgb) { 11243 return alias; 11244 } 11245 } 11246 return false; 11247 }, 11248 RGBtoHSB: function(r, g, b, a) { 11249 r /= 255; 11250 g /= 255; 11251 b /= 255; 11252 11253 var H, S, V, C; 11254 V = Math.max(r, g, b); 11255 C = V - Math.min(r, g, b); 11256 H = (C === 0 ? null : 11257 V === r ? (g - b) / C : 11258 V === g ? (b - r) / C + 2 : 11259 (r - g) / C + 4 11260 ); 11261 H = ((H + 360) % 6) * 60 / 360; 11262 S = C === 0 ? 0 : C / V; 11263 return { 11264 h: this._sanitizeNumber(H), 11265 s: S, 11266 b: V, 11267 a: this._sanitizeNumber(a) 11268 }; 11269 }, 11270 HueToRGB: function(p, q, h) { 11271 if (h < 0) { 11272 h += 1; 11273 } else if (h > 1) { 11274 h -= 1; 11275 } 11276 if ((h * 6) < 1) { 11277 return p + (q - p) * h * 6; 11278 } else if ((h * 2) < 1) { 11279 return q; 11280 } else if ((h * 3) < 2) { 11281 return p + (q - p) * ((2 / 3) - h) * 6; 11282 } else { 11283 return p; 11284 } 11285 }, 11286 HSLtoRGB: function(h, s, l, a) { 11287 if (s < 0) { 11288 s = 0; 11289 } 11290 var q; 11291 if (l <= 0.5) { 11292 q = l * (1 + s); 11293 } else { 11294 q = l + s - (l * s); 11295 } 11296 11297 var p = 2 * l - q; 11298 11299 var tr = h + (1 / 3); 11300 var tg = h; 11301 var tb = h - (1 / 3); 11302
11303 var r = Math.round(this.HueToRGB(p, q, tr) * 255); 11304 var g = Math.round(this.HueToRGB(p, q, tg) * 255); 11305 var b = Math.round(this.HueToRGB(p, q, tb) * 255); 11306 return [r, g, b, this._sanitizeNumber(a)]; 11307 }, 11308 toString: function(format) { 11309 format = format || 'rgba'; 11310 var c = false; 11311 switch (format) { 11312 case 'rgb': 11313 { 11314 c = this.toRGB(); 11315 if (this.rgbaIsTransparent(c)) { 11316 return 'transparent'; 11317 } 11318 return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')'; 11319 } 11320 break; 11321 case 'rgba': 11322 { 11323 c = this.toRGB(); 11324 return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')'; 11325 } 11326 break; 11327 case 'hsl': 11328 { 11329 c = this.toHSL(); 11330 return 'hsl(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%)'; 11331 } 11332 break; 11333 case 'hsla': 11334 { 11335 c = this.toHSL(); 11336 return 'hsla(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%,' + c.a + ')'; 11337 } 11338 break; 11339 case 'hex': 11340 { 11341 return this.toHex(); 11342 } 11343 break; 11344 case 'alias': 11345 return this.toAlias() || this.toHex(); 11346 default: 11347 { 11348 return c; 11349 } 11350 break; 11351 } 11352 }, 11353 // a set of RE's that can match strings and generate color tuples. 11354 // from John Resig color plugin 11355 // https://github.com/jquery/jquery-color/
11356 stringParsers: [{ 11357 re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/, 11358 format: 'rgb', 11359 parse: function(execResult) { 11360 return [ 11361 execResult[1], 11362 execResult[2], 11363 execResult[3], 11364 1 11365 ]; 11366 } 11367 }, { 11368 re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, 11369 format: 'rgb', 11370 parse: function(execResult) { 11371 return [ 11372 2.55 * execResult[1], 11373 2.55 * execResult[2], 11374 2.55 * execResult[3], 11375 1 11376 ]; 11377 } 11378 }, { 11379 re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 11380 format: 'rgba', 11381 parse: function(execResult) { 11382 return [ 11383 execResult[1], 11384 execResult[2], 11385 execResult[3], 11386 execResult[4] 11387 ]; 11388 } 11389 }, { 11390 re: /rgba\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 11391 format: 'rgba', 11392 parse: function(execResult) { 11393 return [ 11394 2.55 * execResult[1], 11395 2.55 * execResult[2], 11396 2.55 * execResult[3], 11397 execResult[4] 11398 ]; 11399 } 11400 }, { 11401 re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, 11402 format: 'hsl', 11403 parse: function(execResult) { 11404 return [ 11405 execResult[1] / 360, 11406 execResult[2] / 100, 11407 execResult[3] / 100, 11408 execResult[4] 11409 ]; 11410 } 11411 }, { 11412 re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, 11413 format: 'hsla', 11414 parse: function(execResult) { 11415 return [ 11416 execResult[1] / 360, 11417 execResult[2] / 100, 11418 execResult[3] / 100, 11419 execResult[4] 11420 ]; 11421 } 11422 }, { 11423 re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, 11424 format: 'hex', 11425 parse: function(execResult) { 11426 return [ 11427 parseInt(execResult[1], 16), 11428 parseInt(execResult[2], 16), 11429 parseInt(execResult[3], 16), 11430 1 11431 ]; 11432 } 11433 }, { 11434 re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, 11435 format: 'hex', 11436 parse: function(execResult) { 11437 return [ 11438 parseInt(execResult[1] + execResult[1], 16), 11439 parseInt(execResult[2] + execResult[2], 16), 11440 parseInt(execResult[3] + execResult[3], 16), 11441 1 11442 ]; 11443 } 11444 }], 11445 colorNameToHex: function(name) { 11446 if (typeof this.colors[name.toLowerCase()] !== 'undefined') { 11447 return this.colors[name.toLowerCase()]; 11448 } 11449 return false; 11450 } 11451 }; 11452 11453 11454 var defaults = { 11455 horizontal: false, // horizontal mode layout ? 11456 inline: false, //forces to show the colorpicker as an inline element 11457 color: false, //forces a color 11458 format: false, //forces a format 11459 input: 'input', // children input selector 11460 container: false, // container selector 11461 component: '.add-on, .input-group-addon', // children component selector 11462 sliders: { 11463 saturation: { 11464 maxLeft: 100, 11465 maxTop: 100, 11466 callLeft: 'setSaturation', 11467 callTop: 'setBrightness' 11468 }, 11469 hue: { 11470 maxLeft: 0, 11471 maxTop: 100, 11472 callLeft: false, 11473 callTop: 'setHue' 11474 }, 11475 alpha: { 11476 maxLeft: 0, 11477 maxTop: 100, 11478 callLeft: false, 11479 callTop: 'setAlpha' 11480 } 11481 }, 11482 slidersHorz: { 11483 saturation: { 11484 maxLeft: 100, 11485 maxTop: 100, 11486 callLeft: 'setSaturation', 11487 callTop: 'setBrightness' 11488 }, 11489 hue: { 11490 maxLeft: 100, 11491 maxTop: 0, 11492 callLeft: 'setHue', 11493 callTop: false 11494 }, 11495 alpha: { 11496 maxLeft: 100, 11497 maxTop: 0, 11498 callLeft: 'setAlpha', 11499 callTop: false 11500 } 11501 }, 11502 template: '<div class="colorpicker dropdown-menu">' + 11503 '<div class="colorpicker-saturation"><i><b></b></i></div>' + 11504 '<div class="colorpicker-hue"><i></i></div>' + 11505 '<div class="colorpicker-alpha"><i></i></div>' + 11506 '<div class="colorpicker-color"><div /></div>' + 11507 '<div class="colorpicker-selectors"></div>' + 11508 '</div>', 11509 align: 'right', 11510 customClass: null, 11511 colorSelectors: null 11512 }; 11513 11514 var Colorpicker = function(element, options) { 11515 this.element = $(element).addClass('colorpicker-element'); 11516 this.options = $.extend(true, {}, defaults, this.element.data(), options); 11517 this.component = this.options.component; 11518 this.component = (this.component !== false) ? this.element.find(this.component) : false;
11519 if (this.component && (this.component.length === 0)) { 11520 this.component = false; 11521 } 11522 this.container = (this.options.container === true) ? this.element : this.options.container; 11523 this.container = (this.container !== false) ? $(this.container) : false; 11524 11525 // Is the element an input? Should we search inside for any input? 11526 this.input = this.element.is('input') ? this.element : (this.options.input ? 11527 this.element.find(this.options.input) : false); 11528 if (this.input && (this.input.length === 0)) { 11529 this.input = false; 11530 } 11531 // Set HSB color 11532 this.color = new Color(this.options.color !== false ? this.options.color : this.getValue(), this.options.colorSelectors); 11533 this.format = this.options.format !== false ? this.options.format : this.color.origFormat; 11534 11535 // Setup picker 11536 this.picker = $(this.options.template); 11537 if (this.options.customClass) { 11538 this.picker.addClass(this.options.customClass); 11539 } 11540 if (this.options.inline) { 11541 this.picker.addClass('colorpicker-inline colorpicker-visible'); 11542 } else { 11543 this.picker.addClass('colorpicker-hidden'); 11544 } 11545 if (this.options.horizontal) { 11546 this.picker.addClass('colorpicker-horizontal'); 11547 } 11548 if (this.format === 'rgba' || this.format === 'hsla' || this.options.format === false) { 11549 this.picker.addClass('colorpicker-with-alpha'); 11550 } 11551 if (this.options.align === 'right') { 11552 this.picker.addClass('colorpicker-right'); 11553 } 11554 if (this.options.colorSelectors) { 11555 var colorpicker = this; 11556 $.each(this.options.colorSelectors, function(name, color) { 11557 var $btn = $('<i />').css('background-color', color).data('class', name); 11558 $btn.click(function() { 11559 colorpicker.setValue($(this).css('background-color')); 11560 }); 11561 colorpicker.picker.find('.colorpicker-selectors').append($btn); 11562 }); 11563 this.picker.find('.colorpicker-selectors').show(); 11564 } 11565 this.picker.on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.mousedown, this)); 11566 this.picker.appendTo(this.container ? this.container : $('body')); 11567 11568 // Bind events 11569 if (this.input !== false) { 11570 this.input.on({ 11571 'keyup.colorpicker': $.proxy(this.keyup, this) 11572 }); 11573 this.input.on({ 11574 'change.colorpicker': $.proxy(this.change, this) 11575 }); 11576 if (this.component === false) { 11577 this.element.on({ 11578 'focus.colorpicker': $.proxy(this.show, this) 11579 }); 11580 } 11581 if (this.options.inline === false) { 11582 this.element.on({ 11583 'focusout.colorpicker': $.proxy(this.hide, this) 11584 }); 11585 } 11586 } 11587 11588 if (this.component !== false) { 11589 this.component.on({ 11590 'click.colorpicker': $.proxy(this.show, this) 11591 }); 11592 } 11593 11594 if ((this.input === false) && (this.component === false)) { 11595 this.element.on({ 11596 'click.colorpicker': $.proxy(this.show, this) 11597 }); 11598 } 11599 11600 // for HTML5 input[type='color'] 11601 if ((this.input !== false) && (this.component !== false) && (this.input.attr('type') === 'color')) { 11602 11603 this.input.on({ 11604 'click.colorpicker': $.proxy(this.show, this), 11605 'focus.colorpicker': $.proxy(this.show, this) 11606 }); 11607 } 11608 this.update(); 11609 11610 $($.proxy(function() { 11611 this.element.trigger('create'); 11612 }, this)); 11613 }; 11614 11615 Colorpicker.Color = Color; 11616 11617 Colorpicker.prototype = { 11618 constructor: Colorpicker, 11619 destroy: function() { 11620 this.picker.remove(); 11621 this.element.removeData('colorpicker').off('.colorpicker'); 11622 if (this.input !== false) { 11623 this.input.off('.colorpicker'); 11624 } 11625 if (this.component !== false) { 11626 this.component.off('.colorpicker'); 11627 } 11628 this.element.removeClass('colorpicker-element'); 11629 this.element.trigger({ 11630 type: 'destroy' 11631 }); 11632 }, 11633 reposition: function() { 11634 if (this.options.inline !== false || this.options.container) { 11635 return false;
11636 } 11637 var type = this.container && this.container[0] !== document.body ? 'position' : 'offset'; 11638 var element = this.component || this.element; 11639 var offset = element[type](); 11640 if (this.options.align === 'right') { 11641 offset.left -= this.picker.outerWidth() - element.outerWidth(); 11642 } 11643 this.picker.css({ 11644 top: offset.top + element.outerHeight(), 11645 left: offset.left 11646 }); 11647 }, 11648 show: function(e) { 11649 if (this.isDisabled()) { 11650 return false; 11651 } 11652 this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden'); 11653 this.reposition(); 11654 $(window).on('resize.colorpicker', $.proxy(this.reposition, this)); 11655 if (e && (!this.hasInput() || this.input.attr('type') === 'color')) { 11656 if (e.stopPropagation && e.preventDefault) { 11657 e.stopPropagation(); 11658 e.preventDefault(); 11659 } 11660 } 11661 if (this.options.inline === false) { 11662 $(window.document).on({ 11663 'mousedown.colorpicker': $.proxy(this.hide, this) 11664 }); 11665 } 11666 this.element.trigger({ 11667 type: 'showPicker', 11668 color: this.color 11669 }); 11670 }, 11671 hide: function() { 11672 this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible'); 11673 $(window).off('resize.colorpicker', this.reposition); 11674 $(document).off({ 11675 'mousedown.colorpicker': this.hide 11676 }); 11677 this.update(); 11678 this.element.trigger({ 11679 type: 'hidePicker', 11680 color: this.color 11681 }); 11682 }, 11683 updateData: function(val) { 11684 val = val || this.color.toString(this.format); 11685 this.element.data('color', val); 11686 return val; 11687 }, 11688 updateInput: function(val) { 11689 val = val || this.color.toString(this.format); 11690 if (this.input !== false) { 11691 if (this.options.colorSelectors) { 11692 var color = new Color(val, this.options.colorSelectors); 11693 var alias = color.toAlias(); 11694 if (typeof this.options.colorSelectors[alias] !== 'undefined') { 11695 val = alias; 11696 } 11697 } 11698 this.input.prop('value', val); 11699 } 11700 return val; 11701 }, 11702 updatePicker: function(val) { 11703 if (val !== undefined) { 11704 this.color = new Color(val, this.options.colorSelectors); 11705 } 11706 var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz; 11707 var icns = this.picker.find('i'); 11708 if (icns.length === 0) { 11709 return; 11710 } 11711 if (this.options.horizontal === false) { 11712 sl = this.options.sliders; 11713 icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end() 11714 .eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a)); 11715 } else { 11716 sl = this.options.slidersHorz; 11717 icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end() 11718 .eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a)); 11719 } 11720 icns.eq(0).css({ 11721 'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop, 11722 'left': this.color.value.s * sl.saturation.maxLeft 11723 }); 11724 this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1)); 11725 this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex()); 11726 this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format)); 11727 return val; 11728 }, 11729 updateComponent: function(val) { 11730 val = val || this.color.toString(this.format); 11731 if (this.component !== false) { 11732 var icn = this.component.find('i').eq(0); 11733 if (icn.length > 0) { 11734 icn.css({ 11735 'backgroundColor': val 11736 }); 11737 } else { 11738 this.component.css({ 11739 'backgroundColor': val 11740 }); 11741 } 11742 } 11743 return val; 11744 }, 11745 update: function(force) { 11746 var val; 11747 if ((this.getValue(false) !== false) || (force === true)) { 11748 // Update input/data only if the current value is not empty 11749 val = this.updateComponent(); 11750 this.updateInput(val); 11751 this.updateData(val); 11752 this.updatePicker(); // only update picker if value is not empty 11753 } 11754 return val; 11755 11756 }, 11757 setValue: function(val) { // set color manually 11758 this.color = new Color(val, this.options.colorSelectors); 11759 this.update(true); 11760 this.element.trigger({ 11761 type: 'changeColor', 11762 color: this.color, 11763 value: val 11764 }); 11765 }, 11766 getValue: function(defaultValue) { 11767 defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue; 11768 var val; 11769 if (this.hasInput()) { 11770 val = this.input.val(); 11771 } else { 11772 val = this.element.data('color'); 11773 } 11774 if ((val === undefined) || (val === '') || (val === null)) { 11775 // if not defined or empty, return default 11776 val = defaultValue; 11777 } 11778 return val; 11779 },
11780 hasInput: function() { 11781 return (this.input !== false); 11782 }, 11783 isDisabled: function() { 11784 if (this.hasInput()) { 11785 return (this.input.prop('disabled') === true); 11786 } 11787 return false; 11788 }, 11789 disable: function() { 11790 if (this.hasInput()) { 11791 this.input.prop('disabled', true); 11792 this.element.trigger({ 11793 type: 'disable', 11794 color: this.color, 11795 value: this.getValue() 11796 }); 11797 return true; 11798 } 11799 return false; 11800 }, 11801 enable: function() { 11802 if (this.hasInput()) { 11803 this.input.prop('disabled', false); 11804 this.element.trigger({ 11805 type: 'enable', 11806 color: this.color, 11807 value: this.getValue() 11808 }); 11809 return true; 11810 } 11811 return false; 11812 }, 11813 currentSlider: null, 11814 mousePointer: { 11815 left: 0, 11816 top: 0 11817 }, 11818 mousedown: function(e) { 11819 if (!e.pageX && !e.pageY && e.originalEvent) { 11820 e.pageX = e.originalEvent.touches[0].pageX; 11821 e.pageY = e.originalEvent.touches[0].pageY; 11822 } 11823 e.stopPropagation(); 11824 e.preventDefault(); 11825 11826 var target = $(e.target); 11827 11828 //detect the slider and set the limits and callbacks 11829 var zone = target.closest('div'); 11830 var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders; 11831 if (!zone.is('.colorpicker')) { 11832 if (zone.is('.colorpicker-saturation')) { 11833 this.currentSlider = $.extend({}, sl.saturation); 11834 } else if (zone.is('.colorpicker-hue')) { 11835 this.currentSlider = $.extend({}, sl.hue); 11836 } else if (zone.is('.colorpicker-alpha')) { 11837 this.currentSlider = $.extend({}, sl.alpha); 11838 } else { 11839 return false; 11840 } 11841 var offset = zone.offset(); 11842 //reference to guide's style 11843 this.currentSlider.guide = zone.find('i')[0].style; 11844 this.currentSlider.left = e.pageX - offset.left; 11845 this.currentSlider.top = e.pageY - offset.top; 11846 this.mousePointer = { 11847 left: e.pageX, 11848 top: e.pageY 11849 }; 11850 //trigger mousemove to move the guide to the current position 11851 $(document).on({ 11852 'mousemove.colorpicker': $.proxy(this.mousemove, this), 11853 'touchmove.colorpicker': $.proxy(this.mousemove, this), 11854 'mouseup.colorpicker': $.proxy(this.mouseup, this), 11855 'touchend.colorpicker': $.proxy(this.mouseup, this) 11856 }).trigger('mousemove'); 11857 } 11858 return false; 11859 }, 11860 mousemove: function(e) { 11861 if (!e.pageX && !e.pageY && e.originalEvent) { 11862 e.pageX = e.originalEvent.touches[0].pageX; 11863 e.pageY = e.originalEvent.touches[0].pageY; 11864 } 11865 e.stopPropagation(); 11866 e.preventDefault(); 11867 var left = Math.max( 11868 0, 11869 Math.min( 11870 this.currentSlider.maxLeft, 11871 this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left) 11872 ) 11873 ); 11874 var top = Math.max( 11875 0, 11876 Math.min( 11877 this.currentSlider.maxTop, 11878 this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top) 11879 ) 11880 ); 11881 this.currentSlider.guide.left = left + 'px'; 11882 this.currentSlider.guide.top = top + 'px'; 11883 if (this.currentSlider.callLeft) { 11884 this.color[this.currentSlider.callLeft].call(this.color, left / this.currentSlider.maxLeft); 11885 } 11886 if (this.currentSlider.callTop) { 11887 this.color[this.currentSlider.callTop].call(this.color, top / this.currentSlider.maxTop); 11888 } 11889 // Change format dynamically 11890 // Only occurs if user choose the dynamic format by 11891 // setting option format to false 11892 if (this.currentSlider.callTop === 'setAlpha' && this.options.format === false) { 11893 11894 // Converting from hex / rgb to rgba 11895 if (this.color.value.a !== 1) { 11896 this.format = 'rgba'; 11897 this.color.origFormat = 'rgba'; 11898 } 11899
11900 // Converting from rgba to hex 11901 else { 11902 this.format = 'hex'; 11903 this.color.origFormat = 'hex'; 11904 } 11905 } 11906 this.update(true); 11907 11908 this.element.trigger({ 11909 type: 'changeColor', 11910 color: this.color 11911 }); 11912 return false; 11913 }, 11914 mouseup: function(e) { 11915 e.stopPropagation(); 11916 e.preventDefault(); 11917 $(document).off({ 11918 'mousemove.colorpicker': this.mousemove, 11919 'touchmove.colorpicker': this.mousemove, 11920 'mouseup.colorpicker': this.mouseup, 11921 'touchend.colorpicker': this.mouseup 11922 }); 11923 return false; 11924 }, 11925 change: function(e) { 11926 this.keyup(e); 11927 }, 11928 keyup: function(e) { 11929 if ((e.keyCode === 38)) { 11930 if (this.color.value.a < 1) { 11931 this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100; 11932 } 11933 this.update(true); 11934 } else if ((e.keyCode === 40)) { 11935 if (this.color.value.a > 0) { 11936 this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100; 11937 } 11938 this.update(true); 11939 } else { 11940 this.color = new Color(this.input.val(), this.options.colorSelectors); 11941 // Change format dynamically 11942 // Only occurs if user choose the dynamic format by 11943 // setting option format to false 11944 if (this.color.origFormat && this.options.format === false) { 11945 this.format = this.color.origFormat; 11946 } 11947 if (this.getValue(false) !== false) { 11948 this.updateData(); 11949 this.updateComponent(); 11950 this.updatePicker(); 11951 } 11952 } 11953 this.element.trigger({ 11954 type: 'changeColor', 11955 color: this.color, 11956 value: this.input.val() 11957 }); 11958 } 11959 }; 11960 11961 $.colorpicker = Colorpicker; 11962 11963 $.fn.colorpicker = function(option) { 11964 var pickerArgs = arguments, 11965 rv; 11966 11967 var $returnValue = this.each(function() { 11968 var $this = $(this), 11969 inst = $this.data('colorpicker'), 11970 options = ((typeof option === 'object') ? option : {}); 11971 if ((!inst) && (typeof option !== 'string')) { 11972 $this.data('colorpicker', new Colorpicker(this, options)); 11973 } else { 11974 if (typeof option === 'string') { 11975 rv = inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1)); 11976 } 11977 } 11978 }); 11979 if (option === 'getValue') { 11980 return rv; 11981 } 11982 return $returnValue; 11983 }; 11984 11985 $.fn.colorpicker.constructor = Colorpicker; 11986 11987 })); 11988(function (factory) { 11989 11990 if (typeof define === 'function' && define.amd) { 11991 // AMD. Register as an anonymous module. 11992 define(['jquery'], factory); 11993 } else if (typeof exports === 'object') { 11994 // Node/CommonJS 11995 factory(require('jquery')); 11996 } else { 11997 // Browser globals 11998 factory(jQuery); 11999 } 12000 12001}(function ($, undef) { 12002 12003 var dataKey = 'plugin_hideShowPassword', 12004 shorthandArgs = ['show', 'innerToggle'], 12005 SPACE = 32, 12006 ENTER = 13; 12007 12008 var canSetInputAttribute = (function(){ 12009 var body = document.body, 12010 input = document.createElement('input'), 12011 result = true; 12012 if (! body) { 12013 body = document.createElement('body'); 12014 } 12015 input = body.appendChild(input); 12016 try { 12017 input.setAttribute('type', 'text'); 12018 } catch (e) { 12019 result = false;
12020 } 12021 body.removeChild(input); 12022 return result; 12023 }()); 12024 12025 var defaults = { 12026 // Visibility of the password text. Can be true, false, 'toggle' 12027 // or 'infer'. If 'toggle', it will be the opposite of whatever 12028 // it currently is. If 'infer', it will be based on the input 12029 // type (false if 'password', otherwise true). 12030 show: 'infer', 12031 12032 // Set to true to create an inner toggle for this input. Can 12033 // also be sent to an event name to delay visibility of toggle 12034 // until that event is triggered on the input element. 12035 innerToggle: false, 12036 12037 // If false, the plugin will be disabled entirely. Set to 12038 // the outcome of a test to insure input attributes can be 12039 // set after input has been inserted into the DOM. 12040 enable: canSetInputAttribute, 12041 12042 // Class to add to input element when the plugin is enabled. 12043 className: 'hideShowPassword-field', 12044 12045 // Event to trigger when the plugin is initialized and enabled. 12046 initEvent: 'hideShowPasswordInit', 12047 12048 // Event to trigger whenever the visibility changes. 12049 changeEvent: 'passwordVisibilityChange', 12050 12051 // Properties to add to the input element. 12052 props: { 12053 autocapitalize: 'off', 12054 autocomplete: 'off', 12055 autocorrect: 'off', 12056 spellcheck: 'false' 12057 }, 12058 12059 // Options specific to the inner toggle. 12060 toggle: { 12061 // The element to create. 12062 element: '<button type="button">', 12063 // Class name of element. 12064 className: 'hideShowPassword-toggle',
12065 // Whether or not to support touch-specific enhancements. 12066 // Defaults to the value of Modernizr.touch if available, 12067 // otherwise false. 12068 touchSupport: (typeof Modernizr === 'undefined') ? false : Modernizr.touch, 12069 // Non-touch event to bind to. 12070 attachToEvent: 'click.hideShowPassword', 12071 // Event to bind to when touchSupport is true. 12072 attachToTouchEvent: 'touchstart.hideShowPassword mousedown.hideShowPassword', 12073 // Key event to bind to if attachToKeyCodes is an array 12074 // of at least one keycode. 12075 attachToKeyEvent: 'keyup', 12076 // Key codes to bind the toggle event to for accessibility. 12077 // If false, this feature is disabled entirely. 12078 // If true, the array of key codes will be determined based 12079 // on the value of the element option. 12080 attachToKeyCodes: true, 12081 // Styles to add to the toggle element. Does not include 12082 // positioning styles. 12083 styles: { position: 'absolute' }, 12084 // Styles to add only when touchSupport is true. 12085 touchStyles: { pointerEvents: 'none' }, 12086 // Where to position the inner toggle relative to the 12087 // input element. Can be 'right', 'left' or 'infer'. If 12088 // 'infer', it will be based on the text-direction of the 12089 // input element. 12090 position: 'infer', 12091 // Where to position the inner toggle on the y-axis 12092 // relative to the input element. Can be 'top', 'bottom' 12093 // or 'middle'. 12094 verticalAlign: 'middle', 12095 // Amount by which to "offset" the toggle from the edge 12096 // of the input element. 12097 offset: 0, 12098 // Attributes to add to the toggle element. 12099 attr: { 12100 role: 'button', 12101 'aria-label': 'Show Password', 12102 tabIndex: 0 12103 } 12104 }, 12105 12106 // Options specific to the wrapper element, created 12107 // when the innerToggle is initialized to help with 12108 // positioning of that element. 12109 wrapper: { 12110 // The element to create. 12111 element: '<div>', 12112 // Class name of element. 12113 className: 'hideShowPassword-wrapper', 12114 // If true, the width of the wrapper will be set 12115 // unless it is already the same width as the inner 12116 // element. If false, the width will never be set. Any 12117 // other value will be used as the width. 12118 enforceWidth: true, 12119 // Styles to add to the wrapper element. Does not 12120 // include inherited styles or width if enforceWidth 12121 // is not false. 12122 styles: { position: 'relative' }, 12123 // Styles to "inherit" from the input element, allowing 12124 // the wrapper to avoid disrupting page styles. 12125 inheritStyles: [ 12126 'display', 12127 'verticalAlign', 12128 'marginTop', 12129 'marginRight', 12130 'marginBottom', 12131 'marginLeft' 12132 ], 12133 // Styles for the input element when wrapped. 12134 innerElementStyles: { 12135 marginTop: 0, 12136 marginRight: 0, 12137 marginBottom: 0, 12138 marginLeft: 0 12139 } 12140 }, 12141 12142 // Options specific to the 'shown' or 'hidden' 12143 // states of the input element. 12144 states: { 12145 shown: { 12146 className: 'hideShowPassword-shown', 12147 changeEvent: 'passwordShown', 12148 props: { type: 'text' }, 12149 toggle: { 12150 className: 'hideShowPassword-toggle-hide', 12151 content: 'Hide', 12152 attr: { 'aria-pressed': 'true' } 12153 } 12154 }, 12155 hidden: { 12156 className: 'hideShowPassword-hidden', 12157 changeEvent: 'passwordHidden', 12158 props: { type: 'password' }, 12159 toggle: { 12160 className: 'hideShowPassword-toggle-show', 12161 content: 'Show', 12162 attr: { 'aria-pressed': 'false' } 12163 } 12164 } 12165 } 12166 12167 }; 12168 12169 function HideShowPassword (element, options) { 12170 this.element = $(element); 12171 this.wrapperElement = $(); 12172 this.toggleElement = $(); 12173 this.init(options); 12174 } 12175 12176 HideShowPassword.prototype = { 12177 12178 init: function (options) { 12179 if (this.update(options, defaults)) { 12180 this.element.addClass(this.options.className); 12181 if (this.options.innerToggle) { 12182 this.wrapElement(this.options.wrapper); 12183 this.initToggle(this.options.toggle); 12184 if (typeof this.options.innerToggle === 'string') { 12185 this.toggleElement.hide(); 12186 this.element.one(this.options.innerToggle, $.proxy(function(){ 12187 this.toggleElement.show(); 12188 }, this)); 12189 } 12190 } 12191 this.element.trigger(this.options.initEvent, [ this ]); 12192 } 12193 }, 12194 12195 update: function (options, base) { 12196 this.options = this.prepareOptions(options, base); 12197 if (this.updateElement()) { 12198 this.element 12199 .trigger(this.options.changeEvent, [ this ]) 12200 .trigger(this.state().changeEvent, [ this ]); 12201 } 12202 return this.options.enable; 12203 }, 12204 12205 toggle: function (showVal) { 12206 showVal = showVal || 'toggle'; 12207 return this.update({ show: showVal }); 12208 }, 12209 12210 prepareOptions: function (options, base) { 12211 var original = options || {}, 12212 keyCodes = [], 12213 testElement; 12214 base = base || this.options; 12215 options = $.extend(true, {}, base, options); 12216 // Ugly conditional to resolve #34 in a backwards-compatible way (for now) 12217 if (original.hasOwnProperty('wrapper') && original.wrapper.hasOwnProperty('inheritStyles')) { 12218 options.wrapper.inheritStyles = original.wrapper.inheritStyles; 12219 } 12220 if (options.enable) { 12221 if (options.show === 'toggle') { 12222 options.show = this.isType('hidden', options.states); 12223 }
12223 else if (options.show === 'infer') { 12224 options.show = this.isType('shown', options.states); 12225 } 12226 if (options.toggle.position === 'infer') { 12227 options.toggle.position = (this.element.css('text-direction') === 'rtl') ? 'left' : 'right'; 12228 } 12229 if (! $.isArray(options.toggle.attachToKeyCodes)) { 12230 if (options.toggle.attachToKeyCodes === true) { 12231 testElement = $(options.toggle.element); 12232 switch(testElement.prop('tagName').toLowerCase()) { 12233 case 'button': 12234 case 'input': 12235 break; 12236 case 'a': 12237 if (testElement.filter('[href]').length) { 12238 keyCodes.push(SPACE); 12239 break; 12240 } 12241 default: 12242 keyCodes.push(SPACE, ENTER); 12243 break; 12244 } 12245 } 12246 options.toggle.attachToKeyCodes = keyCodes; 12247 } 12248 } 12249 return options; 12250 }, 12251 12252 updateElement: function () { 12253 if (! this.options.enable || this.isType()) return false; 12254 this.element 12255 .prop($.extend({}, this.options.props, this.state().props)) 12256 .addClass(this.state().className) 12257 .removeClass(this.otherState().className); 12258 this.updateToggle(); 12259 return true; 12260 }, 12261 12262 isType: function (comparison, states) { 12263 states = states || this.options.states; 12264 comparison = comparison || this.state(undef, undef, states).props.type; 12265 if (states[comparison]) { 12266 comparison = states[comparison].props.type; 12267 } 12268 return this.element.prop('type') === comparison; 12269 }, 12270 12271 state: function (key, invert, states) { 12272 states = states || this.options.states; 12273 if (key === undef) { 12274 key = this.options.show; 12275 } 12276 if (typeof key === 'boolean') { 12277 key = key ? 'shown' : 'hidden'; 12278 } 12279 if (invert) { 12280 key = (key === 'shown') ? 'hidden' : 'shown'; 12281 } 12282 return states[key]; 12283 }, 12284 12285 otherState: function (key) { 12286 return this.state(key, true); 12287 }, 12288 12289 wrapElement: function (options) { 12290 var enforceWidth = options.enforceWidth, 12291 targetWidth; 12292 if (! this.wrapperElement.length) { 12293 targetWidth = this.element.outerWidth(); 12294 $.each(options.inheritStyles, $.proxy(function (index, prop) { 12295 options.styles[prop] = this.element.css(prop); 12296 }, this)); 12297 this.element.css(options.innerElementStyles).wrap( 12298 $(options.element).addClass(options.className).css(options.styles) 12299 ); 12300 this.wrapperElement = this.element.parent(); 12301 if (enforceWidth === true) { 12302 enforceWidth = (this.wrapperElement.outerWidth() === targetWidth) ? false : targetWidth; 12303 } 12304 if (enforceWidth !== false) { 12305 this.wrapperElement.css('width', enforceWidth); 12306 } 12307 } 12308 return this.wrapperElement; 12309 }, 12310 12311 initToggle: function (options) { 12312 if (! this.toggleElement.length) { 12313 // Create element 12314 this.toggleElement = $(options.element) 12315 .attr(options.attr) 12316 .addClass(options.className) 12317 .css(options.styles) 12318 .appendTo(this.wrapperElement); 12319 // Update content/attributes 12320 this.updateToggle(); 12321 // Position 12322 this.positionToggle(options.position, options.verticalAlign, options.offset); 12323 // Events 12324 if (options.touchSupport) { 12325 this.toggleElement.css(options.touchStyles); 12326 this.element.on(options.attachToTouchEvent, $.proxy(this.toggleTouchEvent, this)); 12327 } else { 12328 this.toggleElement.on(options.attachToEvent, $.proxy(this.toggleEvent, this)); 12329 } 12330 if (options.attachToKeyCodes.length) { 12331 this.toggleElement.on(options.attachToKeyEvent, $.proxy(this.toggleKeyEvent, this)); 12332 } 12333 } 12334 return this.toggleElement; 12335 }, 12336 12337 positionToggle: function (position, verticalAlign, offset) { 12338 var styles = {}; 12339 styles[position] = offset; 12340 switch (verticalAlign) { 12341 case 'top': 12342 case 'bottom': 12343 styles[verticalAlign] = offset; 12344 break; 12345 case 'middle': 12346 styles.top = '50%'; 12347 styles.marginTop = this.toggleElement.outerHeight() / -2; 12348 break; 12349 } 12350 return this.toggleElement.css(styles); 12351 }, 12352 12353 updateToggle: function (state, otherState) { 12354 var paddingProp, 12355 targetPadding; 12356 if (this.toggleElement.length) { 12357 paddingProp = 'padding-' + this.options.toggle.position; 12358 state = state || this.state().toggle; 12359 otherState = otherState || this.otherState().toggle; 12360 this.toggleElement 12361 .attr(state.attr) 12362 .addClass(state.className) 12363 .removeClass(otherState.className) 12364 .html(state.content); 12365 targetPadding = this.toggleElement.outerWidth() + (this.options.toggle.offset * 2); 12366 if (this.element.css(paddingProp) !== targetPadding) { 12367 this.element.css(paddingProp, targetPadding); 12368 } 12369 } 12370 return this.toggleElement; 12371 }, 12372 12373 toggleEvent: function (event) { 12374 event.preventDefault(); 12375 this.toggle(); 12376 }, 12377 12378 toggleKeyEvent: function (event) { 12379 $.each(this.options.toggle.attachToKeyCodes, $.proxy(function(index, keyCode) { 12380 if (event.which === keyCode) { 12381 this.toggleEvent(event); 12382 return false;
12383 } 12384 }, this)); 12385 }, 12386 12387 toggleTouchEvent: function (event) { 12388 var toggleX = this.toggleElement.offset().left, 12389 eventX, 12390 lesser, 12391 greater; 12392 if (toggleX) { 12393 eventX = event.pageX || event.originalEvent.pageX; 12394 if (this.options.toggle.position === 'left') { 12395 toggleX+= this.toggleElement.outerWidth(); 12396 lesser = eventX; 12397 greater = toggleX; 12398 } else { 12399 lesser = toggleX; 12400 greater = eventX; 12401 } 12402 if (greater >= lesser) { 12403 this.toggleEvent(event); 12404 } 12405 } 12406 } 12407 12408 }; 12409 12410 $.fn.hideShowPassword = function () { 12411 var options = {}; 12412 $.each(arguments, function (index, value) { 12413 var newOptions = {}; 12414 if (typeof value === 'object') { 12415 newOptions = value; 12416 } else if (shorthandArgs[index]) { 12417 newOptions[shorthandArgs[index]] = value; 12418 } else { 12419 return false; 12420 } 12421 $.extend(true, options, newOptions); 12422 }); 12423 return this.each(function(){ 12424 var $this = $(this), 12425 data = $this.data(dataKey); 12426 if (data) { 12427 data.update(options); 12428 } else { 12429 $this.data(dataKey, new HideShowPassword(this, options)); 12430 } 12431 }); 12432 }; 12433 12434 $.each({ 'show':true, 'hide':false, 'toggle':'toggle' }, function (verb, showVal) { 12435 $.fn[verb + 'Password'] = function (innerToggle, options) { 12436 return this.hideShowPassword(showVal, innerToggle, options); 12437 }; 12438 }); 12439 12440})); 12441/*! Stellar.js v0.6.2 | Copyright 2014, Mark Dalgleish | http://markdalgleish.com/projects/stellar.js | http://markdalgleish.mit-license.org */ 12442!function(a,b,c,d){function e(b,c){this.element=b,this.options=a.extend({},g,c),this._defaults=g,this._name=f,this.init()}var f="stellar",g={scrollProperty:"scroll",positionProperty:"position",horizontalScrolling:!0,verticalScrolling:!0,horizontalOffset:0,verticalOffset:0,responsive:!1,parallaxBackgrounds:!0,parallaxElements:!0,hideDistantElements:!0,hideElement:function(a){a.hide()},showElement:function(a){a.show()}},h={scroll:{getLeft:function(a){return a.scrollLeft()},setLeft:function(a,b){a.scrollLeft(b)},getTop:function(a){return a.scrollTop()},setTop:function(a,b){a.scrollTop(b)}},position:{getLeft:function(a){return-1*parseInt(a.css("left"),10)},getTop:function(a){return-1*parseInt(a.css("top"),10)}},margin:{getLeft:function(a){return-1*parseInt(a.css("margin-left"),10)},getTop:function(a){return-1*parseInt(a.css("margin-top"),10)}},transform:{getLeft:function(a){var b=getComputedStyle(a[0])[k];return"none"!==b?-1*parseInt(b.match(/(-?[0-9]+)/g)[4],10):0},getTop:function(a){var b=getComputedStyle(a[0])[k];return"none"!==b?-1*parseInt(b.match(/(-?[0-9]+)/g)[5],10):0}}},i={position:{setLeft:function(a,b){a.css("left",b)},setTop:function(a,b){a.css("top",b)}},transform:{setPosition:function(a,b,c,d,e){a[0].style[k]="translate3d("+(b-c)+"px, "+(d-e)+"px, 0)"}}},j=function(){var b,c=/^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/,d=a("script")[0].style,e="";for(b in d)if(c.test(b)){e=b.match(c)[0];break}return"WebkitOpacity"in d&&(e="Webkit"),"KhtmlOpacity"in d&&(e="Khtml"),function(a){return e+(e.length>0?a.charAt(0).toUpperCase()+a.slice(1):a)}}(),k=j("transform"),l=a("<div />",{style:"background:#fff"}).css("background-position-x")!==d,m=l?function(a,b,c){a.css({"background-position-x":b,"background-position-y":c})}:function(a,b,c){a.css("background-position",b+" "+c)},n=l?function(a){return[a.css("background-position-x"),a.css("background-position-y")]}:function(a){return a.css("background-position").split(" ")},o=b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||b.oRequestAnimationFrame||b.msRequestAnimationFrame||function(a){setTimeout(a,1e3/60)};e.prototype={init:function(){this.options.name=f+"_"+Math.floor(1e9*Math.random()),this._defineElements(),this._defineGetters(),this._defineSetters(),this._handleWindowLoadAndResize(),this._detectViewport(),this.refresh({firstLoad:!0}),"scroll"===this.options.scrollProperty?this._handleScrollEvent():this._startAnimationLoop()},_defineElements:function(){this.element===c.body&&(this.element=b),this.$scrollElement=a(this.element),this.$element=this.element===b?a("body"):this.$scrollElement,this.$viewportElement=this.options.viewportElement!==d?a(this.options.viewportElement):this.$scrollElement[0]===b||"scroll"===this.options.scrollProperty?this.$scrollElement:this.$scrollElement.parent()},_defineGetters:function(){var a=this,b=h[a.options.scrollProperty];this._getScrollLeft=function(){return b.getLeft(a.$scrollElement)},this._getScrollTop=function(){return b.getTop(a.$scrollElement)}},_defineSetters:function(){var b=this,c=h[b.options.scrollProperty],d=i[b.options.positionProperty],e=c.setLeft,f=c.setTop;this._setScrollLeft="function"==typeof e?function(a){e(b.$scrollElement,a)}:a.noop,this._setScrollTop="function"==typeof f?function(a){f(b.$scrollElement,a)}:a.noop,this._setPosition=d.setPosition||function(a,c,e,f,g){b.options.horizontalScrolling&&d.setLeft(a,c,e),b.options.verticalScrolling&&d.setTop(a,f,g)}}
12442,_handleWindowLoadAndResize:function(){var c=this,d=a(b);c.options.responsive&&d.bind("load."+this.name,function(){c.refresh()}),d.bind("resize."+this.name,function(){c._detectViewport(),c.options.responsive&&c.refresh()})},refresh:function(c){var d=this,e=d._getScrollLeft(),f=d._getScrollTop();c&&c.firstLoad||this._reset(),this._setScrollLeft(0),this._setScrollTop(0),this._setOffsets(),this._findParticles(),this._findBackgrounds(),c&&c.firstLoad&&/WebKit/.test(navigator.userAgent)&&a(b).load(function(){var a=d._getScrollLeft(),b=d._getScrollTop();d._setScrollLeft(a+1),d._setScrollTop(b+1),d._setScrollLeft(a),d._setScrollTop(b)}),this._setScrollLeft(e),this._setScrollTop(f)},_detectViewport:function(){var a=this.$viewportElement.offset(),b=null!==a&&a!==d;this.viewportWidth=this.$viewportElement.width(),this.viewportHeight=this.$viewportElement.height(),this.viewportOffsetTop=b?a.top:0,this.viewportOffsetLeft=b?a.left:0},_findParticles:function(){{var b=this;this._getScrollLeft(),this._getScrollTop()}if(this.particles!==d)for(var c=this.particles.length-1;c>=0;c--)this.particles[c].$element.data("stellar-elementIsActive",d);this.particles=[],this.options.parallaxElements&&this.$element.find("[data-stellar-ratio]").each(function(){var c,e,f,g,h,i,j,k,l,m=a(this),n=0,o=0,p=0,q=0;if(m.data("stellar-elementIsActive")){if(m.data("stellar-elementIsActive")!==this)return}else m.data("stellar-elementIsActive",this);b.options.showElement(m),m.data("stellar-startingLeft")?(m.css("left",m.data("stellar-startingLeft")),m.css("top",m.data("stellar-startingTop"))):(m.data("stellar-startingLeft",m.css("left")),m.data("stellar-startingTop",m.css("top"))),f=m.position().left,g=m.position().top,h="auto"===m.css("margin-left")?0:parseInt(m.css("margin-left"),10),i="auto"===m.css("margin-top")?0:parseInt(m.css("margin-top"),10),k=m.offset().left-h,l=m.offset().top-i,m.parents().each(function(){var b=a(this);return b.data("stellar-offset-parent")===!0?(n=p,o=q,j=b,!1):(p+=b.position().left,void(q+=b.position().top))}),c=m.data("stellar-horizontal-offset")!==d?m.data("stellar-horizontal-offset"):j!==d&&j.data("stellar-horizontal-offset")!==d?j.data("stellar-horizontal-offset"):b.horizontalOffset,e=m.data("stellar-vertical-offset")!==d?m.data("stellar-vertical-offset"):j!==d&&j.data("stellar-vertical-offset")!==d?j.data("stellar-vertical-offset"):b.verticalOffset,b.particles.push({$element:m,$offsetParent:j,isFixed:"fixed"===m.css("position"),horizontalOffset:c,verticalOffset:e,startingPositionLeft:f,startingPositionTop:g,startingOffsetLeft:k,startingOffsetTop:l,parentOffsetLeft:n,parentOffsetTop:o,stellarRatio:m.data("stellar-ratio")!==d?m.data("stellar-ratio"):1,width:m.outerWidth(!0),height:m.outerHeight(!0),isHidden:!1})})},_findBackgrounds:function(){var b,c=this,e=this._getScrollLeft(),f=this._getScrollTop();this.backgrounds=[],this.options.parallaxBackgrounds&&(b=this.$element.find("[data-stellar-background-ratio]"),this.$element.data("stellar-background-ratio")&&(b=b.add(this.$element)),b.each(function(){var b,g,h,i,j,k,l,o=a(this),p=n(o),q=0,r=0,s=0,t=0;if(o.data("stellar-backgroundIsActive")){if(o.data("stellar-backgroundIsActive")!==this)return}else o.data("stellar-backgroundIsActive",this);o.data("stellar-backgroundStartingLeft")?m(o,o.data("stellar-backgroundStartingLeft"),o.data("stellar-backgroundStartingTop")):(o.data("stellar-backgroundStartingLeft",p[0]),o.data("stellar-backgroundStartingTop",p[1])),h="auto"===o.css("margin-left")?0:parseInt(o.css("margin-left"),10),i="auto"===o.css("margin-top")?0:parseInt(o.css("margin-top"),10),j=o.offset().left-h-e,k=o.offset().top-i-f,o.parents().each(function(){var b=a(this);return b.data("stellar-offset-parent")===!0?(q=s,r=t,l=b,!1):(s+=b.position().left,void(t+=b.position().top))}),b=o.data("stellar-horizontal-offset")!==d?o.data("stellar-horizontal-offset"):l!==d&&l.data("stellar-horizontal-offset")!==d?l.data("stellar-horizontal-offset"):c.horizontalOffset,g=o.data("stellar-vertical-offset")!==d?o.data("stellar-vertical-offset"):l!==d&&l.data("stellar-vertical-offset")!==d?l.data("stellar-vertical-offset"):c.verticalOffset,c.backgrounds.push({$element:o,$offsetParent:l,isFixed:"fixed"===o.css("background-attachment"),horizontalOffset:b,verticalOffset:g,startingValueLeft:p[0],startingValueTop:p[1],startingBackgroun
12442dPositionLeft:isNaN(parseInt(p[0],10))?0:parseInt(p[0],10),startingBackgroundPositionTop:isNaN(parseInt(p[1],10))?0:parseInt(p[1],10),startingPositionLeft:o.position().left,startingPositionTop:o.position().top,startingOffsetLeft:j,startingOffsetTop:k,parentOffsetLeft:q,parentOffsetTop:r,stellarRatio:o.data("stellar-background-ratio")===d?1:o.data("stellar-background-ratio")})}))},_reset:function(){var a,b,c,d,e;for(e=this.particles.length-1;e>=0;e--)a=this.particles[e],b=a.$element.data("stellar-startingLeft"),c=a.$element.data("stellar-startingTop"),this._setPosition(a.$element,b,b,c,c),this.options.showElement(a.$element),a.$element.data("stellar-startingLeft",null).data("stellar-elementIsActive",null).data("stellar-backgroundIsActive",null);for(e=this.backgrounds.length-1;e>=0;e--)d=this.backgrounds[e],d.$element.data("stellar-backgroundStartingLeft",null).data("stellar-backgroundStartingTop",null),m(d.$element,d.startingValueLeft,d.startingValueTop)},destroy:function(){this._reset(),this.$scrollElement.unbind("resize."+this.name).unbind("scroll."+this.name),this._animationLoop=a.noop,a(b).unbind("load."+this.name).unbind("resize."+this.name)},_setOffsets:function(){var c=this,d=a(b);d.unbind("resize.horizontal-"+this.name).unbind("resize.vertical-"+this.name),"function"==typeof this.options.horizontalOffset?(this.horizontalOffset=this.options.horizontalOffset(),d.bind("resize.horizontal-"+this.name,function(){c.horizontalOffset=c.options.horizontalOffset()})):this.horizontalOffset=this.options.horizontalOffset,"function"==typeof this.options.verticalOffset?(this.verticalOffset=this.options.verticalOffset(),d.bind("resize.vertical-"+this.name,function(){c.verticalOffset=c.options.verticalOffset()})):this.verticalOffset=this.options.verticalOffset},_repositionElements:function(){var a,b,c,d,e,f,g,h,i,j,k=this._getScrollLeft(),l=this._getScrollTop(),n=!0,o=!0;if(this.currentScrollLeft!==k||this.currentScrollTop!==l||this.currentWidth!==this.viewportWidth||this.currentHeight!==this.viewportHeight){for(this.currentScrollLeft=k,this.currentScrollTop=l,this.currentWidth=this.viewportWidth,this.currentHeight=this.viewportHeight,j=this.particles.length-1;j>=0;j--)a=this.particles[j],b=a.isFixed?1:0,this.options.horizontalScrolling?(f=(k+a.horizontalOffset+this.viewportOffsetLeft+a.startingPositionLeft-a.startingOffsetLeft+a.parentOffsetLeft)*-(a.stellarRatio+b-1)+a.startingPositionLeft,h=f-a.startingPositionLeft+a.startingOffsetLeft):(f=a.startingPositionLeft,h=a.startingOffsetLeft),this.options.verticalScrolling?(g=(l+a.verticalOffset+this.viewportOffsetTop+a.startingPositionTop-a.startingOffsetTop+a.parentOffsetTop)*-(a.stellarRatio+b-1)+a.startingPositionTop,i=g-a.startingPositionTop+a.startingOffsetTop):(g=a.startingPositionTop,i=a.startingOffsetTop),this.options.hideDistantElements&&(o=!this.options.horizontalScrolling||h+a.width>(a.isFixed?0:k)&&h<(a.isFixed?0:k)+this.viewportWidth+this.viewportOffsetLeft,n=!this.options.verticalScrolling||i+a.height>(a.isFixed?0:l)&&i<(a.isFixed?0:l)+this.viewportHeight+this.viewportOffsetTop),o&&n?(a.isHidden&&(this.options.showElement(a.$element),a.isHidden=!1),this._setPosition(a.$element,f,a.startingPositionLeft,g,a.startingPositionTop)):a.isHidden||(this.options.hideElement(a.$element),a.isHidden=!0);for(j=this.backgrounds.length-1;j>=0;j--)c=this.backgrounds[j],b=c.isFixed?0:1,d=this.options.horizontalScrolling?(k+c.horizontalOffset-this.viewportOffsetLeft-c.startingOffsetLeft+c.parentOffsetLeft-c.startingBackgroun
12442dPositionLeft)*(b-c.stellarRatio)+"px":c.startingValueLeft,e=this.options.verticalScrolling?(l+c.verticalOffset-this.viewportOffsetTop-c.startingOffsetTop+c.parentOffsetTop-c.startingBackgroundPositionTop)*(b-c.stellarRatio)+"px":c.startingValueTop,m(c.$element,d,e)}},_handleScrollEvent:function(){var a=this,b=!1,c=function(){a._repositionElements(),b=!1},d=function(){b||(o(c),b=!0)};this.$scrollElement.bind("scroll."+this.name,d),d()},_startAnimationLoop:function(){var a=this;this._animationLoop=function(){o(a._animationLoop),a._repositionElements()},this._animationLoop()}},a.fn[f]=function(b){var c=arguments;return b===d||"object"==typeof b?this.each(function(){a.data(this,"plugin_"+f)||a.data(this,"plugin_"+f,new e(this,b))}):"string"==typeof b&&"_"!==b[0]&&"init"!==b?this.each(function(){var d=a.data(this,"plugin_"+f);d instanceof e&&"function"==typeof d[b]&&d[b].apply(d,Array.prototype.slice.call(c,1)),"destroy"===b&&a.data(this,"plugin_"+f,null)}):void 0},a[f]=function(){var c=a(b);return c.stellar.apply(c,Array.prototype.slice.call(arguments,0))},a[f].scrollProperty=h,a[f].positionProperty=i,b.Stellar=e}(jQuery,this,document); 12443/*! 12444 * clipboard.js v1.6.1 12445 * https://zenorocha.github.io/clipboard.js 12446 * 12447 * Licensed MIT © Zeno Rocha 12448 */ 12449!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Clipboard=e()}}(function(){var e,t,n;return function e(t,n,o){function i(a,c){if(!n[a]){if(!t[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var s=n[a]={exports:{}};t[a][0].call(s.exports,function(e){var n=t[a][1][e];return i(n?n:e)},s,s.exports,e,t,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(e,t,n){function o(e,t){for(;e&&e.nodeType!==i;){if(e.matches(t))return e;e=e.parentNode}}var i=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}t.exports=o},{}],2:[function(e,t,n){function o(e,t,n,o,r){var a=i.apply(this,arguments);return e.addEventListener(n,a,r),{destroy:function(){e.removeEventListener(n,a,r)}}}function i(e,t,n,o){return function(n){n.delegateTarget=r(n.target,t),n.delegateTarget&&o.call(e,n)}}var r=e("./closest");t.exports=o},{"./closest":1}],3:[function(e,t,n){n.node=function(e){return void 0!==e&&e instanceof HTMLElement&&1===e.nodeType},n.nodeList=function(e){var t=Object.prototype.toString.call(e);return void 0!==e&&("[object NodeList]"===t||"[object HTMLCollection]"===t)&&"length"in e&&(0===e.length||n.node(e[0]))},n.string=function(e){return"string"==typeof e||e instanceof String},n.fn=function(e){var t=Object.prototype.toString.call(e);return"[object Function]"===t}},{}],4:[function(e,t,n){function o(e,t,n){if(!e&&!t&&!n)throw new Error("Missing required arguments");if(!c.string(t))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(e))return i(e,t,n);if(c.nodeList(e))return r(e,t,n);if(c.string(e))return a(e,t,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(e,t,n){return e.addEventListener(t,n),{destroy:function(){e.removeEventListener(t,n)}}}function r(e,t,n){return Array.prototype.forEach.call(e,function(e){e.addEventListener(t,n)}),{destroy:function(){Array.prototype.forEach.call(e,function(e){e.removeEventListener(t,n)})}}}function a(e,t,n){return l(document.body,e,t,n)}var c=e("./is"),l=e("delegate");t.exports=o},{"./is":3,delegate:2}],5:[function(e,t,n){function o(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var o=window.getSelection(),i=document.createRange();i.selectNodeContents(e),o.removeAllRanges(),o.addRange(i),t=o.toString()}return t}t.exports=o},{}],6:[function(e,t,n){function o(){}o.prototype={on:function(e,t,n){var o=this.e||(this.e={});return(o[e]||(o[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){function o(){i.off(e,o),t.apply(n,arguments)}var i=this;return o._=t,this.on(e,o,n)}
12449,emit:function(e){var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),o=0,i=n.length;for(o;o<i;o++)n[o].fn.apply(n[o].ctx,t);return this},off:function(e,t){var n=this.e||(this.e={}),o=n[e],i=[];if(o&&t)for(var r=0,a=o.length;r<a;r++)o[r].fn!==t&&o[r].fn._!==t&&i.push(o[r]);return i.length?n[e]=i:delete n[e],this}},t.exports=o},{}],7:[function(t,n,o){!function(i,r){if("function"==typeof e&&e.amd)e(["module","select"],r);else if("undefined"!=typeof o)r(n,t("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(e,t){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(t),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),c=function(){function e(t){o(this,e),this.resolveOptions(t),this.initSelection()}return a(e,[{key:"resolveOptions",value:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function e(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function e(){var t=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function e(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function e(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:"copyText",value:function e(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function e(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function e(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function e(){this.removeFake()}},{key:"action",set:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function e(){return this._action}},{key:"target",set:function e(t){if(void 0!==t){if(!t||"object"!==("undefined"==typeof t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function e(){return this._target}}]),e}();e.exports=c})},{select:5}],8:[function(t,n,o){!function(i,r){if("function"==typeof e&&e.amd)e(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof o)r(n,t("./clipboard-action"),t("tiny-emitter"),t("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(e,t,n,o){"use strict";
12449function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function c(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}var u=i(t),s=i(n),f=i(o),d=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),h=function(e){function t(e,n){r(this,t);var o=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return o.resolveOptions(n),o.listenClick(e),o}return c(t,e),d(t,[{key:"resolveOptions",value:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText}},{key:"listenClick",value:function e(t){var n=this;this.listener=(0,f.default)(t,"click",function(e){return n.onClick(e)})}},{key:"onClick",value:function e(t){var n=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new u.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})}},{key:"defaultAction",value:function e(t){return l("action",t)}},{key:"defaultTarget",value:function e(t){var n=l("target",t);if(n)return document.querySelector(n)}},{key:"defaultText",value:function e(t){return l("text",t)}},{key:"destroy",value:function e(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],n="string"==typeof t?[t]:t,o=!!document.queryCommandSupported;return n.forEach(function(e){o=o&&!!document.queryCommandSupported(e)}),o}}]),t}(s.default);e.exports=h})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)}); 12450 12451/* 12452 * 12453 * More info at [www.dropzonejs.com](http://www.dropzonejs.com) 12454 * 12455 * Copyright (c) 2012, Matias Meno 12456 * 12457 * Permission is hereby granted, free of charge, to any person obtaining a copy 12458 * of this software and associated documentation files (the "Software"), to deal 12459 * in the Software without restriction, including without limitation the rights 12460 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12461 * copies of the Software, and to permit persons to whom the Software is 12462 * furnished to do so, subject to the following conditions: 12463 * 12464 * The above copyright notice and this permission notice shall be included in 12465 * all copies or substantial portions of the Software. 12466 * 12467 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12468 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12469 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 12470 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 12471 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12472 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 12473 * THE SOFTWARE. 12474 * 12475 */ 12476 12477(function() { 12478 var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without, 12479 __slice = [].slice, 12480 __hasProp = {}.hasOwnProperty, 12481 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 12482 12483 noop = function() {}; 12484 12485 Emitter = (function() { 12486 function Emitter() {} 12487 12488 Emitter.prototype.addEventListener = Emitter.prototype.on; 12489 12490 Emitter.prototype.on = function(event, fn) { 12491 this._callbacks = this._callbacks || {}; 12492 if (!this._callbacks[event]) { 12493 this._callbacks[event] = []; 12494 } 12495 this._callbacks[event].push(fn); 12496 return this; 12497 }; 12498 12499 Emitter.prototype.emit = function() { 12500 var args, callback, callbacks, event, _i, _len; 12501 event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 12502 this._callbacks = this._callbacks || {}; 12503 callbacks = this._callbacks[event]; 12504 if (callbacks) { 12505 for (_i = 0, _len = callbacks.length; _i < _len; _i++) { 12506 callback = callbacks[_i]; 12507 callback.apply(this, args); 12508 } 12509 } 12510 return this; 12511 }; 12512 12513 Emitter.prototype.removeListener = Emitter.prototype.off; 12514 12515 Emitter.prototype.removeAllListeners = Emitter.prototype.off; 12516 12517 Emitter.prototype.removeEventListener = Emitter.prototype.off; 12518 12519 Emitter.prototype.off = function(event, fn) { 12520 var callback, callbacks, i, _i, _len; 12521 if (!this._callbacks || arguments.length === 0) { 12522 this._callbacks = {}; 12523 return this; 12524 } 12525 callbacks = this._callbacks[event]; 12526 if (!callbacks) { 12527 return this; 12528 } 12529 if (arguments.length === 1) { 12530 delete this._callbacks[event]; 12531 return this; 12532 } 12533 for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) { 12534 callback = callbacks[i]; 12535 if (callback === fn) { 12536 callbacks.splice(i, 1); 12537 break; 12538 } 12539 } 12540 return this; 12541 }; 12542 12543 return Emitter; 12544 12545 })(); 12546 12547 Dropzone = (function(_super) { 12548 var extend, resolveOption; 12549 12550 __extends(Dropzone, _super); 12551 12552 Dropzone.prototype.Emitter = Emitter; 12553 12554 12555 /* 12556 This is a list of all available events you can register on a dropzone object. 12557 12558 You can register an event handler like this: 12559 12560 dropzone.on("dragEnter", function() { }); 12561 */ 12562 12563 Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"]; 12564 12565 Dropzone.prototype.defaultOptions = { 12566 url: null, 12567 method: "post", 12568 withCredentials: false, 12569 parallelUploads: 2, 12570 uploadMultiple: false, 12571 maxFilesize: 256, 12572 paramName: "file", 12573 createImageThumbnails: true, 12574 maxThumbnailFilesize: 10, 12575 thumbnailWidth: 120, 12576 thumbnailHeight: 120, 12577 filesizeBase: 1000, 12578 maxFiles: null, 12579 params: {}, 12580 clickable: true, 12581 ignoreHiddenFiles: true, 12582 acceptedFiles: null, 12583 acceptedMimeTypes: null, 12584 autoProcessQueue: true, 12585 autoQueue: true, 12586 addRemoveLinks: false, 12587 previewsContainer: null, 12588 hiddenInputContainer: "body", 12589 capture: null, 12590 renameFilename: null, 12591 dictDefaultMessage: "Drop files here to upload", 12592 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", 12593 dictFallbackText: "Please use the fallback form below to upload your files like in the olde
12593n days.", 12594 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.", 12595 dictInvalidFileType: "You can't upload files of this type.", 12596 dictResponseError: "Server responded with {{statusCode}} code.", 12597 dictCancelUpload: "Cancel upload", 12598 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", 12599 dictRemoveFile: "Remove file", 12600 dictRemoveFileConfirmation: null, 12601 dictMaxFilesExceeded: "You can not upload any more files.", 12602 accept: function(file, done) { 12603 return done(); 12604 }, 12605 init: function() { 12606 return noop; 12607 }, 12608 forceFallback: false, 12609 fallback: function() { 12610 var child, messageElement, span, _i, _len, _ref; 12611 this.element.className = "" + this.element.className + " dz-browser-not-supported"; 12612 _ref = this.element.getElementsByTagName("div"); 12613 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12614 child = _ref[_i]; 12615 if (/(^| )dz-message($| )/.test(child.className)) { 12616 messageElement = child; 12617 child.className = "dz-message"; 12618 continue; 12619 } 12620 } 12621 if (!messageElement) { 12622 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>"); 12623 this.element.appendChild(messageElement); 12624 } 12625 span = messageElement.getElementsByTagName("span")[0]; 12626 if (span) { 12627 if (span.textContent != null) { 12628 span.textContent = this.options.dictFallbackMessage; 12629 } else if (span.innerText != null) { 12630 span.innerText = this.options.dictFallbackMessage; 12631 } 12632 } 12633 return this.element.appendChild(this.getFallbackForm()); 12634 }, 12635 resize: function(file) { 12636 var info, srcRatio, trgRatio; 12637 info = { 12638 srcX: 0, 12639 srcY: 0, 12640 srcWidth: file.width, 12641 srcHeight: file.height 12642 }; 12643 srcRatio = file.width / file.height; 12644 info.optWidth = this.options.thumbnailWidth; 12645 info.optHeight = this.options.thumbnailHeight; 12646 if ((info.optWidth == null) && (info.optHeight == null)) { 12647 info.optWidth = info.srcWidth; 12648 info.optHeight = info.srcHeight; 12649 } else if (info.optWidth == null) { 12650 info.optWidth = srcRatio * info.optHeight; 12651 } else if (info.optHeight == null) { 12652 info.optHeight = (1 / srcRatio) * info.optWidth; 12653 } 12654 trgRatio = info.optWidth / info.optHeight; 12655 if (file.height < info.optHeight || file.width < info.optWidth) { 12656 info.trgHeight = info.srcHeight; 12657 info.trgWidth = info.srcWidth; 12658 } else { 12659 if (srcRatio > trgRatio) { 12660 info.srcHeight = file.height; 12661 info.srcWidth = info.srcHeight * trgRatio; 12662 } else { 12663 info.srcWidth = file.width; 12664 info.srcHeight = info.srcWidth / trgRatio; 12665 } 12666 } 12667 info.srcX = (file.width - info.srcWidth) / 2; 12668 info.srcY = (file.height - info.srcHeight) / 2; 12669 return info; 12670 }, 12671 12672 /* 12673 Those functions register themselves to the events on init and handle all 12674 the user interface specific stuff. Overwriting them won't break the upload 12675 but can break the way it's displayed. 12676 You can overwrite them if you don't like the default behavior. If you just 12677 want to add an additional event handler, register it on the dropzone object 12678 and don't overwrite those options. 12679 */ 12680 drop: function(e) { 12681 return this.element.classList.remove("dz-drag-hover"); 12682 }, 12683 dragstart: noop, 12684 dragend: function(e) { 12685 return this.element.classList.remove("dz-drag-hover"); 12686 }, 12687 dragenter: function(e) { 12688 return this.element.classList.add("dz-drag-hover"); 12689 }, 12690 dragover: function(e) { 12691 return this.element.classList.add("dz-drag-hover"); 12692 }, 12693 dragleave: function(e) { 12694 return this.element.classList.remove("dz-drag-hover"); 12695 }, 12696 paste: noop, 12697 reset: function() { 12698 return this.element.classList.remove("dz-started"); 12699 }, 12700 addedfile: function(file) { 12701 var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results; 12702 if (this.element === this.previewsContainer) { 12703 this.element.classList.add("dz-started"); 12704 } 12705 if (this.previewsContainer) { 12706 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim()); 12707 file.previewTemplate = file.previewElement; 12708 this.previewsContainer.appendChild(file.previewElement); 12709 _ref = file.previewElement.querySelectorAll("[data-dz-name]"); 12710 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12711 node = _ref[_i]; 12712 node.textContent = this._renameFilename(file.name); 12713 } 12714 _ref1 = file.previewElement.querySelectorAll("[data-dz-size]"); 12715 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { 12716 node = _ref1[_j]; 12717 node.innerHTML = this.filesize(file.size); 12718 } 12719 if (this.options.addRemoveLinks) { 12720 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>"); 12721 file.previewElement.appendChild(file._removeLink); 12722 } 12723 removeFileEvent = (function(_this) { 12724 return function(e) { 12725 e.preventDefault(); 12726 e.stopPropagation(); 12727 if (file.status === Dropzone.UPLOADING) { 12728 return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() { 12729 return _this.removeFile(file); 12730 }); 12731 } else { 12732 if (_this.options.dictRemoveFileConfirmation) { 12733 return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() { 12734 return _this.removeFile(file); 12735 }); 12736 } else { 12737 return _this.removeFile(file); 12738 } 12739 } 12740 }; 12741 })(this); 12742 _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]"); 12743 _results = []; 12744 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { 12745 removeLink = _ref2[_k]; 12746 _results.push(removeLink.addEventListener("click", removeFileEvent)); 12747 } 12748 return _results; 12749 } 12750 }, 12751 removedfile: function(file) { 12752 var _ref; 12753 if (file.previewElement) { 12754 if ((_ref = file.previewElement) != null) { 12755 _ref.parentNode.removeChild(file.previewElement); 12756 } 12757 } 12758 return this._updateMaxFilesReachedClass(); 12759 }, 12760 thumbnail: function(file, dataUrl) { 12761 var thumbnailElement, _i, _len, _ref; 12762 if (file.previewElement) { 12763 file.previewElement.classList.remove("dz-file-preview"); 12764 _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]"); 12765 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12766 thumbnailElement = _ref[_i]; 12767 thumbnailElement.alt = file.name; 12768 thumbnailElement.src = dataUrl; 12769 } 12770 return setTimeout(((function(_this) { 12771 return function() { 12772 return file.previewElement.classList.add("dz-image-preview"); 12773 }; 12774 })(this)), 1); 12775 } 12776 }, 12777 error: function(file, message) { 12778 var node, _i, _len, _ref, _results; 12779 if (file.previewElement) { 12780 file.previewElement.classList.add("dz-error"); 12781 if (typeof message !== "String" && message.error) { 12782 message = message.error; 12783 } 12784 _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]"); 12785 _results = []; 12786 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12787 node = _ref[_i]; 12788 _results.push(node.textContent = message); 12789 } 12790 return _results; 12791 } 12792 }, 12793 errormultiple: noop, 12794 processing: function(file) { 12795 if (file.previewElement) { 12796 file.previewElement.classList.add("dz-processing"); 12797 if (file._removeLink) { 12798 return file._removeLink.textContent = this.options.dictCancelUpload; 12799 } 12800 } 12801 }, 12802 processingmultiple: noop, 12803 uploadprogress: function(file, progress, bytesSent) { 12804 var node, _i, _len, _ref, _results; 12805 if (file.previewElement) { 12806 _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"); 12807 _results = []; 12808 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12809 node = _ref[_i]; 12810 if (node.nodeName === 'PROGRESS') { 12811 _results.push(node.value = progress); 12812 } else { 12813 _results.push(node.style.width = "" + progress + "%"); 12814 } 12815 } 12816 return _results; 12817 } 12818 }, 12819 totaluploadprogress: noop, 12820 sending: noop, 12821 sendingmultiple: noop, 12822 success: function(file) { 12823 if (file.previewElement) { 12824 return file.previewElement.classList.add("dz-success"); 12825 } 12826 }, 12827 successmultiple: noop, 12828 canceled: function(file) {
12829 return this.emit("error", file, "Upload canceled."); 12830 }, 12831 canceledmultiple: noop, 12832 complete: function(file) { 12833 if (file._removeLink) { 12834 file._removeLink.textContent = this.options.dictRemoveFile; 12835 } 12836 if (file.previewElement) { 12837 return file.previewElement.classList.add("dz-complete"); 12838 } 12839 }, 12840 completemultiple: noop, 12841 maxfilesexceeded: noop, 12842 maxfilesreached: noop, 12843 queuecomplete: noop, 12844 addedfiles: noop, 12845 previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>" 12846 }; 12847 12848 extend = function() { 12849 var key, object, objects, target, val, _i, _len; 12850 target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 12851 for (_i = 0, _len = objects.length; _i < _len; _i++) { 12852 object = objects[_i]; 12853 for (key in object) { 12854 val = object[key]; 12855 target[key] = val; 12856 } 12857 } 12858 return target; 12859 }; 12860 12861 function Dropzone(element, options) { 12862 var elementOptions, fallback, _ref; 12863 this.element = element; 12864 this.version = Dropzone.version; 12865 this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); 12866 this.clickableElements = []; 12867 this.listeners = []; 12868 this.files = []; 12869 if (typeof this.element === "string") { 12870 this.element = document.querySelector(this.element); 12871 } 12872 if (!(this.element && (this.element.nodeType != null))) { 12873 throw new Error("Invalid dropzone element."); 12874 } 12875 if (this.element.dropzone) { 12876 throw new Error("Dropzone already attached."); 12877 } 12878 Dropzone.instances.push(this); 12879 this.element.dropzone = this; 12880 elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {}; 12881 this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); 12882 if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { 12883 return this.options.fallback.call(this); 12884 } 12885 if (this.options.url == null) { 12886 this.options.url = this.element.getAttribute("action"); 12887 } 12888 if (!this.options.url) { 12889 throw new Error("No URL provided."); 12890 } 12891 if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { 12892 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); 12893 } 12894 if (this.options.acceptedMimeTypes) { 12895 this.options.acceptedFiles = this.options.acceptedMimeTypes; 12896 delete this.options.acceptedMimeTypes; 12897 } 12898 this.options.method = this.options.method.toUpperCase(); 12899 if ((fallback = this.getExistingFallback()) && fallback.parentNode) { 12900 fallback.parentNode.removeChild(fallback); 12901 } 12902 if (this.options.previewsContainer !== false) { 12903 if (this.options.previewsContainer) { 12904 this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); 12905 } else { 12906 this.previewsContainer = this.element; 12907 } 12908 } 12909 if (this.options.clickable) { 12910 if (this.options.clickable === true) { 12911 this.clickableElements = [this.element]; 12912 } else { 12913 this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); 12914 } 12915 } 12916 this.init(); 12917 } 12918 12919 Dropzone.prototype.getAcceptedFiles = function() { 12920 var file, _i, _len, _ref, _results; 12921 _ref = this.files; 12922 _results = []; 12923 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12924 file = _ref[_i]; 12925 if (file.accepted) { 12926 _results.push(file); 12927 } 12928 } 12929 return _results; 12930 }; 12931 12932 Dropzone.prototype.getRejectedFiles = function() { 12933 var file, _i, _len, _ref, _results; 12934 _ref = this.files; 12935 _results = []; 12936 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12937 file = _ref[_i]; 12938 if (!file.accepted) { 12939 _results.push(file); 12940 } 12941 } 12942 return _results; 12943 }; 12944 12945 Dropzone.prototype.getFilesWithStatus = function(status) { 12946 var file, _i, _len, _ref, _results; 12947 _ref = this.files; 12948 _results = []; 12949 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12950 file = _ref[_i]; 12951 if (file.status === status) { 12952 _results.push(file); 12953 } 12954 } 12955 return _results; 12956 }; 12957 12958 Dropzone.prototype.getQueuedFiles = function() { 12959 return this.getFilesWithStatus(Dropzone.QUEUED); 12960 }; 12961 12962 Dropzone.prototype.getUploadingFiles = function() { 12963 return this.getFilesWithStatus(Dropzone.UPLOADING); 12964 }; 12965 12966 Dropzone.prototype.getAddedFiles = function() { 12967 return this.getFilesWithStatus(Dropzone.ADDED); 12968 }; 12969 12970 Dropzone.prototype.getActiveFiles = function() { 12971 var file, _i, _len, _ref, _results; 12972 _ref = this.files; 12973 _results = []; 12974 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 12975 file = _ref[_i]; 12976 if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) { 12977 _results.push(file); 12978 } 12979 } 12980 return _results; 12981 }; 12982 12983 Dropzone.prototype.init = function() { 12984 var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1; 12985 if (this.element.tagName === "form") { 12986 this.element.setAttribute("enctype", "multipart/form-data"); 12987 } 12988 if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { 12989 this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>")); 12990 } 12991 if (this.clickableElements.length) { 12992 setupHiddenFileInput = (function(_this) { 12993 return function() { 12994 if (_this.hiddenFileInput) { 12995 _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput); 12996 } 12997 _this.hiddenFileInput = document.createElement("input"); 12998 _this.hiddenFileInput.setAttribute("type", "file"); 12999 if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) { 13000 _this.hiddenFileInput.setAttribute("multiple", "multiple"); 13001 } 13002 _this.hiddenFileInput.className = "dz-hidden-input"; 13003 if (_this.options.acceptedFiles != null) { 13004 _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); 13005 } 13006 if (_this.options.capture != null) { 13007 _this.hiddenFileInput.setAttribute("capture", _this.options.capture); 13008 } 13009 _this.hiddenFileInput.style.visibility = "hidden"; 13010 _this.hiddenFileInput.style.position = "absolute"; 13011 _this.hiddenFileInput.style.top = "0"; 13012 _this.hiddenFileInput.style.left = "0"; 13013 _this.hiddenFileInput.style.height = "0"; 13014 _this.hiddenFileInput.style.width = "0"; 13015 document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput); 13016 return _this.hiddenFileInput.addEventListener("change", function() { 13017 var file, files, _i, _len; 13018 files = _this.hiddenFileInput.files; 13019 if (files.length) { 13020 for (_i = 0, _len = files.length; _i < _len; _i++) { 13021 file = files[_i]; 13022 _this.addFile(file); 13023 } 13024 }
13025 _this.emit("addedfiles", files); 13026 return setupHiddenFileInput(); 13027 }); 13028 }; 13029 })(this); 13030 setupHiddenFileInput(); 13031 } 13032 this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL; 13033 _ref1 = this.events; 13034 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { 13035 eventName = _ref1[_i]; 13036 this.on(eventName, this.options[eventName]); 13037 } 13038 this.on("uploadprogress", (function(_this) { 13039 return function() { 13040 return _this.updateTotalUploadProgress(); 13041 }; 13042 })(this)); 13043 this.on("removedfile", (function(_this) { 13044 return function() { 13045 return _this.updateTotalUploadProgress(); 13046 }; 13047 })(this)); 13048 this.on("canceled", (function(_this) { 13049 return function(file) { 13050 return _this.emit("complete", file); 13051 }; 13052 })(this)); 13053 this.on("complete", (function(_this) { 13054 return function(file) { 13055 if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) { 13056 return setTimeout((function() { 13057 return _this.emit("queuecomplete"); 13058 }), 0); 13059 } 13060 }; 13061 })(this)); 13062 noPropagation = function(e) { 13063 e.stopPropagation(); 13064 if (e.preventDefault) { 13065 return e.preventDefault(); 13066 } else { 13067 return e.returnValue = false; 13068 } 13069 }; 13070 this.listeners = [ 13071 { 13072 element: this.element, 13073 events: { 13074 "dragstart": (function(_this) { 13075 return function(e) { 13076 return _this.emit("dragstart", e); 13077 }; 13078 })(this), 13079 "dragenter": (function(_this) { 13080 return function(e) { 13081 noPropagation(e); 13082 return _this.emit("dragenter", e); 13083 }; 13084 })(this), 13085 "dragover": (function(_this) { 13086 return function(e) { 13087 var efct; 13088 try { 13089 efct = e.dataTransfer.effectAllowed; 13090 } catch (_error) {} 13091 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy'; 13092 noPropagation(e); 13093 return _this.emit("dragover", e); 13094 }; 13095 })(this), 13096 "dragleave": (function(_this) { 13097 return function(e) { 13098 return _this.emit("dragleave", e); 13099 }; 13100 })(this), 13101 "drop": (function(_this) { 13102 return function(e) { 13103 noPropagation(e); 13104 return _this.drop(e); 13105 }; 13106 })(this), 13107 "dragend": (function(_this) { 13108 return function(e) { 13109 return _this.emit("dragend", e); 13110 }; 13111 })(this) 13112 } 13113 } 13114 ]; 13115 this.clickableElements.forEach((function(_this) { 13116 return function(clickableElement) { 13117 return _this.listeners.push({ 13118 element: clickableElement, 13119 events: { 13120 "click": function(evt) { 13121 if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { 13122 _this.hiddenFileInput.click(); 13123 } 13124 return true; 13125 } 13126 } 13127 }); 13128 }; 13129 })(this)); 13130 this.enable(); 13131 return this.options.init.call(this); 13132 }; 13133 13134 Dropzone.prototype.destroy = function() { 13135 var _ref; 13136 this.disable(); 13137 this.removeAllFiles(true); 13138 if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) { 13139 this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); 13140 this.hiddenFileInput = null; 13141 } 13142 delete this.element.dropzone; 13143 return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1); 13144 }; 13145 13146 Dropzone.prototype.updateTotalUploadProgress = function() { 13147 var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref; 13148 totalBytesSent = 0; 13149 totalBytes = 0; 13150 activeFiles = this.getActiveFiles(); 13151 if (activeFiles.length) { 13152 _ref = this.getActiveFiles(); 13153 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13154 file = _ref[_i];
13155 totalBytesSent += file.upload.bytesSent; 13156 totalBytes += file.upload.total; 13157 } 13158 totalUploadProgress = 100 * totalBytesSent / totalBytes; 13159 } else { 13160 totalUploadProgress = 100; 13161 } 13162 return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); 13163 }; 13164 13165 Dropzone.prototype._getParamName = function(n) { 13166 if (typeof this.options.paramName === "function") { 13167 return this.options.paramName(n); 13168 } else { 13169 return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : ""); 13170 } 13171 }; 13172 13173 Dropzone.prototype._renameFilename = function(name) { 13174 if (typeof this.options.renameFilename !== "function") { 13175 return name; 13176 } 13177 return this.options.renameFilename(name); 13178 }; 13179 13180 Dropzone.prototype.getFallbackForm = function() { 13181 var existingFallback, fields, fieldsString, form; 13182 if (existingFallback = this.getExistingFallback()) { 13183 return existingFallback; 13184 } 13185 fieldsString = "<div class=\"dz-fallback\">"; 13186 if (this.options.dictFallbackText) { 13187 fieldsString += "<p>" + this.options.dictFallbackText + "</p>"; 13188 } 13189 fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>"; 13190 fields = Dropzone.createElement(fieldsString); 13191 if (this.element.tagName !== "FORM") { 13192 form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>"); 13193 form.appendChild(fields); 13194 } else { 13195 this.element.setAttribute("enctype", "multipart/form-data"); 13196 this.element.setAttribute("method", this.options.method); 13197 } 13198 return form != null ? form : fields; 13199 }; 13200 13201 Dropzone.prototype.getExistingFallback = function() { 13202 var fallback, getFallback, tagName, _i, _len, _ref; 13203 getFallback = function(elements) { 13204 var el, _i, _len; 13205 for (_i = 0, _len = elements.length; _i < _len; _i++) { 13206 el = elements[_i]; 13207 if (/(^| )fallback($| )/.test(el.className)) { 13208 return el; 13209 } 13210 } 13211 }; 13212 _ref = ["div", "form"]; 13213 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13214 tagName = _ref[_i]; 13215 if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { 13216 return fallback; 13217 } 13218 } 13219 }; 13220 13221 Dropzone.prototype.setupEventListeners = function() { 13222 var elementListeners, event, listener, _i, _len, _ref, _results; 13223 _ref = this.listeners; 13224 _results = []; 13225 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13226 elementListeners = _ref[_i]; 13227 _results.push((function() { 13228 var _ref1, _results1; 13229 _ref1 = elementListeners.events; 13230 _results1 = []; 13231 for (event in _ref1) { 13232 listener = _ref1[event]; 13233 _results1.push(elementListeners.element.addEventListener(event, listener, false)); 13234 } 13235 return _results1; 13236 })()); 13237 } 13238 return _results; 13239 }; 13240 13241 Dropzone.prototype.removeEventListeners = function() { 13242 var elementListeners, event, listener, _i, _len, _ref, _results; 13243 _ref = this.listeners; 13244 _results = []; 13245 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13246 elementListeners = _ref[_i]; 13247 _results.push((function() { 13248 var _ref1, _results1; 13249 _ref1 = elementListeners.events; 13250 _results1 = []; 13251 for (event in _ref1) { 13252 listener = _ref1[event]; 13253 _results1.push(elementListeners.element.removeEventListener(event, listener, false)); 13254 } 13255 return _results1; 13256 })()); 13257 } 13258 return _results; 13259 }; 13260 13261 Dropzone.prototype.disable = function() { 13262 var file, _i, _len, _ref, _results; 13263 this.clickableElements.forEach(function(element) { 13264 return element.classList.remove("dz-clickable"); 13265 }); 13266 this.removeEventListeners(); 13267 _ref = this.files; 13268 _results = []; 13269 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13270 file = _ref[_i]; 13271 _results.push(this.cancelUpload(file)); 13272 } 13273 return _results; 13274 }; 13275 13276 Dropzone.prototype.enable = function() {
13277 this.clickableElements.forEach(function(element) { 13278 return element.classList.add("dz-clickable"); 13279 }); 13280 return this.setupEventListeners(); 13281 }; 13282 13283 Dropzone.prototype.filesize = function(size) { 13284 var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len; 13285 selectedSize = 0; 13286 selectedUnit = "b"; 13287 if (size > 0) { 13288 units = ['TB', 'GB', 'MB', 'KB', 'b']; 13289 for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) { 13290 unit = units[i]; 13291 cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10; 13292 if (size >= cutoff) { 13293 selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i); 13294 selectedUnit = unit; 13295 break; 13296 } 13297 } 13298 selectedSize = Math.round(10 * selectedSize) / 10; 13299 } 13300 return "<strong>" + selectedSize + "</strong> " + selectedUnit; 13301 }; 13302 13303 Dropzone.prototype._updateMaxFilesReachedClass = function() { 13304 if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { 13305 if (this.getAcceptedFiles().length === this.options.maxFiles) { 13306 this.emit('maxfilesreached', this.files); 13307 } 13308 return this.element.classList.add("dz-max-files-reached"); 13309 } else { 13310 return this.element.classList.remove("dz-max-files-reached"); 13311 } 13312 }; 13313 13314 Dropzone.prototype.drop = function(e) { 13315 var files, items; 13316 if (!e.dataTransfer) { 13317 return; 13318 } 13319 this.emit("drop", e); 13320 files = e.dataTransfer.files; 13321 this.emit("addedfiles", files); 13322 if (files.length) { 13323 items = e.dataTransfer.items; 13324 if (items && items.length && (items[0].webkitGetAsEntry != null)) { 13325 this._addFilesFromItems(items); 13326 } else { 13327 this.handleFiles(files); 13328 } 13329 } 13330 }; 13331 13332 Dropzone.prototype.paste = function(e) { 13333 var items, _ref; 13334 if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) { 13335 return; 13336 } 13337 this.emit("paste", e); 13338 items = e.clipboardData.items; 13339 if (items.length) { 13340 return this._addFilesFromItems(items); 13341 } 13342 }; 13343 13344 Dropzone.prototype.handleFiles = function(files) { 13345 var file, _i, _len, _results; 13346 _results = []; 13347 for (_i = 0, _len = files.length; _i < _len; _i++) { 13348 file = files[_i]; 13349 _results.push(this.addFile(file)); 13350 } 13351 return _results; 13352 }; 13353 13354 Dropzone.prototype._addFilesFromItems = function(items) { 13355 var entry, item, _i, _len, _results; 13356 _results = []; 13357 for (_i = 0, _len = items.length; _i < _len; _i++) { 13358 item = items[_i]; 13359 if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) { 13360 if (entry.isFile) { 13361 _results.push(this.addFile(item.getAsFile())); 13362 } else if (entry.isDirectory) { 13363 _results.push(this._addFilesFromDirectory(entry, entry.name)); 13364 } else { 13365 _results.push(void 0); 13366 } 13367 } else if (item.getAsFile != null) { 13368 if ((item.kind == null) || item.kind === "file") { 13369 _results.push(this.addFile(item.getAsFile())); 13370 } else { 13371 _results.push(void 0); 13372 } 13373 } else { 13374 _results.push(void 0); 13375 } 13376 } 13377 return _results; 13378 }; 13379 13380 Dropzone.prototype._addFilesFromDirectory = function(directory, path) { 13381 var dirReader, errorHandler, readEntries; 13382 dirReader = directory.createReader(); 13383 errorHandler = function(error) { 13384 return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; 13385 }; 13386 readEntries = (function(_this) { 13387 return function() { 13388 return dirReader.readEntries(function(entries) { 13389 var entry, _i, _len; 13390 if (entries.length > 0) { 13391 for (_i = 0, _len = entries.length; _i < _len; _i++) { 13392 entry = entries[_i]; 13393 if (entry.isFile) { 13394 entry.file(function(file) { 13395 if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { 13396 return; 13397 } 13398 file.fullPath = "" + path + "/" + file.name; 13399 return _this.addFile(file); 13400 }); 13401 } else if (entry.isDirectory) { 13402 _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name); 13403 } 13404 } 13405 readEntries(); 13406 } 13407 return null; 13408 }, errorHandler); 13409 }; 13410 })(this); 13411 return readEntries(); 13412 }; 13413 13414 Dropzone.prototype.accept = function(file, done) { 13415 if (file.size > this.options.maxFilesize * 1024 * 1024) { 13416 return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); 13417 } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { 13418 return done(this.options.dictInvalidFileType); 13419 } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { 13420 done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
13421 return this.emit("maxfilesexceeded", file); 13422 } else { 13423 return this.options.accept.call(this, file, done); 13424 } 13425 }; 13426 13427 Dropzone.prototype.addFile = function(file) { 13428 file.upload = { 13429 progress: 0, 13430 total: file.size, 13431 bytesSent: 0 13432 }; 13433 this.files.push(file); 13434 file.status = Dropzone.ADDED; 13435 this.emit("addedfile", file); 13436 this._enqueueThumbnail(file); 13437 return this.accept(file, (function(_this) { 13438 return function(error) { 13439 if (error) { 13440 file.accepted = false; 13441 _this._errorProcessing([file], error); 13442 } else { 13443 file.accepted = true; 13444 if (_this.options.autoQueue) { 13445 _this.enqueueFile(file); 13446 } 13447 } 13448 return _this._updateMaxFilesReachedClass(); 13449 }; 13450 })(this)); 13451 }; 13452 13453 Dropzone.prototype.enqueueFiles = function(files) { 13454 var file, _i, _len; 13455 for (_i = 0, _len = files.length; _i < _len; _i++) { 13456 file = files[_i]; 13457 this.enqueueFile(file); 13458 } 13459 return null; 13460 }; 13461 13462 Dropzone.prototype.enqueueFile = function(file) { 13463 if (file.status === Dropzone.ADDED && file.accepted === true) { 13464 file.status = Dropzone.QUEUED; 13465 if (this.options.autoProcessQueue) { 13466 return setTimeout(((function(_this) { 13467 return function() { 13468 return _this.processQueue(); 13469 }; 13470 })(this)), 0); 13471 } 13472 } else { 13473 throw new Error("This file can't be queued because it has already been processed or was rejected."); 13474 } 13475 }; 13476 13477 Dropzone.prototype._thumbnailQueue = []; 13478 13479 Dropzone.prototype._processingThumbnail = false; 13480 13481 Dropzone.prototype._enqueueThumbnail = function(file) { 13482 if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { 13483 this._thumbnailQueue.push(file); 13484 return setTimeout(((function(_this) { 13485 return function() { 13486 return _this._processThumbnailQueue(); 13487 }; 13488 })(this)), 0); 13489 } 13490 }; 13491 13492 Dropzone.prototype._processThumbnailQueue = function() { 13493 if (this._processingThumbnail || this._thumbnailQueue.length === 0) { 13494 return; 13495 } 13496 this._processingThumbnail = true; 13497 return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) { 13498 return function() { 13499 _this._processingThumbnail = false; 13500 return _this._processThumbnailQueue(); 13501 }; 13502 })(this)); 13503 }; 13504 13505 Dropzone.prototype.removeFile = function(file) { 13506 if (file.status === Dropzone.UPLOADING) { 13507 this.cancelUpload(file); 13508 } 13509 this.files = without(this.files, file); 13510 this.emit("removedfile", file); 13511 if (this.files.length === 0) { 13512 return this.emit("reset"); 13513 } 13514 }; 13515 13516 Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { 13517 var file, _i, _len, _ref; 13518 if (cancelIfNecessary == null) { 13519 cancelIfNecessary = false; 13520 } 13521 _ref = this.files.slice(); 13522 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13523 file = _ref[_i]; 13524 if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { 13525 this.removeFile(file); 13526 } 13527 } 13528 return null; 13529 }; 13530 13531 Dropzone.prototype.createThumbnail = function(file, callback) { 13532 var fileReader; 13533 fileReader = new FileReader; 13534 fileReader.onload = (function(_this) { 13535 return function() { 13536 if (file.type === "image/svg+xml") { 13537 _this.emit("thumbnail", file, fileReader.result); 13538 if (callback != null) { 13539 callback(); 13540 } 13541 return; 13542 } 13543 return _this.createThumbnailFromUrl(file, fileReader.result, callback); 13544 }; 13545 })(this); 13546 return fileReader.readAsDataURL(file); 13547 }; 13548 13549 Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback, crossOrigin) { 13550 var img; 13551 img = document.createElement("img"); 13552 if (crossOrigin) { 13553 img.crossOrigin = crossOrigin; 13554 } 13555 img.onload = (function(_this) { 13556 return function() { 13557 var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3; 13558 file.width = img.width;
13559 file.height = img.height; 13560 resizeInfo = _this.options.resize.call(_this, file); 13561 if (resizeInfo.trgWidth == null) { 13562 resizeInfo.trgWidth = resizeInfo.optWidth; 13563 } 13564 if (resizeInfo.trgHeight == null) { 13565 resizeInfo.trgHeight = resizeInfo.optHeight; 13566 } 13567 canvas = document.createElement("canvas"); 13568 ctx = canvas.getContext("2d"); 13569 canvas.width = resizeInfo.trgWidth; 13570 canvas.height = resizeInfo.trgHeight; 13571 drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); 13572 thumbnail = canvas.toDataURL("image/png"); 13573 _this.emit("thumbnail", file, thumbnail); 13574 if (callback != null) { 13575 return callback(); 13576 } 13577 }; 13578 })(this); 13579 if (callback != null) { 13580 img.onerror = callback; 13581 } 13582 return img.src = imageUrl; 13583 }; 13584 13585 Dropzone.prototype.processQueue = function() { 13586 var i, parallelUploads, processingLength, queuedFiles; 13587 parallelUploads = this.options.parallelUploads; 13588 processingLength = this.getUploadingFiles().length; 13589 i = processingLength; 13590 if (processingLength >= parallelUploads) { 13591 return; 13592 } 13593 queuedFiles = this.getQueuedFiles(); 13594 if (!(queuedFiles.length > 0)) { 13595 return; 13596 } 13597 if (this.options.uploadMultiple) { 13598 return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); 13599 } else { 13600 while (i < parallelUploads) { 13601 if (!queuedFiles.length) { 13602 return; 13603 } 13604 this.processFile(queuedFiles.shift()); 13605 i++; 13606 } 13607 } 13608 }; 13609 13610 Dropzone.prototype.processFile = function(file) { 13611 return this.processFiles([file]); 13612 }; 13613 13614 Dropzone.prototype.processFiles = function(files) { 13615 var file, _i, _len; 13616 for (_i = 0, _len = files.length; _i < _len; _i++) { 13617 file = files[_i]; 13618 file.processing = true; 13619 file.status = Dropzone.UPLOADING; 13620 this.emit("processing", file); 13621 } 13622 if (this.options.uploadMultiple) { 13623 this.emit("processingmultiple", files); 13624 } 13625 return this.uploadFiles(files); 13626 }; 13627 13628 Dropzone.prototype._getFilesWithXhr = function(xhr) { 13629 var file, files; 13630 return files = (function() { 13631 var _i, _len, _ref, _results; 13632 _ref = this.files; 13633 _results = []; 13634 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13635 file = _ref[_i]; 13636 if (file.xhr === xhr) { 13637 _results.push(file); 13638 } 13639 } 13640 return _results; 13641 }).call(this); 13642 }; 13643 13644 Dropzone.prototype.cancelUpload = function(file) { 13645 var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref; 13646 if (file.status === Dropzone.UPLOADING) { 13647 groupedFiles = this._getFilesWithXhr(file.xhr); 13648 for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) { 13649 groupedFile = groupedFiles[_i]; 13650 groupedFile.status = Dropzone.CANCELED; 13651 } 13652 file.xhr.abort(); 13653 for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) { 13654 groupedFile = groupedFiles[_j]; 13655 this.emit("canceled", groupedFile); 13656 } 13657 if (this.options.uploadMultiple) { 13658 this.emit("canceledmultiple", groupedFiles); 13659 } 13660 } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) { 13661 file.status = Dropzone.CANCELED; 13662 this.emit("canceled", file); 13663 if (this.options.uploadMultiple) { 13664 this.emit("canceledmultiple", [file]); 13665 } 13666 } 13667 if (this.options.autoProcessQueue) { 13668 return this.processQueue(); 13669 } 13670 }; 13671 13672 resolveOption = function() { 13673 var args, option; 13674 option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 13675 if (typeof option === 'function') { 13676 return option.apply(this, args); 13677 } 13678 return option; 13679 }; 13680 13681 Dropzone.prototype.uploadFile = function(file) { 13682 return this.uploadFiles([file]); 13683 }; 13684 13685 Dropzone.prototype.uploadFiles = function(files) { 13686 var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; 13687 xhr = new XMLHttpRequest(); 13688 for (_i = 0, _len = files.length; _i < _len; _i++) { 13689 file = files[_i]; 13690 file.xhr = xhr; 13691 } 13692 method = resolveOption(this.options.method, files); 13693 url = resolveOption(this.options.url, files); 13694 xhr.open(method, url, true); 13695 xhr.withCredentials = !!this.options.withCredentials; 13696 response = null; 13697 handleError = (function(_this) { 13698 return function() { 13699 var _j, _len1, _results; 13700 _results = []; 13701 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 13702 file = files[_j]; 13703 _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); 13704 } 13705 return _results; 13706 }; 13707 })(this); 13708 updateProgress = (function(_this) { 13709 return function(e) { 13710 var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results; 13711 if (e != null) { 13712 progress = 100 * e.loaded / e.total; 13713 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 13714 file = files[_j]; 13715 file.upload = { 13716 progress: progress, 13717 total: e.total, 13718 bytesSent: e.loaded 13719 }; 13720 } 13721 } else { 13722 allFilesFinished = true; 13723 progress = 100; 13724 for (_k = 0, _len2 = files.length; _k < _len2; _k++) { 13725 file = files[_k]; 13726 if (!(file.upload.progress === 100 && file.upload.b
13726ytesSent === file.upload.total)) { 13727 allFilesFinished = false; 13728 } 13729 file.upload.progress = progress; 13730 file.upload.bytesSent = file.upload.total; 13731 } 13732 if (allFilesFinished) { 13733 return; 13734 } 13735 } 13736 _results = []; 13737 for (_l = 0, _len3 = files.length; _l < _len3; _l++) { 13738 file = files[_l]; 13739 _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); 13740 } 13741 return _results; 13742 }; 13743 })(this); 13744 xhr.onload = (function(_this) { 13745 return function(e) { 13746 var _ref; 13747 if (files[0].status === Dropzone.CANCELED) { 13748 return; 13749 } 13750 if (xhr.readyState !== 4) { 13751 return; 13752 } 13753 response = xhr.responseText; 13754 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { 13755 try { 13756 response = JSON.parse(response); 13757 } catch (_error) { 13758 e = _error; 13759 response = "Invalid JSON response from server."; 13760 } 13761 } 13762 updateProgress(); 13763 if (!((200 <= (_ref = xhr.status) && _ref < 300))) { 13764 return handleError(); 13765 } else { 13766 return _this._finished(files, response, e); 13767 } 13768 }; 13769 })(this); 13770 xhr.onerror = (function(_this) { 13771 return function() { 13772 if (files[0].status === Dropzone.CANCELED) { 13773 return; 13774 } 13775 return handleError(); 13776 }; 13777 })(this); 13778 progressObj = (_ref = xhr.upload) != null ? _ref : xhr; 13779 progressObj.onprogress = updateProgress; 13780 headers = { 13781 "Accept": "application/json", 13782 "Cache-Control": "no-cache", 13783 "X-Requested-With": "XMLHttpRequest" 13784 }; 13785 if (this.options.headers) { 13786 extend(headers, this.options.headers); 13787 } 13788 for (headerName in headers) { 13789 headerValue = headers[headerName]; 13790 if (headerValue) { 13791 xhr.setRequestHeader(headerName, headerValue); 13792 } 13793 } 13794 formData = new FormData(); 13795 if (this.options.params) { 13796 _ref1 = this.options.params; 13797 for (key in _ref1) { 13798 value = _ref1[key]; 13799 formData.append(key, value); 13800 } 13801 } 13802 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 13803 file = files[_j]; 13804 this.emit("sending", file, xhr, formData); 13805 } 13806 if (this.options.uploadMultiple) { 13807 this.emit("sendingmultiple", files, xhr, formData); 13808 } 13809 if (this.element.tagName === "FORM") { 13810 _ref2 = this.element.querySelectorAll("input, textarea, select, button"); 13811 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { 13812 input = _ref2[_k]; 13813 inputName = input.getAttribute("name"); 13814 inputType = input.getAttribute("type"); 13815 if (input.tagName === "SELECT" && input.hasAttribute("multiple")) { 13816 _ref3 = input.options; 13817 for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { 13818 option = _ref3[_l]; 13819 if (option.selected) { 13820 formData.append(inputName, option.value); 13821 } 13822 } 13823 } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) { 13824 formData.append(inputName, input.value); 13825 } 13826 } 13827 } 13828 for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) { 13829 formData.append(this._getParamName(i), files[i], this._renameFilename(files[i].name)); 13830 } 13831 return this.submitRequest(xhr, formData, files); 13832 }; 13833 13834 Dropzone.prototype.submitRequest = function(xhr, formData, files) { 13835 return xhr.send(formData); 13836 }; 13837 13838 Dropzone.prototype._finished = function(files, responseText, e) { 13839 var file, _i, _len; 13840 for (_i = 0, _len = files.length; _i < _len; _i++) { 13841 file = files[_i]; 13842 file.status = Dropzone.SUCCESS;
13843 this.emit("success", file, responseText, e); 13844 this.emit("complete", file); 13845 } 13846 if (this.options.uploadMultiple) { 13847 this.emit("successmultiple", files, responseText, e); 13848 this.emit("completemultiple", files); 13849 } 13850 if (this.options.autoProcessQueue) { 13851 return this.processQueue(); 13852 } 13853 }; 13854 13855 Dropzone.prototype._errorProcessing = function(files, message, xhr) { 13856 var file, _i, _len; 13857 for (_i = 0, _len = files.length; _i < _len; _i++) { 13858 file = files[_i]; 13859 file.status = Dropzone.ERROR; 13860 this.emit("error", file, message, xhr); 13861 this.emit("complete", file); 13862 } 13863 if (this.options.uploadMultiple) { 13864 this.emit("errormultiple", files, message, xhr); 13865 this.emit("completemultiple", files); 13866 } 13867 if (this.options.autoProcessQueue) { 13868 return this.processQueue(); 13869 } 13870 }; 13871 13872 return Dropzone; 13873 13874 })(Emitter); 13875 13876 Dropzone.version = "4.3.0"; 13877 13878 Dropzone.options = {}; 13879 13880 Dropzone.optionsForElement = function(element) { 13881 if (element.getAttribute("id")) { 13882 return Dropzone.options[camelize(element.getAttribute("id"))]; 13883 } else { 13884 return void 0; 13885 } 13886 }; 13887 13888 Dropzone.instances = []; 13889 13890 Dropzone.forElement = function(element) { 13891 if (typeof element === "string") { 13892 element = document.querySelector(element); 13893 } 13894 if ((element != null ? element.dropzone : void 0) == null) { 13895 throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone."); 13896 } 13897 return element.dropzone; 13898 }; 13899 13900 Dropzone.autoDiscover = true; 13901 13902 Dropzone.discover = function() { 13903 var checkElements, dropzone, dropzones, _i, _len, _results; 13904 if (document.querySelectorAll) { 13905 dropzones = document.querySelectorAll(".dropzone"); 13906 } else { 13907 dropzones = []; 13908 checkElements = function(elements) { 13909 var el, _i, _len, _results; 13910 _results = []; 13911 for (_i = 0, _len = elements.length; _i < _len; _i++) { 13912 el = elements[_i]; 13913 if (/(^| )dropzone($| )/.test(el.className)) { 13914 _results.push(dropzones.push(el)); 13915 } else { 13916 _results.push(void 0); 13917 } 13918 } 13919 return _results; 13920 }; 13921 checkElements(document.getElementsByTagName("div")); 13922 checkElements(document.getElementsByTagName("form")); 13923 } 13924 _results = []; 13925 for (_i = 0, _len = dropzones.length; _i < _len; _i++) { 13926 dropzone = dropzones[_i]; 13927 if (Dropzone.optionsForElement(dropzone) !== false) { 13928 _results.push(new Dropzone(dropzone)); 13929 } else { 13930 _results.push(void 0); 13931 } 13932 } 13933 return _results; 13934 }; 13935 13936 Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; 13937 13938 Dropzone.isBrowserSupported = function() { 13939 var capableBrowser, regex, _i, _len, _ref; 13940 capableBrowser = true; 13941 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { 13942 if (!("classList" in document.createElement("a"))) { 13943 capableBrowser = false; 13944 } else { 13945 _ref = Dropzone.blacklistedBrowsers; 13946 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 13947 regex = _ref[_i]; 13948 if (regex.test(navigator.userAgent)) { 13949 capableBrowser = false; 13950 continue; 13951 } 13952 } 13953 } 13954 } else { 13955 capableBrowser = false; 13956 } 13957 return capableBrowser; 13958 }; 13959 13960 without = function(list, rejectedItem) { 13961 var item, _i, _len, _results; 13962 _results = []; 13963 for (_i = 0, _len = list.length; _i < _len; _i++) { 13964 item = list[_i]; 13965 if (item !== rejectedItem) { 13966 _results.push(item); 13967 } 13968 } 13969 return _results; 13970 }; 13971 13972 camelize = function(str) { 13973 return str.replace(/[\-_](\w)/g, function(match) { 13974 return match.charAt(1).toUpperCase(); 13975 }); 13976 }; 13977 13978 Dropzone.createElement = function(string) { 13979 var div; 13980 div = document.createElement("div"); 13981 div.innerHTML = string; 13982 return div.childNodes[0]; 13983 }; 13984 13985 Dropzone.elementInside = function(element, container) { 13986 if (element === container) { 13987 return true; 13988 } 13989 while (element = element.parentNode) { 13990 if (element === container) { 13991 return true; 13992 } 13993 } 13994 return false;
13995 }; 13996 13997 Dropzone.getElement = function(el, name) { 13998 var element; 13999 if (typeof el === "string") { 14000 element = document.querySelector(el); 14001 } else if (el.nodeType != null) { 14002 element = el; 14003 } 14004 if (element == null) { 14005 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); 14006 } 14007 return element; 14008 }; 14009 14010 Dropzone.getElements = function(els, name) { 14011 var e, el, elements, _i, _j, _len, _len1, _ref; 14012 if (els instanceof Array) { 14013 elements = []; 14014 try { 14015 for (_i = 0, _len = els.length; _i < _len; _i++) { 14016 el = els[_i]; 14017 elements.push(this.getElement(el, name)); 14018 } 14019 } catch (_error) { 14020 e = _error; 14021 elements = null; 14022 } 14023 } else if (typeof els === "string") { 14024 elements = []; 14025 _ref = document.querySelectorAll(els); 14026 for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { 14027 el = _ref[_j]; 14028 elements.push(el); 14029 } 14030 } else if (els.nodeType != null) { 14031 elements = [els]; 14032 } 14033 if (!((elements != null) && elements.length)) { 14034 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); 14035 } 14036 return elements; 14037 }; 14038 14039 Dropzone.confirm = function(question, accepted, rejected) { 14040 if (window.confirm(question)) { 14041 return accepted(); 14042 } else if (rejected != null) { 14043 return rejected(); 14044 } 14045 }; 14046 14047 Dropzone.isValidFile = function(file, acceptedFiles) { 14048 var baseMimeType, mimeType, validType, _i, _len; 14049 if (!acceptedFiles) { 14050 return true; 14051 } 14052 acceptedFiles = acceptedFiles.split(","); 14053 mimeType = file.type; 14054 baseMimeType = mimeType.replace(/\/.*$/, ""); 14055 for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) { 14056 validType = acceptedFiles[_i]; 14057 validType = validType.trim(); 14058 if (validType.charAt(0) === ".") { 14059 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) { 14060 return true; 14061 } 14062 } else if (/\/\*$/.test(validType)) { 14063 if (baseMimeType === validType.replace(/\/.*$/, "")) { 14064 return true; 14065 } 14066 } else { 14067 if (mimeType === validType) { 14068 return true; 14069 } 14070 } 14071 } 14072 return false; 14073 }; 14074 14075 if (typeof jQuery !== "undefined" && jQuery !== null) { 14076 jQuery.fn.dropzone = function(options) { 14077 return this.each(function() { 14078 return new Dropzone(this, options); 14079 }); 14080 }; 14081 } 14082 14083 if (typeof module !== "undefined" && module !== null) { 14084 module.exports = Dropzone; 14085 } else { 14086 window.Dropzone = Dropzone; 14087 } 14088 14089 Dropzone.ADDED = "added"; 14090 14091 Dropzone.QUEUED = "queued"; 14092 14093 Dropzone.ACCEPTED = Dropzone.QUEUED; 14094 14095 Dropzone.UPLOADING = "uploading"; 14096 14097 Dropzone.PROCESSING = Dropzone.UPLOADING; 14098 14099 Dropzone.CANCELED = "canceled"; 14100 14101 Dropzone.ERROR = "error"; 14102 14103 Dropzone.SUCCESS = "success"; 14104 14105 14106 /* 14107 14108 Bugfix for iOS 6 and 7 14109 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios 14110 based on the work of https://github.com/stomita/ios-imagefile-megapixel 14111 */ 14112 14113 detectVerticalSquash = function(img) { 14114 var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy; 14115 iw = img.naturalWidth; 14116 ih = img.naturalHeight; 14117 canvas = document.createElement("canvas"); 14118 canvas.width = 1; 14119 canvas.height = ih; 14120 ctx = canvas.getContext("2d"); 14121 ctx.drawImage(img, 0, 0); 14122 data = ctx.getImageData(0, 0, 1, ih).data; 14123 sy = 0; 14124 ey = ih; 14125 py = ih; 14126 while (py > sy) { 14127 alpha = data[(py - 1) * 4 + 3]; 14128 if (alpha === 0) { 14129 ey = py; 14130 } else { 14131 sy = py; 14132 } 14133 py = (ey + sy) >> 1; 14134 } 14135 ratio = py / ih; 14136 if (ratio === 0) { 14137 return 1; 14138 } else { 14139 return ratio; 14140 } 14141 }; 14142 14143 drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { 14144 var vertSquashRatio; 14145 vertSquashRatio = detectVerticalSquash(img); 14146 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); 14147 }; 14148 14149 14150 /* 14151 * contentloaded.js 14152 * 14153 * Author: Diego Perini (diego.perini at gmail.com) 14154 * Summary: cross-browser wrapper for DOMContentLoaded 14155 * Updated: 20101020 14156 * License: MIT 14157 * Version: 1.2 14158 * 14159 * URL: 14160 * http://javascript.nwbox.com/ContentLoaded/ 14161 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE 14162 */ 14163 14164 contentLoaded = function(win, fn) { 14165 var add, doc, done, init, poll, pre, rem, root, top; 14166 done = false;
14167 top = true; 14168 doc = win.document; 14169 root = doc.documentElement; 14170 add = (doc.addEventListener ? "addEventListener" : "attachEvent"); 14171 rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); 14172 pre = (doc.addEventListener ? "" : "on"); 14173 init = function(e) { 14174 if (e.type === "readystatechange" && doc.readyState !== "complete") { 14175 return; 14176 } 14177 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); 14178 if (!done && (done = true)) { 14179 return fn.call(win, e.type || e); 14180 } 14181 }; 14182 poll = function() { 14183 var e; 14184 try { 14185 root.doScroll("left"); 14186 } catch (_error) { 14187 e = _error; 14188 setTimeout(poll, 50); 14189 return; 14190 } 14191 return init("poll"); 14192 }; 14193 if (doc.readyState !== "complete") { 14194 if (doc.createEventObject && root.doScroll) { 14195 try { 14196 top = !win.frameElement; 14197 } catch (_error) {} 14198 if (top) { 14199 poll(); 14200 } 14201 } 14202 doc[add](pre + "DOMContentLoaded", init, false); 14203 doc[add](pre + "readystatechange", init, false); 14204 return win[add](pre + "load", init, false); 14205 } 14206 }; 14207 14208 Dropzone._autoDiscoverFunction = function() { 14209 if (Dropzone.autoDiscover) { 14210 return Dropzone.discover(); 14211 } 14212 }; 14213 14214 contentLoaded(window, Dropzone._autoDiscoverFunction); 14215 14216}).call(this); 14217/** 14218 * menu-aim is a jQuery plugin for dropdown menus that can differentiate 14219 * between a user trying hover over a dropdown item vs trying to navigate into 14220 * a submenu's contents. 14221 * 14222 * menu-aim assumes that you have are using a menu with submenus that expand 14223 * to the menu's right. It will fire events when the user's mouse enters a new 14224 * dropdown item *and* when that item is being intentionally hovered over. 14225 * 14226 * __________________________ 14227 * | Monkeys >| Gorilla | 14228 * | Gorillas >| Content | 14229 * | Chimps >| Here | 14230 * |___________|____________| 14231 * 14232 * In the above example, "Gorillas" is selected and its submenu content is 14233 * being shown on the right. Imagine that the user's cursor is hovering over 14234 * "Gorillas." When they move their mouse into the "Gorilla Content" area, they 14235 * may briefly hover over "Chimps." This shouldn't close the "Gorilla Content" 14236 * area. 14237 * 14238 * This problem is normally solved using timeouts and delays. menu-aim tries to 14239 * solve this by detecting the direction of the user's mouse movement. This can 14240 * make for quicker transitions when navigating up and down the menu. The 14241 * experience is hopefully similar to amazon.com/'s "Shop by Department" 14242 * dropdown. 14243 * 14244 * Use like so: 14245 * 14246 * $("#menu").menuAim({ 14247 * activate: $.noop, // fired on row activation 14248 * deactivate: $.noop // fired on row deactivation 14249 * }); 14250 * 14251 * ...to receive events when a menu's row has been purposefully (de)activated. 14252 * 14253 * The following options can be passed to menuAim. All functions execute with 14254 * the relevant row's HTML element as the execution context ('this'): 14255 * 14256 * .menuAim({ 14257 * // Function to call when a row is purposefully activated. Use this 14258 * // to show a submenu's content for the activated row. 14259 * activate: function() {}, 14260 * 14261 * // Function to call when a row is deactivated. 14262 * deactivate: function() {}, 14263 * 14264 * // Function to call when mouse enters a menu row. Entering a row 14265 * // does not mean the row has been activated, as the user may be 14266 * // mousing over to a submenu. 14267 * enter: function() {}, 14268 * 14269 * // Function to call when mouse exits a menu row. 14270 * exit: function() {}, 14271 * 14272 * // Selector for identifying which elements in the menu are rows 14273 * // that can trigger the above events. Defaults to "> li". 14274 * rowSelector: "> li", 14275 * 14276 * // You may have some menu rows that aren't submenus and therefore 14277 * // shouldn't ever need to "activate." If so, filter submenu rows w/ 14278 * // this selector. Defaults to "*" (all elements). 14279 * submenuSelector: "*", 14280 * 14281 * // Direction the submenu opens relative to the main menu. Can be 14282 * // left, right, above, or below. Defaults to "right". 14283 * submenuDirection: "right" 14284 * }); 14285 * 14286 * https://github.com/kamens/jQuery-menu-aim 14287*/ 14288(function($) { 14289 14290 $.fn.menuAim = function(opts) { 14291 // Initialize menu-aim for all elements in jQuery collection 14292 this.each(function() { 14293 init.call(this, opts); 14294 }); 14295 14296 return this; 14297 }; 14298 14299 function init(opts) { 14300 var $menu = $(this), 14301 activeRow = null, 14302 mouseLocs = [], 14303 lastDelayLoc = null, 14304 timeoutId = null, 14305 options = $.extend({ 14306 rowSelector: "> li", 14307 submenuSelector: "*", 14308 submenuDirection: "right", 14309 tolerance: 75, // bigger = more forgivey when entering submenu 14310 enter: $.noop, 14311 exit: $.noop, 14312 activate: $.noop, 14313 deactivate: $.noop, 14314 exitMenu: $.noop 14315 }, opts); 14316 14317 var MOUSE_LOCS_TRACKED = 3, // number of past mouse locations to track 14318 DELAY = 300; // ms delay when user appears to be entering submenu 14319 14320 /** 14321 * Keep track of the last few locations of the mouse. 14322 */ 14323 var mousemoveDocument = function(e) { 14324 mouseLocs.push({x: e.pageX, y: e.pageY}); 14325 14326 if (mouseLocs.length > MOUSE_LOCS_TRACKED) { 14327 mouseLocs.shift(); 14328 } 14329 }; 14330 14331 /** 14332 * Cancel possible row activations when leaving the menu entirely 14333 */ 14334 var mouseleaveMenu = function() { 14335 if (timeoutId) { 14336 clearTimeout(timeoutId); 14337 } 14338 14339 // If exitMenu is supplied and returns true, deactivate the 14340 // currently active row on menu exit. 14341 if (options.exitMenu(this)) { 14342 if (activeRow) { 14343 options.deactivate(activeRow); 14344 } 14345 14346 activeRow = null; 14347 } 14348 }; 14349 14350 /** 14351 * Trigger a possible row activation whenever entering a new row. 14352 */ 14353 var mouseenterRow = function() { 14354 if (timeoutId) { 14355 // Cancel any previous activation delays 14356 clearTimeout(timeoutId); 14357 } 14358 14359 options.enter(this); 14360 possiblyActivate(this); 14361 }, 14362 mouseleaveRow = function() { 14363 options.exit(this); 14364 }; 14365 14366 /* 14367 * Immediately activate a row if the user clicks on it. 14368 */ 14369 var clickRow = function() { 14370 activate(this); 14371 }; 14372 14373 /** 14374 * Activate a menu row. 14375 */ 14376 var activate = function(row) { 14377 if (row == activeRow) { 14378 return; 14379 } 14380 14381 if (activeRow) { 14382 options.deactivate(activeRow); 14383 } 14384 14385 options.activate(row); 14386 activeRow = row; 14387 }; 14388 14389 /** 14390 * Possibly activate a menu row. If mouse movement indicates that we 14391 * shouldn't activate yet because user may be trying to enter 14392 * a submenu's content, then delay and check again later. 14393 */ 14394 var possiblyActivate = function(row) {
14395 var delay = activationDelay(); 14396 14397 if (delay) { 14398 timeoutId = setTimeout(function() { 14399 possiblyActivate(row); 14400 }, delay); 14401 } else { 14402 activate(row); 14403 } 14404 }; 14405 14406 /** 14407 * Return the amount of time that should be used as a delay before the 14408 * currently hovered row is activated. 14409 * 14410 * Returns 0 if the activation should happen immediately. Otherwise, 14411 * returns the number of milliseconds that should be delayed before 14412 * checking again to see if the row should be activated. 14413 */ 14414 var activationDelay = function() { 14415 if (!activeRow || !$(activeRow).is(options.submenuSelector)) { 14416 // If there is no other submenu row already active, then 14417 // go ahead and activate immediately. 14418 return 0; 14419 } 14420 14421 var offset = $menu.offset(), 14422 upperLeft = { 14423 x: offset.left, 14424 y: offset.top - options.tolerance 14425 }, 14426 upperRight = { 14427 x: offset.left + $menu.outerWidth(), 14428 y: upperLeft.y 14429 }, 14430 lowerLeft = { 14431 x: offset.left, 14432 y: offset.top + $menu.outerHeight() + options.tolerance 14433 }, 14434 lowerRight = { 14435 x: offset.left + $menu.outerWidth(), 14436 y: lowerLeft.y 14437 }, 14438 loc = mouseLocs[mouseLocs.length - 1], 14439 prevLoc = mouseLocs[0]; 14440 14441 if (!loc) { 14442 return 0; 14443 } 14444 14445 if (!prevLoc) { 14446 prevLoc = loc; 14447 } 14448 14449 if (prevLoc.x < offset.left || prevLoc.x > lowerRight.x || 14450 prevLoc.y < offset.top || prevLoc.y > lowerRight.y) { 14451 // If the previous mouse location was outside of the entire 14452 // menu's bounds, immediately activate. 14453 return 0; 14454 } 14455 14456 if (lastDelayLoc && 14457 loc.x == lastDelayLoc.x && loc.y == lastDelayLoc.y) { 14458 // If the mouse hasn't moved since the last time we checked 14459 // for activation status, immediately activate. 14460 return 0; 14461 } 14462 14463 // Detect if the user is moving towards the currently activated 14464 // submenu. 14465 // 14466 // If the mouse is heading relatively clearly towards 14467 // the submenu's content, we should wait and give the user more 14468 // time before activating a new row. If the mouse is heading 14469 // elsewhere, we can immediately activate a new row. 14470 // 14471 // We detect this by calculating the slope formed between the 14472 // current mouse location and the upper/lower right points of 14473 // the menu. We do the same for the previous mouse location. 14474 // If the current mouse location's slopes are 14475 // increasing/decreasing appropriately compared to the 14476 // previous's, we know the user is moving toward the submenu. 14477 // 14478 // Note that since the y-axis increases as the cursor moves 14479 // down the screen, we are looking for the slope between the 14480 // cursor and the upper right corner to decrease over time, not 14481 // increase (somewhat counterintuitively). 14482 function slope(a, b) { 14483 return (b.y - a.y) / (b.x - a.x); 14484 }; 14485 14486 var decreasingCorner = upperRight, 14487 increasingCorner = lowerRight; 14488 14489 // Our expectations for decreasing or increasing slope values 14490 // depends on which direction the submenu opens relative to the 14491 // main menu. By default, if the menu opens on the right, we 14492 // expect the slope between the cursor and the upper right 14493 // corner to decrease over time, as explained above. If the 14494 // submenu opens in a different direction, we change our slope 14495 // expectations. 14496 if (options.submenuDirection == "left") { 14497 decreasingCorner = lowerLeft; 14498 increasingCorner = upperLeft; 14499 } else if (options.submenuDirection == "below") { 14500 decreasingCorner = lowerRight; 14501 increasingCorner = lowerLeft; 14502 } else if (options.submenuDirection == "above") { 14503 decreasingCorner = upperLeft; 14504 increasingCorner = upperRight; 14505 } 14506 14507 var decreasingSlope = slope(loc, decreasingCorner), 14508 increasingSlope = slope(loc, increasingCorner), 14509 prevDecreasingSlope = slope(prevLoc, decreasingCorner), 14510 prevIncreasingSlope = slope(prevLoc, increasingCorner); 14511 14512 if (decreasingSlope < prevDecreasingSlope && 14513 increasingSlope > prevIncreasingSlope) { 14514 // Mouse is moving from previous location towards the 14515 // currently activated submenu. Delay before activating a 14516 // new menu row, because user may be moving into submenu. 14517 lastDelayLoc = loc; 14518 return DELAY; 14519 } 14520 14521 lastDelayLoc = null; 14522 return 0; 14523 }; 14524 14525 /** 14526 * Hook up initial menu events 14527 */ 14528 $menu 14529 .mouseleave(mouseleaveMenu) 14530 .find(options.rowSelector) 14531 .mouseenter(mouseenterRow) 14532 .mouseleave(mouseleaveRow) 14533 .click(clickRow); 14534 14535 $(document).mousemove(mousemoveDocument); 14536 14537 }; 14538})(jQuery); 14539 14540// Textarea and select clone() bug workaround | Spencer Tipping 14541// Licensed under the terms of the MIT source code license 14542 14543// Motivation. 14544// jQuery's clone() method works in most cases, but it fails to copy the value of textareas and select elements. This patch replaces jQuery's clone() method with a wrapper that fills in the 14545// values after the fact. 14546 14547// An interesting error case submitted by Piotr Przybyl: If two <select> options had the same value, the clone() method would select the wrong one in the cloned box. The fix, suggested by Piotr 14548// and implemented here, is to use the selectedIndex property on the <select> box itself rather than relying on jQuery's value-based val(). 14549 14550(function (original) { 14551 jQuery.fn.clone = function () { 14552 var result = original.apply(this, arguments), 14553 my_textareas = this.find('textarea').add(this.filter('textarea')), 14554 result_textareas = result.find('textarea').add(result.filter('textarea')), 14555 my_selects = this.find('select').add(this.filter('select')), 14556 result_selects = result.find('select').add(result.filter('select')); 14557 14558 for (var i = 0, l = my_textareas.length; i < l; ++i) $(result_textareas[i]).val($(my_textareas[i]).val()); 14559 for (var i = 0, l = my_selects.length; i < l; ++i) { 14560 for (var j = 0, m = my_selects[i].options.length; j < m; ++j) { 14561 if (my_selects[i].options[j].selected === true) { 14562 result_selects[i].options[j].selected = true; 14563 } 14564 } 14565 } 14566 return result; 14567 }; 14568}) (jQuery.fn.clone); 14569 14570// Generated by SDoc ; 14571//! moment.js 14572//! version : 2.18.1 14573//! authors : Tim Wood, Iskren Chernev, Moment.js contributors 14574//! license : MIT 14575//! momentjs.com 14576!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return sd.apply(null,arguments)}function b(a){sd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)return!1;return!0}function f(a){return void 0===a}
14576function g(a){return"number"==typeof a||"[object Number]"===Object.prototype.toString.call(a)}function h(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function i(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function j(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function k(a,b){for(var c in b)j(b,c)&&(a[c]=b[c]);return j(b,"toString")&&(a.toString=b.toString),j(b,"valueOf")&&(a.valueOf=b.valueOf),a}function l(a,b,c,d){return sb(a,b,c,d,!0).utc()}function m(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function n(a){return null==a._pf&&(a._pf=m()),a._pf}function o(a){if(null==a._isValid){var b=n(a),c=ud.call(b.parsedDateParts,function(a){return null!=a}),d=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c);if(a._strict&&(d=d&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour),null!=Object.isFrozen&&Object.isFrozen(a))return d;a._isValid=d}return a._isValid}function p(a){var b=l(NaN);return null!=a?k(n(b),a):n(b).userInvalidated=!0,b}function q(a,b){var c,d,e;if(f(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),f(b._i)||(a._i=b._i),f(b._f)||(a._f=b._f),f(b._l)||(a._l=b._l),f(b._strict)||(a._strict=b._strict),f(b._tzm)||(a._tzm=b._tzm),f(b._isUTC)||(a._isUTC=b._isUTC),f(b._offset)||(a._offset=b._offset),f(b._pf)||(a._pf=n(b)),f(b._locale)||(a._locale=b._locale),vd.length>0)for(c=0;c<vd.length;c++)d=vd[c],e=b[d],f(e)||(a[d]=e);return a}function r(b){q(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),wd===!1&&(wd=!0,a.updateOffset(this),wd=!1)}function s(a){return a instanceof r||null!=a&&null!=a._isAMomentObject}function t(a){return a<0?Math.ceil(a)||0:Math.floor(a)}function u(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=t(b)),c}function v(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;d<e;d++)(c&&a[d]!==b[d]||!c&&u(a[d])!==u(b[d]))&&g++;return g+f}function w(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function x(b,c){var d=!0;return k(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,b),d){for(var e,f=[],g=0;g<arguments.length;g++){if(e="","object"==typeof arguments[g]){e+="\n["+g+"] ";for(var h in arguments[0])e+=h+": "+arguments[0][h]+", ";e=e.slice(0,-2)}else e=arguments[g];f.push(e)}w(b+"\nArguments: "+Array.prototype.slice.call(f).join("")+"\n"+(new Error).stack),d=!1}return c.apply(this,arguments)},c)}function y(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),xd[b]||(w(c),xd[b]=!0)}function z(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function A(a){var b,c;for(c in a)b=a[c],z(b)?this[c]=b:this["_"+c]=b;this._config=a,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function B(a,b){var c,e=k({},a);for(c in b)j(b,c)&&(d(a[c])&&d(b[c])?(e[c]={},k(e[c],a[c]),k(e[c],b[c])):null!=b[c]?e[c]=b[c]:delete e[c]);
14576for(c in a)j(a,c)&&!j(b,c)&&d(a[c])&&(e[c]=k({},e[c]));return e}function C(a){null!=a&&this.set(a)}function D(a,b,c){var d=this._calendar[a]||this._calendar.sameElse;return z(d)?d.call(b,c):d}function E(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function F(){return this._invalidDate}function G(a){return this._ordinal.replace("%d",a)}function H(a,b,c,d){var e=this._relativeTime[c];return z(e)?e(a,b,c,d):e.replace(/%d/i,a)}function I(a,b){var c=this._relativeTime[a>0?"future":"past"];return z(c)?c(b):c.replace(/%s/i,b)}function J(a,b){var c=a.toLowerCase();Hd[c]=Hd[c+"s"]=Hd[b]=a}function K(a){return"string"==typeof a?Hd[a]||Hd[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)j(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(a,b){Id[a]=b}function N(a){var b=[];for(var c in a)b.push({unit:c,priority:Id[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function O(b,c){return function(d){return null!=d?(Q(this,b,d),a.updateOffset(this,c),this):P(this,b)}}function P(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function Q(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function R(a){return a=K(a),z(this[a])?this[a]():this}function S(a,b){if("object"==typeof a){a=L(a);for(var c=N(a),d=0;d<c.length;d++)this[c[d].unit](a[c[d].unit])}else if(a=K(a),z(this[a]))return this[a](b);return this}function T(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function U(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Md[a]=e),b&&(Md[b[0]]=function(){return T(e.apply(this,arguments),b[1],b[2])}),c&&(Md[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function V(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function W(a){var b,c,d=a.match(Jd);for(b=0,c=d.length;b<c;b++)Md[d[b]]?d[b]=Md[d[b]]:d[b]=V(d[b]);return function(b){var e,f="";for(e=0;e<c;e++)f+=z(d[e])?d[e].call(b,a):d[e];return f}}function X(a,b){return a.isValid()?(b=Y(b,a.localeData()),Ld[b]=Ld[b]||W(b),Ld[b](a)):a.localeData().invalidDate()}function Y(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Kd.lastIndex=0;d>=0&&Kd.test(a);)a=a.replace(Kd,c),Kd.lastIndex=0,d-=1;return a}function Z(a,b,c){ce[a]=z(b)?b:function(a,d){return a&&c?c:b}}function $(a,b){return j(ce,a)?ce[a](b._strict,b._locale):new RegExp(_(a))}function _(a){return aa(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function aa(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ba(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),g(b)&&(d=function(a,c){c[b]=u(a)}),c=0;c<a.length;c++)de[a[c]]=d}function ca(a,b){ba(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function da(a,b,c){null!=b&&j(de,a)&&de[a](b,c._a,c,a)}function ea(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function fa(a,b){return a?c(this._months)?this._months[a.month()]:this._months[(this._months.isFormat||oe).test(b)?"format":"standalone"][a.month()]:c(this._months)?this._months:this._months.standalone}function ga(a,b){return a?c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[oe.test(b)?"format":"standalone"][a.month()]:c(this._monthsShort)?this._monthsShort:this._monthsShort.standalone}function ha(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;d<12;++d)f=l([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null):(e=ne.call(this._longMonthsParse,g),e!==-1?e:null):"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:(e=ne.call(this._longMonthsParse,g),e!==-1?e:null)):(e=ne.call(this._longMonthsParse,g),e!==-1?e:(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null))}function ia(a,b,c){var d,e,f;if(this._monthsParseExact)return ha.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;d<12;d++){if(e=l([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ja(a,b){var c;if(!a.isValid())return a;
vendor: 7,975 bytes, line 14576
14576if("string"==typeof b)if(/^\d+$/.test(b))b=u(b);else if(b=a.localeData().monthsParse(b),!g(b))return a;return c=Math.min(a.date(),ea(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ka(b){return null!=b?(ja(this,b),a.updateOffset(this,!0),this):P(this,"Month")}function la(){return ea(this.year(),this.month())}function ma(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):(j(this,"_monthsShortRegex")||(this._monthsShortRegex=re),this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex)}function na(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsStrictRegex:this._monthsRegex):(j(this,"_monthsRegex")||(this._monthsRegex=se),this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex)}function oa(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;b<12;b++)c=l([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;b<12;b++)d[b]=aa(d[b]),e[b]=aa(e[b]);for(b=0;b<24;b++)f[b]=aa(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function pa(a){return qa(a)?366:365}function qa(a){return a%4===0&&a%100!==0||a%400===0}function ra(){return qa(this.year())}function sa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return a<100&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ta(a){var b=new Date(Date.UTC.apply(null,arguments));return a<100&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ua(a,b,c){var d=7+b-c,e=(7+ta(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return j<=0?(f=a-1,g=pa(f)+j):j>pa(a)?(f=a+1,g=j-pa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return g<1?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(pa(a)-d+e)/7}function ya(a){return wa(a,this._week.dow,this._week.doy).week}function za(){return this._week.dow}function Aa(){return this._week.doy}function Ba(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ca(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Da(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Ea(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Fa(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:c(this._weekdays)?this._weekdays:this._weekdays.standalone}function Ga(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ha(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ia(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;d<7;++d)f=l([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:null):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null):"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null)))}function Ja(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ia.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;d<7;d++){if(e=l([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function Ka(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Da(a,this.localeData()),this.add(a-b,"d")):b}function La(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Ma(a){if(!this.isValid())return null!=a?this:NaN;if(null!=a){var b=Ea(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Na(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(j(this,"_weekdaysRegex")||(this._weekdaysRegex=ye),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Oa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(j(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ze),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Pa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(j(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ae),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Qa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],j=[];for(b=0;b<7;b++)c=l([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),j.push(d),j.push(e),j.push(f);for(g.sort(a),h.sort(a),i.sort(a),j.sort(a),b=0;b<7;b++)h[b]=aa(h[b]),i[b]=aa(i[b]),j[b]=aa(j[b]);this._weekdaysRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function Ra(){return this.hours()%12||12}function Sa(){return this.hours()||24}function Ta(a,b){U(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Ua(a,b){return b._meridiemParse}function Va(a){return"p"===(a+"").toLowerCase().charAt(0)}function Wa(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Xa(a){return a?a.toLowerCase().replace("_","-"):a}function Ya(a){for(var b,c,d,e,f=0;f<a.length;){for(e=Xa(a[f]).split("-"),b=e.length,c=Xa(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=Za(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&v(e,c,!0)>=b-1)break;b--}f++}return null}function Za(a){var b=null;if(!Fe[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Be._abbr,require("./locale/"+a),$a(b)}catch(a){}return Fe[a]}function $a(a,b){var c;
14576return a&&(c=f(b)?bb(a):_a(a,b),c&&(Be=c)),Be._abbr}function _a(a,b){if(null!==b){var c=Ee;if(b.abbr=a,null!=Fe[a])y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=Fe[a]._config;else if(null!=b.parentLocale){if(null==Fe[b.parentLocale])return Ge[b.parentLocale]||(Ge[b.parentLocale]=[]),Ge[b.parentLocale].push({name:a,config:b}),null;c=Fe[b.parentLocale]._config}return Fe[a]=new C(B(c,b)),Ge[a]&&Ge[a].forEach(function(a){_a(a.name,a.config)}),$a(a),Fe[a]}return delete Fe[a],null}function ab(a,b){if(null!=b){var c,d=Ee;null!=Fe[a]&&(d=Fe[a]._config),b=B(d,b),c=new C(b),c.parentLocale=Fe[a],Fe[a]=c,$a(a)}else null!=Fe[a]&&(null!=Fe[a].parentLocale?Fe[a]=Fe[a].parentLocale:null!=Fe[a]&&delete Fe[a]);return Fe[a]}function bb(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Be;if(!c(a)){if(b=Za(a))return b;a=[a]}return Ya(a)}function cb(){return Ad(Fe)}function db(a){var b,c=a._a;return c&&n(a).overflow===-2&&(b=c[fe]<0||c[fe]>11?fe:c[ge]<1||c[ge]>
14576ea(c[ee],c[fe])?ge:c[he]<0||c[he]>24||24===c[he]&&(0!==c[ie]||0!==c[je]||0!==c[ke])?he:c[ie]<0||c[ie]>59?ie:c[je]<0||c[je]>59?je:c[ke]<0||c[ke]>999?ke:-1,n(a)._overflowDayOfYear&&(b<ee||b>ge)&&(b=ge),n(a)._overflowWeeks&&b===-1&&(b=le),n(a)._overflowWeekday&&b===-1&&(b=me),n(a).overflow=b),a}function eb(a){var b,c,d,e,f,g,h=a._i,i=He.exec(h)||Ie.exec(h);if(i){for(n(a).iso=!0,b=0,c=Ke.length;b<c;b++)if(Ke[b][1].exec(i[1])){e=Ke[b][0],d=Ke[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Le.length;b<c;b++)if(Le[b][1].exec(i[3])){f=(i[2]||" ")+Le[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Je.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),lb(a)}else a._isValid=!1}function fb(a){var b,c,d,e,f,g,h,i,j={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"},k="YXWVUTSRQPONZABCDEFGHIKLM";if(b=a._i.replace(/\([^\)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),c=Ne.exec(b)){if(d=c[1]?"ddd"+(5===c[1].length?", ":" "):"",e="D MMM "+(c[2].length>10?"YYYY ":"YY "),f="HH:mm"+(c[4]?":ss":""),c[1]){var l=new Date(c[2]),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][l.getDay()];if(c[1].substr(0,3)!==m)return n(a).weekdayMismatch=!0,void(a._isValid=!1)}switch(c[5].length){case 2:0===i?h=" +0000":(i=k.indexOf(c[5][1].toUpperCase())-12,h=(i<0?" -":" +")+(""+i).replace(/^-?/,"0").match(/..$/)[0]+"00");break;case 4:h=j[c[5]];break;default:h=j[" GMT"]}c[5]=h,a._i=c.splice(1).join(""),g=" ZZ",a._f=d+e+f+g,lb(a),n(a).rfc2822=!0}else a._isValid=!1}function gb(b){var c=Me.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(eb(b),void(b._isValid===!1&&(delete b._isValid,fb(b),b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b)))))}function hb(a,b,c){return null!=a?a:null!=b?b:c}function ib(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function jb(a){var b,c,d,e,f=[];if(!a._d){for(d=ib(a),a._w&&null==a._a[ge]&&null==a._a[fe]&&kb(a),null!=a._dayOfYear&&(e=hb(a._a[ee],d[ee]),(a._dayOfYear>pa(e)||0===a._dayOfYear)&&(n(a)._overflowDayOfYear=!0),c=ta(e,0,a._dayOfYear),a._a[fe]=c.getUTCMonth(),a._a[ge]=c.getUTCDate()),b=0;b<3&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;b<7;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[he]&&0===a._a[ie]&&0===a._a[je]&&0===a._a[ke]&&(a._nextDay=!0,a._a[he]=0),a._d=(a._useUTC?ta:sa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[he]=24)}}function kb(a){var b,c,d,e,f,g,h,i;if(b=a._w,null!=b.GG||null!=b.W||null!=b.E)f=1,g=4,c=hb(b.GG,a._a[ee],wa(tb(),1,4).year),d=hb(b.W,1),e=hb(b.E,1),(e<1||e>7)&&(i=!0);else{f=a._locale._week.dow,g=a._locale._week.doy;var j=wa(tb(),f,g);c=hb(b.gg,a._a[ee],j.year),d=hb(b.w,j.week),null!=b.d?(e=b.d,(e<0||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f}d<1||d>xa(c,f,g)?n(a)._overflowWeeks=!0:null!=i?n(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[ee]=h.year,a._dayOfYear=h.dayOfYear)}function lb(b){if(b._f===a.ISO_8601)return void eb(b);if(b._f===a.RFC_2822)return void fb(b);b._a=[],n(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Y(b._f,b._locale).match(Jd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match($(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&n(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Md[f]?(d?n(b).empty=!1:n(b).unusedTokens.push(f),da(f,d,b)):b._strict&&!d&&n(b).unusedTokens.push(f);n(b).charsLeftOver=i-j,h.length>0&&n(b).unusedInput.push(h),b._a[he]<=12&&n(b).bigHour===!0&&b._a[he]>0&&(n(b).bigHour=void 0),n(b).parsedDateParts=b._a.slice(0),n(b).meridiem=b._meridiem,b._a[he]=mb(b._locale,b._a[he],b._meridiem),jb(b),db(b)}function mb(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&b<12&&(b+=12),d||12!==b||(b=0),b):b}function nb(a){var b,c,d,e,f;if(0===a._f.length)return n(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=q({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],lb(b),o(b)&&(f+=n(b).charsLeftOver,f+=10*n(b).unusedTokens.length,n(b).score=f,(null==d||f<d)&&(d=f,c=b));k(a,c||b)}function ob(a){if(!a._d){var b=L(a._i);a._a=i([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),jb(a)}}function pb(a){var b=new r(db(qb(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function qb(a){var b=a._i,d=a._f;return a._locale=a._locale||bb(a._l),null===b||void 0===d&&""===b?p({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),s(b)?new r(db(b)):(h(b)?a._d=b:c(d)?nb(a):d?lb(a):rb(a),o(a)||(a._d=null),a))}function rb(b){var e=b._i;f(e)?b._d=new Date(a.now()):h(e)?b._d=new Date(e.valueOf()):"string"==typeof e?gb(b):c(e)?(b._a=i(e.slice(0),function(a){return parseInt(a,10)}),jb(b)):d(e)?ob(b):g(e)?b._d=new Date(e):a.createFromInputFallback(b)}
14576function sb(a,b,f,g,h){var i={};return f!==!0&&f!==!1||(g=f,f=void 0),(d(a)&&e(a)||c(a)&&0===a.length)&&(a=void 0),i._isAMomentObject=!0,i._useUTC=i._isUTC=h,i._l=f,i._i=a,i._f=b,i._strict=g,pb(i)}function tb(a,b,c,d){return sb(a,b,c,d,!1)}function ub(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return tb();for(d=b[0],e=1;e<b.length;++e)b[e].isValid()&&!b[e][a](d)||(d=b[e]);return d}function vb(){var a=[].slice.call(arguments,0);return ub("isBefore",a)}function wb(){var a=[].slice.call(arguments,0);return ub("isAfter",a)}function xb(a){for(var b in a)if(Re.indexOf(b)===-1||null!=a[b]&&isNaN(a[b]))return!1;for(var c=!1,d=0;d<Re.length;++d)if(a[Re[d]]){if(c)return!1;parseFloat(a[Re[d]])!==u(a[Re[d]])&&(c=!0)}return!0}function yb(){return this._isValid}function zb(){return Sb(NaN)}function Ab(a){var b=L(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._isValid=xb(b),this._milliseconds=+k+1e3*j+6e4*i+1e3*h*60*60,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=bb(),this._bubble()}function Bb(a){return a instanceof Ab}function Cb(a){return a<0?Math.round(-1*a)*-1:Math.round(a)}function Db(a,b){U(a,0,0,function(){var a=this.utcOffset(),c="+";return a<0&&(a=-a,c="-"),c+T(~~(a/60),2)+b+T(~~a%60,2)})}function Eb(a,b){var c=(b||"").match(a);if(null===c)return null;var d=c[c.length-1]||[],e=(d+"").match(Se)||["-",0,0],f=+(60*e[1])+u(e[2]);return 0===f?0:"+"===e[0]?f:-f}function Fb(b,c){var d,e;return c._isUTC?(d=c.clone(),e=(s(b)||h(b)?b.valueOf():tb(b).valueOf())-d.valueOf(),d._d.setTime(d._d.valueOf()+e),a.updateOffset(d,!1),d):tb(b).local()}function Gb(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Hb(b,c,d){var e,f=this._offset||0;if(!this.isValid())return null!=b?this:NaN;if(null!=b){if("string"==typeof b){if(b=Eb(_d,b),null===b)return this}else Math.abs(b)<16&&!d&&(b=60*b);return!this._isUTC&&c&&(e=Gb(this)),this._offset=b,this._isUTC=!0,null!=e&&this.add(e,"m"),f!==b&&(!c||this._changeInProgress?Xb(this,Sb(b-f,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?f:Gb(this)}function Ib(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Jb(a){return this.utcOffset(0,a)}function Kb(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Gb(this),"m")),this}function Lb(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var a=Eb($d,this._i);null!=a?this.utcOffset(a):this.utcOffset(0,!0)}return this}function Mb(a){return!!this.isValid()&&(a=a?tb(a).utcOffset():0,(this.utcOffset()-a)%60===0)}function Nb(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ob(){if(!f(this._isDSTShifted))return this._isDSTShifted;var a={};if(q(a,this),a=qb(a),a._a){var b=a._isUTC?l(a._a):tb(a._a);this._isDSTShifted=this.isValid()&&v(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Pb(){return!!this.isValid()&&!this._isUTC}function Qb(){return!!this.isValid()&&this._isUTC}function Rb(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Sb(a,b){var c,d,e,f=a,h=null;return Bb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:g(a)?(f={},b?f[b]=a:f.milliseconds=a):(h=Te.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:u(h[ge])*c,h:u(h[he])*c,m:u(h[ie])*c,s:u(h[je])*c,ms:u(Cb(1e3*h[ke]))*c}):(h=Ue.exec(a))?(c="-"===h[1]?-1:1,f={y:Tb(h[2],c),M:Tb(h[3],c),w:Tb(h[4],c),d:Tb(h[5],c),h:Tb(h[6],c),m:Tb(h[7],c),s:Tb(h[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Vb(tb(f.from),tb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new Ab(f),Bb(a)&&j(a,"_locale")&&(d._locale=a._locale),d}function Tb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Ub(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Vb(a,b){var c;return a.isValid()&&b.isValid()?(b=Fb(b,a),a.isBefore(b)?c=Ub(a,b):(c=Ub(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function Wb(a,b){return function(c,d){var e,f;
14576return null===d||isNaN(+d)||(y(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Sb(c,d),Xb(this,e,a),this}}function Xb(b,c,d,e){var f=c._milliseconds,g=Cb(c._days),h=Cb(c._months);b.isValid()&&(e=null==e||e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&Q(b,"Date",P(b,"Date")+g*d),h&&ja(b,P(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Yb(a,b){var c=a.diff(b,"days",!0);return c<-6?"sameElse":c<-1?"lastWeek":c<0?"lastDay":c<1?"sameDay":c<2?"nextDay":c<7?"nextWeek":"sameElse"}function Zb(b,c){var d=b||tb(),e=Fb(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(z(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,tb(d)))}function $b(){return new r(this)}function _b(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf())}function ac(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf())}function bc(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function cc(a,b){var c,d=s(a)?a:tb(a);return!(!this.isValid()||!d.isValid())&&(b=K(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf()))}function dc(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function ec(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function fc(a,b,c){var d,e,f,g;return this.isValid()?(d=Fb(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=gc(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:t(g)):NaN):NaN}function gc(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return b-f<0?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function hc(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ic(){if(!this.isValid())return null;var a=this.clone().utc();return a.year()<0||a.year()>9999?X(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):z(Date.prototype.toISOString)?this.toDate().toISOString():X(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function jc(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var a="moment",b="";this.isLocal()||(a=0===this.utcOffset()?"moment.utc":"moment.parseZone",b="Z");var c="["+a+'("]',d=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",e="-MM-DD[T]HH:mm:ss.SSS",f=b+'[")]';return this.format(c+d+e+f)}function kc(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=X(this,b);return this.localeData().postformat(c)}function lc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function mc(a){return this.from(tb(),a)}function nc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function oc(a){return this.to(tb(),a)}function pc(a){var b;return void 0===a?this._locale._abbr:(b=bb(a),null!=b&&(this._locale=b),this)}function qc(){return this._locale}function rc(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function sc(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function tc(){return this._d.valueOf()-6e4*(this._offset||0)}function uc(){return Math.floor(this.valueOf()/1e3)}function vc(){return new Date(this.valueOf())}function wc(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function xc(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function yc(){return this.isValid()?this.toISOString():null}function zc(){return o(this)}function Ac(){ 14577return k({},n(this))}function Bc(){return n(this).overflow}function Cc(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Dc(a,b){U(0,[a,a.length],0,b)}function Ec(a){return Ic.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Fc(a){return Ic.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Gc(){return xa(this.year(),1,4)}function Hc(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ic(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Jc.call(this,a,b,c,d,e))}
14577function Jc(a,b,c,d,e){var f=va(a,b,c,d,e),g=ta(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Kc(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Lc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Mc(a,b){b[ke]=u(1e3*("0."+a))}function Nc(){return this._isUTC?"UTC":""}function Oc(){return this._isUTC?"Coordinated Universal Time":""}function Pc(a){return tb(1e3*a)}function Qc(){return tb.apply(null,arguments).parseZone()}function Rc(a){return a}function Sc(a,b,c,d){var e=bb(),f=l().set(d,b);return e[c](f,a)}function Tc(a,b,c){if(g(a)&&(b=a,a=void 0),a=a||"",null!=b)return Sc(a,b,c,"month");var d,e=[];for(d=0;d<12;d++)e[d]=Sc(a,d,c,"month");return e}function Uc(a,b,c,d){"boolean"==typeof a?(g(b)&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,g(b)&&(c=b,b=void 0),b=b||"");var e=bb(),f=a?e._week.dow:0;if(null!=c)return Sc(b,(c+f)%7,d,"day");var h,i=[];for(h=0;h<7;h++)i[h]=Sc(b,(h+f)%7,d,"day");return i}function Vc(a,b){return Tc(a,b,"months")}function Wc(a,b){return Tc(a,b,"monthsShort")}function Xc(a,b,c){return Uc(a,b,c,"weekdays")}function Yc(a,b,c){return Uc(a,b,c,"weekdaysShort")}function Zc(a,b,c){return Uc(a,b,c,"weekdaysMin")}function $c(){var a=this._data;return this._milliseconds=df(this._milliseconds),this._days=df(this._days),this._months=df(this._months),a.milliseconds=df(a.milliseconds),a.seconds=df(a.seconds),a.minutes=df(a.minutes),a.hours=df(a.hours),a.months=df(a.months),a.years=df(a.years),this}function _c(a,b,c,d){var e=Sb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function ad(a,b){return _c(this,a,b,1)}function bd(a,b){return _c(this,a,b,-1)}function cd(a){return a<0?Math.floor(a):Math.ceil(a)}function dd(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||f<=0&&g<=0&&h<=0||(f+=864e5*cd(fd(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=t(f/1e3),i.seconds=a%60,b=t(a/60),i.minutes=b%60,c=t(b/60),i.hours=c%24,g+=t(c/24),e=t(ed(g)),h+=e,g-=cd(fd(e)),d=t(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function ed(a){return 4800*a/146097}function fd(a){return 146097*a/4800}function gd(a){if(!this.isValid())return NaN;var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+ed(b),"month"===a?c:c/12;switch(b=this._days+Math.round(fd(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function hd(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*u(this._months/12):NaN}function id(a){return function(){return this.as(a)}}function jd(a){return a=K(a),this.isValid()?this[a+"s"]():NaN}function kd(a){return function(){return this.isValid()?this._data[a]:NaN}}function ld(){return t(this.days()/7)}function md(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function nd(a,b,c){var d=Sb(a).abs(),e=uf(d.as("s")),f=uf(d.as("m")),g=uf(d.as("h")),h=uf(d.as("d")),i=uf(d.as("M")),j=uf(d.as("y")),k=e<=vf.ss&&["s",e]||e<vf.s&&["ss",e]||f<=1&&["m"]||f<vf.m&&["mm",f]||g<=1&&["h"]||g<vf.h&&["hh",g]||h<=1&&["d"]||h<vf.d&&["dd",h]||i<=1&&["M"]||i<vf.M&&["MM",i]||j<=1&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,md.apply(null,k)}function od(a){return void 0===a?uf:"function"==typeof a&&(uf=a,!0)}function pd(a,b){return void 0!==vf[a]&&(void 0===b?vf[a]:(vf[a]=b,"s"===a&&(vf.ss=b-1),!0))}function qd(a){if(!this.isValid())return this.localeData().invalidDate();var b=this.localeData(),c=nd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function rd(){if(!this.isValid())return this.localeData().invalidDate();var a,b,c,d=wf(this._milliseconds)/1e3,e=wf(this._days),f=wf(this._months);a=t(d/60),b=t(a/60),d%=60,a%=60,c=t(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(m<0?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var sd,td;td=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;d<c;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var ud=td,vd=a.momentProperties=[],wd=!1,xd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var yd;yd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)j(a,b)&&c.push(b);return c};var zd,Ad=yd,Bd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Cd={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Dd="Invalid date",Ed="%d",Fd=/\d{1,2}/,Gd={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Hd={},Id={},Jd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}
vendor: 11,591 bytes, line 14577
14577|x|X|zz?|ZZ?|.)/g,Kd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ld={},Md={},Nd=/\d/,Od=/\d\d/,Pd=/\d{3}/,Qd=/\d{4}/,Rd=/[+-]?\d{6}/,Sd=/\d\d?/,Td=/\d\d\d\d?/,Ud=/\d\d\d\d\d\d?/,Vd=/\d{1,3}/,Wd=/\d{1,4}/,Xd=/[+-]?\d{1,6}/,Yd=/\d+/,Zd=/[+-]?\d+/,$d=/Z|[+-]\d\d:?\d\d/gi,_d=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[+-]?\d+(\.\d{1,3})?/,be=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,ce={},de={},ee=0,fe=1,ge=2,he=3,ie=4,je=5,ke=6,le=7,me=8;zd=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1};var ne=zd;U("M",["MM",2],"Mo",function(){return this.month()+1}),U("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),U("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),M("month",8),Z("M",Sd),Z("MM",Sd,Od),Z("MMM",function(a,b){return b.monthsShortRegex(a)}),Z("MMMM",function(a,b){return b.monthsRegex(a)}),ba(["M","MM"],function(a,b){b[fe]=u(a)-1}),ba(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[fe]=e:n(c).invalidMonth=a});var oe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,pe="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),qe="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),re=be,se=be;U("Y",0,0,function(){var a=this.year();return a<=9999?""+a:"+"+a}),U(0,["YY",2],0,function(){return this.year()%100}),U(0,["YYYY",4],0,"year"),U(0,["YYYYY",5],0,"year"),U(0,["YYYYYY",6,!0],0,"year"),J("year","y"),M("year",1),Z("Y",Zd),Z("YY",Sd,Od),Z("YYYY",Wd,Qd),Z("YYYYY",Xd,Rd),Z("YYYYYY",Xd,Rd),ba(["YYYYY","YYYYYY"],ee),ba("YYYY",function(b,c){c[ee]=2===b.length?a.parseTwoDigitYear(b):u(b)}),ba("YY",function(b,c){c[ee]=a.parseTwoDigitYear(b)}),ba("Y",function(a,b){b[ee]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return u(a)+(u(a)>68?1900:2e3)};var te=O("FullYear",!0);U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),M("week",5),M("isoWeek",5),Z("w",Sd),Z("ww",Sd,Od),Z("W",Sd),Z("WW",Sd,Od),ca(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=u(a)});var ue={dow:0,doy:6};U("d",0,"do","day"),U("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),U("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),U("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),M("day",11),M("weekday",11),M("isoWeekday",11),Z("d",Sd),Z("e",Sd),Z("E",Sd),Z("dd",function(a,b){return b.weekdaysMinRegex(a)}),Z("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Z("dddd",function(a,b){return b.weekdaysRegex(a)}),ca(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:n(c).invalidWeekday=a}),ca(["d","e","E"],function(a,b,c,d){b[d]=u(a)});var ve="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),we="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ye=be,ze=be,Ae=be;U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Ra),U("k",["kk",2],0,Sa),U("hmm",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ta("a",!0),Ta("A",!1),J("hour","h"),M("hour",13),Z("a",Ua),Z("A",Ua),Z("H",Sd),Z("h",Sd),Z("k",Sd),Z("HH",Sd,Od),Z("hh",Sd,Od),Z("kk",Sd,Od),Z("hmm",Td),Z("hmmss",Ud),Z("Hmm",Td),Z("Hmmss",Ud),ba(["H","HH"],he),ba(["k","kk"],function(a,b,c){var d=u(a);b[he]=24===d?0:d}),ba(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),ba(["h","hh"],function(a,b,c){b[he]=u(a),n(c).bigHour=!0}),ba("hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d)),n(c).bigHour=!0}),ba("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e)),n(c).bigHour=!0}),ba("Hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d))}),ba("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e))});var Be,Ce=/[ap]\.?m?\.?/i,De=O("Hours",!0),Ee={calendar:Bd,longDateFormat:Cd,invalidDate:Dd,ordinal:Ed,dayOfMonthOrdinalParse:Fd,relativeTime:Gd,months:pe,monthsShort:qe,week:ue,weekdays:ve,weekdaysMin:xe,weekdaysShort:we,meridiemParse:Ce},Fe={},Ge={},He=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ie=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Je=/Z|[+-]\d\d(?::?\d\d)?/,Ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Le=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Me=/^\/?Date\((\-?\d+)/i,Ne=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;a.createFromInputFallback=x("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),a.ISO_8601=function(){},a.RFC_2822=function(){};var Oe=x("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a<this?this:a:p()}),Pe=x("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:p()}),Qe=function(){return Date.now?Date.now():+new Date},Re=["year","quarter","month","week","day","hour","minute","second","millisecond"];Db("Z",":"),Db("ZZ",""),Z("Z",_d),Z("ZZ",_d),ba(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Eb(_d,a)});var Se=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Te=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ue=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Sb.fn=Ab.prototype,Sb.invalid=zb;var Ve=Wb(1,"add"),We=Wb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xe=x("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});U(0,["gg",2],0,function(){return this.weekYear()%100}),U(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Dc("gggg","weekYear"),Dc("ggggg","weekYear"),Dc("GGGG","isoWeekYear"),Dc("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),M("weekYear",1),M("isoWeekYear",1),Z("G",Zd),Z("g",Zd),Z("GG",Sd,Od),Z("gg",Sd,Od),Z("GGGG",Wd,Qd),Z("gggg",Wd,Qd),Z("GGGGG",Xd,Rd),Z("ggggg",Xd,Rd),ca(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=u(a)}),ca(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),U("Q",0,"Qo","quarter"),J("quarter","Q"),M("quarter",7),Z("Q",Nd),ba("Q",function(a,b){b[fe]=3*(u(a)-1)}),U("D",["DD",2],"Do","date"),J("date","D"),M("date",9),Z("D",Sd),Z("DD",Sd,Od),Z("Do",function(a,b){return a?b._dayOfMonthOrdinalParse||b._ordinalParse:b._dayOfMonthOrdinalParseLenient}),ba(["D","DD"],ge),ba("Do",function(a,b){b[ge]=u(a.match(Sd)[0],10)});var Ye=O("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),M("dayOfYear",4),Z("DDD",Vd),Z("DDDD",Pd),ba(["DDD","DDDD"],function(a,b,c){c._dayOfYear=u(a)}),U("m",["mm",2],0,"minute"),J("minute","m"),M("minute",14),Z("m",Sd),Z("mm",Sd,Od),ba(["m","mm"],ie);var Ze=O("Minutes",!1);U("s",["ss",2],0,"second"),J("second","s"),M("second",15),Z("s",Sd),Z("ss",Sd,Od),ba(["s","ss"],je);var $e=O("Seconds",!1);U("S",0,0,function(){return~~(this.millisecond()/100)}),U(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),U(0,["SSS",3],0,"millisecond"),U(0,["SSSS",4],0,function(){return 10*this.millisecond()}),U(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),U(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),U(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),U(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),U(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),M("millisecond",16),Z("S",Vd,Nd),Z("SS",Vd,Od),Z("SSS",Vd,Pd);var _e;for(_e="SSSS";_e.length<=9;_e+="S")Z(_e,Yd);for(_e="S";_e.length<=9;_e+="S")ba(_e,Mc);var af=O("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var bf=r.prototype;bf.add=Ve,bf.calendar=Zb,bf.clone=$b,bf.diff=fc,bf.endOf=sc,bf.format=kc,bf.from=lc,bf.fromNow=mc,bf.to=nc,bf.toNow=oc,bf.get=R,bf.invalidAt=Bc,bf.isAfter=_b,bf.isBefore=ac,bf.isBetween=bc,bf.isSame=cc,bf.isSameOrAfter=dc,bf.isSameOrBefore=ec,bf.isValid=zc,bf.lang=Xe,bf.locale=pc,bf.localeData=qc,bf.max=Pe,bf.min=Oe,bf.parsingFlags=Ac,bf.set=S,bf.startOf=rc,bf.subtract=We,bf.toArray=wc,bf.toObject=xc,bf.toDate=vc,bf.toISOString=ic,bf.inspect=jc,bf.toJSON=yc,bf.toString=hc,bf.unix=uc,bf.valueOf=tc,bf.creationData=Cc,bf.year=te,bf.isLeapYear=ra,bf.weekYear=Ec,bf.isoWeekYear=Fc,bf.quarter=bf.quarters=Kc,bf.month=ka,bf.daysInMonth=la,bf.week=bf.weeks=Ba,bf.isoWeek=bf.isoWeeks=Ca,bf.weeksInYear=Hc,bf.isoWeeksInYear=Gc,bf.date=Ye,bf.day=bf.days=Ka,bf.weekday=La,bf.isoWeekday=Ma,bf.dayOfYear=Lc,bf.hour=bf.hours=De,bf.minute=bf.minutes=Ze,bf.second=bf.seconds=$e,bf.millisecond=bf.milliseconds=af,bf.utcOffset=Hb,bf.utc=Jb,bf.local=Kb,bf.parseZone=Lb,bf.hasAlignedHourOffset=Mb,bf.isDST=Nb,bf.isLocal=Pb,bf.isUtcOffset=Qb,bf.isUtc=Rb,bf.isUTC=Rb,bf.zoneAbbr=Nc,bf.zoneName=Oc,bf.dates=x("dates accessor is deprecated. Use date instead.",Ye),bf.months=x("months accessor is deprecated. Use month instead",ka),bf.years=x("years accessor is deprecated. Use year instead",te),bf.zone=x("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ib),bf.isDSTShifted=x("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ob);var cf=C.prototype;cf.calendar=D,cf.longDateFormat=E,cf.invalidDate=F,cf.ordinal=G,cf.preparse=Rc,cf.postformat=Rc,cf.relativeTime=H,cf.pastFuture=I,cf.set=A,cf.months=fa,cf.monthsShort=ga,cf.monthsParse=ia,cf.monthsRegex=na,cf.monthsShortRegex=ma,cf.week=ya,cf.firstDayOfYear=Aa,cf.firstDayOfWeek=za,cf.weekdays=Fa,cf.weekdaysMin=Ha,cf.weekdaysShort=Ga,cf.weekdaysParse=Ja,cf.weekdaysRegex=Na,cf.weekdaysShortRegex=Oa,cf.weekdaysMinRegex=Pa,cf.isPM=Va,cf.meri
14577diem=Wa,$a("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===u(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=x("moment.lang is deprecated. Use moment.locale instead.",$a),a.langData=x("moment.langData is deprecated. Use moment.localeData instead.",bb);var df=Math.abs,ef=id("ms"),ff=id("s"),gf=id("m"),hf=id("h"),jf=id("d"),kf=id("w"),lf=id("M"),mf=id("y"),nf=kd("milliseconds"),of=kd("seconds"),pf=kd("minutes"),qf=kd("hours"),rf=kd("days"),sf=kd("months"),tf=kd("years"),uf=Math.round,vf={ss:44,s:45,m:45,h:22,d:26,M:11},wf=Math.abs,xf=Ab.prototype;return xf.isValid=yb,xf.abs=$c,xf.add=ad,xf.subtract=bd,xf.as=gd,xf.asMilliseconds=ef,xf.asSeconds=ff,xf.asMinutes=gf,xf.asHours=hf,xf.asDays=jf,xf.asWeeks=kf,xf.asMonths=lf,xf.asYears=mf,xf.valueOf=hd,xf._bubble=dd,xf.get=jd,xf.milliseconds=nf,xf.seconds=of,xf.minutes=pf,xf.hours=qf,xf.days=rf,xf.weeks=ld,xf.months=sf,xf.years=tf,xf.humanize=qd,xf.toISOString=rd,xf.toString=rd,xf.toJSON=rd,xf.locale=pc,xf.localeData=qc,xf.toIsoString=x("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",rd),xf.lang=Xe,U("X",0,0,"unix"),U("x",0,0,"valueOf"),Z("x",Zd),Z("X",ae),ba("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),ba("x",function(a,b,c){c._d=new Date(u(a))}),a.version="2.18.1",b(tb),a.fn=bf,a.min=vb,a.max=wb,a.now=Qe,a.utc=l,a.unix=Pc,a.months=Vc,a.isDate=h,a.locale=$a,a.invalid=p,a.duration=Sb,a.isMoment=s,a.weekdays=Xc,a.parseZone=Qc,a.localeData=bb,a.isDuration=Bb,a.monthsShort=Wc,a.weekdaysMin=Zc,a.defineLocale=_a,a.updateLocale=ab,a.locales=cb,a.weekdaysShort=Yc,a.normalizeUnits=K,a.relativeTimeRounding=od,a.relativeTimeThreshold=pd,a.calendarFormat=Yb,a.prototype=bf,a}); 14578//! moment.js locale configuration 14579//! locale : catalan (ca) 14580//! author : Juan G. Hurtado : https://github.com/juanghurtado 14581 14582(function (global, factory) { 14583 typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) : 14584 typeof define === 'function' && define.amd ? define(['moment'], factory) : 14585 factory(global.moment) 14586}(this, function (moment) { 'use strict'; 14587 14588 14589 var ca = moment.defineLocale('ca', { 14590 months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), 14591 monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'), 14592 weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), 14593 weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), 14594 weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'), 14595 longDateFormat : { 14596 LT : 'H:mm', 14597 LTS : 'LT:ss', 14598 L : 'DD/MM/YYYY', 14599 LL : 'D MMMM YYYY', 14600 LLL : 'D MMMM YYYY LT', 14601 LLLL : 'dddd D MMMM YYYY LT' 14602 }, 14603 calendar : { 14604 sameDay : function () { 14605 return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; 14606 }, 14607 nextDay : function () { 14608 return '[demàa ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; 14609 }, 14610 nextWeek : function () { 14611 return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; 14612 }, 14613 lastDay : function () { 14614 return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; 14615 }, 14616 lastWeek : function () { 14617 return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; 14618 }, 14619 sameElse : 'L' 14620 }, 14621 relativeTime : { 14622 future : 'en %s', 14623 past : 'fa %s', 14624 s : 'uns segons', 14625 m : 'un minut', 14626 mm : '%d minuts', 14627 h : 'una hora', 14628 hh : '%d hores', 14629 d : 'un dia', 14630 dd : '%d dies', 14631 M : 'un mes', 14632 MM : '%d mesos', 14633 y : 'un any', 14634 yy : '%d anys' 14635 }, 14636 ordinalParse: /\d{1,2}(r|n|t|è|a)/, 14637 ordinal : function (number, period) { 14638 var output = (number === 1) ? 'r' : 14639 (number === 2) ? 'n' : 14640 (number === 3) ? 'r' : 14641 (number === 4) ? 't' : 'è'; 14642 if (period === 'w' || period === 'W') { 14643 output = 'a'; 14644 } 14645 return number + output; 14646 }, 14647 week : { 14648 dow : 1, // Monday is the first day of the week. 14649 doy : 4 // The week that contains Jan 4th is the first week of the year. 14650 } 14651 }); 14652 14653 return ca; 14654 14655})); 14656//! moment.js locale configuration 14657//! locale : spanish (es) 14658//! author : Julio Napurà: https://github.com/julionc 14659 14660(function (global, factory) { 14661 typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) : 14662 typeof define === 'function' && define.amd ? define(['moment'], factory) : 14663 factory(global.moment) 14664}(this, function (moment) { 'use strict'; 14665 14666 14667 var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), 14668 monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); 14669 14670 var es = moment.defineLocale('es', { 14671 months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), 14672 monthsShort : function (m, format) { 14673 if (/-MMM-/.test(format)) { 14674 return monthsShort[m.month()]; 14675 } else { 14676 return monthsShortDot[m.month()]; 14677 } 14678 }, 14679 weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), 14680 weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), 14681 weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'), 14682 longDateFormat : { 14683 LT : 'H:mm', 14684 LTS : 'LT:ss', 14685 L : 'DD/MM/YYYY', 14686 LL : 'D [de] MMMM [de] YYYY', 14687 LLL : 'D [de] MMMM [de] YYYY LT', 14688 LLLL : 'dddd, D [de] MMMM [de] YYYY LT' 14689 }, 14690 calendar : { 14691 sameDay : function () { 14692 return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; 14693 }, 14694 nextDay : function () { 14695 return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; 14696 }, 14697 nextWeek : function () { 14698 return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; 14699 }, 14700 lastDay : function () { 14701 return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; 14702 }, 14703 lastWeek : function () { 14704 return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; 14705 }, 14706 sameElse : 'L' 14707 }, 14708 relativeTime : { 14709 future : 'en %s', 14710 past : 'hace %s', 14711 s : 'unos segundos', 14712 m : 'un minuto', 14713 mm : '%d minutos', 14714 h : 'una hora', 14715 hh : '%d horas', 14716 d : 'un dÃÂa', 14717 dd : '%d dÃÂas', 14718 M : 'un mes', 14719 MM : '%d meses', 14720 y : 'un año', 14721 yy : '%d años' 14722 }, 14723 ordinalParse : /\d{1,2}º/, 14724 ordinal : '%dº', 14725 week : { 14726 dow : 1, // Monday is the first day of the week. 14727 doy : 4 // The week that contains Jan 4th is the first week of the year. 14728 } 14729 }); 14730 14731 return es; 14732 14733})); 14734//! moment.js locale configuration 14735//! locale : Basque [eu] 14736//! author : Eneko Illarramendi : https://github.com/eillarra 14737 14738;(function (global, factory) { 14739 typeof exports === 'object' && typeof module !== 'undefined' 14740 && typeof require === 'function' ? factory(require('../moment')) : 14741 typeof define === 'function' && define.amd ? define(['../moment'], factory) : 14742 factory(global.moment) 14743}(this, (function (moment) { 'use strict'; 14744 14745 14746var eu = moment.defineLocale('eu', { 14747 months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), 14748 monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), 14749 monthsParseExact : true, 14750 weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), 14751 weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), 14752 weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), 14753 weekdaysParseExact : true, 14754 longDateFormat : { 14755 LT : 'HH:mm', 14756 LTS : 'HH:mm:ss', 14757 L : 'YYYY-MM-DD', 14758 LL : 'YYYY[ko] MMMM[ren] D[a]', 14759 LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', 14760 LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', 14761 l : 'YYYY-M-D', 14762 ll : 'YYYY[ko] MMM D[a]', 14763 lll : 'YYYY[ko] MMM D[a] HH:mm', 14764 llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' 14765 }, 14766 calendar : { 14767 sameDay : '[gaur] LT[etan]', 14768 nextDay : '[bihar] LT[etan]', 14769 nextWeek : 'dddd LT[etan]', 14770 lastDay : '[atzo] LT[etan]', 14771 lastWeek : '[aurreko] dddd LT[etan]', 14772 sameElse : 'L' 14773 }, 14774 relativeTime : { 14775 future : '%s barru', 14776 past : 'duela %s', 14777 s : 'segundo batzuk', 14778 ss : '%d segundo', 14779 m : 'minutu bat', 14780 mm : '%d minutu', 14781 h : 'ordu bat', 14782 hh : '%d ordu', 14783 d : 'egun bat', 14784 dd : '%d egun', 14785 M : 'hilabete bat', 14786 MM : '%d hilabete', 14787 y : 'urte bat', 14788 yy : '%d urte' 14789 }, 14790 dayOfMonthOrdinalParse: /\d{1,2}\./, 14791 ordinal : '%d.', 14792 week : { 14793 dow : 1, // Monday is the first day of the week. 14794 doy : 7 // The week that contains Jan 1st is the first week of the year. 14795 } 14796}); 14797 14798return eu; 14799 14800}))); 14801//! moment.js locale configuration 14802//! locale : galician (gl) 14803//! author : Juan G. Hurtado : https://github.com/juanghurtado 14804 14805(function (global, factory) { 14806 typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) : 14807 typeof define === 'function' && define.amd ? define(['moment'], factory) : 14808 factory(global.moment) 14809}(this, function (moment) { 'use strict'; 14810 14811 14812 var gl = moment.defineLocale('gl', { 14813 months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'), 14814 monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'), 14815 weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'), 14816 weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'), 14817 weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'), 14818 longDateFormat : { 14819 LT : 'H:mm', 14820 LTS : 'LT:ss', 14821 L : 'DD/MM/YYYY', 14822 LL : 'D MMMM YYYY', 14823 LLL : 'D MMMM YYYY LT', 14824 LLLL : 'dddd D MMMM YYYY LT' 14825 }, 14826 calendar : { 14827 sameDay : function () { 14828 return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; 14829 }, 14830 nextDay : function () { 14831 return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; 14832 }, 14833 nextWeek : function () { 14834 return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; 14835 }, 14836 lastDay : function () { 14837 return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; 14838 }, 14839 lastWeek : function () { 14840 return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; 14841 }, 14842 sameElse : 'L' 14843 }, 14844 relativeTime : { 14845 future : function (str) { 14846 if (str === 'uns segundos') { 14847 return 'nuns segundos'; 14848 } 14849 return 'en ' + str; 14850 }, 14851 past : 'hai %s', 14852 s : 'uns segundos', 14853 m : 'un minuto', 14854 mm : '%d minutos', 14855 h : 'unha hora', 14856 hh : '%d horas', 14857 d : 'un dÃÂa', 14858 dd : '%d dÃÂas', 14859 M : 'un mes', 14860 MM : '%d meses', 14861 y : 'un ano', 14862 yy : '%d anos' 14863 }, 14864 ordinalParse : /\d{1,2}º/, 14865 ordinal : '%dº', 14866 week : { 14867 dow : 1, // Monday is the first day of the week. 14868 doy : 7 // The week that contains Jan 1st is the first week of the year. 14869 } 14870 }); 14871 14872 return gl; 14873 14874})); 14875/* 14876 * 14877 * Copyright (c) 2006-2014 Sam Collett (http://www.texotela.co.uk) 14878 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 14879 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 14880 * 14881 * Version 1.4.1 14882 * Demo: http://www.texotela.co.uk/code/jquery/numeric/ 14883 * 14884 */ 14885(function(factory){if(typeof define === 'function' && define.amd){define(['jquery'], factory);}else{factory(window.jQuery);}}(function($){$.fn.numeric=function(config,callback){if(typeof config==="boolean"){config={decimal:config,negative:true,decimalPlaces:-1}}config=config||{};if(typeof config.negative=="undefined"){config.negative=true}var decimal=config.decimal===false?"":config.decimal||".";var altDecimal=config.altDecimal===false?"": config.altDecimal||decimal;var negative=config.negative===true?true:false;var decimalPlaces=typeof config.decimalPlaces=="undefined"?-1:config.decimalPlaces;callback=typeof callback=="function"?callback:function(){};return this.data("numeric.decimal",decimal).data("numeric.altDecimal",altDecimal).data("numeric.negative",negative).data("numeric.callback",callback).data("numeric.decimalPlaces",decimalPlaces).keypress($.fn.numeric.keypress).keyup($.fn.numeric.keyup).blur($.fn.numeric.blur)};$.fn.numeric.keypress=function(e){var decimal=$.data(this,"numeric.decimal");var negative=$.data(this,"numeric.negative");var decimalPlaces=$.data(this,"numeric.decimalPlaces");var altDecimal=$.data(this,"numeric.altDecimal");var key=e.charCode?e.charCode:e.keyCode?e.keyCode:0;if(key==13&&this.nodeName.toLowerCase()=="input"){return true}else if(key==13){return false}var allow=false;if(e.ctrlKey&&key==97||e.ctrlKey&&key==65){return true}if(e.ctrlKey&&key==120||e.ctrlKey&&key==88){return true}if(e.ctrlKey&&key==99||e.ctrlKey&&key==67){return true}if(e.ctrlKey&&key==122||e.ctrlKey&&key==90){return true}if(e.ctrlKey&&key==118||e.ctrlKey&&key==86||e.shiftKey&&key==45){return true}if(key<48||key>57){var value=$(this).val();if($.inArray("-",value.split(""))!==0&&negative&&key==45&&(value.length===0||parseInt($.fn.getSelectionStart(this),10)===0)){return true}if(decimal&&key==decimal.charCodeAt(0)&&$.inArray(decimal,value.split(""))!=-1){allow=false}if(key!=8&&key!=9&&key!=13&&key!=35&&key!=36&&key!=37&&key!=39&&key!=46){allow=false}else{if(typeof e.charCode!="undefined"){if(e.keyCode==e.which&&e.which!==0){allow=true;if(e.which==46){allow=false}}else if(e.keyCode!==0&&e.charCode===0&&e.which===0){allow=true}}}if(decimal&&key==decimal.charCodeAt(0)||altDecimal&&key==altDecimal.charCodeAt(0)){if($.inArray(decimal,value.split(""))==-1){allow=true}else{allow=false}}}else{allow=true;if(decimal&&decimalPlaces>0){var dot=$.inArray(decimal,$(this).val().split(""));if(dot>=0&&$(this).val().length>dot+decimalPlaces){allow=false}}}return allow};$.fn.numeric.keyup=function(e){var val=$(this).val();if(val&&val.length>0){var carat=$.fn.getSelectionStart(this);var selectionEnd=$.fn.getSelectionEnd(this);var decimal=$.data(this,"numeric.decimal");var negative=$.data(this,"numeric.negative");var decimalPlaces=$.data(this,"numeric.decimalPlaces");var altDecimal=$.data(this,"numeric.altDecimal");if(decimal!==""&&decimal!==null){var dot=$.inArray(decimal,val.split(""));
14885if(dot===0){this.value="0"+val;carat++;selectionEnd++}if(dot==1&&val.charAt(0)=="-"){this.value="-0"+val.substring(1);carat++;selectionEnd++}val=this.value}var validChars=[0,1,2,3,4,5,6,7,8,9,"-",decimal];var length=val.length;for(var i=length-1;i>=0;i--){var ch=val.charAt(i);if(i!==0&&ch=="-"){val=val.substring(0,i)+val.substring(i+1)}else if(i===0&&!negative&&ch=="-"){val=val.substring(1)}var validChar=false;for(var j=0;j<validChars.length;j++){if(ch==validChars[j]){validChar=true;break}}if(!validChar&&ch==altDecimal){val=val.substring(0,i)+decimal+val.substring(i+1);validChar=true;}if(!validChar||ch==" "){val=val.substring(0,i)+val.substring(i+1)}}var firstDecimal=$.inArray(decimal,val.split(""));if(firstDecimal>0){for(var k=length-1;k>firstDecimal;k--){var chch=val.charAt(k);if(chch==decimal){val=val.substring(0,k)+val.substring(k+1)}}}if(decimal&&decimalPlaces>0){var dot=$.inArray(decimal,val.split(""));if(dot>=0){val=val.substring(0,dot+decimalPlaces+1);selectionEnd=Math.min(val.length,selectionEnd)}}this.value=val;$.fn.setSelection(this,[carat,selectionEnd])}};$.fn.numeric.blur=function(){var decimal=$.data(this,"numeric.decimal");var callback=$.data(this,"numeric.callback");var negative=$.data(this,"numeric.negative");var val=this.value;if(val!==""){var re=new RegExp("^" + (negative?"-?":"") + "\\d+$|^" + (negative?"-?":"") + "\\d*" + decimal + "\\d+$");if(!re.exec(val)){callback.apply(this)}}};$.fn.removeNumeric=function(){return this.data("numeric.decimal",null).data("numeric.altDecimal",null).data("numeric.negative",null).data("numeric.callback",null).data("numeric.decimalPlaces",null).unbind("keypress",$.fn.numeric.keypress).unbind("keyup",$.fn.numeric.keyup).unbind("blur",$.fn.numeric.blur)};$.fn.getSelectionStart=function(o){if(o.type==="number"){return undefined}else if(o.createTextRange&&document.selection){var r=document.selection.createRange().duplicate();r.moveEnd("character",o.value.length);if(r.text=="")return o.value.length;return Math.max(0,o.value.lastIndexOf(r.text))}else{try{return o.selectionStart}catch(e){return 0}}};$.fn.getSelectionEnd=function(o){if(o.type==="number"){return undefined}else if(o.createTextRange&&document.selection){var r=document.selection.createRange().duplicate();r.moveStart("character",-o.value.length);return r.text.length}else return o.selectionEnd};$.fn.setSelection=function(o,p){if(typeof p=="number"){p=[p,p]}if(p&&p.constructor==Array&&p.length==2){if(o.type==="number"){o.focus()}else if(o.createTextRange){var r=o.createTextRange();r.collapse(true);r.moveStart("character",p[0]);r.moveEnd("character",p[1]-p[0]);r.select()}else{o.focus();try{if(o.setSelectionRange){o.setSelectionRange(p[0],p[1])}}catch(e){}}}}})); 14886/** 14887 * Load HTML asynchronously 14888 * @namespace Verkami 14889 * @class Async 14890 * 14891 * Input parameters: 14892 * - "data-async-id" (required): Unique ID declared in both action and placeholder items. Example: community 14893 * - "data-async-source" (required): Source endpoint. Example: /endpoint/async/community 14894 * - "data-async-data" (optional): JSON string. This will be send as data in a POST request. Example: { "project_id": 2 } 14895 * - "data-async-trigger" (optional): Space separated JS hooks to launch functionalities 14896 * after content is loaded. Example: utils.squarize modal.open 14897 * 14898 * Output: The endpoint must return rendered HTML, it will be appended to the defined placeholder. 14899 */ 14900 14901modulejs.define("Verkami/Async", function () { 14902 var Async = { 14903 spinnerClass: "spinner", 14904 spinnerIconClass: "icon icon--spinner", 14905 14906 init: function () { 14907 this.events(); 14908 }, 14909 14910 events: function () { 14911 $(document).on("click.vk.async", ".js-async", this, this.getContent); 14912 }, 14913 14914 addSpinner: function (placeholder) { 14915 var that = this; 14916 var spinner = that.createSpinner(); 14917 14918 placeholder.css({ 14919 overflow: "hidden", 14920 position: "relative", 14921 "min-height": 200, 14922 }); 14923 14924 spinner.appendTo(placeholder); 14925 }, 14926 14927 createSpinner: function () { 14928 var spinner = $("<span/>").addClass("spinner"); 14929 var icon = $("<span/>").addClass("icon icon--spinner"); 14930 14931 icon.appendTo(spinner); 14932 14933 return spinner; 14934 }, 14935 14936 getContent: function (event) { 14937 var that = event.data; 14938 var node = $(this).hasClass("js-async") ? $(this) : $(this).closest(".
14938js-async"); 14939 var id = node.data("async-id"); 14940 var source = node.data("async-source"); 14941 var data = node.data("async-data") || {}; 14942 var trigger = node.data("async-trigger"); 14943 var placeholder = $(".js-async-placeholder[data-async-id='" + id + "']"); 14944 var isLoaded = node.data("async-loaded"); 14945 14946 if (isLoaded) return; 14947 14948 // Show spinner 14949 that.addSpinner(placeholder); 14950 14951 $.get(source, data, function (response) { 14952 node.data("async-loaded", true); 14953 14954 // Show content 14955 $(response).appendTo(placeholder); 14956 14957 // Launch triggers 14958 if (trigger) { 14959 var i; 14960 var triggers = trigger.split(" "); 14961 14962 for (i = 0; i < triggers.length; ++i) { 14963 $(document).trigger("trigger.vk." + triggers[i], placeholder); // trigger each passed param 14964 } 14965 } 14966 14967 // Hide spinner 14968 that.removeSpinner(placeholder); 14969 }).fail(function () { 14970 // Hide spinner 14971 that.removeSpinner(placeholder); 14972 }); 14973 }, 14974 14975 removeSpinner: function (placeholder) { 14976 var spinner = $(".spinner", placeholder); 14977 14978 spinner.fadeOut(function () { 14979 placeholder.css({ 14980 overflow: "", 14981 position: "", 14982 "min-height": "", 14983 }); 14984 14985 $(this).remove(); 14986 }); 14987 }, 14988 }; 14989 14990 Async.init(); 14991 14992 return Async; 14993}); 14994/** 14995 * DataTransfer 14996 * @namespace Verkami 14997 * @class DataTransfer 14998 * 14999 * Instructions: 15000 * - Trigger must have a "js-pull" class, a "data-pull" attribute with element names separated by 15001 * comma. 15002 * - Push elements must have the class "js-push-ELEMENT-NAME". 15003 * - Placeholder elements must have the class "js-placeholder-ELEMENT-NAME". 15004 * - If push content is empty, you can set a default content to avoid showing an empty string 15005 * by setting "data-placeholder-empty" attribute in the "js-placeholder-ELEMENT-NAME" item 15006 * 15007 * Note 1: dataTransfer is getting the value if is a form element, and the inner HTML if is not 15008 * 15009 * Note 2: If there more than one element with same push name, an specific ID like a timestamp must 15010 * be set as a "data-pull-id" in the trigger element, and as a "data-push-id" in the push 15011 * element. 15012 * 15013 * Note 3: If you don't want to trigger the dataTransfer on click, just avoid .js-pull class and use 15014 * DataTransfer.transfer(object). 15015 */ 15016 15017var name = "Verkami/DataTransfer"; 15018 15019modulejs.define(name, function() { 15020 var DataTransfer = { 15021 triggers: [], 15022 pushPrefix: "js-push-", 15023 placeholderPrefix: "js-placeholder-", 15024 15025 init: function() { 15026 var that = this; 15027 that.triggers = $(".js-pull"); 15028 15029 that.triggers.on("click.dataTransfer", function() { 15030 that.transfer($(this).data()); 15031 }); 15032 }, 15033 15034 refresh: function() { 15035 var that = this; 15036 that.triggers = $(".js-pull"); 15037 15038 // Update dataPullId 15039 that.triggers.each(function() { 15040 $(this).data("pull-id", $(this).attr("data-pull-id")); 15041 }); 15042 15043 that.triggers.off("click.dataTransfer").on("click.dataTransfer", function() { 15044 that.transfer($(this).data()); 15045 }); 15046 }, 15047 15048 transfer: function(settings) { 15049 var that = this; 15050 var content = ""; 15051 var dataId = settings.pullId; 15052 var dataLocale = settings.pullLocale; 15053 var pullNodes = settings.pull.split(","); 15054 var pushNode = []; 15055 var placeholderNode = []; 15056 15057 $.each(pullNodes, function(i, element) { 15058 pushNode = $("." + that.pushPrefix + element); 15059 placeholderNode = $("." + that.placeholderPrefix + element); 15060 15061 if (pushNode.length && placeholderNode.length) { 15062 if (dataId) { 15063 if (dataLocale) { 15064 pushNode = pushNode.filter("[data-push-id='" + dataId + "_" + dataLocale + "']"); 15065 placeholderNode = placeholderNode.filter("[data-pull-id='" + dataId + "_" + dataLocale + "']"); 15066 } else { 15067 pushNode = pushNode.filter("[data-push-id='" + dataId + "']"); 15068 placeholderNode = placeholderNode.filter("[data-pull-id='" + dataId + "']"); 15069 } 15070 } 15071 15072 content = pushNode.is(":input") ? pushNode.val() : pushNode.html(); 15073 15074 /** 15075 * Since frontend has not provided any way to i18n-ized JS strings we
15076 * use here 2 data attribs to provide basic interpolation: 15077 * - `data-placeholder-template` for non-empty fields where %{count} will be replaced by their value 15078 * - `data-placeholder-empty` for empty fields. 15079 * */ 15080 if (content.length && placeholderNode.is("[data-placeholder-template]")) { 15081 var template = placeholderNode.attr("data-placeholder-template"); 15082 content = template.replace(/%\{count\}/, content); 15083 } 15084 if (!content.length && placeholderNode.is("[data-placeholder-empty]")) { 15085 content = placeholderNode.attr("data-placeholder-empty"); 15086 } 15087 placeholderNode.html(content); 15088 } 15089 }); 15090 } 15091 }; 15092 15093 DataTransfer.init(); 15094 15095 return DataTransfer; 15096}); 15097/** 15098* DropCap 15099* @namespace Verkami 15100* @class DropCap 15101*/ 15102 15103var name = 'Verkami/DropCap'; 15104 15105modulejs.define(name, function() { 15106 var DropCap = { 15107 wrapper: [], 15108 className: 'drop-cap', 15109 15110 init: function() { 15111 var that = this; 15112 that.wrapper = $('.js-drop-cap'); 15113 15114 if (that.wrapper.length) { 15115 var dropCapCandidates = that.wrapper.children('p'); 15116 var hasImage = 0; 15117 var hasBlockquoteClose = 0; 15118 15119 dropCapCandidates.each(function() { 15120 hasImage = $(this).children('img').length; 15121 hasBlockquoteClose = $(this).prev('blockquote').length; 15122 15123 if (!hasImage) { 15124 if (!hasBlockquoteClose) { 15125 $(this).addClass(that.className); 15126 } 15127 15128 return false; 15129 } 15130 }); 15131 } 15132 } 15133 }; 15134 15135 DropCap.init(); 15136 15137 return DropCap; 15138}); 15139/** 15140* Loading 15141* @namespace Verkami 15142* @class Loading 15143*/ 15144 15145var name = 'Verkami/Loading'; 15146 15147modulejs.define(name, function() { 15148 var Loading = { 15149 iconClass: 'icon icon--spinner', 15150 spinnerClass: 'loading__spinner', 15151 wrapperClass: 'loading', 15152 15153 enable: function(wrapper) { 15154 var that = this; 15155 var loading = $('<div>', { class: that.spinnerClass }); 15156 15157 // Add relative position to loading wrapper 15158 wrapper.addClass(that.wrapperClass); 15159 15160 // Add spinner icon to the loading layer 15161 $('<span/>', { class: that.iconClass }).appendTo(loading); 15162 15163 // Append the loading layer to the wrapper and show it 15164 loading.appendTo(wrapper).fadeIn(); 15165 }, 15166 15167 disable: function(wrapper) { 15168 var that = this; 15169 var loading = $('.' + that.spinnerClass, wrapper); 15170 15171 // Remove relative position of loading wrapper 15172 wrapper.removeClass(that.wrapperClass); 15173 15174 // Hide the loading layer and remove it from the DOM 15175 loading.fadeOut(function() { 15176 $(this).remove(); 15177 }); 15178 } 15179 }; 15180 15181 return Loading; 15182}); 15183/** 15184* Scroll 15185* @namespace Verkami 15186* @class Scroll 15187*/ 15188 15189var name = "Verkami/Scroll"; 15190var deps = [ 15191 "Verkami/Settings" 15192]; 15193 15194modulejs.define(name, deps, function(Settings) { 15195 var Scroll = { 15196 init: function () { 15197 this.smooth.init(); 15198 }, 15199 15200 position: function () { 15201 var position = $(window).scrollTop(); 15202 15203 return position; 15204 }, 15205 15206 // Smooth scroll for internal anchors 15207 smooth: { 15208 init: function () { 15209 var that = this; 15210 15211 // All anchor links items 15212 var scrollableItems = $("a[href^=\"#\"]"); 15213 15214 // Bind click handler to menu items so we can get a fancy scroll animation 15215 scrollableItems.on("click", function (e) { 15216 e.preventDefault(); 15217 15218 var target = $(this).attr("href"); 15219 15220 if ($(target).length) { 15221 that.doScroll($(target)); 15222 } 15223 }); 15224 }, 15225 15226 doScroll: function (target, extraOffset, customContainer) { 15227 if (target.length || target === "reset") { 15228 var easeOutExpo = function (x, t, b, c, d) { 15229 return t === d ? b + c : c * (-Math.pow(2, (-10 * t) / d) + 1) + b; 15230 }; 15231 var container = customContainer ? customContainer : $("html, body"); 15232 var offsetTop = target === "reset" ? 0 : target.offset().top; 15233 var newPosition; 15234 15235 if (extraOffset) { 15236 newPosition = offsetTop - extraOffset; 15237 } else { 15238 newPosition = offsetTop; 15239 } 15240 15241 // @todo: Is it possible to remove speed and easing? They are already set in Verkami/Settings 15242 container.stop().animate({ scrollTop: newPosition }, Settings.speed, easeOutExpo); 15243 } else { 15244 return false;
15245 } 15246 }, 15247 } 15248 }; 15249 15250 Scroll.init(); 15251 15252 return Scroll; 15253}); 15254/** 15255 * Settings 15256 * @namespace Verkami 15257 * @class Settings 15258 */ 15259 15260var name = "Verkami/Settings"; 15261 15262modulejs.define(name, function () { 15263 var Settings = { 15264 delay: 1000, 15265 language: $("meta[name='language']").prop("content"), 15266 speed: 300, 15267 instantSpeed: 0, 15268 15269 init: function () { 15270 var that = this; 15271 15272 // Setting up the default animation speeds 15273 $.extend($.fx.speeds, { 15274 _default: that.speed, 15275 fast: that.speed / 2, 15276 slow: that.speed * 2, 15277 slower: that.speed * 4, 15278 }); 15279 15280 // Extending easing functionality and setting up the default easing function 15281 $.extend($.easing, { 15282 _default: "easeOutExpo", 15283 easeOutExpo: function (x, t, b, c, d) { 15284 return t == d ? b + c : c * (-Math.pow(2, (-10 * t) / d) + 1) + b; 15285 }, 15286 easeInOutCubic: function (x, t, b, c, d) { 15287 if ((t /= d / 2) < 1) return (c / 2) * t * t * t + b; 15288 return (c / 2) * ((t -= 2) * t * t + 2) + b; 15289 }, 15290 }); 15291 }, 15292 15293 beta: { 15294 tokenizationAvailable: function () { 15295 return true; 15296 }, 15297 }, 15298 sliders: { 15299 delay: 4000, 15300 }, 15301 }; 15302 15303 Settings.init(); 15304 15305 return Settings; 15306}); 15307/** 15308 * Utils 15309 * @namespace Verkami 15310 * @class Utils 15311 */ 15312 15313var deps = ["Verkami/Settings"]; 15314 15315modulejs.define("Verkami/Utils", deps, function (Settings) { 15316 var Utils = { 15317 isMobile: false, 15318 isTablet: false, 15319 isDesktop: false, 15320 15321 init: function () { 15322 var that = this; 15323 var timeout; 15324 15325 that.ajaxSettings(); 15326 that.setDeviceFlag(); 15327 that.externalLinks.init(); 15328 that.getSVG(); 15329 that.buttonsAsLinks(); 15330 that.squarize(); 15331 that.widerize(); 15332 that.captchaPositionFixer(); 15333 15334 $(window).resize(function () { 15335 that.setDeviceFlag(); 15336 15337 clearTimeout(timeout); 15338 timeout = setTimeout(function () { 15339 that.squarize(); 15340 that.widerize(); 15341 }, Settings.speed); 15342 }); 15343 15344 that.triggers(); 15345 }, 15346 15347 triggers: function () { 15348 var that = this; 15349 15350 $(document).on("trigger.vk.utils.squarize", function (e, wrapper) { 15351 that.squarize(wrapper); 15352 }); 15353 }, 15354 15355 /** 15356 * Set common headers/properties for all jQuery AJAX requests 15357 * @class ajaxSettings 15358 */ 15359 ajaxSettings: function () { 15360 var that = this; 15361 var csrfToken = $('meta[name="csrf-token"]').prop("content"); 15362 15363 $.ajaxPrefilter(function (options, originalOptions, jqXHR) { 15364 // Unique ID for each ajax request 15365 15366 if (options["url"] == "/user_session") { 15367 var tokens = $('input[name="authenticity_token"]') 15368 .map(function () { 15369 return this.value; 15370 }) 15371 .get() 15372 .join(); 15373 console.log("Sending CSRF token: " + csrfToken); 15374 console.log("Available CSRF tokens: " + tokens); 15375 } 15376 var ajaxID = that.uuid(); 15377 jqXHR.setRequestHeader("X-Verkami-AjaxID", ajaxID); 15378 jqXHR.verkami = { ajaxID: ajaxID }; 15379 15380 if (csrfToken) { 15381 jqXHR.setRequestHeader("X-CSRF-Token", csrfToken); 15382 } 15383 }); 15384 }, 15385 15386 /** 15387 * Return a pseudo UUID v4, useful for IDs 15388 * @class uuid 15389 */ 15390 uuid: function () { 15391 var u = new Date().getTime().toString(16) + Math.random().toString(16).substring(2) + "0000000000000000"; 15392 return u.substr(0, 8) + "-" + u.substr(8, 4) + "-4000-8" + u.substr(12, 3) + "-" + u.substr(15, 12); 15393 }, 15394 15395 caseInsensitiveEqual: function (a, b) { 15396 return typeof a === "string" && typeof b === "string" 15397 ? a.localeCompare(b, undefined, { sensitivity: "accent" }) === 0 15398 : a === b; 15399 }, 15400 15401 /** 15402 * Returns the callback functionality after a specific delay 15403 * @class delayedCallback 15404 * @params 15405 * callback: function to call after the delay 15406 * ms: time applied to the delay (milliseconds) 15407 */ 15408 delayedCallback: function (callback, ms) { 15409 let timer = 0; 15410 15411 return function (...args) { 15412 clearTimeout(timer); 15413 timer = setTimeout(callback.bind(this, ...args), ms || 0); 15414 }; 15415 }, 15416 15417 /** 15418 * Set [target: _blank] to external links 15419 * @class externalLinks 15420 */ 15421 externalLinks: { 15422 init: function () { 15423 var that = this; 15424 var links = $("a").filter(function () { 15425 return this.hostname && this.hostname !== location.hostname; 15426 }); 15427 15428 that.changeTarget(links); 15429 15430 that.events(); 15431 }, 15432 15433 changeTarget: function (links) { 15434 links.attr("target", "_blank"); 15435 }, 15436 15437 events: function () { 15438 $("body").on("click.ExternalLinks", ".js-external-links a", function (e) { 15439 e.preventDefault(); 15440 15441 window.open($(this).prop("href"), "_blank"); 15442 }); 15443 }, 15444 }, 15445 15446 /** 15447 * Get SVG from img tag 15448 * @class getSVG 15449 */ 15450 getSVG: function () { 15451 var svgNodes = $(".js-svg"); 15452 15453 if (svgNodes.length) { 15454 svgNodes.each(function () { 15455 var svgNode = $(this); 15456 var svgURL = svgNode.attr("src"); 15457 15458 $.get( 15459 svgURL, 15460 function (data) { 15461 var svg = $(data).find("svg"); 15462 15463 svgNode.replaceWith(svg); 15464 }, 15465 "xml" 15466 ); 15467 }); 15468 } 15469 }, 15470 15471 buttonsAsLinks: function () { 15472 var buttonsAsLinks = $(".js-button-link"); 15473 15474 if (buttonsAsLinks.length) { 15475 console.log("heyeyydheydhe hohohoho *"); 15476 buttonsAsLinks.each(function () { 15477 var node = $(this); 15478 console.log("heyeyydheydhe hohohoho KOKPKFDWEKFPOEW*"); 15479 var url = node.attr("data-link"); 15480 15481 node.on("click", function (e) { 15482 e.preventDefault(); 15483 console.log("**************************"); 15484 console.log(url); 15485 window.location.href = url; 15486 }); 15487 }); 15488 } 15489 }, 15490 15491 normalizeDiacritics: function (string) { 15492 // https://www.wikiwand.com/en/Combining_Diacritical_Marks 15493 var combiningDiacriticalMarksBlock = /[\u0300-\u036f]/g; 15494 return string.normalize("NFD").replace(combiningDiacriticalMarksBlock, ""); 15495 }, 15496 15497 safeString: function (string) { 15498 // .text() uses the DOM method .createTextNode() and therefor does not interpret the string as HTML. 15499 // cf. https://jsbin.com/pohefecucu/edit?html,js,output 15500 return $("<div/>").text(string).html(); 15501 }, 15502 15503 /** 15504 * Get viewport size 15505 * @class getViewportSize 15506 * @parameter dimension[width,height] 15507 */ 15508 getViewportSize: function (dimension) { 15509 var size; 15510 15511 if (dimension === "width") { 15512 size = $(window).width(); 15513 return size; 15514 } else if (dimension === "height") { 15515 size = $(window).height(); 15516 return size; 15517 } else { 15518 size = { 15519 width: $(window).width(), 15520 height: $(window).height(), 15521 }; 15522 return size; 15523 } 15524 }, 15525 15526 /** 15527 * Get URL hash 15528 * @class hash 15529 */ 15530 hash: { 15531 get: function () { 15532 var hash = decodeURIComponent(window.location.hash.substring(1)); 15533 15534 return hash; 15535 }, 15536 15537 pick: function (name) { 15538 var hash = this.get(); 15539 var sURLVariables = hash.replace("?", "&").split("&"); 15540 var sParameterName; 15541 var i; 15542 15543 for (i = 0; i < sURLVariables.length; i++) { 15544 sParameterName = sURLVariables[i].split("="); 15545 15546 if (sParameterName[0] === name) { 15547 return sParameterName[1] === undefined ? true : sParameterName[1]; 15548 } 15549 } 15550 }, 15551 }, 15552 15553 /** 15554 * Preload images 15555 * @class preloadImages 15556 */ 15557 preloadImages: function (items) { 15558 var item = [];
15559 var itemPath = ""; 15560 15561 items.each(function () { 15562 item = $(this); 15563 itemPath = item.data("preload-image"); 15564 15565 $("<img />").attr("src", itemPath); 15566 15567 item.css("background-image", "url(" + itemPath + ")"); 15568 }); 15569 }, 15570 15571 /** 15572 * Redirect URL 15573 * @class redirect 15574 */ 15575 redirect: function (redirectPath) { 15576 // The redirectPath may be sometimes and encoded URI 15577 // (eg. Facebook Login 'origin' parameter must be encoded in order to be returned) 15578 // Decoded it to be sure we are redirecting correctly 15579 redirectPath = decodeURIComponent(redirectPath); 15580 var redirectBasePath = redirectPath.substr(0, redirectPath.indexOf("#")); 15581 var currentPath = document.location.pathname; 15582 15583 if (redirectPath) { 15584 document.location.assign(redirectPath); 15585 15586 // Force reload if the redirect URL is the same as the current one 15587 if (currentPath === redirectBasePath) { 15588 location.reload(true); 15589 } 15590 } else { 15591 return false; 15592 } 15593 }, 15594 15595 /** 15596 * Disable Responsive 15597 * @class responsiveDisable 15598 */ 15599 responsiveDisable: { 15600 nodes: [], 15601 cookie: "", 15602 cookieName: "cookie_responsive", 15603 meta: "width=1085, initial-scale=0.1, user-scalable=0", 15604 metaFinal: "width=1085, initial-scale=0.1", 15605 15606 init: function () { 15607 var that = this; 15608 var node = []; 15609 that.nodes = $(".js-responsive-disable"); 15610 that.cookie = Cookies.get(that.cookieName); 15611 15612 // Disable responsive if cookie is previously set 15613 if ($("body").hasClass("js-responsive-disable-cookie") && that.cookie) { 15614 that.addMeta(); 15615 } 15616 15617 that.nodes.each(function () { 15618 node = $(this); 15619 15620 // Disable responsive directly. Add click event if the element is a trigger. 15621 if (node.is("body")) { 15622 that.addMeta(); 15623 } else { 15624 node.on("click", function (e) { 15625 e.preventDefault(); 15626 15627 Cookies.set(that.cookieName, "true", { 15628 expires: 365, 15629 }); 15630 15631 location.reload(); 15632 }); 15633 } 15634 }); 15635 }, 15636 15637 addMeta: function () { 15638 var that = this; 15639 Utils.isDesktop = true; 15640 Utils.isMobile = false; 15641 Utils.isTablet = false; 15642 15643 $('meta[name="viewport"]').attr("content", that.meta); 15644 15645 setTimeout(function () { 15646 $('meta[name="viewport"]').attr("content", that.metaFinal); 15647 }, 300); 15648 }, 15649 }, 15650 15651 /** 15652 * Check screen's width to set the device behavior 15653 * @class setDeviceFlag 15654 */ 15655 setDeviceFlag: function () { 15656 var that = this; 15657 var viewportWidth = that.getViewportSize("width"); 15658 15659 if (viewportWidth < 768) { 15660 that.isDesktop = false; 15661 that.isMobile = true; 15662 that.isTablet = false; 15663 15664 that.responsiveDisable.init(); 15665 } else if (viewportWidth < 1025) { 15666 that.isDesktop = false; 15667 that.isMobile = false; 15668 that.isTablet = true; 15669 } else { 15670 that.isDesktop = true; 15671 that.isMobile = false; 15672 that.isTablet = false; 15673 } 15674 }, 15675 15676 /** 15677 * Squarize an element setting its height equal to its width 15678 * @class squarize 15679 */ 15680 squarize: function (wrapper) { 15681 var squares = []; 15682 15683 if (wrapper) { 15684 squares = $(".js-squarize", wrapper); 15685 } else { 15686 squares = $(".js-squarize"); 15687 } 15688 15689 if (squares.length) { 15690 var square; 15691 var squareHeight; 15692 15693 squares.each(function () { 15694 square = $(this); 15695 squareHeight = square.outerWidth(); 15696 15697 square.height(squareHeight); 15698 }); 15699 } 15700 }, 15701 15702 widerize: function () { 15703 var collection = $(".js-widerize"); 15704 15705 if (collection.length) { 15706 var item; 15707 var isPortrait; 15708 var height; 15709 15710 collection.each(function () { 15711 item = $(this); 15712 isPortrait = item.attr("data-widerize-portrait") != undefined; 15713 height = isPortrait ? Math.round((item.outerWidth() / 9) * 16) : Math.round((item.outerWidth() / 16) * 9); 15714 15715 item.height(height); 15716 }); 15717 } 15718 }, 15719 15720 /** 15721 * cf. https://github.com/verkami/verkami/issues/3228#issuecomment-561206607 15722 */ 15723 captchaPositionFixer: function () { 15724 var that = this; 15725 if (!that.isMobile) return false;
15726 15727 console.log("[CAPTCHA] Setting up captcha overlay CSS fixer"); 15728 setInterval(function () { 15729 var reCaptchaIframe = $("iframe[title='recaptcha challenge']"); 15730 if (reCaptchaIframe) { 15731 var reCaptchaOverlay = reCaptchaIframe.parent(); 15732 reCaptchaOverlay.css("position", "fixed"); 15733 } 15734 }, 2000); 15735 }, 15736 }; 15737 15738 Utils.init(); 15739 15740 return Utils; 15741}); 15742/** 15743 * Autocomplete 15744 * @namespace Verkami 15745 * @class Autocomplete 15746 */ 15747 15748var name = "Verkami/Autocomplete"; 15749var deps = ["Verkami/Settings"]; 15750 15751modulejs.define(name, deps, function(Settings) { 15752 var Autocomplete = { 15753 nodes: [], 15754 timeout: null, 15755 minlength: 3, 15756 15757 init: function() { 15758 var that = this; 15759 that.nodes = $(".js-autocomplete"); 15760 15761 that.nodes.each(function() { 15762 that.setup($(this)); 15763 }); 15764 }, 15765 15766 setup: function(node) { 15767 var that = this; 15768 15769 var input = $("input[type='text']", node); 15770 input.data("last-accepted-value", input.val()); 15771 15772 input.attr("autocomplete", "off"); 15773 15774 input.on("blur", function() { 15775 input.val(input.data("last-accepted-value")); 15776 that.hideResults($(this)); 15777 }); 15778 15779 input.on("focus", function() { 15780 that.manageCurrentValue($(this)); 15781 }); 15782 15783 input.on("keyup", function(e) { 15784 switch (e.which) { 15785 case 37: // left 15786 return; 15787 15788 case 38: // up 15789 return; 15790 15791 case 39: // right 15792 return; 15793 15794 case 40: // down 15795 return; 15796 15797 case 13: // enter 15798 return; 15799 } 15800 that.manageCurrentValue($(this)); 15801 }); 15802 }, 15803 15804 manageCurrentValue: function(input) { 15805 var that = this; 15806 var text = input.val().toLowerCase(); 15807 var autocomplete = input.parents(".js-autocomplete"); 15808 var instructions = autocomplete.data("autocomplete-instructions"); 15809 if (text.length >= that.minlength) { 15810 that.requestAutocomplete(input); 15811 } else { 15812 clearTimeout(that.timeout); 15813 that.showResults(input, [ 15814 { 15815 message: instructions 15816 } 15817 ]); 15818 } 15819 }, 15820 15821 requestAutocomplete: function(input) { 15822 console.log("requestAutocomplete 0"); 15823 var that = this; 15824 var text = input.val().toLowerCase(); 15825 var autocomplete = input.parents(".js-autocomplete"); 15826 var source = autocomplete.data("autocomplete-source"); 15827 var noResults = autocomplete.data("autocomplete-no-results"); 15828 15829 var data = { 15830 term: text 15831 }; 15832 15833 $(".js-autocomplete-data", autocomplete).each(function() { 15834 var name = $(this).attr("name"); 15835 var value = $(this).attr("value"); 15836 console.log("requestAutocomplete 1 " + name + " " + value); 15837 15838 data[name] = value; 15839 }); 15840 15841 console.log("requestAutocomplete 2"); 15842 15843 clearTimeout(that.timeout); 15844 15845 that.timeout = setTimeout(function() { 15846 // Show spinner 15847 console.log("requestAutocomplete 3"); 15848 $("<div/>") 15849 .addClass("icon icon--spinner--white") 15850 .appendTo(autocomplete) 15851 .fadeIn(); 15852 15853 $.ajax({ 15854 type: "GET", 15855 url: source, 15856 data: data, 15857 dataType: "json", 15858 error: function(_response, _status, error) { 15859 console.log("requestAutocomplete ERROR " + _response.verkami.ajaxID); 15860 15861 if (text == input.val().toLowerCase()) { 15862 that.showResults(input, [ 15863 { 15864 message: error 15865 } 15866 ]); 15867 15868 setTimeout(function() { 15869 that.hideResults(input); 15870 }, Settings.speed * 10); 15871 } 15872 }, 15873 15874 success: function(results, _status, jqXHR) { 15875 console.log("requestAutocomplete 3_1 " + jqXHR.verkami.ajaxID); 15876 // Check if the user has changed the autocomplete text since we started the process 15877 if (text == input.val().toLowerCase()) { 15878 // Check if the user has changed the autocomplete text since we started the process 15879 console.log("requestAutocomplete 3_1_1 " + jqXHR.verkami.ajaxID); 15880 if (!results.length) { 15881 results = [ 15882 { 15883 message: noResults 15884 } 15885 ]; 15886 //setTimeout(function () { 15887 // that.hideResults(input); 15888 //}, Settings.speed * 10); 15889 } 15890 console.log("requestAutocomplete 3_1_1 showResults " + jqXHR.verkami.ajaxID); 15891 that.showResults(input, results); 15892 } 15893 console.log("requestAutocomplete 3_1b " + jqXHR.verkami.ajaxID); 15894 }, 15895 15896 complete: function(jqXHR) { 15897 console.log("requestAutocomplete 3_2 " + jqXHR.verkami.ajaxID); 15898 $(".icon--spinner--white", autocomplete).fadeOut(function() { 15899 console.log("requestAutocomplete 3_2_1 " + jqXHR.verkami.ajaxID); 15900 $(this).remove(); 15901 }); 15902 } 15903 }); 15904 }, Settings.delay); 15905 }, 15906 15907 hideResults: function(input) { 15908 console.log("hideResults 1"); 15909 var autocomplete = input.parents(".js-autocomplete"); 15910 15911 $(".dropdown__box", autocomplete).fadeOut("fast", function() { 15912 console.log("hideResults 1_1"); 15913 $(this).remove(); 15914 }); 15915 console.log("hideResults 1b"); 15916 }, 15917 15918 showResults: function(input, results) { 15919 console.log("showResults 0"); 15920 15921 var that = this; 15922 var autocomplete = input.parents(".js-autocomplete"); 15923 var resultList = []; 15924 var autocompleteBox = $("<div>", { 15925 class: "dropdown__box" 15926 }); 15927 var autocompleteList = $("<ul>", { 15928 class: "dropdown__list" 15929 }).appendTo(autocompleteBox); 15930 var usePropertyAsLink = autocomplete.data("autocomplete-target"); 15931 console.log("showResults 1"); 15932 input.off("keydown.autocomplete"); 15933 console.log("showResults 2"); 15934 console.log("showResults 2_1 hideResults"); 15935 that.hideResults(input); 15936 console.log("showResults 2_1_1 hideResults done"); 15937 console.log("showResults 3"); 15938 autocomplete.addClass("dropdown"); 15939 15940 $(results).each(function(index, result) { 15941 console.log("showResults 4 /" + index); 15942 15943 resultList = $("<li>", { 15944 class: "dropdown__list__item" 15945 }); 15946 if (result.message) { 15947 console.log("showResults 4_1 /" + index); 15948 that.setupResultAsMessage(result, resultList); 15949 } else { 15950 if (usePropertyAsLink) { 15951 console.log("showResults 4_2 /" + index); 15952 that.setupResultAsLink(result, resultList, usePropertyAsLink); 15953 } else { 15954 console.log("showResults 4_3 /" + index); 15955 that.setupResultAsPush(result, resultList); 15956 } 15957 } 15958 console.log("showResults 4b"); 15959
15960 autocompleteList.append(resultList); 15961 console.log("showResults 4c"); 15962 }); 15963 console.log("showResults 5"); 15964 15965 autocompleteBox.appendTo(autocomplete).fadeIn("fast"); 15966 console.log("showResults 6"); 15967 input.on("keydown.autocomplete", function(e) { 15968 var items = $(this) 15969 .siblings(".dropdown__box") 15970 .find(".dropdown__list__item"); 15971 var hoverItem = $(".dropdown__list__item--hover", autocomplete); 15972 15973 switch (e.which) { 15974 case 38: // up 15975 if (hoverItem.length) { 15976 if (hoverItem.prev().length) { 15977 hoverItem 15978 .removeClass("dropdown__list__item--hover") 15979 .prev() 15980 .addClass("dropdown__list__item--hover"); 15981 that.moveTo(hoverItem.prev()); 15982 } 15983 } 15984 15985 break; 15986 15987 case 40: // down 15988 if (hoverItem.length) { 15989 if (hoverItem.next().length) { 15990 hoverItem 15991 .removeClass("dropdown__list__item--hover") 15992 .next() 15993 .addClass("dropdown__list__item--hover"); 15994 that.moveTo(hoverItem.next()); 15995 } 15996 } else { 15997 items.first().addClass("dropdown__list__item--hover"); 15998 that.moveTo(items.first()); 15999 } 16000 16001 break; 16002 16003 case 13: // enter 16004 if (hoverItem.length) { 16005 if (usePropertyAsLink) { 16006 window.location.href = $("a", hoverItem).attr("href"); 16007 } else { 16008 e.stopPropagation(); 16009 16010 // Copy option to input 16011 that.selectResult($("a", hoverItem)); 16012 16013 // Hide dropdown 16014 $(this).blur(); 16015 } 16016 } 16017 16018 break; 16019 16020 default: 16021 return; // exit this handler for other keys 16022 } 16023 16024 e.preventDefault(); // prevent the default action (scroll / move caret) 16025 }); 16026 }, 16027 16028 selectResult: function(trigger) { 16029 console.log("selectResult 0"); 16030 16031 var autocomplete = trigger.closest(".js-autocomplete"); 16032 var text = trigger.text(); 16033 var data = trigger.data("autocomplete-data"); 16034 var textTarget = $("input[type=\"text\"]", autocomplete); 16035 var dataTargets = $("input[data-autocomplete-pull]", autocomplete); 16036 16037 // Update input value 16038 console.log("selectResult 1 " + text); 16039 textTarget.val(text); 16040 textTarget.data("last-accepted-value", text); 16041 console.log("selectResult 2 " + text); 16042 // Fill in other inputs with there is complementary data 16043 if (dataTargets.length) { 16044 console.log("selectResult 3 "); 16045 var dataTarget = []; 16046 var dataTargetName = ""; 16047 var dataTargetNameLength = 0; 16048 var dataTargetValue = ""; 16049 16050 dataTargets.each(function() { 16051 console.log("selectResult 3_1 "); 16052 dataTarget = $(this); 16053 dataTargetName = dataTarget.data("autocomplete-pull").split("."); 16054 console.log("selectResult 3_2 " + dataTargetName); 16055 dataTargetNameLength = dataTargetName.length; 16056 dataTargetValue = data[dataTargetName[0]]; 16057 16058 if (dataTargetNameLength > 1) { 16059 for (var i = 1; i < dataTargetNameLength; i++) { 16060 dataTargetValue = dataTargetValue[dataTargetName[i]]; 16061 } 16062 } 16063 16064 dataTarget.val(dataTargetValue); 16065 }); 16066 } 16067 console.log("selectResult 3b"); 16068 }, 16069 16070 moveTo: function(item) { 16071 if (item.length) { 16072 var itemHeight = item.outerHeight(); 16073 var itemOffset = item.position().top; 16074 var boxHeight = item.parent().outerHeight(); 16075 var scrollPosition = item.parent().scrollTop(); 16076 var easeOutExpo = function(x, t, b, c, d) { 16077 return t === d ? b + c : c * (-Math.pow(2, (-10 * t) / d) + 1) + b; 16078 }; 16079 16080 if (boxHeight < itemOffset + itemHeight) { 16081 scrollPosition = itemOffset + itemHeight + item.parent().scrollTop() - boxHeight; 16082 } else if (item.parent().scrollTop() > 0 && itemOffset < 0) { 16083 scrollPosition = item.parent().scrollTop() + itemOffset; 16084 } 16085 16086 item 16087 .parent() 16088 .stop() 16089 .animate( 16090 { 16091 scrollTop: scrollPosition 16092 }, 16093 Settings.speed / 2, 16094 easeOutExpo 16095 ); 16096 } 16097 }, 16098 16099 setupResultAsLink: function(result, list, property) { 16100 $("<a>") 16101 .attr({ 16102 title: result.name, 16103 href: result[property] 16104 }) 16105 .text(result.name)
16106 .appendTo(list); 16107 }, 16108 16109 setupResultAsPush: function(result, list) { 16110 var that = this; 16111 $("<a>") 16112 .attr({ 16113 title: result.name, 16114 href: "#" 16115 }) 16116 .text(result.name) 16117 .addClass("js-autocomplete-push") 16118 .data("autocomplete-data", result) 16119 .appendTo(list) 16120 .on("click", function(e) { 16121 e.preventDefault(); 16122 console.log("setupResultAsPush 1"); 16123 console.log("setupResultAsPush result " + result.name); 16124 that.selectResult($(this)); 16125 }); 16126 }, 16127 16128 setupResultAsMessage: function(result, list) { 16129 $("<span>") 16130 .text(result.message) 16131 .appendTo(list); 16132 } 16133 }; 16134 16135 Autocomplete.init(); 16136 16137 return Autocomplete; 16138}); 16139/** 16140* Bar 16141* @namespace Verkami 16142* @class Bar 16143*/ 16144 16145var name = "Verkami/Bar"; 16146var deps = [ 16147 "Verkami/Settings" 16148]; 16149 16150modulejs.define(name, deps, function(Settings) { 16151 var Bar = { 16152 nodes: [], 16153 hiddenClass: "bar--hidden", 16154 16155 init: function() { 16156 var that = this; 16157 that.nodes = $(".js-bar"); 16158 var barsToShowAfter = that.nodes.filter(function () { 16159 return $(this).data("bar-show-after"); 16160 }); 16161 16162 barsToShowAfter.each(function() { 16163 that.setupShowAfter($(this)); 16164 }); 16165 }, 16166 16167 getHeight: function() { 16168 var that = this; 16169 var totalHeight = 0; 16170 16171 that.nodes.each(function() { 16172 totalHeight += $(this).outerHeight(); 16173 }); 16174 16175 return totalHeight; 16176 }, 16177 16178 setupShowAfter: function(node) { 16179 var that = this; 16180 var offset = 0; 16181 var target = $(node.data("bar-show-after")); 16182 16183 if (target.length) { 16184 setTimeout(function() { 16185 offset = target.offset().top; 16186 16187 node.data("bar-show-after-offset", offset); 16188 16189 $(document).on("scroll.Bar", function() { 16190 if ($(window).scrollTop() >= parseInt(offset)) { 16191 node.removeClass(that.hiddenClass); 16192 } else { 16193 node.addClass(that.hiddenClass); 16194 } 16195 }); 16196 }, Settings.speed); 16197 } 16198 } 16199 }; 16200 16201 Bar.init(); 16202 16203 return Bar; 16204}); 16205/** 16206* ColorPicker 16207* @namespace Verkami 16208* @class ColorPicker 16209*/ 16210 16211var name = 'Verkami/ColorPicker'; 16212 16213modulejs.define(name, function() { 16214 var ColorPicker = { 16215 nodes: [], 16216 16217 init: function() { 16218 var that = this; 16219 that.nodes = $('.js-color-picker'); 16220 16221 if (that.nodes.length) { 16222 // @todo: Make colorpicker plugin a dependency 16223 that.nodes.colorpicker({ 16224 component: $('.js-color-picker-trigger'), 16225 format: 'hex' 16226 }); 16227 } 16228 } 16229 }; 16230 16231 ColorPicker.init(); 16232 16233 return ColorPicker; 16234}); 16235/** 16236* Dropdown 16237* @namespace Verkami 16238* @class Dropdown 16239*/ 16240 16241var name = 'Verkami/Dropdown'; 16242var deps = [ 16243 'Verkami/Utils' 16244]; 16245 16246modulejs.define(name, deps, function(Utils) { 16247 var Dropdown = { 16248 nodes: [], 16249 triggers: [], 16250 asideTriggerActiveClass: 'dropdown__list__item--active', 16251 asideVisibleClass: 'dropdown--aside-visible', 16252 16253 init: function() { 16254 var that = this; 16255 that.nodes = $('.js-dropdown'); 16256 16257 if (that.nodes.length) { 16258 that.triggers = $('.js-dropdown-trigger'); 16259 var node = []; 16260 var dropdownList = []; 16261 var dropdownAsides = []; 16262 var dropdownAside = []; 16263 16264 that.nodes.each(function() { 16265 node = $(this); 16266 dropdownAsides = $('.js-dropdown-aside', node); 16267 16268 if (!Utils.isMobile && dropdownAsides.length) { 16269 dropdownList = $('.js-dropdown-list', node); 16270 16271 dropdownList.menuAim({ 16272 activate: function(trigger) { 16273 that.showAside($(trigger)); 16274 }, 16275 deactivate: function(trigger) { 16276 that.hideAside($(trigger)); 16277 } 16278 }); 16279 } 16280 }); 16281 16282 // Show the dropdown 16283 that.triggers.on('click', function(e) { 16284 e.stopPropagation(); 16285 16286 that.show($(this)); 16287 }); 16288 } 16289 }, 16290 16291 hide: function(dropdownBox) { 16292 dropdownBox.fadeOut('fast'); 16293 16294 $('html').off('click'); 16295 16296 if (Utils.isMobile) { 16297 $('body').css('overflow', 'auto'); 16298 } 16299 }, 16300 16301 hideAside: function(trigger) { 16302 var that = this; 16303 var aside = $('.js-dropdown-aside', trigger); 16304 16305 if (aside.length) { 16306 var dropdown = aside.parents('.js-dropdown'); 16307 16308 dropdown.removeClass(that.asideVisibleClass); 16309 trigger.removeClass(that.asideTriggerActiveClass); 16310 aside.hide(); 16311 } 16312 }, 16313 16314 show: function(trigger) { 16315 var that = this; 16316 var dropdown = trigger.parents('.js-dropdown'); 16317 var dropdownBox = $('.js-dropdown-box', dropdown); 16318 var dropdownBoxes = $('.js-dropdown-box', that.nodes); 16319 16320 if (dropdownBox.is(':visible')) { 16321 dropdownBoxes.fadeOut('fast'); 16322 16323 return; 16324 } 16325 16326 dropdownBoxes.fadeOut('fast'); 16327 dropdownBox.fadeIn('fast'); 16328 16329 $('html').on('click', function(e) { 16330 that.hide(dropdownBox); 16331 }); 16332 16333 if (Utils.isMobile) { 16334 $('body').css('overflow', 'hidden'); 16335 } 16336 }, 16337 16338 showAside: function(trigger) { 16339 var that = this; 16340 var aside = $('.js-dropdown-aside', trigger); 16341 16342 if (aside.length) { 16343 var dropdown = aside.parents('.js-dropdown'); 16344 16345 dropdown.addClass(that.asideVisibleClass); 16346 trigger.addClass(that.asideTriggerActiveClass); 16347 aside.show(); 16348 } 16349 } 16350 }; 16351 16352 Dropdown.init(); 16353 16354 return Dropdown; 16355}); 16356/** 16357* Fak 16358* @namespace Verkami 16359* @class Fak 16360*/ 16361 16362var name = 'Verkami/Fak'; 16363var deps = [ 16364 'Verkami/Scroll', 16365 'Verkami/Settings', 16366 'Verkami/Utils' 16367]; 16368 16369modulejs.define(name, deps, function(Scroll, Settings, Utils) { 16370 var Fak = { 16371 nodes: [], 16372 visibleClass: 'title--visible', 16373 16374 init: function() { 16375 var that = this; 16376 that.nodes = $('.js-fak'); 16377 16378 if (that.nodes.length) { 16379 var answers = []; 16380 var questions = []; 16381 16382 that.nodes.each(function() { 16383 answers = $('.answer', this); 16384 questions = $('.title', this); 16385 16386 // Hide all answers by default 16387 answers.hide(); 16388 16389 // Toggle question on click 16390 questions.on('click', function() { 16391 that.toggle($(this)); 16392 }); 16393 }); 16394 16395 // Check if there is any question anchored to the URL, and show it 16396 that.checkHash(); 16397 } 16398 }, 16399 16400 checkHash: function() { 16401 var that = this; 16402 var hash = Utils.hash.get(); 16403 16404 // If there is any question anchored, open it and scroll down to it. 16405 if (hash) { 16406 hashQuestion = $('#' + hash); 16407 16408 if (hashQuestion.length) { 16409 setTimeout(function() { 16410 var title = hashQuestion.children('.title'); 16411 16412 // Show all the answer parents in which the hashQuestion is anidated. 16413 title.parentsUntil(that.nodes, '.answer').toggleClass(that.visibleClass).slideToggle(); 16414 that.toggle(title); 16415 }, Settings.speed * 4); 16416 16417 setTimeout(function() {
16418 Scroll.smooth.doScroll(hashQuestion, 200); 16419 }, Settings.speed * 6); 16420 } 16421 } 16422 }, 16423 16424 toggle: function(trigger) { 16425 var that = this; 16426 16427 if (Utils.isMobile) { 16428 trigger.toggleClass(that.visibleClass).next('.answer').toggle(); 16429 } else { 16430 trigger.toggleClass(that.visibleClass).next('.answer').slideToggle(); 16431 } 16432 } 16433 }; 16434 16435 Fak.init(); 16436 16437 return Fak; 16438}); 16439/** 16440* Faq 16441* @namespace Verkami 16442* @class Faq 16443*/ 16444 16445var name = 'Verkami/Faq'; 16446var deps = [ 16447 'Verkami/Utils' 16448]; 16449 16450modulejs.define(name, deps, function(Utils) { 16451 var Faq = { 16452 nodes: [], 16453 visibleClass: 'faq__item__question--visible', 16454 16455 init: function() { 16456 var that = this; 16457 that.nodes = $('.js-faq'); 16458 16459 if (that.nodes.length) { 16460 var answers = []; 16461 var questions = []; 16462 16463 that.nodes.each(function() { 16464 answers = $('.js-faq-answer', this); 16465 questions = $('.js-faq-question', this); 16466 16467 // Hide all answers by default 16468 answers.hide(); 16469 16470 // Toggle question on click 16471 questions.on('click', function() { 16472 that.toggle($(this), questions); 16473 }); 16474 }); 16475 } 16476 }, 16477 16478 toggle: function(trigger, questions) { 16479 var that = this; 16480 16481 if (Utils.isMobile) { 16482 trigger.toggleClass(that.visibleClass).next('.js-faq-answer').toggle(); 16483 } else { 16484 trigger.toggleClass(that.visibleClass).next('.js-faq-answer').slideToggle(); 16485 } 16486 } 16487 }; 16488 16489 Faq.init(); 16490 16491 return Faq; 16492}); 16493/** 16494 * Form 16495 * @namespace Verkami 16496 * @class Form 16497 */ 16498 16499var name = "Verkami/Form"; 16500var deps = ["Verkami/Modal", "Verkami/Scroll", "Verkami/Settings", "Verkami/Utils"]; 16501 16502modulejs.define(name, deps, function (Modal, Scroll, Settings, Utils) { 16503 var Form = { 16504 init: function () { 16505 var that = this; 16506 that.characterCounter.init(); 16507 that.emptyCheck.init(); 16508 that.numeric.init(); 16509 that.select.init(); 16510 that.submit.init(); 16511 that.textfield.init(); 16512 that.validate.init(); 16513 16514 setTimeout(function () { 16515 that.scrollToErrors(); 16516 }, Settings.speed); 16517 16518 // Clear errors once use the form field 16519 $("body").on("change paste keyup", ".form-item__error", function () { 16520 $(this) 16521 .removeClass("form-item__error") 16522 .siblings(".form-item__error-message") 16523 .slideUp(function () { 16524 $(this).remove(); 16525 }); 16526 }); 16527 }, 16528 16529 characterCounter: { 16530 nodes: [], 16531 cssClass: "form-textarea__counter", 16532 cssClassExceeded: "form-textarea__counter--exceeded", 16533 16534 init: function () { 16535 var that = this; 16536 that.setupNewNodes(); 16537 }, 16538 16539 setupNewNodes: function () { 16540 var that = this; 16541 that.nodes = $(".js-counter"); 16542 16543 //Select nodes that haven't been setup yet 16544 var newNodes = that.nodes.filter(function () { 16545 return !$(this).data("moduleFormCharacterCounterSetupDone"); 16546 }); 16547 16548 if (newNodes.length) { 16549 autosize(newNodes); 16550 16551 newNodes.each(function () { 16552 that.setCounter($(this)); 16553 }); 16554 16555 newNodes.data("moduleFormCharacterCounterSetupDone", true); 16556 } 16557 }, 16558 16559 setCounter: function (node) { 16560 var that = this; 16561 var counter = node; 16562 var limit = parseInt(counter.attr("data-counter-limit")); 16563 var cssClass = counter.attr("data-counter-class") || that.cssClass; 16564 var cssClassExceeded = counter.attr("data-counter-class-exceeded") || that.cssClassExceeded; 16565 16566 // Plugin only allows '%1' as the placeholder 16567 var counterLabel = counter.attr("data-counter-label").replace("%{chars}", "%1"); 16568 16569 node.characterCounter({ 16570 block: true, 16571 limit: limit, 16572 counterWrapper: "div", 16573 counterCssClass: cssClass, 16574 counterFormat: counterLabel, 16575 counterExceededCssClass: cssClassExceeded, 16576 }); 16577 }, 16578 }, 16579 16580 emptyCheck: { 16581 emptyCheckNodes: [], 16582 errorClass: "form-item__error", 16583 submitLoadingClass: "button--loading", 16584 16585 init: function () { 16586 var that = this; 16587 that.emptyCheckNodes = $(".js-empty-check"); 16588 16589 that.events(); 16590 }, 16591 16592 events: function () { 16593 var that = this; 16594 16595 // Validate on submit 16596 $(".js-empty-check-submit", that.emptyCheckNodes).on("click", function (e) { 16597 var emptyCheckSubmit = $(this); 16598 var emptyCheck = emptyCheckSubmit.parents(".js-empty-check"); 16599 var emptyCheckInputs = $(".js-empty-check-input", emptyCheck).filter(function () { 16600 return $(this).is(":visible") === true; 16601 }); 16602 var emptyCheckGroups = $(".js-empty-check-group", emptyCheck).filter(function () { 16603 return $(this).is(":visible") === true; 16604 }); 16605 16606 if (emptyCheckInputs.length) { 16607 that.checkInputs(emptyCheckInputs, e); 16608 } 16609 16610 if (emptyCheckGroups.length) { 16611 that.checkGroups(emptyCheckGroups, emptyCheckSubmit, e); 16612 } 16613 }); 16614 }, 16615 16616 checkGroups: function (emptyCheckGroups, emptyCheckSubmit, e) { 16617 var that = this; 16618 var groupInputs = []; 16619 var groupInputsLength = 0; 16620 var groupInput = []; 16621 var groupInputValue = ""; 16622 var groupModalTriggerId = {}; 16623 16624 emptyCheckGroups.each(function () { 16625 groupInputs = $("input:checkbox, input:radio", this); 16626 groupInputsLength = groupInputs.length; 16627 16628 groupInputs.each(function (i) { 16629 groupInput = $(this); 16630 groupInputValue = groupInput.is(":checked"); 16631 groupModalTriggerId = { 16632 modalTrigger: groupInput.data("empty-check-modal-trigger"), 16633 }; 16634 16635 if (!groupInputValue && i + 1 == groupInputsLength) { 16636 e.stopImmediatePropagation(); 16637 e.preventDefault(); 16638 16639 if (emptyCheckSubmit.hasClass("js-submit")) { 16640 Form.submit.defaultState(emptyCheckSubmit); 16641 } 16642 16643 if (groupModalTriggerId.length) { 16644 Modal.show(modalTriggerId); 16645 } 16646 16647 if (groupInputs.closest(".form-item").hasClass(that.errorClass)) { 16648 groupInputs.closest(".form-item").removeClass(that.errorClass); 16649 16650 setTimeout(function () { 16651 groupInputs.closest(".form-item").addClass(that.errorClass); 16652 }, Settings.speed); 16653 } else { 16654 groupInputs.closest(".form-item").addClass(that.errorClass); 16655 } 16656 16657 groupInputs.one("change", function () { 16658 groupInputs.closest(".form-item").removeClass(that.errorClass); 16659 }); 16660 16661 return false;
16662 } else if (groupInputValue) { 16663 groupInputs.closest(".form-item").removeClass(that.errorClass); 16664 16665 return false; 16666 } 16667 }); 16668 }); 16669 }, 16670 16671 checkInputs: function (emptyCheckInputs, e) { 16672 var that = this; 16673 var inputValue = ""; 16674 var modalData = {}; 16675 16676 emptyCheckInputs.each(function () { 16677 var input = $(this); 16678 inputValue = input.val(); 16679 modalData = { 16680 modalTrigger: input.data("empty-check-modal-trigger"), 16681 }; 16682 16683 if (!inputValue) { 16684 e.stopImmediatePropagation(); 16685 e.preventDefault(); 16686 16687 Modal.show(modalData); 16688 16689 if (input.hasClass(that.errorClass)) { 16690 input.removeClass(that.errorClass); 16691 16692 setTimeout(function () { 16693 input.addClass(that.errorClass); 16694 }, Settings.speed); 16695 } else { 16696 input.addClass(that.errorClass); 16697 } 16698 16699 input.one("keyup", function () { 16700 $(this).removeClass(that.errorClass); 16701 }); 16702 } else { 16703 input.removeClass(that.errorClass); 16704 } 16705 }); 16706 }, 16707 }, 16708 16709 showInputErrors: function (inputMapping, errors, form, submit) { 16710 submit = typeof submit !== "undefined" ? submit : $(".js-submit", form); 16711 16712 $.each(errors, function (_index, error) { 16713 let errorNode = {}; 16714 let input = {}; 16715 16716 for (let name in error) { 16717 if (error.hasOwnProperty(name) && inputMapping[name]) { 16718 input = $(`input[name="${inputMapping[name]}"]`, form); 16719 16720 // Create the error message placeholder and fill it 16721 errorNode = $("<div>", { 16722 class: "form-item__error-message", 16723 }).html(error[name]); 16724 16725 // Append each error to its input 16726 errorNode.appendTo(input.closest('[class*="form-item"]')); 16727 16728 // Remove error message if user is typing 16729 input.one("keyup", function () { 16730 Form.error("hide", $(this)); 16731 16732 $(this) 16733 .closest('[class*="form-item"]') 16734 .find(".form-item__error-message") 16735 .slideUp("fast", function () { 16736 $(this).remove(); 16737 }); 16738 submit.prop("disabled", false); 16739 }); 16740 16741 // Highlight the error 16742 Form.error("show", input, true); 16743 } 16744 } 16745 }); 16746 }, 16747 16748 error: function (action, nodes, removeErrorOnInput) { 16749 var errorClass = "form-item--error"; 16750 var formItemClass = "form-item"; 16751 var node = []; 16752 var wrapper = []; 16753 16754 nodes.each(function () { 16755 node = $(this); 16756 wrapper = node.closest('[class*="' + formItemClass + '"]'); 16757 16758 if (wrapper.length) { 16759 switch (action) { 16760 case "hide": 16761 wrapper.removeClass(errorClass); 16762 break; 16763 case "show": 16764 wrapper.removeClass(errorClass); 16765 16766 setTimeout(function () { 16767 wrapper.addClass(errorClass); 16768 16769 node.one("keyup", function () { 16770 wrapper.removeClass(errorClass); 16771 }); 16772 node.one("click", function () { 16773 wrapper.removeClass(errorClass); 16774 }); 16775 }, Settings.speed); 16776 break; 16777 } 16778 } 16779 }); 16780 }, 16781 16782 reset: function (form) { 16783 var that = this; 16784 var inputs = $(":input", form); 16785 16786 // Hide errors 16787 that.error("hide", inputs); 16788 16789 // Reset and clean inputs 16790 inputs.each(function () { 16791 if ($(this).hasClass("js-non-resettable")) { 16792 return true; 16793 } else { 16794 switch (this.type) { 16795 case "password": 16796 case "text": 16797 case "textarea": 16798 case "date": 16799 case "number": 16800 case "tel": 16801 case "email": 16802 $(this).val(""); 16803 break; 16804 case "select-one": 16805 $(this).find("option:eq(0)").prop("selected", true); 16806 Form.select.refresh($(this)); 16807 break; 16808 case "checkbox": 16809 case "radio": 16810 this.checked = false;
16811 break; 16812 } 16813 } 16814 }); 16815 }, 16816 16817 numeric: { 16818 nodes: [], 16819 16820 init: function () { 16821 var that = this; 16822 var node = []; 16823 var decimalSeparator = ""; 16824 that.nodes = $(".js-numeric"); 16825 16826 if (that.nodes.length) { 16827 that.nodes.each(function () { 16828 node = $(this); 16829 decimalSeparator = node.attr("data-numeric-decimal-separator"); 16830 16831 if (decimalSeparator) { 16832 node.numeric({ 16833 decimal: decimalSeparator, 16834 decimalPlaces: 2, 16835 }); 16836 } else { 16837 node.numeric(); 16838 } 16839 }); 16840 } 16841 }, 16842 }, 16843 16844 select: { 16845 nodes: [], 16846 16847 init: function () { 16848 var that = this; 16849 that.nodes = $(".js-select"); 16850 16851 if (that.nodes.length && !Utils.isMobile) { 16852 $("select", that.nodes).fancySelect({ 16853 includeBlank: true, 16854 }); 16855 } 16856 }, 16857 16858 refresh: function (nodes) { 16859 var node = []; 16860 16861 if (nodes.length && !Utils.isMobile) { 16862 nodes.each(function () { 16863 node = $(this); 16864 16865 if (node.hasClass("fancified")) { 16866 node.removeClass("fancified"); 16867 node.siblings().remove(); 16868 node.unwrap(".fancy-select"); 16869 } 16870 16871 node.fancySelect({ 16872 includeBlank: true, 16873 }); 16874 }); 16875 } 16876 }, 16877 }, 16878 16879 scrollToErrors: function () { 16880 var error = $(".form-item__error").first(); 16881 var errorTop = 0; 16882 var errorBottom = 0; 16883 var viewportTop = 0; 16884 var viewportBottom = 0; 16885 var isVisible = 0; 16886 16887 if (error.length) { 16888 errorTop = error.offset().top; 16889 errorBottom = error.offset().top + error.outerHeight(); 16890 viewportTop = $(window).scrollTop(); 16891 viewportBottom = viewportTop + $(window).height(); 16892 isVisible = viewportBottom > errorTop && viewportTop < errorBottom; 16893 16894 if (!isVisible) { 16895 error.removeClass("form-item__error"); 16896 16897 Scroll.smooth.doScroll(error, 200); 16898 16899 setTimeout(function () { 16900 error.addClass("form-item__error"); 16901 }, Settings.speed * 2); 16902 } 16903 } 16904 }, 16905 16906 submit: { 16907 nodes: [], 16908 submitErrorClass: "button--error", 16909 submitLoadingClass: "button--loading", 16910 submitSuccessClass: "button--success", 16911 16912 init: function () { 16913 const that = this; 16914 that.nodes = $(".js-submit"); 16915 16916 if (that.nodes.length) { 16917 that.nodes.on("click", function () { 16918 that.loadingState($(this)); 16919 }); 16920 } 16921 }, 16922 16923 defaultState: function (target) { 16924 const that = this; 16925 const submitDefaultText = target.attr("data-submit-default-text"); 16926 16927 if (submitDefaultText) { 16928 if (target.is("input")) { 16929 target.val(submitDefaultText); 16930 } else { 16931 target.html(submitDefaultText); 16932 } 16933 } 16934 16935 target.removeClass(`${that.submitLoadingClass} ${that.submitSuccessClass}`).attr("disabled", false); 16936 }, 16937 16938 disabledState: function (target) { 16939 const that = this; 16940 const submitDefaultText = target.attr("data-submit-default-text"); 16941 16942 if (submitDefaultText) { 16943 if (target.is("input")) { 16944 target.val(submitDefaultText); 16945 } else { 16946 target.html(submitDefaultText); 16947 } 16948 } 16949 16950 target.removeClass(`${that.submitLoadingClass} ${that.submitSuccessClass}`).attr("disabled", true); 16951 }, 16952 16953 errorState: function (target) { 16954 const that = this; 16955 const submitDefaultText = target.attr("data-submit-default-text"); 16956 const submitErrorText = target.attr("data-submit-error-text"); 16957 16958 if (submitErrorText) { 16959 if (target.is("input")) { 16960 target.val(submitErrorText); 16961 } else { 16962 target.html(submitErrorText); 16963 } 16964 } 16965 16966 target.removeClass(that.submitLoadingClass).addClass(that.submitErrorClass); 16967 16968 setTimeout(function () { 16969 target.removeClass(that.submitErrorClass); 16970 16971 if (submitDefaultText) { 16972 if (target.is("input")) { 16973 target.val(submitDefaultText); 16974 } else { 16975 target.html(submitDefaultText); 16976 } 16977 } 16978 }, Settings.speed * 12); 16979 }, 16980 16981 loadingState: function (target) { 16982 const that = this; 16983 let submitDefaultText = ""; 16984 const submitLoadingText = target.attr("data-submit-text"); 16985 16986 if (submitLoadingText) { 16987 // Get default text 16988 if (target.is("input")) { 16989 submitDefaultText = target.val(); 16990 } else { 16991 submitDefaultText = target.html(); 16992 } 16993 16994 // Save default text in a new attribute 16995 target.attr("data-submit-default-text", submitDefaultText); 16996 16997 if (target.is("input")) { 16998 target.val(submitLoadingText); 16999 } else { 17000 target.html(submitLoadingText); 17001 } 17002 } 17003 17004 target.blur().addClass(that.submitLoadingClass); 17005 }, 17006 17007 successState: function (target) { 17008 const that = this; 17009 const submitSuccessText = target.attr("data-submit-success-text");
17010 const keepSuccess = Boolean(target.attr("data-submit-keep-success")); 17011 17012 if (submitSuccessText) { 17013 if (target.is("input")) { 17014 target.val(submitSuccessText); 17015 } else { 17016 target.html(submitSuccessText); 17017 } 17018 } 17019 17020 target.removeClass(that.submitLoadingClass).addClass(that.submitSuccessClass); 17021 17022 if (!keepSuccess) { 17023 setTimeout(function () { 17024 that.defaultState(target); 17025 }, Settings.speed * 12); 17026 } 17027 }, 17028 }, 17029 17030 textfield: { 17031 nodes: [], 17032 17033 init: function () { 17034 var that = this; 17035 var node = []; 17036 that.nodes = $(".js-textfield"); 17037 17038 if (that.nodes.length) { 17039 that.nodes.each(function () { 17040 node = $(this); 17041 17042 autosize(node); 17043 17044 node.on("trigger.vk.textfield.autosize", function () { 17045 trigger.vk.textfield.autosize($(this)); 17046 }); 17047 }); 17048 } 17049 }, 17050 }, 17051 17052 validate: { 17053 errorClass: "form-item--error", 17054 urls: [], 17055 17056 init: function () { 17057 var that = this; 17058 var isValid = false; 17059 that.urls = $(".js-validate-url"); 17060 17061 that.urls.on("blur", function () { 17062 var input = $(this); 17063 var wrapper = input.parents(".form-item"); 17064 isValid = that.url(input.val()); 17065 17066 if (isValid) { 17067 wrapper.removeClass(that.errorClass); 17068 } else { 17069 wrapper.addClass(that.errorClass); 17070 } 17071 }); 17072 }, 17073 17074 email: function (value) { 17075 var regExp = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,25}$/i; 17076 var isValid = regExp.test(value); 17077 17078 return isValid; 17079 }, 17080 17081 url: function (value) { 17082 var regExp =
17083 /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i; 17084 var isValid = regExp.test(value); 17085 17086 return isValid; 17087 }, 17088 }, 17089 }; 17090 17091 Form.init(); 17092 17093 return Form; 17094}); 17095/** 17096 * Modal 17097 * @namespace Verkami 17098 * @class Modal 17099 */ 17100 17101var deps = ["Verkami/DataTransfer", "Verkami/Password", "Verkami/Settings", "Verkami/Utils", "Verkami/Captcha"]; 17102 17103modulejs.define("Verkami/Modal", deps, function (DataTransfer, Password, Settings, Utils, Captcha) { 17104 var Modal = { 17105 nodes: [], 17106 closes: [], 17107 triggers: [], 17108 visibleClass: "modal--visible", 17109 bodyVisibleClass: "modal-visible", 17110 17111 init: function () { 17112 var that = this; 17113 that.nodes = $(".js-modal"); 17114 17115 if (that.nodes.length) { 17116 that.closes = $(".js-modal-close"); 17117 that.triggers = $(".js-modal-trigger"); 17118 17119 // Initialize callbacks 17120 that._callbacks(); 17121 17122 // Close modal trigger 17123 that.closes.on("click.vk.modal.close", function (e) { 17124 var modalId = $(this).closest(".js-modal").data("modal-id"); 17125 var jumpToModal = $(this).hasClass("js-modal-trigger"); 17126 var noPropagate = $(this).attr("data-modal-no-propagate"); 17127 17128 if (noPropagate) { 17129 e.stopImmediatePropagation(); 17130 } 17131 e.preventDefault(); 17132 17133 that.hide(modalId, jumpToModal); 17134 }); 17135 17136 // Open modal trigger 17137 that.triggers.on("click.vk.modal.open", function (e) { 17138 var modalTrigger = $(this); 17139 var modalData = modalTrigger.data(); 17140 var noPropagate = modalTrigger.attr("data-modal-no-propagate"); 17141 17142 if (noPropagate) { 17143 e.stopImmediatePropagation(); 17144 } 17145 e.preventDefault(); 17146 17147 that.show(modalData); 17148 }); 17149 17150 // Autoshow modals controller 17151 that.autoTrigger(); 17152 } 17153 }, 17154 17155 // @todo This method should be refactored to adopt the Module#setupNewNodes 17156 // idiom that is used in Share, Follow and Cards. 17157 refresh: function () { 17158 var that = this; 17159 that.nodes = $(".js-modal"); 17160 that.closes = $(".js-modal-close"); 17161 that.triggers = $(".js-modal-trigger"); 17162 17163 that.closes.off("click.vk.modal.close").on("click.vk.modal.close", function (e) { 17164 var modalId = $(this).parents(".js-modal").data("modal-id"); 17165 var jumpToModal = $(this).hasClass("js-modal-trigger"); 17166 var noPropagate = $(this).attr("data-modal-no-propagate"); 17167 17168 if (noPropagate) { 17169 e.stopImmediatePropagation(); 17170 } 17171 e.stopPropagation(); 17172 e.preventDefault(); 17173 17174 that.hide(modalId, jumpToModal); 17175 }); 17176 17177 that.triggers.off("click.vk.modal.open").on("click.vk.modal.open", function (e) { 17178 var modalTrigger = $(this); 17179 var modalId = modalTrigger.attr("data-modal-trigger"); 17180 var modalData = modalTrigger.data(); 17181 var modal = $(".js-modal").filter(function () { 17182 return $(this).attr("data-modal-id") === modalId; 17183 }); 17184 17185 var noPropagate = modalTrigger.attr("data-modal-no-propagate"); 17186 17187 if (noPropagate) { 17188 e.stopImmediatePropagation(); 17189 } 17190 e.preventDefault(); 17191 17192 modal.data("modalId", modalId); 17193 modalTrigger.data("modalTrigger", modalId); 17194 17195 that.show(modalData); 17196 }); 17197 Captcha.setupNewNodes(); 17198 }, 17199 17200 _callbacks: function () { 17201 var that = this; 17202 var modalId = ""; 17203 17204 $(document).on("trigger.vk.modal.close", ".js-modal", function () { 17205 modalId = $(this).attr("data-modal-id"); 17206 17207 that.hide(modalId); 17208 }); 17209 17210 $(document).on("trigger.vk.modal.setup", ".js-modal", function () { 17211 modalId = $(this).attr("data-modal-id"); 17212 17213 that.setup(modalId); 17214 }); 17215 }, 17216 17217 // A modal is shown getting its ID from the URL hash 17218 // 17219 // Usage: 17220 // ------ 17221 // 17222 // [URL]#modal=[NAME] 17223 // Where [NAME] is the modal ID, defined in data-modal-id attribute inside the modal template. 17224 autoTrigger: function () { 17225 var that = this; 17226 var modalData = { 17227 modalTrigger: Utils.hash.pick("modal"), 17228 }; 17229 17230 setTimeout(function () { 17231 that.show(modalData); 17232 }, Settings.speed); 17233 }, 17234 17235 custom: { 17236 init: function (modalData, callback) { 17237 var that = this; 17238 17239 switch (modalData.modalTrigger) { 17240 case "auth_dialog": 17241 that.auth(modalData, callback); 17242 break; 17243 case (modalData.modalTrigger.match("^blogs_preview") || {}
17243).input: 17244 that.blogPreview(modalData, callback); 17245 break; 17246 case (modalData.modalTrigger.match("^embed") || {}).input: 17247 $(document).trigger({ 17248 type: "trigger.vk.widget.getIframe", 17249 modalData: modalData, 17250 }); 17251 17252 callback.resolve(true); 17253 break; 17254 case (modalData.modalTrigger.match("^payments_paypal_backer_failed") || {}).input: 17255 that.paymentPayPalError(modalData, callback); 17256 break; 17257 case (modalData.modalTrigger.match("^pledges_process") || {}).input: 17258 that.pledge(modalData, callback); 17259 break; 17260 case "translation_missing": 17261 that.translationMissing(modalData, callback); 17262 break; 17263 default: 17264 callback.resolve(true); 17265 return true; 17266 } 17267 }, 17268 17269 auth: function (modalData, callback) { 17270 var modal = Modal.get(modalData.modalTrigger); 17271 17272 // Save custom redirect if modal trigger sent it 17273 $(".js-login, .js-signup, .js-auth-facebook, .js-auth-google", modal).attr("data-auth-redirect", modalData.authRedirect); 17274 17275 // Refresh password visibility toggles 17276 Password.init(); 17277 17278 // Refresh auth forms 17279 $(document).trigger("trigger.vk.user.setup"); 17280 17281 callback.resolve(true); 17282 }, 17283 17284 blogPreview: function (modalData, callback) { 17285 var modal = Modal.get(modalData.modalTrigger); 17286 var trigger = $('.js-modal-trigger[data-modal-trigger="' + modalData.modalTrigger + '"]'); 17287 var editor = trigger.closest("form").find(".js-editor"); 17288 var previewCallback = $.Deferred(); 17289 17290 // Load spinner 17291 var loading = $("<div/>").addClass("modal-loading"); 17292 17293 // @todo: Check if it's possible to avoid the speed attribute 17294 loading.appendTo("body").fadeIn(Settings.speed, function () { 17295 $("body").addClass("modal-visible"); 17296 }); 17297 17298 $.when(previewCallback).done(function (response) { 17299 if (response) { 17300 DataTransfer.transfer(trigger.data()); 17301 17302 var images = $(".js-modal-content", modal).find("img"); 17303 var imagesCount = images.length; 17304 var imagesLoaded = 0; 17305 17306 if (imagesCount) { 17307 images.each(function () { 17308 $(this).on("load", function () { 17309 imagesLoaded = imagesLoaded + 1; 17310 17311 if (imagesLoaded === imagesCount) { 17312 loading.fadeOut(); 17313 17314 callback.resolve(true); 17315 } 17316 }); 17317 }); 17318 } else { 17319 loading.fadeOut(); 17320 17321 callback.resolve(true); 17322 } 17323 } 17324 }); 17325 17326 // Get Editor preview 17327 editor.trigger("trigger.vk.editor.getPreview", { 17328 delay: true, 17329 callback: previewCallback, 17330 }); 17331 }, 17332 17333 paymentPayPalError: function (modalData, callback) { 17334 var modal = Modal.get(modalData.modalTrigger); 17335 var errorsPlaceholder = $(".js-paypal-failed-errors", modal); 17336 17337 errorsPlaceholder.html(modalData.pledgePaymentRetryErrorContent); 17338 17339 callback.resolve(true); 17340 }, 17341 17342 pledge: function (modalData, callback) { 17343 var modal = Modal.get(modalData.modalTrigger); 17344 var pledgeNode = modal.hasClass("js-pledge") ? modal : $(".js-pledge", modal); 17345 var modalHeight = $(".modal__box__inner", modal).outerHeight(); 17346 var viewportHeight = Utils.getViewportSize("height"); 17347 var modalVerticalGutter = 0; 17348 var modalMaxHeight = 0; 17349 17350 if (Utils.isDesktop) { 17351 modalVerticalGutter = 30; 17352 modalMaxHeight = viewportHeight - modalVerticalGutter * 2; 17353 } else { 17354 modalVerticalGutter = 60; 17355 var pledgeAsideHeight = $(".js-pledge-aside", modal).outerHeight(); 17356 modalMaxHeight = viewportHeight - pledgeAsideHeight - modalVerticalGutter - modalVerticalGutter / 2; 17357 } 17358 17359 // Refresh auth forms 17360 $(document).trigger("trigger.vk.user.setup"); 17361 17362 // Refresh password visibility toggles 17363 Password.init(); 17364 17365 if (modalHeight > modalMaxHeight) { 17366 $(".js-pledge-content", pledgeNode).outerHeight(modalMaxHeight); 17367 } else { 17368 $(".js-pledge-content", pledgeNode).outerHeight(modalHeight); 17369 } 17370 17371 callback.resolve(true); 17372 }, 17373 17374 translationMissing: function (modalData, callback) { 17375 var modal = Modal.get(modalData.modalTrigger); 17376 var localesWrapper = $(".js-locale-missing-languages", modal); 17377 var localeNames = ""; 17378 17379 // Split locale names by comma if there are several 17380 if (modalData.localesMissing.length > 1) { 17381 localeNames = modalData.localesMissing.join(", "); 17382 } else { 17383 localeNames = modalData.localesMissing; 17384 } 17385 17386 // Print locale names in the modal placeholder 17387 localesWrapper.html(localeNames); 17388 17389 callback.resolve(true); 17390 }, 17391 }, 17392 17393 get: function (modalId) { 17394 var that = this; 17395 17396 var modal = that.nodes.filter(function () { 17397 return $(this).data("modal-id") === modalId; 17398 }); 17399 17400 return modal; 17401 }, 17402 17403 getAsync: function (modal, modalId, modalAsync) { 17404 var that = this; 17405 var loading = $("<div/>").addClass("modal-loading"); 17406 17407 loading.appendTo("body").fadeIn(function () { 17408 that.setupBody(); 17409 }); 17410 17411 $.ajax({ 17412 type: "GET", 17413 17414 url: modalAsync, 17415 dataType: "html", 17416 error: function () { 17417 loading.fadeOut(function () { 17418 that.setupBody(true); 17419 }); 17420 }, 17421 success: function (response) { 17422 var callback = $.Deferred(); 17423 var modalData = { 17424 modalTrigger: modalId, 17425 }; 17426 17427 $(".js-modal-content", modal).html(response); 17428 17429 that.refresh(); 17430 17431 $.when(callback).done(function () { 17432 that.setup(modalId); 17433 17434 $(window).resize(function () { 17435 that.setup(modalId); 17436 }); 17437 17438 modal.addClass(that.visibleClass); 17439 17440 modal.trigger("hook.vk.modal.open", [modalData]); 17441 17442 setTimeout(function () { 17443 loading.fadeOut(); 17444 }, Settings.speed); 17445 }); 17446 17447 that.custom.init(modalData, callback); 17448 }, 17449 }); 17450 }, 17451 17452 hide: function (modalId, jumpToModal) { 17453 var that = this; 17454 var modal = that.get(modalId); 17455 17456 if (!jumpToModal && $("." + that.visibleClass).length === 1) { 17457 that.setupBody(true); 17458 } 17459 17460 modal.removeClass(that.visibleClass); 17461 }, 17462 17463 loading: { 17464 timeout: null, 17465 visibleClass: "modal__loading--visible", 17466 17467 hide: function (node) { 17468 var that = this; 17469 17470 clearTimeout(that.timeout); 17471 17472 node.removeClass(that.visibleClass); 17473 }, 17474 17475 show: function (node) { 17476 var that = this; 17477 17478 clearTimeout(that.timeout); 17479 17480 that.timeout = setTimeout(function () { 17481 node.addClass(that.visibleClass); 17482 }, Settings.speed); 17483 }, 17484 }, 17485 17486 moveToBodyEnd: function (modalId) { 17487 var that = this; 17488 var modal = that.get(modalId); 17489 var isBodyChild = modal.parent().is("body"); 17490 17491 if (!isBodyChild) { 17492 $("body").append(modal.detach()); 17493 } 17494 }, 17495 17496 setup: function (modalId) { 17497 var that = this; 17498 var modalBox = []; 17499 var modalBoxInner = [];
17500 var viewportHeight = Utils.getViewportSize("height"); 17501 var nodes = modalId ? that.get(modalId) : that.nodes; 17502 var modalTopGutter = 0; 17503 var modalBottomGutter = 0; 17504 var modalHeight = 0; 17505 var modalOffset = 0; 17506 var modalVerticalGutter = 0; 17507 var modalMaxHeight = 0; 17508 var scrollHeight = 0; 17509 var scrollTraveled = 0; 17510 var scrollableOpacity = 0; 17511 17512 nodes.each(function () { 17513 modalBox = $(".modal__box", $(this)); 17514 modalBoxInner = $(".modal__box__inner", modalBox); 17515 modalTopGutter = 30; 17516 17517 // Reset old Modal-setup changes 17518 modalBox.css("margin-top", 0); 17519 modalBoxInner.css("height", "auto"); 17520 17521 if (Utils.isMobile) { 17522 modalHeight = modalBox.outerHeight(); 17523 modalBottomGutter = 10; 17524 17525 if ($(this).hasClass("modal--closable") || $(this).hasClass("modal--closable--full")) { 17526 modalTopGutter = 54; 17527 } else { 17528 modalTopGutter = 10; 17529 } 17530 17531 modalMaxHeight = viewportHeight - modalTopGutter - modalBottomGutter; 17532 17533 // console.log('viewportHeight', viewportHeight); 17534 // console.log('modalHeight', modalHeight); 17535 // console.log('modalMaxHeight', modalMaxHeight); 17536 // console.log('modalTopGutter', modalTopGutter); 17537 // console.log('modalBottomGutter', modalBottomGutter); 17538 17539 if (modalHeight > modalMaxHeight) { 17540 modalBoxInner.outerHeight(modalMaxHeight); 17541 modalBox.css("margin-top", modalTopGutter); 17542 17543 // Show scrollable gradient 17544 $(this).addClass("modal--scrollable"); 17545 17546 $(".modal__box__scrollable", modalBox).css("opacity", 1); 17547 17548 // Fade out scrollable gradient while scrolling down 17549 modalBoxInner.off("scroll.vk.modal").on("scroll.vk.modal", function () { 17550 scrollHeight = modalBoxInner[0].scrollHeight - modalMaxHeight; 17551 scrollTraveled = (modalBoxInner[0].scrollTop * 100) / scrollHeight; 17552 scrollableOpacity = (100 - scrollTraveled) / 100; 17553 17554 $(".modal__box__scrollable", modalBox).css("opacity", scrollableOpacity); 17555 }); 17556 } else { 17557 modalOffset = (viewportHeight - modalHeight) / 2; 17558 // Hide scrollable gradient 17559 $(this).removeClass("modal--scrollable"); 17560 17561 // Fade out scrollable gradient while scrolling down 17562 modalBoxInner.off("scroll.vk.modal"); 17563 17564 modalBoxInner.outerHeight(modalHeight); 17565 modalBox.css("margin-top", modalOffset); 17566 } 17567 } else { 17568 if (typeof modalBox.data("modal-height") !== "undefined") { 17569 modalHeight = modalBox.data("modal-height"); 17570 } else { 17571 modalHeight = modalBox.outerHeight(); 17572 modalBox.data("modal-height", modalHeight); 17573 } 17574 17575 modalOffset = (viewportHeight - modalHeight) / 2; 17576 17577 if (Utils.isTablet) { 17578 modalTopGutter = 60; 17579 modalBottomGutter = 30; 17580 modalMaxHeight = viewportHeight - modalTopGutter - modalBottomGutter; 17581 } else { 17582 modalVerticalGutter = 30; 17583 modalMaxHeight = viewportHeight - modalVerticalGutter * 2; 17584 } 17585 17586 if (modalHeight > modalMaxHeight) { 17587 modalOffset = (viewportHeight - modalMaxHeight) / 4; 17588 modalBoxInner.outerHeight(modalMaxHeight); 17589 modalBox.css("margin-top", modalTopGutter); 17590 17591 // Show scrollable gradient 17592 $(this).addClass("modal--scrollable"); 17593 17594 $(".modal__box__scrollable", modalBox).css("opacity", 1); 17595 17596 // Fade out scrollable gradient while scrolling down 17597 modalBoxInner.off("scroll.vk.modal").on("scroll.vk.modal", function () { 17598 scrollHeight = modalBoxInner[0].scrollHeight - modalMaxHeight; 17599 scrollTraveled = (modalBoxInner[0].scrollTop * 100) / scrollHeight; 17600 scrollableOpacity = (100 - scrollTraveled) / 100; 17601 17602 $(".modal__box__scrollable", modalBox).css("opacity", scrollableOpacity); 17603 }); 17604 } else { 17605 // Hide scrollable gradient 17606 $(this).removeClass("modal--scrollable"); 17607 17608 // Fade out scrollable gradient while scrolling down 17609 modalBoxInner.off("scroll.vk.modal"); 17610 17611 modalBoxInner.outerHeight(modalHeight); 17612 modalBox.css("margin-top", modalOffset); 17613 } 17614 } 17615 }); 17616 }, 17617 17618 setupBody: function (remove) { 17619 var that = this; 17620 var body = $("body"); 17621 17622 if (remove) { 17623 body.removeClass(that.bodyVisibleClass); 17624 } else { 17625 body.addClass(that.bodyVisibleClass); 17626 } 17627 }, 17628 17629 show: function (modalData) { 17630 var that = this; 17631 var modalId = modalData.modalTrigger; 17632 var modal = that.get(modalId); 17633 var modalAsync = modal.data("modal-async"); 17634 17635 if (modalAsync) { 17636 that.getAsync(modal, modalId, modalAsync); 17637 return; 17638 } 17639 17640 if (modal.length) { 17641 var callback = $.Deferred(); 17642 17643 $.when(callback).done(function () { 17644 that.setup(modalId); 17645 17646 $(window).resize(function () { 17647 that.setup(modalId); 17648 }); 17649 17650 modal.trigger("hook.vk.modal.open", [modalData]); 17651 17652 setTimeout(function () { 17653 that.setupBody(); 17654 modal.addClass(that.visibleClass); 17655 }, Settings.speed); 17656 }); 17657 17658 that.custom.init(modalData, callback); 17659 } 17660 }, 17661 }; 17662 17663 Modal.init(); 17664 17665 return Modal; 17666}); 17667/** 17668* PopUp 17669* @namespace Verkami 17670* @class PopUp 17671*/ 17672 17673var name = 'Verkami/PopUp'; 17674 17675modulejs.define(name, function() { 17676 var PopUp = { 17677 popupNodes: [], 17678 17679 init: function() { 17680 var that = this; 17681 that.popupNodes = $('.js-popup'); 17682 17683 if (that.popupNodes.length) { 17684 var popupSize; 17685 17686 $.each(that.popupNodes, function(index, val) { 17687 popupSize = { 17688 width: $(this).data('popup-width'), 17689 height: $(this).data('popup-height') 17690 }; 17691 17692 $(this).on('click', function(e) { 17693 e.preventDefault(); 17694 17695 window.open( 17696 $(this).attr('href'), 17697 'title', 17698 'width=' + popupSize.width + ',height=' + popupSize.height 17699 ); 17700 }); 17701 }); 17702 } 17703 } 17704 }; 17705 17706 PopUp.init(); 17707 17708 return PopUp; 17709}); 17710/** 17711* ReadMore 17712* @namespace Verkami 17713* @class ReadMore 17714*/ 17715 17716var name = 'Verkami/ReadMore'; 17717var deps = [ 17718 'Verkami/Settings' 17719]; 17720 17721modulejs.define(name, deps, function(Settings) { 17722 var ReadMore = { 17723 nodes: [], 17724 17725 init: function() { 17726 var that = this; 17727 that.nodes = $('.js-read-more'); 17728 17729 if (that.nodes.length) { 17730 that.nodes.each(function() { 17731 that.setup($(this)); 17732 }); 17733 } 17734 }, 17735 17736 expand: function(trigger) { 17737 var that = this; 17738 var node = trigger.parents('.js-read-more'); 17739 var nodeHeight = parseInt(node.attr('data-read-more-height')); 17740 17741 node.attr('aria-expanded', 'true'); 17742 node.css({ 17743 'max-height': nodeHeight, 17744 'overflow': 'auto' 17745 }); 17746 17747 trigger.hide(); 17748 }, 17749
17750 getBackground: function(node) { 17751 var that = this; 17752 17753 // Is current element's background color set? 17754 var color = node.css('background-color'); 17755 17756 if ((color !== 'rgba(0, 0, 0, 0)') && (color !== 'transparent')) { 17757 return color; 17758 } 17759 17760 // If not: are you at the body element? 17761 if (node.is('body')) { 17762 return node.css('background-color'); 17763 } else { 17764 return that.getBackground(node.parent()); 17765 } 17766 }, 17767 17768 setup: function(node) { 17769 var that = this; 17770 17771 if (!node.hasClass('js-read-more')) { 17772 node = $('.js-read-more', node); 17773 } 17774 17775 if (node.length) { 17776 var isExpanded = (node.attr('aria-expanded') === 'true'); 17777 var maxRows = parseInt(node.attr('data-read-more-rows')); 17778 var nodeHeight = node.outerHeight(); 17779 var rowHeight = parseInt(node.css('line-height')); 17780 var maxHeight = rowHeight * maxRows + 1; // Hack: Firefox could add decimals and increment the height in 1px 17781 var trigger = $('.js-read-more-trigger', node); 17782 var triggerTop = maxHeight - rowHeight; 17783 var triggerBg = that.getBackground(node); 17784 17785 if (isExpanded && nodeHeight > maxHeight) { 17786 node.attr('data-read-more-height', nodeHeight); 17787 node.attr('aria-expanded', 'false'); 17788 node.css({ 17789 'position': 'relative', 17790 'max-height': maxHeight, 17791 'overflow': 'hidden', 17792 'transition': 'max-height ' + Settings.speed / 1000 + 's' 17793 }); 17794 17795 trigger.css({ 17796 'display': 'block', 17797 'background-color': triggerBg, 17798 'padding-left': 4, 17799 'position': 'absolute', 17800 'top': triggerTop, 17801 'right': 0 17802 }); 17803 17804 node.on('click', '.js-read-more-trigger', function() { 17805 that.expand($(this)); 17806 }); 17807 } else if (!isExpanded) { 17808 node.attr('aria-expanded', 'true'); 17809 17810 node.css({ 17811 'max-height': 'none', 17812 'overflow': 'auto' 17813 }); 17814 17815 trigger.hide(); 17816 17817 that.setup(node); 17818 } 17819 } 17820 } 17821 }; 17822 17823 ReadMore.init(); 17824 17825 return ReadMore; 17826}); 17827/** 17828 * Share 17829 * @namespace Verkami 17830 * @class Share 17831 */ 17832 17833var name = "Verkami/Share"; 17834var deps = [ 17835 "Verkami/Settings", 17836 "Verkami/Utils" 17837]; 17838 17839modulejs.define(name, deps, function (Settings, Utils) { 17840 var Share = { 17841 nodes: [], 17842 listVisibleClass: "share__list--visible", 17843 timeout: null, 17844 17845 init: function () { 17846 var that = this; 17847 that.setupNewNodes(); 17848 }, 17849 17850 setupNewNodes: function () { 17851 var that = this; 17852 that.nodes = $(".js-share"); 17853 17854 //Select nodes that haven't been setup yet 17855 var newNodes = that.nodes.filter(function () { 17856 return !$(this).data("moduleShareSetupDone"); 17857 }); 17858 17859 if (newNodes.length) { 17860 newNodes.each(function () { 17861 that.copyUrl.init($(this)); 17862 }); 17863 17864 that.events(newNodes); 17865 17866 newNodes.data("moduleShareSetupDone", true); 17867 } 17868 }, 17869 17870 copyUrl: { 17871 feedbackDelay: 4000, 17872 17873 init: function (node) { 17874 var that = this; 17875 var shareCopyUrl = $(".js-share-copy-url", node); 17876 var feedback = $(".js-share-copy-url-feedback", node); 17877 17878 if (shareCopyUrl.length) { 17879 that.copy(shareCopyUrl, feedback); 17880 } 17881 }, 17882 17883 copy: function (shareCopyUrl, feedback) { 17884 var that = this; 17885 17886 new Clipboard(shareCopyUrl[0], { 17887 text: function (trigger) { 17888 feedback.fadeIn().delay(that.feedbackDelay).fadeOut(); 17889 return $(trigger).attr("href"); 17890 } 17891 }); 17892 } 17893 }, 17894 17895 events: function (nodes) { 17896 var that = this; 17897 17898 // Prevent refresh page after copying the url 17899 nodes.on("click.Share", ".js-share-copy-url", function (e) { 17900 e.preventDefault(); 17901 }); 17902 17903 // Toggle share list 17904 if (!Utils.isMobile && !Utils.isTablet) { 17905 nodes.on("mouseenter.Share", function () { 17906 that.toggle("show", $(this)); 17907 }); 17908 17909 nodes.on("mouseleave.Share", function () { 17910 that.toggle("hide", $(this)); 17911 }); 17912 } 17913 }, 17914 17915 toggle: function (action, node) { 17916 var that = this; 17917 var list = $(".js-share-list", node); 17918 17919 if (action === "show") { 17920 clearTimeout(that.timeout); 17921 17922 // Show the share node 17923 list.addClass(that.listVisibleClass); 17924 17925 // Hide other share nodes 17926 that.nodes.not(node).find(".js-share-list").removeClass(that.listVisibleClass); 17927 } else if (action === "hide") { 17928 // Hide the share node after a little delay 17929 that.timeout = setTimeout(function () { 17930 list.removeClass(that.listVisibleClass); 17931 }, Settings.speed); 17932 } 17933 } 17934 }; 17935
17936 Share.init(); 17937 17938 return Share; 17939}); 17940/** 17941 * Sticky 17942 * @namespace Verkami 17943 * @class Sticky 17944 */ 17945 17946var name = "Verkami/Sticky"; 17947var deps = ["Verkami/Scroll", "Verkami/Settings", "Verkami/Utils"]; 17948 17949modulejs.define(name, deps, function (Scroll, Settings, Utils) { 17950 var Sticky = { 17951 nodes: [], 17952 nodesMobile: [], 17953 activeClass: "bar--sticky", 17954 17955 init: function () { 17956 var that = this; 17957 that.nodes = $(".js-sticky"); 17958 that.nodesMobile = $(".js-sticky-mobile"); 17959 var node = []; 17960 var nodeMobile = []; 17961 17962 setTimeout(function () { 17963 // Run sticky nodes 17964 if (that.nodes.length && !Utils.isMobile && !Utils.isTablet) { 17965 that.nodes.attr("data-sticky", 0); 17966 17967 that.nodes.each(function () { 17968 node = $(this); 17969 17970 that.stick(node, that.nodes); 17971 }); 17972 17973 $(document).on("scroll", function () { 17974 that.nodes.each(function () { 17975 node = $(this); 17976 17977 that.stick(node, that.nodes); 17978 }); 17979 }); 17980 } 17981 17982 // Run sticky nodes in mobile 17983 if (that.nodesMobile.length && Utils.isMobile) { 17984 that.nodesMobile.attr("data-sticky", 0); 17985 17986 that.nodesMobile.each(function () { 17987 nodeMobile = $(this); 17988 17989 that.stick(nodeMobile, that.nodesMobile); 17990 }); 17991 17992 $(document).on("scroll", function () { 17993 that.nodesMobile.each(function () { 17994 nodeMobile = $(this); 17995 17996 that.stick(nodeMobile, that.nodesMobile); 17997 }); 17998 }); 17999 } 18000 }, Settings.speed * 2); 18001 }, 18002 18003 getOffset: function () { 18004 var that = this; 18005 var nodes = []; 18006 var offset = 0; 18007 18008 if (Utils.isMobile || Utils.isTablet) { 18009 nodes = that.nodesMobile.filter(function () { 18010 return parseInt($(this).attr("data-sticky")) === 1; 18011 }); 18012 } else { 18013 nodes = that.nodes.filter(function () { 18014 return parseInt($(this).attr("data-sticky")) === 1; 18015 }); 18016 } 18017 18018 nodes.each(function () { 18019 offset += $(this).outerHeight(); 18020 }); 18021 18022 return offset; 18023 }, 18024 18025 stick: function (node, nodes) { 18026 var that = this; 18027 var scrollPosition = Scroll.position(); 18028 var stickyHeight = node.outerHeight(); 18029 var stickyOffset = 0; 18030 var nextElement = node.nextAll(":visible").first(); 18031 var nextElementTopPadding = 0; 18032 var isStuck = false; 18033 var stickyOthersHeight = 0; 18034 var activeClass = node.data("sticky-class") || that.activeClass; 18035 18036 if (!nextElement.length) { 18037 nextElement = node.parent(); 18038 } 18039 18040 if (nextElement.attr("data-sticky-padding") === undefined) { 18041 nextElement.attr("data-sticky-padding", parseInt(nextElement.css("padding-top"))); 18042 } 18043 18044 if (!node.attr("data-sticky-offset")) { 18045 if (Utils.isMobile) { 18046 node.attr("data-sticky-offset", node.offset().top + stickyHeight); 18047 } else { 18048 node.attr("data-sticky-offset", node.offset().top); 18049 } 18050 } 18051 18052 nextElementTopPadding = parseInt(nextElement.attr("data-sticky-padding")); 18053 stickyOffset = node.attr("data-sticky-offset"); 18054 18055 nodes.not(node).each(function () { 18056 isStuck = parseInt($(this).attr("data-sticky")); 18057 18058 if (isStuck) { 18059 stickyOthersHeight += $(this).outerHeight(); 18060 } 18061 }); 18062 18063 if (scrollPosition >= stickyOffset - stickyOthersHeight) { 18064 if (!parseInt(node.attr("data-sticky"))) { 18065 if (node.data("sticky-lock-width")) { 18066 node.css("width", node.outerWidth()); 18067 } 18068 if (Utils.isMobile) { 18069 node.css("bottom", stickyOthersHeight); 18070 } else { 18071 node.css("top", stickyOthersHeight); 18072 } 18073 18074 node.attr("data-sticky", 1).addClass(activeClass); 18075 nextElement.css("padding-top", nextElementTopPadding + stickyHeight); 18076 } 18077 } else { 18078 if (parseInt(node.attr("data-sticky"))) { 18079 if (node.data("sticky-lock-width")) { 18080 node.css("width", ""); 18081 } 18082 node.attr("data-sticky", 0).removeClass(activeClass).css("top", "auto"); 18083 nextElement.css("padding-top", nextElementTopPadding); 18084 } 18085 } 18086 }, 18087 }; 18088 18089 Sticky.init(); 18090 18091 return Sticky; 18092}); 18093/** 18094 * Switch Content (same as Toggle but using radio buttons and 2 possible contents, hidden and shown) 18095 * @namespace Verkami 18096 * @class Switcher 18097 */ 18098 18099var name = "Verkami/Switcher"; 18100var deps = ["Verkami/Settings"]; 18101 18102modulejs.define(name, deps, function (Settings) { 18103 const Switcher = { 18104 nodes: [], 18105 18106 init: function () { 18107 const that = this; 18108 that.nodes = $(".js-switcher"); 18109 18110 if (that.nodes.length) { 18111 that.nodes.each(function () { 18112 that.setup($(this)); 18113 }); 18114 } 18115 }, 18116 18117 setup: function (node) { 18118 const that = this; 18119 18120 if (!node.hasClass("js-switcher")) { 18121 node = $(".js-switcher", node); 18122 } 18123 18124 if (node.length) { 18125 const onContent = $(".js-switcher-content[data-switcher-on]", node); 18126 const offContent = $(".js-switcher-content[data-switcher-off]", node); 18127 18128 // Let's determine the content that should be shown by default 18129 const checkedToggleValue = $(".js-switcher-toggle:checked", node).val(); 18130 const shouldDisplayContent = !!+checkedToggleValue; 18131 if (shouldDisplayContent) { 18132 offContent.hide(); 18133 } else { 18134 onContent.hide(); 18135 } 18136 18137 node.on("change.switcher", ".js-switcher-toggle", function (e) {
18138 const node = $(this).closest(".js-switcher"); 18139 const action = Boolean(parseInt(this.value)); 18140 18141 that.switch(node, action); 18142 }); 18143 } 18144 }, 18145 18146 switch: function (node, show) { 18147 const offContent = $(".js-switcher-content[data-switcher-off]", node); 18148 const onContent = $(".js-switcher-content[data-switcher-on]", node); 18149 18150 if (show) { 18151 onContent.slideDown(); 18152 offContent.slideUp(); 18153 } else { 18154 offContent.slideDown(); 18155 onContent.slideUp(); 18156 } 18157 }, 18158 }; 18159 18160 Switcher.init(); 18161 18162 return Switcher; 18163}); 18164/** 18165 * Tabs 18166 * @namespace Verkami 18167 * @class Tabs 18168 */ 18169 18170var name = "Verkami/Tabs"; 18171var deps = [ 18172 "Verkami/Carousel", 18173 "Verkami/Utils" 18174]; 18175 18176modulejs.define(name, deps, function (Carousel, Utils) { 18177 var Tabs = { 18178 nodes: [], 18179 triggerActiveClass: "tabs__item--active", 18180 18181 init: function () { 18182 var that = this; 18183 that.nodes = $(".js-tabs"); 18184 18185 if (that.nodes.length) { 18186 that.nodes.each(function () { 18187 that.setup($(this)); 18188 }); 18189 } 18190 18191 that.callbacks(); 18192 18193 that.events(); 18194 }, 18195 18196 callbacks: function () { 18197 var that = this; 18198 18199 $(document).on("trigger.vk.tabs.setup", ".js-tabs", function () { 18200 that.setup($(this)); 18201 }); 18202 }, 18203 18204 events: function () { 18205 var that = this; 18206 18207 // Toggle tab contents by clicking a trigger 18208 $(document).on("click.vk.tabs.toggle", ".js-tabs-trigger", function () { 18209 var trigger = $(this); 18210 var node = trigger.closest(".js-tabs"); 18211 var triggers = $(".js-tabs-trigger", node); 18212 var contents = $(".js-tabs-content", node); 18213 var i = triggers.index(trigger); 18214 18215 if (!trigger.hasClass(that.triggerActiveClass)) { 18216 that.toggleContents(contents, i); 18217 that.toggleTriggers(trigger); 18218 } 18219 }); 18220 }, 18221 18222 setup: function (node) { 18223 var that = this; 18224 var triggers = $(".js-tabs-trigger", node); 18225 var contents = $(".js-tabs-content", node); 18226 var trigger = []; 18227 var triggerActive = []; 18228 var triggerActiveMobile = []; 18229 var isActive; 18230 var activeIndex = "unknown"; 18231 18232 // Check for specific active tab in mobile devices 18233 if (Utils.isMobile && !Utils.hash.get()) { 18234 triggerActiveMobile = triggers.filter(function () { 18235 return $(this).data("tabs-active-mobile"); 18236 }); 18237 18238 if (triggerActiveMobile.length) { 18239 activeIndex = triggers.index(triggerActiveMobile); 18240 18241 triggers.removeClass(that.triggerActiveClass); 18242 triggerActiveMobile.addClass(that.triggerActiveClass); 18243 18244 triggerActive = triggerActiveMobile; 18245 } 18246 } 18247 18248 // If active trigger is not previusly defined, find it by class 18249 if (!triggerActive.length) { 18250 triggers.each(function (index, el) { 18251 trigger = $(this); 18252 isActive = trigger.hasClass(that.triggerActiveClass); 18253 18254 if (isActive) { 18255 activeIndex = triggers.index(trigger); 18256 return true; 18257 } 18258 }); 18259 } 18260 18261 if (activeIndex == "unknown") { 18262 triggers.first().addClass(that.triggerActiveClass); 18263 18264 contents.slice(1).hide(); 18265 } else { 18266 contents.not(":eq(" + activeIndex + ")").hide(); 18267 } 18268 18269 // Emit a callback to be used if needed in other components 18270 node.trigger("hook.vk.tabs.ready"); 18271 }, 18272 18273 toggleContents: function (contents, activeIndex) { 18274 if (Utils.isMobile) { 18275 contents.hide().eq(activeIndex).show(); 18276 } else { 18277 contents.slideUp().eq(activeIndex).slideDown(); 18278 } 18279 18280 // Emit a special event to use it as a callback 18281 contents.eq(activeIndex).trigger("hook.vk.tabs.show", [activeIndex]); 18282 }, 18283 18284 toggleTriggers: function (activeTrigger) { 18285 var that = this; 18286 18287 activeTrigger.siblings().removeClass(that.triggerActiveClass); 18288 activeTrigger.addClass(that.triggerActiveClass); 18289 } 18290 }; 18291 18292 Tabs.init(); 18293 18294 return Tabs; 18295}); 18296/** 18297 * Toggle Content 18298 * @namespace Verkami 18299 * @class Toggle 18300 */ 18301 18302var name = "Verkami/Toggle"; 18303var deps = ["Verkami/Settings"]; 18304 18305modulejs.define(name, deps, function (Settings) { 18306 const Toggle = { 18307 nodes: [], 18308 18309 init: function () { 18310 const that = this; 18311 that.setupNewNodes(); 18312 }, 18313 18314 setupNewNodes: function () { 18315 var that = this; 18316 that.nodes = $(".js-toggle"); 18317 18318 var newNodes = that.nodes.filter(function () { 18319 return !$(this).data("moduleToggleSetupDone"); 18320 }); 18321 18322 if (newNodes.length) { 18323 newNodes.each(function () { 18324 that.setup($(this)); 18325 }); 18326 newNodes.data("moduleToggleSetupDone", true); 18327 } 18328 }, 18329 18330 toggle: function (node) { 18331 const content = $(".js-toggle-content", node).first(); 18332 const isExpanded = node.attr("data-toggle-expanded") === "true"; 18333 const triggerCollapse = $(".js-toggle-trigger-collapse", node).first(); 18334 const triggerExpand = $(".js-toggle-trigger-expand", node).first(); 18335 18336 if (isExpanded) { 18337 node.attr("data-toggle-expanded", "false"); 18338 content.attr("aria-expanded", "false"); 18339 triggerCollapse.hide(); 18340 triggerExpand.show(); 18341 content.slideUp(); 18342 } else { 18343 node.attr("data-toggle-expanded", "true"); 18344 content.attr("aria-expanded", "true"); 18345 triggerCollapse.show(); 18346 triggerExpand.hide(); 18347 content.slideDown(); 18348 } 18349 }, 18350 18351 setup: function (node) { 18352 const that = this; 18353 18354 if (!node.hasClass("js-toggle")) { 18355 node = $(".js-toggle", node).first(); 18356 } 18357 18358 if (node.length) { 18359 node.off("click.toggle", ".js-toggle-trigger:first").on("click.toggle", ".js-toggle-trigger:first", function (e) { 18360 e.preventDefault(); 18361 that.toggle(node); 18362 }); 18363 } 18364 }, 18365 }; 18366
18367 Toggle.init(); 18368 18369 return Toggle; 18370}); 18371/** 18372* Url 18373* @namespace Verkami 18374* @class Url 18375*/ 18376 18377var name = 'Verkami/Url'; 18378 18379modulejs.define(name, function() { 18380 var Url = { 18381 nodes: [], 18382 18383 init: function() { 18384 var that = this; 18385 var name = ''; 18386 var source = ''; 18387 that.nodes = $('.js-url'); 18388 18389 if (that.nodes.length) { 18390 that.nodes.on('click', function() { 18391 name = $(this).attr('data-url-name'); 18392 source = $(this).attr('data-url-source'); 18393 18394 if (source) { 18395 that.update({ page: name }, source); 18396 } 18397 }); 18398 } 18399 }, 18400 18401 update: function(name, source) { 18402 history.pushState(name, null, source); 18403 } 18404 }; 18405 18406 Url.init(); 18407 18408 return Url; 18409}); 18410/** 18411 * Video 18412 * @namespace Verkami 18413 * @class Video 18414 */ 18415 18416modulejs.define("Verkami/Video", function () { 18417 var Video = { 18418 nodes: [], 18419 ratio: 1.77777777778, // 16:9 by default, set `data-video-ratio` to use another 18420 events: { 18421 resize: "resize.vk.video", 18422 }, 18423 18424 init: function () { 18425 var that = this; 18426 that.nodes = $(".js-video"); 18427 18428 if (that.nodes.length) { 18429 that.initialize(that.nodes); 18430 } 18431 }, 18432 18433 initialize: function (nodes) { 18434 var that = this; 18435 var node = []; 18436 nodes = nodes.filter(function () { 18437 return !$(this).attr("data-video-initialized"); 18438 }); 18439 18440 if (nodes.length) { 18441 nodes.each(function () { 18442 node = $(this); 18443 18444 if (node.is(":visible")) { 18445 that.setSize(node); 18446 } 18447 }); 18448 18449 $(window).on(that.events.resize, function () { 18450 nodes.each(function () { 18451 node = $(this); 18452 18453 if (node.is(":visible")) { 18454 that.setSize(node); 18455 } 18456 }); 18457 }); 18458 } 18459 }, 18460 18461 setSize: function (video) { 18462 var that = this; 18463 var videoRatio = video.data("video-ratio") ? video.data("video-ratio") : that.ratio; 18464 var currentHeight = 0; 18465 var currentWidth = 0; 18466 var currentRatio = 0; 18467 var adjustedSize = 0; 18468 18469 // Reset former values 18470 video.css({ 18471 height: "", 18472 "max-width": "", 18473 }); 18474 18475 // Calculate current Size and Ratio 18476 currentHeight = video.height(); 18477 currentWidth = video.width(); 18478 currentRatio = currentWidth / currentHeight; 18479 18480 if (videoRatio < currentRatio && isFinite(currentRatio)) { 18481 adjustedSize = parseInt(currentHeight * videoRatio); 18482 18483 // Adjust width to the desired ratio 18484 video.css("max-width", adjustedSize); 18485 } else { 18486 adjustedSize = parseInt(currentWidth / videoRatio); 18487 18488 // Adjust height to the desired ratio 18489 video.height(adjustedSize); 18490 } 18491 18492 video.attr("data-video-initialized", "true"); 18493 }, 18494 }; 18495 18496 Video.init(); 18497 18498 return Video; 18499}); 18500/** 18501 * Auth 18502 * @namespace Verkami 18503 * @class Auth 18504 */ 18505 18506modulejs.define( 18507 "Verkami/Auth", 18508 ["Verkami/Form", "Verkami/Settings", "Verkami/Utils"], 18509 function (Form, Settings, Utils) { 18510 const Auth = { 18511 authLayer: [], 18512 18513 init: function () { 18514 const that = this; 18515 that.authLayer = $(".js-auth"); 18516 18517 sessionStorage.removeItem("auth-email"); 18518 sessionStorage.removeItem("auth-gmail"); 18519 sessionStorage.removeItem("auth-layer-previous"); 18520 sessionStorage.setItem("auth-layer", "email"); 18521 18522 that.setupBackLink(); 18523 18524 that._events(); 18525 }, 18526 18527 _events: function () { 18528 const that = this; 18529 18530 that.authLayer.on("input.auth.email", ".js-auth-email-field", function () { 18531 if (Form.validate.email($(this).val())) { 18532 $(".js-auth-email-form .js-submit").prop("disabled", false); 18533 } else { 18534 $(".js-auth-email-form .js-submit").prop("disabled", true); 18535 } 18536 }); 18537 18538 that.authLayer.on("submit.auth.verifyEmail", ".js-auth-email-form", function (e) { 18539 e.preventDefault(); 18540 that.verifyEmail(); 18541 }); 18542 18543 that.authLayer.on("submit.auth.login", ".js-auth-login-form", function (e) { 18544 e.preventDefault(); 18545 that.login(); 18546 }); 18547 18548 that.authLayer.on("click.auth.recoverPassword", ".js-auth-password-recovery", function (e) { 18549 const endpoint = $(this).prop("href"); 18550 18551 e.preventDefault(); 18552 that.recoverPassword(endpoint); 18553 }); 18554 18555 that.authLayer.on("submit.auth.signup", ".js-auth-signup-form", function (e) { 18556 e.preventDefault(); 18557 that.signup(); 18558 }); 18559 18560 that.authLayer.on("click.auth.trigger", ".js-auth-trigger", function () { 18561 const layer = $(this).data("auth-layer"); 18562 18563 that.toggleLayer(layer); 18564 }); 18565 }, 18566
18567 fillEmailPlaceholders: function (layerName) { 18568 const that = this; 18569 const email = sessionStorage.getItem("auth-email"); 18570 const layer = $(`.js-auth-layer[data-auth-layer='${layerName}']`, that.authLayer); 18571 18572 $(".js-auth-email-placeholder", layer).html(email); 18573 }, 18574 18575 gmailChecking: function (email) { 18576 const that = this; 18577 const domainList = ["gmail.com"]; 18578 18579 // Extract full domain from the email address 18580 const domain = email.substring(email.lastIndexOf("@") + 1); 18581 18582 // Check if the domain is present in the array of valid domains 18583 const isGmail = domainList.includes(domain); 18584 18585 if (isGmail) { 18586 $(".js-auth-gmail-only", that.authLayer).show(); 18587 } else { 18588 $(".js-auth-gmail-only", that.authLayer).hide(); 18589 } 18590 }, 18591 18592 login: function () { 18593 const that = this; 18594 const form = $(".js-auth-login-form", that.authLayer); 18595 const submit = $(".js-submit", form); 18596 const endpoint = form.prop("action"); 18597 let redirectPath = form.attr("data-auth-redirect"); 18598 let errorMessage = form.attr("data-error-message"); 18599 const formData = form.serializeArray(); 18600 const formValues = formData.reduce(function (obj, item) { 18601 obj[item.name] = item.value; 18602 return obj; 18603 }, {}); 18604 18605 // Add email address to the form data 18606 formValues["user_session[login]"] = sessionStorage.getItem("auth-email"); 18607 18608 $.ajax({ 18609 type: "POST", 18610 url: endpoint, 18611 data: formValues, 18612 dataType: "json", 18613 error: function () { 18614 Form.submit.errorState(submit); 18615 }, 18616 success: function (response) { 18617 if (response.logged) { 18618 Form.submit.successState(submit); 18619 18620 // Go to the custom redirect URL 18621 redirectPath = redirectPath || response.redirect; 18622 18623 if (redirectPath) { 18624 Utils.redirect(redirectPath); 18625 } else { 18626 $(document).trigger("trigger.vk.auth.loggedIn"); 18627 } 18628 } else { 18629 const formNames = { 18630 password: "user_session[password]", 18631 }; 18632 errors = [ 18633 { 18634 password: errorMessage, 18635 }, 18636 ]; 18637 Form.showInputErrors(formNames, errors, form); 18638 Form.submit.errorState(submit); 18639 18640 // Show password error 18641 Form.error("show", $(".js-auth-login-password", form), true); 18642 } 18643 }, 18644 }); 18645 }, 18646 18647 recoverPassword: function (endpoint) { 18648 const that = this; 18649 const email = sessionStorage.getItem("auth-email"); 18650 18651 $.ajax({ 18652 type: "POST", 18653 url: endpoint, 18654 data: { 18655 user: { 18656 email, 18657 }, 18658 }, 18659 dataType: "json", 18660 success: function () { 18661 that.toggleLayer("password-recovery"); 18662 }, 18663 }); 18664 }, 18665 18666 setupBackLink: function (oldLayer, layer) { 18667 const backLink = $(".js-auth-back"); 18668 18669 if (["email", "password-recovery"].includes(layer) || !layer) { 18670 backLink.hide(); 18671 sessionStorage.removeItem("auth-layer-previous"); 18672 } else { 18673 backLink.show(); 18674 backLink.attr("data-auth-layer", oldLayer); 18675 } 18676 }, 18677 18678 setupPasswordLayer: function () { 18679 const that = this; 18680 const email = sessionStorage.getItem("auth-email"); 18681 18682 // Check if it's a gmail account to show the Google button 18683 that.gmailChecking(email); 18684 18685 // Show user's email in specific placeholders 18686 that.fillEmailPlaceholders("password"); 18687 }, 18688 18689 setupSignupLayer: function () { 18690 const that = this; 18691 const email = sessionStorage.getItem("auth-email"); 18692 18693 // Copy email address from the first step 18694 $(".js-auth-signup-email", that.authLayer).val(email); 18695 }, 18696 18697 signup: async function () { 18698 const that = this; 18699 const formNames = { 18700 email: "user[email]", 18701 email_confirmation: "user[email_confirmation]", 18702 name: "user[name]", 18703 password: "user[password]", 18704 newsletter: "user[wants_newsletter]", 18705 terms_agreement: "user[terms_agreement]", 18706 }; 18707 const form = $(".js-auth-signup-form", that.authLayer); 18708 const captchaKey = form.attr("data-captcha-key"); 18709 const submit = $(".js-submit", form); 18710 const endpoint = form.prop("action"); 18711 let redirectPath = form.attr("data-auth-redirect"); 18712 const formData = form.serializeArray(); 18713 18714 // Validate Form 18715 const formValues = formData.reduce(function (obj, item) { 18716 obj[item.name] = item.value; 18717 return obj; 18718 }, {}); 18719 18720 const usernameCheck = formValues[formNames.name].length; 18721 const passwordCheck = formValues[formNames.password].length; 18722 const termsCheck = Boolean(parseInt(formValues[formNames.terms_agreement])); 18723 18724 if (!usernameCheck) { 18725 Form.error("show", $(`input[name="${formNames.name}"]`, form, true)); 18726 } 18727 18728 if (!passwordCheck) { 18729 Form.error("show", $(`input[name="${formNames.password}"]`, form, true)); 18730 } 18731 18732 if (!termsCheck) { 18733 Form.error("show", $(`input[name="${formNames.terms_agreement}"]`, form, true)); 18734 } 18735 18736 if (!usernameCheck || !passwordCheck || !termsCheck) { 18737 Form.submit.errorState(submit); 18738 return; 18739 } 18740 18741 // Execute captcha if it's enabled 18742 if (captchaKey) { 18743 const token = await grecaptcha.execute(captchaKey, { action: "signup" }); 18744 18745 formData.push( 18746 { 18747 name: "g-recaptcha-response", 18748 value: token, 18749 }, 18750 { 18751 name: "g-recaptcha-version", 18752 value: "v3", 18753 } 18754 ); 18755 } 18756 18757 // Send signup form to the backend 18758 $.ajax({ 18759 type: "POST", 18760 url: endpoint, 18761 data: formData, 18762 dataType: "json", 18763 error: function () { 18764 Form.submit.errorState(submit); 18765 }, 18766 success: function (response) { 18767 if (response.signup) { 18768 // Show success feedback in submit button 18769 Form.submit.successState(submit); 18770 18771 // Go to the custom redirect URL 18772 redirectPath = redirectPath || response.redirect; 18773 18774 if (redirectPath) { 18775 Utils.redirect(redirectPath); 18776 } else { 18777 $(document).trigger("trigger.vk.auth.signedUp"); 18778 } 18779 } else { 18780 // Remove old error messages 18781 $('input[name^="user["]', form) 18782 .closest('[class*="form-item"]') 18783 .find(".form-item__error-message") 18784 .remove(); 18785 18786 Form.showInputErrors(formNames, response.errors, form); 18787 18788 // Show error feedback in submit button 18789 Form.submit.errorState(submit); 18790 } 18791 }, 18792 }); 18793 }, 18794 18795 toggleLayer: function (layer) { 18796 const that = this; 18797 const oldLayer = sessionStorage.getItem("auth-layer"); 18798
18799 // Do nothing if the new layer is the same as the current one 18800 if (oldLayer === layer) return; 18801 18802 // Setup a few things depending on the new layer 18803 switch (layer) { 18804 case "password": 18805 that.setupPasswordLayer(); 18806 break; 18807 case "signup": 18808 that.setupSignupLayer(); 18809 break; 18810 } 18811 18812 $(`.js-auth-layer[data-auth-layer='${oldLayer}']`, that.authLayer).fadeOut(Settings.speed, function () { 18813 // Show/hide the back link depending on the step, and change its target 18814 that.setupBackLink(oldLayer, layer); 18815 18816 // Show/hide the captcha legal text depending on the step 18817 that.toggleCaptcha(layer); 18818 18819 $(`.js-auth-layer[data-auth-layer='${layer}']`, that.authLayer).fadeIn(Settings.speed); 18820 }); 18821 18822 // Save current and previous layers locally 18823 sessionStorage.setItem("auth-layer-previous", oldLayer); 18824 sessionStorage.setItem("auth-layer", layer); 18825 }, 18826 18827 toggleCaptcha: function (layer) { 18828 const that = this; 18829 const captcha = $(".js-auth-captcha", that.authLayer); 18830 18831 if (layer === "email") { 18832 captcha.fadeIn(); 18833 } else { 18834 captcha.fadeOut(); 18835 } 18836 }, 18837 18838 verifyEmail: function () { 18839 const that = this; 18840 const email = $(".js-auth-email-field").val(); 18841 const endpoint = $(".js-auth-email-form").prop("action"); 18842 const form = $(".js-auth-email-form", that.authLayer); 18843 const submit = $(".js-submit", form); 18844 18845 const formNames = { 18846 email: "user[login]", 18847 }; 18848 18849 $.ajax({ 18850 type: "POST", 18851 url: endpoint, 18852 data: { 18853 user: { 18854 email, 18855 }, 18856 }, 18857 dataType: "json", 18858 error: function () { 18859 Form.submit.errorState($(".js-auth-email-form .js-submit")); 18860 }, 18861 success: function (response) { 18862 if (response.errors.length === 0) { 18863 Form.submit.successState($(".js-auth-email-form .js-submit")); 18864 18865 sessionStorage.setItem("auth-email", email); 18866 18867 if (Utils.caseInsensitiveEqual(response.user, email)) { 18868 that.toggleLayer("password"); 18869 } else { 18870 that.toggleLayer("signup"); 18871 } 18872 } else { 18873 $('input[name^="user["]', form) 18874 .closest('[class*="form-item"]') 18875 .find(".form-item__error-message") 18876 .remove(); 18877 18878 Form.showInputErrors(formNames, response.errors, form); 18879 18880 Form.submit.errorState(submit); 18881 } 18882 }, 18883 }); 18884 }, 18885 }; 18886 18887 Auth.init(); 18888 18889 return Auth; 18890 } 18891); 18892/** 18893* Avatar 18894* @namespace Verkami 18895* @class Avatar 18896*/ 18897 18898var name = 'Verkami/Avatar'; 18899var deps = [ 18900 'Verkami/Form', 18901 'Verkami/Settings' 18902]; 18903 18904modulejs.define(name, deps, function(Form, Settings) { 18905 var Avatar = { 18906 nodes: [], 18907 csrfToken: '', 18908 18909 init: function() { 18910 var that = this; 18911 that.nodes = $('.js-avatar'); 18912 18913 if (that.nodes.length) { 18914 that.csrfToken = $('meta[name="csrf-token"]').prop('content'); 18915 18916 that.nodes.each(function(i) { 18917 that.create($(this), i); 18918 }); 18919 } 18920 }, 18921 18922 create: function(avatarModule, i) { 18923 var that = this; 18924 var avatarModal = $(this).hasClass('js-modal') ? avatarModule : avatarModule.closest('.js-modal'); 18925 var avatarPlaceholders = $('.' + avatarModule.data('avatar-placeholder')); 18926 var avatarSize = parseInt(avatarModule.data('avatar-size')); 18927 var avatarTarget = avatarModule.prop('action'); 18928 var avatarTrigger = $('.js-avatar-trigger', avatarModule); 18929 var ajaxHeaders = (that.csrfToken) ? { 'X_CSRF_TOKEN': that.csrfToken } : {}; 18930 18931 avatarModule.prop('id', 'avatarModule' + i); 18932 18933 avatarTrigger.on('click', function(e) { 18934 // Make sure that the form isn't actually being sent. 18935 e.preventDefault(); 18936 e.stopPropagation(); 18937 }); 18938 18939 avatarModule.dropzone({ 18940 acceptedFiles: '.jpg, .png, .jpeg', 18941 headers: ajaxHeaders, 18942 hiddenInputContainer: '#avatarModule' + i, 18943 maxFilesize: 10, 18944 previewTemplate: '<div class="dz-preview dz-file-preview"><img data-dz-thumbnail /></div>', 18945 previewsContainer: '#avatarModule' + i + ' .js-avatar-preview', 18946 thumbnailWidth: avatarSize, 18947 thumbnailHeight: avatarSize, 18948 uploadMultiple: false, 18949 url: avatarTarget, 18950 clickable: '#avatarModule' + i + ' .js-avatar-trigger', 18951 18952 addedfile: function(data) { 18953 Form.submit.loadingState(avatarTrigger); 18954 18955 $('.js-avatar-cancel', avatarModule).css('visibility', 'hidden'); 18956 18957 $('.js-modal-close', avatarModule).one('click.avatarCancel', function() { 18958 if (data.status != "success") { 18959 avatarModule[0].dropzone.removeAllFiles(true); 18960 18961 avatarPlaceholders.each(function() { 18962 $(this).prop('src', $(this).data('avatar-old')); 18963 }); 18964 } 18965 }); 18966 }, 18967 18968 complete: function(data) { 18969 if (data.status == 'success') { 18970 Form.submit.successState(avatarTrigger); 18971 18972 $('.js-modal-close', avatarModule).off('click.avatarCancel'); 18973 18974 setTimeout(function() { 18975 avatarModule[0].dropzone.removeAllFiles(true); 18976 18977 avatarModal.trigger('trigger.vk.modal.close'); 18978 }, Settings.speed * 10); 18979 } else { 18980 Form.submit.errorState(avatarTrigger); 18981 } 18982 18983 $('.js-avatar-cancel', avatarModule).css('visibility', 'visible'); 18984 }, 18985 18986 thumbnail: function(data, dataUrl) { 18987 var avatarPlaceholder = []; 18988 var avatarOld = ''; 18989 18990 avatarPlaceholders.each(function() { 18991 avatarPlaceholder = $(this); 18992 18993 if (avatarPlaceholder.is('img')) { 18994 avatarOld = avatarPlaceholder.attr('src'); 18995 avatarPlaceholder.data('avatar-old', avatarOld).attr('src', dataUrl); 18996 } else { 18997 avatarOld = avatarPlaceholder.css('background-image'); 18998 avatarPlaceholder.data('avatar-old', avatarOld).css('background-image', 'url(' + dataUrl + ')'); 18999 } 19000 }); 19001 } 19002 }); 19003 }, 19004 19005 refresh: function(imageSrc) { 19006 var avatarPlaceholders = $('.js-avatar-profile-placeholder'); 19007 var avatarPlaceholder = []; 19008 var avatarOld = ''; 19009 19010 avatarPlaceholders.each(function() { 19011 avatarPlaceholder = $(this); 19012 19013 if (avatarPlaceholder.is('img')) { 19014 avatarOld = avatarPlaceholder.attr('src'); 19015 avatarPlaceholder.data('avatar-old', avatarOld).attr('src', imageSrc); 19016 } else { 19017 avatarOld = avatarPlaceholder.css('background-image'); 19018 avatarPlaceholder.data('avatar-old', avatarOld).css('background-image', 'url(' + imageSrc + ')'); 19019 } 19020 }); 19021 } 19022 }; 19023 19024 Avatar.init(); 19025 19026 return Avatar; 19027}); 19028/** 19029* Backers 19030* @namespace Verkami 19031* @class Backers 19032*/ 19033 19034var name = 'Verkami/Backers'; 19035 19036modulejs.define(name, function() { 19037 var Backers = { 19038 input: [], 19039 output: [], 19040 ratio: 0, 19041 19042 init: function() { 19043 var that = this; 19044 that.input = $('.js-backers-avg-input'); 19045 19046 if (that.input.length) { 19047 that.output = $('.js-backers-avg-output'); 19048 that.ratio = parseInt(that.output.data('avg-contribution')); 19049 19050 // Calculate backers on load 19051 that.calculate(); 19052 19053 // Calculate backers every time user types something 19054 that.input.on('change paste keyup', function() { 19055 that.calculate(); 19056 }); 19057 } 19058 }, 19059 19060 calculate: function() { 19061 var that = this; 19062 var goal = parseInt(that.input.val()); 19063 var backers = parseInt(goal / that.ratio); 19064 19065 if (backers > 0) { 19066 that.output.val(backers); 19067 } else { 19068 that.output.val(''); 19069 } 19070 } 19071 }; 19072 19073 Backers.init(); 19074 19075 return Backers; 19076}); 19077/** 19078* BlogBar 19079* @namespace Verkami 19080* @class BlogBar 19081*/ 19082 19083var name = 'Verkami/BlogBar'; 19084var deps = [ 19085 'Verkami/Scroll' 19086]; 19087 19088modulejs.define(name, deps, function(Scroll) { 19089 var BlogBar = { 19090 node: [], 19091 visibleClass: 'blog-bar--visible', 19092 post: [], 19093 postOffset: null, 19094 19095 init: function() { 19096 var that = this; 19097 that.node = $('.js-blog-bar'); 19098 19099 if (that.node.length) { 19100 that.post = $('.js-blog-post'); 19101 that.postOffset = that.post.offset().top; 19102
19103 that.toggle(); 19104 19105 $(window).scroll(function() { 19106 that.toggle(); 19107 }); 19108 } 19109 }, 19110 19111 toggle: function() { 19112 var that = this; 19113 19114 var scrollPosition = Scroll.position(); 19115 19116 if (scrollPosition > that.postOffset) { 19117 that.node.addClass(that.visibleClass); 19118 } else { 19119 that.node.removeClass(that.visibleClass); 19120 } 19121 } 19122 }; 19123 19124 BlogBar.init(); 19125 19126 return BlogBar; 19127}); 19128/** 19129* BlogNavigation 19130* @namespace Verkami 19131* @class BlogNavigation 19132*/ 19133 19134var name = 'Verkami/BlogNavigation'; 19135 19136modulejs.define(name, function() { 19137 var BlogNavigation = { 19138 nodes: [], 19139 19140 init: function() { 19141 var that = this; 19142 that.nodes = $('.js-blog-nav'); 19143 19144 if (that.nodes.length) { 19145 var links = []; 19146 var link = []; 19147 var separator = []; 19148 var linkWidth = 0; 19149 var separatorWidth = 0; 19150 var wrapperWidth = 0; 19151 19152 that.nodes.each(function() { 19153 links = $('.js-blog-nav-link', $(this)); 19154 19155 links.each(function() { 19156 link = $(this); 19157 separator = link.siblings('.js-blog-nav-separator'); 19158 19159 // Get widths 19160 linkWidth = link.width(); 19161 separatorWidth = separator.width(); 19162 wrapperWidth = linkWidth + separatorWidth; 19163 19164 // Set width 19165 link.parent().width(wrapperWidth); 19166 }); 19167 }); 19168 } 19169 } 19170 }; 19171 19172 BlogNavigation.init(); 19173 19174 return BlogNavigation; 19175}); 19176/** 19177 * Captcha 19178 * @namespace Verkami 19179 * @class Captcha 19180 */ 19181 19182var name = "Verkami/Captcha"; 19183 19184modulejs.define(name, function() { 19185 var Captcha = { 19186 nodeSelector: ".js-recaptcha", 19187 containerSelector: ".captcha-container", 19188 nodes: [], 19189 content: [], 19190 trigger: [], 19191 19192 init: function() { 19193 var that = this; 19194 that.setupNewNodes(); 19195 }, 19196 setupNewNodes: function() { 19197 var that = this; 19198 that.nodes = $(that.nodeSelector); 19199 19200 var newNodes = that.nodes.filter(function() { 19201 return !$(this).data("moduleCaptchaSetupDone"); 19202 }); 19203 19204 if (newNodes.length && !captchaUnavailable) { 19205 console.log("[CAPTCHA] New captcha nodes detected"); 19206 19207 var captchaUnavailable = typeof grecaptcha === "undefined" || typeof grecaptcha.render === "undefined"; 19208 if (captchaUnavailable) { 19209 console.log("[CAPTCHA] Captcha library is not available yet."); 19210 } else { 19211 newNodes.each(function(_index, node) { 19212 console.log("[CAPTCHA] Processing captcha node..."); 19213 19214 $(node).on("click", function(e) { 19215 var widgetId = $(this).data("moduleCaptchaWidgetID"); 19216 e.preventDefault(); 19217 console.log("[CAPTCHA] Resetting " + widgetId); 19218 grecaptcha.reset(widgetId); 19219 console.log("[CAPTCHA] Executing " + widgetId); 19220 grecaptcha.execute(widgetId); 19221 }); 19222 19223 var container = $(node) 19224 .closest(".js-modal") 19225 .find(".captcha-holder")[0]; 19226 var widgetId = grecaptcha.render(container, { 19227 sitekey: $(node).data("sitekey"), 19228 size: "invisible", 19229 callback: function(token) { 19230 that.submitCallback(token, node); 19231 } 19232 }); 19233 19234 $(node).data("moduleCaptchaWidgetID", widgetId); 19235 console.log("[CAPTCHA] ...setup done with id " + widgetId); 19236 }); 19237 newNodes.data("moduleCaptchaSetupDone", true); 19238 } 19239 } 19240 }, 19241 submitCallback: function(_token, node) { 19242 var validatedEvent = "captcha.vk.validated"; 19243 var widgetId = $(node).data("moduleCaptchaWidgetID"); 19244 console.log("[CAPTCHA] Processing submitCallback ID#" + widgetId+ " triggering " + validatedEvent); 19245 $(node).trigger(validatedEvent); 19246 } 19247 }; 19248 return Captcha; 19249}); 19250/** 19251 * Cards 19252 * @namespace Verkami 19253 * @class Cards 19254 */ 19255 19256var name = "Verkami/Cards"; 19257var deps = [ 19258 "Verkami/Carousel", 19259 "Verkami/Settings", 19260 "Verkami/Utils" 19261]; 19262 19263modulejs.define(name, deps, function (Carousel, Settings, Utils) { 19264 var Cards = { 19265 nodes: [], 19266 19267 init: function () { 19268 var that = this; 19269 that.setupNewNodes(); 19270 if (that.nodes.length) { 19271 $(window).resize(function () { 19272 setTimeout(function () {
19273 that.setHeight.init(); 19274 }, Settings.speed); 19275 }); 19276 } 19277 }, 19278 19279 setupNewNodes: function () { 19280 var that = this; 19281 that.nodes = $(".js-card"); 19282 19283 var newNodes = that.nodes.filter(function () { 19284 return !$(this).data("moduleCardsSetupDone"); 19285 }); 19286 19287 if (newNodes.length) { 19288 newNodes.each(function () { 19289 that.excerpt.init($(this)); 19290 that.review.init($(this)); 19291 }); 19292 newNodes.data("moduleCardsSetupDone", true); 19293 that.setHeight.init(); 19294 } 19295 }, 19296 19297 19298 excerpt: { 19299 init: function (card) { 19300 var that = this; 19301 var triggers = $(".js-card-excerpt-show", card); 19302 19303 if (triggers.length) { 19304 triggers.on("click", function () { 19305 that.showExcerpt($(this)); 19306 }); 19307 } 19308 }, 19309 19310 showExcerpt: function (trigger) { 19311 trigger.fadeOut().closest(".js-card").find(".js-card-excerpt").slideDown(); 19312 } 19313 }, 19314 19315 review: { 19316 triggerVisibleClass: "card__review--visible", 19317 19318 init: function (card) { 19319 var that = this; 19320 var review = $(".js-review", card); 19321 19322 if (review.length && (Utils.isMobile || Utils.isTablet)) { 19323 var triggerShow = $(".js-review-show", card); 19324 var triggerHide = $(".js-review-hide", card); 19325 19326 triggerShow.on("click", function (e) { 19327 e.preventDefault(); 19328 review.addClass(that.triggerVisibleClass); 19329 }); 19330 19331 triggerHide.on("click", function (e) { 19332 review.removeClass(that.triggerVisibleClass); 19333 }); 19334 } 19335 } 19336 }, 19337 19338 setHeight: { 19339 init: function () { 19340 var that = this; 19341 var group = null; 19342 var cardsInGroup = []; 19343 var isHidden = false; 19344 var cardsPerRow = 3; 19345 var cardsInRow = []; 19346 19347 $(".js-cards").each(function () { 19348 group = $(this); 19349 cardsInGroup = $(".js-card", group); 19350 19351 if (cardsInGroup.length) { 19352 isHidden = !group.is(":visible"); 19353 19354 if (isHidden) { 19355 group.show(); 19356 } 19357 19358 $(".js-card-tags", cardsInGroup).removeAttr("style"); 19359 19360 if (group.hasClass("js-carousel")) { 19361 that.setRowHeight(cardsInGroup); 19362 } else if (!Utils.isMobile) { 19363 if (Utils.isTablet) { 19364 cardsPerRow = 2; 19365 } 19366 19367 for (var i = 0; i < cardsInGroup.length; i += cardsPerRow) { 19368 cardsInRow = cardsInGroup.slice(i, i + cardsPerRow); 19369 that.setRowHeight(cardsInRow); 19370 } 19371 } 19372 19373 if (isHidden) { 19374 group.hide(); 19375 } 19376 } 19377 }); 19378 }, 19379 19380 setRowHeight: function (cards) { 19381 var card; 19382 var difference = 0; 19383 var maxHeight = 0; 19384 var tagsInitialMargin = 0; 19385 19386 // Get tallest card's height 19387 cards.each(function () { 19388 card = $(this); 19389 if (card.outerHeight() > maxHeight) { 19390 maxHeight = card.outerHeight(); 19391 } 19392 }); 19393 19394 // Add the height difference to smaller cards, then all will have the same height 19395 cards.each(function () { 19396 card = $(this); 19397 if (card.outerHeight() < maxHeight) { 19398 tagsInitialMargin = parseInt($(".js-card-tags", card).css("margin-top")); 19399 difference = maxHeight - card.outerHeight() + tagsInitialMargin + "px"; 19400 $(".js-card-tags", card).css("margin-top", difference); 19401 } 19402 }); 19403 } 19404 } 19405 }; 19406 19407 Cards.init(); 19408 19409 return Cards; 19410}); 19411/** 19412 * Carousel 19413 * @namespace Verkami 19414 * @class Carousel 19415 */ 19416 19417var name = "Verkami/Carousel"; 19418var deps = ["Verkami/Settings", "Verkami/Utils"]; 19419 19420modulejs.define(name, deps, function (Settings, Utils) { 19421 var Carousel = { 19422 carousel: [], 19423 slideshow: [], 19424 carouselMedia: [], 19425 carouselRewards: [], 19426 carouselStats: [], 19427 19428 init: async function () { 19429 var that = this; 19430 that.carousel = $(".js-carousel"); 19431 that.slideshow = $(".js-home-slideshow"); 19432 that.carouselMedia = $(".js-carousel-media"); 19433 that.carouselRewards = $(".js-carousel-rewards"); 19434 that.carouselStats = $(".js-carousel-stats"); 19435 19436 that.setupFlickity(); 19437 19438 if (that.carousel.length) { 19439 that.carousel.each(function () { 19440 var carousel = $(this); 19441
19442 // This data attribute is optional, it shows a linked plus icon when the carousel ends 19443 var target = carousel.data("carousel-target"); 19444 var link = target 19445 ? '<a class="carousel__more" href="' + target + '"><span class="carousel__more__icon"></span></a>' 19446 : ""; 19447 19448 carousel.on("ready.flickity", function () { 19449 carousel.append(link); 19450 }); 19451 19452 carousel.flickity({ 19453 autoPlay: false, 19454 arrowShape: 19455 "M100,46.0502528 L100,54.0502528 L14.285,54.05 L50,90.0588744 L44.1074435,96 L1.92185743,53.4687275 C1.36520756,53.1296066 0.897900066,52.658349 0.563506539,52.098526 L0.418771097,51.9512258 L0.458351735,51.9112208 C0.16565554,51.3553323 8.2282208e-17,50.722138 0,50.0502528 C-8.54815162e-17,49.3522432 0.178788065,48.6959919 0.493067616,48.1247953 L0.418771097,48.0487742 L0.761583529,47.7018614 C1.00238436,47.3703724 1.29283986,47.0772883 1.62202636,46.8335328 L44.1074435,4 L50,9.94112562 L14.186,46.05 L100,46.0502528 Z", 19456 dragThreshold: 10, 19457 freeScroll: Utils.isMobile || Utils.isTablet, 19458 groupCells: true, 19459 pageDots: false, 19460 }); 19461 19462 // If using Tabs, recalculate Carousel's height after changing the tab 19463 if (carousel.hasClass("js-tabs-content") || carousel.closest(".js-tabs-content").length) { 19464 carousel.one("hook.vk.tabs.show", function () { 19465 $(this).flickity("resize"); 19466 }); 19467 } 19468 }); 19469 } 19470 19471 if (that.carouselMedia.length) { 19472 that.carouselMedia.flickity({ 19473 autoPlay: Settings.sliders.delay, 19474 dragThreshold: 10, 19475 freeScroll: Utils.isMobile || Utils.isTablet, 19476 fade: true, 19477 prevNextButtons: false, 19478 }); 19479 } 19480 19481 if (that.carouselRewards.length && Utils.isMobile) { 19482 that.carouselRewards.flickity({ 19483 autoPlay: false, 19484 dragThreshold: 10, 19485 freeScroll: Utils.isMobile || Utils.isTablet, 19486 imagesLoaded: true, 19487 pageDots: false, 19488 prevNextButtons: false, 19489 contain: true, 19490 }); 19491 } 19492 19493 if (that.carouselStats.length) { 19494 that.carouselStats.flickity({ 19495 autoPlay: Settings.sliders.delay, 19496 dragThreshold: 10, 19497 freeScroll: Utils.isMobile || Utils.isTablet, 19498 fade: true, 19499 prevNextButtons: false, 19500 }); 19501 } 19502 19503 if (that.slideshow.length) { 19504 that.slideshow.flickity({ 19505 arrowShape: 19506 "M28.7187079,1.21482578e-13 L31.2058209,1.43593539 L3.167,50 L31.2058209,98.5640646 L28.7187079,100 L-1.67332814e-12,50.2577388 L0.446,50 L-5.22248911e-13,49.7422612 L28.7187079,1.21482578e-13 Z", 19507 autoPlay: Settings.sliders.delay, 19508 contain: true, 19509 fade: true, 19510 pageDots: false, 19511 wrapAround: true, 19512 }); 19513 } 19514 }, 19515 19516 setupFlickity: function () { 19517 Flickity.prototype._createResizeClass = function () { 19518 this.element.classList.add("flickity-resize"); 19519 }; 19520 19521 Flickity.createMethods.push("_createResizeClass"); 19522 19523 var resize = Flickity.prototype.resize; 19524 Flickity.prototype.resize = function () { 19525 this.element.classList.remove("flickity-resize"); 19526 resize.call(this); 19527 this.element.classList.add("flickity-resize"); 19528 }; 19529 }, 19530 }; 19531 19532 Carousel.init(); 19533 19534 return Carousel; 19535}); 19536/** 19537 * Checkout 19538 * @namespace Verkami 19539 * @class Checkout 19540 */ 19541 19542modulejs.define("Verkami/Checkout", ["Verkami/Form", "Verkami/Settings", "Verkami/Utils"], function (Form, Settings, Utils) { 19543 const Checkout = { 19544 checkoutLayer: [], 19545 19546 init: function () { 19547 const that = this; 19548 this.checkoutLayer = $(".js-checkout"); 19549 19550 if (!this.checkoutLayer.length) return; 19551 19552 that._events(); 19553 that._hooks(); 19554 that.setupCart(); 19555 that.setLayerFromURL(); 19556 that.checkPaymentError(); 19557 //that.checkDefaultPaymentMethod(); 19558 }, 19559 19560 _events: function () { 19561 const that = this; 19562 19563 that.checkoutLayer.on("click.checkout.toggleLayer", ".js-checkout-toggle-layer", function () { 19564 const layer = $(this).data("checkout-layer"); 19565 19566 that.toggleLayer(layer); 19567 }); 19568 19569 that.checkoutLayer.on("change.fs.checkout.shippingZone", ".js-checkout-shipping-zone", async function (e) { 19570 let cart = that.getCart(); 19571 const shippingZone = that.getShippingZone(); 19572 19573 if (shippingZone) { 19574 cart.shipping_zone = shippingZone.id; 19575 19576 // Show loader 19577 that.enableLoader(); 19578 19579 // Update addons list 19580 await that.getAddonsList(cart); 19581 19582 // Reset addons in cart 19583 cart = that.resetAddons(cart); 19584 19585 // Update cart 19586 await that.saveCart(cart, true); 19587 19588 // Update shipping label in Totals 19589 that.updateShippingZoneName(shippingZone.name); 19590 19591 // Hide loader 19592 that.disableLoader(); 19593 } 19594 }); 19595 19596 that.checkoutLayer.on("click.checkout.addon.add", ".js-checkout-addon-add", async function (e) {
19597 const addon = $(this).closest(".js-checkout-addon"); 19598 const id = parseInt(addon.attr("data-checkout-addon-id")); 19599 19600 await that.updateAddon(addon, id, 1); 19601 that.toggleAddonSelector(addon, 1); 19602 }); 19603 19604 that.checkoutLayer.on("click.checkout.addon.remove", ".js-checkout-addon-remove", async function (e) { 19605 const addon = $(this).closest(".js-checkout-addon"); 19606 const id = parseInt(addon.attr("data-checkout-addon-id")); 19607 19608 await that.removeAddon(id); 19609 that.toggleAddonSelector(addon, 0); 19610 }); 19611 19612 that.checkoutLayer.on("click.checkout.addon.decrease", ".js-checkout-addon-decrease", async function (e) { 19613 const addon = $(this).closest(".js-checkout-addon"); 19614 const id = parseInt(addon.attr("data-checkout-addon-id")); 19615 const quantity = parseInt($(".js-checkout-addon-value", addon).val()) - 1; 19616 19617 if (quantity === 0) { 19618 await that.removeAddon(id); 19619 that.toggleAddonSelector(addon, 0); 19620 } else { 19621 await that.updateAddon(addon, id, quantity); 19622 } 19623 }); 19624 19625 that.checkoutLayer.on("click.checkout.addon.increase", ".js-checkout-addon-increase", async function (e) { 19626 const addon = $(this).closest(".js-checkout-addon"); 19627 const id = parseInt(addon.attr("data-checkout-addon-id")); 19628 const quantity = parseInt($(".js-checkout-addon-value", addon).val()) + 1; 19629 19630 await that.updateAddon(addon, id, quantity); 19631 }); 19632 19633 that.checkoutLayer.on( 19634 "keyup.checkout.bonus", 19635 ".js-checkout-bonus", 19636 Utils.delayedCallback(function (e) { 19637 that.updateBonus($(this).val()); 19638 }, Settings.speed * 4) 19639 ); 19640 19641 // Avoid non-integer numbers in free pledge input 19642 that.checkoutLayer.on("keypress.checkout.bonus paste.checkout.bonus", ".js-checkout-bonus", function (e) { 19643 if (String.fromCharCode(e.keyCode).match(/[^0-9]/g)) return false; 19644 }); 19645 19646 // Show/hide cart on mobile devices 19647 that.checkoutLayer.on("click.checkout.cart.toggle", ".js-checkout-cart-toggle", function (e) { 19648 that.toggleCart(); 19649 }); 19650 19651 that.checkoutLayer.on("change.checkout.payment.getForm", ".js-checkout-payment-type", function () { 19652 const paymentEndpoint = $(this).attr("data-checkout-payment-endpoint"); 19653 const paymentType = $(this).attr("data-checkout-payment-type"); 19654 19655 that.getPaymentForm(paymentEndpoint, paymentType); 19656 }); 19657 19658 that.checkoutLayer.on("click.checkout.payment.pledge", ".js-checkout-payment-submit", function (e) { 19659 /* 19660 Payment types can have an additional check that overrides the regular type. 19661 An example is the untokenized "redsys" type, which has a checkbox to save the card token after the payment, 19662 this checkbox will always override its main type (redsys) if checked. 19663 */ 19664 const paymentInput = $(".js-checkout-payment-type:checked", that.checkoutLayer); 19665 const additionalInput = $(".js-checkout-payment-type-additional", paymentInput.parent()); 19666 const additionalType = additionalInput.length && additionalInput.is(":checked") ? additionalInput.attr("data-checkout-payment-type") : false; 19667 const paymentType = additionalType || paymentInput.attr("data-checkout-payment-type"); 19668 19669 e.preventDefault(); 19670 19671 that.pledge(paymentType); 19672 }); 19673 }, 19674 19675 _hooks: function () { 19676 const that = this; 19677 19678 this.checkoutLayer.on("checkout.cartBreakdown.loaded", function (e, cartBreakdown) { 19679 that.updateTotal(cartBreakdown); 19680 that.updateAddonsLimitations(cartBreakdown); 19681 }); 19682 19683 $(document).on("trigger.vk.auth.loggedIn", function (e) { 19684 that.toggleLayer("payment"); 19685 }); 19686 19687 $(document).on("trigger.vk.auth.signedUp", function (e) { 19688 that.toggleLayer("payment"); 19689 }); 19690 }, 19691 19692 checkDefaultPaymentMethod: function () { 19693 console.log("[CHECKOUT] Checking default payment method"); 19694 const that = this; 19695 const defaultMethod = $(".js-checkout-payment-type", that.checkoutLayer).first(); 19696 defaultMethod.prop("checked", true); 19697 defaultMethod.trigger("change.checkout.payment.getForm"); 19698 }, 19699 19700 checkCartExtras: function () { 19701 const that = this; 19702 const extrasWrapper = $(".js-checkout-cart-extras", that.checkoutLayer); 19703 const addonsWrapper = $(".js-checkout-cart-addons", that.checkoutLayer); 19704 const bonusWrapper = $(".js-checkout-cart-bonus", that.checkoutLayer); 19705 const cart = that.getCart(); 19706 const hasAddons = Boolean(cart.addons && cart.addons.length);
19707 const hasBonus = Boolean(cart.bonus && cart.bonus >= 0); 19708 const hasExtras = hasAddons || hasBonus; 19709 19710 if (hasExtras) { 19711 extrasWrapper.fadeIn(); 19712 } else { 19713 extrasWrapper.fadeOut(); 19714 } 19715 19716 if (hasAddons) { 19717 addonsWrapper.fadeIn(); 19718 } else { 19719 addonsWrapper.fadeOut(); 19720 } 19721 19722 if (hasBonus) { 19723 bonusWrapper.fadeIn(); 19724 } else { 19725 bonusWrapper.fadeOut(); 19726 } 19727 }, 19728 19729 checkPaymentError: function () { 19730 const errorBox = $(".js-checkout-error", this.checkoutLayer); 19731 const searchParams = new URLSearchParams(window.location.search); 19732 const errorType = searchParams.has("checkout[error]") ? searchParams.get("checkout[error]") : undefined; 19733 19734 if (errorType === "redsys") { 19735 errorBox.show(); 19736 } else { 19737 errorBox.hide(); 19738 } 19739 }, 19740 19741 disableLoader: function () { 19742 const that = this; 19743 const loader = $(".js-checkout-loading", that.checkoutLayer); 19744 19745 loader.removeClass("checkout__loading--active"); 19746 }, 19747 19748 enableLoader: function () { 19749 const that = this; 19750 const loader = $(".js-checkout-loading", that.checkoutLayer); 19751 19752 loader.addClass("checkout__loading--active"); 19753 }, 19754 19755 getAddonsBreakdown: async function (cart) { 19756 const that = this; 19757 const addonsPlaceholder = $(".js-checkout-cart-addons", that.checkoutLayer); 19758 const endpoint = addonsPlaceholder.attr("data-checkout-addons-breakdown-endpoint"); 19759 let result; 19760 19761 try { 19762 result = await $.ajax({ 19763 type: "POST", 19764 url: endpoint, 19765 data: cart, 19766 dataType: "html", 19767 success: function (response) { 19768 that.checkoutLayer.trigger("checkout.addonsBreakdown.loaded", response); 19769 }, 19770 }); 19771 19772 if (result) { 19773 addonsPlaceholder.html(result); 19774 } else { 19775 addonsPlaceholder.html(); 19776 } 19777 } catch (error) { 19778 console.error(error); 19779 } 19780 }, 19781 19782 getAddonsList: async function (cart) { 19783 const that = this; 19784 const addonsPlaceholder = $(".js-checkout-addons", that.checkoutLayer); 19785 const endpoint = addonsPlaceholder.attr("data-checkout-addons-endpoint"); 19786 let result; 19787 19788 try { 19789 result = await $.ajax({ 19790 type: "POST", 19791 url: endpoint, 19792 data: cart, 19793 dataType: "html", 19794 success: function (response) { 19795 that.checkoutLayer.trigger("checkout.addons.loaded", response); 19796 }, 19797 }); 19798 19799 if (result) { 19800 addonsPlaceholder.html(result); 19801 } else { 19802 addonsPlaceholder.html(); 19803 } 19804 } catch (error) { 19805 console.error(error); 19806 } 19807 }, 19808 19809 getCart: function () { 19810 return JSON.parse(sessionStorage.getItem("checkout-cart")); 19811 }, 19812 19813 getFirstLayer: function () { 19814 const that = this; 19815 const layersByPriority = ["customize", "auth", "payment"]; 19816 const existingLayers = layersByPriority.filter((layerName) => { 19817 return $(`.js-checkout-layer[data-checkout-layer='${layerName}']`, that.checkoutLayer).length; 19818 }); 19819 const layer = existingLayers[0]; 19820 19821 return layer; 19822 }, 19823 19824 getPaymentForm: function (endpoint, type) { 19825 console.log("[CHECKOUT] Checking payment method " + type); 19826 const that = this; 19827 const formData = that.getCart(); 19828 const typeSelector = $(".js-checkout-payment-type", that.checkoutLayer); 19829 const paymentForm = $(`.js-checkout-payment-${type}`, that.checkoutLayer); 19830 const forms = $(".js-checkout-payment-forms", that.checkoutLayer); 19831 const submit = $(".js-checkout-payment-submit", that.checkoutLayer); 19832 19833 // Request payment form if it doesn't exist yet 19834 if (!paymentForm.length) { 19835 // Disable selector 19836 typeSelector.prop("disabled", true); 19837 19838 // Disable submit button 19839 Form.submit.loadingState(submit); 19840 submit.prop("disabled", true); 19841 19842 console.log("[CHECKOUT] Getting payment method for " + type); 19843 $.ajax({ 19844 type: "GET", 19845 url: endpoint, 19846 data: formData, 19847 dataType: "html", 19848 success: function (response) { 19849 // Insert new payment form 19850 forms.append(response); 19851 19852 // Enable selector back 19853 typeSelector.prop("disabled", false); 19854 19855 // Enable submit button 19856 Form.submit.defaultState(submit); 19857 submit.prop("disabled", false); 19858 }, 19859 }); 19860 } else { 19861 // Enable submit button 19862 submit.prop("disabled", false); 19863 } 19864 }, 19865 19866 getPriceBreakdown: async function () { 19867 const that = this; 19868 const endpoint = that.checkoutLayer.attr("data-checkout-price-endpoint"); 19869 const cart = that.getCart(); 19870 const buttonNoExtras = $(".js-checkout-customize-no-extras", that.checkoutLayer); 19871 const buttonContinue = $(".js-checkout-customize-continue", that.checkoutLayer); 19872 let result; 19873
19874 try { 19875 console.log("[CHECKOUT] Getting price breakdown"); 19876 result = await $.ajax({ 19877 type: "POST", 19878 url: endpoint, 19879 data: cart, 19880 dataType: "json", 19881 success: function (response) { 19882 console.log("[CHECKOUT] Price breakdown retrieved"); 19883 that.checkoutLayer.trigger("checkout.cartBreakdown.loaded", response); 19884 }, 19885 }); 19886 19887 that.resetPaymentForms(); 19888 that.checkDefaultPaymentMethod(); 19889 19890 if ((result.addons && result.addons.length) || (result.extra && result.extra.units !== 0)) { 19891 buttonNoExtras.fadeOut(Settings.speed, function () { 19892 buttonContinue.fadeIn(Settings.speed); 19893 }); 19894 } else { 19895 buttonContinue.fadeOut(Settings.speed, function () { 19896 buttonNoExtras.fadeIn(Settings.speed); 19897 }); 19898 } 19899 19900 return result; 19901 } catch (error) { 19902 console.error(error); 19903 } 19904 }, 19905 19906 getShippingZone: function () { 19907 const that = this; 19908 const shippingZoneSelect = $(".js-checkout-shipping-zone", that.checkoutLayer); 19909 const shippingZoneId = shippingZoneSelect.length ? shippingZoneSelect.val() : undefined; 19910 const shippingZoneName = shippingZoneSelect.length ? $("option:selected", shippingZoneSelect).text() : undefined; 19911 19912 return { 19913 id: shippingZoneId, 19914 name: shippingZoneName, 19915 }; 19916 }, 19917 19918 pledge: function (type) { 19919 const that = this; 19920 const paymentForm = $(`.js-checkout-payment-${type}`, that.checkoutLayer); 19921 const submit = $(".js-checkout-payment-submit", that.checkoutLayer); 19922 19923 // As the default text for submit sending has been used to describe the payment type selection process 19924 // e.g. "Configurando metodo de pago" here we need an extra text to represent the real submit event 19925 // to the backend 19926 submit.prop("disabled", true); 19927 const pledgingText = submit.attr("data-submit-pledging-text"); 19928 submit.html(pledgingText); 19929 paymentForm.submit(); 19930 19931 // Original frontend chose to move the submit to the default state but that will re-enable the submit 19932 // allowing users to click multiple times (generating in some cases multiple contributions) 19933 // I (AGR) don't know what was the rationale behind that decision but I'm removing that instruction 19934 // from the time being. 19935 // Form.submit.defaultState(submit); 19936 }, 19937 19938 removeAddon: async function (id) { 19939 const that = this; 19940 const cart = that.getCart(); 19941 const addonIndex = cart.addons.findIndex((addon) => addon.id === id); 19942 19943 // Show loader 19944 that.enableLoader(); 19945 19946 // Remove addon from cart 19947 cart.addons.splice(addonIndex, 1); 19948 19949 // Update cart 19950 await that.saveCart(cart, true); 19951 19952 // Update addons breakdown 19953 await that.getAddonsBreakdown(cart); 19954 19955 await that.recoverDefaultLimitedValuesForAddon(id); 19956 19957 // Hide loader 19958 that.disableLoader(); 19959 }, 19960 19961 recoverDefaultLimitedValuesForAddon: function (addonId) { 19962 addon = $("#reward_" + addonId); 19963 addon.find(".available_units").html(addon.attr("data-base-available-units")); 19964 addon.find(".total_units").html(addon.attr("data-total-units")); 19965 }, 19966 19967 resetAddons: function (cart) { 19968 cart.addons = []; 19969 19970 return cart; 19971 }, 19972 19973 resetPaymentForms: function () { 19974 console.log("[CHECKOUT] Resetting payment forms"); 19975 19976 const that = this; 19977 const forms = $(".js-checkout-payment-forms", that.checkoutLayer); 19978 19979 forms.empty(); 19980 }, 19981 19982 saveCart: async function (cart, update) { 19983 const that = this; 19984 console.log("[CHECKOUT] Saving cart"); 19985 19986 sessionStorage.setItem("checkout-cart", JSON.stringify(cart)); 19987 19988 if (update) { 19989 // If updating cart, remove older payment forms 19990 that.resetPaymentForms(); 19991 19992 // Update total value 19993 await that.getPriceBreakdown(); 19994 19995 // Check if extras wrapper has to be displayed 19996 that.checkCartExtras(); 19997 } 19998 }, 19999 20000 setLayerFromURL: function () { 20001 const that = this; 20002 const searchParams = new URLSearchParams(window.location.search); 20003 const layer = searchParams.has("checkout[layer]") ? searchParams.get("checkout[layer]") : undefined; 20004 20005 // Reset current layer 20006 sessionStorage.removeItem("checkout-layer"); 20007 20008 if (layer) { 20009 that.toggleLayer(layer); 20010 } else { 20011 that.toggleLayer(); 20012 } 20013 }, 20014 20015 setupCart: function () { 20016 const that = this; 20017 const reward = that.checkoutLayer.attr("data-checkout-reward-id"); 20018 const shippingZone = that.getShippingZone().id; 20019 const cart = { 20020 bonus: 0, 20021 reward: reward, 20022 }; 20023 20024 if (shippingZone) { 20025 cart.shipping_zone = shippingZone; 20026 } 20027 20028 // Reset Cart 20029 sessionStorage.removeItem("checkout-cart"); 20030 sessionStorage.removeItem("checkout-cart-total"); 20031 20032 // Create cart 20033 that.saveCart(cart); 20034 }, 20035 20036 toggleAddonSelector: function (addon, quantity) { 20037 const button = $(".js-checkout-addon-add", addon); 20038 const selector = $(".js-checkout-addon-handler", addon); 20039 20040 if (quantity === 0) {
20041 selector.fadeOut(Settings.speed * 2, function () { 20042 button.fadeIn(Settings.speed * 2); 20043 }); 20044 } else { 20045 button.fadeOut(Settings.speed * 2, function () { 20046 selector.fadeIn(Settings.speed * 2); 20047 }); 20048 } 20049 }, 20050 20051 toggleCart: function (hide) { 20052 const that = this; 20053 const cartOpenClass = "checkout--cart-open"; 20054 20055 if (hide) { 20056 that.checkoutLayer.removeClass(cartOpenClass); 20057 } else { 20058 that.checkoutLayer.toggleClass(cartOpenClass); 20059 } 20060 }, 20061 20062 toggleLayer: function (layer) { 20063 const that = this; 20064 const oldLayer = sessionStorage.getItem("checkout-layer"); 20065 const bar = $(".js-checkout-bar", that.checkoutLayer); 20066 20067 if (!layer) { 20068 console.log("[CHECKOUT] Toggling layer to first layer"); 20069 layer = that.getFirstLayer(); 20070 } else { 20071 console.log("[CHECKOUT] Toggling layer to requested: " + layer); 20072 } 20073 20074 if (oldLayer === layer) return; 20075 20076 if (Utils.isMobile) { 20077 that.toggleCart(true); 20078 20079 switch (layer) { 20080 case "auth": 20081 // Hide toggle layer button 20082 $(".js-checkout-toggle-layer", bar).hide(); 20083 break; 20084 20085 case "payment": 20086 // Show payment submit instead of toggle layer button 20087 $(".js-checkout-toggle-layer", bar).hide(); 20088 $(".js-checkout-payment-submit", bar).show(); 20089 break; 20090 20091 default: 20092 // Hide payment submit and show toggle layer button 20093 $(".js-checkout-payment-submit", bar).hide(); 20094 $(".js-checkout-toggle-layer", bar).show(); 20095 } 20096 } else { 20097 switch (layer) { 20098 case "customize": 20099 bar.fadeIn(); 20100 break; 20101 20102 default: 20103 bar.fadeOut(); 20104 } 20105 } 20106 if (layer == "payment") { 20107 that.resetPaymentForms(); 20108 that.checkDefaultPaymentMethod(); 20109 } 20110 20111 if (oldLayer) { 20112 $(`.js-checkout-layer[data-checkout-layer='${oldLayer}']`, that.checkoutLayer).fadeOut(Settings.speed, function () { 20113 $("html, body").scrollTop(0); 20114 $(`.js-checkout-layer[data-checkout-layer='${layer}']`, that.checkoutLayer).fadeIn(Settings.speed); 20115 }); 20116 } else { 20117 $(`.js-checkout-layer[data-checkout-layer='${layer}']`, that.checkoutLayer).fadeIn(Settings.speed); 20118 } 20119 20120 sessionStorage.setItem("checkout-layer", layer); 20121 }, 20122 20123 updateAddon: async function (addon, id, quantity) { 20124 const that = this; 20125 const cart = that.getCart(); 20126 const quantityPlaceholder = $(".js-checkout-addon-value", addon); 20127 const hasAddons = cart.addons && cart.addons.length; 20128 const addonIndex = hasAddons 20129 ? cart.addons.findIndex((addon) => { 20130 return addon.id === id; 20131 }) 20132 : -1; 20133 20134 // Show loader 20135 that.enableLoader(); 20136 20137 if (addonIndex !== -1) { 20138 cart.addons[addonIndex].quantity = quantity; 20139 } else if (hasAddons) { 20140 cart.addons.push({ 20141 id: id, 20142 quantity: quantity, 20143 }); 20144 } else { 20145 cart.addons = []; 20146 cart.addons.push({ 20147 id: id, 20148 quantity: quantity, 20149 }); 20150 } 20151 20152 await that.saveCart(cart, true); 20153 20154 // Update addons breakdown 20155 await that.getAddonsBreakdown(cart); 20156 20157 // Update input value with quantity 20158 quantityPlaceholder.val(quantity); 20159 20160 // Hide loader 20161 that.disableLoader(); 20162 }, 20163 20164 updateBonus: async function (amount) { 20165 const that = this; 20166 const placeholder = $(".js-checkout-bonus-placeholder", that.checkoutLayer); 20167 const cart = that.getCart(); 20168 20169 // Be sure that we have an integer 20170 amount = parseInt(amount || 0); 20171 20172 if (amount >= 0 && cart.bonus !== amount) { 20173 // Show loader 20174 that.enableLoader(); 20175 20176 cart.bonus = amount; 20177 20178 // Update cart 20179 await that.saveCart(cart, true); 20180 20181 // Update free pledge in cart summary 20182 placeholder.attr("data-checkout-bonus-amount", amount).html(amount); 20183 20184 // Hide loader 20185 that.disableLoader(); 20186 } 20187 }, 20188 20189 updateShippingZoneName: function (name) { 20190 const that = this; 20191 const namePlaceholders = $(".js-checkout-shipping-zone-label", that.checkoutLayer); 20192 20193 namePlaceholders.html(name); 20194 }, 20195 20196 updateTotal: function (cartBreakdown) { 20197 const that = this; 20198 20199 $(".js-checkout-cart-total", that.checkoutLayer).html(cartBreakdown.total); 20200 }, 20201 20202 updateAddonsLimitations: function (cartBreakdown) { 20203 const that = this; 20204 const limitedAddons = cartBreakdown.addons.filter(function (item) { 20205 return item.limited_units == true; 20206 }); 20207 20208 // Update the legend of limited addons 20209 limitedAddons.forEach((element) => { 20210 addon = $("#reward_" + element.reward_id); 20211 addon.attr("data-limited-units", element.limited_units); 20212 addon.attr("data-base-available-units", element.available_units + element.units); 20213 addon.attr("data-total-units", element.total_units); 20214 addon.find(".available_units").html(element.available_units); 20215 addon.find(".total_units").html(element.total_units); 20216 addon.find(".js-checkout-addon-increase").prop("disabled", element.available_units <= 0); 20217 }); 20218 }, 20219 }; 20220 20221 Checkout.init(); 20222 20223 return Checkout; 20224}); 20225/** 20226* Comment 20227* @namespace Verkami 20228* @class Comment 20229*/ 20230 20231var name = 'Verkami/Comment'; 20232 20233modulejs.define(name, function() { 20234 var Comment = { 20235 nodes: [], 20236 buttonDisabledClass: 'button--disabled', 20237 20238 init: function() { 20239 var that = this; 20240 that.nodes = $('.js-comment'); 20241 20242 if (that.nodes.length) { 20243 $('.js-comment-button', that.nodes).hide().addClass(that.buttonDisabledClass); 20244 20245 $('.js-comment-button-trigger', that.nodes).on('focus', function() { 20246 $(this).parents('.js-comment').find('.js-comment-button').slideDown(); 20247 }); 20248 20249 $('.js-comment-button-trigger', that.nodes).on('keyup', function() { 20250 if ($.trim($(this).val())) { 20251 $(this).parents('.js-comment').find('.js-comment-button').removeClass(that.buttonDisabledClass); 20252 } 20253 }); 20254 } 20255 } 20256 }; 20257 20258 Comment.init(); 20259 20260 return Comment; 20261}); 20262/** 20263* Comments 20264* @namespace Verkami 20265* @class Comments 20266*/ 20267 20268var name = 'Verkami/Comments'; 20269 20270modulejs.define(name, function() { 20271 var Comments = { 20272 node: [], 20273 list: [], 20274 20275 init: function() { 20276 var that = this; 20277 var node = []; 20278 var feedback = ''; 20279 that.node = $('.js-comments'); 20280 20281 if (that.node.length) { 20282 that.list = $('.js-comments-list', that.node); 20283 20284 // Get next comments page 20285 that.node.on('click', '.js-comments-more', function(e) { 20286 node = $(this); 20287 feedback = node.attr('data-comments-more-feedback'); 20288 20289 e.preventDefault(); 20290 20291 $('a', node).html(feedback); 20292 20293 $.get($('a', node).attr('href'), function(data) { 20294 node.remove(); 20295 that.list.append(data); 20296 }); 20297 }); 20298 } 20299 } 20300 }; 20301 20302 Comments.init(); 20303 20304 return Comments; 20305}); 20306/** 20307 * Community
20308 * @namespace Verkami 20309 * @class Community 20310 */ 20311 20312var deps = ["Verkami/Settings"]; 20313 20314modulejs.define("Verkami/Community", deps, function (Settings) { 20315 var Community = { 20316 sliderPageSize: 10, 20317 sliderSpeed: Settings.speed * 25, 20318 hideClass: "community__stats__people__item--hide", 20319 showClass: "community__stats__people__item--show", 20320 20321 init: function () { 20322 var that = this; 20323 var node = $(".js-community"); 20324 20325 if (node.length) { 20326 that.setup(node); 20327 } 20328 20329 that.triggers(); 20330 }, 20331 20332 triggers: function () { 20333 var that = this; 20334 20335 $(document).on("trigger.vk.community.setup", function (e, wrapper) { 20336 var node = $(".js-community", wrapper); 20337 20338 that.setup(node); 20339 }); 20340 }, 20341 20342 changeSlice: function (node, avatarsPaged) { 20343 var that = this; 20344 var sliderPage = parseInt(node.data("community-slider-page")) || 0; 20345 20346 setTimeout( 20347 function () { 20348 that.hideAvatars(avatarsPaged[sliderPage]); 20349 20350 sliderPage = parseInt(sliderPage + 2) > avatarsPaged.length ? 0 : parseInt(sliderPage + 1); 20351 node.data("community-slider-page", sliderPage); 20352 20353 setTimeout( 20354 function () { 20355 that.showAvatars(node, avatarsPaged, sliderPage); 20356 }.bind(this), 20357 Settings.speed * 4 20358 ); 20359 }.bind(this), 20360 that.sliderSpeed 20361 ); 20362 }, 20363 20364 hideAvatars: function (avatars) { 20365 var that = this; 20366 20367 avatars.each(function (i) { 20368 $(this).addClass(that.hideClass); 20369 20370 setTimeout( 20371 function () { 20372 $(this).removeClass(that.hideClass).hide(); 20373 }.bind(this), 20374 Settings.speed * 3 + (Settings.speed / 4) * i 20375 ); 20376 }); 20377 }, 20378 20379 setup: function (node) { 20380 var that = this; 20381 var avatars = $(".js-community-avatar"); 20382 var avatarsPaged = []; 20383 20384 // Enable slider if more than 1 page of avatars 20385 if (avatars.length > that.sliderPageSize) { 20386 node.data("community-slider-enabled", true); 20387 20388 avatars.slice(10).hide(); 20389 } 20390 20391 avatarsPaged = that.sliceAvatars(avatars); 20392 20393 that.showAvatars(node, avatarsPaged, 0); 20394 }, 20395 20396 showAvatars: function (node, avatarsPaged, sliderPage) { 20397 var that = this; 20398 20399 avatarsPaged[sliderPage].show(); 20400 20401 avatarsPaged[sliderPage].each(function (i) { 20402 $(this).addClass(that.showClass); 20403 20404 setTimeout( 20405 function () { 20406 $(this).removeClass(that.showClass); 20407 }.bind(this), 20408 Settings.speed * 3 + (Settings.speed / 4) * i 20409 ); 20410 }); 20411 20412 if (node.data("community-slider-enabled") === true) { 20413 that.changeSlice(node, avatarsPaged); 20414 } 20415 }, 20416 20417 sliceAvatars: function (avatars) { 20418 var that = this; 20419 var index = 0; 20420 var avatarsPaged = []; 20421 var avatarsPage = []; 20422 20423 for (index = 0; index < avatars.length; index += that.sliderPageSize) { 20424 avatarsPage = avatars.slice(index, index + that.sliderPageSize); 20425 avatarsPaged.push(avatarsPage); 20426 } 20427 20428 return avatarsPaged; 20429 }, 20430 }; 20431 20432 Community.init(); 20433 20434 return Community; 20435}); 20436/** 20437 * CookiesAgreement 20438 * @namespace Verkami 20439 * @class CookiesAgreement 20440 */ 20441 20442var name = "Verkami/CookiesAgreement";
20443 20444modulejs.define(name, ["Verkami/Start", "Verkami/Sticky", "Verkami/Utils"], function (Start, Sticky, Utils) { 20445 var CookiesAgreement = { 20446 cookie: "", 20447 cookieName: "cookies_consent_level", 20448 disclaimer: [], 20449 disclaimerClose: [], 20450 disclaimerVisibleClass: "cookies--visible", 20451 20452 init: function () { 20453 var that = this; 20454 20455 // @todo: Make Cookies plugin a dependency 20456 that.cookie = Cookies.get(that.cookieName); 20457 that.disclaimer = $(".js-cookies"); 20458 20459 if (that.disclaimer.length && !that.cookie) { 20460 that.showDisclaimer(); 20461 } 20462 20463 // Check if there is any sticky bar in mobile to add a offset 20464 if (Utils.isMobile) { 20465 that.addMobileStickyOffset(); 20466 20467 $(window).scroll(function () { 20468 that.addMobileStickyOffset(); 20469 }); 20470 } 20471 }, 20472 20473 addMobileStickyOffset: function () { 20474 var that = this; 20475 var mobileStickyBar = Sticky.nodesMobile.filter(function () { 20476 return parseInt($(this).attr("data-sticky")) === 1; 20477 }); 20478 var startBar = Start.bar.node.hasClass(Start.bar.visibleClass) ? Start.bar.node : []; 20479 var mobileStickyOffset = 0; 20480 var isAnyStickyBar = mobileStickyBar.length || startBar.length; 20481 var isCookiesVisible = that.disclaimer.hasClass(that.disclaimerVisibleClass); 20482 20483 if (isAnyStickyBar && isCookiesVisible) { 20484 if (mobileStickyBar.length) { 20485 mobileStickyOffset = mobileStickyBar.outerHeight(); 20486 } else if (startBar.length) { 20487 mobileStickyOffset = startBar.outerHeight(); 20488 } 20489 } else { 20490 mobileStickyOffset = 0; 20491 } 20492 20493 that.disclaimer.css("transform", "translateY(-" + mobileStickyOffset + "px)"); 20494 }, 20495 20496 hideDisclaimer: function (level) { 20497 var that = this; 20498 20499 Cookies.set(that.cookieName, level); 20500 that.cookie = Cookies.get(that.cookieName); 20501 20502 that.disclaimer.removeClass(that.disclaimerVisibleClass); 20503 20504 // Reset the CSS variable with the cookies bar height 20505 $(":root")[0].style.setProperty("--cookiesHeight", 0); 20506 }, 20507 20508 showDisclaimer: function () { 20509 var that = this; 20510 that.disclaimerClose = $(".js-cookies-close", that.disclaimer); 20511 that.essentialsClose = $(".js-cookies-essentials-close", that.disclaimer); 20512 that.allClose = $(".js-cookies-all-close", that.disclaimer); 20513 20514 that.disclaimer.addClass(that.disclaimerVisibleClass); 20515 20516 // Add a CSS variable with the cookies bar height 20517 $(":root")[0].style.setProperty("--cookiesHeight", that.disclaimer.innerHeight()); 20518 20519 that.disclaimerClose.on("click", function () { 20520 that.hideDisclaimer(2); 20521 }); 20522 that.essentialsClose.on("click", function () { 20523 that.hideDisclaimer(1); 20524 }); 20525 that.allClose.on("click", function () { 20526 that.hideDisclaimer(2); 20527 }); 20528 }, 20529 }; 20530 20531 CookiesAgreement.init(); 20532 20533 return CookiesAgreement; 20534}); 20535/** 20536* Filters 20537* @namespace Verkami 20538* @class Filters 20539*/ 20540 20541var name = 'Verkami/Filters'; 20542var deps = [ 20543 'Verkami/Utils' 20544]; 20545 20546modulejs.define(name, deps, function(Utils) { 20547 var Filters = { 20548 node: [], 20549 content: [], 20550 trigger: [], 20551 triggerOpenClass: 'browse-bar__trigger--open', 20552 20553 init: function() { 20554 var that = this; 20555 that.node = $('.js-filters'); 20556 20557 // Filters are hidden in Mobile, this is a trigger to show them 20558 if (that.node.length && Utils.isMobile) { 20559 that.content = $('.js-filters-content'); 20560 that.trigger = $('.js-filters-trigger'); 20561 20562 that.trigger.on('click', function() { 20563 that.trigger.toggleClass(that.triggerOpenClass); 20564 that.content.slideToggle(); 20565 }); 20566 } 20567 } 20568 }; 20569 20570 Filters.init(); 20571 20572 return Filters; 20573}); 20574/** 20575 * Follow 20576 * @namespace Verkami 20577 * @class Flash 20578 */ 20579 20580var name = "Verkami/Flash"; 20581var deps = ["Verkami/Settings"]; 20582 20583modulejs.define(name, deps, function(Settings) { 20584 var Flash = { 20585 nodes: [], 20586 nodeSelector: ".js-flash-box", 20587 20588 init: function() { 20589 var that = this; 20590 that.setupNewNodes(); 20591 }, 20592 20593 setupNewNodes: function() { 20594 var that = this; 20595 that.nodes = $(that.nodeSelector); 20596 20597 var newNodes = that.nodes.filter(function() { 20598 return !$(this).data("moduleFlashSetupDone"); 20599 }); 20600 20601 if (newNodes.length) { 20602 that.hideFlash(newNodes); 20603 newNodes.data("moduleFlashSetupDone", true); 20604 } 20605 }, 20606 20607 hideFlash: function(nodes) { 20608 nodes.each(function() { 20609 var flashNode = $(this); 20610 setTimeout(function() { 20611 flashNode.fadeOut(); 20612 }, Settings.speed * 6); 20613 }); 20614 } 20615 }; 20616
20617 Flash.init(); 20618 20619 return Flash; 20620}); 20621/** 20622 * Follow 20623 * @namespace Verkami 20624 * @class Follow 20625 */ 20626 20627var deps = ["Verkami/CookiesAgreement", "Verkami/Modal", "Verkami/Settings", "Verkami/Utils"]; 20628 20629modulejs.define("Verkami/Follow", deps, function (CookiesAgreement, Modal, Settings, Utils) { 20630 var Follow = { 20631 nodes: [], 20632 cookie: false, 20633 cookieName: "follow_tutorial", 20634 followActiveClass: "follow--active", 20635 followErrorClass: "follow--error", 20636 followModalId: { 20637 modalTrigger: "follow", 20638 }, 20639 followTimeoutError: null, 20640 20641 init: function () { 20642 var that = this; 20643 that.cookie = Cookies.get(that.cookieName); 20644 that.setupNewNodes(); 20645 that.goToFollow(); 20646 }, 20647 20648 setupNewNodes: function () { 20649 var that = this; 20650 that.nodes = $(".js-follow"); 20651 20652 var newNodes = that.nodes.filter(function () { 20653 return !$(this).data("moduleFollowSetupDone"); 20654 }); 20655 20656 if (newNodes.length) { 20657 that.showCounter(newNodes); 20658 that.events(newNodes); 20659 newNodes.data("moduleFollowSetupDone", true); 20660 } 20661 }, 20662 20663 showCounter: function (nodes) { 20664 var followCounter = []; 20665 var followTrigger = []; 20666 20667 nodes.each(function () { 20668 followTrigger = $(this); 20669 followCounter = $(".js-follow-counter", followTrigger); 20670 20671 if (followCounter.attr("data-follow-value") == "hidden") { 20672 followCounter.animate( 20673 { 20674 width: "hide", 20675 }, 20676 "fast" 20677 ); 20678 } 20679 }); 20680 }, 20681 20682 events: function (nodes) { 20683 var that = this; 20684 20685 nodes.on("click.Follow", function () { 20686 that.toggle($(this)); 20687 }); 20688 }, 20689 20690 toggle: function (followTrigger) { 20691 var that = this; 20692 var followCounter = $(".js-follow-counter", followTrigger); 20693 var isFollowing = followTrigger.hasClass(that.followActiveClass); 20694 var isRequesting = false; 20695 var followTargetFollow = followTrigger.attr("data-follow"); 20696 var followTargetUnfollow = followTrigger.attr("data-unfollow"); 20697 var followTarget = isFollowing ? followTargetUnfollow : followTargetFollow; 20698 20699 if (!isRequesting) { 20700 $.ajax({ 20701 type: "POST", 20702 url: followTarget, 20703 dataType: "json", 20704 beforeSend: function () { 20705 isRequesting = true; 20706 }, 20707 error: function (data) { 20708 that.updateCounter(followCounter, followTrigger, false, data); 20709 isRequesting = false; 20710 }, 20711 success: function (data) { 20712 if (data.error) { 20713 that.updateCounter(followCounter, followTrigger, false, data); 20714 } else { 20715 $(".js-follow-feedback").fadeOut(); 20716 that.updateCounter(followCounter, followTrigger, true, data); 20717 } 20718 isRequesting = false; 20719 }, 20720 }); 20721 20722 // Show the follow instructions modal just once 20723 if (!that.cookie && !isFollowing) { 20724 console.log(that.followModalId.modalTrigger); 20725 Modal.moveToBodyEnd(that.followModalId.modalTrigger); 20726 Modal.show(that.followModalId); 20727 20728 // Save cookie if agreement it's previously done to prevent showing 20729 // this tutorial modal again. 20730 if (CookiesAgreement.cookie) { 20731 Cookies.set(that.cookieName, "true"); 20732 that.cookie = Cookies.get(that.cookieName); 20733 } 20734 } 20735 } 20736 }, 20737 20738 updateCounter: function (followCounter, followTrigger, status, data) { 20739 var that = this; 20740 20741 if (status) { 20742 followCounter.text(data.formatted_likes); 20743 followTrigger.toggleClass(that.followActiveClass).blur(); 20744 that.counterToggle(followCounter, data.likes); 20745 } else { 20746 clearTimeout(that.followTimeoutError); 20747 20748 followTrigger.addClass(that.followErrorClass).blur(); 20749 20750 that.followTimeoutError = setTimeout(function () { 20751 followTrigger.removeClass(that.followErrorClass); 20752 }, Settings.speed * 10); 20753 } 20754 }, 20755 20756 counterToggle: function (followCounter, likes) { 20757 // Hide counter if nobody is following the project 20758 if (likes == 0) { 20759 followCounter.animate( 20760 { 20761 width: "hide", 20762 }, 20763 "fast" 20764 ); 20765 } else { 20766 followCounter.animate( 20767 { 20768 width: "show", 20769 }, 20770 "fast" 20771 ); 20772 } 20773 }, 20774 20775 goToFollow: function () { 20776 var hash = Utils.hash.get(); 20777 var hashTest = /^[a-zA-Z0-9-_]+$/; 20778 var node = null; 20779 20780 // If there is any anchor to the follow trigger, scroll down to it and show a tip box 20781 if (hash && hashTest.test(hash)) { 20782 node = $("#" + hash); 20783 20784 if (node.length && node.hasClass("js-follow")) { 20785 setTimeout(function () { 20786 $(".js-follow-feedback").fadeIn(); 20787 }, Settings.speed * 6); 20788 } 20789 } 20790 }, 20791 }; 20792 20793 Follow.init(); 20794 20795 return Follow; 20796}); 20797/** 20798* Footer 20799* @namespace Verkami 20800* @class Footer 20801*/ 20802 20803var name = 'Verkami/Footer'; 20804var deps = [ 20805 'Verkami/Utils' 20806]; 20807 20808modulejs.define(name, deps, function(Utils) { 20809 var Footer = { 20810 node: [],
20811 visibleClass: 'footer--visible', 20812 20813 init: function() { 20814 var that = this; 20815 that.node = $('.js-footer'); 20816 20817 if (that.node.length && !Utils.isMobile) { 20818 // @todo: Add Appear plugin as a dependency 20819 that.node.appear(); 20820 20821 that.node.on('appear', function() { 20822 that.node.addClass(that.visibleClass); 20823 }); 20824 20825 that.node.on('disappear', function() { 20826 that.node.removeClass(that.visibleClass); 20827 }); 20828 } 20829 } 20830 }; 20831 20832 Footer.init(); 20833 20834 return Footer; 20835}); 20836/** 20837* Hero 20838* @namespace Verkami 20839* @class Hero 20840*/ 20841 20842var name = 'Verkami/Hero'; 20843var deps = [ 20844 'Verkami/Settings', 20845 'Verkami/Utils' 20846]; 20847 20848modulejs.define(name, deps, function(Settings, Utils) { 20849 var Hero = { 20850 node: [], 20851 backgrounds: [], 20852 left: [], 20853 right: [], 20854 figures: [], 20855 figuresPausedClass: 'figures--paused', 20856 20857 init: function() { 20858 var that = this; 20859 that.node = $('.js-hero'); 20860 20861 if (that.node.length) { 20862 that.backgrounds = $('.js-hero-bgs', that.node); 20863 that.left = $('.js-hero-left', that.node); 20864 that.leftItems = $('.js-hero-bgs-left', that.backgrounds); 20865 that.right = $('.js-hero-right', that.node); 20866 that.rightItems = $('.js-hero-bgs-right', that.backgrounds); 20867 that.figures = $('.js-figures', that.node); 20868 var leftItemsIndex = 0; 20869 var leftItemsCount = that.leftItems.length; 20870 var rightItemsIndex = 0; 20871 var rightItemsCount = that.rightItems.length; 20872 20873 that.preloadBackgrounds(); 20874 20875 that.left.hover(function() { 20876 if (leftItemsIndex == leftItemsCount) { 20877 leftItemsIndex = 0; 20878 } 20879 that.showBg(that.leftItems.eq(leftItemsIndex), that.right); 20880 leftItemsIndex++; 20881 }, function() { 20882 that.hideBg(that.leftItems, that.right); 20883 }); 20884 20885 that.right.hover(function() { 20886 if (rightItemsIndex == rightItemsCount) { 20887 rightItemsIndex = 0; 20888 } 20889 that.showBg(that.rightItems.eq(rightItemsIndex), that.left); 20890 rightItemsIndex++; 20891 }, function() { 20892 that.hideBg(that.rightItems, that.left); 20893 }); 20894 } 20895 }, 20896 20897 hideBg: function(target, otherSide) { 20898 var that = this; 20899 20900 that.figures.removeClass(that.figuresPausedClass); 20901 20902 otherSide.css('opacity', 1); 20903 20904 // @todo: Check if it's possible to avoid the speed attribute 20905 that.backgrounds.stop(true, true).fadeOut(Settings.speed, function() { 20906 target.css('display', 'none'); 20907 }); 20908 }, 20909 20910 preloadBackgrounds: function() { 20911 var that = this; 20912 var heroItems = $.fn.add.call(that.leftItems, that.rightItems); 20913 20914 Utils.preloadImages(heroItems); 20915 }, 20916 20917 showBg: function(target, otherSide) { 20918 var that = this; 20919 20920 that.figures.addClass(that.figuresPausedClass); 20921 20922 otherSide.css('opacity', 0); 20923 20924 target.css('display', 'table'); 20925 that.backgrounds.stop(true, true).fadeIn(); 20926 } 20927 }; 20928 20929 Hero.init(); 20930 20931 return Hero; 20932}); 20933/** 20934* IEWarning 20935* @namespace Verkami 20936* @class IEWarning 20937*/ 20938 20939var name = 'Verkami/IEWarning'; 20940 20941modulejs.define(name, function() { 20942 var IEWarning = { 20943 ieWarningBar: [], 20944 20945 init: function() { 20946 var that = this; 20947 var userAgent = window.navigator.userAgent; 20948 var isIE = userAgent.indexOf('MSIE '); 20949 that.ieWarningBar = $('.js-ie-warning'); 20950 20951 if (that.ieWarningBar.length && isIE > 0) { 20952 that.ieWarningBar.show(); 20953 } 20954 } 20955 }; 20956 20957 IEWarning.init(); 20958 20959 return IEWarning; 20960}); 20961/** 20962* Navigation 20963* @namespace Verkami 20964* @class Navigation 20965*/ 20966 20967var name = 'Verkami/Navigation'; 20968var deps = [ 20969 'Verkami/Utils' 20970]; 20971 20972modulejs.define(name, deps, function(Utils) { 20973 var Navigation = { 20974 toggle: [], 20975 navigationWrapper: [], 20976 toggleActiveClass: 'header-overlay-xs-visible', 20977 20978 init: function() { 20979 var that = this; 20980 20981 that.toggle = $('.js-navigation-toggle'); 20982 20983 if (that.toggle.length && (Utils.isMobile || Utils.isTablet)) { 20984 that.navigationWrapper = $('.js-navigation-wrapper'); 20985 20986 that.setup(); 20987 20988 that.toggle.on('click', function() { 20989 $('body').toggleClass(that.toggleActiveClass); 20990 }); 20991 20992 $(window).resize(function() { 20993 that.setup(); 20994 }); 20995 } 20996 }, 20997 20998 setup: function() { 20999 var that = this;
21000 var viewportHeight = Utils.getViewportSize('height'); 21001 var navigationWrapperTopMargin = parseInt(that.navigationWrapper.css('margin-top')); 21002 21003 that.navigationWrapper.css('max-height', viewportHeight - navigationWrapperTopMargin); 21004 } 21005 }; 21006 21007 Navigation.init(); 21008 21009 return Navigation; 21010}); 21011/** 21012 * Paginator 21013 * @namespace Verkami 21014 * @class Paginator 21015 */ 21016 21017var name = "Verkami/Paginator"; 21018var deps = [ 21019 "Verkami/Cards", 21020 "Verkami/Follow", 21021 "Verkami/Form", 21022 "Verkami/Modal", 21023 "Verkami/Share", 21024 "Verkami/Utils", 21025 "Verkami/Toggle", 21026]; 21027 21028modulejs.define(name, deps, function (Cards, Follow, Form, Modal, Share, Utils, Toggle) { 21029 var Paginator = { 21030 nodes: [], 21031 autoTriggerLimit: 3, 21032 21033 init: function () { 21034 var that = this; 21035 var node = []; 21036 that.nodes = $(".js-paginator"); 21037 21038 if (that.nodes.length) { 21039 // Set default page 21040 that.nodes.each(function () { 21041 $(this).attr({ 21042 "data-paginator-loading": 0, 21043 "data-paginator-page": 1, 21044 }); 21045 }); 21046 21047 // Initialize jquery.appear in paginator nodes 21048 $(".js-paginator-trigger", that.nodes).appear(); 21049 21050 // Load next page on click trigger 21051 that.nodes.on("click", ".js-paginator-trigger", function (e) { 21052 e.preventDefault(); 21053 21054 // Load next page 21055 that.getNextPage($(this)); 21056 }); 21057 21058 // Load next page on scroll down 21059 that.nodes.on("appear", ".js-paginator-trigger", function () { 21060 // Load next page 21061 that.getNextPage($(this)); 21062 }); 21063 } 21064 }, 21065 21066 getNextPage: function (trigger) { 21067 var that = this; 21068 var node = trigger.closest(".js-paginator"); 21069 var placeholder = trigger.closest(".js-paginator-placeholder"); 21070 var endpoint = trigger.attr("href"); 21071 var newContent = []; 21072 var page = parseInt(node.attr("data-paginator-page")); 21073 var isLoading = parseInt(node.attr("data-paginator-loading")); 21074 21075 if (!isLoading) { 21076 // Set loading flag 21077 node.attr("data-paginator-loading", 1); 21078 21079 // Show loading feedback 21080 Form.submit.loadingState(trigger); 21081 21082 // Disable autotrigger after reaching autoTriggerLimit
21083 if (page === that.autoTriggerLimit) { 21084 node.off("appear", ".js-paginator-trigger"); 21085 } 21086 21087 $.get(endpoint, function (data) { 21088 newContent = $(data); 21089 21090 // Update paginator information 21091 node.attr({ 21092 "data-paginator-loading": 0, 21093 "data-paginator-page": page + 1, 21094 }); 21095 21096 // Show new content 21097 placeholder.replaceWith(newContent); 21098 21099 if (newContent.find(".js-squarize").length) { 21100 Utils.squarize(); 21101 } 21102 21103 // Manually refresh affected modules so the triggering events they install 21104 // can be applied to the new, asynchronously loaded nodes. 21105 Follow.setupNewNodes(); 21106 Share.setupNewNodes(); 21107 Cards.setupNewNodes(); 21108 Form.characterCounter.setupNewNodes(); 21109 Toggle.setupNewNodes(); 21110 Modal.refresh(); 21111 }); 21112 } 21113 }, 21114 }; 21115 21116 Paginator.init(); 21117 21118 return Paginator; 21119}); 21120/** 21121 * Panels 21122 * @namespace Verkami 21123 * @class Panels 21124 * 21125 * Panel IDs: 21126 * 1. Sign up 21127 * 2. Log in 21128 * 3. Signed up with Facebook 21129 * 4. Forgot password 21130 * 5. Forgot password confirmation 21131 * 6. Logged in 21132 */ 21133 21134var name = "Verkami/Panels"; 21135var deps = [ 21136 "Verkami/Form", 21137 "Verkami/PledgePayments", 21138 "Verkami/Settings", 21139 "Verkami/Utils" 21140]; 21141 21142modulejs.define(name, deps, function (Form, PledgePayments, Settings, Utils) { 21143 var Panels = { 21144 signup: 1, 21145 login: 2, 21146 signupFacebook: 3, 21147 forgotPassword: 4, 21148 forgotPasswordConfirmation: 5, 21149 loggedIn: 6, 21150 21151 nodes: [], 21152 panelsContentActiveClass: "modal-pledge__content__panel--active", 21153 21154 init: function () { 21155 var that = this; 21156 21157 that._hooks(); 21158 }, 21159 21160 _hooks: function () { 21161 var that = this; 21162 21163 // Initialize Panels once modal is open 21164 $(document).on("hook.vk.modal.open", ".js-modal", function (e, modalData) { 21165 var isAuthModal = modalData.modalTrigger === "auth_dialog"; 21166 var isPasswordExpiredModal = modalData.modalTrigger === "auth_reset_password_token_expired"; 21167 var isPledgeModal = modalData.modalTrigger.match("^pledges_process"); 21168 var panelModule = []; 21169 var panelId = null; 21170 21171 if (isAuthModal || isPasswordExpiredModal || isPledgeModal) { 21172 panelModule = $(this).hasClass("js-panels") ? $(this) : $(".js-panels", $(this)); 21173 panelId = modalData.panelsTrigger ? modalData.panelsTrigger : Utils.hash.pick("panel"); 21174 21175 that.setup(); 21176 21177 // If panel is defined, show it directly 21178 if (panelId) { 21179 that.toggleContents(panelModule, panelId, Settings.instantSpeed); 21180 } else { 21181 if (isPledgeModal && panelModule.data("logged-in")) { 21182 that.toggleContents(panelModule, that.loggedIn, Settings.instantSpeed); 21183 } else { 21184 that.toggleContents(panelModule, that.signup, Settings.instantSpeed); 21185 } 21186 } 21187 } 21188 }); 21189 }, 21190 21191 getContent: function (panels, panelId) { 21192 var contents = $(".js-panels-content", panels); 21193 var content = contents.filter("[data-panels-content*=\"" + panelId + "\"]"); 21194 21195 return content; 21196 }, 21197 21198 getActiveContent: function (panels) { 21199 return panels.data("panels-active"); 21200 }, 21201 21202 setActiveContent: function (panels, content) { 21203 panels.data("panels-active", content); 21204 // Using the data() method to update data does not affect attributes in the DOM. 21205 // cf. https://api.jquery.com/data/ 21206 // Keep both updated consistently to prevent bugs like 21207 // https://github.com/verkami/verkami/issues/3394#issuecomment-712721591 21208 panels.attr("data-panels-active", content); 21209 }, 21210 21211 setup: function () { 21212 var that = this; 21213 var panel = []; 21214 that.nodes = $(".js-panels"); 21215 21216 that.nodes.each(function () { 21217 panel = $(this); 21218 21219 that.setActiveContent(panel, that.signup); 21220 21221 // Toggle panel content 21222 panel.off("click.vk.panel.toggle").on("click.vk.panel.toggle", ".js-panels-trigger", function (e) { 21223 var panels = $(this).closest(".js-panels"); 21224 var panelId = $(this).data("panels-trigger"); 21225 21226 e.preventDefault(); 21227 21228 that.toggleContents(panels, panelId); 21229 }); 21230 }); 21231 }, 21232 21233 showSubmitButton: function (modal, panelId) { 21234 var that = this; 21235 if (panelId == that.login) { 21236 $(".js-pledge-submit", modal).hide(); 21237 $(".js-pledge-login-submit", modal).show(); 21238 } else { 21239 $(".js-pledge-submit", modal).show(); 21240 $(".js-pledge-login-submit", modal).hide(); 21241 } 21242 }, 21243 21244 toggleContents: function (panels, panelId, speed) { 21245 speed = speed === undefined ? Settings.speed : speed; 21246 panelId = parseInt(panelId); 21247 var that = this; 21248 var contents = $(".js-panels-content", panels); 21249 var content = that.getContent(panels, panelId);
21250 var pledgeSubmit = panels.closest(".js-pledge").find(".js-pledge-submit"); 21251 var pledgePayments = panels.closest(".js-pledge").find(".js-pledge-payments"); 21252 21253 that.setActiveContent(panels, panelId); 21254 21255 switch (panelId) { 21256 case that.signup: 21257 var signupInputs = $(".js-signup", contents).find(":input"); 21258 21259 Form.error("hide", signupInputs); 21260 PledgePayments.reset(pledgePayments); 21261 PledgePayments.enable(pledgePayments); 21262 break; 21263 21264 case that.login: 21265 var loginInputs = $(".js-login", contents).find(":input"); 21266 21267 Form.error("hide", loginInputs); 21268 $(".js-login", contents).trigger("trigger.vk.user.login.init"); 21269 PledgePayments.reset(pledgePayments); 21270 PledgePayments.enable(pledgePayments, { 21271 "hidePayments": Settings.beta.tokenizationAvailable() 21272 }); 21273 break; 21274 21275 case that.forgotPassword: 21276 case that.forgotPasswordConfirmation: 21277 PledgePayments.disable(pledgePayments, true); 21278 pledgeSubmit.trigger("trigger.vk.pledge.hideSubmit"); 21279 break; 21280 21281 default: 21282 PledgePayments.enable(pledgePayments); 21283 break; 21284 } 21285 21286 if (Settings.beta.tokenizationAvailable()) { 21287 that.showSubmitButton(panels, panelId); 21288 } 21289 21290 contents.fadeOut(speed).delay(speed).filter(content).fadeIn(speed); 21291 } 21292 }; 21293 21294 Panels.init(); 21295 21296 return Panels; 21297}); 21298/** 21299* PartnerFollow 21300* @namespace Verkami 21301* @class PartnerFollow 21302*/ 21303 21304var name = 'Verkami/PartnerFollow'; 21305 21306modulejs.define(name, function() { 21307 var PartnerFollow = { 21308 node: [], 21309 activeClass: 'partner-profile__follow--active', 21310 21311 init: function() { 21312 var that = this; 21313 that.node = $('.js-partner-follow'); 21314 21315 if (that.node.length) { 21316 that.node.on('click', function() { 21317 that.node.toggleClass(that.activeClass).blur(); 21318 }); 21319 } 21320 } 21321 }; 21322 21323 PartnerFollow.init(); 21324 21325 return PartnerFollow; 21326}); 21327/** 21328* Password 21329* @namespace Verkami 21330* @class Password 21331*/ 21332 21333var name = 'Verkami/Password'; 21334 21335modulejs.define(name, function() { 21336 var Password = { 21337 nodes: [], 21338 visibleClass: 'form-password--visible', 21339 21340 init: function() { 21341 var that = this; 21342 that.nodes = $('.js-password'); 21343 21344 // Initialize change password Form toggle controller 21345 that.changeForm.init(); 21346 21347 if (that.nodes.length) { 21348 that.nodes.off('click.passwordToggle').on('click.passwordToggle', '.js-password-toggle', function() { 21349 var container = $(this).closest('.js-password'); 21350 21351 $('.js-password-input', container).togglePassword(); 21352 container.toggleClass(that.visibleClass); 21353 }); 21354 21355 var doubleCheck = that.nodes.filter(function() { 21356 return $(this).hasClass('js-password-double-check'); 21357 }); 21358 21359 if (doubleCheck.length) { 21360 var doubleCheckMain = []; 21361 var doubleCheckTwin = []; 21362 21363 doubleCheck.each(function() { 21364 doubleCheckMain = $('.js-password-input', this); 21365 doubleCheckTwin = $(this).siblings('.js-password').find('.js-password-input'); 21366 21367 doubleCheckMain.add(doubleCheckTwin).off('keyup.passwordCheck').on('keyup.passwordCheck', function() { 21368 if (doubleCheckMain.val() === doubleCheckTwin.val()) { 21369 doubleCheckTwin.closest('form').find('input[type="submit"]').removeClass('button--disabled'); 21370 doubleCheckTwin.removeClass('form-item__error'); 21371 } else { 21372 doubleCheckTwin.closest('form').find('input[type="submit"]').addClass('button--disabled'); 21373 doubleCheckTwin.addClass('form-item__error'); 21374 } 21375 }); 21376 }); 21377 } 21378 } 21379 }, 21380 21381 changeForm: { 21382 form: [], 21383 trigger: [], 21384 21385 init: function() { 21386 var that = this; 21387 that.form = $('.js-password-change-form'); 21388 21389 if (that.form.length) { 21390 that.trigger = $('.js-password-change-trigger'); 21391 21392 if (that.form.attr('data-password-change-show') === 'true') { 21393 that.trigger.hide(); 21394 that.form.show(); 21395 } 21396 21397 that.trigger.on('click', function() { 21398 that.trigger.fadeOut(); 21399 that.form.slideToggle(); 21400 }); 21401 } 21402 } 21403 } 21404 }; 21405 21406 Password.init(); 21407 21408 return Password; 21409}); 21410/** 21411 * Player 21412 * @namespace Verkami 21413 * @class Player 21414 * 21415 * Feature: External placeholder 21416 * ----------------------------- 21417 * There is way to put the placeholder outside the main node 21418 * by adding `data-player-name` to both node and placeholder to match them. 21419 * This works only on desktop, mobile and tablet get the placeholder and 21420 * append it to the main node. 21421 * 21422 * API Events: 21423 * ------ 21424 * Video ends: [.js-player] hook.vk.player.end 21425 * Video starts: [.js-player] hook.vk.player.start 21426 */ 21427 21428/* global Vimeo, YT */ 21429 21430var deps = ["Verkami/Settings", "Verkami/Utils", "Verkami/Video"]; 21431 21432modulejs.define("Verkami/Player", deps, function (Settings, Utils, Video) { 21433 var Player = { 21434 nodes: [], 21435 vimeoAPI: "https://player.vimeo.com/api/player.js", 21436 vimeoPlayers: [], 21437 youtubeAPI: "https://www.youtube.com/iframe_api", 21438 youtubePlayers: [], 21439 loadingClass: "player--loading", 21440 playingClass: "player--playing", 21441 events: { 21442 esc: "keyup.vk.player.esc", 21443 outside: "click.vk.player.outside", 21444 trigger: "click.vk.player.trigger", 21445 }, 21446 hooks: { 21447 end: "hook.vk.player.end", 21448 start: "hook.vk.player.start", 21449 }, 21450 21451 init: function () { 21452 var that = this; 21453 that.nodes = $(".js-player"); 21454 21455 if (that.nodes.length) { 21456 // Clean Vimeo players 21457 if (that.vimeoPlayers.length) { 21458 that.vimeoPlayers = []; 21459 } 21460 21461 // Clean Youtube players 21462 if (that.youtubePlayers.length) { 21463 that.youtubePlayers = []; 21464 } 21465 21466 // Run players 21467 that.initialize(that.nodes); 21468 } 21469 }, 21470 21471 addExitEvents: function(node) { 21472 var that = this; 21473 var exitOutside = node.attr("data-player-exit-outside") === "enabled"; 21474 21475 if (!Utils.isMobile) { 21476 // Clicking outside the player closes it 21477 if (exitOutside) { 21478 $(document).on(that.events.outside, function(e) { 21479 var $target = $(e.target); 21480 var isOutside = !$target.closest(node).length; 21481 var isFollow = $target.closest(".follow").length || $target.hasClass("follow"); 21482 21483 if (isOutside && !isFollow) { 21484 that.showCover(node); 21485 } 21486 }); 21487 } 21488 21489 // Escape key closes the player 21490 $(document).on(that.events.esc, function(e) { 21491 if (e.keyCode == 27) { 21492 that.showCover(node); 21493 } 21494 }); 21495 } 21496 }, 21497 21498 enhanceThumbnail: function (node) { 21499 var cover = $(".js-player-cover", node); 21500 var coverPath = ""; 21501 var enhance = cover.attr("data-player-enhance-thumbnail") === "true"; 21502 var enhanceUrl = ""; 21503 21504 if (enhance) { 21505 enhanceUrl = cover.attr("data-player-enhance-thumbnail-url"); 21506 21507 $.get(enhanceUrl, function (response) { 21508 // If no image is retrieved, don't change anything 21509 if (Object.prototype.hasOwnProperty.call(response, "image")) {
21510 coverPath = "url(" + response.image + ")"; 21511 21512 cover.css("background-image", coverPath); 21513 21514 // Turn off enhancement to avoid new requests 21515 cover.attr("data-player-enhance-thumbnail", "false"); 21516 } 21517 }); 21518 } 21519 }, 21520 21521 getPlaceholder: function (node) { 21522 var name = node.data("player-name"); 21523 var placeholder = []; 21524 21525 if (name) { 21526 placeholder = $(".js-player-placeholder[data-player-name=" + name + "]").length 21527 ? $(".js-player-placeholder[data-player-name=" + name + "]") 21528 : $(".js-player-placeholder", node); 21529 21530 if (!Utils.isDesktop) { 21531 placeholder.appendTo(node); 21532 } 21533 } else { 21534 placeholder = $(".js-player-placeholder", node); 21535 } 21536 21537 return placeholder; 21538 }, 21539 21540 hideCover: function (node) { 21541 var that = this; 21542 var cover = $(".js-player-cover", node); 21543 var trigger = $(".js-player-trigger", node); 21544 var placeholder = that.getPlaceholder(node); 21545 21546 node.trigger(that.hooks.start); 21547 21548 that.addExitEvents(node); 21549 21550 cover.fadeOut("slower"); 21551 trigger.fadeOut("slower"); 21552 $("body").addClass(that.playingClass); 21553 21554 setTimeout(function () { 21555 placeholder.stop().animate( 21556 { 21557 opacity: 1, 21558 }, 21559 Settings.speed * 4, 21560 "easeInOutCubic" 21561 ); 21562 21563 node.removeClass(that.loadingClass); 21564 }, Settings.speed * 4); 21565 }, 21566 21567 initialize: function (nodes) { 21568 var that = this; 21569 var node = []; 21570 var placeholder = []; 21571 nodes = nodes.filter(function () { 21572 return !$(this).attr("data-player-initialized"); 21573 }); 21574 21575 if (nodes.length) { 21576 nodes.each(function (i) { 21577 node = $(this); 21578 placeholder = that.getPlaceholder(node); 21579 21580 node.data("data-player-index", i); 21581 21582 that.enhanceThumbnail(node); 21583 21584 node 21585 .off(that.events.trigger, ".js-player-trigger") 21586 .on(that.events.trigger, ".js-player-trigger", function () { 21587 that.setup($(this).closest(".js-player"), i); 21588 }); 21589 21590 node.attr("data-player-initialized", "true"); 21591 21592 placeholder.css("opacity", 0); 21593 }); 21594 } 21595 }, 21596 21597 loadYoutube: function (node, callback) { 21598 var that = this; 21599 21600 // Get YouTube API 21601 $.getScript(that.youtubeAPI); 21602 21603 // Use API just once it's ready 21604 window.onYouTubeIframeAPIReady = function () { 21605 callback.resolve(node); 21606 }; 21607 }, 21608 21609 loadVimeo: function (node, callback) { 21610 var that = this; 21611 21612 // Get Vimeo API 21613 $.getScript(that.vimeoAPI, function () { 21614 callback.resolve(node); 21615 }); 21616 }, 21617 21618 removeExitEvents: function () { 21619 var that = this; 21620 21621 if (!Utils.isMobile) { 21622 // See addExitEvents() for further information 21623 $(document).off(that.events.outside); 21624 21625 // See addExitEvents() for further information 21626 $(document).off(that.events.esc); 21627 } 21628 }, 21629 21630 renderYoutube: function (node, i) { 21631 var that = this; 21632 var id = node.attr("data-player-id"); 21633 var iframe = $("<div/>"); 21634 var placeholder = that.getPlaceholder(node); 21635 21636 node.addClass(that.loadingClass); 21637 21638 iframe.prop("id", "video_" + id).appendTo(placeholder); 21639 21640 that.youtubePlayers[i] = new window.YT.Player("video_" + id, { 21641 videoId: id, 21642 playerVars: { 21643 autoplay: !Utils.isMobile && !Utils.isTablet ? 1 : 0, 21644 iv_load_policy: 3, 21645 modestbranding: 1, 21646 rel: 0, 21647 showinfo: 0, 21648 }, 21649 events: { 21650 onReady: function () { 21651 Video.setSize($("iframe", placeholder)); 21652 21653 that.hideCover(node); 21654 }, 21655 onStateChange: function (e) { 21656 if (e.data == YT.PlayerState.PLAYING) { 21657 that.hideCover(node); 21658 } else if (e.data == YT.PlayerState.ENDED) { 21659 that.showCover(node); 21660 } 21661 }, 21662 }, 21663 }); 21664 21665 $(window).on("resize.player", function () { 21666 Video.setSize($("iframe", placeholder)); 21667 }); 21668 }, 21669 21670 renderVimeo: function (node, i) { 21671 var that = this; 21672 var id = node.attr("data-player-id"); 21673 var placeholder = that.getPlaceholder(node); 21674 21675 node.addClass(that.loadingClass); 21676 21677 that.vimeoPlayers[i] = new Vimeo.Player(placeholder, { 21678 id: id, 21679 autoplay: !Utils.isMobile && !Utils.isTablet, 21680 muted: true, 21681 outro: false, 21682 }); 21683 21684 that.vimeoPlayers[i].ready().then(function () { 21685 that.vimeoPlayers[i].on("loaded", function () { 21686 Video.setSize($("iframe", placeholder)); 21687 21688 // Play video 21689 // Note: autoplay is not working in last Chrome version 66.0.3359.139 21690 that.vimeoPlayers[i].play(); 21691 21692 if (Utils.isMobile || Utils.isTablet) {
21693 that.hideCover($(this.element).closest(".js-player")); 21694 } 21695 21696 $(window).resize(function () { 21697 Video.setSize($("iframe", placeholder)); 21698 }); 21699 }); 21700 21701 that.vimeoPlayers[i].on("play", function () { 21702 that.hideCover($(this.element).closest(".js-player")); 21703 }); 21704 21705 that.vimeoPlayers[i].on("ended", function () { 21706 that.showCover(node); 21707 }); 21708 }); 21709 }, 21710 21711 showCover: function (node) { 21712 var that = this; 21713 var cover = $(".js-player-cover", node); 21714 var trigger = $(".js-player-trigger", node); 21715 var type = node.attr("data-player-type").toLowerCase(); 21716 var index = parseInt(node.data("data-player-index")); 21717 var placeholder = that.getPlaceholder(node); 21718 21719 node.trigger(that.hooks.end); 21720 21721 that.removeExitEvents(); 21722 21723 switch (type) { 21724 case "vimeo": 21725 // Check if Vimeo API is loaded 21726 if (window.Vimeo) { 21727 that.vimeoPlayers[index].pause(); 21728 } 21729 break; 21730 21731 case "youtube": 21732 // Check if YouTube API is loaded 21733 if (window.YT) { 21734 that.youtubePlayers[index].pauseVideo(); 21735 } 21736 break; 21737 } 21738 21739 placeholder.stop().animate( 21740 { 21741 opacity: 0, 21742 }, 21743 Settings.speed * 4, 21744 "easeInOutCubic" 21745 ); 21746 cover.fadeIn("slower"); 21747 trigger.fadeIn("slower"); 21748 $("body").removeClass(that.playingClass); 21749 }, 21750 21751 setup: function (node, i) { 21752 var that = this; 21753 var callback = null; 21754 var type = node.attr("data-player-type").toLowerCase(); 21755 var placeholder = that.getPlaceholder(node); 21756 21757 switch (type) { 21758 case "vimeo": 21759 // Check if Vimeo API is loaded 21760 if (window.Vimeo) { 21761 // Check if video is already loaded 21762 if (placeholder.is(":empty")) { 21763 that.renderVimeo(node, i); 21764 } else { 21765 that.vimeoPlayers[i].play(); 21766 that.hideCover(node); 21767 } 21768 } else { 21769 callback = $.Deferred(); 21770 21771 // Load Vimeo API 21772 that.loadVimeo(node, callback); 21773 21774 callback.done(function (node) { 21775 that.renderVimeo(node, i); 21776 }); 21777 } 21778 21779 break; 21780 21781 case "youtube": 21782 // Check if YouTube API is loaded 21783 if (window.YT) { 21784 // Check if video is already loaded 21785 if (placeholder.is(":empty")) { 21786 that.renderYoutube(node, i); 21787 } else { 21788 that.youtubePlayers[i].playVideo(); 21789 } 21790 } else { 21791 callback = $.Deferred(); 21792 21793 // Load Youtube API 21794 that.loadYoutube(node, callback); 21795 21796 callback.done(function (node) { 21797 that.renderYoutube(node, i); 21798 }); 21799 } 21800 21801 break; 21802 } 21803 }, 21804 }; 21805 21806 Player.init(); 21807 21808 return Player; 21809}); 21810/** 21811 * Pledge 21812 * @namespace Verkami 21813 * @class Pledge 21814 */ 21815 21816var name = "Verkami/Pledge"; 21817var deps = [ 21818 "Verkami/Form", 21819 "Verkami/Modal", 21820 "Verkami/Panels", 21821 "Verkami/PledgePayments", 21822 "Verkami/Scroll", 21823 "Verkami/User", 21824 "Verkami/Settings", 21825 "Verkami/Utils", 21826]; 21827 21828modulejs.define(name, deps, function (Form, Modal, Panels, PledgePayments, Scroll, User, Settings, Utils) { 21829 var Pledge = { 21830 pledgeButtonDisabledClass: "button--disabled", 21831 21832 init: function () { 21833 var that = this; 21834 21835 that._callbacks(); 21836 that._hooks(); 21837 }, 21838 21839 _callbacks: function () { 21840 var that = this; 21841 21842 $(document).on("trigger.vk.pledge.disableSubmit", ".js-pledge-submit", function () { 21843 that.disableSubmit($(this)); 21844 }); 21845 21846 $(document).on("trigger.vk.pledge.hideSubmit", ".js-pledge-submit", function () { 21847 that.disableSubmit($(this), true); 21848 }); 21849 21850 $(document).on("trigger.vk.pledge.enableSubmit", ".js-pledge-submit", function () { 21851 that.enableSubmit($(this)); 21852 }); 21853 }, 21854 21855 _hooks: function () { 21856 var that = this; 21857 21858 $(document).on("hook.vk.modal.open", ".js-modal", function (e, modalData) { 21859 var isPledgeModal = modalData.modalTrigger.match("^pledges_process"); 21860 21861 if (isPledgeModal) { 21862 var pledgeNode = $(this).hasClass("js-pledge") ? $(this) : $(".js-pledge", $(this)); 21863 21864 that.setup(pledgeNode); 21865 } 21866 }); 21867 }, 21868 21869 events: function (pledge) { 21870 var that = this; 21871 21872 pledge.payments.on("change", ".js-pledge-payments-trigger", function () { 21873 PledgePayments.paymentMethodSelected($(this)); 21874 }); 21875 21876 pledge.node 21877 .off("click.vk.pledge.asideToggle") 21878 .on("click.vk.pledge.asideToggle", ".js-pledge-aside-toggle", function (e) { 21879 e.preventDefault(); 21880
21881 $(".js-pledge-aside-content", $(this).closest(".js-pledge-aside")).slideToggle("fast"); 21882 21883 $(this).toggleClass("modal-pledge__aside__toggle--active"); 21884 }); 21885 21886 pledge.loginSubmit.off("click.vk.pledge.login.submit").on("click.vk.pledge.login.submit", function () { 21887 var authForm = $(this).closest(".js-modal").find(".js-login"); 21888 that.submit("login", authForm, null, { 21889 submit: $(this), 21890 }); 21891 }); 21892 21893 var captchaEnabledInSubmit = pledge.submit.hasClass("js-recaptcha"); 21894 var eventToListen = "click.vk.pledge.submit"; 21895 if (captchaEnabledInSubmit) { 21896 console.log("[CAPTCHA] Pledge submit with captcha requirements detected."); 21897 console.log("[CAPTCHA] Listening to captcha events."); 21898 eventToListen = "captcha.vk.validated"; 21899 } 21900 21901 pledge.submit.off(eventToListen).on(eventToListen, function () { 21902 console.log("Processing pledge submit triggered by " + eventToListen); 21903 21904 var pledgeNode = $(this).closest(".js-pledge"); 21905 var pledge = { 21906 panels: $(".js-panels", pledgeNode), 21907 content: $(".js-pledge-content", pledgeNode), 21908 node: pledgeNode, 21909 payments: $(".js-pledge-payments", pledgeNode), 21910 paymentsTip: $(".js-pledge-payments-tip", pledgeNode), 21911 submit: $(this), 21912 }; 21913 var activeContent = Panels.getActiveContent(pledge.panels); 21914 var paymentForm = []; 21915 var paymentTrigger = $(".js-pledge-payments-trigger", pledge.payments).filter(":checked"); 21916 var paymentType = paymentTrigger.attr("data-pledge-payment"); 21917 var currentModal = pledge.submit.closest(".js-modal"); 21918 var authForm = []; 21919 21920 // Save redirect in the auth form if triggering submit has a custom one. 21921 // This is later used by the User module. 21922 $(".js-login, .js-signup, .js-auth-facebook, .js-auth-google", currentModal).attr( 21923 "data-auth-redirect", 21924 pledge.submit.data("authRedirect") 21925 ); 21926 21927 if (activeContent == Panels.signup) { 21928 if (paymentTrigger.length) { 21929 authForm = currentModal.find(".js-signup"); 21930 that.submit("signup", authForm, paymentType, pledge); 21931 } 21932 } else if (activeContent == Panels.login) { 21933 if (paymentTrigger.length) { 21934 authForm = currentModal.find(".js-login"); 21935 that.submit("login", authForm, paymentType, pledge); 21936 } 21937 } else if (activeContent == Panels.loggedIn) { 21938 var selector = that.paymentTypeSelector(pledge, paymentType); 21939 paymentForm = $(selector, pledge.payments); 21940 // Disable the submit element to prevent double-clicks/submissions 21941 Form.submit.loadingState(pledge.submit); 21942 paymentForm.submit(); 21943 } 21944 }); 21945 }, 21946 21947 paymentTypeSelector: function (pledge, selectedPaymentType) { 21948 if (selectedPaymentType == "redsys" || selectedPaymentType == "redsys_direct") { 21949 var requestTokenCheck = $(".js-redsys-token-request-check", pledge.payments); 21950 if (requestTokenCheck.is(":checked")) { 21951 selectedPaymentType += "-token-request"; 21952 } 21953 } 21954 return ".js-pledge-payments-" + selectedPaymentType; 21955 }, 21956 21957 disableSubmit: function (pledgeSubmit, hide) { 21958 var that = this; 21959 21960 if (hide) { 21961 pledgeSubmit.fadeOut(); 21962 } else { 21963 pledgeSubmit.addClass(that.pledgeButtonDisabledClass); 21964 21965 if (!pledgeSubmit.is(":visible")) { 21966 pledgeSubmit.fadeIn(); 21967 } 21968 } 21969 }, 21970 21971 enableSubmit: function (pledgeSubmit) { 21972 var that = this; 21973 21974 if (!pledgeSubmit.is(":visible")) { 21975 pledgeSubmit.fadeIn(); 21976 } 21977 21978 pledgeSubmit.removeClass(that.pledgeButtonDisabledClass); 21979 }, 21980 21981 setAuth: function (pledge) { 21982 var panelModule = $(".js-panels", pledge.node); 21983 if (panelModule.data("logged-in")) { 21984 Panels.toggleContents(panelModule, Panels.loggedIn); 21985 } 21986 }, 21987 21988 setup: function (pledgeNode) { 21989 var that = this; 21990 var pledge = { 21991 content: $(".js-pledge-content", pledgeNode), 21992 node: pledgeNode, 21993 payments: $(".js-pledge-payments", pledgeNode), 21994 paymentsTip: $(".js-pledge-payments-tip", pledgeNode), 21995 submit: $(".js-pledge-submit", pledgeNode), 21996 loginSubmit: $(".js-pledge-login-submit", pledgeNode), 21997 };
21998 var viewportHeight = Utils.getViewportSize("height"); 21999 var modalHeight = $(".modal__box", pledge.node).outerHeight(); 22000 var modalOffset = 30; 22001 var modalMaxHeight = viewportHeight - modalOffset * 2; 22002 22003 // Toggle loggedin panel if user is already logged in that.setAuth(pledge); 22004 22005 if (modalHeight > modalMaxHeight) { 22006 var rewardDescription = $(".js-pledge-reward-description", pledge.node); 22007 var rewardDescriptionOffset = rewardDescription.position().top; 22008 22009 pledge.content.outerHeight(modalMaxHeight); 22010 rewardDescription.css("maxHeight", modalMaxHeight - rewardDescriptionOffset - 120); 22011 } 22012 22013 // Add events 22014 that.events(pledge); 22015 }, 22016 22017 submit: function (type, authForm, paymentType, pledge) { 22018 var that = this; 22019 var successCallback, errorCallback, authType; 22020 22021 Form.submit.loadingState(pledge.submit); 22022 22023 if (type == "signup") { 22024 successCallback = User.signedUpEvent; 22025 errorCallback = User.signedUpErrorEvent; 22026 authType = User.signup; 22027 } else if (type == "login") { 22028 successCallback = User.loggedInEvent; 22029 errorCallback = User.loginErrorEvent; 22030 authType = User.login; 22031 } 22032 22033 authForm.one(successCallback, function () { 22034 if (Settings.beta.tokenizationAvailable() && successCallback == User.loggedInEvent) { 22035 var currentModal = pledge.submit.closest(".js-modal"); 22036 var loading = currentModal.find(".js-modal-loading"); 22037 var panelContents = currentModal.find(".js-panels"); 22038 Modal.loading.hide(loading); 22039 Form.submit.defaultState(pledge.submit); 22040 Panels.showSubmitButton(currentModal, Panels.pledgeSubmit); 22041 Panels.toggleContents(panelContents, Panels.loggedIn); 22042 } else { 22043 pledge.payments.one("paymentFormLoaded", function () { 22044 var selector = that.paymentTypeSelector(pledge, paymentType); 22045 var paymentForm = $(selector, pledge.payments); 22046 paymentForm.submit(); 22047 }); 22048 PledgePayments.getForm(pledge.node, false); 22049 } 22050 }); 22051 22052 authForm.one(errorCallback, function () { 22053 authForm.off(successCallback); 22054 Form.submit.errorState(pledge.submit); 22055 Scroll.smooth.doScroll("reset", 0, pledge.content); 22056 }); 22057 22058 authType.submit(authForm, false); 22059 }, 22060 }; 22061 22062 Pledge.init(); 22063 22064 return Pledge; 22065}); 22066/** 22067* PledgeHigh 22068* @namespace Verkami 22069* @class PledgeHigh 22070*/ 22071 22072var name = 'Verkami/PledgeHigh'; 22073var deps = [ 22074 'Verkami/Form', 22075 'Verkami/Modal', 22076 'Verkami/Settings' 22077]; 22078 22079modulejs.define(name, deps, function(Form, Modal, Settings) { 22080 var PledgeHigh = { 22081 nodes: [], 22082 22083 init: function() { 22084 var that = this; 22085 var modalId = ''; 22086 var node = []; 22087 var trigger = []; 22088 that.nodes = $('.js-pledge-high'); 22089 22090 if (that.nodes.length) { 22091 that.nodes.each(function() { 22092 node = $(this); 22093 22094 node.on('submit', function(e) { 22095 node = $(this); 22096 modalId = node.closest('.js-modal').attr('data-modal-id'); 22097 trigger = $('.js-pledge-high-trigger', node); 22098 22099 // Prevent form native submitting 22100 e.preventDefault(); 22101 22102 // Change submit button to loading state 22103 Form.submit.loadingState(trigger); 22104 22105 // Send request 22106 $.post(node.attr('action'), node.serialize()) 22107 .done(function() { 22108 // Change submit button to success state 22109 Form.submit.successState(trigger); 22110 22111 // Close modal after a little bit 22112 setTimeout(function() { 22113 Modal.hide(modalId); 22114 }, Settings.speed * 10); 22115 }) 22116 .fail(function() { 22117 // Change submit button to error state 22118 Form.submit.errorState(trigger); 22119 }); 22120 }); 22121 }); 22122 } 22123 } 22124 }; 22125 22126 PledgeHigh.init(); 22127 22128 return PledgeHigh; 22129}); 22130/** 22131 * PledgePayments 22132 * @namespace Verkami 22133 * @class PledgePayments 22134 */ 22135 22136var name = "Verkami/PledgePayments"; 22137var deps = ["Verkami/Form", "Verkami/Modal", "Verkami/Settings", "Verkami/Utils"]; 22138
22139modulejs.define(name, deps, function (Form, Modal, Settings, Utils) { 22140 var PledgePayments = { 22141 disabledClass: "modal-pledge__payment--disabled", 22142 22143 init: function () { 22144 var that = this; 22145 // Initialize Retry Payment controller 22146 that.retryPaypal.init(); 22147 that.retryRedsys.init(); 22148 }, 22149 22150 disable: function (node, hide) { 22151 var that = this; 22152 if (hide) { 22153 node.fadeOut(); 22154 } else { 22155 node.addClass(that.disabledClass); 22156 22157 if (!node.is(":visible")) { 22158 node.fadeIn(); 22159 } 22160 } 22161 }, 22162 22163 reset: function (node) { 22164 var that = this; 22165 22166 Form.reset(node); 22167 $(".js-pledge-payments-forms", node).empty(); 22168 $(".js-tokenized-cards", node) 22169 .empty() 22170 // Make the placeholder take no space when it holds no cards 22171 .removeClass("form-item"); 22172 22173 // Hide pledge payment information 22174 if (!Utils.isMobile) { 22175 that.tip.hide($(".js-pledge-payments-tip", node)); 22176 } 22177 22178 // Disable pledge button 22179 $(".js-pledge-submit", node.closest(".js-pledge")).trigger("trigger.vk.pledge.disableSubmit"); 22180 }, 22181 22182 enable: function (node, options) { 22183 options = options || {}; 22184 var that = this; 22185 if (options.hidePayments) { 22186 node.fadeOut(Settings.speed); 22187 } else { 22188 if (!node.is(":visible")) { 22189 node.delay(Settings.speed).fadeIn(Settings.speed); 22190 } 22191 node.removeClass(that.disabledClass); 22192 //that.checkDefaultPaymentMethod(node); 22193 } 22194 }, 22195 22196 checkDefaultPaymentMethod: function (pledgeNode) { 22197 var that = this; 22198 var selectedMethod = $(".js-pledge-payments-trigger", pledgeNode).first(); 22199 selectedMethod.prop("checked", true); 22200 that.paymentMethodSelected(selectedMethod); 22201 }, 22202 22203 paymentMethodSelected: function (paymentMethod) { 22204 var that = this; 22205 var pledge = paymentMethod.closest(".js-pledge"); 22206 var pledgeSubmit = $(".js-pledge-submit", pledge); 22207 var isLoggedIn = $(".js-panels", pledge).data("logged-in"); 22208 22209 if (isLoggedIn) { 22210 PledgePayments.getForm(pledge, true); 22211 } else { 22212 // Else, enable pledge button, payment form will be requested when user triggers the submit 22213 pledgeSubmit.trigger("trigger.vk.pledge.enableSubmit"); 22214 } 22215 that.showTokenizationCheck(pledge, paymentMethod); 22216 that.showBizumDisclaimer(pledge, paymentMethod); 22217 }, 22218 22219 showTokenizationCheck: function (pledge, paymentMethod) { 22220 var paymentType = paymentMethod.attr("data-pledge-payment"); 22221 var box = pledge.find(".js-redsys-token-request-box"); 22222 if (paymentType == "redsys" || paymentType == "redsys_direct") { 22223 box.slideDown(); 22224 } else { 22225 box.slideUp(); 22226 } 22227 }, 22228 22229 showBizumDisclaimer: function (pledge, paymentMethod) { 22230 var paymentType = paymentMethod.attr("data-pledge-payment"); 22231 var box = pledge.find(".js-bizum-disclaimer"); 22232 if (paymentType == "bizum" || paymentType == "bizum_direct") { 22233 box.slideDown(); 22234 } else { 22235 box.slideUp(); 22236 } 22237 }, 22238 22239 getForm: function (pledgeNode, waitForUser) { 22240 var that = this; 22241 var loading = []; 22242 var pledge = { 22243 content: $(".js-pledge-content", pledgeNode), 22244 node: pledgeNode, 22245 payments: $(".js-pledge-payments", pledgeNode), 22246 paymentsTip: $(".js-pledge-payments-tip", pledgeNode), 22247 submit: $(".js-pledge-submit", pledgeNode), 22248 }; 22249 var paymentTriggers = $(".js-pledge-payments-trigger", pledge.payments); 22250 var paymentTrigger = paymentTriggers.filter(":checked"); 22251 var paymentEndpoint = paymentTrigger.attr("data-pledge-payment-endpoint"); 22252 var paymentType = paymentTrigger.attr("data-pledge-payment"); 22253 var paymentForm = $(".js-pledge-payments-" + paymentType, pledge.payments); 22254 22255 // Request payment form if it doesn't exist yet 22256 if (!paymentForm.length) { 22257 loading = pledge.payments.closest(".js-modal").find(".js-modal-loading"); 22258 // Disable selector 22259 paymentTriggers.prop("disabled", true); 22260 // Hide pledge payment information 22261 if (!Utils.isMobile) { 22262 that.tip.hide(pledge.paymentsTip); 22263 } 22264 // Show loading spinner 22265 Modal.loading.show(loading); 22266 22267 $.ajax({ 22268 type: "GET", 22269 url: paymentEndpoint, 22270 dataType: "html", 22271 success: function (response) { 22272 // Insert new payment form 22273 $(".js-pledge-payments-forms", pledge.payments).append(response); 22274 22275 // If feedback is required 22276 if (waitForUser) { 22277 // Enable selector back 22278 paymentTriggers.prop("disabled", false); 22279 22280 // Hide loading spinner 22281 Modal.loading.hide(loading); 22282 22283 // Show pledge payment information 22284 if (!Utils.isMobile) { 22285 that.tip.show(pledge.paymentsTip); 22286 } 22287 22288 // Enable pledge button 22289 pledge.submit.trigger("trigger.vk.pledge.enableSubmit"); 22290 } else { 22291 // Trigger payment form loaded callback 22292 pledge.payments.trigger("paymentFormLoaded"); 22293 } 22294 }, 22295 }); 22296 } else { 22297 // Show pledge payment information 22298 if (!Utils.isMobile) { 22299 that.tip.show(pledge.paymentsTip); 22300 } 22301 22302 // Enable pledge button 22303 pledge.submit.trigger("trigger.vk.pledge.enableSubmit"); 22304 } 22305 }, 22306 22307 retryRedsys: { 22308 init: function () { 22309 var that = this; 22310 $("body").on("click.PledgeRetry", ".js-pledge-payment-retry-redsys", function (e) { 22311 e.preventDefault(); 22312 that.retry($(this)); 22313 }); 22314 }, 22315 retry: function (node) { 22316 var endpoint = node.attr("data-pledge-payment-retry-redsys-endpoint"); 22317 var formHolder = node.siblings(".js-pledge-payment-retry-redsys-form"); 22318 $.ajax({ 22319 type: "GET", 22320 url: endpoint, 22321 dataType: "html", 22322 success: function (response) { 22323 formHolder.append(response); 22324 $("form", formHolder).submit(); 22325 }, 22326 }); 22327 }, 22328 }, 22329 22330 retryPaypal: { 22331 init: function () { 22332 var that = this; 22333 $("body").on("click.PledgeRetry", ".js-pledge-payment-retry-paypal", function (e) { 22334 e.preventDefault(); 22335 22336 that.send($(this)); 22337 }); 22338 }, 22339 22340 send: function (node) { 22341 // Error 520009: "Account AUTHOR_EMAIL is restricted" 22342 var authorAccountIsRestrictedError = "520009"; 22343 var authorEmail = node.attr("data-pledge-payment-retry-author"); 22344 var endpoint = node.attr("data-pledge-payment-retry-endpoint"); 22345 var backerErrorModal = node.attr("data-pledge-payment-retry-backer-error-modal"); 22346 var authorErrorModal = node.attr("data-pledge-payment-retry-author-error-modal"); 22347 var success = node.attr("data-pledge-payment-retry-success-modal"); 22348 var errorPayload = []; 22349 var errorList = []; 22350 var errorFlat = {}; 22351 var errorContent = []; 22352 var errorsIdList = []; 22353 var errorAccountRestrictedIndex = null; 22354 var errorAccountRestrictedEmail = null; 22355 var modal = []; 22356 var modalData = {}; 22357 22358 $.get(endpoint, function (data) { 22359 if (data.paymentExecStatus === "COMPLETED") { 22360 modal = Modal.get(success); 22361 modalData = { 22362 modalTrigger: success, 22363 }; 22364 22365 // Switch button to success state 22366 Form.submit.successState(node); 22367 22368 // Open success payment modal 22369 Modal.show(modalData); 22370 22371 // Refresh page if user closes the modal 22372 $(".js-modal-close", modal) 22373 .off("click.vk.modal.close") 22374 .on("click", function () { 22375 location.reload(true); 22376 }); 22377 } else { 22378 // Switch button to error state 22379 Form.submit.errorState(node); 22380 22381 // Join all errors 22382 errorPayload = (data.payErrorList && data.payErrorList.payError) || data.error; 22383 22384 // Parse errors 22385 errorList = $.map(errorPayload, function (e) { 22386 errorFlat = e.error ? e.error : e; 22387 22388 return { 22389 id: errorFlat.errorId, 22390 message: errorFlat.message, 22391 parameter: errorFlat.parameter && errorFlat.parameter[0], 22392 }; 22393 }); 22394 22395 if (errorList.length) { 22396 errorContent = $("<div>"); 22397 22398 // Output errors in HTML 22399 $.each(errorList, function (i, val) { 22400 $("<p>") 22401 .html(errorList[i].message + "<br />Error ID: " + errorList[i].id) 22402 .appendTo(errorContent); 22403 }); 22404 22405 // List errors by ID 22406 errorsIdList = $.map(errorList, function (e) { 22407 return e.id; 22408 }); 22409 22410 errorAccountRestrictedIndex = errorsIdList.indexOf(authorAccountIsRestrictedError); 22411 if (errorAccountRestrictedIndex !== -1) { 22412 // If present, check if the error is due to author's email being restricted 22413 errorAccountRestrictedEmail = 22414 errorList[errorAccountRestrictedIndex].parameter.__value__ || 22415 errorList[errorAccountRestrictedIndex].parameter; 22416 } 22417 if (errorAccountRestrictedEmail === authorEmail) { 22418 modalData = { modalTrigger: authorErrorModal }; 22419 } else { 22420 modalData = { 22421 modalTrigger: backerErrorModal, 22422 pledgePaymentRetryErrorContent: errorContent, 22423 }; 22424 } 22425 // Open PayPal error modal 22426 Modal.show(modalData); 22427 } 22428 } 22429 }); 22430 }, 22431 }, 22432 22433 tip: { 22434 delay: 5000, 22435 timeout: null, 22436 tipVisibleClass: "modal-pledge__payment__tip--visible", 22437 22438 hide: function (node) { 22439 var that = this; 22440 22441 node.removeClass(that.tipVisibleClass); 22442 }, 22443 22444 show: function (node) { 22445 var that = this; 22446 22447 node.addClass(that.tipVisibleClass); 22448 22449 clearTimeout(that.timeout); 22450 22451 that.timeout = setTimeout(function () { 22452 that.hide(node); 22453 }, that.delay); 22454 }, 22455 }, 22456 }; 22457 22458 PledgePayments.init(); 22459 22460 return PledgePayments; 22461}); 22462/** 22463 * ProjectHero 22464 * @namespace Verkami 22465 * @class ProjectHero 22466 */ 22467 22468var name = "Verkami/ProjectHero"; 22469var deps = ["Verkami/Player", "Verkami/Settings", "Verkami/Utils"]; 22470 22471modulejs.define(name, deps, function (Player, Settings, Utils) { 22472 var ProjectHero = { 22473 node: [], 22474 playingClass: "project-hero--playing", 22475 22476 init: function () { 22477 var that = this; 22478 that.node = $(".js-project-hero"); 22479 22480 if (that.node.length) { 22481 that.follow.init(); 22482 that.player.init(); 22483 } 22484 }, 22485 22486 follow: { 22487 node: [], 22488 liteClass: "follow--lite", 22489 liteWidth: "104px", 22490 22491 init: function () { 22492 var that = this; 22493 this.follow = $(".follow", ProjectHero.node); 22494 var width = 0; 22495 22496 if (this.follow.length) { 22497 width = that.follow.outerWidth(); 22498 22499 // Save its initial width to perform the animation 22500 that.follow.data("follow-width", width); 22501 } 22502 }, 22503 22504 collapse: function () { 22505 var that = this; 22506 that.follow.addClass(that.liteClass); 22507 22508 that.follow.stop().animate( 22509 { 22510 width: that.liteWidth, 22511 }, 22512 Settings.speed * 4, 22513 "easeInOutCubic" 22514 ); 22515 }, 22516 22517 expand: function () { 22518 var that = this; 22519 that.follow.removeClass(that.liteClass); 22520 22521 that.follow.stop().animate( 22522 { 22523 width: that.follow.data("follow-width"), 22524 }, 22525 Settings.speed * 4 22526 ); 22527 }, 22528 }, 22529 22530 player: { 22531 init: function () { 22532 var that = ProjectHero; 22533 var player = $(".js-player", that.node); 22534 22535 player.on("hook.vk.player.start", function () { 22536 that.node.addClass(that.playingClass); 22537 22538 if (Utils.isDesktop) { 22539 that.follow.collapse(); 22540 } 22541 }); 22542 22543 player.on("hook.vk.player.end", function () { 22544 that.node.removeClass(that.playingClass); 22545 22546 if (Utils.isDesktop) { 22547 that.follow.expand(); 22548 } 22549 }); 22550 }, 22551 }, 22552 }; 22553 22554 ProjectHero.init(); 22555 22556 return ProjectHero; 22557}); 22558/** 22559 * Project 22560 * @namespace Verkami 22561 * @class Project 22562 */ 22563 22564var name = "Verkami/Project"; 22565var deps = [ 22566 "Verkami/Modal", 22567 "Verkami/Player", 22568 "Verkami/Scroll", 22569 "Verkami/Settings", 22570 "Verkami/Sticky", 22571 "Verkami/Tabs", 22572 "Verkami/TwitterWidget", 22573 "Verkami/Url", 22574 "Verkami/Utils", 22575 "Verkami/Video", 22576]; 22577 22578modulejs.define(name, deps, function (Modal, Player, Scroll, Settings, Sticky, Tabs, TwitterWidget, Url, Utils, Video) { 22579 var Project = { 22580 node: [], 22581 about: [], 22582 tabs: [], 22583 22584 init: function () { 22585 var that = this; 22586 var initialPageName = ""; 22587 var pageName = ""; 22588 var trigger = []; 22589 var tabsIndex = null; 22590 var tabsContents = []; 22591 var stickyOffset = null; 22592 var hash = Utils.hash.get(); 22593 var hashTest = /^[a-zA-Z0-9-_]+$/; 22594 var hashComment = []; 22595 that.node = $(".js-project"); 22596 22597 $(".js-project-bonus-input").one("input.project.bonus", function (e) { 22598 $(".js-project-bonus-submit").slideDown(); 22599 }); 22600 22601 that.node.on("keypress.checkout.bonus paste.checkout.bonus", ".js-project-bonus-input", function (e) { 22602 if (String.fromCharCode(e.keyCode).match(/[^0-9]/g)) return false;
22603 }); 22604 22605 if (that.node.length) { 22606 that.about = $(".js-project-about", that.node); 22607 that.tabs = $(".js-project-tabs", that.node); 22608 initialPageName = that.tabs.attr("data-project-tabs-active"); 22609 22610 // Save initial URL state 22611 window.history.replaceState({ page: initialPageName }, null, location.href); 22612 22613 // Hook browser history 22614 $(window).on("popstate.project", function (e) { 22615 if (e.originalEvent.state) { 22616 pageName = e.originalEvent.state.page; 22617 tabsContents = $(".js-tabs-content", that.tabs); 22618 stickyOffset = Sticky.getOffset(); 22619 22620 switch (pageName) { 22621 case "project": 22622 trigger = $(".js-tabs-trigger", that.tabs).filter(function () { 22623 return $(this).attr("data-url-name") === "project"; 22624 }); 22625 tabsIndex = $(".js-tabs-trigger", that.tabs).index(trigger); 22626 22627 Tabs.toggleContents(tabsContents, tabsIndex); 22628 Tabs.toggleTriggers(trigger); 22629 Scroll.smooth.doScroll(that.tabs, stickyOffset); 22630 22631 break; 22632 22633 case "projectBlogList": 22634 trigger = $(".js-tabs-trigger", that.tabs).filter(function () { 22635 return $(this).attr("data-url-name") === "projectBlogList"; 22636 }); 22637 tabsIndex = $(".js-tabs-trigger", that.tabs).index(trigger); 22638 22639 Tabs.toggleContents(tabsContents, tabsIndex); 22640 Tabs.toggleTriggers(trigger); 22641 Scroll.smooth.doScroll(that.tabs, stickyOffset); 22642 22643 // Show list view 22644 that.blog.toggleView("list"); 22645 break; 22646 22647 case "projectBlogPost": 22648 var trigger = $(".js-tabs-trigger", that.tabs).filter(function () { 22649 return $(this).attr("data-url-name") === "projectBlogList"; 22650 }); 22651 var tabsIndex = $(".js-tabs-trigger", that.tabs).index(trigger); 22652 22653 Tabs.toggleContents(tabsContents, tabsIndex); 22654 Tabs.toggleTriggers(trigger); 22655 Scroll.smooth.doScroll(that.tabs, stickyOffset); 22656 22657 // Show list view 22658 that.blog.toggleView("post"); 22659 break; 22660 22661 default: 22662 return; 22663 } 22664 } 22665 }); 22666 22667 // Initialize Twitter Third Party Widget 22668 TwitterWidget.init(); 22669 22670 // Initialize project blog controller 22671 that.blog.init(); 22672 22673 // Process images and embeds in mobile version 22674 if (Utils.isMobile) { 22675 that.processMedia(); 22676 } 22677 22678 // Hook tabs change event 22679 $(".js-tabs-content", that.tabs).on("hook.vk.tabs.show", function (e, index) { 22680 // Mobile only: Set blog class to project tabs if blog is active 22681 if (Utils.isMobile) { 22682 var urlName = $(".js-tabs-trigger", that.tabs).eq(index).attr("data-url-name"); 22683 var tabClass = "project-details__block--blog"; 22684 22685 if (urlName === "projectBlogList") { 22686 that.tabs.addClass(tabClass); 22687 } else { 22688 that.tabs.removeClass(tabClass); 22689 } 22690 } 22691 22692 // Reset video size if tab was hidden 22693 $(".js-video", this).each(function () { 22694 Video.setSize($(this)); 22695 }); 22696 }); 22697 22698 // Show blog list 22699 that.node.on("click", ".js-project-more-updates", function () { 22700 var activeIndex = 1; 22701 var activeTrigger = $(".js-tabs-trigger", that.tabs).eq(activeIndex); 22702 var tabsContents = $(".js-tabs-content", that.tabs); 22703 var stickyOffset = Sticky.getOffset(); 22704 22705 Tabs.toggleContents(tabsContents, activeIndex); 22706 Tabs.toggleTriggers(activeTrigger); 22707 Scroll.smooth.doScroll(that.tabs, stickyOffset); 22708 }); 22709 22710 if (Utils.isMobile || Utils.Tablet) { 22711 that.tabs.on("click", ".js-tabs-trigger", function () { 22712 Scroll.smooth.doScroll($("#project_details_anchor")); 22713 }); 22714 } 22715 22716 // If there is any comment anchored, scroll down to it 22717 if (hash && hashTest.test(hash)) { 22718 hashComment = $("#" + hash, that.node); 22719 22720 if (hashComment.length) { 22721 setTimeout(function () { 22722 stickyOffset = Sticky.getOffset(); 22723
22724 Scroll.smooth.doScroll(hashComment, stickyOffset + 40); 22725 }, Settings.speed * 4); 22726 } 22727 } 22728 } 22729 }, 22730 22731 blog: { 22732 blogListPlaceholder: [], 22733 blogPostPlaceholder: [], 22734 blogLoading: [], 22735 22736 init: function () { 22737 var that = this; 22738 that.blogListPlaceholder = $(".js-project-blog-list", Project.node); 22739 that.blogPostPlaceholder = $(".js-project-blog-post", Project.node); 22740 that.blogLoading = $(".js-project-blog-loading", Project.node); 22741 22742 Project.node.on("click", ".js-project-blog-post-load", function (e) { 22743 var source = $(this).attr("href"); 22744 22745 e.preventDefault(); 22746 22747 that.getPost(source); 22748 }); 22749 22750 that.blogPostPlaceholder.on("click", ".js-project-blog-back", function (e) { 22751 var source = $(this).attr("href"); 22752 22753 e.preventDefault(); 22754 22755 // Show list view 22756 that.toggleView("list", source); 22757 }); 22758 }, 22759 22760 getPost: function (source) { 22761 var that = this; 22762 var stickyOffset = Sticky.getOffset(); 22763 var isBlogListVisible = that.blogListPlaceholder.is(":visible"); 22764 var hash = source.indexOf("#") != -1 ? source.substring(source.indexOf("#")) : false; 22765 var trigger = []; 22766 var tabsIndex = null; 22767 22768 // Show list view 22769 if (!isBlogListVisible) { 22770 trigger = $(".js-tabs-trigger", Project.tabs).filter(function () { 22771 return $(this).attr("data-url-name") === "projectBlogList"; 22772 }); 22773 tabsIndex = $(".js-tabs-trigger", Project.tabs).index(trigger); 22774 22775 Tabs.toggleContents($(".js-tabs-content", Project.tabs), tabsIndex); 22776 Tabs.toggleTriggers(trigger); 22777 } 22778 22779 // Scroll to the top of the post 22780 Scroll.smooth.doScroll(Project.tabs, stickyOffset); 22781 22782 // Show spinner 22783 that.blogLoading.fadeIn(); 22784 22785 $.get(source, function (response) { 22786 // Add post content to the DOM 22787 that.blogPostPlaceholder.html(response); 22788 22789 // Refresh modal triggers 22790 Modal.refresh(); 22791 22792 // Refresh players 22793 console.log("Setting size for players to adjust in " + Settings.speed); 22794 setTimeout(() => { 22795 $(".js-video", that.blogPostPlaceholder).each(function () { 22796 console.log("Setting size for video... " + $(this)); 22797 Video.setSize($(this)); 22798 }); 22799 console.log("Player init"); 22800 Player.init(); 22801 console.log("Player done"); 22802 }, Settings.speed * 2); 22803 22804 // Hide spinner 22805 that.blogLoading.fadeOut(); 22806 22807 // Show post view 22808 that.toggleView("post", source); 22809 22810 if (hash) { 22811 setTimeout(function () { 22812 Scroll.smooth.doScroll($(hash), stickyOffset); 22813 }, Settings.speed * 3); 22814 } 22815 }); 22816 }, 22817 22818 toggleView: function (view, source) { 22819 var that = this; 22820 22821 if (view === "post") { 22822 that.blogListPlaceholder.fadeOut(function () { 22823 that.blogPostPlaceholder.fadeIn(); 22824 22825 // Update URL 22826 if (source) { 22827 Url.update({ page: "projectBlogPost" }, source); 22828 } 22829 }); 22830 } else { 22831 that.blogPostPlaceholder.fadeOut(function () { 22832 that.blogListPlaceholder.fadeIn(); 22833 22834 // Update URL 22835 if (source) { 22836 Url.update({ page: "projectBlogList" }, source); 22837 } 22838 }); 22839 } 22840 }, 22841 }, 22842 22843 processMedia: function () { 22844 var that = this; 22845 var iframes = $("iframe", that.about); 22846 var images = $("img", that.about); 22847 var nodes = $.fn.add.call(iframes, images); 22848 var parent = []; 22849 22850 nodes.each(function () { 22851 parent = $(this).parent(); 22852 22853 if (parent.hasClass("js-project-about")) { 22854 $(this).wrap('<p class="project-details__about__media"></p>'); 22855 } else { 22856 parent.addClass("project-details__about__media"); 22857 } 22858 }); 22859 }, 22860 }; 22861 22862 Project.init(); 22863 22864 return Project; 22865}); 22866/** 22867 * Promotion 22868 * @namespace Verkami 22869 * @class Promotion 22870 */ 22871 22872var name = "Verkami/Promotion"; 22873var deps = ["Verkami/CookiesAgreement", "Verkami/Utils"]; 22874 22875modulejs.define(name, deps, function(CookiesAgreement, Utils) { 22876 var Promotion = { 22877 nodes: [], 22878 hiddenClass: "promotion--hidden", 22879 22880 init: function() { 22881 var that = this; 22882 that.nodes = $(".js-promotion"); 22883 22884 if (that.nodes.length) { 22885 var close = []; 22886 var links = []; 22887 22888 that.nodes.each(function() { 22889 var node = this; 22890 var link = $(node).find("a"); 22891 22892 if (that.isPromotionHidden($(node))) { 22893 $(node).addClass(that.hiddenClass); 22894 } else { 22895 $(node).on("click", function() { 22896 that.hidePromotion($(node)); 22897 Utils.redirect(link.attr("href")); 22898 }); 22899 close = $(".js-promotion-close", node); 22900 close.on("click", function(e) { 22901 e.stopPropagation(); 22902 that.hidePromotion($(node)); 22903 }); 22904 link.on("click", function(e) { 22905 e.stopPropagation(); 22906 that.hidePromotion($(node)); 22907 }); 22908 } 22909 }); 22910 } 22911 }, 22912 22913 isPromotionHidden: function(promotion) { 22914 return !!Cookies.get(promotion.attr("data-promotion-cookie-name")); 22915 }, 22916 22917 hidePromotion: function(promotion) { 22918 var that = this; 22919 promotion.addClass(that.hiddenClass); 22920 Cookies.set(promotion.attr("data-promotion-cookie-name"), "true", { expires: 365 * 20 }); 22921 } 22922 }; 22923 22924 Promotion.init(); 22925 22926 return Promotion; 22927}); 22928/** 22929 * Question 22930 * @namespace Verkami 22931 * @class Question 22932 */ 22933 22934var name = "Verkami/Question"; 22935var deps = ["Verkami/Form", "Verkami/Modal", "Verkami/Settings"]; 22936
22937modulejs.define(name, deps, function (Form, Modal, Settings) { 22938 var Question = { 22939 nodes: [], 22940 22941 init: function () { 22942 var that = this; 22943 that.nodes = $(".js-question"); 22944 22945 that.nodes.each(function () { 22946 that.setup($(this)); 22947 }); 22948 }, 22949 22950 setup: function (node) { 22951 var endpoint = ""; 22952 var submit = []; 22953 22954 node.on("submit", function (e) { 22955 endpoint = node.attr("action"); 22956 submit = $(":submit", node); 22957 22958 // Prevent submit form by default 22959 e.preventDefault(); 22960 22961 Form.submit.loadingState(submit); 22962 22963 // Send the following status and get the current likes 22964 $.ajax({ 22965 type: "POST", 22966 url: endpoint, 22967 data: $(this).serialize(), 22968 error: function (data) { 22969 Form.submit.errorState(submit); 22970 }, 22971 success: function (data) { 22972 if (data.sent) { 22973 submit.removeAttr("disabled"); 22974 Form.submit.successState(submit); 22975 22976 setTimeout(function () { 22977 submit.closest(".js-modal").trigger("trigger.vk.modal.close"); 22978 22979 setTimeout(function () { 22980 Form.reset(submit.closest("form")); 22981 }, Settings.speed * 3); 22982 }, Settings.speed * 12); 22983 } else { 22984 Form.submit.errorState(submit); 22985 } 22986 }, 22987 }); 22988 }); 22989 }, 22990 }; 22991 22992 Question.init(); 22993 22994 return Question; 22995}); 22996/** 22997* Search 22998* @namespace Verkami 22999* @class Search 23000*/ 23001 23002var name = 'Verkami/Search'; 23003var deps = [ 23004 'Verkami/Settings', 23005 'Verkami/Utils' 23006]; 23007 23008modulejs.define(name, deps, function(Settings, Utils) { 23009 var Search = { 23010 node: [], 23011 close: [], 23012 input: [], 23013 form: [], 23014 trigger: [], 23015 wrapper: [], 23016 loadingClass: 'search--loading', 23017 visibleClass: 'search-visible', 23018 23019 init: function() { 23020 var that = this; 23021 that.node = $('.js-search'); 23022 23023 if (that.node.length) { 23024 that.close = $('.js-search-close', that.node); 23025 that.input = $('.js-search-field', that.node); 23026 that.form = $('.js-search-form', that.node); 23027 that.trigger = $('.js-search-trigger'); 23028 that.wrapper = $('.js-search-wrapper', that.node); 23029 23030 that.results.init(); 23031 23032 that.trigger.on('click', function() { 23033 $('body').addClass(that.visibleClass); 23034 23035 // @todo: Can I avoid speed as first parameter? 23036 that.node.fadeIn(Settings.speed, function() { 23037 that.setup(); 23038 23039 that.input.focus(); 23040 23041 $(window).resize(function() { 23042 that.setup(); 23043 }); 23044 }); 23045 23046 // Escape key closes the search layer 23047 $(document).on('keyup', function(e) { 23048 if (e.keyCode == 27) { 23049 that.hide(); 23050 23051 $(this).off('keyup'); 23052 } 23053 }); 23054 }); 23055 23056 that.close.on('click', function() { 23057 that.hide(); 23058 }); 23059 } 23060 }, 23061 23062 hide: function() { 23063 var that = this; 23064 23065 $('body').removeClass(that.visibleClass); 23066 that.node.fadeOut(); 23067 that.input.blur(); 23068 }, 23069 23070 results: { 23071 categories: [], 23072 empty: [], 23073 projects: [], 23074 source: '', 23075 lastQuery: '', 23076 minQuery: 3, 23077 timeout: null, 23078 23079 init: function() { 23080 var that = this; 23081 that.categories = $('.js-search-categories', Search.node); 23082 that.empty = $('.js-search-empty', Search.node); 23083 that.projects = $('.js-search-projects', Search.node); 23084 that.source = Search.input.data('search-source'); 23085 23086 Search.input.on('keyup', function() { 23087 that.getResults(); 23088 }); 23089 }, 23090 23091 buildResult: function(data) { 23092 var name = data.name; 23093 var url = data.url; 23094 var result = $('<li>', { class: 'search__results__group__list__item' }); 23095 var link = $('<a>', { href: url, title: name }).text(name).appendTo(result); 23096 23097 return result; 23098 }, 23099 23100 getResults: function() { 23101 var that = this; 23102 var text = Search.input.val().toLowerCase(); 23103 23104 if (text.length >= that.minQuery && text !== that.lastQuery) { 23105 clearTimeout(that.timeout); 23106 23107 that.timeout = setTimeout(function() { 23108 // Show spinner 23109 Search.node.addClass(Search.loadingClass); 23110 23111 // Avoid submit form until request ends 23112 Search.form.off('submit.form').on('submit.form', function(e) { 23113 e.preventDefault(); 23114 }); 23115 23116 // Disable search input 23117 Search.input.attr('disabled', true); 23118 23119 // Hide results 23120 that.hideResults([that.categories, that.empty, that.projects]); 23121 23122 $.ajax({ 23123 type: 'GET', 23124 url: that.source, 23125 data: { 23126 'term': text, 23127 'sorted_by': 'by_money' 23128 }, 23129 dataType: 'text', 23130 error: function(msg) { 23131 // We need to check if the value is the same 23132 if (text == Search.input.val().toLowerCase()) { 23133 $('form', Search.node).attr('action', '#'); 23134 } 23135 }, 23136 success: function(msg) { 23137 // We need to check if the value is the same 23138 if (text == Search.input.val().toLowerCase()) { 23139 var results = $.parseJSON(msg); 23140 var url = results.items[0].url; 23141 var projects = results.items[1].children; 23142 var categories = results.items[2].children; 23143 23144 // Cache the query 23145 that.lastQuery = text; 23146 23147 // Remove form submit blocker 23148 Search.form.off('submit.form'); 23149 23150 if (categories || projects) { 23151 // Change search label 23152 $('.js-search-label', Search.node).children('span').first().fadeOut('fast', function() { 23153 $('.js-search-label', Search.node).children('span').last().fadeIn('fast'); 23154 }); 23155 23156 // Update search form target 23157 $('form', Search.node).attr('action', url); 23158 23159 if (categories) { 23160 that.showResults(that.categories, categories); 23161 } 23162 23163 if (projects) { 23164 that.showResults(that.projects, projects); 23165 } 23166 } else { 23167 that.showResults(that.empty); 23168 } 23169 } 23170 }, 23171 complete: function() { 23172 // Remove spinner 23173 Search.node.removeClass(Search.loadingClass); 23174 23175 // Enable search input back again 23176 Search.input.attr('disabled', false).focus(); 23177 } 23178 }); 23179 }, Settings.delay); 23180 } else { 23181 if (text !== that.lastQuery) { 23182 // Change search label 23183 $('.js-search-label').children('span').last().fadeOut('fast', function() { 23184 $('.js-search-label').children('span').first().fadeIn('fast'); 23185 }); 23186 23187 // Hide results 23188 that.hideResults([that.categories, that.empty, that.projects]); 23189 } 23190 } 23191 }, 23192 23193 hideResults: function(target) { 23194 var that = this; 23195 23196 $.each(target, function() { 23197 $(this).fadeOut('fast', function() { 23198 $('.js-search-results', this).children().remove().end(); 23199 }); 23200 }); 23201 }, 23202 23203 showResults: function(target, data) { 23204 var that = this; 23205 data = data ? data : false;
23206 var results = []; 23207 var resultsList = target.find('.js-search-results'); 23208 23209 if (data) { 23210 $.each(data, function(index, val) { 23211 var result = that.buildResult(val); 23212 23213 results.push(result); 23214 }); 23215 23216 target.fadeOut('fast', function() { 23217 resultsList.children().remove().end(); 23218 resultsList.append(results).end().fadeIn('fast'); 23219 }); 23220 } else { 23221 target.fadeIn('fast'); 23222 } 23223 } 23224 }, 23225 23226 setup: function() { 23227 var that = this; 23228 var gutter = parseInt(that.node.css('padding-top')); 23229 var offset = that.wrapper.position().top + gutter; 23230 var viewportHeight = Utils.getViewportSize('height'); 23231 var wrapperHeight = viewportHeight - offset; 23232 23233 that.wrapper.outerHeight(wrapperHeight); 23234 } 23235 }; 23236 23237 Search.init(); 23238 23239 return Search; 23240}); 23241/** 23242* SettingsNotifications 23243* @namespace Verkami 23244* @class SettingsNotifications 23245*/ 23246 23247var name = 'Verkami/SettingsNotifications'; 23248 23249modulejs.define(name, function() { 23250 var SettingsNotifications = { 23251 node: [], 23252 box: [], 23253 triggers: [], 23254 23255 init: function() { 23256 var that = this; 23257 that.node = $('.js-profile-notifications'); 23258 23259 if (that.node.length) { 23260 that.box = $('.js-profile-notifications-box', that.node); 23261 that.triggers = $('input[type=radio]', that.node); 23262 var isTrigger = $('.js-profile-notifications-trigger').is(':checked'); 23263 23264 that.toggleBox(isTrigger); 23265 23266 that.triggers.on('change', function() { 23267 isTrigger = $(this).hasClass('js-profile-notifications-trigger'); 23268 23269 that.toggleBox(isTrigger); 23270 }); 23271 } 23272 }, 23273 23274 toggleBox: function(isTrigger) { 23275 var that = this; 23276 23277 if (isTrigger) { 23278 that.box.slideDown(); 23279 } else { 23280 that.box.slideUp(); 23281 } 23282 } 23283 }; 23284 23285 SettingsNotifications.init(); 23286 23287 return SettingsNotifications; 23288}); 23289/** 23290 * SettingsNotifications 23291 * @namespace Verkami 23292 * @class SettingsSubscriptions 23293 */ 23294
23295var name = "Verkami/SettingsSubscriptions"; 23296 23297modulejs.define(name, function() { 23298 var SettingsSubscriptions = { 23299 node: [], 23300 switchers: [], 23301 checks: [], 23302 23303 init: function() { 23304 var that = this; 23305 that.node = $(".js-settings-subscriptions"); 23306 23307 if (that.node.length) { 23308 that.switchers = $(".js-settings-subscriptions-switcher", that.node); 23309 that.checks = $("input[type=checkbox]", that.node); 23310 23311 that.checks.on("click", function() { 23312 var switcher = $(this).siblings(".js-settings-subscriptions-switcher"); 23313 if ($(this).is(":checked")) { 23314 switcher.show(); 23315 } else { 23316 switcher.hide(); 23317 } 23318 }); 23319 23320 that.switchers.on("click", function() { 23321 if ($(this).attr("data-alternative-mode")) { 23322 that.switch($(this)); 23323 } 23324 }); 23325 } 23326 }, 23327 23328 switch: function(switcher) { 23329 var currentMode = switcher.attr("data-current-mode"); 23330 var currentModeName = switcher.attr("data-current-mode-name"); 23331 var formField = switcher.parent().find(".js-settings-subscriptions-switcher-value"); 23332 switcher.attr("data-current-mode", switcher.attr("data-alternative-mode")); 23333 switcher.attr("data-current-mode-name", switcher.attr("data-alternative-mode-name")); 23334 formField.val(switcher.attr("data-current-mode")); 23335 switcher.html(switcher.attr("data-current-mode-name")); 23336 switcher.attr("data-alternative-mode", currentMode); 23337 switcher.attr("data-alternative-mode-name", currentModeName); 23338 } 23339 }; 23340 23341 SettingsSubscriptions.init(); 23342 23343 return SettingsSubscriptions; 23344}); 23345/** 23346* SocialManage 23347* @namespace Verkami 23348* @class SocialManage 23349*/ 23350 23351var name = 'Verkami/SocialManage'; 23352var deps = [ 23353 'Verkami/Form' 23354]; 23355 23356modulejs.define(name, deps, function(Form) { 23357 var SocialManage = { 23358 node: [], 23359 limit: 0, 23360 template: [], 23361 23362 init: function() { 23363 var that = this; 23364 that.node = $('.js-social-manage'); 23365 23366 if (that.node.length) { 23367 that.limit = that.node.attr('data-social-profiles-limit'); 23368 that.template = $('.js-social-manage-template', that.node); 23369 23370 // If limit is not reached, show a input to add a new link 23371 if (!that.isLimitReached()) { 23372 that.addLink(); 23373 } 23374 23375 // Show new link and remove link once choosing a social network 23376 $(that.node).on('change.fs', '.js-social-manage-select', function() { 23377 var item = $(this).parents('.js-social-manage-item').removeClass('js-social-manage-placeholder'); 23378 var isLast = !item.next('.js-social-manage-item').length; 23379 23380 $('.js-social-manage-remove', item).fadeIn('fast'); 23381 23382 if (isLast && !that.isLimitReached()) { 23383 that.addLink(); 23384 } 23385 }); 23386 23387 // Remove social link 23388 that.node.on('click', '.js-social-manage-remove', function() { 23389 that.removeLink($(this)); 23390 }); 23391 } 23392 }, 23393 23394 addLink: function() { 23395 var that = this; 23396 var links = $('.js-social-manage-item', that.node); 23397 var linkNew = that.template.clone().addClass('js-social-manage-placeholder'); 23398 var linkNewId = $.now(); 23399 var input = $('.js-social-manage-input', linkNew); 23400 var label = $('.js-social-manage-label', linkNew); 23401 var select = $('.js-social-manage-select', linkNew); 23402 var placeholder = 'placeholder'; 23403 var newInputId = input.attr('id').replace(placeholder, linkNewId); 23404 var newInputName = input.attr('name').replace(placeholder, linkNewId); 23405 var newSelectName = select.attr('name').replace(placeholder, linkNewId); 23406 23407 // Update form fields unique attributes 23408 input.attr({ 23409 'id': newInputId, 23410 'name': newInputName 23411 }); 23412 label.attr('for', newInputId); 23413 select.attr('name', newSelectName); 23414 23415 // Style new select 23416 Form.select.refresh($('select', linkNew)); 23417 23418 // Set classes, add to the DOM and show it 23419 linkNew.toggleClass('js-social-manage-template js-social-manage-item'); 23420 23421 // Insert new link in the right place 23422 if (links.last().length) { 23423 linkNew.insertAfter(links.last()); 23424 } else { 23425 linkNew.appendTo(that.node); 23426 } 23427 23428 // Show new link 23429 linkNew.slideDown('fast'); 23430 }, 23431 23432 isLimitReached: function() { 23433 var that = this; 23434 var linksCount = $('.js-social-manage-item', that.node).filter(function() { 23435 return $(this).is(':visible'); 23436 }).length; 23437 23438 return linksCount === that.limit || linksCount >= that.limit; 23439 }, 23440 23441 isPlaceholder: function() { 23442 var that = this; 23443 var isPlaceholder = $('.js-social-manage-placeholder', that.node).length; 23444 23445 return isPlaceholder; 23446 }, 23447 23448 removeLink: function(trigger) { 23449 var that = this; 23450 var linkToRemove = trigger.closest('.js-social-manage-item'); 23451 var linkHiddenName = $('.js-social-manage-input', linkToRemove).attr('name').replace('value', '_destroy'); 23452 23453 // Save removed input in a hidden field 23454 $('<input>').attr({ 23455 'name': linkHiddenName, 23456 'type': 'hidden', 23457 'value': 1 23458 }
23458).appendTo(linkToRemove); 23459 23460 // Hide the link 23461 linkToRemove.slideUp('fast', function() { 23462 // Add a new placeholder 23463 if (!that.isLimitReached() && !that.isPlaceholder()) { 23464 that.addLink(); 23465 } 23466 }); 23467 } 23468 }; 23469 23470 SocialManage.init(); 23471 23472 return SocialManage; 23473}); 23474/** 23475* Start 23476* @namespace Verkami 23477* @class Start 23478*/ 23479 23480var name = 'Verkami/Start'; 23481var deps = [ 23482 'Verkami/Scroll', 23483 'Verkami/Utils' 23484]; 23485 23486modulejs.define(name, deps, function(Scroll, Utils) { 23487 var Start = { 23488 heroModule: [], 23489 23490 init: function() { 23491 var that = this; 23492 that.heroModule = $('.js-start-hero'); 23493 23494 if (!Utils.isMobile && !Utils.isTablet) { 23495 if (that.heroModule.length) { 23496 that.setHeroHeight(); 23497 } 23498 23499 that.parallax(); 23500 } 23501 23502 that.bar.init(); 23503 }, 23504 23505 bar: { 23506 node: [], 23507 visibleClass: 'start-bar--visible', 23508 trigger: [], 23509 triggerOffset: null, 23510 23511 init: function() { 23512 var that = this; 23513 that.node = $('.js-start-bar'); 23514 23515 if (that.node.length) { 23516 that.trigger = $('.js-start-bar-trigger'); 23517 that.triggerOffset = that.trigger.offset().top; 23518 23519 that.toggle(); 23520 23521 $(window).scroll(function() { 23522 that.toggle(); 23523 }); 23524 } 23525 }, 23526 23527 toggle: function() { 23528 var that = this; 23529 var scrollPosition = Scroll.position(); 23530 23531 if (scrollPosition > that.triggerOffset) { 23532 that.node.addClass(that.visibleClass); 23533 } else { 23534 that.node.removeClass(that.visibleClass); 23535 } 23536 } 23537 }, 23538 23539 parallax: function() { 23540 var that = this; 23541 var offset = Utils.getViewportSize('height') / 2 - 55; 23542 23543 $.stellar({ 23544 horizontalScrolling: false, 23545 parallaxBackgrounds: false, 23546 verticalOffset: offset 23547 }); 23548 23549 }, 23550 23551 setHeroHeight: function() { 23552 var that = this; 23553 var offsetToTop = that.heroModule.offset().top; 23554 var viewportHeight = Utils.getViewportSize('height'); 23555 var heroHeight = viewportHeight - offsetToTop; 23556 23557 that.heroModule.height(heroHeight); 23558 } 23559 }; 23560 23561 Start.init(); 23562 23563 return Start; 23564}); 23565/** 23566* StartRewards 23567* @namespace Verkami 23568* @class StartRewards 23569*/ 23570 23571var name = 'Verkami/StartRewards'; 23572var deps = [ 23573 'Verkami/DataTransfer', 23574 'Verkami/Form', 23575 'Verkami/Modal', 23576 'Verkami/ReadMore', 23577 'Verkami/Settings' 23578]; 23579 23580modulejs.define(name, deps, function(DataTransfer, Form, Modal, ReadMore, Settings) { 23581 var StartRewards = { 23582 node: [], 23583 23584 init: function() { 23585 var that = this; 23586 that.node = $('.js-rewards'); 23587 23588 if (that.node.length) { 23589 that.events(); 23590 } 23591 }, 23592 23593 add: function(rewardItem) { 23594 var that = this; 23595 var newRewardItem = rewardItem.clone().hide(); 23596 var callback = $.Deferred(); 23597 23598 // Set up reward ID 23599 newRewardItem = that.setup(newRewardItem, callback); 23600 23601 // Insert new reward in DOM after set it up 23602 $.when(callback).done(function(response) { 23603 if (response) { 23604 newRewardItem 23605 .removeClass('start__rewards__item--add') 23606 .insertBefore(rewardItem) 23607 .slideDown(); 23608 23609 // Refresh events and other functionalities 23610 that.refreshReward(newRewardItem); 23611 23612 // Perform the dataTransfer from the form to the reward display 23613 DataTransfer.transfer($('.js-pull', newRewardItem).data()); 23614 23615 // Reset add reward form 23616 Form.reset($('.start__rewards__item--add', that.node)); 23617 } 23618 }); 23619 }, 23620 23621 delete: function(rewardItem) { 23622 var that = this; 23623 23624 // @todo: Check if it's possible to avoid the speed attribute 23625 rewardItem.slideUp(Settings.speed, function() { 23626 rewardItem.remove(); 23627 }); 23628 }, 23629 23630 duplicate: function(rewardItem) { 23631 var that = this; 23632 var newRewardItem = rewardItem.clone().hide(); 23633 var callback = $.Deferred(); 23634 23635 // Set up reward ID 23636 newRewardItem = that.setup(newRewardItem, callback); 23637 23638 // Insert new reward in DOM after set it up 23639 $.when(callback).done(function(response) { 23640 if (response) { 23641 newRewardItem.insertAfter(rewardItem).slideDown(); 23642 23643 // Refresh events and other functionalities 23644 that.refreshReward(newRewardItem); 23645 } 23646 }); 23647 }, 23648 23649 edit: function(rewardItem) { 23650 var that = this; 23651 var editedClass = 'start__rewards__item--edited'; 23652 23653 // Format month display 23654 var monthPlaceholder = $('.js-reward-month', rewardItem);
23655 var month = moment(new Date(monthPlaceholder.html())).format('MMMM'); 23656 23657 monthPlaceholder.html(month); 23658 23659 setTimeout(function() { 23660 rewardItem.addClass(editedClass); 23661 23662 setTimeout(function() { 23663 rewardItem.removeClass(editedClass); 23664 }, Settings.speed * 2); 23665 }, Settings.speed); 23666 }, 23667 23668 events: function() { 23669 var that = this; 23670 23671 that.node.on('click', '.js-rewards-add', function(e) { 23672 e.preventDefault(); 23673 23674 that.add(that.getRewardItem($(this))); 23675 }); 23676 23677 that.node.on('click', '.js-rewards-delete', function() { 23678 that.delete(that.getRewardItem($(this))); 23679 }); 23680 23681 that.node.on('click', '.js-rewards-duplicate', function() { 23682 that.duplicate(that.getRewardItem($(this))); 23683 }); 23684 23685 that.node.on('click', '.js-rewards-edit', function(e) { 23686 e.preventDefault(); 23687 23688 that.edit(that.getRewardItem($(this))); 23689 }); 23690 }, 23691 23692 getRewardItem: function(element) { 23693 var rewardItem = element.closest('.js-rewards-item'); 23694 23695 return $(rewardItem); 23696 }, 23697 23698 refreshReward: function(rewardItem) { 23699 // Set Up readMore node 23700 ReadMore.setup(rewardItem); 23701 23702 // Refresh dataTransfer 23703 DataTransfer.refresh(); 23704 23705 // Set Up selects and form validation 23706 Form.emptyCheck.init(); 23707 Form.select.refresh($('.js-select select', rewardItem)); 23708 23709 // Refresh modal events 23710 Modal.refresh(); 23711 }, 23712 23713 setup: function(rewardItem, callback) { 23714 var id = rewardItem.data('reward-id'); 23715 var newId = $.now(); 23716 var idPlaceholders = $('.js-reward-item-id-placeholder', rewardItem); 23717 var idPlaceholderItem = []; 23718 var replacedData = ''; 23719 var replacedId = ''; 23720 var replacedFor = ''; 23721 var replacedName = ''; 23722 23723 // Save the new reward ID 23724 rewardItem.attr('data-reward-id', newId); 23725 23726 // Change Reward ID in all places 23727 idPlaceholders.each(function() { 23728 idPlaceholderItem = $(this); 23729 23730 // Find and replace the ID in form field names, fors and data attributes 23731 if (idPlaceholderItem.is(':input')) { 23732 // Replace old ID to the new one 23733 if (idPlaceholderItem.is('[id]')) { 23734 replacedId = idPlaceholderItem.attr('id').replace(id, newId); 23735 23736 idPlaceholderItem.attr('id', replacedId); 23737 } 23738 23739 // Replace old name to the new one 23740 if (idPlaceholderItem.is('[name]')) { 23741 replacedName = idPlaceholderItem.attr('name').replace(id, newId); 23742 23743 idPlaceholderItem.attr('name', replacedName); 23744 } 23745 } else if (idPlaceholderItem.is('label')) { 23746 // Replace old for to the new one 23747 if (idPlaceholderItem.is('[for]')) { 23748 replacedFor = idPlaceholderItem.attr('for').replace(id, newId); 23749 23750 idPlaceholderItem.attr('for', replacedFor); 23751 } 23752 } 23753 23754 $.each(idPlaceholderItem.data(), function(key, value) { 23755 // Find data attributes containing the old ID 23756 if (typeof value === 'string' && ~value.indexOf(id)) { 23757 // Convert the key from camelCase to dashed 23758 key = key.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase(); 23759 23760 // Replace old ID to the new one 23761 replacedData = idPlaceholderItem.attr('data-' + key).replace(id, newId); 23762 23763 // Save the new data attribute value 23764 idPlaceholderItem.attr('data-' + key, replacedData); 23765 } 23766 }); 23767 }); 23768 23769 // Resolve Set Up callback 23770 callback.resolve(true); 23771 23772 return rewardItem; 23773 } 23774 }; 23775 23776 StartRewards.init(); 23777 23778 return StartRewards; 23779}); 23780/** 23781 * Subscribe 23782 * @namespace Verkami 23783 * @class Subscribe 23784 */ 23785 23786var name = "Verkami/Subscribe"; 23787var deps = ["Verkami/Form", "Verkami/Settings", "Verkami/Utils"]; 23788 23789modulejs.define(name, deps, function (Form, Settings, Utils) { 23790 var Subscribe = { 23791 node: [], 23792 form: [], 23793 input: [], 23794 button: [], 23795 feedback: [], 23796 trigger: [], 23797 close: [], 23798 type: "", 23799 emailErrorMessage: "", 23800 buttonDisabledClass: "button--disabled", 23801 buttonErrorClass: "button--alert", 23802 buttonLoadingClass: "button--loading", 23803 buttonOkClass: "button--success", 23804 buttonTransitionSpeed: Settings.speed * 16, 23805 feedbackErrorClass: "subscribe__feedback--error", 23806 feedbackOkClass: "subscribe__feedback--success", 23807 triggerErrorClass: "subscribe__trigger--error", 23808 triggerOkClass: "subscribe__trigger--success", 23809 triggerLoadingClass: "subscribe__trigger--loading", 23810 triggerLoadingText: "", 23811 23812 init: function () { 23813 var that = this; 23814 that.node = $(".js-subscribe"); 23815 23816 if (that.node.length) { 23817 that.form = $(".js-subscribe-form", that.node); 23818 that.feedback = $(".js-subscribe-feedback", that.node); 23819 that.emailErrorMessage = that.form.attr("data-subscribe-error"); 23820 that.type = that.node.attr("data-subscribe-type"); 23821 that.close = $(".js-subscribe-close", that.node); 23822 23823 that.close.on("click", function() { 23824 Cookies.set(that.node.attr("data-cookie-name"), "true"); 23825 that.node.fadeOut(); 23826 }); 23827 // Set up different events for each subscribe form type 23828 if (that.type === "direct") { 23829 that.trigger = $(".js-subscribe-trigger", that.node); 23830 that.triggerLoadingText = that.trigger.attr("data-subscribe-sending-text"); 23831 23832 // One-click subscribing when user is logged in 23833 that.trigger.on("click", function () { 23834 // Save default text 23835 that.trigger.attr("data-subscribe-default-text", $("span", that.trigger).html()); 23836 23837 // Turn on the loading style 23838 that.trigger.addClass(that.triggerLoadingClass); 23839 23840 // Show loading text 23841 $("span", that.trigger).html(that.triggerLoadingText); 23842 23843 $.post( 23844 that.form.attr("action"), 23845 that.form.serialize(), 23846 function (response) { 23847 that.toggleFeedback(response.signed_up, response.message, that.type); 23848 }, 23849 "json", 23850 ); 23851 }); 23852 } else if (that.type === "redirect") { 23853 that.trigger = $(".js-subscribe-trigger", that.node); 23854 that.trigger.on("click", function () { 23855 Cookies.set(that.node.attr("data-cookie-name"), "true"); 23856 window.location.href = that.node.attr("data-subscribe-url"); 23857 }); 23858 } else if (that.type === "form") { 23859 that.input = $(".js-subscribe-input", that.node); 23860 that.button = $(".js-subscribe-button", that.node); 23861 23862 if (Utils.isMobile || Utils.isTablet) { 23863 that.trigger = $(".js-subscribe-trigger", that.node); 23864 23865 that.trigger.on("click", function () { 23866 that.showForm(); 23867 }); 23868 } 23869 23870 that.input.on("keyup input blur", function () { 23871 that.validate(); 23872 }); 23873 23874 that.form.submit(function () { 23875 that.button.addClass(that.buttonLoadingClass); 23876 23877 if (that.validate()) { 23878 $.post( 23879 $(this).attr("action"), 23880 $(this).serialize(), 23881 function (response) { 23882 that.toggleFeedback(response.signed_up, response.message, that.type); 23883 }, 23884 "json", 23885 ); 23886 } else { 23887 that.toggleFeedback(false, that.emailErrorMessage, that.type); 23888 } 23889 return false;
23890 }); 23891 } 23892 } 23893 }, 23894 23895 showForm: function () { 23896 var that = this; 23897 23898 // @todo: Is it possible to jump the speed attr and set callback as first arg? 23899 that.trigger.slideUp(Settings.speed, function () { 23900 that.form.slideDown(); 23901 that.input.focus(); 23902 }); 23903 }, 23904 23905 toggleFeedback: function (signedUp, message, type) { 23906 var that = this; 23907 var buttonClass = signedUp ? that.buttonOkClass : that.buttonErrorClass; 23908 var feedbackClass = signedUp ? that.feedbackOkClass : that.feedbackErrorClass; 23909 var triggerClass = signedUp ? that.triggerOkClass : that.triggerErrorClass; 23910 23911 if (type === "direct") { 23912 // Turn on the loading style 23913 that.trigger.removeClass(that.triggerLoadingClass); 23914 23915 // Change trigger style depending on the response 23916 that.trigger.addClass(triggerClass); 23917 23918 // Show feedback message 23919 that.feedback.html(message).fadeIn(); 23920 23921 if (!signedUp) { 23922 setTimeout(function () { 23923 // Hide feedback message 23924 that.feedback.fadeOut(); 23925 23926 // Hide loading text 23927 $("span", that.trigger).html(that.trigger.attr("data-subscribe-default-text")); 23928 23929 // Remove the error class 23930 that.trigger.removeClass(triggerClass); 23931 }, that.buttonTransitionSpeed); 23932 } 23933 } else if (type === "form") { 23934 // Update submit style 23935 that.button.removeClass(that.buttonLoadingClass).addClass(buttonClass); 23936 23937 // Update feedback style and toggle it 23938 that.feedback.html(message).addClass(feedbackClass).slideDown(); 23939 23940 // Get the form back to its default state 23941 setTimeout(function () { 23942 that.button.removeClass(buttonClass); 23943 23944 // @todo: Is it possible to jump the speed attr and set callback as first arg?
23945 that.feedback.slideUp(Settings.speed, function () { 23946 that.feedback.removeClass(feedbackClass); 23947 }); 23948 23949 that.input.val(""); 23950 }, that.buttonTransitionSpeed); 23951 } 23952 }, 23953 23954 validate: function () { 23955 var that = this; 23956 23957 var isValid = Form.validate.email(that.input.val()); 23958 23959 if (isValid) { 23960 that.button.removeClass(that.buttonDisabledClass); 23961 return true; 23962 } else { 23963 that.button.addClass(that.buttonDisabledClass); 23964 return false; 23965 } 23966 }, 23967 }; 23968 23969 Subscribe.init(); 23970 23971 return Subscribe; 23972}); 23973/** 23974* SurveyBillingShipping 23975* @namespace Verkami 23976* @class SurveyBillingShipping 23977*/ 23978 23979var name = "Verkami/SurveyBillingShipping"; 23980 23981modulejs.define(name, function() { 23982 var SurveyBillingShipping = { 23983 node: [], 23984 box: [], 23985 triggers: [], 23986 23987 init: function() { 23988 var that = this; 23989 that.node = $(".js-use-billing-for-shipping"); 23990 23991 if (that.node.length) { 23992 that.box = $(".js-use-billing-for-shipping-box", that.node); 23993 that.triggers = $("input[type=radio]", that.node); 23994 var isTrigger = $(".js-use-billing-for-shipping-trigger").is(":checked"); 23995 23996 that.toggleBox(isTrigger); 23997 23998 that.triggers.on("change", function() { 23999 isTrigger = $(this).hasClass("js-use-billing-for-shipping-trigger"); 24000 24001 that.toggleBox(isTrigger); 24002 }); 24003 } 24004 }, 24005 24006 toggleBox: function(isTrigger) { 24007 var that = this; 24008 24009 if (isTrigger) { 24010 that.box.slideDown(); 24011 } else { 24012 that.box.slideUp(); 24013 } 24014 } 24015 }; 24016 24017 SurveyBillingShipping.init(); 24018 24019 return SurveyBillingShipping; 24020}); 24021/** 24022* TwitterWidget 24023* @namespace Verkami 24024* @class TwitterWidget 24025*/ 24026 24027var name = 'Verkami/TwitterWidget'; 24028 24029modulejs.define(name, function() { 24030 var TwitterWidget = { 24031 source: 'https://platform.twitter.com/widgets.js', 24032 24033 init: function() { 24034 var that = this; 24035 24036 window.twttr = (function (d, s, id) { 24037 var t, js, fjs = d.getElementsByTagName(s)[0]; 24038 if (d.getElementById(id)) return; 24039 js = d.createElement(s); js.id = id; js.src= that.source; 24040 fjs.parentNode.insertBefore(js, fjs); 24041 return window.twttr || (t = { _e: [], ready: function (f) { t._e.push(f) } }); 24042 }(document, 'script', 'twitter-wjs')); 24043 } 24044 }; 24045 24046 TwitterWidget.init(); 24047 24048 return TwitterWidget; 24049}); 24050/** 24051 * User 24052 * @namespace Verkami 24053 * @class User 24054 */ 24055 24056var name = "Verkami/User"; 24057var deps = ["Verkami/Avatar", "Verkami/Form", "Verkami/Modal", "Verkami/Panels", "Verkami/Settings", "Verkami/Utils"]; 24058 24059modulejs.define(name, deps, function (Avatar, Form, Modal, Panels, Settings, Utils) { 24060 var User = { 24061 logoutTrigger: [], 24062 passwordForm: [], 24063 signupForm: [], 24064 buttonDisabledClass: "button--disabled", 24065 loggedInEvent: "loggedIn", 24066 loginErrorEvent: "loginError", 24067 signedUpEvent: "signedUp", 24068 signedUpErrorEvent: "signedUpError", 24069 24070 init: function () { 24071 var that = this; 24072 24073 that._callbacks(); 24074 24075 that.setup(); 24076 }, 24077 24078 _callbacks: function () { 24079 var that = this; 24080 24081 $(document).on("trigger.vk.user.setup", function (e) { 24082 that.setup(); 24083 }); 24084 24085 $(document).on("trigger.vk.user.login.init", ".js-login", function () { 24086 that.login.init($(this)); 24087 }); 24088 }, 24089 24090 facebook: function (nodes) { 24091 var node = []; 24092 var path = []; 24093 var pathNew = []; 24094 var redirect = []; 24095 24096 nodes.each(function () { 24097 node = $(this); 24098 redirect = node.attr("data-auth-redirect"); 24099 24100 if (redirect) { 24101 path = node.attr("href"); 24102 pathNew = path + "&origin=" + redirect; 24103 24104 node.attr("href", pathNew); 24105 } 24106 }); 24107 }, 24108 24109 google: function (nodes) { 24110 var node = []; 24111 var path = []; 24112 var pathNew = []; 24113 var redirect = []; 24114 24115 nodes.each(function () { 24116 node = $(this); 24117 redirect = node.attr("data-auth-redirect"); 24118 24119 if (redirect) { 24120 //path = node.attr("href"); 24121 input = node.parent().find("input[name='proceed_to']"); 24122 input.val(input.val() + "&origin=" + redirect); 24123 } 24124 }); 24125 }, 24126 24127 refreshUserInfo: function (panelContents, userInfo) { 24128 $(".js-username-placeholder").html(userInfo.name); 24129 if (Settings.beta.tokenizationAvailable()) { 24130 $(".js-tokenized-cards", panelContents) 24131 // Make the placeholder a regular form item when it holds cards 24132 .addClass("form-item") 24133 .html(userInfo.cards); 24134 } 24135 Avatar.refresh(userInfo.avatar); 24136 }, 24137 24138 login: { 24139 inputEvents: "keyup.loginInput paste.loginInput input.loginInput", 24140 loginErrorTimeout: null, 24141 24142 init: function (loginForm) { 24143 var that = this; 24144 var loginButton = $(".js-login-button", loginForm.closest(".
24144js-modal")); 24145 24146 loginButton.off("click.loginSubmit").on("click.loginSubmit", function (e) { 24147 e.preventDefault(); 24148 24149 that.submit(loginForm, false); 24150 }); 24151 }, 24152 24153 error: function (loading, loginInputs) { 24154 // Hide loading spinner 24155 Modal.loading.hide(loading); 24156 24157 // Enable inputs back 24158 loginInputs.prop("disabled", false); 24159 24160 // Show errors 24161 Form.error("show", loginInputs); 24162 }, 24163 24164 submit: function (loginForm, feedback) { 24165 var that = this; 24166 var loginEmail = $(".js-login-email", loginForm); 24167 var loginPassword = $(".js-login-password", loginForm); 24168 var loginInputs = $.fn.add(loginEmail).add(loginPassword); 24169 var formData = loginForm.serializeArray(); 24170 var source = loginForm.attr("action"); 24171 var loading = loginForm.closest(".js-modal").find(".js-modal-loading"); 24172 24173 // Boolean to know if we are inside the pledge process 24174 var isPledge = loginForm.closest(".js-pledge").length; 24175 24176 // Remove error class on keyup 24177 Form.error("hide", loginInputs); 24178 24179 clearTimeout(that.loginErrorTimeout); 24180 24181 // Disable inputs 24182 loginInputs.prop("disabled", true); 24183 24184 // Show loading spinner 24185 Modal.loading.show(loading); 24186 24187 $.ajax({ 24188 type: "POST", 24189 url: source, 24190 data: formData, 24191 dataType: "json", 24192 error: function () { 24193 // Show errors 24194 that.error(loading, loginInputs); 24195 24196 // Remove error style if user is typing 24197 loginInputs.off("keyup.removeError").one("keyup.removeError", function () { 24198 $(this).closest(".form-item--error").removeClass("form-item--error"); 24199 }); 24200 24201 if (isPledge) { 24202 // Trigger loginError callback to use in the pledge modal 24203 loginForm.trigger(User.loginErrorEvent); 24204 } 24205 }, 24206 success: function (response) { 24207 var isLogged = response.logged; 24208 var redirectPath = loginForm.attr("data-auth-redirect"); 24209 24210 if (feedback) { 24211 Modal.loading.hide(loading); 24212 } 24213 24214 if (isLogged) { 24215 var panelContents = loginForm.closest(".js-panels"); 24216 var loggedInPanelPresent = Panels.getContent(panelContents, Panels.loggedIn).length; 24217 24218 if (loggedInPanelPresent) { 24219 $(".js-pledge .js-panels").data("logged-in", true); 24220 User.refreshUserInfo(panelContents, response.user); 24221 loginInputs.prop("disabled", false); 24222 24223 if (isPledge) { 24224 // Trigger loggedIn callback to use in the pledge modal 24225 if (redirectPath) { 24226 Utils.redirect(redirectPath); 24227 } else { 24228 loginForm.trigger(User.loggedInEvent); 24229 } 24230 } else { 24231 Modal.loading.hide(loading); 24232 loginForm 24233 .closest(".js-modal") 24234 .find(".js-modal-close") 24235 .off("click.vk.modal.close") 24236 .on("click.vk.modal.close", function () { 24237 // Go to the custom redirect URL 24238 Utils.redirect(redirectPath || response.redirect); 24239 }); 24240 } 24241 } else { 24242 Utils.redirect(redirectPath || response.redirect); 24243 } 24244 } else { 24245 // Show errors 24246 that.error(loading, loginInputs); 24247 24248 // Remove error style if user is typing 24249 loginInputs.off("keyup.removeError").one("keyup.removeError", function () { 24250 $(this).closest(".form-item--error").removeClass("form-item--error"); 24251 }); 24252 24253 if (isPledge) { 24254 // Trigger loginError callback to use in the pledge modal 24255 loginForm.trigger(User.loginErrorEvent); 24256 } 24257 } 24258 }, 24259 }); 24260 }, 24261 24262 validate: function (loginEmail, loginPassword) { 24263 var isValidEmail = Form.validate.email(loginEmail.val()); 24264 var isValidPassword = loginPassword.val().length > 3; 24265 24266 return isValidEmail && isValidPassword; 24267 }, 24268 }, 24269 24270 logout: function (trigger) { 24271 var source = trigger.attr("href"); 24272 var isLoggedOut = null; 24273 var panelContents = [];
24274 var loading = trigger.closest(".js-modal").find(".js-modal-loading"); 24275 24276 // Show loading spinner 24277 Modal.loading.show(loading); 24278 24279 $.ajax({ 24280 type: "GET", 24281 url: source, 24282 dataType: "json", 24283 success: function (response) { 24284 isLoggedOut = !response.logged; 24285 24286 // Hide loading spinner 24287 Modal.loading.hide(loading); 24288 24289 if (isLoggedOut) { 24290 panelContents = trigger.closest(".js-panels"); 24291 24292 // Change pledge logged in flag 24293 $(".js-pledge .js-panels").data("logged-in", false); 24294 24295 // Clean login input 24296 Form.reset($(".js-login")); 24297 24298 // Show login panel 24299 Panels.toggleContents(panelContents, 2); 24300 24301 // Refresh page if user closes the modal (this is a temporarily fix to show user's menu, top bars, etc.) 24302 trigger 24303 .closest(".js-modal") 24304 .find(".js-modal-close") 24305 .off("click.vk.modal.close") 24306 .on("click.vk.modal.close", function () { 24307 location.reload(true); 24308 }); 24309 } 24310 }, 24311 }); 24312 }, 24313 24314 passwordRecovery: { 24315 error: function (emailField, type) { 24316 var errorClass = "form-item__error"; 24317 var errorDatabaseMessage = emailField.closest(".js-password-recovery").find(".js-password-recovery-database"); 24318 var errorGenericMessage = emailField.closest(".js-password-recovery").find(".js-password-recovery-generic"); 24319 var errorTypoMessage = emailField.closest(".js-password-recovery").find(".js-password-recovery-typo"); 24320 24321 // Add error style to the field 24322 emailField.addClass(errorClass); 24323 24324 // Show the error message 24325 switch (type) { 24326 case "generic": 24327 errorGenericMessage.slideDown("fast"); 24328 24329 setTimeout(function () { 24330 errorGenericMessage.slideUp("fast"); 24331 }, Settings.speed * 10); 24332 24333 break; 24334 case "database": 24335 errorDatabaseMessage.slideDown("fast"); 24336 24337 setTimeout(function () { 24338 errorDatabaseMessage.slideUp("fast"); 24339 }, Settings.speed * 10); 24340 24341 break; 24342 24343 case "typo": 24344 errorTypoMessage.slideDown("fast"); 24345 24346 setTimeout(function () { 24347 errorTypoMessage.slideUp("fast"); 24348 }, Settings.speed * 10); 24349 24350 break; 24351 } 24352 24353 // Remove errors once user starts to type again 24354 emailField.off("keyup.passwordRecover").one("keyup.passwordRecover", function () { 24355 // Clean email field error 24356 emailField.removeClass(errorClass); 24357 }); 24358 }, 24359 24360 recover: function (form) { 24361 var that = this; 24362 var emailField = $(".js-password-recovery-email", form); 24363 var email = emailField.val().trim(); 24364 var isValidEmail = Form.validate.email(email); 24365 var panelModule = []; 24366 var panelId = 0; 24367 var loading = []; 24368 var formData = []; 24369 24370 if (isValidEmail) { 24371 formData = form.serializeArray(); 24372 loading = form.closest(".js-modal").find(".js-modal-loading"); 24373 24374 // Show loading spinner 24375 Modal.loading.show(loading); 24376 24377 $.ajax({ 24378 type: "POST", 24379 url: form.attr("action"), 24380 data: formData, 24381 dataType: "json", 24382 error: function () { 24383 // Hide loading spinner 24384 Modal.loading.hide(loading); 24385 24386 // Show error 24387 that.error(emailField, "generic"); 24388 }, 24389 success: function (data) { 24390 // Hide loading spinner 24391 Modal.loading.hide(loading); 24392 24393 // Check if provided email is the same as the response one 24394 if (data.user) { 24395 panelId = parseInt($(".button:submit", form).attr("data-panels-trigger")); 24396 panelModule = form.closest(".js-panels"); 24397 24398 // Show confirmation panel if requested in the submit button 24399 if (panelId) { 24400 Panels.toggleContents(panelModule, panelId); 24401 } 24402 } else { 24403 // Show error 24404 that.error(emailField, "database"); 24405 } 24406 }, 24407 }); 24408 } else { 24409 // Show error 24410 that.error(emailField, "typo"); 24411 } 24412 }, 24413 }, 24414 24415 setup: function () { 24416 var that = this; 24417 that.logoutTrigger = $(".js-logout"); 24418 that.passwordForm = $(".js-password-recovery"); 24419 that.signupForm = $(".js-signup"); 24420 24421 if (that.logoutTrigger.length) { 24422 that.logoutTrigger.off("click.logoutTrigger").on("click.logoutTrigger", function (e) { 24423 e.preventDefault(); 24424 24425 that.logout($(this)); 24426 }); 24427 } 24428 24429 if (that.passwordForm.length) { 24430 that.passwordForm.off("submit.passwordRecovery").on("submit.passwordRecovery", function (e) { 24431 e.preventDefault(); 24432 24433 that.passwordRecovery.recover($(this)); 24434 }); 24435 } 24436 24437 if (that.signupForm.length) { 24438 that.signupForm.each(function () { 24439 that.signup.init($(this)); 24440 }); 24441 } 24442 24443 // Setup Facebook button 24444 that.facebook($(".js-auth-facebook")); 24445 that.google($(".js-auth-google")); 24446 }, 24447 24448 signup: { 24449 init: function (node) { 24450 var that = this; 24451 24452 that.events(node); 24453 }, 24454 24455 events: function (node) { 24456 var that = this;
24457 var submit = node.closest(".js-modal").find(".js-signup-submit"); 24458 var captchaEnabledInSubmit = submit.hasClass("js-recaptcha"); 24459 var eventToListen = "click.signUpSubmit"; 24460 if (captchaEnabledInSubmit) { 24461 console.log("[CAPTCHA] Signup with captcha requirements detected."); 24462 console.log("[CAPTCHA] Listening to captcha events."); 24463 eventToListen = "captcha.vk.validated"; 24464 } 24465 24466 submit.off(eventToListen).on(eventToListen, function (e) { 24467 console.log("Processing signup submit triggered by " + eventToListen); 24468 e.preventDefault(); 24469 24470 that.submit($(this).closest(".js-modal").find(".js-signup"), true); 24471 }); 24472 }, 24473 24474 submit: function (signupForm, feedback) { 24475 var signupAgreement = signupForm.closest(".js-modal").find(".js-signup-agreement"); 24476 var signupEmail = $(".js-signup-email", signupForm); 24477 var signupEmailConfirmation = $(".js-signup-email-confirmation", signupForm); 24478 var signupName = $(".js-signup-name", signupForm); 24479 var signupNewsletter = $(".js-signup-newsletter", signupForm); 24480 var signupPassword = $(".js-signup-password", signupForm); 24481 var signupInputs = $.fn.add(signupEmail).add(signupEmailConfirmation).add(signupName).add(signupPassword); 24482 var timeout = null; 24483 var loading = signupForm.closest(".js-modal").find(".js-modal-loading"); 24484 24485 // Validate agreement 24486 var isValidAgreement = signupAgreement.is(":checked"); 24487 24488 // Boolean to know if we are inside the pledge process 24489 var isPledge = signupForm.closest(".js-pledge").length; 24490 24491 // Remove input error on keyup 24492 signupInputs.off("keyup.signupInputs"); 24493 24494 signupInputs.on("keyup.signupInputs", function () { 24495 Form.error("hide", $(this)); 24496 }); 24497 24498 // Remove checkbox error on change 24499 signupAgreement.off("change.signupAgreement"); 24500 24501 signupAgreement.on("change.signupAgreement", function () { 24502 Form.error("hide", $(this)); 24503 }); 24504 24505 // Submit form is all required fields are ok, otherwise show errors 24506 if (isValidAgreement) { 24507 var formData = signupForm.serializeArray(); 24508 var source = signupForm.attr("action"); 24509 24510 // Show loading spinner 24511 Modal.loading.show(loading); 24512 24513 clearTimeout(timeout); 24514 24515 timeout = setTimeout(function () { 24516 $.ajax({ 24517 type: "POST", 24518 url: source, 24519 data: formData, 24520 dataType: "json", 24521 error: function () { 24522 // Hide loading spinner 24523 Modal.loading.hide(loading); 24524 24525 Form.error("show", $.fn.add.call(signupInputs, isValidAgreement)); 24526 24527 if (isPledge) { 24528 signupForm.trigger(User.signedUpErrorEvent); 24529 } 24530 }, 24531 success: function (response) { 24532 var isSignedUp = response.signup; 24533 var modalId = null; 24534 var redirectPath = signupForm.attr("data-auth-redirect"); 24535 24536 if (feedback) { 24537 // Hide loading spinner 24538 Modal.loading.hide(loading); 24539 } 24540 24541 if (isSignedUp) { 24542 redirectPath = redirectPath ? redirectPath : response.redirect; 24543 24544 if (isPledge) { 24545 // Trigger signedUp callback to use in the pledge modal 24546 signupForm.trigger(User.signedUpEvent); 24547 } else { 24548 modalId = signupForm.closest(".js-modal").data("modal-id"); 24549 24550 // Go to the custom redirect URL 24551 Utils.redirect(redirectPath); 24552 } 24553 } else { 24554 // Show error messages 24555 var errorNode = []; 24556 24557 // Remove old errors 24558 signupInputs.closest("[class*='form-item']").find(".form-item__error-message").remove(); 24559 24560 $.each(response.errors, function (index, error) { 24561 for (var name in error) { 24562 if (error.hasOwnProperty(name)) { 24563 // Error message placeholder 24564 errorNode = $("<div>", { 24565 class: "form-item__error-message", 24566 }).html(error[name]); 24567 24568 // Output each error in its place 24569 switch (name) { 24570 case "email": 24571 Form.error("show", signupEmail); 24572 errorNode.appendTo(signupEmail.closest("[class*='form-item']")); 24573 break; 24574 24575 case "email_confirmation": 24576 Form.error("show", signupEmailConfirmation); 24577 errorNode.appendTo(signupEmailConfirmation.closest("[class*='form-item']")); 24578 break; 24579 24580 case "name": 24581 Form.error("show", signupName); 24582 errorNode.appendTo(signupName.closest("[class*='form-item']")); 24583 break; 24584 24585 case "password": 24586 Form.error("show", signupPassword); 24587 errorNode.appendTo(signupPassword.closest("[class*='form-item']")); 24588 break; 24589 } 24590 } 24591 } 24592 }); 24593 24594 // Remove error message if user is typing 24595 signupInputs.one("keyup", function () { 24596 $(this) 24597 .closest("[class*='form-item']") 24598 .find(".form-item__error-message") 24599 .slideUp("fast", function () { 24600 $(this).remove(); 24601 }); 24602 }); 24603 24604 // Hide loading spinner 24605 Modal.loading.hide(loading); 24606 24607 if (isPledge) { 24608 signupForm.trigger(User.signedUpErrorEvent); 24609 } 24610 } 24611 }, 24612 }); 24613 }, Settings.delay); 24614 } else { 24615 Form.error("show", signupAgreement); 24616 24617 if (isPledge) { 24618 signupForm.trigger(User.signedUpErrorEvent); 24619 } 24620 } 24621 }, 24622 }, 24623 }; 24624 24625 User.init(); 24626 24627 return User; 24628}); 24629/** 24630* Widget 24631* @namespace Verkami 24632* @class Widget 24633*/ 24634 24635var name = 'Verkami/Widget'; 24636var deps = [ 24637 'Verkami/Modal', 24638 'Verkami/Settings' 24639]; 24640 24641modulejs.define(name, deps, function(Modal, Settings) { 24642 var Widget = { 24643 nodes: [], 24644 feedbackDelay: 4000,
24645 horizontalClass: 'modal-embed--horizontal', 24646 verticalClass: 'modal-embed--vertical', 24647 24648 init: function() { 24649 var that = this; 24650 that.nodes = $('.js-widget'); 24651 24652 if (that.nodes.length) { 24653 // Initialize callbacks 24654 that._callbacks(); 24655 24656 that.nodes.each(function() { 24657 that.events($(this)); 24658 }); 24659 } 24660 }, 24661 24662 _callbacks: function() { 24663 var that = this; 24664 24665 $(document).on('trigger.vk.widget.getIframe', function(e) { 24666 that.getIframe(e.modalData); 24667 }); 24668 }, 24669 24670 events: function(node) { 24671 var that = this; 24672 var toggles = $('.js-widget-toggle', node); 24673 var copy = $('.js-widget-copy', node); 24674 var feedback = $('.js-widget-feedback', node); 24675 24676 // Toggle widget orientation 24677 toggles.on('click', function() { 24678 var orientation = $(this).data('widget-orientation'); 24679 24680 that.toggle(orientation, node); 24681 }); 24682 24683 // Copy widget code to clipboard 24684 new Clipboard(copy[0], { 24685 text: function(trigger) { 24686 var markUp = ''; 24687 var modalId = node.closest('.js-modal').data('modal-id'); 24688 24689 if (node.hasClass(that.horizontalClass)) { 24690 markUp = $('#verkamiLandscape', node)[0].outerHTML; 24691 } else if (node.hasClass(that.verticalClass)) { 24692 markUp = $('#verkamiPortrait', node)[0].outerHTML; 24693 } 24694 24695 // @todo: Check if it's possible to avoid the speed attribute 24696 feedback.fadeIn().delay(that.feedbackDelay).fadeOut(Settings.speed, function() { 24697 Modal.hide(modalId, false); 24698 }); 24699 24700 return markUp; 24701 } 24702 }); 24703 }, 24704 24705 getIframe: function(modalData) { 24706 var that = this; 24707 var iframe = []; 24708 var iframeSrc = ''; 24709 var modal = Modal.get(modalData.modalTrigger); 24710 24711 $('.js-widget-iframe', modal).each(function() { 24712 iframe = $(this); 24713 iframeSrc = iframe.attr('data-widget-src'); 24714 24715 if (iframe.attr('src') !== iframeSrc) { 24716 iframe.attr('src', iframeSrc); 24717 24718 // Clean up iframe data 24719 iframe.removeAttr('data-widget-src'); 24720 } 24721 }); 24722 }, 24723 24724 toggle: function(orientation, node) { 24725 var that = this; 24726 var modalId = node.closest('.js-modal').data('modal-id'); 24727 24728 switch (orientation) { 24729 case 'horizontal': 24730 node.removeClass(that.verticalClass) 24731 .addClass(that.horizontalClass) 24732 .closest('.js-modal') 24733 .addClass('modal--xl'); 24734 break; 24735 case 'vertical': 24736 node.removeClass(that.horizontalClass) 24737 .addClass(that.verticalClass) 24738 .closest('.js-modal') 24739 .removeClass('modal--xl'); 24740 break; 24741 } 24742 24743 setTimeout(function() { 24744 Modal.setup(modalId); 24745 }, Settings.speed); 24746 } 24747 }; 24748 24749 Widget.init(); 24750 24751 return Widget; 24752}); 24753/** 24754 * YearInReview 24755 * @namespace Verkami 24756 * @class YearInReview 24757 */ 24758 24759var name = "Verkami/YearInReview"; 24760var deps = ["Verkami/CookiesAgreement"]; 24761 24762modulejs.define(name, deps, function(CookiesAgreement) { 24763 var YearInReview = { 24764 node: [], 24765 cookieName: "", 24766 cookie: "", 24767 close: [], 24768 hiddenClass: "year-in-review--hidden", 24769 24770 init: function() { 24771 var that = this; 24772 that.node = $(".js-year-in-review"); 24773 24774 if (that.node.length) { 24775 that.cookieName = that.node.attr("data-year-in-review-cookie"); 24776 that.cookie = Cookies.get(that.cookieName); 24777 24778 if (that.cookie) { 24779 that.node.addClass(that.hiddenClass); 24780 } else { 24781 that.close = $(".js-year-in-review-close", that.node); 24782 24783 that.close.on("click", function() { 24784 that.node.addClass(that.hiddenClass); 24785 24786 if (CookiesAgreement.cookie) { 24787 // @todo: Make Cookies plugin a dependency 24788 Cookies.set(that.cookieName, "true", { expires: 365 }); 24789 } 24790 }); 24791 } 24792 } 24793 } 24794 }; 24795 24796 YearInReview.init(); 24797 24798 return YearInReview; 24799}); 24800 24801 24802 24803/** 24804 * ModuleJS (JS dependency manager) 24805 */ 24806 24807 24808/** 24809 * Load third party plugins 24810 * Note: jQuery is a global dependency and it's loaded separately 24811 */ 24812 24813 24814 24815 24816 24817 24818 24819 24820 24821 24822 24823 24824 24825 24826 24827 24828 24829 24830 24831 24832 24833/** 24834 * Load Verkami utils, components and modules 24835 */ 24836 24837 24838 24839 24840/**
24841 * Set up Verkami dependencies sorted by name 24842 * 24843 * Note: Dependencies are managed in each module 24844 */ 24845function VerkamiApp() { 24846 // Load utils 24847 modulejs.require("Verkami/Async"); 24848 modulejs.require("Verkami/DataTransfer"); 24849 modulejs.require("Verkami/DropCap"); 24850 modulejs.require("Verkami/Scroll"); 24851 modulejs.require("Verkami/Settings"); 24852 modulejs.require("Verkami/Utils"); 24853 24854 // Load components 24855 modulejs.require("Verkami/Autocomplete"); 24856 modulejs.require("Verkami/Bar"); 24857 modulejs.require("Verkami/ColorPicker"); 24858 modulejs.require("Verkami/Dropdown"); 24859 modulejs.require("Verkami/Fak"); 24860 modulejs.require("Verkami/Faq"); 24861 modulejs.require("Verkami/Form"); 24862 modulejs.require("Verkami/Modal"); 24863 modulejs.require("Verkami/PopUp"); 24864 modulejs.require("Verkami/ReadMore"); 24865 modulejs.require("Verkami/Share"); 24866 modulejs.require("Verkami/Sticky"); 24867 modulejs.require("Verkami/Switcher"); 24868 modulejs.require("Verkami/Tabs"); 24869 modulejs.require("Verkami/Toggle"); 24870 modulejs.require("Verkami/Url"); 24871 modulejs.require("Verkami/Video"); 24872 24873 // Load modules 24874 modulejs.require("Verkami/Auth"); 24875 modulejs.require("Verkami/Avatar"); 24876 modulejs.require("Verkami/Backers"); 24877 modulejs.require("Verkami/BlogBar"); 24878 modulejs.require("Verkami/BlogNavigation"); 24879 modulejs.require("Verkami/Cards"); 24880 modulejs.require("Verkami/Carousel"); 24881 modulejs.require("Verkami/Checkout"); 24882 modulejs.require("Verkami/Comment"); 24883 modulejs.require("Verkami/Comments"); 24884 modulejs.require("Verkami/Community"); 24885 modulejs.require("Verkami/CookiesAgreement"); 24886 modulejs.require("Verkami/Filters"); 24887 modulejs.require("Verkami/Flash"); 24888 modulejs.require("Verkami/Follow"); 24889 modulejs.require("Verkami/Footer"); 24890 modulejs.require("Verkami/Hero"); 24891 modulejs.require("Verkami/IEWarning"); 24892 modulejs.require("Verkami/Navigation"); 24893 modulejs.require("Verkami/Paginator"); 24894 modulejs.require("Verkami/Panels"); 24895 modulejs.require("Verkami/PartnerFollow"); 24896 modulejs.require("Verkami/Password"); 24897 modulejs.require("Verkami/Player"); 24898 modulejs.require("Verkami/Pledge"); 24899 modulejs.require("Verkami/PledgeHigh"); 24900 modulejs.require("Verkami/PledgePayments"); 24901 modulejs.require("Verkami/Project"); 24902 modulejs.require("Verkami/ProjectHero"); 24903 modulejs.require("Verkami/Question"); 24904 modulejs.require("Verkami/Search"); 24905 modulejs.require("Verkami/SettingsNotifications");
24906 modulejs.require("Verkami/SettingsSubscriptions"); 24907 modulejs.require("Verkami/SocialManage"); 24908 modulejs.require("Verkami/Start"); 24909 modulejs.require("Verkami/StartRewards"); 24910 modulejs.require("Verkami/Subscribe"); 24911 modulejs.require("Verkami/User"); 24912 modulejs.require("Verkami/Widget"); 24913 modulejs.require("Verkami/YearInReview"); 24914 modulejs.require("Verkami/Promotion"); 24915 modulejs.require("Verkami/SurveyBillingShipping"); 24916} 24917 24918function LoadVerkamiCaptcha() { 24919 console.log("[CAPTCHA] Enabling captcha system."); 24920 var captcha = modulejs.require("Verkami/Captcha"); 24921 captcha.init(); 24922} 24923/** 24924 * Initialize Verkami JS on loading 24925 */ 24926$(function () { 24927 // We could expose the modules here like window.Verkami = { module: "require_here", }; 24928 VerkamiApp(); 24929});
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.