1/*!
2 * jQuery JavaScript Library v1.12.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright jQuery Foundation and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2016-05-20T17:17Z
13 */
14
15(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//"use strict";
45var deletedIds = [];
46
47var document = window.document;
48
49var slice = deletedIds.slice;
50
51var concat = deletedIds.concat;
52
53var push = deletedIds.push;
54
55var indexOf = deletedIds.indexOf;
56
57var class2type = {};
58
59var toString = class2type.toString;
60
61var hasOwn = class2type.hasOwnProperty;
62
63var support = {};
64
65
66
67var
68 version = "1.12.4",
69
70 // Define a local copy of jQuery
71 jQuery = function( selector, context ) {
72
73 // The jQuery object is actually just the init constructor 'enhanced'
74 // Need init if jQuery is called (just allow error to be thrown if not included)
75 return new jQuery.fn.init( selector, context );
76 },
77
78 // Support: Android<4.1, IE<9
79 // Make sure we trim BOM and NBSP
80 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
81
82 // Matches dashed string for camelizing
83 rmsPrefix = /^-ms-/,
84 rdashAlpha = /-([\da-z])/gi,
85
86 // Used by jQuery.camelCase as callback to replace()
87 fcamelCase = function( all, letter ) {
88 return letter.toUpperCase();
89 };
90
91jQuery.fn = jQuery.prototype = {
92
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 each: function( callback ) {
137 return jQuery.each( this, callback );
138 },
139
140 map: function( callback ) {
141 return this.pushStack( jQuery.map( this, function( elem, i ) {
142 return callback.call( elem, i, elem );
143 } ) );
144 },
145
146 slice: function() {
147 return this.pushStack( slice.apply( this, arguments ) );
148 },
149
150 first: function() {
151 return this.eq( 0 );
152 },
153
154 last: function() {
155 return this.eq( -1 );
156 },
157
158 eq: function( i ) {
159 var len = this.length,
160 j = +i + ( i < 0 ? len : 0 );
161 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
162 },
163
164 end: function() {
165 return this.prevObject || this.constructor();
166 },
167
168 // For internal use only.
169 // Behaves like an Array's method, not like a jQuery method.
170 push: push,
171 sort: deletedIds.sort,
172 splice: deletedIds.splice
173};
174
175jQuery.extend = jQuery.fn.extend = function() {
176 var src, copyIsArray, copy, name, options, clone,
177 target = arguments[ 0 ] || {},
178 i = 1,
179 length = arguments.length,
180 deep = false;
181
182 // Handle a deep copy situation
183 if ( typeof target === "boolean" ) {
184 deep = target;
185
186 // skip the boolean and the target
187 target = arguments[ i ] || {};
188 i++;
189 }
190
191 // Handle case when target is a string or something (possible in deep copy)
192 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
193 target = {};
194 }
195
196 // extend jQuery itself if only one argument is passed
197 if ( i === length ) {
198 target = this;
199 i--;
200 }
201
202 for ( ; i < length; i++ ) {
203
204 // Only deal with non-null/undefined values
205 if ( ( options = arguments[ i ] ) != null ) {
206
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 ) ||
219 ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
220
221 if ( copyIsArray ) {
222 copyIsArray = false;
223 clone = src && jQuery.isArray( src ) ? src : [];
224
225 } else {
226 clone = src && jQuery.isPlainObject( src ) ? src : {};
227 }
228
229 // Never move original objects, clone them
230 target[ name ] = jQuery.extend( deep, clone, copy );
231
232 // Don't bring in undefined values
233 } else if ( copy !== undefined ) {
234 target[ name ] = copy;
235 }
236 }
237 }
238 }
239
240 // Return the modified object
241 return target;
242};
243
244jQuery.extend( {
245
246 // Unique for each copy of jQuery on the page
247 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
248
249 // Assume jQuery is ready without the ready module
250 isReady: true,
251
252 error: function( msg ) {
253 throw new Error( msg );
254 },
255
256 noop: function() {},
257
258 // See test/unit/core.js for details concerning isFunction.
259 // Since version 1.3, DOM methods and functions like alert
260 // aren't supported. They return false on IE (#2968).
261 isFunction: function( obj ) {
262 return jQuery.type( obj ) === "function";
263 },
264
265 isArray: Array.isArray || function( obj ) {
266 return jQuery.type( obj ) === "array";
267 },
268
269 isWindow: function( obj ) {
270 /* jshint eqeqeq: false */
271 return obj != null && obj == obj.window;
272 },
273
274 isNumeric: function( obj ) {
275
276 // parseFloat NaNs numeric-cast false positives (null|true|false|"")
277 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
278 // subtraction forces infinities to NaN
279 // adding 1 corrects loss of precision from parseFloat (#15100)
280 var realStringObj = obj && obj.toString();
281 return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
282 },
283
284 isEmptyObject: function( obj ) {
285 var name;
286 for ( name in obj ) {
287 return false;
288 }
289 return true;
290 },
291
292 isPlainObject: function( obj ) {
293 var key;
294
295 // Must be an Object.
296 // Because of IE, we also have to check the presence of the constructor property.
297 // Make sure that DOM nodes and window objects don't pass through, as well
298 if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
299 return false;
300 }
301
302 try {
303
304 // Not own constructor property must be Object
305 if ( obj.constructor &&
306 !hasOwn.call( obj, "constructor" ) &&
307 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
308 return false;
309 }
310 } catch ( e ) {
311
312 // IE8,9 Will throw exceptions on certain host objects #9897
313 return false;
314 }
315
316 // Support: IE<9
317 // Handle iteration over inherited properties before own properties.
318 if ( !support.ownFirst ) {
319 for ( key in obj ) {
320 return hasOwn.call( obj, key );
321 }
322 }
323
324 // Own properties are enumerated firstly, so to speed up,
325 // if last one is own, then all properties are own.
326 for ( key in obj ) {}
327
328 return key === undefined || hasOwn.call( obj, key );
329 },
330
331 type: function( obj ) {
332 if ( obj == null ) {
333 return obj + "";
334 }
335 return typeof obj === "object" || typeof obj === "function" ?
336 class2type[ toString.call( obj ) ] || "object" :
337 typeof obj;
338 },
339
340 // Workarounds based on findings by Jim Driscoll
341 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
342 globalEval: function( data ) {
343 if ( data && jQuery.trim( data ) ) {
344
345 // We use execScript on Internet Explorer
346 // We use an anonymous function so that context is window
347 // rather than jQuery in Firefox
348 ( window.execScript || function( data ) {
349 window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
350 } )( data );
351 }
352 },
353
354 // Convert dashed to camelCase; used by the css and data modules
355 // Microsoft forgot to hump their vendor prefix (#9572)
356 camelCase: function( string ) {
357 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
358 },
359
360 nodeName: function( elem, name ) {
361 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
362 },
363
364 each: function( obj, callback ) {
365 var length, i = 0;
366
367 if ( isArrayLike( obj ) ) {
368 length = obj.length;
369 for ( ; i < length; i++ ) {
370 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371 break;
372 }
373 }
374 } else {
375 for ( i in obj ) {
376 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
377 break;
378 }
379 }
380 }
381
382 return obj;
383 },
384
385 // Support: Android<4.1, IE<9
386 trim: function( text ) {
387 return text == null ?
388 "" :
389 ( text + "" ).replace( rtrim, "" );
390 },
391
392 // results is for internal usage only
393 makeArray: function( arr, results ) {
394 var ret = results || [];
395
396 if ( arr != null ) {
397 if ( isArrayLike( Object( arr ) ) ) {
398 jQuery.merge( ret,
399 typeof arr === "string" ?
400 [ arr ] : arr
401 );
402 } else {
403 push.call( ret, arr );
404 }
405 }
406
407 return ret;
408 },
409
410 inArray: function( elem, arr, i ) {
411 var len;
412
413 if ( arr ) {
414 if ( indexOf ) {
415 return indexOf.call( arr, elem, i );
416 }
417
418 len = arr.length;
419 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
420
421 for ( ; i < len; i++ ) {
422
423 // Skip accessing in sparse arrays
424 if ( i in arr && arr[ i ] === elem ) {
425 return i;
426 }
427 }
428 }
429
430 return -1;
431 },
432
433 merge: function( first, second ) {
434 var len = +second.length,
435 j = 0,
436 i = first.length;
437
438 while ( j < len ) {
439 first[ i++ ] = second[ j++ ];
440 }
441
442 // Support: IE<9
443 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
444 if ( len !== len ) {
445 while ( second[ j ] !== undefined ) {
446 first[ i++ ] = second[ j++ ];
447 }
448 }
449
450 first.length = i;
451
452 return first;
453 },
454
455 grep: function( elems, callback, invert ) {
456 var callbackInverse,
457 matches = [],
458 i = 0,
459 length = elems.length,
460 callbackExpect = !invert;
461
462 // Go through the array, only saving the items
463 // that pass the validator function
464 for ( ; i < length; i++ ) {
465 callbackInverse = !callback( elems[ i ], i );
466 if ( callbackInverse !== callbackExpect ) {
467 matches.push( elems[ i ] );
468 }
469 }
470
471 return matches;
472 },
473
474 // arg is for internal usage only
475 map: function( elems, callback, arg ) {
476 var length, value,
477 i = 0,
478 ret = [];
479
480 // Go through the array, translating each of the items to their new values
481 if ( isArrayLike( elems ) ) {
482 length = elems.length;
483 for ( ; i < length; i++ ) {
484 value = callback( elems[ i ], i, arg );
485
486 if ( value != null ) {
487 ret.push( value );
488 }
489 }
490
491 // Go through every key on the object,
492 } else {
493 for ( i in elems ) {
494 value = callback( elems[ i ], i, arg );
495
496 if ( value != null ) {
497 ret.push( value );
498 }
499 }
500 }
501
502 // Flatten any nested arrays
503 return concat.apply( [], ret );
504 },
505
506 // A global GUID counter for objects
507 guid: 1,
508
509 // Bind a function to a context, optionally partially applying any
510 // arguments.
511 proxy: function( fn, context ) {
512 var args, proxy, tmp;
513
514 if ( typeof context === "string" ) {
515 tmp = fn[ context ];
516 context = fn;
517 fn = tmp;
518 }
519
520 // Quick check to determine if target is callable, in the spec
521 // this throws a TypeError, but we will just return undefined.
522 if ( !jQuery.isFunction( fn ) ) {
523 return undefined;
524 }
525
526 // Simulated bind
527 args = slice.call( arguments, 2 );
528 proxy = function() {
529 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
530 };
531
532 // Set the guid of unique handler to the same of original handler, so it can be removed
533 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
534
535 return proxy;
536 },
537
538 now: function() {
539 return +( new Date() );
540 },
541
542 // jQuery.support is not used in Core but other projects attach their
543 // properties to it so it needs to exist.
544 support: support
545} );
546
547// JSHint would error on this code due to the Symbol not being defined in ES5.
548// Defining this global in .jshintrc would create a danger of using the global
549// unguarded in another place, it seems safer to just disable JSHint for these
550// three lines.
551/* jshint ignore: start */
552if ( typeof Symbol === "function" ) {
553 jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
554}
555/* jshint ignore: end */
556
557// Populate the class2type map
558jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
559function( i, name ) {
560 class2type[ "[object " + name + "]" ] = name.toLowerCase();
561} );
562
563function isArrayLike( obj ) {
564
565 // Support: iOS 8.2 (not reproducible in simulator)
566 // `in` check used to prevent JIT error (gh-2145)
567 // hasOwn isn't used here due to false negatives
568 // regarding Nodelist length in IE
569 var length = !!obj && "length" in obj && obj.length,
570 type = jQuery.type( obj );
571
572 if ( type === "function" || jQuery.isWindow( obj ) ) {
573 return false;
574 }
575
576 return type === "array" || length === 0 ||
577 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
578}
579var Sizzle =
580/*!
581 * Sizzle CSS Selector Engine v2.2.1
582 * http://sizzlejs.com/
583 *
584 * Copyright jQuery Foundation and other contributors
585 * Released under the MIT license
586 * http://jquery.org/license
587 *
588 * Date: 2015-10-17
589 */
590(function( window ) {
591
592var i,
593 support,
594 Expr,
595 getText,
596 isXML,
597 tokenize,
598 compile,
599 select,
600 outermostContext,
601 sortInput,
602 hasDuplicate,
603
604 // Local document vars
605 setDocument,
606 document,
607 docElem,
608 documentIsHTML,
609 rbuggyQSA,
610 rbuggyMatches,
611 matches,
612 contains,
613
614 // Instance-specific data
615 expando = "sizzle" + 1 * new Date(),
616 preferredDoc = window.document,
617 dirruns = 0,
618 done = 0,
619 classCache = createCache(),
620 tokenCache = createCache(),
621 compilerCache = createCache(),
622 sortOrder = function( a, b ) {
623 if ( a === b ) {
624 hasDuplicate = true;
625 }
626 return 0;
627 },
628
629 // General-purpose constants
630 MAX_NEGATIVE = 1 << 31,
631
632 // Instance methods
633 hasOwn = ({}).hasOwnProperty,
634 arr = [],
635 pop = arr.pop,
636 push_native = arr.push,
637 push = arr.push,
638 slice = arr.slice,
639 // Use a stripped-down indexOf as it's faster than native
640 // http://jsperf.com/thor-indexof-vs-for/5
641 indexOf = function( list, elem ) {
642 var i = 0,
643 len = list.length;
644 for ( ; i < len; i++ ) {
645 if ( list[i] === elem ) {
646 return i;
647 }
648 }
649 return -1;
650 },
651
652 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
653
654 // Regular expressions
655
656 // http://www.w3.org/TR/css3-selectors/#whitespace
657 whitespace = "[\\x20\\t\\r\\n\\f]",
658
659 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
660 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
661
662 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
663 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
664 // Operator (capture 2)
665 "*([*^$|!~]?=)" + whitespace +
666 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
667 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
668 "*\\]",
669
670 pseudos = ":(" + identifier + ")(?:\\((" +
671 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
672 // 1. quoted (capture 3; capture 4 or capture 5)
673 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
674 // 2. simple (capture 6)
675 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
676 // 3. anything else (capture 2)
677 ".*" +
678 ")\\)|)",
679
680 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
681 rwhitespace = new RegExp( whitespace + "+", "g" ),
682 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
683
684 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
685 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
686
687 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
688
689 rpseudo = new RegExp( pseudos ),
690 ridentifier = new RegExp( "^" + identifier + "$" ),
691
692 matchExpr = {
693 "ID": new RegExp( "^#(" + identifier + ")" ),
694 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
695 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
696 "ATTR": new RegExp( "^" + attributes ),
697 "PSEUDO": new RegExp( "^" + pseudos ),
698 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
699 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
700 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
701 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
702 // For use in libraries implementing .is()
703 // We use this for POS matching in `select`
704 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
705 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
706 },
707
708 rinputs = /^(?:input|select|textarea|button)$/i,
709 rheader = /^h\d$/i,
710
711 rnative = /^[^{]+\{\s*\[native \w/,
712
713 // Easily-parseable/retrievable ID or TAG or CLASS selectors
714 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
715
716 rsibling = /[+~]/,
717 rescape = /'|\\/g,
718
719 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
720 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
721 funescape = function( _, escaped, escapedWhitespace ) {
722 var high = "0x" + escaped - 0x10000;
723 // NaN means non-codepoint
724 // Support: Firefox<24
725 // Workaround erroneous numeric interpretation of +"0x"
726 return high !== high || escapedWhitespace ?
727 escaped :
728 high < 0 ?
729 // BMP codepoint
730 String.fromCharCode( high + 0x10000 ) :
731 // Supplemental Plane codepoint (surrogate pair)
732 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
733 },
734
735 // Used for iframes
736 // See setDocument()
737 // Removing the function wrapper causes a "Permission Denied"
738 // error in IE
739 unloadHandler = function() {
740 setDocument();
741 };
742
743// Optimize for push.apply( _, NodeList )
744try {
745 push.apply(
746 (arr = slice.call( preferredDoc.childNodes )),
747 preferredDoc.childNodes
748 );
749 // Support: Android<4.0
750 // Detect silently failing push.apply
751 arr[ preferredDoc.childNodes.length ].nodeType;
752} catch ( e ) {
753 push = { apply: arr.length ?
754
755 // Leverage slice if possible
756 function( target, els ) {
757 push_native.apply( target, slice.call(els) );
758 } :
759
760 // Support: IE<9
761 // Otherwise append directly
762 function( target, els ) {
763 var j = target.length,
764 i = 0;
765 // Can't trust NodeList.length
766 while ( (target[j++] = els[i++]) ) {}
767 target.length = j - 1;
768 }
769 };
770}
771
772function Sizzle( selector, context, results, seed ) {
773 var m, i, elem, nid, nidselect, match, groups, newSelector,
774 newContext = context && context.ownerDocument,
775
776 // nodeType defaults to 9, since context defaults to document
777 nodeType = context ? context.nodeType : 9;
778
779 results = results || [];
780
781 // Return early from calls with invalid selector or context
782 if ( typeof selector !== "string" || !selector ||
783 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
784
785 return results;
786 }
787
788 // Try to shortcut find operations (as opposed to filters) in HTML documents
789 if ( !seed ) {
790
791 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
792 setDocument( context );
793 }
794 context = context || document;
795
796 if ( documentIsHTML ) {
797
798 // If the selector is sufficiently simple, try using a "get*By*" DOM method
799 // (excepting DocumentFragment context, where the methods don't exist)
800 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
801
802 // ID selector
803 if ( (m = match[1]) ) {
804
805 // Document context
806 if ( nodeType === 9 ) {
807 if ( (elem = context.getElementById( m )) ) {
808
809 // Support: IE, Opera, Webkit
810 // TODO: identify versions
811 // getElementById can match elements by name instead of ID
812 if ( elem.id === m ) {
813 results.push( elem );
814 return results;
815 }
816 } else {
817 return results;
818 }
819
820 // Element context
821 } else {
822
823 // Support: IE, Opera, Webkit
824 // TODO: identify versions
825 // getElementById can match elements by name instead of ID
826 if ( newContext && (elem = newContext.getElementById( m )) &&
827 contains( context, elem ) &&
828 elem.id === m ) {
829
830 results.push( elem );
831 return results;
832 }
833 }
834
835 // Type selector
836 } else if ( match[2] ) {
837 push.apply( results, context.getElementsByTagName( selector ) );
838 return results;
839
840 // Class selector
841 } else if ( (m = match[3]) && support.getElementsByClassName &&
842 context.getElementsByClassName ) {
843
844 push.apply( results, context.getElementsByClassName( m ) );
845 return results;
846 }
847 }
848
849 // Take advantage of querySelectorAll
850 if ( support.qsa &&
851 !compilerCache[ selector + " " ] &&
852 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
853
854 if ( nodeType !== 1 ) {
855 newContext = context;
856 newSelector = selector;
857
858 // qSA looks outside Element context, which is not what we want
859 // Thanks to Andrew Dupont for this workaround technique
860 // Support: IE <=8
861 // Exclude object elements
862 } else if ( context.nodeName.toLowerCase() !== "object" ) {
863
864 // Capture the context ID, setting it first if necessary
865 if ( (nid = context.getAttribute( "id" )) ) {
866 nid = nid.replace( rescape, "\\$&" );
867 } else {
868 context.setAttribute( "id", (nid = expando) );
869 }
870
871 // Prefix every selector in the list
872 groups = tokenize( selector );
873 i = groups.length;
874 nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
875 while ( i-- ) {
876 groups[i] = nidselect + " " + toSelector( groups[i] );
877 }
878 newSelector = groups.join( "," );
879
880 // Expand context for sibling selectors
881 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
882 context;
883 }
884
885 if ( newSelector ) {
886 try {
887 push.apply( results,
888 newContext.querySelectorAll( newSelector )
889 );
890 return results;
891 } catch ( qsaError ) {
892 } finally {
893 if ( nid === expando ) {
894 context.removeAttribute( "id" );
895 }
896 }
897 }
898 }
899 }
900 }
901
902 // All others
903 return select( selector.replace( rtrim, "$1" ), context, results, seed );
904}
905
906/**
907 * Create key-value caches of limited size
908 * @returns {function(string, object)} Returns the Object data after storing it on itself with
909 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
910 * deleting the oldest entry
911 */
912function createCache() {
913 var keys = [];
914
915 function cache( key, value ) {
916 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
917 if ( keys.push( key + " " ) > Expr.cacheLength ) {
918 // Only keep the most recent entries
919 delete cache[ keys.shift() ];
920 }
921 return (cache[ key + " " ] = value);
922 }
923 return cache;
924}
925
926/**
927 * Mark a function for special use by Sizzle
928 * @param {Function} fn The function to mark
929 */
930function markFunction( fn ) {
931 fn[ expando ] = true;
932 return fn;
933}
934
935/**
936 * Support testing using an element
937 * @param {Function} fn Passed the created div and expects a boolean result
938 */
939function assert( fn ) {
940 var div = document.createElement("div");
941
942 try {
943 return !!fn( div );
944 } catch (e) {
945 return false;
946 } finally {
947 // Remove from its parent by default
948 if ( div.parentNode ) {
949 div.parentNode.removeChild( div );
950 }
951 // release memory in IE
952 div = null;
953 }
954}
955
956/**
957 * Adds the same handler for all of the specified attrs
958 * @param {String} attrs Pipe-separated list of attributes
959 * @param {Function} handler The method that will be applied
960 */
961function addHandle( attrs, handler ) {
962 var arr = attrs.split("|"),
963 i = arr.length;
964
965 while ( i-- ) {
966 Expr.attrHandle[ arr[i] ] = handler;
967 }
968}
969
970/**
971 * Checks document order of two siblings
972 * @param {Element} a
973 * @param {Element} b
974 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
975 */
976function siblingCheck( a, b ) {
977 var cur = b && a,
978 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
979 ( ~b.sourceIndex || MAX_NEGATIVE ) -
980 ( ~a.sourceIndex || MAX_NEGATIVE );
981
982 // Use IE sourceIndex if available on both nodes
983 if ( diff ) {
984 return diff;
985 }
986
987 // Check if b follows a
988 if ( cur ) {
989 while ( (cur = cur.nextSibling) ) {
990 if ( cur === b ) {
991 return -1;
992 }
993 }
994 }
995
996 return a ? 1 : -1;
997}
998
999/**
1000 * Returns a function to use in pseudos for input types
1001 * @param {String} type
1002 */
1003function createInputPseudo( type ) {
1004 return function( elem ) {
1005 var name = elem.nodeName.toLowerCase();
1006 return name === "input" && elem.type === type;
1007 };
1008}
1009
1010/**
1011 * Returns a function to use in pseudos for buttons
1012 * @param {String} type
1013 */
1014function createButtonPseudo( type ) {
1015 return function( elem ) {
1016 var name = elem.nodeName.toLowerCase();
1017 return (name === "input" || name === "button") && elem.type === type;
1018 };
1019}
1020
1021/**
1022 * Returns a function to use in pseudos for positionals
1023 * @param {Function} fn
1024 */
1025function createPositionalPseudo( fn ) {
1026 return markFunction(function( argument ) {
1027 argument = +argument;
1028 return markFunction(function( seed, matches ) {
1029 var j,
1030 matchIndexes = fn( [], seed.length, argument ),
1031 i = matchIndexes.length;
1032
1033 // Match elements found at the specified indexes
1034 while ( i-- ) {
1035 if ( seed[ (j = matchIndexes[i]) ] ) {
1036 seed[j] = !(matches[j] = seed[j]);
1037 }
1038 }
1039 });
1040 });
1041}
1042
1043/**
1044 * Checks a node for validity as a Sizzle context
1045 * @param {Element|Object=} context
1046 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1047 */
1048function testContext( context ) {
1049 return context && typeof context.getElementsByTagName !== "undefined" && context;
1050}
1051
1052// Expose support vars for convenience
1053support = Sizzle.support = {};
1054
1055/**
1056 * Detects XML nodes
1057 * @param {Element|Object} elem An element or a document
1058 * @returns {Boolean} True iff elem is a non-HTML XML node
1059 */
1060isXML = Sizzle.isXML = function( elem ) {
1061 // documentElement is verified for cases where it doesn't yet exist
1062 // (such as loading iframes in IE - #4833)
1063 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1064 return documentElement ? documentElement.nodeName !== "HTML" : false;
1065};
1066
1067/**
1068 * Sets document-related variables once based on the current document
1069 * @param {Element|Object} [doc] An element or document object to use to set the document
1070 * @returns {Object} Returns the current document
1071 */
1072setDocument = Sizzle.setDocument = function( node ) {
1073 var hasCompare, parent,
1074 doc = node ? node.ownerDocument || node : preferredDoc;
1075
1076 // Return early if doc is invalid or already selected
1077 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1078 return document;
1079 }
1080
1081 // Update global variables
1082 document = doc;
1083 docElem = document.documentElement;
1084 documentIsHTML = !isXML( document );
1085
1086 // Support: IE 9-11, Edge
1087 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1088 if ( (parent = document.defaultView) && parent.top !== parent ) {
1089 // Support: IE 11
1090 if ( parent.addEventListener ) {
1091 parent.addEventListener( "unload", unloadHandler, false );
1092
1093 // Support: IE 9 - 10 only
1094 } else if ( parent.attachEvent ) {
1095 parent.attachEvent( "onunload", unloadHandler );
1096 }
1097 }
1098
1099 /* Attributes
1100 ---------------------------------------------------------------------- */
1101
1102 // Support: IE<8
1103 // Verify that getAttribute really returns attributes and not properties
1104 // (excepting IE8 booleans)
1105 support.attributes = assert(function( div ) {
1106 div.className = "i";
1107 return !div.getAttribute("className");
1108 });
1109
1110 /* getElement(s)By*
1111 ---------------------------------------------------------------------- */
1112
1113 // Check if getElementsByTagName("*") returns only elements
1114 support.getElementsByTagName = assert(function( div ) {
1115 div.appendChild( document.createComment("") );
1116 return !div.getElementsByTagName("*").length;
1117 });
1118
1119 // Support: IE<9
1120 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1121
1122 // Support: IE<10
1123 // Check if getElementById returns elements by name
1124 // The broken getElementById methods don't pick up programatically-set names,
1125 // so use a roundabout getElementsByName test
1126 support.getById = assert(function( div ) {
1127 docElem.appendChild( div ).id = expando;
1128 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1129 });
1130
1131 // ID find and filter
1132 if ( support.getById ) {
1133 Expr.find["ID"] = function( id, context ) {
1134 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1135 var m = context.getElementById( id );
1136 return m ? [ m ] : [];
1137 }
1138 };
1139 Expr.filter["ID"] = function( id ) {
1140 var attrId = id.replace( runescape, funescape );
1141 return function( elem ) {
1142 return elem.getAttribute("id") === attrId;
1143 };
1144 };
1145 } else {
1146 // Support: IE6/7
1147 // getElementById is not reliable as a find shortcut
1148 delete Expr.find["ID"];
1149
1150 Expr.filter["ID"] = function( id ) {
1151 var attrId = id.replace( runescape, funescape );
1152 return function( elem ) {
1153 var node = typeof elem.getAttributeNode !== "undefined" &&
1154 elem.getAttributeNode("id");
1155 return node && node.value === attrId;
1156 };
1157 };
1158 }
1159
1160 // Tag
1161 Expr.find["TAG"] = support.getElementsByTagName ?
1162 function( tag, context ) {
1163 if ( typeof context.getElementsByTagName !== "undefined" ) {
1164 return context.getElementsByTagName( tag );
1165
1166 // DocumentFragment nodes don't have gEBTN
1167 } else if ( support.qsa ) {
1168 return context.querySelectorAll( tag );
1169 }
1170 } :
1171
1172 function( tag, context ) {
1173 var elem,
1174 tmp = [],
1175 i = 0,
1176 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1177 results = context.getElementsByTagName( tag );
1178
1179 // Filter out possible comments
1180 if ( tag === "*" ) {
1181 while ( (elem = results[i++]) ) {
1182 if ( elem.nodeType === 1 ) {
1183 tmp.push( elem );
1184 }
1185 }
1186
1187 return tmp;
1188 }
1189 return results;
1190 };
1191
1192 // Class
1193 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1194 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1195 return context.getElementsByClassName( className );
1196 }
1197 };
1198
1199 /* QSA/matchesSelector
1200 ---------------------------------------------------------------------- */
1201
1202 // QSA and matchesSelector support
1203
1204 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1205 rbuggyMatches = [];
1206
1207 // qSa(:focus) reports false when true (Chrome 21)
1208 // We allow this because of a bug in IE8/9 that throws an error
1209 // whenever `document.activeElement` is accessed on an iframe
1210 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1211 // See http://bugs.jquery.com/ticket/13378
1212 rbuggyQSA = [];
1213
1214 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1215 // Build QSA regex
1216 // Regex strategy adopted from Diego Perini
1217 assert(function( div ) {
1218 // Select is set to empty string on purpose
1219 // This is to test IE's treatment of not explicitly
1220 // setting a boolean content attribute,
1221 // since its presence should be enough
1222 // http://bugs.jquery.com/ticket/12359
1223 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1224 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1225 "<option selected=''></option></select>";
1226
1227 // Support: IE8, Opera 11-12.16
1228 // Nothing should be selected when empty strings follow ^= or $= or *=
1229 // The test attribute must be unknown in Opera but "safe" for WinRT
1230 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1231 if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1232 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1233 }
1234
1235 // Support: IE8
1236 // Boolean attributes and "value" are not treated correctly
1237 if ( !div.querySelectorAll("[selected]").length ) {
1238 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1239 }
1240
1241 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1242 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1243 rbuggyQSA.push("~=");
1244 }
1245
1246 // Webkit/Opera - :checked should return selected option elements
1247 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1248 // IE8 throws error here and will not see later tests
1249 if ( !div.querySelectorAll(":checked").length ) {
1250 rbuggyQSA.push(":checked");
1251 }
1252
1253 // Support: Safari 8+, iOS 8+
1254 // https://bugs.webkit.org/show_bug.cgi?id=136851
1255 // In-page `selector#id sibing-combinator selector` fails
1256 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1257 rbuggyQSA.push(".#.+[+~]");
1258 }
1259 });
1260
1261 assert(function( div ) {
1262 // Support: Windows 8 Native Apps
1263 // The type and name attributes are restricted during .innerHTML assignment
1264 var input = document.createElement("input");
1265 input.setAttribute( "type", "hidden" );
1266 div.appendChild( input ).setAttribute( "name", "D" );
1267
1268 // Support: IE8
1269 // Enforce case-sensitivity of name attribute
1270 if ( div.querySelectorAll("[name=d]").length ) {
1271 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1272 }
1273
1274 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1275 // IE8 throws error here and will not see later tests
1276 if ( !div.querySelectorAll(":enabled").length ) {
1277 rbuggyQSA.push( ":enabled", ":disabled" );
1278 }
1279
1280 // Opera 10-11 does not throw on post-comma invalid pseudos
1281 div.querySelectorAll("*,:x");
1282 rbuggyQSA.push(",.*:");
1283 });
1284 }
1285
1286 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1287 docElem.webkitMatchesSelector ||
1288 docElem.mozMatchesSelector ||
1289 docElem.oMatchesSelector ||
1290 docElem.msMatchesSelector) )) ) {
1291
1292 assert(function( div ) {
1293 // Check to see if it's possible to do matchesSelector
1294 // on a disconnected node (IE 9)
1295 support.disconnectedMatch = matches.call( div, "div" );
1296
1297 // This should fail with an exception
1298 // Gecko does not error, returns false instead
1299 matches.call( div, "[s!='']:x" );
1300 rbuggyMatches.push( "!=", pseudos );
1301 });
1302 }
1303
1304 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1305 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1306
1307 /* Contains
1308 ---------------------------------------------------------------------- */
1309 hasCompare = rnative.test( docElem.compareDocumentPosition );
1310
1311 // Element contains another
1312 // Purposefully self-exclusive
1313 // As in, an element does not contain itself
1314 contains = hasCompare || rnative.test( docElem.contains ) ?
1315 function( a, b ) {
1316 var adown = a.nodeType === 9 ? a.documentElement : a,
1317 bup = b && b.parentNode;
1318 return a === bup || !!( bup && bup.nodeType === 1 && (
1319 adown.contains ?
1320 adown.contains( bup ) :
1321 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1322 ));
1323 } :
1324 function( a, b ) {
1325 if ( b ) {
1326 while ( (b = b.parentNode) ) {
1327 if ( b === a ) {
1328 return true;
1329 }
1330 }
1331 }
1332 return false;
1333 };
1334
1335 /* Sorting
1336 ---------------------------------------------------------------------- */
1337
1338 // Document order sorting
1339 sortOrder = hasCompare ?
1340 function( a, b ) {
1341
1342 // Flag for duplicate removal
1343 if ( a === b ) {
1344 hasDuplicate = true;
1345 return 0;
1346 }
1347
1348 // Sort on method existence if only one input has compareDocumentPosition
1349 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1350 if ( compare ) {
1351 return compare;
1352 }
1353
1354 // Calculate position if both inputs belong to the same document
1355 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1356 a.compareDocumentPosition( b ) :
1357
1358 // Otherwise we know they are disconnected
1359 1;
1360
1361 // Disconnected nodes
1362 if ( compare & 1 ||
1363 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1364
1365 // Choose the first element that is related to our preferred document
1366 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1367 return -1;
1368 }
1369 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1370 return 1;
1371 }
1372
1373 // Maintain original order
1374 return sortInput ?
1375 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1376 0;
1377 }
1378
1379 return compare & 4 ? -1 : 1;
1380 } :
1381 function( a, b ) {
1382 // Exit early if the nodes are identical
1383 if ( a === b ) {
1384 hasDuplicate = true;
1385 return 0;
1386 }
1387
1388 var cur,
1389 i = 0,
1390 aup = a.parentNode,
1391 bup = b.parentNode,
1392 ap = [ a ],
1393 bp = [ b ];
1394
1395 // Parentless nodes are either documents or disconnected
1396 if ( !aup || !bup ) {
1397 return a === document ? -1 :
1398 b === document ? 1 :
1399 aup ? -1 :
1400 bup ? 1 :
1401 sortInput ?
1402 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1403 0;
1404
1405 // If the nodes are siblings, we can do a quick check
1406 } else if ( aup === bup ) {
1407 return siblingCheck( a, b );
1408 }
1409
1410 // Otherwise we need full lists of their ancestors for comparison
1411 cur = a;
1412 while ( (cur = cur.parentNode) ) {
1413 ap.unshift( cur );
1414 }
1415 cur = b;
1416 while ( (cur = cur.parentNode) ) {
1417 bp.unshift( cur );
1418 }
1419
1420 // Walk down the tree looking for a discrepancy
1421 while ( ap[i] === bp[i] ) {
1422 i++;
1423 }
1424
1425 return i ?
1426 // Do a sibling check if the nodes have a common ancestor
1427 siblingCheck( ap[i], bp[i] ) :
1428
1429 // Otherwise nodes in our document sort first
1430 ap[i] === preferredDoc ? -1 :
1431 bp[i] === preferredDoc ? 1 :
1432 0;
1433 };
1434
1435 return document;
1436};
1437
1438Sizzle.matches = function( expr, elements ) {
1439 return Sizzle( expr, null, null, elements );
1440};
1441
1442Sizzle.matchesSelector = function( elem, expr ) {
1443 // Set document vars if needed
1444 if ( ( elem.ownerDocument || elem ) !== document ) {
1445 setDocument( elem );
1446 }
1447
1448 // Make sure that attribute selectors are quoted
1449 expr = expr.replace( rattributeQuotes, "='$1']" );
1450
1451 if ( support.matchesSelector && documentIsHTML &&
1452 !compilerCache[ expr + " " ] &&
1453 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1454 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1455
1456 try {
1457 var ret = matches.call( elem, expr );
1458
1459 // IE 9's matchesSelector returns false on disconnected nodes
1460 if ( ret || support.disconnectedMatch ||
1461 // As well, disconnected nodes are said to be in a document
1462 // fragment in IE 9
1463 elem.document && elem.document.nodeType !== 11 ) {
1464 return ret;
1465 }
1466 } catch (e) {}
1467 }
1468
1469 return Sizzle( expr, document, null, [ elem ] ).length > 0;
1470};
1471
1472Sizzle.contains = function( context, elem ) {
1473 // Set document vars if needed
1474 if ( ( context.ownerDocument || context ) !== document ) {
1475 setDocument( context );
1476 }
1477 return contains( context, elem );
1478};
1479
1480Sizzle.attr = function( elem, name ) {
1481 // Set document vars if needed
1482 if ( ( elem.ownerDocument || elem ) !== document ) {
1483 setDocument( elem );
1484 }
1485
1486 var fn = Expr.attrHandle[ name.toLowerCase() ],
1487 // Don't get fooled by Object.prototype properties (jQuery #13807)
1488 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1489 fn( elem, name, !documentIsHTML ) :
1490 undefined;
1491
1492 return val !== undefined ?
1493 val :
1494 support.attributes || !documentIsHTML ?
1495 elem.getAttribute( name ) :
1496 (val = elem.getAttributeNode(name)) && val.specified ?
1497 val.value :
1498 null;
1499};
1500
1501Sizzle.error = function( msg ) {
1502 throw new Error( "Syntax error, unrecognized expression: " + msg );
1503};
1504
1505/**
1506 * Document sorting and removing duplicates
1507 * @param {ArrayLike} results
1508 */
1509Sizzle.uniqueSort = function( results ) {
1510 var elem,
1511 duplicates = [],
1512 j = 0,
1513 i = 0;
1514
1515 // Unless we *know* we can detect duplicates, assume their presence
1516 hasDuplicate = !support.detectDuplicates;
1517 sortInput = !support.sortStable && results.slice( 0 );
1518 results.sort( sortOrder );
1519
1520 if ( hasDuplicate ) {
1521 while ( (elem = results[i++]) ) {
1522 if ( elem === results[ i ] ) {
1523 j = duplicates.push( i );
1524 }
1525 }
1526 while ( j-- ) {
1527 results.splice( duplicates[ j ], 1 );
1528 }
1529 }
1530
1531 // Clear input after sorting to release objects
1532 // See https://github.com/jquery/sizzle/pull/225
1533 sortInput = null;
1534
1535 return results;
1536};
1537
1538/**
1539 * Utility function for retrieving the text value of an array of DOM nodes
1540 * @param {Array|Element} elem
1541 */
1542getText = Sizzle.getText = function( elem ) {
1543 var node,
1544 ret = "",
1545 i = 0,
1546 nodeType = elem.nodeType;
1547
1548 if ( !nodeType ) {
1549 // If no nodeType, this is expected to be an array
1550 while ( (node = elem[i++]) ) {
1551 // Do not traverse comment nodes
1552 ret += getText( node );
1553 }
1554 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1555 // Use textContent for elements
1556 // innerText usage removed for consistency of new lines (jQuery #11153)
1557 if ( typeof elem.textContent === "string" ) {
1558 return elem.textContent;
1559 } else {
1560 // Traverse its children
1561 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1562 ret += getText( elem );
1563 }
1564 }
1565 } else if ( nodeType === 3 || nodeType === 4 ) {
1566 return elem.nodeValue;
1567 }
1568 // Do not include comment or processing instruction nodes
1569
1570 return ret;
1571};
1572
1573Expr = Sizzle.selectors = {
1574
1575 // Can be adjusted by the user
1576 cacheLength: 50,
1577
1578 createPseudo: markFunction,
1579
1580 match: matchExpr,
1581
1582 attrHandle: {},
1583
1584 find: {},
1585
1586 relative: {
1587 ">": { dir: "parentNode", first: true },
1588 " ": { dir: "parentNode" },
1589 "+": { dir: "previousSibling", first: true },
1590 "~": { dir: "previousSibling" }
1591 },
1592
1593 preFilter: {
1594 "ATTR": function( match ) {
1595 match[1] = match[1].replace( runescape, funescape );
1596
1597 // Move the given value to match[3] whether quoted or unquoted
1598 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1599
1600 if ( match[2] === "~=" ) {
1601 match[3] = " " + match[3] + " ";
1602 }
1603
1604 return match.slice( 0, 4 );
1605 },
1606
1607 "CHILD": function( match ) {
1608 /* matches from matchExpr["CHILD"]
1609 1 type (only|nth|...)
1610 2 what (child|of-type)
1611 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1612 4 xn-component of xn+y argument ([+-]?\d*n|)
1613 5 sign of xn-component
1614 6 x of xn-component
1615 7 sign of y-component
1616 8 y of y-component
1617 */
1618 match[1] = match[1].toLowerCase();
1619
1620 if ( match[1].slice( 0, 3 ) === "nth" ) {
1621 // nth-* requires argument
1622 if ( !match[3] ) {
1623 Sizzle.error( match[0] );
1624 }
1625
1626 // numeric x and y parameters for Expr.filter.CHILD
1627 // remember that false/true cast respectively to 0/1
1628 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1629 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1630
1631 // other types prohibit arguments
1632 } else if ( match[3] ) {
1633 Sizzle.error( match[0] );
1634 }
1635
1636 return match;
1637 },
1638
1639 "PSEUDO": function( match ) {
1640 var excess,
1641 unquoted = !match[6] && match[2];
1642
1643 if ( matchExpr["CHILD"].test( match[0] ) ) {
1644 return null;
1645 }
1646
1647 // Accept quoted arguments as-is
1648 if ( match[3] ) {
1649 match[2] = match[4] || match[5] || "";
1650
1651 // Strip excess characters from unquoted arguments
1652 } else if ( unquoted && rpseudo.test( unquoted ) &&
1653 // Get excess from tokenize (recursively)
1654 (excess = tokenize( unquoted, true )) &&
1655 // advance to the next closing parenthesis
1656 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1657
1658 // excess is a negative index
1659 match[0] = match[0].slice( 0, excess );
1660 match[2] = unquoted.slice( 0, excess );
1661 }
1662
1663 // Return only captures needed by the pseudo filter method (type and argument)
1664 return match.slice( 0, 3 );
1665 }
1666 },
1667
1668 filter: {
1669
1670 "TAG": function( nodeNameSelector ) {
1671 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1672 return nodeNameSelector === "*" ?
1673 function() { return true; } :
1674 function( elem ) {
1675 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1676 };
1677 },
1678
1679 "CLASS": function( className ) {
1680 var pattern = classCache[ className + " " ];
1681
1682 return pattern ||
1683 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1684 classCache( className, function( elem ) {
1685 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1686 });
1687 },
1688
1689 "ATTR": function( name, operator, check ) {
1690 return function( elem ) {
1691 var result = Sizzle.attr( elem, name );
1692
1693 if ( result == null ) {
1694 return operator === "!=";
1695 }
1696 if ( !operator ) {
1697 return true;
1698 }
1699
1700 result += "";
1701
1702 return operator === "=" ? result === check :
1703 operator === "!=" ? result !== check :
1704 operator === "^=" ? check && result.indexOf( check ) === 0 :
1705 operator === "*=" ? check && result.indexOf( check ) > -1 :
1706 operator === "$=" ? check && result.slice( -check.length ) === check :
1707 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1708 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1709 false;
1710 };
1711 },
1712
1713 "CHILD": function( type, what, argument, first, last ) {
1714 var simple = type.slice( 0, 3 ) !== "nth",
1715 forward = type.slice( -4 ) !== "last",
1716 ofType = what === "of-type";
1717
1718 return first === 1 && last === 0 ?
1719
1720 // Shortcut for :nth-*(n)
1721 function( elem ) {
1722 return !!elem.parentNode;
1723 } :
1724
1725 function( elem, context, xml ) {
1726 var cache, uniqueCache, outerCache, node, nodeIndex, start,
1727 dir = simple !== forward ? "nextSibling" : "previousSibling",
1728 parent = elem.parentNode,
1729 name = ofType && elem.nodeName.toLowerCase(),
1730 useCache = !xml && !ofType,
1731 diff = false;
1732
1733 if ( parent ) {
1734
1735 // :(first|last|only)-(child|of-type)
1736 if ( simple ) {
1737 while ( dir ) {
1738 node = elem;
1739 while ( (node = node[ dir ]) ) {
1740 if ( ofType ?
1741 node.nodeName.toLowerCase() === name :
1742 node.nodeType === 1 ) {
1743
1744 return false;
1745 }
1746 }
1747 // Reverse direction for :only-* (if we haven't yet done so)
1748 start = dir = type === "only" && !start && "nextSibling";
1749 }
1750 return true;
1751 }
1752
1753 start = [ forward ? parent.firstChild : parent.lastChild ];
1754
1755 // non-xml :nth-child(...) stores cache data on `parent`
1756 if ( forward && useCache ) {
1757
1758 // Seek `elem` from a previously-cached index
1759
1760 // ...in a gzip-friendly way
1761 node = parent;
1762 outerCache = node[ expando ] || (node[ expando ] = {});
1763
1764 // Support: IE <9 only
1765 // Defend against cloned attroperties (jQuery gh-1709)
1766 uniqueCache = outerCache[ node.uniqueID ] ||
1767 (outerCache[ node.uniqueID ] = {});
1768
1769 cache = uniqueCache[ type ] || [];
1770 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1771 diff = nodeIndex && cache[ 2 ];
1772 node = nodeIndex && parent.childNodes[ nodeIndex ];
1773
1774 while ( (node = ++nodeIndex && node && node[ dir ] ||
1775
1776 // Fallback to seeking `elem` from the start
1777 (diff = nodeIndex = 0) || start.pop()) ) {
1778
1779 // When found, cache indexes on `parent` and break
1780 if ( node.nodeType === 1 && ++diff && node === elem ) {
1781 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1782 break;
1783 }
1784 }
1785
1786 } else {
1787 // Use previously-cached element index if available
1788 if ( useCache ) {
1789 // ...in a gzip-friendly way
1790 node = elem;
1791 outerCache = node[ expando ] || (node[ expando ] = {});
1792
1793 // Support: IE <9 only
1794 // Defend against cloned attroperties (jQuery gh-1709)
1795 uniqueCache = outerCache[ node.uniqueID ] ||
1796 (outerCache[ node.uniqueID ] = {});
1797
1798 cache = uniqueCache[ type ] || [];
1799 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1800 diff = nodeIndex;
1801 }
1802
1803 // xml :nth-child(...)
1804 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1805 if ( diff === false ) {
1806 // Use the same loop as above to seek `elem` from the start
1807 while ( (node = ++nodeIndex && node && node[ dir ] ||
1808 (diff = nodeIndex = 0) || start.pop()) ) {
1809
1810 if ( ( ofType ?
1811 node.nodeName.toLowerCase() === name :
1812 node.nodeType === 1 ) &&
1813 ++diff ) {
1814
1815 // Cache the index of each encountered element
1816 if ( useCache ) {
1817 outerCache = node[ expando ] || (node[ expando ] = {});
1818
1819 // Support: IE <9 only
1820 // Defend against cloned attroperties (jQuery gh-1709)
1821 uniqueCache = outerCache[ node.uniqueID ] ||
1822 (outerCache[ node.uniqueID ] = {});
1823
1824 uniqueCache[ type ] = [ dirruns, diff ];
1825 }
1826
1827 if ( node === elem ) {
1828 break;
1829 }
1830 }
1831 }
1832 }
1833 }
1834
1835 // Incorporate the offset, then check against cycle size
1836 diff -= last;
1837 return diff === first || ( diff % first === 0 && diff / first >= 0 );
1838 }
1839 };
1840 },
1841
1842 "PSEUDO": function( pseudo, argument ) {
1843 // pseudo-class names are case-insensitive
1844 // http://www.w3.org/TR/selectors/#pseudo-classes
1845 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1846 // Remember that setFilters inherits from pseudos
1847 var args,
1848 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1849 Sizzle.error( "unsupported pseudo: " + pseudo );
1850
1851 // The user may use createPseudo to indicate that
1852 // arguments are needed to create the filter function
1853 // just as Sizzle does
1854 if ( fn[ expando ] ) {
1855 return fn( argument );
1856 }
1857
1858 // But maintain support for old signatures
1859 if ( fn.length > 1 ) {
1860 args = [ pseudo, pseudo, "", argument ];
1861 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1862 markFunction(function( seed, matches ) {
1863 var idx,
1864 matched = fn( seed, argument ),
1865 i = matched.length;
1866 while ( i-- ) {
1867 idx = indexOf( seed, matched[i] );
1868 seed[ idx ] = !( matches[ idx ] = matched[i] );
1869 }
1870 }) :
1871 function( elem ) {
1872 return fn( elem, 0, args );
1873 };
1874 }
1875
1876 return fn;
1877 }
1878 },
1879
1880 pseudos: {
1881 // Potentially complex pseudos
1882 "not": markFunction(function( selector ) {
1883 // Trim the selector passed to compile
1884 // to avoid treating leading and trailing
1885 // spaces as combinators
1886 var input = [],
1887 results = [],
1888 matcher = compile( selector.replace( rtrim, "$1" ) );
1889
1890 return matcher[ expando ] ?
1891 markFunction(function( seed, matches, context, xml ) {
1892 var elem,
1893 unmatched = matcher( seed, null, xml, [] ),
1894 i = seed.length;
1895
1896 // Match elements unmatched by `matcher`
1897 while ( i-- ) {
1898 if ( (elem = unmatched[i]) ) {
1899 seed[i] = !(matches[i] = elem);
1900 }
1901 }
1902 }) :
1903 function( elem, context, xml ) {
1904 input[0] = elem;
1905 matcher( input, null, xml, results );
1906 // Don't keep the element (issue #299)
1907 input[0] = null;
1908 return !results.pop();
1909 };
1910 }),
1911
1912 "has": markFunction(function( selector ) {
1913 return function( elem ) {
1914 return Sizzle( selector, elem ).length > 0;
1915 };
1916 }),
1917
1918 "contains": markFunction(function( text ) {
1919 text = text.replace( runescape, funescape );
1920 return function( elem ) {
1921 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1922 };
1923 }),
1924
1925 // "Whether an element is represented by a :lang() selector
1926 // is based solely on the element's language value
1927 // being equal to the identifier C,
1928 // or beginning with the identifier C immediately followed by "-".
1929 // The matching of C against the element's language value is performed case-insensitively.
1930 // The identifier C does not have to be a valid language name."
1931 // http://www.w3.org/TR/selectors/#lang-pseudo
1932 "lang": markFunction( function( lang ) {
1933 // lang value must be a valid identifier
1934 if ( !ridentifier.test(lang || "") ) {
1935 Sizzle.error( "unsupported lang: " + lang );
1936 }
1937 lang = lang.replace( runescape, funescape ).toLowerCase();
1938 return function( elem ) {
1939 var elemLang;
1940 do {
1941 if ( (elemLang = documentIsHTML ?
1942 elem.lang :
1943 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1944
1945 elemLang = elemLang.toLowerCase();
1946 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1947 }
1948 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1949 return false;
1950 };
1951 }),
1952
1953 // Miscellaneous
1954 "target": function( elem ) {
1955 var hash = window.location && window.location.hash;
1956 return hash && hash.slice( 1 ) === elem.id;
1957 },
1958
1959 "root": function( elem ) {
1960 return elem === docElem;
1961 },
1962
1963 "focus": function( elem ) {
1964 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1965 },
1966
1967 // Boolean properties
1968 "enabled": function( elem ) {
1969 return elem.disabled === false;
1970 },
1971
1972 "disabled": function( elem ) {
1973 return elem.disabled === true;
1974 },
1975
1976 "checked": function( elem ) {
1977 // In CSS3, :checked should return both checked and selected elements
1978 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1979 var nodeName = elem.nodeName.toLowerCase();
1980 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1981 },
1982
1983 "selected": function( elem ) {
1984 // Accessing this property makes selected-by-default
1985 // options in Safari work properly
1986 if ( elem.parentNode ) {
1987 elem.parentNode.selectedIndex;
1988 }
1989
1990 return elem.selected === true;
1991 },
1992
1993 // Contents
1994 "empty": function( elem ) {
1995 // http://www.w3.org/TR/selectors/#empty-pseudo
1996 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1997 // but not by others (comment: 8; processing instruction: 7; etc.)
1998 // nodeType < 6 works because attributes (2) do not appear as children
1999 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2000 if ( elem.nodeType < 6 ) {
2001 return false;
2002 }
2003 }
2004 return true;
2005 },
2006
2007 "parent": function( elem ) {
2008 return !Expr.pseudos["empty"]( elem );
2009 },
2010
2011 // Element/input types
2012 "header": function( elem ) {
2013 return rheader.test( elem.nodeName );
2014 },
2015
2016 "input": function( elem ) {
2017 return rinputs.test( elem.nodeName );
2018 },
2019
2020 "button": function( elem ) {
2021 var name = elem.nodeName.toLowerCase();
2022 return name === "input" && elem.type === "button" || name === "button";
2023 },
2024
2025 "text": function( elem ) {
2026 var attr;
2027 return elem.nodeName.toLowerCase() === "input" &&
2028 elem.type === "text" &&
2029
2030 // Support: IE<8
2031 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2032 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2033 },
2034
2035 // Position-in-collection
2036 "first": createPositionalPseudo(function() {
2037 return [ 0 ];
2038 }),
2039
2040 "last": createPositionalPseudo(function( matchIndexes, length ) {
2041 return [ length - 1 ];
2042 }),
2043
2044 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2045 return [ argument < 0 ? argument + length : argument ];
2046 }),
2047
2048 "even": createPositionalPseudo(function( matchIndexes, length ) {
2049 var i = 0;
2050 for ( ; i < length; i += 2 ) {
2051 matchIndexes.push( i );
2052 }
2053 return matchIndexes;
2054 }),
2055
2056 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2057 var i = 1;
2058 for ( ; i < length; i += 2 ) {
2059 matchIndexes.push( i );
2060 }
2061 return matchIndexes;
2062 }),
2063
2064 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2065 var i = argument < 0 ? argument + length : argument;
2066 for ( ; --i >= 0; ) {
2067 matchIndexes.push( i );
2068 }
2069 return matchIndexes;
2070 }),
2071
2072 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2073 var i = argument < 0 ? argument + length : argument;
2074 for ( ; ++i < length; ) {
2075 matchIndexes.push( i );
2076 }
2077 return matchIndexes;
2078 })
2079 }
2080};
2081
2082Expr.pseudos["nth"] = Expr.pseudos["eq"];
2083
2084// Add button/input type pseudos
2085for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2086 Expr.pseudos[ i ] = createInputPseudo( i );
2087}
2088for ( i in { submit: true, reset: true } ) {
2089 Expr.pseudos[ i ] = createButtonPseudo( i );
2090}
2091
2092// Easy API for creating new setFilters
2093function setFilters() {}
2094setFilters.prototype = Expr.filters = Expr.pseudos;
2095Expr.setFilters = new setFilters();
2096
2097tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2098 var matched, match, tokens, type,
2099 soFar, groups, preFilters,
2100 cached = tokenCache[ selector + " " ];
2101
2102 if ( cached ) {
2103 return parseOnly ? 0 : cached.slice( 0 );
2104 }
2105
2106 soFar = selector;
2107 groups = [];
2108 preFilters = Expr.preFilter;
2109
2110 while ( soFar ) {
2111
2112 // Comma and first run
2113 if ( !matched || (match = rcomma.exec( soFar )) ) {
2114 if ( match ) {
2115 // Don't consume trailing commas as valid
2116 soFar = soFar.slice( match[0].length ) || soFar;
2117 }
2118 groups.push( (tokens = []) );
2119 }
2120
2121 matched = false;
2122
2123 // Combinators
2124 if ( (match = rcombinators.exec( soFar )) ) {
2125 matched = match.shift();
2126 tokens.push({
2127 value: matched,
2128 // Cast descendant combinators to space
2129 type: match[0].replace( rtrim, " " )
2130 });
2131 soFar = soFar.slice( matched.length );
2132 }
2133
2134 // Filters
2135 for ( type in Expr.filter ) {
2136 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2137 (match = preFilters[ type ]( match ))) ) {
2138 matched = match.shift();
2139 tokens.push({
2140 value: matched,
2141 type: type,
2142 matches: match
2143 });
2144 soFar = soFar.slice( matched.length );
2145 }
2146 }
2147
2148 if ( !matched ) {
2149 break;
2150 }
2151 }
2152
2153 // Return the length of the invalid excess
2154 // if we're just parsing
2155 // Otherwise, throw an error or return tokens
2156 return parseOnly ?
2157 soFar.length :
2158 soFar ?
2159 Sizzle.error( selector ) :
2160 // Cache the tokens
2161 tokenCache( selector, groups ).slice( 0 );
2162};
2163
2164function toSelector( tokens ) {
2165 var i = 0,
2166 len = tokens.length,
2167 selector = "";
2168 for ( ; i < len; i++ ) {
2169 selector += tokens[i].value;
2170 }
2171 return selector;
2172}
2173
2174function addCombinator( matcher, combinator, base ) {
2175 var dir = combinator.dir,
2176 checkNonElements = base && dir === "parentNode",
2177 doneName = done++;
2178
2179 return combinator.first ?
2180 // Check against closest ancestor/preceding element
2181 function( elem, context, xml ) {
2182 while ( (elem = elem[ dir ]) ) {
2183 if ( elem.nodeType === 1 || checkNonElements ) {
2184 return matcher( elem, context, xml );
2185 }
2186 }
2187 } :
2188
2189 // Check against all ancestor/preceding elements
2190 function( elem, context, xml ) {
2191 var oldCache, uniqueCache, outerCache,
2192 newCache = [ dirruns, doneName ];
2193
2194 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2195 if ( xml ) {
2196 while ( (elem = elem[ dir ]) ) {
2197 if ( elem.nodeType === 1 || checkNonElements ) {
2198 if ( matcher( elem, context, xml ) ) {
2199 return true;
2200 }
2201 }
2202 }
2203 } else {
2204 while ( (elem = elem[ dir ]) ) {
2205 if ( elem.nodeType === 1 || checkNonElements ) {
2206 outerCache = elem[ expando ] || (elem[ expando ] = {});
2207
2208 // Support: IE <9 only
2209 // Defend against cloned attroperties (jQuery gh-1709)
2210 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2211
2212 if ( (oldCache = uniqueCache[ dir ]) &&
2213 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2214
2215 // Assign to newCache so results back-propagate to previous elements
2216 return (newCache[ 2 ] = oldCache[ 2 ]);
2217 } else {
2218 // Reuse newcache so results back-propagate to previous elements
2219 uniqueCache[ dir ] = newCache;
2220
2221 // A match means we're done; a fail means we have to keep checking
2222 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2223 return true;
2224 }
2225 }
2226 }
2227 }
2228 }
2229 };
2230}
2231
2232function elementMatcher( matchers ) {
2233 return matchers.length > 1 ?
2234 function( elem, context, xml ) {
2235 var i = matchers.length;
2236 while ( i-- ) {
2237 if ( !matchers[i]( elem, context, xml ) ) {
2238 return false;
2239 }
2240 }
2241 return true;
2242 } :
2243 matchers[0];
2244}
2245
2246function multipleContexts( selector, contexts, results ) {
2247 var i = 0,
2248 len = contexts.length;
2249 for ( ; i < len; i++ ) {
2250 Sizzle( selector, contexts[i], results );
2251 }
2252 return results;
2253}
2254
2255function condense( unmatched, map, filter, context, xml ) {
2256 var elem,
2257 newUnmatched = [],
2258 i = 0,
2259 len = unmatched.length,
2260 mapped = map != null;
2261
2262 for ( ; i < len; i++ ) {
2263 if ( (elem = unmatched[i]) ) {
2264 if ( !filter || filter( elem, context, xml ) ) {
2265 newUnmatched.push( elem );
2266 if ( mapped ) {
2267 map.push( i );
2268 }
2269 }
2270 }
2271 }
2272
2273 return newUnmatched;
2274}
2275
2276function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2277 if ( postFilter && !postFilter[ expando ] ) {
2278 postFilter = setMatcher( postFilter );
2279 }
2280 if ( postFinder && !postFinder[ expando ] ) {
2281 postFinder = setMatcher( postFinder, postSelector );
2282 }
2283 return markFunction(function( seed, results, context, xml ) {
2284 var temp, i, elem,
2285 preMap = [],
2286 postMap = [],
2287 preexisting = results.length,
2288
2289 // Get initial elements from seed or context
2290 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2291
2292 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2293 matcherIn = preFilter && ( seed || !selector ) ?
2294 condense( elems, preMap, preFilter, context, xml ) :
2295 elems,
2296
2297 matcherOut = matcher ?
2298 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2299 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2300
2301 // ...intermediate processing is necessary
2302 [] :
2303
2304 // ...otherwise use results directly
2305 results :
2306 matcherIn;
2307
2308 // Find primary matches
2309 if ( matcher ) {
2310 matcher( matcherIn, matcherOut, context, xml );
2311 }
2312
2313 // Apply postFilter
2314 if ( postFilter ) {
2315 temp = condense( matcherOut, postMap );
2316 postFilter( temp, [], context, xml );
2317
2318 // Un-match failing elements by moving them back to matcherIn
2319 i = temp.length;
2320 while ( i-- ) {
2321 if ( (elem = temp[i]) ) {
2322 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2323 }
2324 }
2325 }
2326
2327 if ( seed ) {
2328 if ( postFinder || preFilter ) {
2329 if ( postFinder ) {
2330 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2331 temp = [];
2332 i = matcherOut.length;
2333 while ( i-- ) {
2334 if ( (elem = matcherOut[i]) ) {
2335 // Restore matcherIn since elem is not yet a final match
2336 temp.push( (matcherIn[i] = elem) );
2337 }
2338 }
2339 postFinder( null, (matcherOut = []), temp, xml );
2340 }
2341
2342 // Move matched elements from seed to results to keep them synchronized
2343 i = matcherOut.length;
2344 while ( i-- ) {
2345 if ( (elem = matcherOut[i]) &&
2346 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2347
2348 seed[temp] = !(results[temp] = elem);
2349 }
2350 }
2351 }
2352
2353 // Add elements to results, through postFinder if defined
2354 } else {
2355 matcherOut = condense(
2356 matcherOut === results ?
2357 matcherOut.splice( preexisting, matcherOut.length ) :
2358 matcherOut
2359 );
2360 if ( postFinder ) {
2361 postFinder( null, results, matcherOut, xml );
2362 } else {
2363 push.apply( results, matcherOut );
2364 }
2365 }
2366 });
2367}
2368
2369function matcherFromTokens( tokens ) {
2370 var checkContext, matcher, j,
2371 len = tokens.length,
2372 leadingRelative = Expr.relative[ tokens[0].type ],
2373 implicitRelative = leadingRelative || Expr.relative[" "],
2374 i = leadingRelative ? 1 : 0,
2375
2376 // The foundational matcher ensures that elements are reachable from top-level context(s)
2377 matchContext = addCombinator( function( elem ) {
2378 return elem === checkContext;
2379 }, implicitRelative, true ),
2380 matchAnyContext = addCombinator( function( elem ) {
2381 return indexOf( checkContext, elem ) > -1;
2382 }, implicitRelative, true ),
2383 matchers = [ function( elem, context, xml ) {
2384 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2385 (checkContext = context).nodeType ?
2386 matchContext( elem, context, xml ) :
2387 matchAnyContext( elem, context, xml ) );
2388 // Avoid hanging onto element (issue #299)
2389 checkContext = null;
2390 return ret;
2391 } ];
2392
2393 for ( ; i < len; i++ ) {
2394 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2395 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2396 } else {
2397 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2398
2399 // Return special upon seeing a positional matcher
2400 if ( matcher[ expando ] ) {
2401 // Find the next relative operator (if any) for proper handling
2402 j = ++i;
2403 for ( ; j < len; j++ ) {
2404 if ( Expr.relative[ tokens[j].type ] ) {
2405 break;
2406 }
2407 }
2408 return setMatcher(
2409 i > 1 && elementMatcher( matchers ),
2410 i > 1 && toSelector(
2411 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2412 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2413 ).replace( rtrim, "$1" ),
2414 matcher,
2415 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2416 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2417 j < len && toSelector( tokens )
2418 );
2419 }
2420 matchers.push( matcher );
2421 }
2422 }
2423
2424 return elementMatcher( matchers );
2425}
2426
2427function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2428 var bySet = setMatchers.length > 0,
2429 byElement = elementMatchers.length > 0,
2430 superMatcher = function( seed, context, xml, results, outermost ) {
2431 var elem, j, matcher,
2432 matchedCount = 0,
2433 i = "0",
2434 unmatched = seed && [],
2435 setMatched = [],
2436 contextBackup = outermostContext,
2437 // We must always have either seed elements or outermost context
2438 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2439 // Use integer dirruns iff this is the outermost matcher
2440 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2441 len = elems.length;
2442
2443 if ( outermost ) {
2444 outermostContext = context === document || context || outermost;
2445 }
2446
2447 // Add elements passing elementMatchers directly to results
2448 // Support: IE<9, Safari
2449 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2450 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2451 if ( byElement && elem ) {
2452 j = 0;
2453 if ( !context && elem.ownerDocument !== document ) {
2454 setDocument( elem );
2455 xml = !documentIsHTML;
2456 }
2457 while ( (matcher = elementMatchers[j++]) ) {
2458 if ( matcher( elem, context || document, xml) ) {
2459 results.push( elem );
2460 break;
2461 }
2462 }
2463 if ( outermost ) {
2464 dirruns = dirrunsUnique;
2465 }
2466 }
2467
2468 // Track unmatched elements for set filters
2469 if ( bySet ) {
2470 // They will have gone through all possible matchers
2471 if ( (elem = !matcher && elem) ) {
2472 matchedCount--;
2473 }
2474
2475 // Lengthen the array for every element, matched or not
2476 if ( seed ) {
2477 unmatched.push( elem );
2478 }
2479 }
2480 }
2481
2482 // `i` is now the count of elements visited above, and adding it to `matchedCount`
2483 // makes the latter nonnegative.
2484 matchedCount += i;
2485
2486 // Apply set filters to unmatched elements
2487 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2488 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2489 // no element matchers and no seed.
2490 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2491 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2492 // numerically zero.
2493 if ( bySet && i !== matchedCount ) {
2494 j = 0;
2495 while ( (matcher = setMatchers[j++]) ) {
2496 matcher( unmatched, setMatched, context, xml );
2497 }
2498
2499 if ( seed ) {
2500 // Reintegrate element matches to eliminate the need for sorting
2501 if ( matchedCount > 0 ) {
2502 while ( i-- ) {
2503 if ( !(unmatched[i] || setMatched[i]) ) {
2504 setMatched[i] = pop.call( results );
2505 }
2506 }
2507 }
2508
2509 // Discard index placeholder values to get only actual matches
2510 setMatched = condense( setMatched );
2511 }
2512
2513 // Add matches to results
2514 push.apply( results, setMatched );
2515
2516 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2517 if ( outermost && !seed && setMatched.length > 0 &&
2518 ( matchedCount + setMatchers.length ) > 1 ) {
2519
2520 Sizzle.uniqueSort( results );
2521 }
2522 }
2523
2524 // Override manipulation of globals by nested matchers
2525 if ( outermost ) {
2526 dirruns = dirrunsUnique;
2527 outermostContext = contextBackup;
2528 }
2529
2530 return unmatched;
2531 };
2532
2533 return bySet ?
2534 markFunction( superMatcher ) :
2535 superMatcher;
2536}
2537
2538compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2539 var i,
2540 setMatchers = [],
2541 elementMatchers = [],
2542 cached = compilerCache[ selector + " " ];
2543
2544 if ( !cached ) {
2545 // Generate a function of recursive functions that can be used to check each element
2546 if ( !match ) {
2547 match = tokenize( selector );
2548 }
2549 i = match.length;
2550 while ( i-- ) {
2551 cached = matcherFromTokens( match[i] );
2552 if ( cached[ expando ] ) {
2553 setMatchers.push( cached );
2554 } else {
2555 elementMatchers.push( cached );
2556 }
2557 }
2558
2559 // Cache the compiled function
2560 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2561
2562 // Save selector and tokenization
2563 cached.selector = selector;
2564 }
2565 return cached;
2566};
2567
2568/**
2569 * A low-level selection function that works with Sizzle's compiled
2570 * selector functions
2571 * @param {String|Function} selector A selector or a pre-compiled
2572 * selector function built with Sizzle.compile
2573 * @param {Element} context
2574 * @param {Array} [results]
2575 * @param {Array} [seed] A set of elements to match against
2576 */
2577select = Sizzle.select = function( selector, context, results, seed ) {
2578 var i, tokens, token, type, find,
2579 compiled = typeof selector === "function" && selector,
2580 match = !seed && tokenize( (selector = compiled.selector || selector) );
2581
2582 results = results || [];
2583
2584 // Try to minimize operations if there is only one selector in the list and no seed
2585 // (the latter of which guarantees us context)
2586 if ( match.length === 1 ) {
2587
2588 // Reduce context if the leading compound selector is an ID
2589 tokens = match[0] = match[0].slice( 0 );
2590 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2591 support.getById && context.nodeType === 9 && documentIsHTML &&
2592 Expr.relative[ tokens[1].type ] ) {
2593
2594 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2595 if ( !context ) {
2596 return results;
2597
2598 // Precompiled matchers will still verify ancestry, so step up a level
2599 } else if ( compiled ) {
2600 context = context.parentNode;
2601 }
2602
2603 selector = selector.slice( tokens.shift().value.length );
2604 }
2605
2606 // Fetch a seed set for right-to-left matching
2607 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2608 while ( i-- ) {
2609 token = tokens[i];
2610
2611 // Abort if we hit a combinator
2612 if ( Expr.relative[ (type = token.type) ] ) {
2613 break;
2614 }
2615 if ( (find = Expr.find[ type ]) ) {
2616 // Search, expanding context for leading sibling combinators
2617 if ( (seed = find(
2618 token.matches[0].replace( runescape, funescape ),
2619 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2620 )) ) {
2621
2622 // If seed is empty or no tokens remain, we can return early
2623 tokens.splice( i, 1 );
2624 selector = seed.length && toSelector( tokens );
2625 if ( !selector ) {
2626 push.apply( results, seed );
2627 return results;
2628 }
2629
2630 break;
2631 }
2632 }
2633 }
2634 }
2635
2636 // Compile and execute a filtering function if one is not provided
2637 // Provide `match` to avoid retokenization if we modified the selector above
2638 ( compiled || compile( selector, match ) )(
2639 seed,
2640 context,
2641 !documentIsHTML,
2642 results,
2643 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2644 );
2645 return results;
2646};
2647
2648// One-time assignments
2649
2650// Sort stability
2651support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2652
2653// Support: Chrome 14-35+
2654// Always assume duplicates if they aren't passed to the comparison function
2655support.detectDuplicates = !!hasDuplicate;
2656
2657// Initialize against the default document
2658setDocument();
2659
2660// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2661// Detached nodes confoundingly follow *each other*
2662support.sortDetached = assert(function( div1 ) {
2663 // Should return 1, but returns 4 (following)
2664 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2665});
2666
2667// Support: IE<8
2668// Prevent attribute/property "interpolation"
2669// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2670if ( !assert(function( div ) {
2671 div.innerHTML = "<a href='#'></a>";
2672 return div.firstChild.getAttribute("href") === "#" ;
2673}) ) {
2674 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2675 if ( !isXML ) {
2676 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2677 }
2678 });
2679}
2680
2681// Support: IE<9
2682// Use defaultValue in place of getAttribute("value")
2683if ( !support.attributes || !assert(function( div ) {
2684 div.innerHTML = "<input/>";
2685 div.firstChild.setAttribute( "value", "" );
2686 return div.firstChild.getAttribute( "value" ) === "";
2687}) ) {
2688 addHandle( "value", function( elem, name, isXML ) {
2689 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2690 return elem.defaultValue;
2691 }
2692 });
2693}
2694
2695// Support: IE<9
2696// Use getAttributeNode to fetch booleans when getAttribute lies
2697if ( !assert(function( div ) {
2698 return div.getAttribute("disabled") == null;
2699}) ) {
2700 addHandle( booleans, function( elem, name, isXML ) {
2701 var val;
2702 if ( !isXML ) {
2703 return elem[ name ] === true ? name.toLowerCase() :
2704 (val = elem.getAttributeNode( name )) && val.specified ?
2705 val.value :
2706 null;
2707 }
2708 });
2709}
2710
2711return Sizzle;
2712
2713})( window );
2714
2715
2716
2717jQuery.find = Sizzle;
2718jQuery.expr = Sizzle.selectors;
2719jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2720jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2721jQuery.text = Sizzle.getText;
2722jQuery.isXMLDoc = Sizzle.isXML;
2723jQuery.contains = Sizzle.contains;
2724
2725
2726
2727var dir = function( elem, dir, until ) {
2728 var matched = [],
2729 truncate = until !== undefined;
2730
2731 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2732 if ( elem.nodeType === 1 ) {
2733 if ( truncate && jQuery( elem ).is( until ) ) {
2734 break;
2735 }
2736 matched.push( elem );
2737 }
2738 }
2739 return matched;
2740};
2741
2742
2743var siblings = function( n, elem ) {
2744 var matched = [];
2745
2746 for ( ; n; n = n.nextSibling ) {
2747 if ( n.nodeType === 1 && n !== elem ) {
2748 matched.push( n );
2749 }
2750 }
2751
2752 return matched;
2753};
2754
2755
2756var rneedsContext = jQuery.expr.match.needsContext;
2757
2758var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2759
2760
2761
2762var risSimple = /^.[^:#\[\.,]*$/;
2763
2764// Implement the identical functionality for filter and not
2765function winnow( elements, qualifier, not ) {
2766 if ( jQuery.isFunction( qualifier ) ) {
2767 return jQuery.grep( elements, function( elem, i ) {
2768 /* jshint -W018 */
2769 return !!qualifier.call( elem, i, elem ) !== not;
2770 } );
2771
2772 }
2773
2774 if ( qualifier.nodeType ) {
2775 return jQuery.grep( elements, function( elem ) {
2776 return ( elem === qualifier ) !== not;
2777 } );
2778
2779 }
2780
2781 if ( typeof qualifier === "string" ) {
2782 if ( risSimple.test( qualifier ) ) {
2783 return jQuery.filter( qualifier, elements, not );
2784 }
2785
2786 qualifier = jQuery.filter( qualifier, elements );
2787 }
2788
2789 return jQuery.grep( elements, function( elem ) {
2790 return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2791 } );
2792}
2793
2794jQuery.filter = function( expr, elems, not ) {
2795 var elem = elems[ 0 ];
2796
2797 if ( not ) {
2798 expr = ":not(" + expr + ")";
2799 }
2800
2801 return elems.length === 1 && elem.nodeType === 1 ?
2802 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2803 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2804 return elem.nodeType === 1;
2805 } ) );
2806};
2807
2808jQuery.fn.extend( {
2809 find: function( selector ) {
2810 var i,
2811 ret = [],
2812 self = this,
2813 len = self.length;
2814
2815 if ( typeof selector !== "string" ) {
2816 return this.pushStack( jQuery( selector ).filter( function() {
2817 for ( i = 0; i < len; i++ ) {
2818 if ( jQuery.contains( self[ i ], this ) ) {
2819 return true;
2820 }
2821 }
2822 } ) );
2823 }
2824
2825 for ( i = 0; i < len; i++ ) {
2826 jQuery.find( selector, self[ i ], ret );
2827 }
2828
2829 // Needed because $( selector, context ) becomes $( context ).find( selector )
2830 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2831 ret.selector = this.selector ? this.selector + " " + selector : selector;
2832 return ret;
2833 },
2834 filter: function( selector ) {
2835 return this.pushStack( winnow( this, selector || [], false ) );
2836 },
2837 not: function( selector ) {
2838 return this.pushStack( winnow( this, selector || [], true ) );
2839 },
2840 is: function( selector ) {
2841 return !!winnow(
2842 this,
2843
2844 // If this is a positional/relative selector, check membership in the returned set
2845 // so $("p:first").is("p:last") won't return true for a doc with two "p".
2846 typeof selector === "string" && rneedsContext.test( selector ) ?
2847 jQuery( selector ) :
2848 selector || [],
2849 false
2850 ).length;
2851 }
2852} );
2853
2854
2855// Initialize a jQuery object
2856
2857
2858// A central reference to the root jQuery(document)
2859var rootjQuery,
2860
2861 // A simple way to check for HTML strings
2862 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2863 // Strict HTML recognition (#11290: must start with <)
2864 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2865
2866 init = jQuery.fn.init = function( selector, context, root ) {
2867 var match, elem;
2868
2869 // HANDLE: $(""), $(null), $(undefined), $(false)
2870 if ( !selector ) {
2871 return this;
2872 }
2873
2874 // init accepts an alternate rootjQuery
2875 // so migrate can support jQuery.sub (gh-2101)
2876 root = root || rootjQuery;
2877
2878 // Handle HTML strings
2879 if ( typeof selector === "string" ) {
2880 if ( selector.charAt( 0 ) === "<" &&
2881 selector.charAt( selector.length - 1 ) === ">" &&
2882 selector.length >= 3 ) {
2883
2884 // Assume that strings that start and end with <> are HTML and skip the regex check
2885 match = [ null, selector, null ];
2886
2887 } else {
2888 match = rquickExpr.exec( selector );
2889 }
2890
2891 // Match html or make sure no context is specified for #id
2892 if ( match && ( match[ 1 ] || !context ) ) {
2893
2894 // HANDLE: $(html) -> $(array)
2895 if ( match[ 1 ] ) {
2896 context = context instanceof jQuery ? context[ 0 ] : context;
2897
2898 // scripts is true for back-compat
2899 // Intentionally let the error be thrown if parseHTML is not present
2900 jQuery.merge( this, jQuery.parseHTML(
2901 match[ 1 ],
2902 context && context.nodeType ? context.ownerDocument || context : document,
2903 true
2904 ) );
2905
2906 // HANDLE: $(html, props)
2907 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2908 for ( match in context ) {
2909
2910 // Properties of context are called as methods if possible
2911 if ( jQuery.isFunction( this[ match ] ) ) {
2912 this[ match ]( context[ match ] );
2913
2914 // ...and otherwise set as attributes
2915 } else {
2916 this.attr( match, context[ match ] );
2917 }
2918 }
2919 }
2920
2921 return this;
2922
2923 // HANDLE: $(#id)
2924 } else {
2925 elem = document.getElementById( match[ 2 ] );
2926
2927 // Check parentNode to catch when Blackberry 4.6 returns
2928 // nodes that are no longer in the document #6963
2929 if ( elem && elem.parentNode ) {
2930
2931 // Handle the case where IE and Opera return items
2932 // by name instead of ID
2933 if ( elem.id !== match[ 2 ] ) {
2934 return rootjQuery.find( selector );
2935 }
2936
2937 // Otherwise, we inject the element directly into the jQuery object
2938 this.length = 1;
2939 this[ 0 ] = elem;
2940 }
2941
2942 this.context = document;
2943 this.selector = selector;
2944 return this;
2945 }
2946
2947 // HANDLE: $(expr, $(...))
2948 } else if ( !context || context.jquery ) {
2949 return ( context || root ).find( selector );
2950
2951 // HANDLE: $(expr, context)
2952 // (which is just equivalent to: $(context).find(expr)
2953 } else {
2954 return this.constructor( context ).find( selector );
2955 }
2956
2957 // HANDLE: $(DOMElement)
2958 } else if ( selector.nodeType ) {
2959 this.context = this[ 0 ] = selector;
2960 this.length = 1;
2961 return this;
2962
2963 // HANDLE: $(function)
2964 // Shortcut for document ready
2965 } else if ( jQuery.isFunction( selector ) ) {
2966 return typeof root.ready !== "undefined" ?
2967 root.ready( selector ) :
2968
2969 // Execute immediately if ready is not present
2970 selector( jQuery );
2971 }
2972
2973 if ( selector.selector !== undefined ) {
2974 this.selector = selector.selector;
2975 this.context = selector.context;
2976 }
2977
2978 return jQuery.makeArray( selector, this );
2979 };
2980
2981// Give the init function the jQuery prototype for later instantiation
2982init.prototype = jQuery.fn;
2983
2984// Initialize central reference
2985rootjQuery = jQuery( document );
2986
2987
2988var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2989
2990 // methods guaranteed to produce a unique set when starting from a unique set
2991 guaranteedUnique = {
2992 children: true,
2993 contents: true,
2994 next: true,
2995 prev: true
2996 };
2997
2998jQuery.fn.extend( {
2999 has: function( target ) {
3000 var i,
3001 targets = jQuery( target, this ),
3002 len = targets.length;
3003
3004 return this.filter( function() {
3005 for ( i = 0; i < len; i++ ) {
3006 if ( jQuery.contains( this, targets[ i ] ) ) {
3007 return true;
3008 }
3009 }
3010 } );
3011 },
3012
3013 closest: function( selectors, context ) {
3014 var cur,
3015 i = 0,
3016 l = this.length,
3017 matched = [],
3018 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
3019 jQuery( selectors, context || this.context ) :
3020 0;
3021
3022 for ( ; i < l; i++ ) {
3023 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3024
3025 // Always skip document fragments
3026 if ( cur.nodeType < 11 && ( pos ?
3027 pos.index( cur ) > -1 :
3028
3029 // Don't pass non-elements to Sizzle
3030 cur.nodeType === 1 &&
3031 jQuery.find.matchesSelector( cur, selectors ) ) ) {
3032
3033 matched.push( cur );
3034 break;
3035 }
3036 }
3037 }
3038
3039 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3040 },
3041
3042 // Determine the position of an element within
3043 // the matched set of elements
3044 index: function( elem ) {
3045
3046 // No argument, return index in parent
3047 if ( !elem ) {
3048 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3049 }
3050
3051 // index in selector
3052 if ( typeof elem === "string" ) {
3053 return jQuery.inArray( this[ 0 ], jQuery( elem ) );
3054 }
3055
3056 // Locate the position of the desired element
3057 return jQuery.inArray(
3058
3059 // If it receives a jQuery object, the first element is used
3060 elem.jquery ? elem[ 0 ] : elem, this );
3061 },
3062
3063 add: function( selector, context ) {
3064 return this.pushStack(
3065 jQuery.uniqueSort(
3066 jQuery.merge( this.get(), jQuery( selector, context ) )
3067 )
3068 );
3069 },
3070
3071 addBack: function( selector ) {
3072 return this.add( selector == null ?
3073 this.prevObject : this.prevObject.filter( selector )
3074 );
3075 }
3076} );
3077
3078function sibling( cur, dir ) {
3079 do {
3080 cur = cur[ dir ];
3081 } while ( cur && cur.nodeType !== 1 );
3082
3083 return cur;
3084}
3085
3086jQuery.each( {
3087 parent: function( elem ) {
3088 var parent = elem.parentNode;
3089 return parent && parent.nodeType !== 11 ? parent : null;
3090 },
3091 parents: function( elem ) {
3092 return dir( elem, "parentNode" );
3093 },
3094 parentsUntil: function( elem, i, until ) {
3095 return dir( elem, "parentNode", until );
3096 },
3097 next: function( elem ) {
3098 return sibling( elem, "nextSibling" );
3099 },
3100 prev: function( elem ) {
3101 return sibling( elem, "previousSibling" );
3102 },
3103 nextAll: function( elem ) {
3104 return dir( elem, "nextSibling" );
3105 },
3106 prevAll: function( elem ) {
3107 return dir( elem, "previousSibling" );
3108 },
3109 nextUntil: function( elem, i, until ) {
3110 return dir( elem, "nextSibling", until );
3111 },
3112 prevUntil: function( elem, i, until ) {
3113 return dir( elem, "previousSibling", until );
3114 },
3115 siblings: function( elem ) {
3116 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3117 },
3118 children: function( elem ) {
3119 return siblings( elem.firstChild );
3120 },
3121 contents: function( elem ) {
3122 return jQuery.nodeName( elem, "iframe" ) ?
3123 elem.contentDocument || elem.contentWindow.document :
3124 jQuery.merge( [], elem.childNodes );
3125 }
3126}, function( name, fn ) {
3127 jQuery.fn[ name ] = function( until, selector ) {
3128 var ret = jQuery.map( this, fn, until );
3129
3130 if ( name.slice( -5 ) !== "Until" ) {
3131 selector = until;
3132 }
3133
3134 if ( selector && typeof selector === "string" ) {
3135 ret = jQuery.filter( selector, ret );
3136 }
3137
3138 if ( this.length > 1 ) {
3139
3140 // Remove duplicates
3141 if ( !guaranteedUnique[ name ] ) {
3142 ret = jQuery.uniqueSort( ret );
3143 }
3144
3145 // Reverse order for parents* and prev-derivatives
3146 if ( rparentsprev.test( name ) ) {
3147 ret = ret.reverse();
3148 }
3149 }
3150
3151 return this.pushStack( ret );
3152 };
3153} );
3154var rnotwhite = ( /\S+/g );
3155
3156
3157
3158// Convert String-formatted options into Object-formatted ones
3159function createOptions( options ) {
3160 var object = {};
3161 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3162 object[ flag ] = true;
3163 } );
3164 return object;
3165}
3166
3167/*
3168 * Create a callback list using the following parameters:
3169 *
3170 * options: an optional list of space-separated options that will change how
3171 * the callback list behaves or a more traditional option object
3172 *
3173 * By default a callback list will act like an event callback list and can be
3174 * "fired" multiple times.
3175 *
3176 * Possible options:
3177 *
3178 * once: will ensure the callback list can only be fired once (like a Deferred)
3179 *
3180 * memory: will keep track of previous values and will call any callback added
3181 * after the list has been fired right away with the latest "memorized"
3182 * values (like a Deferred)
3183 *
3184 * unique: will ensure a callback can only be added once (no duplicate in the list)
3185 *
3186 * stopOnFalse: interrupt callings when a callback returns false
3187 *
3188 */
3189jQuery.Callbacks = function( options ) {
3190
3191 // Convert options from String-formatted to Object-formatted if needed
3192 // (we check in cache first)
3193 options = typeof options === "string" ?
3194 createOptions( options ) :
3195 jQuery.extend( {}, options );
3196
3197 var // Flag to know if list is currently firing
3198 firing,
3199
3200 // Last fire value for non-forgettable lists
3201 memory,
3202
3203 // Flag to know if list was already fired
3204 fired,
3205
3206 // Flag to prevent firing
3207 locked,
3208
3209 // Actual callback list
3210 list = [],
3211
3212 // Queue of execution data for repeatable lists
3213 queue = [],
3214
3215 // Index of currently firing callback (modified by add/remove as needed)
3216 firingIndex = -1,
3217
3218 // Fire callbacks
3219 fire = function() {
3220
3221 // Enforce single-firing
3222 locked = options.once;
3223
3224 // Execute callbacks for all pending executions,
3225 // respecting firingIndex overrides and runtime changes
3226 fired = firing = true;
3227 for ( ; queue.length; firingIndex = -1 ) {
3228 memory = queue.shift();
3229 while ( ++firingIndex < list.length ) {
3230
3231 // Run callback and check for early termination
3232 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3233 options.stopOnFalse ) {
3234
3235 // Jump to end and forget the data so .add doesn't re-fire
3236 firingIndex = list.length;
3237 memory = false;
3238 }
3239 }
3240 }
3241
3242 // Forget the data if we're done with it
3243 if ( !options.memory ) {
3244 memory = false;
3245 }
3246
3247 firing = false;
3248
3249 // Clean up if we're done firing for good
3250 if ( locked ) {
3251
3252 // Keep an empty list if we have data for future add calls
3253 if ( memory ) {
3254 list = [];
3255
3256 // Otherwise, this object is spent
3257 } else {
3258 list = "";
3259 }
3260 }
3261 },
3262
3263 // Actual Callbacks object
3264 self = {
3265
3266 // Add a callback or a collection of callbacks to the list
3267 add: function() {
3268 if ( list ) {
3269
3270 // If we have memory from a past run, we should fire after adding
3271 if ( memory && !firing ) {
3272 firingIndex = list.length - 1;
3273 queue.push( memory );
3274 }
3275
3276 ( function add( args ) {
3277 jQuery.each( args, function( _, arg ) {
3278 if ( jQuery.isFunction( arg ) ) {
3279 if ( !options.unique || !self.has( arg ) ) {
3280 list.push( arg );
3281 }
3282 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3283
3284 // Inspect recursively
3285 add( arg );
3286 }
3287 } );
3288 } )( arguments );
3289
3290 if ( memory && !firing ) {
3291 fire();
3292 }
3293 }
3294 return this;
3295 },
3296
3297 // Remove a callback from the list
3298 remove: function() {
3299 jQuery.each( arguments, function( _, arg ) {
3300 var index;
3301 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3302 list.splice( index, 1 );
3303
3304 // Handle firing indexes
3305 if ( index <= firingIndex ) {
3306 firingIndex--;
3307 }
3308 }
3309 } );
3310 return this;
3311 },
3312
3313 // Check if a given callback is in the list.
3314 // If no argument is given, return whether or not list has callbacks attached.
3315 has: function( fn ) {
3316 return fn ?
3317 jQuery.inArray( fn, list ) > -1 :
3318 list.length > 0;
3319 },
3320
3321 // Remove all callbacks from the list
3322 empty: function() {
3323 if ( list ) {
3324 list = [];
3325 }
3326 return this;
3327 },
3328
3329 // Disable .fire and .add
3330 // Abort any current/pending executions
3331 // Clear all callbacks and values
3332 disable: function() {
3333 locked = queue = [];
3334 list = memory = "";
3335 return this;
3336 },
3337 disabled: function() {
3338 return !list;
3339 },
3340
3341 // Disable .fire
3342 // Also disable .add unless we have memory (since it would have no effect)
3343 // Abort any pending executions
3344 lock: function() {
3345 locked = true;
3346 if ( !memory ) {
3347 self.disable();
3348 }
3349 return this;
3350 },
3351 locked: function() {
3352 return !!locked;
3353 },
3354
3355 // Call all callbacks with the given context and arguments
3356 fireWith: function( context, args ) {
3357 if ( !locked ) {
3358 args = args || [];
3359 args = [ context, args.slice ? args.slice() : args ];
3360 queue.push( args );
3361 if ( !firing ) {
3362 fire();
3363 }
3364 }
3365 return this;
3366 },
3367
3368 // Call all the callbacks with the given arguments
3369 fire: function() {
3370 self.fireWith( this, arguments );
3371 return this;
3372 },
3373
3374 // To know if the callbacks have already been called at least once
3375 fired: function() {
3376 return !!fired;
3377 }
3378 };
3379
3380 return self;
3381};
3382
3383
3384jQuery.extend( {
3385
3386 Deferred: function( func ) {
3387 var tuples = [
3388
3389 // action, add listener, listener list, final state
3390 [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3391 [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3392 [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3393 ],
3394 state = "pending",
3395 promise = {
3396 state: function() {
3397 return state;
3398 },
3399 always: function() {
3400 deferred.done( arguments ).fail( arguments );
3401 return this;
3402 },
3403 then: function( /* fnDone, fnFail, fnProgress */ ) {
3404 var fns = arguments;
3405 return jQuery.Deferred( function( newDefer ) {
3406 jQuery.each( tuples, function( i, tuple ) {
3407 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3408
3409 // deferred[ done | fail | progress ] for forwarding actions to newDefer
3410 deferred[ tuple[ 1 ] ]( function() {
3411 var returned = fn && fn.apply( this, arguments );
3412 if ( returned && jQuery.isFunction( returned.promise ) ) {
3413 returned.promise()
3414 .progress( newDefer.notify )
3415 .done( newDefer.resolve )
3416 .fail( newDefer.reject );
3417 } else {
3418 newDefer[ tuple[ 0 ] + "With" ](
3419 this === promise ? newDefer.promise() : this,
3420 fn ? [ returned ] : arguments
3421 );
3422 }
3423 } );
3424 } );
3425 fns = null;
3426 } ).promise();
3427 },
3428
3429 // Get a promise for this deferred
3430 // If obj is provided, the promise aspect is added to the object
3431 promise: function( obj ) {
3432 return obj != null ? jQuery.extend( obj, promise ) : promise;
3433 }
3434 },
3435 deferred = {};
3436
3437 // Keep pipe for back-compat
3438 promise.pipe = promise.then;
3439
3440 // Add list-specific methods
3441 jQuery.each( tuples, function( i, tuple ) {
3442 var list = tuple[ 2 ],
3443 stateString = tuple[ 3 ];
3444
3445 // promise[ done | fail | progress ] = list.add
3446 promise[ tuple[ 1 ] ] = list.add;
3447
3448 // Handle state
3449 if ( stateString ) {
3450 list.add( function() {
3451
3452 // state = [ resolved | rejected ]
3453 state = stateString;
3454
3455 // [ reject_list | resolve_list ].disable; progress_list.lock
3456 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3457 }
3458
3459 // deferred[ resolve | reject | notify ]
3460 deferred[ tuple[ 0 ] ] = function() {
3461 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3462 return this;
3463 };
3464 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3465 } );
3466
3467 // Make the deferred a promise
3468 promise.promise( deferred );
3469
3470 // Call given func if any
3471 if ( func ) {
3472 func.call( deferred, deferred );
3473 }
3474
3475 // All done!
3476 return deferred;
3477 },
3478
3479 // Deferred helper
3480 when: function( subordinate /* , ..., subordinateN */ ) {
3481 var i = 0,
3482 resolveValues = slice.call( arguments ),
3483 length = resolveValues.length,
3484
3485 // the count of uncompleted subordinates
3486 remaining = length !== 1 ||
3487 ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3488
3489 // the master Deferred.
3490 // If resolveValues consist of only a single Deferred, just use that.
3491 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3492
3493 // Update function for both resolve and progress values
3494 updateFunc = function( i, contexts, values ) {
3495 return function( value ) {
3496 contexts[ i ] = this;
3497 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3498 if ( values === progressValues ) {
3499 deferred.notifyWith( contexts, values );
3500
3501 } else if ( !( --remaining ) ) {
3502 deferred.resolveWith( contexts, values );
3503 }
3504 };
3505 },
3506
3507 progressValues, progressContexts, resolveContexts;
3508
3509 // add listeners to Deferred subordinates; treat others as resolved
3510 if ( length > 1 ) {
3511 progressValues = new Array( length );
3512 progressContexts = new Array( length );
3513 resolveContexts = new Array( length );
3514 for ( ; i < length; i++ ) {
3515 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3516 resolveValues[ i ].promise()
3517 .progress( updateFunc( i, progressContexts, progressValues ) )
3518 .done( updateFunc( i, resolveContexts, resolveValues ) )
3519 .fail( deferred.reject );
3520 } else {
3521 --remaining;
3522 }
3523 }
3524 }
3525
3526 // if we're not waiting on anything, resolve the master
3527 if ( !remaining ) {
3528 deferred.resolveWith( resolveContexts, resolveValues );
3529 }
3530
3531 return deferred.promise();
3532 }
3533} );
3534
3535
3536// The deferred used on DOM ready
3537var readyList;
3538
3539jQuery.fn.ready = function( fn ) {
3540
3541 // Add the callback
3542 jQuery.ready.promise().done( fn );
3543
3544 return this;
3545};
3546
3547jQuery.extend( {
3548
3549 // Is the DOM ready to be used? Set to true once it occurs.
3550 isReady: false,
3551
3552 // A counter to track how many items to wait for before
3553 // the ready event fires. See #6781
3554 readyWait: 1,
3555
3556 // Hold (or release) the ready event
3557 holdReady: function( hold ) {
3558 if ( hold ) {
3559 jQuery.readyWait++;
3560 } else {
3561 jQuery.ready( true );
3562 }
3563 },
3564
3565 // Handle when the DOM is ready
3566 ready: function( wait ) {
3567
3568 // Abort if there are pending holds or we're already ready
3569 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3570 return;
3571 }
3572
3573 // Remember that the DOM is ready
3574 jQuery.isReady = true;
3575
3576 // If a normal DOM Ready event fired, decrement, and wait if need be
3577 if ( wait !== true && --jQuery.readyWait > 0 ) {
3578 return;
3579 }
3580
3581 // If there are functions bound, to execute
3582 readyList.resolveWith( document, [ jQuery ] );
3583
3584 // Trigger any bound ready events
3585 if ( jQuery.fn.triggerHandler ) {
3586 jQuery( document ).triggerHandler( "ready" );
3587 jQuery( document ).off( "ready" );
3588 }
3589 }
3590} );
3591
3592/**
3593 * Clean-up method for dom ready events
3594 */
3595function detach() {
3596 if ( document.addEventListener ) {
3597 document.removeEventListener( "DOMContentLoaded", completed );
3598 window.removeEventListener( "load", completed );
3599
3600 } else {
3601 document.detachEvent( "onreadystatechange", completed );
3602 window.detachEvent( "onload", completed );
3603 }
3604}
3605
3606/**
3607 * The ready event handler and self cleanup method
3608 */
3609function completed() {
3610
3611 // readyState === "complete" is good enough for us to call the dom ready in oldIE
3612 if ( document.addEventListener ||
3613 window.event.type === "load" ||
3614 document.readyState === "complete" ) {
3615
3616 detach();
3617 jQuery.ready();
3618 }
3619}
3620
3621jQuery.ready.promise = function( obj ) {
3622 if ( !readyList ) {
3623
3624 readyList = jQuery.Deferred();
3625
3626 // Catch cases where $(document).ready() is called
3627 // after the browser event has already occurred.
3628 // Support: IE6-10
3629 // Older IE sometimes signals "interactive" too soon
3630 if ( document.readyState === "complete" ||
3631 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3632
3633 // Handle it asynchronously to allow scripts the opportunity to delay ready
3634 window.setTimeout( jQuery.ready );
3635
3636 // Standards-based browsers support DOMContentLoaded
3637 } else if ( document.addEventListener ) {
3638
3639 // Use the handy event callback
3640 document.addEventListener( "DOMContentLoaded", completed );
3641
3642 // A fallback to window.onload, that will always work
3643 window.addEventListener( "load", completed );
3644
3645 // If IE event model is used
3646 } else {
3647
3648 // Ensure firing before onload, maybe late but safe also for iframes
3649 document.attachEvent( "onreadystatechange", completed );
3650
3651 // A fallback to window.onload, that will always work
3652 window.attachEvent( "onload", completed );
3653
3654 // If IE and not a frame
3655 // continually check to see if the document is ready
3656 var top = false;
3657
3658 try {
3659 top = window.frameElement == null && document.documentElement;
3660 } catch ( e ) {}
3661
3662 if ( top && top.doScroll ) {
3663 ( function doScrollCheck() {
3664 if ( !jQuery.isReady ) {
3665
3666 try {
3667
3668 // Use the trick by Diego Perini
3669 // http://javascript.nwbox.com/IEContentLoaded/
3670 top.doScroll( "left" );
3671 } catch ( e ) {
3672 return window.setTimeout( doScrollCheck, 50 );
3673 }
3674
3675 // detach all dom ready events
3676 detach();
3677
3678 // and execute any waiting functions
3679 jQuery.ready();
3680 }
3681 } )();
3682 }
3683 }
3684 }
3685 return readyList.promise( obj );
3686};
3687
3688// Kick off the DOM ready check even if the user does not
3689jQuery.ready.promise();
3690
3691
3692
3693
3694// Support: IE<9
3695// Iteration over object's inherited properties before its own
3696var i;
3697for ( i in jQuery( support ) ) {
3698 break;
3699}
3700support.ownFirst = i === "0";
3701
3702// Note: most support tests are defined in their respective modules.
3703// false until the test is run
3704support.inlineBlockNeedsLayout = false;
3705
3706// Execute ASAP in case we need to set body.style.zoom
3707jQuery( function() {
3708
3709 // Minified: var a,b,c,d
3710 var val, div, body, container;
3711
3712 body = document.getElementsByTagName( "body" )[ 0 ];
3713 if ( !body || !body.style ) {
3714
3715 // Return for frameset docs that don't have a body
3716 return;
3717 }
3718
3719 // Setup
3720 div = document.createElement( "div" );
3721 container = document.createElement( "div" );
3722 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3723 body.appendChild( container ).appendChild( div );
3724
3725 if ( typeof div.style.zoom !== "undefined" ) {
3726
3727 // Support: IE<8
3728 // Check if natively block-level elements act like inline-block
3729 // elements when setting their display to 'inline' and giving
3730 // them layout
3731 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3732
3733 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3734 if ( val ) {
3735
3736 // Prevent IE 6 from affecting layout for positioned elements #11048
3737 // Prevent IE from shrinking the body in IE 7 mode #12869
3738 // Support: IE<8
3739 body.style.zoom = 1;
3740 }
3741 }
3742
3743 body.removeChild( container );
3744} );
3745
3746
3747( function() {
3748 var div = document.createElement( "div" );
3749
3750 // Support: IE<9
3751 support.deleteExpando = true;
3752 try {
3753 delete div.test;
3754 } catch ( e ) {
3755 support.deleteExpando = false;
3756 }
3757
3758 // Null elements to avoid leaks in IE.
3759 div = null;
3760} )();
3761var acceptData = function( elem ) {
3762 var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
3763 nodeType = +elem.nodeType || 1;
3764
3765 // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3766 return nodeType !== 1 && nodeType !== 9 ?
3767 false :
3768
3769 // Nodes accept data unless otherwise specified; rejection can be conditional
3770 !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
3771};
3772
3773
3774
3775
3776var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3777 rmultiDash = /([A-Z])/g;
3778
3779function dataAttr( elem, key, data ) {
3780
3781 // If nothing was found internally, try to fetch any
3782 // data from the HTML5 data-* attribute
3783 if ( data === undefined && elem.nodeType === 1 ) {
3784
3785 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3786
3787 data = elem.getAttribute( name );
3788
3789 if ( typeof data === "string" ) {
3790 try {
3791 data = data === "true" ? true :
3792 data === "false" ? false :
3793 data === "null" ? null :
3794
3795 // Only convert to a number if it doesn't change the string
3796 +data + "" === data ? +data :
3797 rbrace.test( data ) ? jQuery.parseJSON( data ) :
3798 data;
3799 } catch ( e ) {}
3800
3801 // Make sure we set the data so it isn't changed later
3802 jQuery.data( elem, key, data );
3803
3804 } else {
3805 data = undefined;
3806 }
3807 }
3808
3809 return data;
3810}
3811
3812// checks a cache object for emptiness
3813function isEmptyDataObject( obj ) {
3814 var name;
3815 for ( name in obj ) {
3816
3817 // if the public data object is empty, the private is still empty
3818 if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
3819 continue;
3820 }
3821 if ( name !== "toJSON" ) {
3822 return false;
3823 }
3824 }
3825
3826 return true;
3827}
3828
3829function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3830 if ( !acceptData( elem ) ) {
3831 return;
3832 }
3833
3834 var ret, thisCache,
3835 internalKey = jQuery.expando,
3836
3837 // We have to handle DOM nodes and JS objects differently because IE6-7
3838 // can't GC object references properly across the DOM-JS boundary
3839 isNode = elem.nodeType,
3840
3841 // Only DOM nodes need the global jQuery cache; JS object data is
3842 // attached directly to the object so GC can occur automatically
3843 cache = isNode ? jQuery.cache : elem,
3844
3845 // Only defining an ID for JS objects if its cache already exists allows
3846 // the code to shortcut on the same path as a DOM node with no cache
3847 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3848
3849 // Avoid doing any more work than we need to when trying to get data on an
3850 // object that has no data at all
3851 if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
3852 data === undefined && typeof name === "string" ) {
3853 return;
3854 }
3855
3856 if ( !id ) {
3857
3858 // Only DOM nodes need a new unique ID for each element since their data
3859 // ends up in the global cache
3860 if ( isNode ) {
3861 id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3862 } else {
3863 id = internalKey;
3864 }
3865 }
3866
3867 if ( !cache[ id ] ) {
3868
3869 // Avoid exposing jQuery metadata on plain JS objects when the object
3870 // is serialized using JSON.stringify
3871 cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3872 }
3873
3874 // An object can be passed to jQuery.data instead of a key/value pair; this gets
3875 // shallow copied over onto the existing cache
3876 if ( typeof name === "object" || typeof name === "function" ) {
3877 if ( pvt ) {
3878 cache[ id ] = jQuery.extend( cache[ id ], name );
3879 } else {
3880 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3881 }
3882 }
3883
3884 thisCache = cache[ id ];
3885
3886 // jQuery data() is stored in a separate object inside the object's internal data
3887 // cache in order to avoid key collisions between internal data and user-defined
3888 // data.
3889 if ( !pvt ) {
3890 if ( !thisCache.data ) {
3891 thisCache.data = {};
3892 }
3893
3894 thisCache = thisCache.data;
3895 }
3896
3897 if ( data !== undefined ) {
3898 thisCache[ jQuery.camelCase( name ) ] = data;
3899 }
3900
3901 // Check for both converted-to-camel and non-converted data property names
3902 // If a data property was specified
3903 if ( typeof name === "string" ) {
3904
3905 // First Try to find as-is property data
3906 ret = thisCache[ name ];
3907
3908 // Test for null|undefined property data
3909 if ( ret == null ) {
3910
3911 // Try to find the camelCased property
3912 ret = thisCache[ jQuery.camelCase( name ) ];
3913 }
3914 } else {
3915 ret = thisCache;
3916 }
3917
3918 return ret;
3919}
3920
3921function internalRemoveData( elem, name, pvt ) {
3922 if ( !acceptData( elem ) ) {
3923 return;
3924 }
3925
3926 var thisCache, i,
3927 isNode = elem.nodeType,
3928
3929 // See jQuery.data for more information
3930 cache = isNode ? jQuery.cache : elem,
3931 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3932
3933 // If there is already no cache entry for this object, there is no
3934 // purpose in continuing
3935 if ( !cache[ id ] ) {
3936 return;
3937 }
3938
3939 if ( name ) {
3940
3941 thisCache = pvt ? cache[ id ] : cache[ id ].data;
3942
3943 if ( thisCache ) {
3944
3945 // Support array or space separated string names for data keys
3946 if ( !jQuery.isArray( name ) ) {
3947
3948 // try the string as a key before any manipulation
3949 if ( name in thisCache ) {
3950 name = [ name ];
3951 } else {
3952
3953 // split the camel cased version by spaces unless a key with the spaces exists
3954 name = jQuery.camelCase( name );
3955 if ( name in thisCache ) {
3956 name = [ name ];
3957 } else {
3958 name = name.split( " " );
3959 }
3960 }
3961 } else {
3962
3963 // If "name" is an array of keys...
3964 // When data is initially created, via ("key", "val") signature,
3965 // keys will be converted to camelCase.
3966 // Since there is no way to tell _how_ a key was added, remove
3967 // both plain key and camelCase key. #12786
3968 // This will only penalize the array argument path.
3969 name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3970 }
3971
3972 i = name.length;
3973 while ( i-- ) {
3974 delete thisCache[ name[ i ] ];
3975 }
3976
3977 // If there is no data left in the cache, we want to continue
3978 // and let the cache object itself get destroyed
3979 if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
3980 return;
3981 }
3982 }
3983 }
3984
3985 // See jQuery.data for more information
3986 if ( !pvt ) {
3987 delete cache[ id ].data;
3988
3989 // Don't destroy the parent cache unless the internal data object
3990 // had been the only thing left in it
3991 if ( !isEmptyDataObject( cache[ id ] ) ) {
3992 return;
3993 }
3994 }
3995
3996 // Destroy the cache
3997 if ( isNode ) {
3998 jQuery.cleanData( [ elem ], true );
3999
4000 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
4001 /* jshint eqeqeq: false */
4002 } else if ( support.deleteExpando || cache != cache.window ) {
4003 /* jshint eqeqeq: true */
4004 delete cache[ id ];
4005
4006 // When all else fails, undefined
4007 } else {
4008 cache[ id ] = undefined;
4009 }
4010}
4011
4012jQuery.extend( {
4013 cache: {},
4014
4015 // The following elements (space-suffixed to avoid Object.prototype collisions)
4016 // throw uncatchable exceptions if you attempt to set expando properties
4017 noData: {
4018 "applet ": true,
4019 "embed ": true,
4020
4021 // ...but Flash objects (which have this classid) *can* handle expandos
4022 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
4023 },
4024
4025 hasData: function( elem ) {
4026 elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
4027 return !!elem && !isEmptyDataObject( elem );
4028 },
4029
4030 data: function( elem, name, data ) {
4031 return internalData( elem, name, data );
4032 },
4033
4034 removeData: function( elem, name ) {
4035 return internalRemoveData( elem, name );
4036 },
4037
4038 // For internal use only.
4039 _data: function( elem, name, data ) {
4040 return internalData( elem, name, data, true );
4041 },
4042
4043 _removeData: function( elem, name ) {
4044 return internalRemoveData( elem, name, true );
4045 }
4046} );
4047
4048jQuery.fn.extend( {
4049 data: function( key, value ) {
4050 var i, name, data,
4051 elem = this[ 0 ],
4052 attrs = elem && elem.attributes;
4053
4054 // Special expections of .data basically thwart jQuery.access,
4055 // so implement the relevant behavior ourselves
4056
4057 // Gets all values
4058 if ( key === undefined ) {
4059 if ( this.length ) {
4060 data = jQuery.data( elem );
4061
4062 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
4063 i = attrs.length;
4064 while ( i-- ) {
4065
4066 // Support: IE11+
4067 // The attrs elements can be null (#14894)
4068 if ( attrs[ i ] ) {
4069 name = attrs[ i ].name;
4070 if ( name.indexOf( "data-" ) === 0 ) {
4071 name = jQuery.camelCase( name.slice( 5 ) );
4072 dataAttr( elem, name, data[ name ] );
4073 }
4074 }
4075 }
4076 jQuery._data( elem, "parsedAttrs", true );
4077 }
4078 }
4079
4080 return data;
4081 }
4082
4083 // Sets multiple values
4084 if ( typeof key === "object" ) {
4085 return this.each( function() {
4086 jQuery.data( this, key );
4087 } );
4088 }
4089
4090 return arguments.length > 1 ?
4091
4092 // Sets one value
4093 this.each( function() {
4094 jQuery.data( this, key, value );
4095 } ) :
4096
4097 // Gets one value
4098 // Try to fetch any internally stored data first
4099 elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
4100 },
4101
4102 removeData: function( key ) {
4103 return this.each( function() {
4104 jQuery.removeData( this, key );
4105 } );
4106 }
4107} );
4108
4109
4110jQuery.extend( {
4111 queue: function( elem, type, data ) {
4112 var queue;
4113
4114 if ( elem ) {
4115 type = ( type || "fx" ) + "queue";
4116 queue = jQuery._data( elem, type );
4117
4118 // Speed up dequeue by getting out quickly if this is just a lookup
4119 if ( data ) {
4120 if ( !queue || jQuery.isArray( data ) ) {
4121 queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
4122 } else {
4123 queue.push( data );
4124 }
4125 }
4126 return queue || [];
4127 }
4128 },
4129
4130 dequeue: function( elem, type ) {
4131 type = type || "fx";
4132
4133 var queue = jQuery.queue( elem, type ),
4134 startLength = queue.length,
4135 fn = queue.shift(),
4136 hooks = jQuery._queueHooks( elem, type ),
4137 next = function() {
4138 jQuery.dequeue( elem, type );
4139 };
4140
4141 // If the fx queue is dequeued, always remove the progress sentinel
4142 if ( fn === "inprogress" ) {
4143 fn = queue.shift();
4144 startLength--;
4145 }
4146
4147 if ( fn ) {
4148
4149 // Add a progress sentinel to prevent the fx queue from being
4150 // automatically dequeued
4151 if ( type === "fx" ) {
4152 queue.unshift( "inprogress" );
4153 }
4154
4155 // clear up the last queue stop function
4156 delete hooks.stop;
4157 fn.call( elem, next, hooks );
4158 }
4159
4160 if ( !startLength && hooks ) {
4161 hooks.empty.fire();
4162 }
4163 },
4164
4165 // not intended for public consumption - generates a queueHooks object,
4166 // or returns the current one
4167 _queueHooks: function( elem, type ) {
4168 var key = type + "queueHooks";
4169 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4170 empty: jQuery.Callbacks( "once memory" ).add( function() {
4171 jQuery._removeData( elem, type + "queue" );
4172 jQuery._removeData( elem, key );
4173 } )
4174 } );
4175 }
4176} );
4177
4178jQuery.fn.extend( {
4179 queue: function( type, data ) {
4180 var setter = 2;
4181
4182 if ( typeof type !== "string" ) {
4183 data = type;
4184 type = "fx";
4185 setter--;
4186 }
4187
4188 if ( arguments.length < setter ) {
4189 return jQuery.queue( this[ 0 ], type );
4190 }
4191
4192 return data === undefined ?
4193 this :
4194 this.each( function() {
4195 var queue = jQuery.queue( this, type, data );
4196
4197 // ensure a hooks for this queue
4198 jQuery._queueHooks( this, type );
4199
4200 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4201 jQuery.dequeue( this, type );
4202 }
4203 } );
4204 },
4205 dequeue: function( type ) {
4206 return this.each( function() {
4207 jQuery.dequeue( this, type );
4208 } );
4209 },
4210 clearQueue: function( type ) {
4211 return this.queue( type || "fx", [] );
4212 },
4213
4214 // Get a promise resolved when queues of a certain type
4215 // are emptied (fx is the type by default)
4216 promise: function( type, obj ) {
4217 var tmp,
4218 count = 1,
4219 defer = jQuery.Deferred(),
4220 elements = this,
4221 i = this.length,
4222 resolve = function() {
4223 if ( !( --count ) ) {
4224 defer.resolveWith( elements, [ elements ] );
4225 }
4226 };
4227
4228 if ( typeof type !== "string" ) {
4229 obj = type;
4230 type = undefined;
4231 }
4232 type = type || "fx";
4233
4234 while ( i-- ) {
4235 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4236 if ( tmp && tmp.empty ) {
4237 count++;
4238 tmp.empty.add( resolve );
4239 }
4240 }
4241 resolve();
4242 return defer.promise( obj );
4243 }
4244} );
4245
4246
4247( function() {
4248 var shrinkWrapBlocksVal;
4249
4250 support.shrinkWrapBlocks = function() {
4251 if ( shrinkWrapBlocksVal != null ) {
4252 return shrinkWrapBlocksVal;
4253 }
4254
4255 // Will be changed later if needed.
4256 shrinkWrapBlocksVal = false;
4257
4258 // Minified: var b,c,d
4259 var div, body, container;
4260
4261 body = document.getElementsByTagName( "body" )[ 0 ];
4262 if ( !body || !body.style ) {
4263
4264 // Test fired too early or in an unsupported environment, exit.
4265 return;
4266 }
4267
4268 // Setup
4269 div = document.createElement( "div" );
4270 container = document.createElement( "div" );
4271 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4272 body.appendChild( container ).appendChild( div );
4273
4274 // Support: IE6
4275 // Check if elements with layout shrink-wrap their children
4276 if ( typeof div.style.zoom !== "undefined" ) {
4277
4278 // Reset CSS: box-sizing; display; margin; border
4279 div.style.cssText =
4280
4281 // Support: Firefox<29, Android 2.3
4282 // Vendor-prefix box-sizing
4283 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
4284 "box-sizing:content-box;display:block;margin:0;border:0;" +
4285 "padding:1px;width:1px;zoom:1";
4286 div.appendChild( document.createElement( "div" ) ).style.width = "5px";
4287 shrinkWrapBlocksVal = div.offsetWidth !== 3;
4288 }
4289
4290 body.removeChild( container );
4291
4292 return shrinkWrapBlocksVal;
4293 };
4294
4295} )();
4296var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4297
4298var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4299
4300
4301var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4302
4303var isHidden = function( elem, el ) {
4304
4305 // isHidden might be called from jQuery#filter function;
4306 // in that case, element will be second argument
4307 elem = el || elem;
4308 return jQuery.css( elem, "display" ) === "none" ||
4309 !jQuery.contains( elem.ownerDocument, elem );
4310 };
4311
4312
4313
4314function adjustCSS( elem, prop, valueParts, tween ) {
4315 var adjusted,
4316 scale = 1,
4317 maxIterations = 20,
4318 currentValue = tween ?
4319 function() { return tween.cur(); } :
4320 function() { return jQuery.css( elem, prop, "" ); },
4321 initial = currentValue(),
4322 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4323
4324 // Starting value computation is required for potential unit mismatches
4325 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4326 rcssNum.exec( jQuery.css( elem, prop ) );
4327
4328 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4329
4330 // Trust units reported by jQuery.css
4331 unit = unit || initialInUnit[ 3 ];
4332
4333 // Make sure we update the tween properties later on
4334 valueParts = valueParts || [];
4335
4336 // Iteratively approximate from a nonzero starting point
4337 initialInUnit = +initial || 1;
4338
4339 do {
4340
4341 // If previous iteration zeroed out, double until we get *something*.
4342 // Use string for doubling so we don't accidentally see scale as unchanged below
4343 scale = scale || ".5";
4344
4345 // Adjust and apply
4346 initialInUnit = initialInUnit / scale;
4347 jQuery.style( elem, prop, initialInUnit + unit );
4348
4349 // Update scale, tolerating zero or NaN from tween.cur()
4350 // Break the loop if scale is unchanged or perfect, or if we've just had enough.
4351 } while (
4352 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4353 );
4354 }
4355
4356 if ( valueParts ) {
4357 initialInUnit = +initialInUnit || +initial || 0;
4358
4359 // Apply relative offset (+=/-=) if specified
4360 adjusted = valueParts[ 1 ] ?
4361 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4362 +valueParts[ 2 ];
4363 if ( tween ) {
4364 tween.unit = unit;
4365 tween.start = initialInUnit;
4366 tween.end = adjusted;
4367 }
4368 }
4369 return adjusted;
4370}
4371
4372
4373// Multifunctional method to get and set values of a collection
4374// The value/s can optionally be executed if it's a function
4375var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4376 var i = 0,
4377 length = elems.length,
4378 bulk = key == null;
4379
4380 // Sets many values
4381 if ( jQuery.type( key ) === "object" ) {
4382 chainable = true;
4383 for ( i in key ) {
4384 access( elems, fn, i, key[ i ], true, emptyGet, raw );
4385 }
4386
4387 // Sets one value
4388 } else if ( value !== undefined ) {
4389 chainable = true;
4390
4391 if ( !jQuery.isFunction( value ) ) {
4392 raw = true;
4393 }
4394
4395 if ( bulk ) {
4396
4397 // Bulk operations run against the entire set
4398 if ( raw ) {
4399 fn.call( elems, value );
4400 fn = null;
4401
4402 // ...except when executing function values
4403 } else {
4404 bulk = fn;
4405 fn = function( elem, key, value ) {
4406 return bulk.call( jQuery( elem ), value );
4407 };
4408 }
4409 }
4410
4411 if ( fn ) {
4412 for ( ; i < length; i++ ) {
4413 fn(
4414 elems[ i ],
4415 key,
4416 raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
4417 );
4418 }
4419 }
4420 }
4421
4422 return chainable ?
4423 elems :
4424
4425 // Gets
4426 bulk ?
4427 fn.call( elems ) :
4428 length ? fn( elems[ 0 ], key ) : emptyGet;
4429};
4430var rcheckableType = ( /^(?:checkbox|radio)$/i );
4431
4432var rtagName = ( /<([\w:-]+)/ );
4433
4434var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4435
4436var rleadingWhitespace = ( /^\s+/ );
4437
4438var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
4439 "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
4440 "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4441
4442
4443
4444function createSafeFragment( document ) {
4445 var list = nodeNames.split( "|" ),
4446 safeFrag = document.createDocumentFragment();
4447
4448 if ( safeFrag.createElement ) {
4449 while ( list.length ) {
4450 safeFrag.createElement(
4451 list.pop()
4452 );
4453 }
4454 }
4455 return safeFrag;
4456}
4457
4458
4459( function() {
4460 var div = document.createElement( "div" ),
4461 fragment = document.createDocumentFragment(),
4462 input = document.createElement( "input" );
4463
4464 // Setup
4465 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4466
4467 // IE strips leading whitespace when .innerHTML is used
4468 support.leadingWhitespace = div.firstChild.nodeType === 3;
4469
4470 // Make sure that tbody elements aren't automatically inserted
4471 // IE will insert them into empty tables
4472 support.tbody = !div.getElementsByTagName( "tbody" ).length;
4473
4474 // Make sure that link elements get serialized correctly by innerHTML
4475 // This requires a wrapper element in IE
4476 support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4477
4478 // Makes sure cloning an html5 element does not cause problems
4479 // Where outerHTML is undefined, this still works
4480 support.html5Clone =
4481 document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4482
4483 // Check if a disconnected checkbox will retain its checked
4484 // value of true after appended to the DOM (IE6/7)
4485 input.type = "checkbox";
4486 input.checked = true;
4487 fragment.appendChild( input );
4488 support.appendChecked = input.checked;
4489
4490 // Make sure textarea (and checkbox) defaultValue is properly cloned
4491 // Support: IE6-IE11+
4492 div.innerHTML = "<textarea>x</textarea>";
4493 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4494
4495 // #11217 - WebKit loses check when the name is after the checked attribute
4496 fragment.appendChild( div );
4497
4498 // Support: Windows Web Apps (WWA)
4499 // `name` and `type` must use .setAttribute for WWA (#14901)
4500 input = document.createElement( "input" );
4501 input.setAttribute( "type", "radio" );
4502 input.setAttribute( "checked", "checked" );
4503 input.setAttribute( "name", "t" );
4504
4505 div.appendChild( input );
4506
4507 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4508 // old WebKit doesn't clone checked state correctly in fragments
4509 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4510
4511 // Support: IE<9
4512 // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4513 support.noCloneEvent = !!div.addEventListener;
4514
4515 // Support: IE<9
4516 // Since attributes and properties are the same in IE,
4517 // cleanData must set properties to undefined rather than use removeAttribute
4518 div[ jQuery.expando ] = 1;
4519 support.attributes = !div.getAttribute( jQuery.expando );
4520} )();
4521
4522
4523// We have to close these tags to support XHTML (#13200)
4524var wrapMap = {
4525 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4526 legend: [ 1, "<fieldset>", "</fieldset>" ],
4527 area: [ 1, "<map>", "</map>" ],
4528
4529 // Support: IE8
4530 param: [ 1, "<object>", "</object>" ],
4531 thead: [ 1, "<table>", "</table>" ],
4532 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4533 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4534 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4535
4536 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4537 // unless wrapped in a div with non-breaking characters in front of it.
4538 _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
4539};
4540
4541// Support: IE8-IE9
4542wrapMap.optgroup = wrapMap.option;
4543
4544wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4545wrapMap.th = wrapMap.td;
4546
4547
4548function getAll( context, tag ) {
4549 var elems, elem,
4550 i = 0,
4551 found = typeof context.getElementsByTagName !== "undefined" ?
4552 context.getElementsByTagName( tag || "*" ) :
4553 typeof context.querySelectorAll !== "undefined" ?
4554 context.querySelectorAll( tag || "*" ) :
4555 undefined;
4556
4557 if ( !found ) {
4558 for ( found = [], elems = context.childNodes || context;
4559 ( elem = elems[ i ] ) != null;
4560 i++
4561 ) {
4562 if ( !tag || jQuery.nodeName( elem, tag ) ) {
4563 found.push( elem );
4564 } else {
4565 jQuery.merge( found, getAll( elem, tag ) );
4566 }
4567 }
4568 }
4569
4570 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4571 jQuery.merge( [ context ], found ) :
4572 found;
4573}
4574
4575
4576// Mark scripts as having already been evaluated
4577function setGlobalEval( elems, refElements ) {
4578 var elem,
4579 i = 0;
4580 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
4581 jQuery._data(
4582 elem,
4583 "globalEval",
4584 !refElements || jQuery._data( refElements[ i ], "globalEval" )
4585 );
4586 }
4587}
4588
4589
4590var rhtml = /<|&#?\w+;/,
4591 rtbody = /<tbody/i;
4592
4593function fixDefaultChecked( elem ) {
4594 if ( rcheckableType.test( elem.type ) ) {
4595 elem.defaultChecked = elem.checked;
4596 }
4597}
4598
4599function buildFragment( elems, context, scripts, selection, ignored ) {
4600 var j, elem, contains,
4601 tmp, tag, tbody, wrap,
4602 l = elems.length,
4603
4604 // Ensure a safe fragment
4605 safe = createSafeFragment( context ),
4606
4607 nodes = [],
4608 i = 0;
4609
4610 for ( ; i < l; i++ ) {
4611 elem = elems[ i ];
4612
4613 if ( elem || elem === 0 ) {
4614
4615 // Add nodes directly
4616 if ( jQuery.type( elem ) === "object" ) {
4617 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4618
4619 // Convert non-html into a text node
4620 } else if ( !rhtml.test( elem ) ) {
4621 nodes.push( context.createTextNode( elem ) );
4622
4623 // Convert html into DOM nodes
4624 } else {
4625 tmp = tmp || safe.appendChild( context.createElement( "div" ) );
4626
4627 // Deserialize a standard representation
4628 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4629 wrap = wrapMap[ tag ] || wrapMap._default;
4630
4631 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4632
4633 // Descend through wrappers to the right content
4634 j = wrap[ 0 ];
4635 while ( j-- ) {
4636 tmp = tmp.lastChild;
4637 }
4638
4639 // Manually add leading whitespace removed by IE
4640 if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4641 nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
4642 }
4643
4644 // Remove IE's autoinserted <tbody> from table fragments
4645 if ( !support.tbody ) {
4646
4647 // String was a <table>, *may* have spurious <tbody>
4648 elem = tag === "table" && !rtbody.test( elem ) ?
4649 tmp.firstChild :
4650
4651 // String was a bare <thead> or <tfoot>
4652 wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
4653 tmp :
4654 0;
4655
4656 j = elem && elem.childNodes.length;
4657 while ( j-- ) {
4658 if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
4659 !tbody.childNodes.length ) {
4660
4661 elem.removeChild( tbody );
4662 }
4663 }
4664 }
4665
4666 jQuery.merge( nodes, tmp.childNodes );
4667
4668 // Fix #12392 for WebKit and IE > 9
4669 tmp.textContent = "";
4670
4671 // Fix #12392 for oldIE
4672 while ( tmp.firstChild ) {
4673 tmp.removeChild( tmp.firstChild );
4674 }
4675
4676 // Remember the top-level container for proper cleanup
4677 tmp = safe.lastChild;
4678 }
4679 }
4680 }
4681
4682 // Fix #11356: Clear elements from fragment
4683 if ( tmp ) {
4684 safe.removeChild( tmp );
4685 }
4686
4687 // Reset defaultChecked for any radios and checkboxes
4688 // about to be appended to the DOM in IE 6/7 (#8060)
4689 if ( !support.appendChecked ) {
4690 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
4691 }
4692
4693 i = 0;
4694 while ( ( elem = nodes[ i++ ] ) ) {
4695
4696 // Skip elements already in the context collection (trac-4087)
4697 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4698 if ( ignored ) {
4699 ignored.push( elem );
4700 }
4701
4702 continue;
4703 }
4704
4705 contains = jQuery.contains( elem.ownerDocument, elem );
4706
4707 // Append to fragment
4708 tmp = getAll( safe.appendChild( elem ), "script" );
4709
4710 // Preserve script evaluation history
4711 if ( contains ) {
4712 setGlobalEval( tmp );
4713 }
4714
4715 // Capture executables
4716 if ( scripts ) {
4717 j = 0;
4718 while ( ( elem = tmp[ j++ ] ) ) {
4719 if ( rscriptType.test( elem.type || "" ) ) {
4720 scripts.push( elem );
4721 }
4722 }
4723 }
4724 }
4725
4726 tmp = null;
4727
4728 return safe;
4729}
4730
4731
4732( function() {
4733 var i, eventName,
4734 div = document.createElement( "div" );
4735
4736 // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4737 for ( i in { submit: true, change: true, focusin: true } ) {
4738 eventName = "on" + i;
4739
4740 if ( !( support[ i ] = eventName in window ) ) {
4741
4742 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4743 div.setAttribute( eventName, "t" );
4744 support[ i ] = div.attributes[ eventName ].expando === false;
4745 }
4746 }
4747
4748 // Null elements to avoid leaks in IE.
4749 div = null;
4750} )();
4751
4752
4753var rformElems = /^(?:input|select|textarea)$/i,
4754 rkeyEvent = /^key/,
4755 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4756 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4757 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4758
4759function returnTrue() {
4760 return true;
4761}
4762
4763function returnFalse() {
4764 return false;
4765}
4766
4767// Support: IE9
4768// See #13393 for more info
4769function safeActiveElement() {
4770 try {
4771 return document.activeElement;
4772 } catch ( err ) { }
4773}
4774
4775function on( elem, types, selector, data, fn, one ) {
4776 var origFn, type;
4777
4778 // Types can be a map of types/handlers
4779 if ( typeof types === "object" ) {
4780
4781 // ( types-Object, selector, data )
4782 if ( typeof selector !== "string" ) {
4783
4784 // ( types-Object, data )
4785 data = data || selector;
4786 selector = undefined;
4787 }
4788 for ( type in types ) {
4789 on( elem, type, selector, data, types[ type ], one );
4790 }
4791 return elem;
4792 }
4793
4794 if ( data == null && fn == null ) {
4795
4796 // ( types, fn )
4797 fn = selector;
4798 data = selector = undefined;
4799 } else if ( fn == null ) {
4800 if ( typeof selector === "string" ) {
4801
4802 // ( types, selector, fn )
4803 fn = data;
4804 data = undefined;
4805 } else {
4806
4807 // ( types, data, fn )
4808 fn = data;
4809 data = selector;
4810 selector = undefined;
4811 }
4812 }
4813 if ( fn === false ) {
4814 fn = returnFalse;
4815 } else if ( !fn ) {
4816 return elem;
4817 }
4818
4819 if ( one === 1 ) {
4820 origFn = fn;
4821 fn = function( event ) {
4822
4823 // Can use an empty set, since event contains the info
4824 jQuery().off( event );
4825 return origFn.apply( this, arguments );
4826 };
4827
4828 // Use same guid so caller can remove using origFn
4829 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4830 }
4831 return elem.each( function() {
4832 jQuery.event.add( this, types, fn, data, selector );
4833 } );
4834}
4835
4836/*
4837 * Helper functions for managing events -- not part of the public interface.
4838 * Props to Dean Edwards' addEvent library for many of the ideas.
4839 */
4840jQuery.event = {
4841
4842 global: {},
4843
4844 add: function( elem, types, handler, data, selector ) {
4845 var tmp, events, t, handleObjIn,
4846 special, eventHandle, handleObj,
4847 handlers, type, namespaces, origType,
4848 elemData = jQuery._data( elem );
4849
4850 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4851 if ( !elemData ) {
4852 return;
4853 }
4854
4855 // Caller can pass in an object of custom data in lieu of the handler
4856 if ( handler.handler ) {
4857 handleObjIn = handler;
4858 handler = handleObjIn.handler;
4859 selector = handleObjIn.selector;
4860 }
4861
4862 // Make sure that the handler has a unique ID, used to find/remove it later
4863 if ( !handler.guid ) {
4864 handler.guid = jQuery.guid++;
4865 }
4866
4867 // Init the element's event structure and main handler, if this is the first
4868 if ( !( events = elemData.events ) ) {
4869 events = elemData.events = {};
4870 }
4871 if ( !( eventHandle = elemData.handle ) ) {
4872 eventHandle = elemData.handle = function( e ) {
4873
4874 // Discard the second event of a jQuery.event.trigger() and
4875 // when an event is called after a page has unloaded
4876 return typeof jQuery !== "undefined" &&
4877 ( !e || jQuery.event.triggered !== e.type ) ?
4878 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4879 undefined;
4880 };
4881
4882 // Add elem as a property of the handle fn to prevent a memory leak
4883 // with IE non-native events
4884 eventHandle.elem = elem;
4885 }
4886
4887 // Handle multiple events separated by a space
4888 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4889 t = types.length;
4890 while ( t-- ) {
4891 tmp = rtypenamespace.exec( types[ t ] ) || [];
4892 type = origType = tmp[ 1 ];
4893 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4894
4895 // There *must* be a type, no attaching namespace-only handlers
4896 if ( !type ) {
4897 continue;
4898 }
4899
4900 // If event changes its type, use the special event handlers for the changed type
4901 special = jQuery.event.special[ type ] || {};
4902
4903 // If selector defined, determine special event api type, otherwise given type
4904 type = ( selector ? special.delegateType : special.bindType ) || type;
4905
4906 // Update special based on newly reset type
4907 special = jQuery.event.special[ type ] || {};
4908
4909 // handleObj is passed to all event handlers
4910 handleObj = jQuery.extend( {
4911 type: type,
4912 origType: origType,
4913 data: data,
4914 handler: handler,
4915 guid: handler.guid,
4916 selector: selector,
4917 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4918 namespace: namespaces.join( "." )
4919 }, handleObjIn );
4920
4921 // Init the event handler queue if we're the first
4922 if ( !( handlers = events[ type ] ) ) {
4923 handlers = events[ type ] = [];
4924 handlers.delegateCount = 0;
4925
4926 // Only use addEventListener/attachEvent if the special events handler returns false
4927 if ( !special.setup ||
4928 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4929
4930 // Bind the global event handler to the element
4931 if ( elem.addEventListener ) {
4932 elem.addEventListener( type, eventHandle, false );
4933
4934 } else if ( elem.attachEvent ) {
4935 elem.attachEvent( "on" + type, eventHandle );
4936 }
4937 }
4938 }
4939
4940 if ( special.add ) {
4941 special.add.call( elem, handleObj );
4942
4943 if ( !handleObj.handler.guid ) {
4944 handleObj.handler.guid = handler.guid;
4945 }
4946 }
4947
4948 // Add to the element's handler list, delegates in front
4949 if ( selector ) {
4950 handlers.splice( handlers.delegateCount++, 0, handleObj );
4951 } else {
4952 handlers.push( handleObj );
4953 }
4954
4955 // Keep track of which events have ever been used, for event optimization
4956 jQuery.event.global[ type ] = true;
4957 }
4958
4959 // Nullify elem to prevent memory leaks in IE
4960 elem = null;
4961 },
4962
4963 // Detach an event or set of events from an element
4964 remove: function( elem, types, handler, selector, mappedTypes ) {
4965 var j, handleObj, tmp,
4966 origCount, t, events,
4967 special, handlers, type,
4968 namespaces, origType,
4969 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4970
4971 if ( !elemData || !( events = elemData.events ) ) {
4972 return;
4973 }
4974
4975 // Once for each type.namespace in types; type may be omitted
4976 types = ( types || "" ).match( rnotwhite ) || [ "" ];
4977 t = types.length;
4978 while ( t-- ) {
4979 tmp = rtypenamespace.exec( types[ t ] ) || [];
4980 type = origType = tmp[ 1 ];
4981 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4982
4983 // Unbind all events (on this namespace, if provided) for the element
4984 if ( !type ) {
4985 for ( type in events ) {
4986 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4987 }
4988 continue;
4989 }
4990
4991 special = jQuery.event.special[ type ] || {};
4992 type = ( selector ? special.delegateType : special.bindType ) || type;
4993 handlers = events[ type ] || [];
4994 tmp = tmp[ 2 ] &&
4995 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4996
4997 // Remove matching events
4998 origCount = j = handlers.length;
4999 while ( j-- ) {
5000 handleObj = handlers[ j ];
5001
5002 if ( ( mappedTypes || origType === handleObj.origType ) &&
5003 ( !handler || handler.guid === handleObj.guid ) &&
5004 ( !tmp || tmp.test( handleObj.namespace ) ) &&
5005 ( !selector || selector === handleObj.selector ||
5006 selector === "**" && handleObj.selector ) ) {
5007 handlers.splice( j, 1 );
5008
5009 if ( handleObj.selector ) {
5010 handlers.delegateCount--;
5011 }
5012 if ( special.remove ) {
5013 special.remove.call( elem, handleObj );
5014 }
5015 }
5016 }
5017
5018 // Remove generic event handler if we removed something and no more handlers exist
5019 // (avoids potential for endless recursion during removal of special event handlers)
5020 if ( origCount && !handlers.length ) {
5021 if ( !special.teardown ||
5022 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5023
5024 jQuery.removeEvent( elem, type, elemData.handle );
5025 }
5026
5027 delete events[ type ];
5028 }
5029 }
5030
5031 // Remove the expando if it's no longer used
5032 if ( jQuery.isEmptyObject( events ) ) {
5033 delete elemData.handle;
5034
5035 // removeData also checks for emptiness and clears the expando if empty
5036 // so use it instead of delete
5037 jQuery._removeData( elem, "events" );
5038 }
5039 },
5040
5041 trigger: function( event, data, elem, onlyHandlers ) {
5042 var handle, ontype, cur,
5043 bubbleType, special, tmp, i,
5044 eventPath = [ elem || document ],
5045 type = hasOwn.call( event, "type" ) ? event.type : event,
5046 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
5047
5048 cur = tmp = elem = elem || document;
5049
5050 // Don't do events on text and comment nodes
5051 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
5052 return;
5053 }
5054
5055 // focus/blur morphs to focusin/out; ensure we're not firing them right now
5056 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
5057 return;
5058 }
5059
5060 if ( type.indexOf( "." ) > -1 ) {
5061
5062 // Namespaced trigger; create a regexp to match event type in handle()
5063 namespaces = type.split( "." );
5064 type = namespaces.shift();
5065 namespaces.sort();
5066 }
5067 ontype = type.indexOf( ":" ) < 0 && "on" + type;
5068
5069 // Caller can pass in a jQuery.Event object, Object, or just an event type string
5070 event = event[ jQuery.expando ] ?
5071 event :
5072 new jQuery.Event( type, typeof event === "object" && event );
5073
5074 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
5075 event.isTrigger = onlyHandlers ? 2 : 3;
5076 event.namespace = namespaces.join( "." );
5077 event.rnamespace = event.namespace ?
5078 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
5079 null;
5080
5081 // Clean up the event in case it is being reused
5082 event.result = undefined;
5083 if ( !event.target ) {
5084 event.target = elem;
5085 }
5086
5087 // Clone any incoming data and prepend the event, creating the handler arg list
5088 data = data == null ?
5089 [ event ] :
5090 jQuery.makeArray( data, [ event ] );
5091
5092 // Allow special events to draw outside the lines
5093 special = jQuery.event.special[ type ] || {};
5094 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
5095 return;
5096 }
5097
5098 // Determine event propagation path in advance, per W3C events spec (#9951)
5099 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
5100 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
5101
5102 bubbleType = special.delegateType || type;
5103 if ( !rfocusMorph.test( bubbleType + type ) ) {
5104 cur = cur.parentNode;
5105 }
5106 for ( ; cur; cur = cur.parentNode ) {
5107 eventPath.push( cur );
5108 tmp = cur;
5109 }
5110
5111 // Only add window if we got to document (e.g., not plain obj or detached DOM)
5112 if ( tmp === ( elem.ownerDocument || document ) ) {
5113 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
5114 }
5115 }
5116
5117 // Fire handlers on the event path
5118 i = 0;
5119 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
5120
5121 event.type = i > 1 ?
5122 bubbleType :
5123 special.bindType || type;
5124
5125 // jQuery handler
5126 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
5127 jQuery._data( cur, "handle" );
5128
5129 if ( handle ) {
5130 handle.apply( cur, data );
5131 }
5132
5133 // Native handler
5134 handle = ontype && cur[ ontype ];
5135 if ( handle && handle.apply && acceptData( cur ) ) {
5136 event.result = handle.apply( cur, data );
5137 if ( event.result === false ) {
5138 event.preventDefault();
5139 }
5140 }
5141 }
5142 event.type = type;
5143
5144 // If nobody prevented the default action, do it now
5145 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
5146
5147 if (
5148 ( !special._default ||
5149 special._default.apply( eventPath.pop(), data ) === false
5150 ) && acceptData( elem )
5151 ) {
5152
5153 // Call a native DOM method on the target with the same name name as the event.
5154 // Can't use an .isFunction() check here because IE6/7 fails that test.
5155 // Don't do default actions on window, that's where global variables be (#6170)
5156 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
5157
5158 // Don't re-trigger an onFOO event when we call its FOO() method
5159 tmp = elem[ ontype ];
5160
5161 if ( tmp ) {
5162 elem[ ontype ] = null;
5163 }
5164
5165 // Prevent re-triggering of the same event, since we already bubbled it above
5166 jQuery.event.triggered = type;
5167 try {
5168 elem[ type ]();
5169 } catch ( e ) {
5170
5171 // IE<9 dies on focus/blur to hidden element (#1486,#12518)
5172 // only reproducible on winXP IE8 native, not IE9 in IE8 mode
5173 }
5174 jQuery.event.triggered = undefined;
5175
5176 if ( tmp ) {
5177 elem[ ontype ] = tmp;
5178 }
5179 }
5180 }
5181 }
5182
5183 return event.result;
5184 },
5185
5186 dispatch: function( event ) {
5187
5188 // Make a writable jQuery.Event from the native event object
5189 event = jQuery.event.fix( event );
5190
5191 var i, j, ret, matched, handleObj,
5192 handlerQueue = [],
5193 args = slice.call( arguments ),
5194 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
5195 special = jQuery.event.special[ event.type ] || {};
5196
5197 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5198 args[ 0 ] = event;
5199 event.delegateTarget = this;
5200
5201 // Call the preDispatch hook for the mapped type, and let it bail if desired
5202 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5203 return;
5204 }
5205
5206 // Determine handlers
5207 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5208
5209 // Run delegates first; they may want to stop propagation beneath us
5210 i = 0;
5211 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5212 event.currentTarget = matched.elem;
5213
5214 j = 0;
5215 while ( ( handleObj = matched.handlers[ j++ ] ) &&
5216 !event.isImmediatePropagationStopped() ) {
5217
5218 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
5219 // a subset or equal to those in the bound event (both can have no namespace).
5220 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5221
5222 event.handleObj = handleObj;
5223 event.data = handleObj.data;
5224
5225 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5226 handleObj.handler ).apply( matched.elem, args );
5227
5228 if ( ret !== undefined ) {
5229 if ( ( event.result = ret ) === false ) {
5230 event.preventDefault();
5231 event.stopPropagation();
5232 }
5233 }
5234 }
5235 }
5236 }
5237
5238 // Call the postDispatch hook for the mapped type
5239 if ( special.postDispatch ) {
5240 special.postDispatch.call( this, event );
5241 }
5242
5243 return event.result;
5244 },
5245
5246 handlers: function( event, handlers ) {
5247 var i, matches, sel, handleObj,
5248 handlerQueue = [],
5249 delegateCount = handlers.delegateCount,
5250 cur = event.target;
5251
5252 // Support (at least): Chrome, IE9
5253 // Find delegate handlers
5254 // Black-hole SVG <use> instance trees (#13180)
5255 //
5256 // Support: Firefox<=42+
5257 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5258 if ( delegateCount && cur.nodeType &&
5259 ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5260
5261 /* jshint eqeqeq: false */
5262 for ( ; cur != this; cur = cur.parentNode || this ) {
5263 /* jshint eqeqeq: true */
5264
5265 // Don't check non-elements (#13208)
5266 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5267 if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5268 matches = [];
5269 for ( i = 0; i < delegateCount; i++ ) {
5270 handleObj = handlers[ i ];
5271
5272 // Don't conflict with Object.prototype properties (#13203)
5273 sel = handleObj.selector + " ";
5274
5275 if ( matches[ sel ] === undefined ) {
5276 matches[ sel ] = handleObj.needsContext ?
5277 jQuery( sel, this ).index( cur ) > -1 :
5278 jQuery.find( sel, this, null, [ cur ] ).length;
5279 }
5280 if ( matches[ sel ] ) {
5281 matches.push( handleObj );
5282 }
5283 }
5284 if ( matches.length ) {
5285 handlerQueue.push( { elem: cur, handlers: matches } );
5286 }
5287 }
5288 }
5289 }
5290
5291 // Add the remaining (directly-bound) handlers
5292 if ( delegateCount < handlers.length ) {
5293 handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5294 }
5295
5296 return handlerQueue;
5297 },
5298
5299 fix: function( event ) {
5300 if ( event[ jQuery.expando ] ) {
5301 return event;
5302 }
5303
5304 // Create a writable copy of the event object and normalize some properties
5305 var i, prop, copy,
5306 type = event.type,
5307 originalEvent = event,
5308 fixHook = this.fixHooks[ type ];
5309
5310 if ( !fixHook ) {
5311 this.fixHooks[ type ] = fixHook =
5312 rmouseEvent.test( type ) ? this.mouseHooks :
5313 rkeyEvent.test( type ) ? this.keyHooks :
5314 {};
5315 }
5316 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5317
5318 event = new jQuery.Event( originalEvent );
5319
5320 i = copy.length;
5321 while ( i-- ) {
5322 prop = copy[ i ];
5323 event[ prop ] = originalEvent[ prop ];
5324 }
5325
5326 // Support: IE<9
5327 // Fix target property (#1925)
5328 if ( !event.target ) {
5329 event.target = originalEvent.srcElement || document;
5330 }
5331
5332 // Support: Safari 6-8+
5333 // Target should not be a text node (#504, #13143)
5334 if ( event.target.nodeType === 3 ) {
5335 event.target = event.target.parentNode;
5336 }
5337
5338 // Support: IE<9
5339 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5340 event.metaKey = !!event.metaKey;
5341
5342 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5343 },
5344
5345 // Includes some event props shared by KeyEvent and MouseEvent
5346 props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5347 "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5348
5349 fixHooks: {},
5350
5351 keyHooks: {
5352 props: "char charCode key keyCode".split( " " ),
5353 filter: function( event, original ) {
5354
5355 // Add which for key events
5356 if ( event.which == null ) {
5357 event.which = original.charCode != null ? original.charCode : original.keyCode;
5358 }
5359
5360 return event;
5361 }
5362 },
5363
5364 mouseHooks: {
5365 props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
5366 "pageX pageY screenX screenY toElement" ).split( " " ),
5367 filter: function( event, original ) {
5368 var body, eventDoc, doc,
5369 button = original.button,
5370 fromElement = original.fromElement;
5371
5372 // Calculate pageX/Y if missing and clientX/Y available
5373 if ( event.pageX == null && original.clientX != null ) {
5374 eventDoc = event.target.ownerDocument || document;
5375 doc = eventDoc.documentElement;
5376 body = eventDoc.body;
5377
5378 event.pageX = original.clientX +
5379 ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5380 ( doc && doc.clientLeft || body && body.clientLeft || 0 );
5381 event.pageY = original.clientY +
5382 ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
5383 ( doc && doc.clientTop || body && body.clientTop || 0 );
5384 }
5385
5386 // Add relatedTarget, if necessary
5387 if ( !event.relatedTarget && fromElement ) {
5388 event.relatedTarget = fromElement === event.target ?
5389 original.toElement :
5390 fromElement;
5391 }
5392
5393 // Add which for click: 1 === left; 2 === middle; 3 === right
5394 // Note: button is not normalized, so don't use it
5395 if ( !event.which && button !== undefined ) {
5396 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5397 }
5398
5399 return event;
5400 }
5401 },
5402
5403 special: {
5404 load: {
5405
5406 // Prevent triggered image.load events from bubbling to window.load
5407 noBubble: true
5408 },
5409 focus: {
5410
5411 // Fire native event if possible so blur/focus sequence is correct
5412 trigger: function() {
5413 if ( this !== safeActiveElement() && this.focus ) {
5414 try {
5415 this.focus();
5416 return false;
5417 } catch ( e ) {
5418
5419 // Support: IE<9
5420 // If we error on focus to hidden element (#1486, #12518),
5421 // let .trigger() run the handlers
5422 }
5423 }
5424 },
5425 delegateType: "focusin"
5426 },
5427 blur: {
5428 trigger: function() {
5429 if ( this === safeActiveElement() && this.blur ) {
5430 this.blur();
5431 return false;
5432 }
5433 },
5434 delegateType: "focusout"
5435 },
5436 click: {
5437
5438 // For checkbox, fire native event so checked state will be right
5439 trigger: function() {
5440 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
5441 this.click();
5442 return false;
5443 }
5444 },
5445
5446 // For cross-browser consistency, don't fire native .click() on links
5447 _default: function( event ) {
5448 return jQuery.nodeName( event.target, "a" );
5449 }
5450 },
5451
5452 beforeunload: {
5453 postDispatch: function( event ) {
5454
5455 // Support: Firefox 20+
5456 // Firefox doesn't alert if the returnValue field is not set.
5457 if ( event.result !== undefined && event.originalEvent ) {
5458 event.originalEvent.returnValue = event.result;
5459 }
5460 }
5461 }
5462 },
5463
5464 // Piggyback on a donor event to simulate a different one
5465 simulate: function( type, elem, event ) {
5466 var e = jQuery.extend(
5467 new jQuery.Event(),
5468 event,
5469 {
5470 type: type,
5471 isSimulated: true
5472
5473 // Previously, `originalEvent: {}` was set here, so stopPropagation call
5474 // would not be triggered on donor event, since in our own
5475 // jQuery.event.stopPropagation function we had a check for existence of
5476 // originalEvent.stopPropagation method, so, consequently it would be a noop.
5477 //
5478 // Guard for simulated events was moved to jQuery.event.stopPropagation function
5479 // since `originalEvent` should point to the original event for the
5480 // constancy with other events and for more focused logic
5481 }
5482 );
5483
5484 jQuery.event.trigger( e, null, elem );
5485
5486 if ( e.isDefaultPrevented() ) {
5487 event.preventDefault();
5488 }
5489 }
5490};
5491
5492jQuery.removeEvent = document.removeEventListener ?
5493 function( elem, type, handle ) {
5494
5495 // This "if" is needed for plain objects
5496 if ( elem.removeEventListener ) {
5497 elem.removeEventListener( type, handle );
5498 }
5499 } :
5500 function( elem, type, handle ) {
5501 var name = "on" + type;
5502
5503 if ( elem.detachEvent ) {
5504
5505 // #8545, #7054, preventing memory leaks for custom events in IE6-8
5506 // detachEvent needed property on element, by name of that event,
5507 // to properly expose it to GC
5508 if ( typeof elem[ name ] === "undefined" ) {
5509 elem[ name ] = null;
5510 }
5511
5512 elem.detachEvent( name, handle );
5513 }
5514 };
5515
5516jQuery.Event = function( src, props ) {
5517
5518 // Allow instantiation without the 'new' keyword
5519 if ( !( this instanceof jQuery.Event ) ) {
5520 return new jQuery.Event( src, props );
5521 }
5522
5523 // Event object
5524 if ( src && src.type ) {
5525 this.originalEvent = src;
5526 this.type = src.type;
5527
5528 // Events bubbling up the document may have been marked as prevented
5529 // by a handler lower down the tree; reflect the correct value.
5530 this.isDefaultPrevented = src.defaultPrevented ||
5531 src.defaultPrevented === undefined &&
5532
5533 // Support: IE < 9, Android < 4.0
5534 src.returnValue === false ?
5535 returnTrue :
5536 returnFalse;
5537
5538 // Event type
5539 } else {
5540 this.type = src;
5541 }
5542
5543 // Put explicitly provided properties onto the event object
5544 if ( props ) {
5545 jQuery.extend( this, props );
5546 }
5547
5548 // Create a timestamp if incoming event doesn't have one
5549 this.timeStamp = src && src.timeStamp || jQuery.now();
5550
5551 // Mark it as fixed
5552 this[ jQuery.expando ] = true;
5553};
5554
5555// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5556// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5557jQuery.Event.prototype = {
5558 constructor: jQuery.Event,
5559 isDefaultPrevented: returnFalse,
5560 isPropagationStopped: returnFalse,
5561 isImmediatePropagationStopped: returnFalse,
5562
5563 preventDefault: function() {
5564 var e = this.originalEvent;
5565
5566 this.isDefaultPrevented = returnTrue;
5567 if ( !e ) {
5568 return;
5569 }
5570
5571 // If preventDefault exists, run it on the original event
5572 if ( e.preventDefault ) {
5573 e.preventDefault();
5574
5575 // Support: IE
5576 // Otherwise set the returnValue property of the original event to false
5577 } else {
5578 e.returnValue = false;
5579 }
5580 },
5581 stopPropagation: function() {
5582 var e = this.originalEvent;
5583
5584 this.isPropagationStopped = returnTrue;
5585
5586 if ( !e || this.isSimulated ) {
5587 return;
5588 }
5589
5590 // If stopPropagation exists, run it on the original event
5591 if ( e.stopPropagation ) {
5592 e.stopPropagation();
5593 }
5594
5595 // Support: IE
5596 // Set the cancelBubble property of the original event to true
5597 e.cancelBubble = true;
5598 },
5599 stopImmediatePropagation: function() {
5600 var e = this.originalEvent;
5601
5602 this.isImmediatePropagationStopped = returnTrue;
5603
5604 if ( e && e.stopImmediatePropagation ) {
5605 e.stopImmediatePropagation();
5606 }
5607
5608 this.stopPropagation();
5609 }
5610};
5611
5612// Create mouseenter/leave events using mouseover/out and event-time checks
5613// so that event delegation works in jQuery.
5614// Do the same for pointerenter/pointerleave and pointerover/pointerout
5615//
5616// Support: Safari 7 only
5617// Safari sends mouseenter too often; see:
5618// https://code.google.com/p/chromium/issues/detail?id=470258
5619// for the description of the bug (it existed in older Chrome versions as well).
5620jQuery.each( {
5621 mouseenter: "mouseover",
5622 mouseleave: "mouseout",
5623 pointerenter: "pointerover",
5624 pointerleave: "pointerout"
5625}, function( orig, fix ) {
5626 jQuery.event.special[ orig ] = {
5627 delegateType: fix,
5628 bindType: fix,
5629
5630 handle: function( event ) {
5631 var ret,
5632 target = this,
5633 related = event.relatedTarget,
5634 handleObj = event.handleObj;
5635
5636 // For mouseenter/leave call the handler if related is outside the target.
5637 // NB: No relatedTarget if the mouse left/entered the browser window
5638 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5639 event.type = handleObj.origType;
5640 ret = handleObj.handler.apply( this, arguments );
5641 event.type = fix;
5642 }
5643 return ret;
5644 }
5645 };
5646} );
5647
5648// IE submit delegation
5649if ( !support.submit ) {
5650
5651 jQuery.event.special.submit = {
5652 setup: function() {
5653
5654 // Only need this for delegated form submit events
5655 if ( jQuery.nodeName( this, "form" ) ) {
5656 return false;
5657 }
5658
5659 // Lazy-add a submit handler when a descendant form may potentially be submitted
5660 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5661
5662 // Node name check avoids a VML-related crash in IE (#9807)
5663 var elem = e.target,
5664 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
5665
5666 // Support: IE <=8
5667 // We use jQuery.prop instead of elem.form
5668 // to allow fixing the IE8 delegated submit issue (gh-2332)
5669 // by 3rd party polyfills/workarounds.
5670 jQuery.prop( elem, "form" ) :
5671 undefined;
5672
5673 if ( form && !jQuery._data( form, "submit" ) ) {
5674 jQuery.event.add( form, "submit._submit", function( event ) {
5675 event._submitBubble = true;
5676 } );
5677 jQuery._data( form, "submit", true );
5678 }
5679 } );
5680
5681 // return undefined since we don't need an event listener
5682 },
5683
5684 postDispatch: function( event ) {
5685
5686 // If form was submitted by the user, bubble the event up the tree
5687 if ( event._submitBubble ) {
5688 delete event._submitBubble;
5689 if ( this.parentNode && !event.isTrigger ) {
5690 jQuery.event.simulate( "submit", this.parentNode, event );
5691 }
5692 }
5693 },
5694
5695 teardown: function() {
5696
5697 // Only need this for delegated form submit events
5698 if ( jQuery.nodeName( this, "form" ) ) {
5699 return false;
5700 }
5701
5702 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5703 jQuery.event.remove( this, "._submit" );
5704 }
5705 };
5706}
5707
5708// IE change delegation and checkbox/radio fix
5709if ( !support.change ) {
5710
5711 jQuery.event.special.change = {
5712
5713 setup: function() {
5714
5715 if ( rformElems.test( this.nodeName ) ) {
5716
5717 // IE doesn't fire change on a check/radio until blur; trigger it on click
5718 // after a propertychange. Eat the blur-change in special.change.handle.
5719 // This still fires onchange a second time for check/radio after blur.
5720 if ( this.type === "checkbox" || this.type === "radio" ) {
5721 jQuery.event.add( this, "propertychange._change", function( event ) {
5722 if ( event.originalEvent.propertyName === "checked" ) {
5723 this._justChanged = true;
5724 }
5725 } );
5726 jQuery.event.add( this, "click._change", function( event ) {
5727 if ( this._justChanged && !event.isTrigger ) {
5728 this._justChanged = false;
5729 }
5730
5731 // Allow triggered, simulated change events (#11500)
5732 jQuery.event.simulate( "change", this, event );
5733 } );
5734 }
5735 return false;
5736 }
5737
5738 // Delegated event; lazy-add a change handler on descendant inputs
5739 jQuery.event.add( this, "beforeactivate._change", function( e ) {
5740 var elem = e.target;
5741
5742 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
5743 jQuery.event.add( elem, "change._change", function( event ) {
5744 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5745 jQuery.event.simulate( "change", this.parentNode, event );
5746 }
5747 } );
5748 jQuery._data( elem, "change", true );
5749 }
5750 } );
5751 },
5752
5753 handle: function( event ) {
5754 var elem = event.target;
5755
5756 // Swallow native change events from checkbox/radio, we already triggered them above
5757 if ( this !== elem || event.isSimulated || event.isTrigger ||
5758 ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
5759
5760 return event.handleObj.handler.apply( this, arguments );
5761 }
5762 },
5763
5764 teardown: function() {
5765 jQuery.event.remove( this, "._change" );
5766
5767 return !rformElems.test( this.nodeName );
5768 }
5769 };
5770}
5771
5772// Support: Firefox
5773// Firefox doesn't have focus(in | out) events
5774// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5775//
5776// Support: Chrome, Safari
5777// focus(in | out) events fire after focus & blur events,
5778// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5779// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5780if ( !support.focusin ) {
5781 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5782
5783 // Attach a single capturing handler on the document while someone wants focusin/focusout
5784 var handler = function( event ) {
5785 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
5786 };
5787
5788 jQuery.event.special[ fix ] = {
5789 setup: function() {
5790 var doc = this.ownerDocument || this,
5791 attaches = jQuery._data( doc, fix );
5792
5793 if ( !attaches ) {
5794 doc.addEventListener( orig, handler, true );
5795 }
5796 jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5797 },
5798 teardown: function() {
5799 var doc = this.ownerDocument || this,
5800 attaches = jQuery._data( doc, fix ) - 1;
5801
5802 if ( !attaches ) {
5803 doc.removeEventListener( orig, handler, true );
5804 jQuery._removeData( doc, fix );
5805 } else {
5806 jQuery._data( doc, fix, attaches );
5807 }
5808 }
5809 };
5810 } );
5811}
5812
5813jQuery.fn.extend( {
5814
5815 on: function( types, selector, data, fn ) {
5816 return on( this, types, selector, data, fn );
5817 },
5818 one: function( types, selector, data, fn ) {
5819 return on( this, types, selector, data, fn, 1 );
5820 },
5821 off: function( types, selector, fn ) {
5822 var handleObj, type;
5823 if ( types && types.preventDefault && types.handleObj ) {
5824
5825 // ( event ) dispatched jQuery.Event
5826 handleObj = types.handleObj;
5827 jQuery( types.delegateTarget ).off(
5828 handleObj.namespace ?
5829 handleObj.origType + "." + handleObj.namespace :
5830 handleObj.origType,
5831 handleObj.selector,
5832 handleObj.handler
5833 );
5834 return this;
5835 }
5836 if ( typeof types === "object" ) {
5837
5838 // ( types-object [, selector] )
5839 for ( type in types ) {
5840 this.off( type, selector, types[ type ] );
5841 }
5842 return this;
5843 }
5844 if ( selector === false || typeof selector === "function" ) {
5845
5846 // ( types [, fn] )
5847 fn = selector;
5848 selector = undefined;
5849 }
5850 if ( fn === false ) {
5851 fn = returnFalse;
5852 }
5853 return this.each( function() {
5854 jQuery.event.remove( this, types, fn, selector );
5855 } );
5856 },
5857
5858 trigger: function( type, data ) {
5859 return this.each( function() {
5860 jQuery.event.trigger( type, data, this );
5861 } );
5862 },
5863 triggerHandler: function( type, data ) {
5864 var elem = this[ 0 ];
5865 if ( elem ) {
5866 return jQuery.event.trigger( type, data, elem, true );
5867 }
5868 }
5869} );
5870
5871
5872var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5873 rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
5874 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5875
5876 // Support: IE 10-11, Edge 10240+
5877 // In IE/Edge using regex groups here causes severe slowdowns.
5878 // See https://connect.microsoft.com/IE/feedback/details/1736512/
5879 rnoInnerhtml = /<script|<style|<link/i,
5880
5881 // checked="checked" or checked
5882 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5883 rscriptTypeMasked = /^true\/(.*)/,
5884 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5885 safeFragment = createSafeFragment( document ),
5886 fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
5887
5888// Support: IE<8
5889// Manipulating tables requires a tbody
5890function manipulationTarget( elem, content ) {
5891 return jQuery.nodeName( elem, "table" ) &&
5892 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5893
5894 elem.getElementsByTagName( "tbody" )[ 0 ] ||
5895 elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5896 elem;
5897}
5898
5899// Replace/restore the type attribute of script elements for safe DOM manipulation
5900function disableScript( elem ) {
5901 elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
5902 return elem;
5903}
5904function restoreScript( elem ) {
5905 var match = rscriptTypeMasked.exec( elem.type );
5906 if ( match ) {
5907 elem.type = match[ 1 ];
5908 } else {
5909 elem.removeAttribute( "type" );
5910 }
5911 return elem;
5912}
5913
5914function cloneCopyEvent( src, dest ) {
5915 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5916 return;
5917 }
5918
5919 var type, i, l,
5920 oldData = jQuery._data( src ),
5921 curData = jQuery._data( dest, oldData ),
5922 events = oldData.events;
5923
5924 if ( events ) {
5925 delete curData.handle;
5926 curData.events = {};
5927
5928 for ( type in events ) {
5929 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5930 jQuery.event.add( dest, type, events[ type ][ i ] );
5931 }
5932 }
5933 }
5934
5935 // make the cloned public data object a copy from the original
5936 if ( curData.data ) {
5937 curData.data = jQuery.extend( {}, curData.data );
5938 }
5939}
5940
5941function fixCloneNodeIssues( src, dest ) {
5942 var nodeName, e, data;
5943
5944 // We do not need to do anything for non-Elements
5945 if ( dest.nodeType !== 1 ) {
5946 return;
5947 }
5948
5949 nodeName = dest.nodeName.toLowerCase();
5950
5951 // IE6-8 copies events bound via attachEvent when using cloneNode.
5952 if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5953 data = jQuery._data( dest );
5954
5955 for ( e in data.events ) {
5956 jQuery.removeEvent( dest, e, data.handle );
5957 }
5958
5959 // Event data gets referenced instead of copied if the expando gets copied too
5960 dest.removeAttribute( jQuery.expando );
5961 }
5962
5963 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5964 if ( nodeName === "script" && dest.text !== src.text ) {
5965 disableScript( dest ).text = src.text;
5966 restoreScript( dest );
5967
5968 // IE6-10 improperly clones children of object elements using classid.
5969 // IE10 throws NoModificationAllowedError if parent is null, #12132.
5970 } else if ( nodeName === "object" ) {
5971 if ( dest.parentNode ) {
5972 dest.outerHTML = src.outerHTML;
5973 }
5974
5975 // This path appears unavoidable for IE9. When cloning an object
5976 // element in IE9, the outerHTML strategy above is not sufficient.
5977 // If the src has innerHTML and the destination does not,
5978 // copy the src.innerHTML into the dest.innerHTML. #10324
5979 if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
5980 dest.innerHTML = src.innerHTML;
5981 }
5982
5983 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5984
5985 // IE6-8 fails to persist the checked state of a cloned checkbox
5986 // or radio button. Worse, IE6-7 fail to give the cloned element
5987 // a checked appearance if the defaultChecked value isn't also set
5988
5989 dest.defaultChecked = dest.checked = src.checked;
5990
5991 // IE6-7 get confused and end up setting the value of a cloned
5992 // checkbox/radio button to an empty string instead of "on"
5993 if ( dest.value !== src.value ) {
5994 dest.value = src.value;
5995 }
5996
5997 // IE6-8 fails to return the selected option to the default selected
5998 // state when cloning options
5999 } else if ( nodeName === "option" ) {
6000 dest.defaultSelected = dest.selected = src.defaultSelected;
6001
6002 // IE6-8 fails to set the defaultValue to the correct value when
6003 // cloning other types of input fields
6004 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6005 dest.defaultValue = src.defaultValue;
6006 }
6007}
6008
6009function domManip( collection, args, callback, ignored ) {
6010
6011 // Flatten any nested arrays
6012 args = concat.apply( [], args );
6013
6014 var first, node, hasScripts,
6015 scripts, doc, fragment,
6016 i = 0,
6017 l = collection.length,
6018 iNoClone = l - 1,
6019 value = args[ 0 ],
6020 isFunction = jQuery.isFunction( value );
6021
6022 // We can't cloneNode fragments that contain checked, in WebKit
6023 if ( isFunction ||
6024 ( l > 1 && typeof value === "string" &&
6025 !support.checkClone && rchecked.test( value ) ) ) {
6026 return collection.each( function( index ) {
6027 var self = collection.eq( index );
6028 if ( isFunction ) {
6029 args[ 0 ] = value.call( this, index, self.html() );
6030 }
6031 domManip( self, args, callback, ignored );
6032 } );
6033 }
6034
6035 if ( l ) {
6036 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6037 first = fragment.firstChild;
6038
6039 if ( fragment.childNodes.length === 1 ) {
6040 fragment = first;
6041 }
6042
6043 // Require either new content or an interest in ignored elements to invoke the callback
6044 if ( first || ignored ) {
6045 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6046 hasScripts = scripts.length;
6047
6048 // Use the original fragment for the last item
6049 // instead of the first because it can end up
6050 // being emptied incorrectly in certain situations (#8070).
6051 for ( ; i < l; i++ ) {
6052 node = fragment;
6053
6054 if ( i !== iNoClone ) {
6055 node = jQuery.clone( node, true, true );
6056
6057 // Keep references to cloned scripts for later restoration
6058 if ( hasScripts ) {
6059
6060 // Support: Android<4.1, PhantomJS<2
6061 // push.apply(_, arraylike) throws on ancient WebKit
6062 jQuery.merge( scripts, getAll( node, "script" ) );
6063 }
6064 }
6065
6066 callback.call( collection[ i ], node, i );
6067 }
6068
6069 if ( hasScripts ) {
6070 doc = scripts[ scripts.length - 1 ].ownerDocument;
6071
6072 // Reenable scripts
6073 jQuery.map( scripts, restoreScript );
6074
6075 // Evaluate executable scripts on first document insertion
6076 for ( i = 0; i < hasScripts; i++ ) {
6077 node = scripts[ i ];
6078 if ( rscriptType.test( node.type || "" ) &&
6079 !jQuery._data( node, "globalEval" ) &&
6080 jQuery.contains( doc, node ) ) {
6081
6082 if ( node.src ) {
6083
6084 // Optional AJAX dependency, but won't run scripts if not present
6085 if ( jQuery._evalUrl ) {
6086 jQuery._evalUrl( node.src );
6087 }
6088 } else {
6089 jQuery.globalEval(
6090 ( node.text || node.textContent || node.innerHTML || "" )
6091 .replace( rcleanScript, "" )
6092 );
6093 }
6094 }
6095 }
6096 }
6097
6098 // Fix #11809: Avoid leaking memory
6099 fragment = first = null;
6100 }
6101 }
6102
6103 return collection;
6104}
6105
6106function remove( elem, selector, keepData ) {
6107 var node,
6108 elems = selector ? jQuery.filter( selector, elem ) : elem,
6109 i = 0;
6110
6111 for ( ; ( node = elems[ i ] ) != null; i++ ) {
6112
6113 if ( !keepData && node.nodeType === 1 ) {
6114 jQuery.cleanData( getAll( node ) );
6115 }
6116
6117 if ( node.parentNode ) {
6118 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
6119 setGlobalEval( getAll( node, "script" ) );
6120 }
6121 node.parentNode.removeChild( node );
6122 }
6123 }
6124
6125 return elem;
6126}
6127
6128jQuery.extend( {
6129 htmlPrefilter: function( html ) {
6130 return html.replace( rxhtmlTag, "<$1></$2>" );
6131 },
6132
6133 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6134 var destElements, node, clone, i, srcElements,
6135 inPage = jQuery.contains( elem.ownerDocument, elem );
6136
6137 if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
6138 !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6139
6140 clone = elem.cloneNode( true );
6141
6142 // IE<=8 does not properly clone detached, unknown element nodes
6143 } else {
6144 fragmentDiv.innerHTML = elem.outerHTML;
6145 fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6146 }
6147
6148 if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
6149 ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
6150
6151 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
6152 destElements = getAll( clone );
6153 srcElements = getAll( elem );
6154
6155 // Fix all IE cloning issues
6156 for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
6157
6158 // Ensure that the destination node is not null; Fixes #9587
6159 if ( destElements[ i ] ) {
6160 fixCloneNodeIssues( node, destElements[ i ] );
6161 }
6162 }
6163 }
6164
6165 // Copy the events from the original to the clone
6166 if ( dataAndEvents ) {
6167 if ( deepDataAndEvents ) {
6168 srcElements = srcElements || getAll( elem );
6169 destElements = destElements || getAll( clone );
6170
6171 for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
6172 cloneCopyEvent( node, destElements[ i ] );
6173 }
6174 } else {
6175 cloneCopyEvent( elem, clone );
6176 }
6177 }
6178
6179 // Preserve script evaluation history
6180 destElements = getAll( clone, "script" );
6181 if ( destElements.length > 0 ) {
6182 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6183 }
6184
6185 destElements = srcElements = node = null;
6186
6187 // Return the cloned set
6188 return clone;
6189 },
6190
6191 cleanData: function( elems, /* internal */ forceAcceptData ) {
6192 var elem, type, id, data,
6193 i = 0,
6194 internalKey = jQuery.expando,
6195 cache = jQuery.cache,
6196 attributes = support.attributes,
6197 special = jQuery.event.special;
6198
6199 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
6200 if ( forceAcceptData || acceptData( elem ) ) {
6201
6202 id = elem[ internalKey ];
6203 data = id && cache[ id ];
6204
6205 if ( data ) {
6206 if ( data.events ) {
6207 for ( type in data.events ) {
6208 if ( special[ type ] ) {
6209 jQuery.event.remove( elem, type );
6210
6211 // This is a shortcut to avoid jQuery.event.remove's overhead
6212 } else {
6213 jQuery.removeEvent( elem, type, data.handle );
6214 }
6215 }
6216 }
6217
6218 // Remove cache only if it was not already removed by jQuery.event.remove
6219 if ( cache[ id ] ) {
6220
6221 delete cache[ id ];
6222
6223 // Support: IE<9
6224 // IE does not allow us to delete expando properties from nodes
6225 // IE creates expando attributes along with the property
6226 // IE does not have a removeAttribute function on Document nodes
6227 if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
6228 elem.removeAttribute( internalKey );
6229
6230 // Webkit & Blink performance suffers when deleting properties
6231 // from DOM nodes, so set to undefined instead
6232 // https://code.google.com/p/chromium/issues/detail?id=378607
6233 } else {
6234 elem[ internalKey ] = undefined;
6235 }
6236
6237 deletedIds.push( id );
6238 }
6239 }
6240 }
6241 }
6242 }
6243} );
6244
6245jQuery.fn.extend( {
6246
6247 // Keep domManip exposed until 3.0 (gh-2225)
6248 domManip: domManip,
6249
6250 detach: function( selector ) {
6251 return remove( this, selector, true );
6252 },
6253
6254 remove: function( selector ) {
6255 return remove( this, selector );
6256 },
6257
6258 text: function( value ) {
6259 return access( this, function( value ) {
6260 return value === undefined ?
6261 jQuery.text( this ) :
6262 this.empty().append(
6263 ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
6264 );
6265 }, null, value, arguments.length );
6266 },
6267
6268 append: function() {
6269 return domManip( this, arguments, function( elem ) {
6270 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6271 var target = manipulationTarget( this, elem );
6272 target.appendChild( elem );
6273 }
6274 } );
6275 },
6276
6277 prepend: function() {
6278 return domManip( this, arguments, function( elem ) {
6279 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6280 var target = manipulationTarget( this, elem );
6281 target.insertBefore( elem, target.firstChild );
6282 }
6283 } );
6284 },
6285
6286 before: function() {
6287 return domManip( this, arguments, function( elem ) {
6288 if ( this.parentNode ) {
6289 this.parentNode.insertBefore( elem, this );
6290 }
6291 } );
6292 },
6293
6294 after: function() {
6295 return domManip( this, arguments, function( elem ) {
6296 if ( this.parentNode ) {
6297 this.parentNode.insertBefore( elem, this.nextSibling );
6298 }
6299 } );
6300 },
6301
6302 empty: function() {
6303 var elem,
6304 i = 0;
6305
6306 for ( ; ( elem = this[ i ] ) != null; i++ ) {
6307
6308 // Remove element nodes and prevent memory leaks
6309 if ( elem.nodeType === 1 ) {
6310 jQuery.cleanData( getAll( elem, false ) );
6311 }
6312
6313 // Remove any remaining nodes
6314 while ( elem.firstChild ) {
6315 elem.removeChild( elem.firstChild );
6316 }
6317
6318 // If this is a select, ensure that it displays empty (#12336)
6319 // Support: IE<9
6320 if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
6321 elem.options.length = 0;
6322 }
6323 }
6324
6325 return this;
6326 },
6327
6328 clone: function( dataAndEvents, deepDataAndEvents ) {
6329 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6330 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6331
6332 return this.map( function() {
6333 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6334 } );
6335 },
6336
6337 html: function( value ) {
6338 return access( this, function( value ) {
6339 var elem = this[ 0 ] || {},
6340 i = 0,
6341 l = this.length;
6342
6343 if ( value === undefined ) {
6344 return elem.nodeType === 1 ?
6345 elem.innerHTML.replace( rinlinejQuery, "" ) :
6346 undefined;
6347 }
6348
6349 // See if we can take a shortcut and just use innerHTML
6350 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6351 ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
6352 ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
6353 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6354
6355 value = jQuery.htmlPrefilter( value );
6356
6357 try {
6358 for ( ; i < l; i++ ) {
6359
6360 // Remove element nodes and prevent memory leaks
6361 elem = this[ i ] || {};
6362 if ( elem.nodeType === 1 ) {
6363 jQuery.cleanData( getAll( elem, false ) );
6364 elem.innerHTML = value;
6365 }
6366 }
6367
6368 elem = 0;
6369
6370 // If using innerHTML throws an exception, use the fallback method
6371 } catch ( e ) {}
6372 }
6373
6374 if ( elem ) {
6375 this.empty().append( value );
6376 }
6377 }, null, value, arguments.length );
6378 },
6379
6380 replaceWith: function() {
6381 var ignored = [];
6382
6383 // Make the changes, replacing each non-ignored context element with the new content
6384 return domManip( this, arguments, function( elem ) {
6385 var parent = this.parentNode;
6386
6387 if ( jQuery.inArray( this, ignored ) < 0 ) {
6388 jQuery.cleanData( getAll( this ) );
6389 if ( parent ) {
6390 parent.replaceChild( elem, this );
6391 }
6392 }
6393
6394 // Force callback invocation
6395 }, ignored );
6396 }
6397} );
6398
6399jQuery.each( {
6400 appendTo: "append",
6401 prependTo: "prepend",
6402 insertBefore: "before",
6403 insertAfter: "after",
6404 replaceAll: "replaceWith"
6405}, function( name, original ) {
6406 jQuery.fn[ name ] = function( selector ) {
6407 var elems,
6408 i = 0,
6409 ret = [],
6410 insert = jQuery( selector ),
6411 last = insert.length - 1;
6412
6413 for ( ; i <= last; i++ ) {
6414 elems = i === last ? this : this.clone( true );
6415 jQuery( insert[ i ] )[ original ]( elems );
6416
6417 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6418 push.apply( ret, elems.get() );
6419 }
6420
6421 return this.pushStack( ret );
6422 };
6423} );
6424
6425
6426var iframe,
6427 elemdisplay = {
6428
6429 // Support: Firefox
6430 // We have to pre-define these values for FF (#10227)
6431 HTML: "block",
6432 BODY: "block"
6433 };
6434
6435/**
6436 * Retrieve the actual display of a element
6437 * @param {String} name nodeName of the element
6438 * @param {Object} doc Document object
6439 */
6440
6441// Called only from within defaultDisplay
6442function actualDisplay( name, doc ) {
6443 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6444
6445 display = jQuery.css( elem[ 0 ], "display" );
6446
6447 // We don't have any data stored on the element,
6448 // so use "detach" method as fast way to get rid of the element
6449 elem.detach();
6450
6451 return display;
6452}
6453
6454/**
6455 * Try to determine the default display value of an element
6456 * @param {String} nodeName
6457 */
6458function defaultDisplay( nodeName ) {
6459 var doc = document,
6460 display = elemdisplay[ nodeName ];
6461
6462 if ( !display ) {
6463 display = actualDisplay( nodeName, doc );
6464
6465 // If the simple way fails, read from inside an iframe
6466 if ( display === "none" || !display ) {
6467
6468 // Use the already-created iframe if possible
6469 iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
6470 .appendTo( doc.documentElement );
6471
6472 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6473 doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6474
6475 // Support: IE
6476 doc.write();
6477 doc.close();
6478
6479 display = actualDisplay( nodeName, doc );
6480 iframe.detach();
6481 }
6482
6483 // Store the correct default display
6484 elemdisplay[ nodeName ] = display;
6485 }
6486
6487 return display;
6488}
6489var rmargin = ( /^margin/ );
6490
6491var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6492
6493var swap = function( elem, options, callback, args ) {
6494 var ret, name,
6495 old = {};
6496
6497 // Remember the old values, and insert the new ones
6498 for ( name in options ) {
6499 old[ name ] = elem.style[ name ];
6500 elem.style[ name ] = options[ name ];
6501 }
6502
6503 ret = callback.apply( elem, args || [] );
6504
6505 // Revert the old values
6506 for ( name in options ) {
6507 elem.style[ name ] = old[ name ];
6508 }
6509
6510 return ret;
6511};
6512
6513
6514var documentElement = document.documentElement;
6515
6516
6517
6518( function() {
6519 var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
6520 reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
6521 container = document.createElement( "div" ),
6522 div = document.createElement( "div" );
6523
6524 // Finish early in limited (non-browser) environments
6525 if ( !div.style ) {
6526 return;
6527 }
6528
6529 div.style.cssText = "float:left;opacity:.5";
6530
6531 // Support: IE<9
6532 // Make sure that element opacity exists (as opposed to filter)
6533 support.opacity = div.style.opacity === "0.5";
6534
6535 // Verify style float existence
6536 // (IE uses styleFloat instead of cssFloat)
6537 support.cssFloat = !!div.style.cssFloat;
6538
6539 div.style.backgroundClip = "content-box";
6540 div.cloneNode( true ).style.backgroundClip = "";
6541 support.clearCloneStyle = div.style.backgroundClip === "content-box";
6542
6543 container = document.createElement( "div" );
6544 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6545 "padding:0;margin-top:1px;position:absolute";
6546 div.innerHTML = "";
6547 container.appendChild( div );
6548
6549 // Support: Firefox<29, Android 2.3
6550 // Vendor-prefix box-sizing
6551 support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
6552 div.style.WebkitBoxSizing === "";
6553
6554 jQuery.extend( support, {
6555 reliableHiddenOffsets: function() {
6556 if ( pixelPositionVal == null ) {
6557 computeStyleTests();
6558 }
6559 return reliableHiddenOffsetsVal;
6560 },
6561
6562 boxSizingReliable: function() {
6563
6564 // We're checking for pixelPositionVal here instead of boxSizingReliableVal
6565 // since that compresses better and they're computed together anyway.
6566 if ( pixelPositionVal == null ) {
6567 computeStyleTests();
6568 }
6569 return boxSizingReliableVal;
6570 },
6571
6572 pixelMarginRight: function() {
6573
6574 // Support: Android 4.0-4.3
6575 if ( pixelPositionVal == null ) {
6576 computeStyleTests();
6577 }
6578 return pixelMarginRightVal;
6579 },
6580
6581 pixelPosition: function() {
6582 if ( pixelPositionVal == null ) {
6583 computeStyleTests();
6584 }
6585 return pixelPositionVal;
6586 },
6587
6588 reliableMarginRight: function() {
6589
6590 // Support: Android 2.3
6591 if ( pixelPositionVal == null ) {
6592 computeStyleTests();
6593 }
6594 return reliableMarginRightVal;
6595 },
6596
6597 reliableMarginLeft: function() {
6598
6599 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6600 if ( pixelPositionVal == null ) {
6601 computeStyleTests();
6602 }
6603 return reliableMarginLeftVal;
6604 }
6605 } );
6606
6607 function computeStyleTests() {
6608 var contents, divStyle,
6609 documentElement = document.documentElement;
6610
6611 // Setup
6612 documentElement.appendChild( container );
6613
6614 div.style.cssText =
6615
6616 // Support: Android 2.3
6617 // Vendor-prefix box-sizing
6618 "-webkit-box-sizing:border-box;box-sizing:border-box;" +
6619 "position:relative;display:block;" +
6620 "margin:auto;border:1px;padding:1px;" +
6621 "top:1%;width:50%";
6622
6623 // Support: IE<9
6624 // Assume reasonable values in the absence of getComputedStyle
6625 pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6626 pixelMarginRightVal = reliableMarginRightVal = true;
6627
6628 // Check for getComputedStyle so that this code is not run in IE<9.
6629 if ( window.getComputedStyle ) {
6630 divStyle = window.getComputedStyle( div );
6631 pixelPositionVal = ( divStyle || {} ).top !== "1%";
6632 reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
6633 boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
6634
6635 // Support: Android 4.0 - 4.3 only
6636 // Some styles come back with percentage values, even though they shouldn't
6637 div.style.marginRight = "50%";
6638 pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
6639
6640 // Support: Android 2.3 only
6641 // Div with explicit width and no margin-right incorrectly
6642 // gets computed margin-right based on width of container (#3333)
6643 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6644 contents = div.appendChild( document.createElement( "div" ) );
6645
6646 // Reset CSS: box-sizing; display; margin; border; padding
6647 contents.style.cssText = div.style.cssText =
6648
6649 // Support: Android 2.3
6650 // Vendor-prefix box-sizing
6651 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6652 "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6653 contents.style.marginRight = contents.style.width = "0";
6654 div.style.width = "1px";
6655
6656 reliableMarginRightVal =
6657 !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
6658
6659 div.removeChild( contents );
6660 }
6661
6662 // Support: IE6-8
6663 // First check that getClientRects works as expected
6664 // Check if table cells still have offsetWidth/Height when they are set
6665 // to display:none and there are still other visible table cells in a
6666 // table row; if so, offsetWidth/Height are not reliable for use when
6667 // determining if an element has been hidden directly using
6668 // display:none (it is still safe to use offsets if a parent element is
6669 // hidden; don safety goggles and see bug #4512 for more information).
6670 div.style.display = "none";
6671 reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6672 if ( reliableHiddenOffsetsVal ) {
6673 div.style.display = "";
6674 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6675 div.childNodes[ 0 ].style.borderCollapse = "separate";
6676 contents = div.getElementsByTagName( "td" );
6677 contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6678 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6679 if ( reliableHiddenOffsetsVal ) {
6680 contents[ 0 ].style.display = "";
6681 contents[ 1 ].style.display = "none";
6682 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6683 }
6684 }
6685
6686 // Teardown
6687 documentElement.removeChild( container );
6688 }
6689
6690} )();
6691
6692
6693var getStyles, curCSS,
6694 rposition = /^(top|right|bottom|left)$/;
6695
6696if ( window.getComputedStyle ) {
6697 getStyles = function( elem ) {
6698
6699 // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6700 // IE throws on elements created in popups
6701 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6702 var view = elem.ownerDocument.defaultView;
6703
6704 if ( !view || !view.opener ) {
6705 view = window;
6706 }
6707
6708 return view.getComputedStyle( elem );
6709 };
6710
6711 curCSS = function( elem, name, computed ) {
6712 var width, minWidth, maxWidth, ret,
6713 style = elem.style;
6714
6715 computed = computed || getStyles( elem );
6716
6717 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6718 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6719
6720 // Support: Opera 12.1x only
6721 // Fall back to style even without computed
6722 // computed is undefined for elems on document fragments
6723 if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6724 ret = jQuery.style( elem, name );
6725 }
6726
6727 if ( computed ) {
6728
6729 // A tribute to the "awesome hack by Dean Edwards"
6730 // Chrome < 17 and Safari 5.0 uses "computed value"
6731 // instead of "used value" for margin-right
6732 // Safari 5.1.7 (at least) returns percentage for a larger set of values,
6733 // but width seems to be reliably pixels
6734 // this is against the CSSOM draft spec:
6735 // http://dev.w3.org/csswg/cssom/#resolved-values
6736 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6737
6738 // Remember the original values
6739 width = style.width;
6740 minWidth = style.minWidth;
6741 maxWidth = style.maxWidth;
6742
6743 // Put in the new values to get a computed value out
6744 style.minWidth = style.maxWidth = style.width = ret;
6745 ret = computed.width;
6746
6747 // Revert the changed values
6748 style.width = width;
6749 style.minWidth = minWidth;
6750 style.maxWidth = maxWidth;
6751 }
6752 }
6753
6754 // Support: IE
6755 // IE returns zIndex value as an integer.
6756 return ret === undefined ?
6757 ret :
6758 ret + "";
6759 };
6760} else if ( documentElement.currentStyle ) {
6761 getStyles = function( elem ) {
6762 return elem.currentStyle;
6763 };
6764
6765 curCSS = function( elem, name, computed ) {
6766 var left, rs, rsLeft, ret,
6767 style = elem.style;
6768
6769 computed = computed || getStyles( elem );
6770 ret = computed ? computed[ name ] : undefined;
6771
6772 // Avoid setting ret to empty string here
6773 // so we don't default to auto
6774 if ( ret == null && style && style[ name ] ) {
6775 ret = style[ name ];
6776 }
6777
6778 // From the awesome hack by Dean Edwards
6779 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6780
6781 // If we're not dealing with a regular pixel number
6782 // but a number that has a weird ending, we need to convert it to pixels
6783 // but not position css attributes, as those are
6784 // proportional to the parent element instead
6785 // and we can't measure the parent instead because it
6786 // might trigger a "stacking dolls" problem
6787 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6788
6789 // Remember the original values
6790 left = style.left;
6791 rs = elem.runtimeStyle;
6792 rsLeft = rs && rs.left;
6793
6794 // Put in the new values to get a computed value out
6795 if ( rsLeft ) {
6796 rs.left = elem.currentStyle.left;
6797 }
6798 style.left = name === "fontSize" ? "1em" : ret;
6799 ret = style.pixelLeft + "px";
6800
6801 // Revert the changed values
6802 style.left = left;
6803 if ( rsLeft ) {
6804 rs.left = rsLeft;
6805 }
6806 }
6807
6808 // Support: IE
6809 // IE returns zIndex value as an integer.
6810 return ret === undefined ?
6811 ret :
6812 ret + "" || "auto";
6813 };
6814}
6815
6816
6817
6818
6819function addGetHookIf( conditionFn, hookFn ) {
6820
6821 // Define the hook, we'll check on the first run if it's really needed.
6822 return {
6823 get: function() {
6824 if ( conditionFn() ) {
6825
6826 // Hook not needed (or it's not possible to use it due
6827 // to missing dependency), remove it.
6828 delete this.get;
6829 return;
6830 }
6831
6832 // Hook needed; redefine it so that the support test is not executed again.
6833 return ( this.get = hookFn ).apply( this, arguments );
6834 }
6835 };
6836}
6837
6838
6839var
6840
6841 ralpha = /alpha\([^)]*\)/i,
6842 ropacity = /opacity\s*=\s*([^)]*)/i,
6843
6844 // swappable if display is none or starts with table except
6845 // "table", "table-cell", or "table-caption"
6846 // see here for display values:
6847 // https://developer.mozilla.org/en-US/docs/CSS/display
6848 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6849 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6850
6851 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6852 cssNormalTransform = {
6853 letterSpacing: "0",
6854 fontWeight: "400"
6855 },
6856
6857 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6858 emptyStyle = document.createElement( "div" ).style;
6859
6860
6861// return a css property mapped to a potentially vendor prefixed property
6862function vendorPropName( name ) {
6863
6864 // shortcut for names that are not vendor prefixed
6865 if ( name in emptyStyle ) {
6866 return name;
6867 }
6868
6869 // check for vendor prefixed names
6870 var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
6871 i = cssPrefixes.length;
6872
6873 while ( i-- ) {
6874 name = cssPrefixes[ i ] + capName;
6875 if ( name in emptyStyle ) {
6876 return name;
6877 }
6878 }
6879}
6880
6881function showHide( elements, show ) {
6882 var display, elem, hidden,
6883 values = [],
6884 index = 0,
6885 length = elements.length;
6886
6887 for ( ; index < length; index++ ) {
6888 elem = elements[ index ];
6889 if ( !elem.style ) {
6890 continue;
6891 }
6892
6893 values[ index ] = jQuery._data( elem, "olddisplay" );
6894 display = elem.style.display;
6895 if ( show ) {
6896
6897 // Reset the inline display of this element to learn if it is
6898 // being hidden by cascaded rules or not
6899 if ( !values[ index ] && display === "none" ) {
6900 elem.style.display = "";
6901 }
6902
6903 // Set elements which have been overridden with display: none
6904 // in a stylesheet to whatever the default browser style is
6905 // for such an element
6906 if ( elem.style.display === "" && isHidden( elem ) ) {
6907 values[ index ] =
6908 jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
6909 }
6910 } else {
6911 hidden = isHidden( elem );
6912
6913 if ( display && display !== "none" || !hidden ) {
6914 jQuery._data(
6915 elem,
6916 "olddisplay",
6917 hidden ? display : jQuery.css( elem, "display" )
6918 );
6919 }
6920 }
6921 }
6922
6923 // Set the display of most of the elements in a second loop
6924 // to avoid the constant reflow
6925 for ( index = 0; index < length; index++ ) {
6926 elem = elements[ index ];
6927 if ( !elem.style ) {
6928 continue;
6929 }
6930 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6931 elem.style.display = show ? values[ index ] || "" : "none";
6932 }
6933 }
6934
6935 return elements;
6936}
6937
6938function setPositiveNumber( elem, value, subtract ) {
6939 var matches = rnumsplit.exec( value );
6940 return matches ?
6941
6942 // Guard against undefined "subtract", e.g., when used as in cssHooks
6943 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6944 value;
6945}
6946
6947function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6948 var i = extra === ( isBorderBox ? "border" : "content" ) ?
6949
6950 // If we already have the right measurement, avoid augmentation
6951 4 :
6952
6953 // Otherwise initialize for horizontal or vertical properties
6954 name === "width" ? 1 : 0,
6955
6956 val = 0;
6957
6958 for ( ; i < 4; i += 2 ) {
6959
6960 // both box models exclude margin, so add it if we want it
6961 if ( extra === "margin" ) {
6962 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6963 }
6964
6965 if ( isBorderBox ) {
6966
6967 // border-box includes padding, so remove it if we want content
6968 if ( extra === "content" ) {
6969 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6970 }
6971
6972 // at this point, extra isn't border nor margin, so remove border
6973 if ( extra !== "margin" ) {
6974 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6975 }
6976 } else {
6977
6978 // at this point, extra isn't content, so add padding
6979 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6980
6981 // at this point, extra isn't content nor padding, so add border
6982 if ( extra !== "padding" ) {
6983 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6984 }
6985 }
6986 }
6987
6988 return val;
6989}
6990
6991function getWidthOrHeight( elem, name, extra ) {
6992
6993 // Start with offset property, which is equivalent to the border-box value
6994 var valueIsBorderBox = true,
6995 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6996 styles = getStyles( elem ),
6997 isBorderBox = support.boxSizing &&
6998 jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6999
7000 // some non-html elements return undefined for offsetWidth, so check for null/undefined
7001 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
7002 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
7003 if ( val <= 0 || val == null ) {
7004
7005 // Fall back to computed then uncomputed css if necessary
7006 val = curCSS( elem, name, styles );
7007 if ( val < 0 || val == null ) {
7008 val = elem.style[ name ];
7009 }
7010
7011 // Computed unit is not pixels. Stop here and return.
7012 if ( rnumnonpx.test( val ) ) {
7013 return val;
7014 }
7015
7016 // we need the check for style in case a browser which returns unreliable values
7017 // for getComputedStyle silently falls back to the reliable elem.style
7018 valueIsBorderBox = isBorderBox &&
7019 ( support.boxSizingReliable() || val === elem.style[ name ] );
7020
7021 // Normalize "", auto, and prepare for extra
7022 val = parseFloat( val ) || 0;
7023 }
7024
7025 // use the active box-sizing model to add/subtract irrelevant styles
7026 return ( val +
7027 augmentWidthOrHeight(
7028 elem,
7029 name,
7030 extra || ( isBorderBox ? "border" : "content" ),
7031 valueIsBorderBox,
7032 styles
7033 )
7034 ) + "px";
7035}
7036
7037jQuery.extend( {
7038
7039 // Add in style property hooks for overriding the default
7040 // behavior of getting and setting a style property
7041 cssHooks: {
7042 opacity: {
7043 get: function( elem, computed ) {
7044 if ( computed ) {
7045
7046 // We should always get a number back from opacity
7047 var ret = curCSS( elem, "opacity" );
7048 return ret === "" ? "1" : ret;
7049 }
7050 }
7051 }
7052 },
7053
7054 // Don't automatically add "px" to these possibly-unitless properties
7055 cssNumber: {
7056 "animationIterationCount": true,
7057 "columnCount": true,
7058 "fillOpacity": true,
7059 "flexGrow": true,
7060 "flexShrink": true,
7061 "fontWeight": true,
7062 "lineHeight": true,
7063 "opacity": true,
7064 "order": true,
7065 "orphans": true,
7066 "widows": true,
7067 "zIndex": true,
7068 "zoom": true
7069 },
7070
7071 // Add in properties whose names you wish to fix before
7072 // setting or getting the value
7073 cssProps: {
7074
7075 // normalize float css property
7076 "float": support.cssFloat ? "cssFloat" : "styleFloat"
7077 },
7078
7079 // Get and set the style property on a DOM Node
7080 style: function( elem, name, value, extra ) {
7081
7082 // Don't set styles on text and comment nodes
7083 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7084 return;
7085 }
7086
7087 // Make sure that we're working with the right name
7088 var ret, type, hooks,
7089 origName = jQuery.camelCase( name ),
7090 style = elem.style;
7091
7092 name = jQuery.cssProps[ origName ] ||
7093 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7094
7095 // gets hook for the prefixed version
7096 // followed by the unprefixed version
7097 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7098
7099 // Check if we're setting a value
7100 if ( value !== undefined ) {
7101 type = typeof value;
7102
7103 // Convert "+=" or "-=" to relative numbers (#7345)
7104 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7105 value = adjustCSS( elem, name, ret );
7106
7107 // Fixes bug #9237
7108 type = "number";
7109 }
7110
7111 // Make sure that null and NaN values aren't set. See: #7116
7112 if ( value == null || value !== value ) {
7113 return;
7114 }
7115
7116 // If a number was passed in, add the unit (except for certain CSS properties)
7117 if ( type === "number" ) {
7118 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7119 }
7120
7121 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
7122 // but it would mean to define eight
7123 // (for every problematic property) identical functions
7124 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7125 style[ name ] = "inherit";
7126 }
7127
7128 // If a hook was provided, use that value, otherwise just set the specified value
7129 if ( !hooks || !( "set" in hooks ) ||
7130 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7131
7132 // Support: IE
7133 // Swallow errors from 'invalid' CSS values (#5509)
7134 try {
7135 style[ name ] = value;
7136 } catch ( e ) {}
7137 }
7138
7139 } else {
7140
7141 // If a hook was provided get the non-computed value from there
7142 if ( hooks && "get" in hooks &&
7143 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7144
7145 return ret;
7146 }
7147
7148 // Otherwise just get the value from the style object
7149 return style[ name ];
7150 }
7151 },
7152
7153 css: function( elem, name, extra, styles ) {
7154 var num, val, hooks,
7155 origName = jQuery.camelCase( name );
7156
7157 // Make sure that we're working with the right name
7158 name = jQuery.cssProps[ origName ] ||
7159 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7160
7161 // gets hook for the prefixed version
7162 // followed by the unprefixed version
7163 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7164
7165 // If a hook was provided get the computed value from there
7166 if ( hooks && "get" in hooks ) {
7167 val = hooks.get( elem, true, extra );
7168 }
7169
7170 // Otherwise, if a way to get the computed value exists, use that
7171 if ( val === undefined ) {
7172 val = curCSS( elem, name, styles );
7173 }
7174
7175 //convert "normal" to computed value
7176 if ( val === "normal" && name in cssNormalTransform ) {
7177 val = cssNormalTransform[ name ];
7178 }
7179
7180 // Return, converting to number if forced or a qualifier was provided and val looks numeric
7181 if ( extra === "" || extra ) {
7182 num = parseFloat( val );
7183 return extra === true || isFinite( num ) ? num || 0 : val;
7184 }
7185 return val;
7186 }
7187} );
7188
7189jQuery.each( [ "height", "width" ], function( i, name ) {
7190 jQuery.cssHooks[ name ] = {
7191 get: function( elem, computed, extra ) {
7192 if ( computed ) {
7193
7194 // certain elements can have dimension info if we invisibly show them
7195 // however, it must have a current display style that would benefit from this
7196 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7197 elem.offsetWidth === 0 ?
7198 swap( elem, cssShow, function() {
7199 return getWidthOrHeight( elem, name, extra );
7200 } ) :
7201 getWidthOrHeight( elem, name, extra );
7202 }
7203 },
7204
7205 set: function( elem, value, extra ) {
7206 var styles = extra && getStyles( elem );
7207 return setPositiveNumber( elem, value, extra ?
7208 augmentWidthOrHeight(
7209 elem,
7210 name,
7211 extra,
7212 support.boxSizing &&
7213 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7214 styles
7215 ) : 0
7216 );
7217 }
7218 };
7219} );
7220
7221if ( !support.opacity ) {
7222 jQuery.cssHooks.opacity = {
7223 get: function( elem, computed ) {
7224
7225 // IE uses filters for opacity
7226 return ropacity.test( ( computed && elem.currentStyle ?
7227 elem.currentStyle.filter :
7228 elem.style.filter ) || "" ) ?
7229 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7230 computed ? "1" : "";
7231 },
7232
7233 set: function( elem, value ) {
7234 var style = elem.style,
7235 currentStyle = elem.currentStyle,
7236 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7237 filter = currentStyle && currentStyle.filter || style.filter || "";
7238
7239 // IE has trouble with opacity if it does not have layout
7240 // Force it by setting the zoom level
7241 style.zoom = 1;
7242
7243 // if setting opacity to 1, and no other filters exist -
7244 // attempt to remove filter attribute #6652
7245 // if value === "", then remove inline opacity #12685
7246 if ( ( value >= 1 || value === "" ) &&
7247 jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7248 style.removeAttribute ) {
7249
7250 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7251 // if "filter:" is present at all, clearType is disabled, we want to avoid this
7252 // style.removeAttribute is IE Only, but so apparently is this code path...
7253 style.removeAttribute( "filter" );
7254
7255 // if there is no filter style applied in a css rule
7256 // or unset inline opacity, we are done
7257 if ( value === "" || currentStyle && !currentStyle.filter ) {
7258 return;
7259 }
7260 }
7261
7262 // otherwise, set new filter values
7263 style.filter = ralpha.test( filter ) ?
7264 filter.replace( ralpha, opacity ) :
7265 filter + " " + opacity;
7266 }
7267 };
7268}
7269
7270jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
7271 function( elem, computed ) {
7272 if ( computed ) {
7273 return swap( elem, { "display": "inline-block" },
7274 curCSS, [ elem, "marginRight" ] );
7275 }
7276 }
7277);
7278
7279jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7280 function( elem, computed ) {
7281 if ( computed ) {
7282 return (
7283 parseFloat( curCSS( elem, "marginLeft" ) ) ||
7284
7285 // Support: IE<=11+
7286 // Running getBoundingClientRect on a disconnected node in IE throws an error
7287 // Support: IE8 only
7288 // getClientRects() errors on disconnected elems
7289 ( jQuery.contains( elem.ownerDocument, elem ) ?
7290 elem.getBoundingClientRect().left -
7291 swap( elem, { marginLeft: 0 }, function() {
7292 return elem.getBoundingClientRect().left;
7293 } ) :
7294 0
7295 )
7296 ) + "px";
7297 }
7298 }
7299);
7300
7301// These hooks are used by animate to expand properties
7302jQuery.each( {
7303 margin: "",
7304 padding: "",
7305 border: "Width"
7306}, function( prefix, suffix ) {
7307 jQuery.cssHooks[ prefix + suffix ] = {
7308 expand: function( value ) {
7309 var i = 0,
7310 expanded = {},
7311
7312 // assumes a single number if not a string
7313 parts = typeof value === "string" ? value.split( " " ) : [ value ];
7314
7315 for ( ; i < 4; i++ ) {
7316 expanded[ prefix + cssExpand[ i ] + suffix ] =
7317 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7318 }
7319
7320 return expanded;
7321 }
7322 };
7323
7324 if ( !rmargin.test( prefix ) ) {
7325 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7326 }
7327} );
7328
7329jQuery.fn.extend( {
7330 css: function( name, value ) {
7331 return access( this, function( elem, name, value ) {
7332 var styles, len,
7333 map = {},
7334 i = 0;
7335
7336 if ( jQuery.isArray( name ) ) {
7337 styles = getStyles( elem );
7338 len = name.length;
7339
7340 for ( ; i < len; i++ ) {
7341 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7342 }
7343
7344 return map;
7345 }
7346
7347 return value !== undefined ?
7348 jQuery.style( elem, name, value ) :
7349 jQuery.css( elem, name );
7350 }, name, value, arguments.length > 1 );
7351 },
7352 show: function() {
7353 return showHide( this, true );
7354 },
7355 hide: function() {
7356 return showHide( this );
7357 },
7358 toggle: function( state ) {
7359 if ( typeof state === "boolean" ) {
7360 return state ? this.show() : this.hide();
7361 }
7362
7363 return this.each( function() {
7364 if ( isHidden( this ) ) {
7365 jQuery( this ).show();
7366 } else {
7367 jQuery( this ).hide();
7368 }
7369 } );
7370 }
7371} );
7372
7373
7374function Tween( elem, options, prop, end, easing ) {
7375 return new Tween.prototype.init( elem, options, prop, end, easing );
7376}
7377jQuery.Tween = Tween;
7378
7379Tween.prototype = {
7380 constructor: Tween,
7381 init: function( elem, options, prop, end, easing, unit ) {
7382 this.elem = elem;
7383 this.prop = prop;
7384 this.easing = easing || jQuery.easing._default;
7385 this.options = options;
7386 this.start = this.now = this.cur();
7387 this.end = end;
7388 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7389 },
7390 cur: function() {
7391 var hooks = Tween.propHooks[ this.prop ];
7392
7393 return hooks && hooks.get ?
7394 hooks.get( this ) :
7395 Tween.propHooks._default.get( this );
7396 },
7397 run: function( percent ) {
7398 var eased,
7399 hooks = Tween.propHooks[ this.prop ];
7400
7401 if ( this.options.duration ) {
7402 this.pos = eased = jQuery.easing[ this.easing ](
7403 percent, this.options.duration * percent, 0, 1, this.options.duration
7404 );
7405 } else {
7406 this.pos = eased = percent;
7407 }
7408 this.now = ( this.end - this.start ) * eased + this.start;
7409
7410 if ( this.options.step ) {
7411 this.options.step.call( this.elem, this.now, this );
7412 }
7413
7414 if ( hooks && hooks.set ) {
7415 hooks.set( this );
7416 } else {
7417 Tween.propHooks._default.set( this );
7418 }
7419 return this;
7420 }
7421};
7422
7423Tween.prototype.init.prototype = Tween.prototype;
7424
7425Tween.propHooks = {
7426 _default: {
7427 get: function( tween ) {
7428 var result;
7429
7430 // Use a property on the element directly when it is not a DOM element,
7431 // or when there is no matching style property that exists.
7432 if ( tween.elem.nodeType !== 1 ||
7433 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7434 return tween.elem[ tween.prop ];
7435 }
7436
7437 // passing an empty string as a 3rd parameter to .css will automatically
7438 // attempt a parseFloat and fallback to a string if the parse fails
7439 // so, simple values such as "10px" are parsed to Float.
7440 // complex values such as "rotate(1rad)" are returned as is.
7441 result = jQuery.css( tween.elem, tween.prop, "" );
7442
7443 // Empty strings, null, undefined and "auto" are converted to 0.
7444 return !result || result === "auto" ? 0 : result;
7445 },
7446 set: function( tween ) {
7447
7448 // use step hook for back compat - use cssHook if its there - use .style if its
7449 // available and use plain properties where available
7450 if ( jQuery.fx.step[ tween.prop ] ) {
7451 jQuery.fx.step[ tween.prop ]( tween );
7452 } else if ( tween.elem.nodeType === 1 &&
7453 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
7454 jQuery.cssHooks[ tween.prop ] ) ) {
7455 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7456 } else {
7457 tween.elem[ tween.prop ] = tween.now;
7458 }
7459 }
7460 }
7461};
7462
7463// Support: IE <=9
7464// Panic based approach to setting things on disconnected nodes
7465
7466Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7467 set: function( tween ) {
7468 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7469 tween.elem[ tween.prop ] = tween.now;
7470 }
7471 }
7472};
7473
7474jQuery.easing = {
7475 linear: function( p ) {
7476 return p;
7477 },
7478 swing: function( p ) {
7479 return 0.5 - Math.cos( p * Math.PI ) / 2;
7480 },
7481 _default: "swing"
7482};
7483
7484jQuery.fx = Tween.prototype.init;
7485
7486// Back Compat <1.8 extension point
7487jQuery.fx.step = {};
7488
7489
7490
7491
7492var
7493 fxNow, timerId,
7494 rfxtypes = /^(?:toggle|show|hide)$/,
7495 rrun = /queueHooks$/;
7496
7497// Animations created synchronously will run synchronously
7498function createFxNow() {
7499 window.setTimeout( function() {
7500 fxNow = undefined;
7501 } );
7502 return ( fxNow = jQuery.now() );
7503}
7504
7505// Generate parameters to create a standard animation
7506function genFx( type, includeWidth ) {
7507 var which,
7508 attrs = { height: type },
7509 i = 0;
7510
7511 // if we include width, step value is 1 to do all cssExpand values,
7512 // if we don't include width, step value is 2 to skip over Left and Right
7513 includeWidth = includeWidth ? 1 : 0;
7514 for ( ; i < 4 ; i += 2 - includeWidth ) {
7515 which = cssExpand[ i ];
7516 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7517 }
7518
7519 if ( includeWidth ) {
7520 attrs.opacity = attrs.width = type;
7521 }
7522
7523 return attrs;
7524}
7525
7526function createTween( value, prop, animation ) {
7527 var tween,
7528 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7529 index = 0,
7530 length = collection.length;
7531 for ( ; index < length; index++ ) {
7532 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7533
7534 // we're done with this property
7535 return tween;
7536 }
7537 }
7538}
7539
7540function defaultPrefilter( elem, props, opts ) {
7541 /* jshint validthis: true */
7542 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7543 anim = this,
7544 orig = {},
7545 style = elem.style,
7546 hidden = elem.nodeType && isHidden( elem ),
7547 dataShow = jQuery._data( elem, "fxshow" );
7548
7549 // handle queue: false promises
7550 if ( !opts.queue ) {
7551 hooks = jQuery._queueHooks( elem, "fx" );
7552 if ( hooks.unqueued == null ) {
7553 hooks.unqueued = 0;
7554 oldfire = hooks.empty.fire;
7555 hooks.empty.fire = function() {
7556 if ( !hooks.unqueued ) {
7557 oldfire();
7558 }
7559 };
7560 }
7561 hooks.unqueued++;
7562
7563 anim.always( function() {
7564
7565 // doing this makes sure that the complete handler will be called
7566 // before this completes
7567 anim.always( function() {
7568 hooks.unqueued--;
7569 if ( !jQuery.queue( elem, "fx" ).length ) {
7570 hooks.empty.fire();
7571 }
7572 } );
7573 } );
7574 }
7575
7576 // height/width overflow pass
7577 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7578
7579 // Make sure that nothing sneaks out
7580 // Record all 3 overflow attributes because IE does not
7581 // change the overflow attribute when overflowX and
7582 // overflowY are set to the same value
7583 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7584
7585 // Set display property to inline-block for height/width
7586 // animations on inline elements that are having width/height animated
7587 display = jQuery.css( elem, "display" );
7588
7589 // Test default display if display is currently "none"
7590 checkDisplay = display === "none" ?
7591 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7592
7593 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7594
7595 // inline-level elements accept inline-block;
7596 // block-level elements need to be inline with layout
7597 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7598 style.display = "inline-block";
7599 } else {
7600 style.zoom = 1;
7601 }
7602 }
7603 }
7604
7605 if ( opts.overflow ) {
7606 style.overflow = "hidden";
7607 if ( !support.shrinkWrapBlocks() ) {
7608 anim.always( function() {
7609 style.overflow = opts.overflow[ 0 ];
7610 style.overflowX = opts.overflow[ 1 ];
7611 style.overflowY = opts.overflow[ 2 ];
7612 } );
7613 }
7614 }
7615
7616 // show/hide pass
7617 for ( prop in props ) {
7618 value = props[ prop ];
7619 if ( rfxtypes.exec( value ) ) {
7620 delete props[ prop ];
7621 toggle = toggle || value === "toggle";
7622 if ( value === ( hidden ? "hide" : "show" ) ) {
7623
7624 // If there is dataShow left over from a stopped hide or show
7625 // and we are going to proceed with show, we should pretend to be hidden
7626 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7627 hidden = true;
7628 } else {
7629 continue;
7630 }
7631 }
7632 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7633
7634 // Any non-fx value stops us from restoring the original display value
7635 } else {
7636 display = undefined;
7637 }
7638 }
7639
7640 if ( !jQuery.isEmptyObject( orig ) ) {
7641 if ( dataShow ) {
7642 if ( "hidden" in dataShow ) {
7643 hidden = dataShow.hidden;
7644 }
7645 } else {
7646 dataShow = jQuery._data( elem, "fxshow", {} );
7647 }
7648
7649 // store state if its toggle - enables .stop().toggle() to "reverse"
7650 if ( toggle ) {
7651 dataShow.hidden = !hidden;
7652 }
7653 if ( hidden ) {
7654 jQuery( elem ).show();
7655 } else {
7656 anim.done( function() {
7657 jQuery( elem ).hide();
7658 } );
7659 }
7660 anim.done( function() {
7661 var prop;
7662 jQuery._removeData( elem, "fxshow" );
7663 for ( prop in orig ) {
7664 jQuery.style( elem, prop, orig[ prop ] );
7665 }
7666 } );
7667 for ( prop in orig ) {
7668 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7669
7670 if ( !( prop in dataShow ) ) {
7671 dataShow[ prop ] = tween.start;
7672 if ( hidden ) {
7673 tween.end = tween.start;
7674 tween.start = prop === "width" || prop === "height" ? 1 : 0;
7675 }
7676 }
7677 }
7678
7679 // If this is a noop like .hide().hide(), restore an overwritten display value
7680 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
7681 style.display = display;
7682 }
7683}
7684
7685function propFilter( props, specialEasing ) {
7686 var index, name, easing, value, hooks;
7687
7688 // camelCase, specialEasing and expand cssHook pass
7689 for ( index in props ) {
7690 name = jQuery.camelCase( index );
7691 easing = specialEasing[ name ];
7692 value = props[ index ];
7693 if ( jQuery.isArray( value ) ) {
7694 easing = value[ 1 ];
7695 value = props[ index ] = value[ 0 ];
7696 }
7697
7698 if ( index !== name ) {
7699 props[ name ] = value;
7700 delete props[ index ];
7701 }
7702
7703 hooks = jQuery.cssHooks[ name ];
7704 if ( hooks && "expand" in hooks ) {
7705 value = hooks.expand( value );
7706 delete props[ name ];
7707
7708 // not quite $.extend, this wont overwrite keys already present.
7709 // also - reusing 'index' from above because we have the correct "name"
7710 for ( index in value ) {
7711 if ( !( index in props ) ) {
7712 props[ index ] = value[ index ];
7713 specialEasing[ index ] = easing;
7714 }
7715 }
7716 } else {
7717 specialEasing[ name ] = easing;
7718 }
7719 }
7720}
7721
7722function Animation( elem, properties, options ) {
7723 var result,
7724 stopped,
7725 index = 0,
7726 length = Animation.prefilters.length,
7727 deferred = jQuery.Deferred().always( function() {
7728
7729 // don't match elem in the :animated selector
7730 delete tick.elem;
7731 } ),
7732 tick = function() {
7733 if ( stopped ) {
7734 return false;
7735 }
7736 var currentTime = fxNow || createFxNow(),
7737 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7738
7739 // Support: Android 2.3
7740 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7741 temp = remaining / animation.duration || 0,
7742 percent = 1 - temp,
7743 index = 0,
7744 length = animation.tweens.length;
7745
7746 for ( ; index < length ; index++ ) {
7747 animation.tweens[ index ].run( percent );
7748 }
7749
7750 deferred.notifyWith( elem, [ animation, percent, remaining ] );
7751
7752 if ( percent < 1 && length ) {
7753 return remaining;
7754 } else {
7755 deferred.resolveWith( elem, [ animation ] );
7756 return false;
7757 }
7758 },
7759 animation = deferred.promise( {
7760 elem: elem,
7761 props: jQuery.extend( {}, properties ),
7762 opts: jQuery.extend( true, {
7763 specialEasing: {},
7764 easing: jQuery.easing._default
7765 }, options ),
7766 originalProperties: properties,
7767 originalOptions: options,
7768 startTime: fxNow || createFxNow(),
7769 duration: options.duration,
7770 tweens: [],
7771 createTween: function( prop, end ) {
7772 var tween = jQuery.Tween( elem, animation.opts, prop, end,
7773 animation.opts.specialEasing[ prop ] || animation.opts.easing );
7774 animation.tweens.push( tween );
7775 return tween;
7776 },
7777 stop: function( gotoEnd ) {
7778 var index = 0,
7779
7780 // if we are going to the end, we want to run all the tweens
7781 // otherwise we skip this part
7782 length = gotoEnd ? animation.tweens.length : 0;
7783 if ( stopped ) {
7784 return this;
7785 }
7786 stopped = true;
7787 for ( ; index < length ; index++ ) {
7788 animation.tweens[ index ].run( 1 );
7789 }
7790
7791 // resolve when we played the last frame
7792 // otherwise, reject
7793 if ( gotoEnd ) {
7794 deferred.notifyWith( elem, [ animation, 1, 0 ] );
7795 deferred.resolveWith( elem, [ animation, gotoEnd ] );
7796 } else {
7797 deferred.rejectWith( elem, [ animation, gotoEnd ] );
7798 }
7799 return this;
7800 }
7801 } ),
7802 props = animation.props;
7803
7804 propFilter( props, animation.opts.specialEasing );
7805
7806 for ( ; index < length ; index++ ) {
7807 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7808 if ( result ) {
7809 if ( jQuery.isFunction( result.stop ) ) {
7810 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7811 jQuery.proxy( result.stop, result );
7812 }
7813 return result;
7814 }
7815 }
7816
7817 jQuery.map( props, createTween, animation );
7818
7819 if ( jQuery.isFunction( animation.opts.start ) ) {
7820 animation.opts.start.call( elem, animation );
7821 }
7822
7823 jQuery.fx.timer(
7824 jQuery.extend( tick, {
7825 elem: elem,
7826 anim: animation,
7827 queue: animation.opts.queue
7828 } )
7829 );
7830
7831 // attach callbacks from options
7832 return animation.progress( animation.opts.progress )
7833 .done( animation.opts.done, animation.opts.complete )
7834 .fail( animation.opts.fail )
7835 .always( animation.opts.always );
7836}
7837
7838jQuery.Animation = jQuery.extend( Animation, {
7839
7840 tweeners: {
7841 "*": [ function( prop, value ) {
7842 var tween = this.createTween( prop, value );
7843 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7844 return tween;
7845 } ]
7846 },
7847
7848 tweener: function( props, callback ) {
7849 if ( jQuery.isFunction( props ) ) {
7850 callback = props;
7851 props = [ "*" ];
7852 } else {
7853 props = props.match( rnotwhite );
7854 }
7855
7856 var prop,
7857 index = 0,
7858 length = props.length;
7859
7860 for ( ; index < length ; index++ ) {
7861 prop = props[ index ];
7862 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7863 Animation.tweeners[ prop ].unshift( callback );
7864 }
7865 },
7866
7867 prefilters: [ defaultPrefilter ],
7868
7869 prefilter: function( callback, prepend ) {
7870 if ( prepend ) {
7871 Animation.prefilters.unshift( callback );
7872 } else {
7873 Animation.prefilters.push( callback );
7874 }
7875 }
7876} );
7877
7878jQuery.speed = function( speed, easing, fn ) {
7879 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7880 complete: fn || !fn && easing ||
7881 jQuery.isFunction( speed ) && speed,
7882 duration: speed,
7883 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7884 };
7885
7886 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7887 opt.duration in jQuery.fx.speeds ?
7888 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7889
7890 // normalize opt.queue - true/undefined/null -> "fx"
7891 if ( opt.queue == null || opt.queue === true ) {
7892 opt.queue = "fx";
7893 }
7894
7895 // Queueing
7896 opt.old = opt.complete;
7897
7898 opt.complete = function() {
7899 if ( jQuery.isFunction( opt.old ) ) {
7900 opt.old.call( this );
7901 }
7902
7903 if ( opt.queue ) {
7904 jQuery.dequeue( this, opt.queue );
7905 }
7906 };
7907
7908 return opt;
7909};
7910
7911jQuery.fn.extend( {
7912 fadeTo: function( speed, to, easing, callback ) {
7913
7914 // show any hidden elements after setting opacity to 0
7915 return this.filter( isHidden ).css( "opacity", 0 ).show()
7916
7917 // animate to the value specified
7918 .end().animate( { opacity: to }, speed, easing, callback );
7919 },
7920 animate: function( prop, speed, easing, callback ) {
7921 var empty = jQuery.isEmptyObject( prop ),
7922 optall = jQuery.speed( speed, easing, callback ),
7923 doAnimation = function() {
7924
7925 // Operate on a copy of prop so per-property easing won't be lost
7926 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7927
7928 // Empty animations, or finishing resolves immediately
7929 if ( empty || jQuery._data( this, "finish" ) ) {
7930 anim.stop( true );
7931 }
7932 };
7933 doAnimation.finish = doAnimation;
7934
7935 return empty || optall.queue === false ?
7936 this.each( doAnimation ) :
7937 this.queue( optall.queue, doAnimation );
7938 },
7939 stop: function( type, clearQueue, gotoEnd ) {
7940 var stopQueue = function( hooks ) {
7941 var stop = hooks.stop;
7942 delete hooks.stop;
7943 stop( gotoEnd );
7944 };
7945
7946 if ( typeof type !== "string" ) {
7947 gotoEnd = clearQueue;
7948 clearQueue = type;
7949 type = undefined;
7950 }
7951 if ( clearQueue && type !== false ) {
7952 this.queue( type || "fx", [] );
7953 }
7954
7955 return this.each( function() {
7956 var dequeue = true,
7957 index = type != null && type + "queueHooks",
7958 timers = jQuery.timers,
7959 data = jQuery._data( this );
7960
7961 if ( index ) {
7962 if ( data[ index ] && data[ index ].stop ) {
7963 stopQueue( data[ index ] );
7964 }
7965 } else {
7966 for ( index in data ) {
7967 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7968 stopQueue( data[ index ] );
7969 }
7970 }
7971 }
7972
7973 for ( index = timers.length; index--; ) {
7974 if ( timers[ index ].elem === this &&
7975 ( type == null || timers[ index ].queue === type ) ) {
7976
7977 timers[ index ].anim.stop( gotoEnd );
7978 dequeue = false;
7979 timers.splice( index, 1 );
7980 }
7981 }
7982
7983 // start the next in the queue if the last step wasn't forced
7984 // timers currently will call their complete callbacks, which will dequeue
7985 // but only if they were gotoEnd
7986 if ( dequeue || !gotoEnd ) {
7987 jQuery.dequeue( this, type );
7988 }
7989 } );
7990 },
7991 finish: function( type ) {
7992 if ( type !== false ) {
7993 type = type || "fx";
7994 }
7995 return this.each( function() {
7996 var index,
7997 data = jQuery._data( this ),
7998 queue = data[ type + "queue" ],
7999 hooks = data[ type + "queueHooks" ],
8000 timers = jQuery.timers,
8001 length = queue ? queue.length : 0;
8002
8003 // enable finishing flag on private data
8004 data.finish = true;
8005
8006 // empty the queue first
8007 jQuery.queue( this, type, [] );
8008
8009 if ( hooks && hooks.stop ) {
8010 hooks.stop.call( this, true );
8011 }
8012
8013 // look for any active animations, and finish them
8014 for ( index = timers.length; index--; ) {
8015 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8016 timers[ index ].anim.stop( true );
8017 timers.splice( index, 1 );
8018 }
8019 }
8020
8021 // look for any animations in the old queue and finish them
8022 for ( index = 0; index < length; index++ ) {
8023 if ( queue[ index ] && queue[ index ].finish ) {
8024 queue[ index ].finish.call( this );
8025 }
8026 }
8027
8028 // turn off finishing flag
8029 delete data.finish;
8030 } );
8031 }
8032} );
8033
8034jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
8035 var cssFn = jQuery.fn[ name ];
8036 jQuery.fn[ name ] = function( speed, easing, callback ) {
8037 return speed == null || typeof speed === "boolean" ?
8038 cssFn.apply( this, arguments ) :
8039 this.animate( genFx( name, true ), speed, easing, callback );
8040 };
8041} );
8042
8043// Generate shortcuts for custom animations
8044jQuery.each( {
8045 slideDown: genFx( "show" ),
8046 slideUp: genFx( "hide" ),
8047 slideToggle: genFx( "toggle" ),
8048 fadeIn: { opacity: "show" },
8049 fadeOut: { opacity: "hide" },
8050 fadeToggle: { opacity: "toggle" }
8051}, function( name, props ) {
8052 jQuery.fn[ name ] = function( speed, easing, callback ) {
8053 return this.animate( props, speed, easing, callback );
8054 };
8055} );
8056
8057jQuery.timers = [];
8058jQuery.fx.tick = function() {
8059 var timer,
8060 timers = jQuery.timers,
8061 i = 0;
8062
8063 fxNow = jQuery.now();
8064
8065 for ( ; i < timers.length; i++ ) {
8066 timer = timers[ i ];
8067
8068 // Checks the timer has not already been removed
8069 if ( !timer() && timers[ i ] === timer ) {
8070 timers.splice( i--, 1 );
8071 }
8072 }
8073
8074 if ( !timers.length ) {
8075 jQuery.fx.stop();
8076 }
8077 fxNow = undefined;
8078};
8079
8080jQuery.fx.timer = function( timer ) {
8081 jQuery.timers.push( timer );
8082 if ( timer() ) {
8083 jQuery.fx.start();
8084 } else {
8085 jQuery.timers.pop();
8086 }
8087};
8088
8089jQuery.fx.interval = 13;
8090
8091jQuery.fx.start = function() {
8092 if ( !timerId ) {
8093 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
8094 }
8095};
8096
8097jQuery.fx.stop = function() {
8098 window.clearInterval( timerId );
8099 timerId = null;
8100};
8101
8102jQuery.fx.speeds = {
8103 slow: 600,
8104 fast: 200,
8105
8106 // Default speed
8107 _default: 400
8108};
8109
8110
8111// Based off of the plugin by Clint Helfers, with permission.
8112// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8113jQuery.fn.delay = function( time, type ) {
8114 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8115 type = type || "fx";
8116
8117 return this.queue( type, function( next, hooks ) {
8118 var timeout = window.setTimeout( next, time );
8119 hooks.stop = function() {
8120 window.clearTimeout( timeout );
8121 };
8122 } );
8123};
8124
8125
8126( function() {
8127 var a,
8128 input = document.createElement( "input" ),
8129 div = document.createElement( "div" ),
8130 select = document.createElement( "select" ),
8131 opt = select.appendChild( document.createElement( "option" ) );
8132
8133 // Setup
8134 div = document.createElement( "div" );
8135 div.setAttribute( "className", "t" );
8136 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
8137 a = div.getElementsByTagName( "a" )[ 0 ];
8138
8139 // Support: Windows Web Apps (WWA)
8140 // `type` must use .setAttribute for WWA (#14901)
8141 input.setAttribute( "type", "checkbox" );
8142 div.appendChild( input );
8143
8144 a = div.getElementsByTagName( "a" )[ 0 ];
8145
8146 // First batch of tests.
8147 a.style.cssText = "top:1px";
8148
8149 // Test setAttribute on camelCase class.
8150 // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8151 support.getSetAttribute = div.className !== "t";
8152
8153 // Get the style information from getAttribute
8154 // (IE uses .cssText instead)
8155 support.style = /top/.test( a.getAttribute( "style" ) );
8156
8157 // Make sure that URLs aren't manipulated
8158 // (IE normalizes it by default)
8159 support.hrefNormalized = a.getAttribute( "href" ) === "/a";
8160
8161 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
8162 support.checkOn = !!input.value;
8163
8164 // Make sure that a selected-by-default option has a working selected property.
8165 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
8166 support.optSelected = opt.selected;
8167
8168 // Tests for enctype support on a form (#6743)
8169 support.enctype = !!document.createElement( "form" ).enctype;
8170
8171 // Make sure that the options inside disabled selects aren't marked as disabled
8172 // (WebKit marks them as disabled)
8173 select.disabled = true;
8174 support.optDisabled = !opt.disabled;
8175
8176 // Support: IE8 only
8177 // Check if we can trust getAttribute("value")
8178 input = document.createElement( "input" );
8179 input.setAttribute( "value", "" );
8180 support.input = input.getAttribute( "value" ) === "";
8181
8182 // Check if an input maintains its value after becoming a radio
8183 input.value = "t";
8184 input.setAttribute( "type", "radio" );
8185 support.radioValue = input.value === "t";
8186} )();
8187
8188
8189var rreturn = /\r/g,
8190 rspaces = /[\x20\t\r\n\f]+/g;
8191
8192jQuery.fn.extend( {
8193 val: function( value ) {
8194 var hooks, ret, isFunction,
8195 elem = this[ 0 ];
8196
8197 if ( !arguments.length ) {
8198 if ( elem ) {
8199 hooks = jQuery.valHooks[ elem.type ] ||
8200 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8201
8202 if (
8203 hooks &&
8204 "get" in hooks &&
8205 ( ret = hooks.get( elem, "value" ) ) !== undefined
8206 ) {
8207 return ret;
8208 }
8209
8210 ret = elem.value;
8211
8212 return typeof ret === "string" ?
8213
8214 // handle most common string cases
8215 ret.replace( rreturn, "" ) :
8216
8217 // handle cases where value is null/undef or number
8218 ret == null ? "" : ret;
8219 }
8220
8221 return;
8222 }
8223
8224 isFunction = jQuery.isFunction( value );
8225
8226 return this.each( function( i ) {
8227 var val;
8228
8229 if ( this.nodeType !== 1 ) {
8230 return;
8231 }
8232
8233 if ( isFunction ) {
8234 val = value.call( this, i, jQuery( this ).val() );
8235 } else {
8236 val = value;
8237 }
8238
8239 // Treat null/undefined as ""; convert numbers to string
8240 if ( val == null ) {
8241 val = "";
8242 } else if ( typeof val === "number" ) {
8243 val += "";
8244 } else if ( jQuery.isArray( val ) ) {
8245 val = jQuery.map( val, function( value ) {
8246 return value == null ? "" : value + "";
8247 } );
8248 }
8249
8250 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8251
8252 // If set returns undefined, fall back to normal setting
8253 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8254 this.value = val;
8255 }
8256 } );
8257 }
8258} );
8259
8260jQuery.extend( {
8261 valHooks: {
8262 option: {
8263 get: function( elem ) {
8264 var val = jQuery.find.attr( elem, "value" );
8265 return val != null ?
8266 val :
8267
8268 // Support: IE10-11+
8269 // option.text throws exceptions (#14686, #14858)
8270 // Strip and collapse whitespace
8271 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8272 jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8273 }
8274 },
8275 select: {
8276 get: function( elem ) {
8277 var value, option,
8278 options = elem.options,
8279 index = elem.selectedIndex,
8280 one = elem.type === "select-one" || index < 0,
8281 values = one ? null : [],
8282 max = one ? index + 1 : options.length,
8283 i = index < 0 ?
8284 max :
8285 one ? index : 0;
8286
8287 // Loop through all the selected options
8288 for ( ; i < max; i++ ) {
8289 option = options[ i ];
8290
8291 // oldIE doesn't update selected after form reset (#2551)
8292 if ( ( option.selected || i === index ) &&
8293
8294 // Don't return options that are disabled or in a disabled optgroup
8295 ( support.optDisabled ?
8296 !option.disabled :
8297 option.getAttribute( "disabled" ) === null ) &&
8298 ( !option.parentNode.disabled ||
8299 !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8300
8301 // Get the specific value for the option
8302 value = jQuery( option ).val();
8303
8304 // We don't need an array for one selects
8305 if ( one ) {
8306 return value;
8307 }
8308
8309 // Multi-Selects return an array
8310 values.push( value );
8311 }
8312 }
8313
8314 return values;
8315 },
8316
8317 set: function( elem, value ) {
8318 var optionSet, option,
8319 options = elem.options,
8320 values = jQuery.makeArray( value ),
8321 i = options.length;
8322
8323 while ( i-- ) {
8324 option = options[ i ];
8325
8326 if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
8327
8328 // Support: IE6
8329 // When new option element is added to select box we need to
8330 // force reflow of newly added node in order to workaround delay
8331 // of initialization properties
8332 try {
8333 option.selected = optionSet = true;
8334
8335 } catch ( _ ) {
8336
8337 // Will be executed only in IE6
8338 option.scrollHeight;
8339 }
8340
8341 } else {
8342 option.selected = false;
8343 }
8344 }
8345
8346 // Force browsers to behave consistently when non-matching value is set
8347 if ( !optionSet ) {
8348 elem.selectedIndex = -1;
8349 }
8350
8351 return options;
8352 }
8353 }
8354 }
8355} );
8356
8357// Radios and checkboxes getter/setter
8358jQuery.each( [ "radio", "checkbox" ], function() {
8359 jQuery.valHooks[ this ] = {
8360 set: function( elem, value ) {
8361 if ( jQuery.isArray( value ) ) {
8362 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8363 }
8364 }
8365 };
8366 if ( !support.checkOn ) {
8367 jQuery.valHooks[ this ].get = function( elem ) {
8368 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8369 };
8370 }
8371} );
8372
8373
8374
8375
8376var nodeHook, boolHook,
8377 attrHandle = jQuery.expr.attrHandle,
8378 ruseDefault = /^(?:checked|selected)$/i,
8379 getSetAttribute = support.getSetAttribute,
8380 getSetInput = support.input;
8381
8382jQuery.fn.extend( {
8383 attr: function( name, value ) {
8384 return access( this, jQuery.attr, name, value, arguments.length > 1 );
8385 },
8386
8387 removeAttr: function( name ) {
8388 return this.each( function() {
8389 jQuery.removeAttr( this, name );
8390 } );
8391 }
8392} );
8393
8394jQuery.extend( {
8395 attr: function( elem, name, value ) {
8396 var ret, hooks,
8397 nType = elem.nodeType;
8398
8399 // Don't get/set attributes on text, comment and attribute nodes
8400 if ( nType === 3 || nType === 8 || nType === 2 ) {
8401 return;
8402 }
8403
8404 // Fallback to prop when attributes are not supported
8405 if ( typeof elem.getAttribute === "undefined" ) {
8406 return jQuery.prop( elem, name, value );
8407 }
8408
8409 // All attributes are lowercase
8410 // Grab necessary hook if one is defined
8411 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8412 name = name.toLowerCase();
8413 hooks = jQuery.attrHooks[ name ] ||
8414 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
8415 }
8416
8417 if ( value !== undefined ) {
8418 if ( value === null ) {
8419 jQuery.removeAttr( elem, name );
8420 return;
8421 }
8422
8423 if ( hooks && "set" in hooks &&
8424 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8425 return ret;
8426 }
8427
8428 elem.setAttribute( name, value + "" );
8429 return value;
8430 }
8431
8432 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8433 return ret;
8434 }
8435
8436 ret = jQuery.find.attr( elem, name );
8437
8438 // Non-existent attributes return null, we normalize to undefined
8439 return ret == null ? undefined : ret;
8440 },
8441
8442 attrHooks: {
8443 type: {
8444 set: function( elem, value ) {
8445 if ( !support.radioValue && value === "radio" &&
8446 jQuery.nodeName( elem, "input" ) ) {
8447
8448 // Setting the type on a radio button after the value resets the value in IE8-9
8449 // Reset value to default in case type is set after value during creation
8450 var val = elem.value;
8451 elem.setAttribute( "type", value );
8452 if ( val ) {
8453 elem.value = val;
8454 }
8455 return value;
8456 }
8457 }
8458 }
8459 },
8460
8461 removeAttr: function( elem, value ) {
8462 var name, propName,
8463 i = 0,
8464 attrNames = value && value.match( rnotwhite );
8465
8466 if ( attrNames && elem.nodeType === 1 ) {
8467 while ( ( name = attrNames[ i++ ] ) ) {
8468 propName = jQuery.propFix[ name ] || name;
8469
8470 // Boolean attributes get special treatment (#10870)
8471 if ( jQuery.expr.match.bool.test( name ) ) {
8472
8473 // Set corresponding property to false
8474 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8475 elem[ propName ] = false;
8476
8477 // Support: IE<9
8478 // Also clear defaultChecked/defaultSelected (if appropriate)
8479 } else {
8480 elem[ jQuery.camelCase( "default-" + name ) ] =
8481 elem[ propName ] = false;
8482 }
8483
8484 // See #9699 for explanation of this approach (setting first, then removal)
8485 } else {
8486 jQuery.attr( elem, name, "" );
8487 }
8488
8489 elem.removeAttribute( getSetAttribute ? name : propName );
8490 }
8491 }
8492 }
8493} );
8494
8495// Hooks for boolean attributes
8496boolHook = {
8497 set: function( elem, value, name ) {
8498 if ( value === false ) {
8499
8500 // Remove boolean attributes when set to false
8501 jQuery.removeAttr( elem, name );
8502 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8503
8504 // IE<8 needs the *property* name
8505 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8506
8507 } else {
8508
8509 // Support: IE<9
8510 // Use defaultChecked and defaultSelected for oldIE
8511 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8512 }
8513 return name;
8514 }
8515};
8516
8517jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8518 var getter = attrHandle[ name ] || jQuery.find.attr;
8519
8520 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8521 attrHandle[ name ] = function( elem, name, isXML ) {
8522 var ret, handle;
8523 if ( !isXML ) {
8524
8525 // Avoid an infinite loop by temporarily removing this function from the getter
8526 handle = attrHandle[ name ];
8527 attrHandle[ name ] = ret;
8528 ret = getter( elem, name, isXML ) != null ?
8529 name.toLowerCase() :
8530 null;
8531 attrHandle[ name ] = handle;
8532 }
8533 return ret;
8534 };
8535 } else {
8536 attrHandle[ name ] = function( elem, name, isXML ) {
8537 if ( !isXML ) {
8538 return elem[ jQuery.camelCase( "default-" + name ) ] ?
8539 name.toLowerCase() :
8540 null;
8541 }
8542 };
8543 }
8544} );
8545
8546// fix oldIE attroperties
8547if ( !getSetInput || !getSetAttribute ) {
8548 jQuery.attrHooks.value = {
8549 set: function( elem, value, name ) {
8550 if ( jQuery.nodeName( elem, "input" ) ) {
8551
8552 // Does not return so that setAttribute is also used
8553 elem.defaultValue = value;
8554 } else {
8555
8556 // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8557 return nodeHook && nodeHook.set( elem, value, name );
8558 }
8559 }
8560 };
8561}
8562
8563// IE6/7 do not support getting/setting some attributes with get/setAttribute
8564if ( !getSetAttribute ) {
8565
8566 // Use this for any attribute in IE6/7
8567 // This fixes almost every IE6/7 issue
8568 nodeHook = {
8569 set: function( elem, value, name ) {
8570
8571 // Set the existing or create a new attribute node
8572 var ret = elem.getAttributeNode( name );
8573 if ( !ret ) {
8574 elem.setAttributeNode(
8575 ( ret = elem.ownerDocument.createAttribute( name ) )
8576 );
8577 }
8578
8579 ret.value = value += "";
8580
8581 // Break association with cloned elements by also using setAttribute (#9646)
8582 if ( name === "value" || value === elem.getAttribute( name ) ) {
8583 return value;
8584 }
8585 }
8586 };
8587
8588 // Some attributes are constructed with empty-string values when not defined
8589 attrHandle.id = attrHandle.name = attrHandle.coords =
8590 function( elem, name, isXML ) {
8591 var ret;
8592 if ( !isXML ) {
8593 return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
8594 ret.value :
8595 null;
8596 }
8597 };
8598
8599 // Fixing value retrieval on a button requires this module
8600 jQuery.valHooks.button = {
8601 get: function( elem, name ) {
8602 var ret = elem.getAttributeNode( name );
8603 if ( ret && ret.specified ) {
8604 return ret.value;
8605 }
8606 },
8607 set: nodeHook.set
8608 };
8609
8610 // Set contenteditable to false on removals(#10429)
8611 // Setting to empty string throws an error as an invalid value
8612 jQuery.attrHooks.contenteditable = {
8613 set: function( elem, value, name ) {
8614 nodeHook.set( elem, value === "" ? false : value, name );
8615 }
8616 };
8617
8618 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8619 // This is for removals
8620 jQuery.each( [ "width", "height" ], function( i, name ) {
8621 jQuery.attrHooks[ name ] = {
8622 set: function( elem, value ) {
8623 if ( value === "" ) {
8624 elem.setAttribute( name, "auto" );
8625 return value;
8626 }
8627 }
8628 };
8629 } );
8630}
8631
8632if ( !support.style ) {
8633 jQuery.attrHooks.style = {
8634 get: function( elem ) {
8635
8636 // Return undefined in the case of empty string
8637 // Note: IE uppercases css property names, but if we were to .toLowerCase()
8638 // .cssText, that would destroy case sensitivity in URL's, like in "background"
8639 return elem.style.cssText || undefined;
8640 },
8641 set: function( elem, value ) {
8642 return ( elem.style.cssText = value + "" );
8643 }
8644 };
8645}
8646
8647
8648
8649
8650var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8651 rclickable = /^(?:a|area)$/i;
8652
8653jQuery.fn.extend( {
8654 prop: function( name, value ) {
8655 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8656 },
8657
8658 removeProp: function( name ) {
8659 name = jQuery.propFix[ name ] || name;
8660 return this.each( function() {
8661
8662 // try/catch handles cases where IE balks (such as removing a property on window)
8663 try {
8664 this[ name ] = undefined;
8665 delete this[ name ];
8666 } catch ( e ) {}
8667 } );
8668 }
8669} );
8670
8671jQuery.extend( {
8672 prop: function( elem, name, value ) {
8673 var ret, hooks,
8674 nType = elem.nodeType;
8675
8676 // Don't get/set properties on text, comment and attribute nodes
8677 if ( nType === 3 || nType === 8 || nType === 2 ) {
8678 return;
8679 }
8680
8681 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8682
8683 // Fix name and attach hooks
8684 name = jQuery.propFix[ name ] || name;
8685 hooks = jQuery.propHooks[ name ];
8686 }
8687
8688 if ( value !== undefined ) {
8689 if ( hooks && "set" in hooks &&
8690 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8691 return ret;
8692 }
8693
8694 return ( elem[ name ] = value );
8695 }
8696
8697 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8698 return ret;
8699 }
8700
8701 return elem[ name ];
8702 },
8703
8704 propHooks: {
8705 tabIndex: {
8706 get: function( elem ) {
8707
8708 // elem.tabIndex doesn't always return the
8709 // correct value when it hasn't been explicitly set
8710 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8711 // Use proper attribute retrieval(#12072)
8712 var tabindex = jQuery.find.attr( elem, "tabindex" );
8713
8714 return tabindex ?
8715 parseInt( tabindex, 10 ) :
8716 rfocusable.test( elem.nodeName ) ||
8717 rclickable.test( elem.nodeName ) && elem.href ?
8718 0 :
8719 -1;
8720 }
8721 }
8722 },
8723
8724 propFix: {
8725 "for": "htmlFor",
8726 "class": "className"
8727 }
8728} );
8729
8730// Some attributes require a special call on IE
8731// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8732if ( !support.hrefNormalized ) {
8733
8734 // href/src property should get the full normalized URL (#10299/#12915)
8735 jQuery.each( [ "href", "src" ], function( i, name ) {
8736 jQuery.propHooks[ name ] = {
8737 get: function( elem ) {
8738 return elem.getAttribute( name, 4 );
8739 }
8740 };
8741 } );
8742}
8743
8744// Support: Safari, IE9+
8745// Accessing the selectedIndex property
8746// forces the browser to respect setting selected
8747// on the option
8748// The getter ensures a default option is selected
8749// when in an optgroup
8750if ( !support.optSelected ) {
8751 jQuery.propHooks.selected = {
8752 get: function( elem ) {
8753 var parent = elem.parentNode;
8754
8755 if ( parent ) {
8756 parent.selectedIndex;
8757
8758 // Make sure that it also works with optgroups, see #5701
8759 if ( parent.parentNode ) {
8760 parent.parentNode.selectedIndex;
8761 }
8762 }
8763 return null;
8764 },
8765 set: function( elem ) {
8766 var parent = elem.parentNode;
8767 if ( parent ) {
8768 parent.selectedIndex;
8769
8770 if ( parent.parentNode ) {
8771 parent.parentNode.selectedIndex;
8772 }
8773 }
8774 }
8775 };
8776}
8777
8778jQuery.each( [
8779 "tabIndex",
8780 "readOnly",
8781 "maxLength",
8782 "cellSpacing",
8783 "cellPadding",
8784 "rowSpan",
8785 "colSpan",
8786 "useMap",
8787 "frameBorder",
8788 "contentEditable"
8789], function() {
8790 jQuery.propFix[ this.toLowerCase() ] = this;
8791} );
8792
8793// IE6/7 call enctype encoding
8794if ( !support.enctype ) {
8795 jQuery.propFix.enctype = "encoding";
8796}
8797
8798
8799
8800
8801var rclass = /[\t\r\n\f]/g;
8802
8803function getClass( elem ) {
8804 return jQuery.attr( elem, "class" ) || "";
8805}
8806
8807jQuery.fn.extend( {
8808 addClass: function( value ) {
8809 var classes, elem, cur, curValue, clazz, j, finalValue,
8810 i = 0;
8811
8812 if ( jQuery.isFunction( value ) ) {
8813 return this.each( function( j ) {
8814 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8815 } );
8816 }
8817
8818 if ( typeof value === "string" && value ) {
8819 classes = value.match( rnotwhite ) || [];
8820
8821 while ( ( elem = this[ i++ ] ) ) {
8822 curValue = getClass( elem );
8823 cur = elem.nodeType === 1 &&
8824 ( " " + curValue + " " ).replace( rclass, " " );
8825
8826 if ( cur ) {
8827 j = 0;
8828 while ( ( clazz = classes[ j++ ] ) ) {
8829 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8830 cur += clazz + " ";
8831 }
8832 }
8833
8834 // only assign if different to avoid unneeded rendering.
8835 finalValue = jQuery.trim( cur );
8836 if ( curValue !== finalValue ) {
8837 jQuery.attr( elem, "class", finalValue );
8838 }
8839 }
8840 }
8841 }
8842
8843 return this;
8844 },
8845
8846 removeClass: function( value ) {
8847 var classes, elem, cur, curValue, clazz, j, finalValue,
8848 i = 0;
8849
8850 if ( jQuery.isFunction( value ) ) {
8851 return this.each( function( j ) {
8852 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8853 } );
8854 }
8855
8856 if ( !arguments.length ) {
8857 return this.attr( "class", "" );
8858 }
8859
8860 if ( typeof value === "string" && value ) {
8861 classes = value.match( rnotwhite ) || [];
8862
8863 while ( ( elem = this[ i++ ] ) ) {
8864 curValue = getClass( elem );
8865
8866 // This expression is here for better compressibility (see addClass)
8867 cur = elem.nodeType === 1 &&
8868 ( " " + curValue + " " ).replace( rclass, " " );
8869
8870 if ( cur ) {
8871 j = 0;
8872 while ( ( clazz = classes[ j++ ] ) ) {
8873
8874 // Remove *all* instances
8875 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8876 cur = cur.replace( " " + clazz + " ", " " );
8877 }
8878 }
8879
8880 // Only assign if different to avoid unneeded rendering.
8881 finalValue = jQuery.trim( cur );
8882 if ( curValue !== finalValue ) {
8883 jQuery.attr( elem, "class", finalValue );
8884 }
8885 }
8886 }
8887 }
8888
8889 return this;
8890 },
8891
8892 toggleClass: function( value, stateVal ) {
8893 var type = typeof value;
8894
8895 if ( typeof stateVal === "boolean" && type === "string" ) {
8896 return stateVal ? this.addClass( value ) : this.removeClass( value );
8897 }
8898
8899 if ( jQuery.isFunction( value ) ) {
8900 return this.each( function( i ) {
8901 jQuery( this ).toggleClass(
8902 value.call( this, i, getClass( this ), stateVal ),
8903 stateVal
8904 );
8905 } );
8906 }
8907
8908 return this.each( function() {
8909 var className, i, self, classNames;
8910
8911 if ( type === "string" ) {
8912
8913 // Toggle individual class names
8914 i = 0;
8915 self = jQuery( this );
8916 classNames = value.match( rnotwhite ) || [];
8917
8918 while ( ( className = classNames[ i++ ] ) ) {
8919
8920 // Check each className given, space separated list
8921 if ( self.hasClass( className ) ) {
8922 self.removeClass( className );
8923 } else {
8924 self.addClass( className );
8925 }
8926 }
8927
8928 // Toggle whole class name
8929 } else if ( value === undefined || type === "boolean" ) {
8930 className = getClass( this );
8931 if ( className ) {
8932
8933 // store className if set
8934 jQuery._data( this, "__className__", className );
8935 }
8936
8937 // If the element has a class name or if we're passed "false",
8938 // then remove the whole classname (if there was one, the above saved it).
8939 // Otherwise bring back whatever was previously saved (if anything),
8940 // falling back to the empty string if nothing was stored.
8941 jQuery.attr( this, "class",
8942 className || value === false ?
8943 "" :
8944 jQuery._data( this, "__className__" ) || ""
8945 );
8946 }
8947 } );
8948 },
8949
8950 hasClass: function( selector ) {
8951 var className, elem,
8952 i = 0;
8953
8954 className = " " + selector + " ";
8955 while ( ( elem = this[ i++ ] ) ) {
8956 if ( elem.nodeType === 1 &&
8957 ( " " + getClass( elem ) + " " ).replace( rclass, " " )
8958 .indexOf( className ) > -1
8959 ) {
8960 return true;
8961 }
8962 }
8963
8964 return false;
8965 }
8966} );
8967
8968
8969
8970
8971// Return jQuery for attributes-only inclusion
8972
8973
8974jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8975 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8976 "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8977 function( i, name ) {
8978
8979 // Handle event binding
8980 jQuery.fn[ name ] = function( data, fn ) {
8981 return arguments.length > 0 ?
8982 this.on( name, null, data, fn ) :
8983 this.trigger( name );
8984 };
8985} );
8986
8987jQuery.fn.extend( {
8988 hover: function( fnOver, fnOut ) {
8989 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8990 }
8991} );
8992
8993
8994var location = window.location;
8995
8996var nonce = jQuery.now();
8997
8998var rquery = ( /\?/ );
8999
9000
9001
9002var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
9003
9004jQuery.parseJSON = function( data ) {
9005
9006 // Attempt to parse using the native JSON parser first
9007 if ( window.JSON && window.JSON.parse ) {
9008
9009 // Support: Android 2.3
9010 // Workaround failure to string-cast null input
9011 return window.JSON.parse( data + "" );
9012 }
9013
9014 var requireNonComma,
9015 depth = null,
9016 str = jQuery.trim( data + "" );
9017
9018 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
9019 // after removing valid tokens
9020 return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
9021
9022 // Force termination if we see a misplaced comma
9023 if ( requireNonComma && comma ) {
9024 depth = 0;
9025 }
9026
9027 // Perform no more replacements after returning to outermost depth
9028 if ( depth === 0 ) {
9029 return token;
9030 }
9031
9032 // Commas must not follow "[", "{", or ","
9033 requireNonComma = open || comma;
9034
9035 // Determine new depth
9036 // array/object open ("[" or "{"): depth += true - false (increment)
9037 // array/object close ("]" or "}"): depth += false - true (decrement)
9038 // other cases ("," or primitive): depth += true - true (numeric cast)
9039 depth += !close - !open;
9040
9041 // Remove this token
9042 return "";
9043 } ) ) ?
9044 ( Function( "return " + str ) )() :
9045 jQuery.error( "Invalid JSON: " + data );
9046};
9047
9048
9049// Cross-browser xml parsing
9050jQuery.parseXML = function( data ) {
9051 var xml, tmp;
9052 if ( !data || typeof data !== "string" ) {
9053 return null;
9054 }
9055 try {
9056 if ( window.DOMParser ) { // Standard
9057 tmp = new window.DOMParser();
9058 xml = tmp.parseFromString( data, "text/xml" );
9059 } else { // IE
9060 xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
9061 xml.async = "false";
9062 xml.loadXML( data );
9063 }
9064 } catch ( e ) {
9065 xml = undefined;
9066 }
9067 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
9068 jQuery.error( "Invalid XML: " + data );
9069 }
9070 return xml;
9071};
9072
9073
9074var
9075 rhash = /#.*$/,
9076 rts = /([?&])_=[^&]*/,
9077
9078 // IE leaves an \r character at EOL
9079 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
9080
9081 // #7653, #8125, #8152: local protocol detection
9082 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9083 rnoContent = /^(?:GET|HEAD)$/,
9084 rprotocol = /^\/\//,
9085 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
9086
9087 /* Prefilters
9088 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9089 * 2) These are called:
9090 * - BEFORE asking for a transport
9091 * - AFTER param serialization (s.data is a string if s.processData is true)
9092 * 3) key is the dataType
9093 * 4) the catchall symbol "*" can be used
9094 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9095 */
9096 prefilters = {},
9097
9098 /* Transports bindings
9099 * 1) key is the dataType
9100 * 2) the catchall symbol "*" can be used
9101 * 3) selection will start with transport dataType and THEN go to "*" if needed
9102 */
9103 transports = {},
9104
9105 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9106 allTypes = "*/".concat( "*" ),
9107
9108 // Document location
9109 ajaxLocation = location.href,
9110
9111 // Segment location into parts
9112 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
9113
9114// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9115function addToPrefiltersOrTransports( structure ) {
9116
9117 // dataTypeExpression is optional and defaults to "*"
9118 return function( dataTypeExpression, func ) {
9119
9120 if ( typeof dataTypeExpression !== "string" ) {
9121 func = dataTypeExpression;
9122 dataTypeExpression = "*";
9123 }
9124
9125 var dataType,
9126 i = 0,
9127 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
9128
9129 if ( jQuery.isFunction( func ) ) {
9130
9131 // For each dataType in the dataTypeExpression
9132 while ( ( dataType = dataTypes[ i++ ] ) ) {
9133
9134 // Prepend if requested
9135 if ( dataType.charAt( 0 ) === "+" ) {
9136 dataType = dataType.slice( 1 ) || "*";
9137 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9138
9139 // Otherwise append
9140 } else {
9141 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9142 }
9143 }
9144 }
9145 };
9146}
9147
9148// Base inspection function for prefilters and transports
9149function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9150
9151 var inspected = {},
9152 seekingTransport = ( structure === transports );
9153
9154 function inspect( dataType ) {
9155 var selected;
9156 inspected[ dataType ] = true;
9157 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9158 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9159 if ( typeof dataTypeOrTransport === "string" &&
9160 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9161
9162 options.dataTypes.unshift( dataTypeOrTransport );
9163 inspect( dataTypeOrTransport );
9164 return false;
9165 } else if ( seekingTransport ) {
9166 return !( selected = dataTypeOrTransport );
9167 }
9168 } );
9169 return selected;
9170 }
9171
9172 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9173}
9174
9175// A special extend for ajax options
9176// that takes "flat" options (not to be deep extended)
9177// Fixes #9887
9178function ajaxExtend( target, src ) {
9179 var deep, key,
9180 flatOptions = jQuery.ajaxSettings.flatOptions || {};
9181
9182 for ( key in src ) {
9183 if ( src[ key ] !== undefined ) {
9184 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9185 }
9186 }
9187 if ( deep ) {
9188 jQuery.extend( true, target, deep );
9189 }
9190
9191 return target;
9192}
9193
9194/* Handles responses to an ajax request:
9195 * - finds the right dataType (mediates between content-type and expected dataType)
9196 * - returns the corresponding response
9197 */
9198function ajaxHandleResponses( s, jqXHR, responses ) {
9199 var firstDataType, ct, finalDataType, type,
9200 contents = s.contents,
9201 dataTypes = s.dataTypes;
9202
9203 // Remove auto dataType and get content-type in the process
9204 while ( dataTypes[ 0 ] === "*" ) {
9205 dataTypes.shift();
9206 if ( ct === undefined ) {
9207 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9208 }
9209 }
9210
9211 // Check if we're dealing with a known content-type
9212 if ( ct ) {
9213 for ( type in contents ) {
9214 if ( contents[ type ] && contents[ type ].test( ct ) ) {
9215 dataTypes.unshift( type );
9216 break;
9217 }
9218 }
9219 }
9220
9221 // Check to see if we have a response for the expected dataType
9222 if ( dataTypes[ 0 ] in responses ) {
9223 finalDataType = dataTypes[ 0 ];
9224 } else {
9225
9226 // Try convertible dataTypes
9227 for ( type in responses ) {
9228 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9229 finalDataType = type;
9230 break;
9231 }
9232 if ( !firstDataType ) {
9233 firstDataType = type;
9234 }
9235 }
9236
9237 // Or just use first one
9238 finalDataType = finalDataType || firstDataType;
9239 }
9240
9241 // If we found a dataType
9242 // We add the dataType to the list if needed
9243 // and return the corresponding response
9244 if ( finalDataType ) {
9245 if ( finalDataType !== dataTypes[ 0 ] ) {
9246 dataTypes.unshift( finalDataType );
9247 }
9248 return responses[ finalDataType ];
9249 }
9250}
9251
9252/* Chain conversions given the request and the original response
9253 * Also sets the responseXXX fields on the jqXHR instance
9254 */
9255function ajaxConvert( s, response, jqXHR, isSuccess ) {
9256 var conv2, current, conv, tmp, prev,
9257 converters = {},
9258
9259 // Work with a copy of dataTypes in case we need to modify it for conversion
9260 dataTypes = s.dataTypes.slice();
9261
9262 // Create converters map with lowercased keys
9263 if ( dataTypes[ 1 ] ) {
9264 for ( conv in s.converters ) {
9265 converters[ conv.toLowerCase() ] = s.converters[ conv ];
9266 }
9267 }
9268
9269 current = dataTypes.shift();
9270
9271 // Convert to each sequential dataType
9272 while ( current ) {
9273
9274 if ( s.responseFields[ current ] ) {
9275 jqXHR[ s.responseFields[ current ] ] = response;
9276 }
9277
9278 // Apply the dataFilter if provided
9279 if ( !prev && isSuccess && s.dataFilter ) {
9280 response = s.dataFilter( response, s.dataType );
9281 }
9282
9283 prev = current;
9284 current = dataTypes.shift();
9285
9286 if ( current ) {
9287
9288 // There's only work to do if current dataType is non-auto
9289 if ( current === "*" ) {
9290
9291 current = prev;
9292
9293 // Convert response if prev dataType is non-auto and differs from current
9294 } else if ( prev !== "*" && prev !== current ) {
9295
9296 // Seek a direct converter
9297 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9298
9299 // If none found, seek a pair
9300 if ( !conv ) {
9301 for ( conv2 in converters ) {
9302
9303 // If conv2 outputs current
9304 tmp = conv2.split( " " );
9305 if ( tmp[ 1 ] === current ) {
9306
9307 // If prev can be converted to accepted input
9308 conv = converters[ prev + " " + tmp[ 0 ] ] ||
9309 converters[ "* " + tmp[ 0 ] ];
9310 if ( conv ) {
9311
9312 // Condense equivalence converters
9313 if ( conv === true ) {
9314 conv = converters[ conv2 ];
9315
9316 // Otherwise, insert the intermediate dataType
9317 } else if ( converters[ conv2 ] !== true ) {
9318 current = tmp[ 0 ];
9319 dataTypes.unshift( tmp[ 1 ] );
9320 }
9321 break;
9322 }
9323 }
9324 }
9325 }
9326
9327 // Apply converter (if not an equivalence)
9328 if ( conv !== true ) {
9329
9330 // Unless errors are allowed to bubble, catch and return them
9331 if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
9332 response = conv( response );
9333 } else {
9334 try {
9335 response = conv( response );
9336 } catch ( e ) {
9337 return {
9338 state: "parsererror",
9339 error: conv ? e : "No conversion from " + prev + " to " + current
9340 };
9341 }
9342 }
9343 }
9344 }
9345 }
9346 }
9347
9348 return { state: "success", data: response };
9349}
9350
9351jQuery.extend( {
9352
9353 // Counter for holding the number of active queries
9354 active: 0,
9355
9356 // Last-Modified header cache for next request
9357 lastModified: {},
9358 etag: {},
9359
9360 ajaxSettings: {
9361 url: ajaxLocation,
9362 type: "GET",
9363 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
9364 global: true,
9365 processData: true,
9366 async: true,
9367 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9368 /*
9369 timeout: 0,
9370 data: null,
9371 dataType: null,
9372 username: null,
9373 password: null,
9374 cache: null,
9375 throws: false,
9376 traditional: false,
9377 headers: {},
9378 */
9379
9380 accepts: {
9381 "*": allTypes,
9382 text: "text/plain",
9383 html: "text/html",
9384 xml: "application/xml, text/xml",
9385 json: "application/json, text/javascript"
9386 },
9387
9388 contents: {
9389 xml: /\bxml\b/,
9390 html: /\bhtml/,
9391 json: /\bjson\b/
9392 },
9393
9394 responseFields: {
9395 xml: "responseXML",
9396 text: "responseText",
9397 json: "responseJSON"
9398 },
9399
9400 // Data converters
9401 // Keys separate source (or catchall "*") and destination types with a single space
9402 converters: {
9403
9404 // Convert anything to text
9405 "* text": String,
9406
9407 // Text to html (true = no transformation)
9408 "text html": true,
9409
9410 // Evaluate text as a json expression
9411 "text json": jQuery.parseJSON,
9412
9413 // Parse text as xml
9414 "text xml": jQuery.parseXML
9415 },
9416
9417 // For options that shouldn't be deep extended:
9418 // you can add your own custom options here if
9419 // and when you create one that shouldn't be
9420 // deep extended (see ajaxExtend)
9421 flatOptions: {
9422 url: true,
9423 context: true
9424 }
9425 },
9426
9427 // Creates a full fledged settings object into target
9428 // with both ajaxSettings and settings fields.
9429 // If target is omitted, writes into ajaxSettings.
9430 ajaxSetup: function( target, settings ) {
9431 return settings ?
9432
9433 // Building a settings object
9434 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9435
9436 // Extending ajaxSettings
9437 ajaxExtend( jQuery.ajaxSettings, target );
9438 },
9439
9440 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9441 ajaxTransport: addToPrefiltersOrTransports( transports ),
9442
9443 // Main method
9444 ajax: function( url, options ) {
9445
9446 // If url is an object, simulate pre-1.5 signature
9447 if ( typeof url === "object" ) {
9448 options = url;
9449 url = undefined;
9450 }
9451
9452 // Force options to be an object
9453 options = options || {};
9454
9455 var
9456
9457 // Cross-domain detection vars
9458 parts,
9459
9460 // Loop variable
9461 i,
9462
9463 // URL without anti-cache param
9464 cacheURL,
9465
9466 // Response headers as string
9467 responseHeadersString,
9468
9469 // timeout handle
9470 timeoutTimer,
9471
9472 // To know if global events are to be dispatched
9473 fireGlobals,
9474
9475 transport,
9476
9477 // Response headers
9478 responseHeaders,
9479
9480 // Create the final options object
9481 s = jQuery.ajaxSetup( {}, options ),
9482
9483 // Callbacks context
9484 callbackContext = s.context || s,
9485
9486 // Context for global events is callbackContext if it is a DOM node or jQuery collection
9487 globalEventContext = s.context &&
9488 ( callbackContext.nodeType || callbackContext.jquery ) ?
9489 jQuery( callbackContext ) :
9490 jQuery.event,
9491
9492 // Deferreds
9493 deferred = jQuery.Deferred(),
9494 completeDeferred = jQuery.Callbacks( "once memory" ),
9495
9496 // Status-dependent callbacks
9497 statusCode = s.statusCode || {},
9498
9499 // Headers (they are sent all at once)
9500 requestHeaders = {},
9501 requestHeadersNames = {},
9502
9503 // The jqXHR state
9504 state = 0,
9505
9506 // Default abort message
9507 strAbort = "canceled",
9508
9509 // Fake xhr
9510 jqXHR = {
9511 readyState: 0,
9512
9513 // Builds headers hashtable if needed
9514 getResponseHeader: function( key ) {
9515 var match;
9516 if ( state === 2 ) {
9517 if ( !responseHeaders ) {
9518 responseHeaders = {};
9519 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9520 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
9521 }
9522 }
9523 match = responseHeaders[ key.toLowerCase() ];
9524 }
9525 return match == null ? null : match;
9526 },
9527
9528 // Raw string
9529 getAllResponseHeaders: function() {
9530 return state === 2 ? responseHeadersString : null;
9531 },
9532
9533 // Caches the header
9534 setRequestHeader: function( name, value ) {
9535 var lname = name.toLowerCase();
9536 if ( !state ) {
9537 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9538 requestHeaders[ name ] = value;
9539 }
9540 return this;
9541 },
9542
9543 // Overrides response content-type header
9544 overrideMimeType: function( type ) {
9545 if ( !state ) {
9546 s.mimeType = type;
9547 }
9548 return this;
9549 },
9550
9551 // Status-dependent callbacks
9552 statusCode: function( map ) {
9553 var code;
9554 if ( map ) {
9555 if ( state < 2 ) {
9556 for ( code in map ) {
9557
9558 // Lazy-add the new callback in a way that preserves old ones
9559 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9560 }
9561 } else {
9562
9563 // Execute the appropriate callbacks
9564 jqXHR.always( map[ jqXHR.status ] );
9565 }
9566 }
9567 return this;
9568 },
9569
9570 // Cancel the request
9571 abort: function( statusText ) {
9572 var finalText = statusText || strAbort;
9573 if ( transport ) {
9574 transport.abort( finalText );
9575 }
9576 done( 0, finalText );
9577 return this;
9578 }
9579 };
9580
9581 // Attach deferreds
9582 deferred.promise( jqXHR ).complete = completeDeferred.add;
9583 jqXHR.success = jqXHR.done;
9584 jqXHR.error = jqXHR.fail;
9585
9586 // Remove hash character (#7531: and string promotion)
9587 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9588 // Handle falsy url in the settings object (#10093: consistency with old signature)
9589 // We also use the url parameter if available
9590 s.url = ( ( url || s.url || ajaxLocation ) + "" )
9591 .replace( rhash, "" )
9592 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9593
9594 // Alias method option to type as per ticket #12004
9595 s.type = options.method || options.type || s.method || s.type;
9596
9597 // Extract dataTypes list
9598 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9599
9600 // A cross-domain request is in order when we have a protocol:host:port mismatch
9601 if ( s.crossDomain == null ) {
9602 parts = rurl.exec( s.url.toLowerCase() );
9603 s.crossDomain = !!( parts &&
9604 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9605 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9606 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9607 );
9608 }
9609
9610 // Convert data if not already a string
9611 if ( s.data && s.processData && typeof s.data !== "string" ) {
9612 s.data = jQuery.param( s.data, s.traditional );
9613 }
9614
9615 // Apply prefilters
9616 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9617
9618 // If request was aborted inside a prefilter, stop there
9619 if ( state === 2 ) {
9620 return jqXHR;
9621 }
9622
9623 // We can fire global events as of now if asked to
9624 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9625 fireGlobals = jQuery.event && s.global;
9626
9627 // Watch for a new set of requests
9628 if ( fireGlobals && jQuery.active++ === 0 ) {
9629 jQuery.event.trigger( "ajaxStart" );
9630 }
9631
9632 // Uppercase the type
9633 s.type = s.type.toUpperCase();
9634
9635 // Determine if request has content
9636 s.hasContent = !rnoContent.test( s.type );
9637
9638 // Save the URL in case we're toying with the If-Modified-Since
9639 // and/or If-None-Match header later on
9640 cacheURL = s.url;
9641
9642 // More options handling for requests with no content
9643 if ( !s.hasContent ) {
9644
9645 // If data is available, append data to url
9646 if ( s.data ) {
9647 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9648
9649 // #9682: remove data so that it's not used in an eventual retry
9650 delete s.data;
9651 }
9652
9653 // Add anti-cache in url if needed
9654 if ( s.cache === false ) {
9655 s.url = rts.test( cacheURL ) ?
9656
9657 // If there is already a '_' parameter, set its value
9658 cacheURL.replace( rts, "$1_=" + nonce++ ) :
9659
9660 // Otherwise add one to the end
9661 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9662 }
9663 }
9664
9665 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9666 if ( s.ifModified ) {
9667 if ( jQuery.lastModified[ cacheURL ] ) {
9668 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9669 }
9670 if ( jQuery.etag[ cacheURL ] ) {
9671 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9672 }
9673 }
9674
9675 // Set the correct header, if data is being sent
9676 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9677 jqXHR.setRequestHeader( "Content-Type", s.contentType );
9678 }
9679
9680 // Set the Accepts header for the server, depending on the dataType
9681 jqXHR.setRequestHeader(
9682 "Accept",
9683 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9684 s.accepts[ s.dataTypes[ 0 ] ] +
9685 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9686 s.accepts[ "*" ]
9687 );
9688
9689 // Check for headers option
9690 for ( i in s.headers ) {
9691 jqXHR.setRequestHeader( i, s.headers[ i ] );
9692 }
9693
9694 // Allow custom headers/mimetypes and early abort
9695 if ( s.beforeSend &&
9696 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9697
9698 // Abort if not done already and return
9699 return jqXHR.abort();
9700 }
9701
9702 // aborting is no longer a cancellation
9703 strAbort = "abort";
9704
9705 // Install callbacks on deferreds
9706 for ( i in { success: 1, error: 1, complete: 1 } ) {
9707 jqXHR[ i ]( s[ i ] );
9708 }
9709
9710 // Get transport
9711 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9712
9713 // If no transport, we auto-abort
9714 if ( !transport ) {
9715 done( -1, "No Transport" );
9716 } else {
9717 jqXHR.readyState = 1;
9718
9719 // Send global event
9720 if ( fireGlobals ) {
9721 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9722 }
9723
9724 // If request was aborted inside ajaxSend, stop there
9725 if ( state === 2 ) {
9726 return jqXHR;
9727 }
9728
9729 // Timeout
9730 if ( s.async && s.timeout > 0 ) {
9731 timeoutTimer = window.setTimeout( function() {
9732 jqXHR.abort( "timeout" );
9733 }, s.timeout );
9734 }
9735
9736 try {
9737 state = 1;
9738 transport.send( requestHeaders, done );
9739 } catch ( e ) {
9740
9741 // Propagate exception as error if not done
9742 if ( state < 2 ) {
9743 done( -1, e );
9744
9745 // Simply rethrow otherwise
9746 } else {
9747 throw e;
9748 }
9749 }
9750 }
9751
9752 // Callback for when everything is done
9753 function done( status, nativeStatusText, responses, headers ) {
9754 var isSuccess, success, error, response, modified,
9755 statusText = nativeStatusText;
9756
9757 // Called once
9758 if ( state === 2 ) {
9759 return;
9760 }
9761
9762 // State is "done" now
9763 state = 2;
9764
9765 // Clear timeout if it exists
9766 if ( timeoutTimer ) {
9767 window.clearTimeout( timeoutTimer );
9768 }
9769
9770 // Dereference transport for early garbage collection
9771 // (no matter how long the jqXHR object will be used)
9772 transport = undefined;
9773
9774 // Cache response headers
9775 responseHeadersString = headers || "";
9776
9777 // Set readyState
9778 jqXHR.readyState = status > 0 ? 4 : 0;
9779
9780 // Determine if successful
9781 isSuccess = status >= 200 && status < 300 || status === 304;
9782
9783 // Get response data
9784 if ( responses ) {
9785 response = ajaxHandleResponses( s, jqXHR, responses );
9786 }
9787
9788 // Convert no matter what (that way responseXXX fields are always set)
9789 response = ajaxConvert( s, response, jqXHR, isSuccess );
9790
9791 // If successful, handle type chaining
9792 if ( isSuccess ) {
9793
9794 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9795 if ( s.ifModified ) {
9796 modified = jqXHR.getResponseHeader( "Last-Modified" );
9797 if ( modified ) {
9798 jQuery.lastModified[ cacheURL ] = modified;
9799 }
9800 modified = jqXHR.getResponseHeader( "etag" );
9801 if ( modified ) {
9802 jQuery.etag[ cacheURL ] = modified;
9803 }
9804 }
9805
9806 // if no content
9807 if ( status === 204 || s.type === "HEAD" ) {
9808 statusText = "nocontent";
9809
9810 // if not modified
9811 } else if ( status === 304 ) {
9812 statusText = "notmodified";
9813
9814 // If we have data, let's convert it
9815 } else {
9816 statusText = response.state;
9817 success = response.data;
9818 error = response.error;
9819 isSuccess = !error;
9820 }
9821 } else {
9822
9823 // We extract error from statusText
9824 // then normalize statusText and status for non-aborts
9825 error = statusText;
9826 if ( status || !statusText ) {
9827 statusText = "error";
9828 if ( status < 0 ) {
9829 status = 0;
9830 }
9831 }
9832 }
9833
9834 // Set data for the fake xhr object
9835 jqXHR.status = status;
9836 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9837
9838 // Success/Error
9839 if ( isSuccess ) {
9840 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9841 } else {
9842 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9843 }
9844
9845 // Status-dependent callbacks
9846 jqXHR.statusCode( statusCode );
9847 statusCode = undefined;
9848
9849 if ( fireGlobals ) {
9850 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9851 [ jqXHR, s, isSuccess ? success : error ] );
9852 }
9853
9854 // Complete
9855 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9856
9857 if ( fireGlobals ) {
9858 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9859
9860 // Handle the global AJAX counter
9861 if ( !( --jQuery.active ) ) {
9862 jQuery.event.trigger( "ajaxStop" );
9863 }
9864 }
9865 }
9866
9867 return jqXHR;
9868 },
9869
9870 getJSON: function( url, data, callback ) {
9871 return jQuery.get( url, data, callback, "json" );
9872 },
9873
9874 getScript: function( url, callback ) {
9875 return jQuery.get( url, undefined, callback, "script" );
9876 }
9877} );
9878
9879jQuery.each( [ "get", "post" ], function( i, method ) {
9880 jQuery[ method ] = function( url, data, callback, type ) {
9881
9882 // shift arguments if data argument was omitted
9883 if ( jQuery.isFunction( data ) ) {
9884 type = type || callback;
9885 callback = data;
9886 data = undefined;
9887 }
9888
9889 // The url can be an options object (which then must have .url)
9890 return jQuery.ajax( jQuery.extend( {
9891 url: url,
9892 type: method,
9893 dataType: type,
9894 data: data,
9895 success: callback
9896 }, jQuery.isPlainObject( url ) && url ) );
9897 };
9898} );
9899
9900
9901jQuery._evalUrl = function( url ) {
9902 return jQuery.ajax( {
9903 url: url,
9904
9905 // Make this explicit, since user can override this through ajaxSetup (#11264)
9906 type: "GET",
9907 dataType: "script",
9908 cache: true,
9909 async: false,
9910 global: false,
9911 "throws": true
9912 } );
9913};
9914
9915
9916jQuery.fn.extend( {
9917 wrapAll: function( html ) {
9918 if ( jQuery.isFunction( html ) ) {
9919 return this.each( function( i ) {
9920 jQuery( this ).wrapAll( html.call( this, i ) );
9921 } );
9922 }
9923
9924 if ( this[ 0 ] ) {
9925
9926 // The elements to wrap the target around
9927 var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9928
9929 if ( this[ 0 ].parentNode ) {
9930 wrap.insertBefore( this[ 0 ] );
9931 }
9932
9933 wrap.map( function() {
9934 var elem = this;
9935
9936 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9937 elem = elem.firstChild;
9938 }
9939
9940 return elem;
9941 } ).append( this );
9942 }
9943
9944 return this;
9945 },
9946
9947 wrapInner: function( html ) {
9948 if ( jQuery.isFunction( html ) ) {
9949 return this.each( function( i ) {
9950 jQuery( this ).wrapInner( html.call( this, i ) );
9951 } );
9952 }
9953
9954 return this.each( function() {
9955 var self = jQuery( this ),
9956 contents = self.contents();
9957
9958 if ( contents.length ) {
9959 contents.wrapAll( html );
9960
9961 } else {
9962 self.append( html );
9963 }
9964 } );
9965 },
9966
9967 wrap: function( html ) {
9968 var isFunction = jQuery.isFunction( html );
9969
9970 return this.each( function( i ) {
9971 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9972 } );
9973 },
9974
9975 unwrap: function() {
9976 return this.parent().each( function() {
9977 if ( !jQuery.nodeName( this, "body" ) ) {
9978 jQuery( this ).replaceWith( this.childNodes );
9979 }
9980 } ).end();
9981 }
9982} );
9983
9984
9985function getDisplay( elem ) {
9986 return elem.style && elem.style.display || jQuery.css( elem, "display" );
9987}
9988
9989function filterHidden( elem ) {
9990
9991 // Disconnected elements are considered hidden
9992 if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
9993 return true;
9994 }
9995 while ( elem && elem.nodeType === 1 ) {
9996 if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
9997 return true;
9998 }
9999 elem = elem.parentNode;
10000 }
10001 return false;
10002}
10003
10004jQuery.expr.filters.hidden = function( elem ) {
10005
10006 // Support: Opera <= 12.12
10007 // Opera reports offsetWidths and offsetHeights less than zero on some elements
10008 return support.reliableHiddenOffsets() ?
10009 ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
10010 !elem.getClientRects().length ) :
10011 filterHidden( elem );
10012};
10013
10014jQuery.expr.filters.visible = function( elem ) {
10015 return !jQuery.expr.filters.hidden( elem );
10016};
10017
10018
10019
10020
10021var r20 = /%20/g,
10022 rbracket = /\[\]$/,
10023 rCRLF = /\r?\n/g,
10024 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10025 rsubmittable = /^(?:input|select|textarea|keygen)/i;
10026
10027function buildParams( prefix, obj, traditional, add ) {
10028 var name;
10029
10030 if ( jQuery.isArray( obj ) ) {
10031
10032 // Serialize array item.
10033 jQuery.each( obj, function( i, v ) {
10034 if ( traditional || rbracket.test( prefix ) ) {
10035
10036 // Treat each array item as a scalar.
10037 add( prefix, v );
10038
10039 } else {
10040
10041 // Item is non-scalar (array or object), encode its numeric index.
10042 buildParams(
10043 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10044 v,
10045 traditional,
10046 add
10047 );
10048 }
10049 } );
10050
10051 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
10052
10053 // Serialize object item.
10054 for ( name in obj ) {
10055 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10056 }
10057
10058 } else {
10059
10060 // Serialize scalar item.
10061 add( prefix, obj );
10062 }
10063}
10064
10065// Serialize an array of form elements or a set of
10066// key/values into a query string
10067jQuery.param = function( a, traditional ) {
10068 var prefix,
10069 s = [],
10070 add = function( key, value ) {
10071
10072 // If value is a function, invoke it and return its value
10073 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
10074 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
10075 };
10076
10077 // Set traditional to true for jQuery <= 1.3.2 behavior.
10078 if ( traditional === undefined ) {
10079 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
10080 }
10081
10082 // If an array was passed in, assume that it is an array of form elements.
10083 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10084
10085 // Serialize the form elements
10086 jQuery.each( a, function() {
10087 add( this.name, this.value );
10088 } );
10089
10090 } else {
10091
10092 // If traditional, encode the "old" way (the way 1.3.2 or older
10093 // did it), otherwise encode params recursively.
10094 for ( prefix in a ) {
10095 buildParams( prefix, a[ prefix ], traditional, add );
10096 }
10097 }
10098
10099 // Return the resulting serialization
10100 return s.join( "&" ).replace( r20, "+" );
10101};
10102
10103jQuery.fn.extend( {
10104 serialize: function() {
10105 return jQuery.param( this.serializeArray() );
10106 },
10107 serializeArray: function() {
10108 return this.map( function() {
10109
10110 // Can add propHook for "elements" to filter or add form elements
10111 var elements = jQuery.prop( this, "elements" );
10112 return elements ? jQuery.makeArray( elements ) : this;
10113 } )
10114 .filter( function() {
10115 var type = this.type;
10116
10117 // Use .is(":disabled") so that fieldset[disabled] works
10118 return this.name && !jQuery( this ).is( ":disabled" ) &&
10119 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10120 ( this.checked || !rcheckableType.test( type ) );
10121 } )
10122 .map( function( i, elem ) {
10123 var val = jQuery( this ).val();
10124
10125 return val == null ?
10126 null :
10127 jQuery.isArray( val ) ?
10128 jQuery.map( val, function( val ) {
10129 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10130 } ) :
10131 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10132 } ).get();
10133 }
10134} );
10135
10136
10137// Create the request object
10138// (This is still attached to ajaxSettings for backward compatibility)
10139jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
10140
10141 // Support: IE6-IE8
10142 function() {
10143
10144 // XHR cannot access local files, always use ActiveX for that case
10145 if ( this.isLocal ) {
10146 return createActiveXHR();
10147 }
10148
10149 // Support: IE 9-11
10150 // IE seems to error on cross-domain PATCH requests when ActiveX XHR
10151 // is used. In IE 9+ always use the native XHR.
10152 // Note: this condition won't catch Edge as it doesn't define
10153 // document.documentMode but it also doesn't support ActiveX so it won't
10154 // reach this code.
10155 if ( document.documentMode > 8 ) {
10156 return createStandardXHR();
10157 }
10158
10159 // Support: IE<9
10160 // oldIE XHR does not support non-RFC2616 methods (#13240)
10161 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
10162 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10163 // Although this check for six methods instead of eight
10164 // since IE also does not support "trace" and "connect"
10165 return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
10166 createStandardXHR() || createActiveXHR();
10167 } :
10168
10169 // For all other browsers, use the standard XMLHttpRequest object
10170 createStandardXHR;
10171
10172var xhrId = 0,
10173 xhrCallbacks = {},
10174 xhrSupported = jQuery.ajaxSettings.xhr();
10175
10176// Support: IE<10
10177// Open requests must be manually aborted on unload (#5280)
10178// See https://support.microsoft.com/kb/2856746 for more info
10179if ( window.attachEvent ) {
10180 window.attachEvent( "onunload", function() {
10181 for ( var key in xhrCallbacks ) {
10182 xhrCallbacks[ key ]( undefined, true );
10183 }
10184 } );
10185}
10186
10187// Determine support properties
10188support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10189xhrSupported = support.ajax = !!xhrSupported;
10190
10191// Create transport if the browser can provide an xhr
10192if ( xhrSupported ) {
10193
10194 jQuery.ajaxTransport( function( options ) {
10195
10196 // Cross domain only allowed if supported through XMLHttpRequest
10197 if ( !options.crossDomain || support.cors ) {
10198
10199 var callback;
10200
10201 return {
10202 send: function( headers, complete ) {
10203 var i,
10204 xhr = options.xhr(),
10205 id = ++xhrId;
10206
10207 // Open the socket
10208 xhr.open(
10209 options.type,
10210 options.url,
10211 options.async,
10212 options.username,
10213 options.password
10214 );
10215
10216 // Apply custom fields if provided
10217 if ( options.xhrFields ) {
10218 for ( i in options.xhrFields ) {
10219 xhr[ i ] = options.xhrFields[ i ];
10220 }
10221 }
10222
10223 // Override mime type if needed
10224 if ( options.mimeType && xhr.overrideMimeType ) {
10225 xhr.overrideMimeType( options.mimeType );
10226 }
10227
10228 // X-Requested-With header
10229 // For cross-domain requests, seeing as conditions for a preflight are
10230 // akin to a jigsaw puzzle, we simply never set it to be sure.
10231 // (it can always be set on a per-request basis or even using ajaxSetup)
10232 // For same-domain requests, won't change header if already provided.
10233 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10234 headers[ "X-Requested-With" ] = "XMLHttpRequest";
10235 }
10236
10237 // Set headers
10238 for ( i in headers ) {
10239
10240 // Support: IE<9
10241 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
10242 // request header to a null-value.
10243 //
10244 // To keep consistent with other XHR implementations, cast the value
10245 // to string and ignore `undefined`.
10246 if ( headers[ i ] !== undefined ) {
10247 xhr.setRequestHeader( i, headers[ i ] + "" );
10248 }
10249 }
10250
10251 // Do send the request
10252 // This may raise an exception which is actually
10253 // handled in jQuery.ajax (so no try/catch here)
10254 xhr.send( ( options.hasContent && options.data ) || null );
10255
10256 // Listener
10257 callback = function( _, isAbort ) {
10258 var status, statusText, responses;
10259
10260 // Was never called and is aborted or complete
10261 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
10262
10263 // Clean up
10264 delete xhrCallbacks[ id ];
10265 callback = undefined;
10266 xhr.onreadystatechange = jQuery.noop;
10267
10268 // Abort manually if needed
10269 if ( isAbort ) {
10270 if ( xhr.readyState !== 4 ) {
10271 xhr.abort();
10272 }
10273 } else {
10274 responses = {};
10275 status = xhr.status;
10276
10277 // Support: IE<10
10278 // Accessing binary-data responseText throws an exception
10279 // (#11426)
10280 if ( typeof xhr.responseText === "string" ) {
10281 responses.text = xhr.responseText;
10282 }
10283
10284 // Firefox throws an exception when accessing
10285 // statusText for faulty cross-domain requests
10286 try {
10287 statusText = xhr.statusText;
10288 } catch ( e ) {
10289
10290 // We normalize with Webkit giving an empty statusText
10291 statusText = "";
10292 }
10293
10294 // Filter status for non standard behaviors
10295
10296 // If the request is local and we have data: assume a success
10297 // (success with no data won't get notified, that's the best we
10298 // can do given current implementations)
10299 if ( !status && options.isLocal && !options.crossDomain ) {
10300 status = responses.text ? 200 : 404;
10301
10302 // IE - #1450: sometimes returns 1223 when it should be 204
10303 } else if ( status === 1223 ) {
10304 status = 204;
10305 }
10306 }
10307 }
10308
10309 // Call complete if needed
10310 if ( responses ) {
10311 complete( status, statusText, responses, xhr.getAllResponseHeaders() );
10312 }
10313 };
10314
10315 // Do send the request
10316 // `xhr.send` may raise an exception, but it will be
10317 // handled in jQuery.ajax (so no try/catch here)
10318 if ( !options.async ) {
10319
10320 // If we're in sync mode we fire the callback
10321 callback();
10322 } else if ( xhr.readyState === 4 ) {
10323
10324 // (IE6 & IE7) if it's in cache and has been
10325 // retrieved directly we need to fire the callback
10326 window.setTimeout( callback );
10327 } else {
10328
10329 // Register the callback, but delay it in case `xhr.send` throws
10330 // Add to the list of active xhr callbacks
10331 xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
10332 }
10333 },
10334
10335 abort: function() {
10336 if ( callback ) {
10337 callback( undefined, true );
10338 }
10339 }
10340 };
10341 }
10342 } );
10343}
10344
10345// Functions to create xhrs
10346function createStandardXHR() {
10347 try {
10348 return new window.XMLHttpRequest();
10349 } catch ( e ) {}
10350}
10351
10352function createActiveXHR() {
10353 try {
10354 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
10355 } catch ( e ) {}
10356}
10357
10358
10359
10360
10361// Install script dataType
10362jQuery.ajaxSetup( {
10363 accepts: {
10364 script: "text/javascript, application/javascript, " +
10365 "application/ecmascript, application/x-ecmascript"
10366 },
10367 contents: {
10368 script: /\b(?:java|ecma)script\b/
10369 },
10370 converters: {
10371 "text script": function( text ) {
10372 jQuery.globalEval( text );
10373 return text;
10374 }
10375 }
10376} );
10377
10378// Handle cache's special case and global
10379jQuery.ajaxPrefilter( "script", function( s ) {
10380 if ( s.cache === undefined ) {
10381 s.cache = false;
10382 }
10383 if ( s.crossDomain ) {
10384 s.type = "GET";
10385 s.global = false;
10386 }
10387} );
10388
10389// Bind script tag hack transport
10390jQuery.ajaxTransport( "script", function( s ) {
10391
10392 // This transport only deals with cross domain requests
10393 if ( s.crossDomain ) {
10394
10395 var script,
10396 head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
10397
10398 return {
10399
10400 send: function( _, callback ) {
10401
10402 script = document.createElement( "script" );
10403
10404 script.async = true;
10405
10406 if ( s.scriptCharset ) {
10407 script.charset = s.scriptCharset;
10408 }
10409
10410 script.src = s.url;
10411
10412 // Attach handlers for all browsers
10413 script.onload = script.onreadystatechange = function( _, isAbort ) {
10414
10415 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
10416
10417 // Handle memory leak in IE
10418 script.onload = script.onreadystatechange = null;
10419
10420 // Remove the script
10421 if ( script.parentNode ) {
10422 script.parentNode.removeChild( script );
10423 }
10424
10425 // Dereference the script
10426 script = null;
10427
10428 // Callback if not abort
10429 if ( !isAbort ) {
10430 callback( 200, "success" );
10431 }
10432 }
10433 };
10434
10435 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10436 // Use native DOM manipulation to avoid our domManip AJAX trickery
10437 head.insertBefore( script, head.firstChild );
10438 },
10439
10440 abort: function() {
10441 if ( script ) {
10442 script.onload( undefined, true );
10443 }
10444 }
10445 };
10446 }
10447} );
10448
10449
10450
10451
10452var oldCallbacks = [],
10453 rjsonp = /(=)\?(?=&|$)|\?\?/;
10454
10455// Default jsonp settings
10456jQuery.ajaxSetup( {
10457 jsonp: "callback",
10458 jsonpCallback: function() {
10459 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
10460 this[ callback ] = true;
10461 return callback;
10462 }
10463} );
10464
10465// Detect, normalize options and install callbacks for jsonp requests
10466jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10467
10468 var callbackName, overwritten, responseContainer,
10469 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10470 "url" :
10471 typeof s.data === "string" &&
10472 ( s.contentType || "" )
10473 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10474 rjsonp.test( s.data ) && "data"
10475 );
10476
10477 // Handle iff the expected data type is "jsonp" or we have a parameter to set
10478 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10479
10480 // Get callback name, remembering preexisting value associated with it
10481 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
10482 s.jsonpCallback() :
10483 s.jsonpCallback;
10484
10485 // Insert callback into url or form data
10486 if ( jsonProp ) {
10487 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10488 } else if ( s.jsonp !== false ) {
10489 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10490 }
10491
10492 // Use data converter to retrieve json after script execution
10493 s.converters[ "script json" ] = function() {
10494 if ( !responseContainer ) {
10495 jQuery.error( callbackName + " was not called" );
10496 }
10497 return responseContainer[ 0 ];
10498 };
10499
10500 // force json dataType
10501 s.dataTypes[ 0 ] = "json";
10502
10503 // Install callback
10504 overwritten = window[ callbackName ];
10505 window[ callbackName ] = function() {
10506 responseContainer = arguments;
10507 };
10508
10509 // Clean-up function (fires after converters)
10510 jqXHR.always( function() {
10511
10512 // If previous value didn't exist - remove it
10513 if ( overwritten === undefined ) {
10514 jQuery( window ).removeProp( callbackName );
10515
10516 // Otherwise restore preexisting value
10517 } else {
10518 window[ callbackName ] = overwritten;
10519 }
10520
10521 // Save back as free
10522 if ( s[ callbackName ] ) {
10523
10524 // make sure that re-using the options doesn't screw things around
10525 s.jsonpCallback = originalSettings.jsonpCallback;
10526
10527 // save the callback name for future use
10528 oldCallbacks.push( callbackName );
10529 }
10530
10531 // Call if it was a function and we have a response
10532 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
10533 overwritten( responseContainer[ 0 ] );
10534 }
10535
10536 responseContainer = overwritten = undefined;
10537 } );
10538
10539 // Delegate to script
10540 return "script";
10541 }
10542} );
10543
10544
10545
10546
10547// data: string of html
10548// context (optional): If specified, the fragment will be created in this context,
10549// defaults to document
10550// keepScripts (optional): If true, will include scripts passed in the html string
10551jQuery.parseHTML = function( data, context, keepScripts ) {
10552 if ( !data || typeof data !== "string" ) {
10553 return null;
10554 }
10555 if ( typeof context === "boolean" ) {
10556 keepScripts = context;
10557 context = false;
10558 }
10559 context = context || document;
10560
10561 var parsed = rsingleTag.exec( data ),
10562 scripts = !keepScripts && [];
10563
10564 // Single tag
10565 if ( parsed ) {
10566 return [ context.createElement( parsed[ 1 ] ) ];
10567 }
10568
10569 parsed = buildFragment( [ data ], context, scripts );
10570
10571 if ( scripts && scripts.length ) {
10572 jQuery( scripts ).remove();
10573 }
10574
10575 return jQuery.merge( [], parsed.childNodes );
10576};
10577
10578
10579// Keep a copy of the old load method
10580var _load = jQuery.fn.load;
10581
10582/**
10583 * Load a url into a page
10584 */
10585jQuery.fn.load = function( url, params, callback ) {
10586 if ( typeof url !== "string" && _load ) {
10587 return _load.apply( this, arguments );
10588 }
10589
10590 var selector, type, response,
10591 self = this,
10592 off = url.indexOf( " " );
10593
10594 if ( off > -1 ) {
10595 selector = jQuery.trim( url.slice( off, url.length ) );
10596 url = url.slice( 0, off );
10597 }
10598
10599 // If it's a function
10600 if ( jQuery.isFunction( params ) ) {
10601
10602 // We assume that it's the callback
10603 callback = params;
10604 params = undefined;
10605
10606 // Otherwise, build a param string
10607 } else if ( params && typeof params === "object" ) {
10608 type = "POST";
10609 }
10610
10611 // If we have elements to modify, make the request
10612 if ( self.length > 0 ) {
10613 jQuery.ajax( {
10614 url: url,
10615
10616 // If "type" variable is undefined, then "GET" method will be used.
10617 // Make value of this field explicit since
10618 // user can override it through ajaxSetup method
10619 type: type || "GET",
10620 dataType: "html",
10621 data: params
10622 } ).done( function( responseText ) {
10623
10624 // Save response for use in complete callback
10625 response = arguments;
10626
10627 self.html( selector ?
10628
10629 // If a selector was specified, locate the right elements in a dummy div
10630 // Exclude scripts to avoid IE 'Permission Denied' errors
10631 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10632
10633 // Otherwise use the full result
10634 responseText );
10635
10636 // If the request succeeds, this function gets "data", "status", "jqXHR"
10637 // but they are ignored because response was set above.
10638 // If it fails, this function gets "jqXHR", "status", "error"
10639 } ).always( callback && function( jqXHR, status ) {
10640 self.each( function() {
10641 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10642 } );
10643 } );
10644 }
10645
10646 return this;
10647};
10648
10649
10650
10651
10652// Attach a bunch of functions for handling common AJAX events
10653jQuery.each( [
10654 "ajaxStart",
10655 "ajaxStop",
10656 "ajaxComplete",
10657 "ajaxError",
10658 "ajaxSuccess",
10659 "ajaxSend"
10660], function( i, type ) {
10661 jQuery.fn[ type ] = function( fn ) {
10662 return this.on( type, fn );
10663 };
10664} );
10665
10666
10667
10668
10669jQuery.expr.filters.animated = function( elem ) {
10670 return jQuery.grep( jQuery.timers, function( fn ) {
10671 return elem === fn.elem;
10672 } ).length;
10673};
10674
10675
10676
10677
10678
10679/**
10680 * Gets a window from an element
10681 */
10682function getWindow( elem ) {
10683 return jQuery.isWindow( elem ) ?
10684 elem :
10685 elem.nodeType === 9 ?
10686 elem.defaultView || elem.parentWindow :
10687 false;
10688}
10689
10690jQuery.offset = {
10691 setOffset: function( elem, options, i ) {
10692 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10693 position = jQuery.css( elem, "position" ),
10694 curElem = jQuery( elem ),
10695 props = {};
10696
10697 // set position first, in-case top/left are set even on static elem
10698 if ( position === "static" ) {
10699 elem.style.position = "relative";
10700 }
10701
10702 curOffset = curElem.offset();
10703 curCSSTop = jQuery.css( elem, "top" );
10704 curCSSLeft = jQuery.css( elem, "left" );
10705 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10706 jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
10707
10708 // need to be able to calculate position if either top or left
10709 // is auto and position is either absolute or fixed
10710 if ( calculatePosition ) {
10711 curPosition = curElem.position();
10712 curTop = curPosition.top;
10713 curLeft = curPosition.left;
10714 } else {
10715 curTop = parseFloat( curCSSTop ) || 0;
10716 curLeft = parseFloat( curCSSLeft ) || 0;
10717 }
10718
10719 if ( jQuery.isFunction( options ) ) {
10720
10721 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10722 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10723 }
10724
10725 if ( options.top != null ) {
10726 props.top = ( options.top - curOffset.top ) + curTop;
10727 }
10728 if ( options.left != null ) {
10729 props.left = ( options.left - curOffset.left ) + curLeft;
10730 }
10731
10732 if ( "using" in options ) {
10733 options.using.call( elem, props );
10734 } else {
10735 curElem.css( props );
10736 }
10737 }
10738};
10739
10740jQuery.fn.extend( {
10741 offset: function( options ) {
10742 if ( arguments.length ) {
10743 return options === undefined ?
10744 this :
10745 this.each( function( i ) {
10746 jQuery.offset.setOffset( this, options, i );
10747 } );
10748 }
10749
10750 var docElem, win,
10751 box = { top: 0, left: 0 },
10752 elem = this[ 0 ],
10753 doc = elem && elem.ownerDocument;
10754
10755 if ( !doc ) {
10756 return;
10757 }
10758
10759 docElem = doc.documentElement;
10760
10761 // Make sure it's not a disconnected DOM node
10762 if ( !jQuery.contains( docElem, elem ) ) {
10763 return box;
10764 }
10765
10766 // If we don't have gBCR, just use 0,0 rather than error
10767 // BlackBerry 5, iOS 3 (original iPhone)
10768 if ( typeof elem.getBoundingClientRect !== "undefined" ) {
10769 box = elem.getBoundingClientRect();
10770 }
10771 win = getWindow( doc );
10772 return {
10773 top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10774 left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10775 };
10776 },
10777
10778 position: function() {
10779 if ( !this[ 0 ] ) {
10780 return;
10781 }
10782
10783 var offsetParent, offset,
10784 parentOffset = { top: 0, left: 0 },
10785 elem = this[ 0 ];
10786
10787 // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10788 // because it is its only offset parent
10789 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10790
10791 // we assume that getBoundingClientRect is available when computed position is fixed
10792 offset = elem.getBoundingClientRect();
10793 } else {
10794
10795 // Get *real* offsetParent
10796 offsetParent = this.offsetParent();
10797
10798 // Get correct offsets
10799 offset = this.offset();
10800 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10801 parentOffset = offsetParent.offset();
10802 }
10803
10804 // Add offsetParent borders
10805 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10806 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10807 }
10808
10809 // Subtract parent offsets and element margins
10810 // note: when an element has margin: auto the offsetLeft and marginLeft
10811 // are the same in Safari causing offset.left to incorrectly be 0
10812 return {
10813 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10814 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10815 };
10816 },
10817
10818 offsetParent: function() {
10819 return this.map( function() {
10820 var offsetParent = this.offsetParent;
10821
10822 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
10823 jQuery.css( offsetParent, "position" ) === "static" ) ) {
10824 offsetParent = offsetParent.offsetParent;
10825 }
10826 return offsetParent || documentElement;
10827 } );
10828 }
10829} );
10830
10831// Create scrollLeft and scrollTop methods
10832jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10833 var top = /Y/.test( prop );
10834
10835 jQuery.fn[ method ] = function( val ) {
10836 return access( this, function( elem, method, val ) {
10837 var win = getWindow( elem );
10838
10839 if ( val === undefined ) {
10840 return win ? ( prop in win ) ? win[ prop ] :
10841 win.document.documentElement[ method ] :
10842 elem[ method ];
10843 }
10844
10845 if ( win ) {
10846 win.scrollTo(
10847 !top ? val : jQuery( win ).scrollLeft(),
10848 top ? val : jQuery( win ).scrollTop()
10849 );
10850
10851 } else {
10852 elem[ method ] = val;
10853 }
10854 }, method, val, arguments.length, null );
10855 };
10856} );
10857
10858// Support: Safari<7-8+, Chrome<37-44+
10859// Add the top/left cssHooks using jQuery.fn.position
10860// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10861// getComputedStyle returns percent when specified for top/left/bottom/right
10862// rather than make the css module depend on the offset module, we just check for it here
10863jQuery.each( [ "top", "left" ], function( i, prop ) {
10864 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10865 function( elem, computed ) {
10866 if ( computed ) {
10867 computed = curCSS( elem, prop );
10868
10869 // if curCSS returns percentage, fallback to offset
10870 return rnumnonpx.test( computed ) ?
10871 jQuery( elem ).position()[ prop ] + "px" :
10872 computed;
10873 }
10874 }
10875 );
10876} );
10877
10878
10879// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10880jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10881 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10882 function( defaultExtra, funcName ) {
10883
10884 // margin is only for outerHeight, outerWidth
10885 jQuery.fn[ funcName ] = function( margin, value ) {
10886 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10887 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10888
10889 return access( this, function( elem, type, value ) {
10890 var doc;
10891
10892 if ( jQuery.isWindow( elem ) ) {
10893
10894 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10895 // isn't a whole lot we can do. See pull request at this URL for discussion:
10896 // https://github.com/jquery/jquery/pull/764
10897 return elem.document.documentElement[ "client" + name ];
10898 }
10899
10900 // Get document width or height
10901 if ( elem.nodeType === 9 ) {
10902 doc = elem.documentElement;
10903
10904 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10905 // whichever is greatest
10906 // unfortunately, this causes bug #3838 in IE6/8 only,
10907 // but there is currently no good, small way to fix it.
10908 return Math.max(
10909 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10910 elem.body[ "offset" + name ], doc[ "offset" + name ],
10911 doc[ "client" + name ]
10912 );
10913 }
10914
10915 return value === undefined ?
10916
10917 // Get width or height on the element, requesting but not forcing parseFloat
10918 jQuery.css( elem, type, extra ) :
10919
10920 // Set width or height on the element
10921 jQuery.style( elem, type, value, extra );
10922 }, type, chainable ? margin : undefined, chainable, null );
10923 };
10924 } );
10925} );
10926
10927
10928jQuery.fn.extend( {
10929
10930 bind: function( types, data, fn ) {
10931 return this.on( types, null, data, fn );
10932 },
10933 unbind: function( types, fn ) {
10934 return this.off( types, null, fn );
10935 },
10936
10937 delegate: function( selector, types, data, fn ) {
10938 return this.on( types, selector, data, fn );
10939 },
10940 undelegate: function( selector, types, fn ) {
10941
10942 // ( namespace ) or ( selector, types [, fn] )
10943 return arguments.length === 1 ?
10944 this.off( selector, "**" ) :
10945 this.off( types, selector || "**", fn );
10946 }
10947} );
10948
10949// The number of elements contained in the matched element set
10950jQuery.fn.size = function() {
10951 return this.length;
10952};
10953
10954jQuery.fn.andSelf = jQuery.fn.addBack;
10955
10956
10957
10958
10959// Register as a named AMD module, since jQuery can be concatenated with other
10960// files that may use define, but not via a proper concatenation script that
10961// understands anonymous AMD modules. A named AMD is safest and most robust
10962// way to register. Lowercase jquery is used because AMD module names are
10963// derived from file names, and jQuery is normally delivered in a lowercase
10964// file name. Do this after creating the global so that if an AMD module wants
10965// to call noConflict to hide this version of jQuery, it will work.
10966
10967// Note that for maximum portability, libraries that are not jQuery should
10968// declare themselves as anonymous modules, and avoid setting a global if an
10969// AMD loader is present. jQuery is a special case. For more information, see
10970// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10971
10972if ( typeof define === "function" && define.amd ) {
10973 define( "jquery", [], function() {
10974 return jQuery;
10975 } );
10976}
10977
10978
10979
10980var
10981
10982 // Map over jQuery in case of overwrite
10983 _jQuery = window.jQuery,
10984
10985 // Map over the $ in case of overwrite
10986 _$ = window.$;
10987
10988jQuery.noConflict = function( deep ) {
10989 if ( window.$ === jQuery ) {
10990 window.$ = _$;
10991 }
10992
10993 if ( deep && window.jQuery === jQuery ) {
10994 window.jQuery = _jQuery;
10995 }
10996
10997 return jQuery;
10998};
10999
11000// Expose jQuery and $ identifiers, even in
11001// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11002// and CommonJS for browser emulators (#13566)
11003if ( !noGlobal ) {
11004 window.jQuery = window.$ = jQuery;
11005}
11006
11007return jQuery;
11008}));
11009
11010/*!
11011 * Bootstrap v3.4.1 (https://getbootstrap.com/)
11012 * Copyright 2011-2019 Twitter, Inc.
11013 * Licensed under the MIT license
11014 */
11015
11016if (typeof jQuery === 'undefined') {
11017 throw new Error('Bootstrap\'s JavaScript requires jQuery')
11018}
11019
11020+function ($) {
11021 'use strict';
11022 var version = $.fn.jquery.split(' ')[0].split('.')
11023 if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
11024 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
11025 }
11026}(jQuery);
11027
11028/* ========================================================================
11029 * Bootstrap: transition.js v3.4.1
11030 * https://getbootstrap.com/docs/3.4/javascript/#transitions
11031 * ========================================================================
11032 * Copyright 2011-2019 Twitter, Inc.
11033 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11034 * ======================================================================== */
11035
11036
11037+function ($) {
11038 'use strict';
11039
11040 // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)
11041 // ============================================================
11042
11043 function transitionEnd() {
11044 var el = document.createElement('bootstrap')
11045
11046 var transEndEventNames = {
11047 WebkitTransition : 'webkitTransitionEnd',
11048 MozTransition : 'transitionend',
11049 OTransition : 'oTransitionEnd otransitionend',
11050 transition : 'transitionend'
11051 }
11052
11053 for (var name in transEndEventNames) {
11054 if (el.style[name] !== undefined) {
11055 return { end: transEndEventNames[name] }
11056 }
11057 }
11058
11059 return false // explicit for ie8 ( ._.)
11060 }
11061
11062 // https://blog.alexmaccaw.com/css-transitions
11063 $.fn.emulateTransitionEnd = function (duration) {
11064 var called = false
11065 var $el = this
11066 $(this).one('bsTransitionEnd', function () { called = true })
11067 var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
11068 setTimeout(callback, duration)
11069 return this
11070 }
11071
11072 $(function () {
11073 $.support.transition = transitionEnd()
11074
11075 if (!$.support.transition) return
11076
11077 $.event.special.bsTransitionEnd = {
11078 bindType: $.support.transition.end,
11079 delegateType: $.support.transition.end,
11080 handle: function (e) {
11081 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
11082 }
11083 }
11084 })
11085
11086}(jQuery);
11087
11088/* ========================================================================
11089 * Bootstrap: alert.js v3.4.1
11090 * https://getbootstrap.com/docs/3.4/javascript/#alerts
11091 * ========================================================================
11092 * Copyright 2011-2019 Twitter, Inc.
11093 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11094 * ======================================================================== */
11095
11096
11097+function ($) {
11098 'use strict';
11099
11100 // ALERT CLASS DEFINITION
11101 // ======================
11102
11103 var dismiss = '[data-dismiss="alert"]'
11104 var Alert = function (el) {
11105 $(el).on('click', dismiss, this.close)
11106 }
11107
11108 Alert.VERSION = '3.4.1'
11109
11110 Alert.TRANSITION_DURATION = 150
11111
11112 Alert.prototype.close = function (e) {
11113 var $this = $(this)
11114 var selector = $this.attr('data-target')
11115
11116 if (!selector) {
11117 selector = $this.attr('href')
11118 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
11119 }
11120
11121 selector = selector === '#' ? [] : selector
11122 var $parent = $(document).find(selector)
11123
11124 if (e) e.preventDefault()
11125
11126 if (!$parent.length) {
11127 $parent = $this.closest('.alert')
11128 }
11129
11130 $parent.trigger(e = $.Event('close.bs.alert'))
11131
11132 if (e.isDefaultPrevented()) return
11133
11134 $parent.removeClass('in')
11135
11136 function removeElement() {
11137 // detach from parent, fire event then clean up data
11138 $parent.detach().trigger('closed.bs.alert').remove()
11139 }
11140
11141 $.support.transition && $parent.hasClass('fade') ?
11142 $parent
11143 .one('bsTransitionEnd', removeElement)
11144 .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
11145 removeElement()
11146 }
11147
11148
11149 // ALERT PLUGIN DEFINITION
11150 // =======================
11151
11152 function Plugin(option) {
11153 return this.each(function () {
11154 var $this = $(this)
11155 var data = $this.data('bs.alert')
11156
11157 if (!data) $this.data('bs.alert', (data = new Alert(this)))
11158 if (typeof option == 'string') data[option].call($this)
11159 })
11160 }
11161
11162 var old = $.fn.alert
11163
11164 $.fn.alert = Plugin
11165 $.fn.alert.Constructor = Alert
11166
11167
11168 // ALERT NO CONFLICT
11169 // =================
11170
11171 $.fn.alert.noConflict = function () {
11172 $.fn.alert = old
11173 return this
11174 }
11175
11176
11177 // ALERT DATA-API
11178 // ==============
11179
11180 $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
11181
11182}(jQuery);
11183
11184/* ========================================================================
11185 * Bootstrap: button.js v3.4.1
11186 * https://getbootstrap.com/docs/3.4/javascript/#buttons
11187 * ========================================================================
11188 * Copyright 2011-2019 Twitter, Inc.
11189 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11190 * ======================================================================== */
11191
11192
11193+function ($) {
11194 'use strict';
11195
11196 // BUTTON PUBLIC CLASS DEFINITION
11197 // ==============================
11198
11199 var Button = function (element, options) {
11200 this.$element = $(element)
11201 this.options = $.extend({}, Button.DEFAULTS, options)
11202 this.isLoading = false
11203 }
11204
11205 Button.VERSION = '3.4.1'
11206
11207 Button.DEFAULTS = {
11208 loadingText: 'loading...'
11209 }
11210
11211 Button.prototype.setState = function (state) {
11212 var d = 'disabled'
11213 var $el = this.$element
11214 var val = $el.is('input') ? 'val' : 'html'
11215 var data = $el.data()
11216
11217 state += 'Text'
11218
11219 if (data.resetText == null) $el.data('resetText', $el[val]())
11220
11221 // push to event loop to allow forms to submit
11222 setTimeout($.proxy(function () {
11223 $el[val](data[state] == null ? this.options[state] : data[state])
11224
11225 if (state == 'loadingText') {
11226 this.isLoading = true
11227 $el.addClass(d).attr(d, d).prop(d, true)
11228 } else if (this.isLoading) {
11229 this.isLoading = false
11230 $el.removeClass(d).removeAttr(d).prop(d, false)
11231 }
11232 }, this), 0)
11233 }
11234
11235 Button.prototype.toggle = function () {
11236 var changed = true
11237 var $parent = this.$element.closest('[data-toggle="buttons"]')
11238
11239 if ($parent.length) {
11240 var $input = this.$element.find('input')
11241 if ($input.prop('type') == 'radio') {
11242 if ($input.prop('checked')) changed = false
11243 $parent.find('.active').removeClass('active')
11244 this.$element.addClass('active')
11245 } else if ($input.prop('type') == 'checkbox') {
11246 if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
11247 this.$element.toggleClass('active')
11248 }
11249 $input.prop('checked', this.$element.hasClass('active'))
11250 if (changed) $input.trigger('change')
11251 } else {
11252 this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
11253 this.$element.toggleClass('active')
11254 }
11255 }
11256
11257
11258 // BUTTON PLUGIN DEFINITION
11259 // ========================
11260
11261 function Plugin(option) {
11262 return this.each(function () {
11263 var $this = $(this)
11264 var data = $this.data('bs.button')
11265 var options = typeof option == 'object' && option
11266
11267 if (!data) $this.data('bs.button', (data = new Button(this, options)))
11268
11269 if (option == 'toggle') data.toggle()
11270 else if (option) data.setState(option)
11271 })
11272 }
11273
11274 var old = $.fn.button
11275
11276 $.fn.button = Plugin
11277 $.fn.button.Constructor = Button
11278
11279
11280 // BUTTON NO CONFLICT
11281 // ==================
11282
11283 $.fn.button.noConflict = function () {
11284 $.fn.button = old
11285 return this
11286 }
11287
11288
11289 // BUTTON DATA-API
11290 // ===============
11291
11292 $(document)
11293 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
11294 var $btn = $(e.target).closest('.btn')
11295 Plugin.call($btn, 'toggle')
11296 if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
11297 // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
11298 e.preventDefault()
11299 // The target component still receive the focus
11300 if ($btn.is('input,button')) $btn.trigger('focus')
11301 else $btn.find('input:visible,button:visible').first().trigger('focus')
11302 }
11303 })
11304 .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
11305 $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
11306 })
11307
11308}(jQuery);
11309
11310/* ========================================================================
11311 * Bootstrap: carousel.js v3.4.1
11312 * https://getbootstrap.com/docs/3.4/javascript/#carousel
11313 * ========================================================================
11314 * Copyright 2011-2019 Twitter, Inc.
11315 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11316 * ======================================================================== */
11317
11318
11319+function ($) {
11320 'use strict';
11321
11322 // CAROUSEL CLASS DEFINITION
11323 // =========================
11324
11325 var Carousel = function (element, options) {
11326 this.$element = $(element)
11327 this.$indicators = this.$element.find('.carousel-indicators')
11328 this.options = options
11329 this.paused = null
11330 this.sliding = null
11331 this.interval = null
11332 this.$active = null
11333 this.$items = null
11334
11335 this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
11336
11337 this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
11338 .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
11339 .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
11340 }
11341
11342 Carousel.VERSION = '3.4.1'
11343
11344 Carousel.TRANSITION_DURATION = 600
11345
11346 Carousel.DEFAULTS = {
11347 interval: 5000,
11348 pause: 'hover',
11349 wrap: true,
11350 keyboard: true
11351 }
11352
11353 Carousel.prototype.keydown = function (e) {
11354 if (/input|textarea/i.test(e.target.tagName)) return
11355 switch (e.which) {
11356 case 37: this.prev(); break
11357 case 39: this.next(); break
11358 default: return
11359 }
11360
11361 e.preventDefault()
11362 }
11363
11364 Carousel.prototype.cycle = function (e) {
11365 e || (this.paused = false)
11366
11367 this.interval && clearInterval(this.interval)
11368
11369 this.options.interval
11370 && !this.paused
11371 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
11372
11373 return this
11374 }
11375
11376 Carousel.prototype.getItemIndex = function (item) {
11377 this.$items = item.parent().children('.item')
11378 return this.$items.index(item || this.$active)
11379 }
11380
11381 Carousel.prototype.getItemForDirection = function (direction, active) {
11382 var activeIndex = this.getItemIndex(active)
11383 var willWrap = (direction == 'prev' && activeIndex === 0)
11384 || (direction == 'next' && activeIndex == (this.$items.length - 1))
11385 if (willWrap && !this.options.wrap) return active
11386 var delta = direction == 'prev' ? -1 : 1
11387 var itemIndex = (activeIndex + delta) % this.$items.length
11388 return this.$items.eq(itemIndex)
11389 }
11390
11391 Carousel.prototype.to = function (pos) {
11392 var that = this
11393 var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
11394
11395 if (pos > (this.$items.length - 1) || pos < 0) return
11396
11397 if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
11398 if (activeIndex == pos) return this.pause().cycle()
11399
11400 return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
11401 }
11402
11403 Carousel.prototype.pause = function (e) {
11404 e || (this.paused = true)
11405
11406 if (this.$element.find('.next, .prev').length && $.support.transition) {
11407 this.$element.trigger($.support.transition.end)
11408 this.cycle(true)
11409 }
11410
11411 this.interval = clearInterval(this.interval)
11412
11413 return this
11414 }
11415
11416 Carousel.prototype.next = function () {
11417 if (this.sliding) return
11418 return this.slide('next')
11419 }
11420
11421 Carousel.prototype.prev = function () {
11422 if (this.sliding) return
11423 return this.slide('prev')
11424 }
11425
11426 Carousel.prototype.slide = function (type, next) {
11427 var $active = this.$element.find('.item.active')
11428 var $next = next || this.getItemForDirection(type, $active)
11429 var isCycling = this.interval
11430 var direction = type == 'next' ? 'left' : 'right'
11431 var that = this
11432
11433 if ($next.hasClass('active')) return (this.sliding = false)
11434
11435 var relatedTarget = $next[0]
11436 var slideEvent = $.Event('slide.bs.carousel', {
11437 relatedTarget: relatedTarget,
11438 direction: direction
11439 })
11440 this.$element.trigger(slideEvent)
11441 if (slideEvent.isDefaultPrevented()) return
11442
11443 this.sliding = true
11444
11445 isCycling && this.pause()
11446
11447 if (this.$indicators.length) {
11448 this.$indicators.find('.active').removeClass('active')
11449 var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
11450 $nextIndicator && $nextIndicator.addClass('active')
11451 }
11452
11453 var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
11454 if ($.support.transition && this.$element.hasClass('slide')) {
11455 $next.addClass(type)
11456 if (typeof $next === 'object' && $next.length) {
11457 $next[0].offsetWidth // force reflow
11458 }
11459 $active.addClass(direction)
11460 $next.addClass(direction)
11461 $active
11462 .one('bsTransitionEnd', function () {
11463 $next.removeClass([type, direction].join(' ')).addClass('active')
11464 $active.removeClass(['active', direction].join(' '))
11465 that.sliding = false
11466 setTimeout(function () {
11467 that.$element.trigger(slidEvent)
11468 }, 0)
11469 })
11470 .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
11471 } else {
11472 $active.removeClass('active')
11473 $next.addClass('active')
11474 this.sliding = false
11475 this.$element.trigger(slidEvent)
11476 }
11477
11478 isCycling && this.cycle()
11479
11480 return this
11481 }
11482
11483
11484 // CAROUSEL PLUGIN DEFINITION
11485 // ==========================
11486
11487 function Plugin(option) {
11488 return this.each(function () {
11489 var $this = $(this)
11490 var data = $this.data('bs.carousel')
11491 var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
11492 var action = typeof option == 'string' ? option : options.slide
11493
11494 if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
11495 if (typeof option == 'number') data.to(option)
11496 else if (action) data[action]()
11497 else if (options.interval) data.pause().cycle()
11498 })
11499 }
11500
11501 var old = $.fn.carousel
11502
11503 $.fn.carousel = Plugin
11504 $.fn.carousel.Constructor = Carousel
11505
11506
11507 // CAROUSEL NO CONFLICT
11508 // ====================
11509
11510 $.fn.carousel.noConflict = function () {
11511 $.fn.carousel = old
11512 return this
11513 }
11514
11515
11516 // CAROUSEL DATA-API
11517 // =================
11518
11519 var clickHandler = function (e) {
11520 var $this = $(this)
11521 var href = $this.attr('href')
11522 if (href) {
11523 href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
11524 }
11525
11526 var target = $this.attr('data-target') || href
11527 var $target = $(document).find(target)
11528
11529 if (!$target.hasClass('carousel')) return
11530
11531 var options = $.extend({}, $target.data(), $this.data())
11532 var slideIndex = $this.attr('data-slide-to')
11533 if (slideIndex) options.interval = false
11534
11535 Plugin.call($target, options)
11536
11537 if (slideIndex) {
11538 $target.data('bs.carousel').to(slideIndex)
11539 }
11540
11541 e.preventDefault()
11542 }
11543
11544 $(document)
11545 .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
11546 .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
11547
11548 $(window).on('load', function () {
11549 $('[data-ride="carousel"]').each(function () {
11550 var $carousel = $(this)
11551 Plugin.call($carousel, $carousel.data())
11552 })
11553 })
11554
11555}(jQuery);
11556
11557/* ========================================================================
11558 * Bootstrap: collapse.js v3.4.1
11559 * https://getbootstrap.com/docs/3.4/javascript/#collapse
11560 * ========================================================================
11561 * Copyright 2011-2019 Twitter, Inc.
11562 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11563 * ======================================================================== */
11564
11565/* jshint latedef: false */
11566
11567+function ($) {
11568 'use strict';
11569
11570 // COLLAPSE PUBLIC CLASS DEFINITION
11571 // ================================
11572
11573 var Collapse = function (element, options) {
11574 this.$element = $(element)
11575 this.options = $.extend({}, Collapse.DEFAULTS, options)
11576 this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
11577 '[data-toggle="collapse"][data-target="#' + element.id + '"]')
11578 this.transitioning = null
11579
11580 if (this.options.parent) {
11581 this.$parent = this.getParent()
11582 } else {
11583 this.addAriaAndCollapsedClass(this.$element, this.$trigger)
11584 }
11585
11586 if (this.options.toggle) this.toggle()
11587 }
11588
11589 Collapse.VERSION = '3.4.1'
11590
11591 Collapse.TRANSITION_DURATION = 350
11592
11593 Collapse.DEFAULTS = {
11594 toggle: true
11595 }
11596
11597 Collapse.prototype.dimension = function () {
11598 var hasWidth = this.$element.hasClass('width')
11599 return hasWidth ? 'width' : 'height'
11600 }
11601
11602 Collapse.prototype.show = function () {
11603 if (this.transitioning || this.$element.hasClass('in')) return
11604
11605 var activesData
11606 var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
11607
11608 if (actives && actives.length) {
11609 activesData = actives.data('bs.collapse')
11610 if (activesData && activesData.transitioning) return
11611 }
11612
11613 var startEvent = $.Event('show.bs.collapse')
11614 this.$element.trigger(startEvent)
11615 if (startEvent.isDefaultPrevented()) return
11616
11617 if (actives && actives.length) {
11618 Plugin.call(actives, 'hide')
11619 activesData || actives.data('bs.collapse', null)
11620 }
11621
11622 var dimension = this.dimension()
11623
11624 this.$element
11625 .removeClass('collapse')
11626 .addClass('collapsing')[dimension](0)
11627 .attr('aria-expanded', true)
11628
11629 this.$trigger
11630 .removeClass('collapsed')
11631 .attr('aria-expanded', true)
11632
11633 this.transitioning = 1
11634
11635 var complete = function () {
11636 this.$element
11637 .removeClass('collapsing')
11638 .addClass('collapse in')[dimension]('')
11639 this.transitioning = 0
11640 this.$element
11641 .trigger('shown.bs.collapse')
11642 }
11643
11644 if (!$.support.transition) return complete.call(this)
11645
11646 var scrollSize = $.camelCase(['scroll', dimension].join('-'))
11647
11648 this.$element
11649 .one('bsTransitionEnd', $.proxy(complete, this))
11650 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
11651 }
11652
11653 Collapse.prototype.hide = function () {
11654 if (this.transitioning || !this.$element.hasClass('in')) return
11655
11656 var startEvent = $.Event('hide.bs.collapse')
11657 this.$element.trigger(startEvent)
11658 if (startEvent.isDefaultPrevented()) return
11659
11660 var dimension = this.dimension()
11661
11662 this.$element[dimension](this.$element[dimension]())[0].offsetHeight
11663
11664 this.$element
11665 .addClass('collapsing')
11666 .removeClass('collapse in')
11667 .attr('aria-expanded', false)
11668
11669 this.$trigger
11670 .addClass('collapsed')
11671 .attr('aria-expanded', false)
11672
11673 this.transitioning = 1
11674
11675 var complete = function () {
11676 this.transitioning = 0
11677 this.$element
11678 .removeClass('collapsing')
11679 .addClass('collapse')
11680 .trigger('hidden.bs.collapse')
11681 }
11682
11683 if (!$.support.transition) return complete.call(this)
11684
11685 this.$element
11686 [dimension](0)
11687 .one('bsTransitionEnd', $.proxy(complete, this))
11688 .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
11689 }
11690
11691 Collapse.prototype.toggle = function () {
11692 this[this.$element.hasClass('in') ? 'hide' : 'show']()
11693 }
11694
11695 Collapse.prototype.getParent = function () {
11696 return $(document).find(this.options.parent)
11697 .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
11698 .each($.proxy(function (i, element) {
11699 var $element = $(element)
11700 this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
11701 }, this))
11702 .end()
11703 }
11704
11705 Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
11706 var isOpen = $element.hasClass('in')
11707
11708 $element.attr('aria-expanded', isOpen)
11709 $trigger
11710 .toggleClass('collapsed', !isOpen)
11711 .attr('aria-expanded', isOpen)
11712 }
11713
11714 function getTargetFromTrigger($trigger) {
11715 var href
11716 var target = $trigger.attr('data-target')
11717 || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
11718
11719 return $(document).find(target)
11720 }
11721
11722
11723 // COLLAPSE PLUGIN DEFINITION
11724 // ==========================
11725
11726 function Plugin(option) {
11727 return this.each(function () {
11728 var $this = $(this)
11729 var data = $this.data('bs.collapse')
11730 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
11731
11732 if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
11733 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
11734 if (typeof option == 'string') data[option]()
11735 })
11736 }
11737
11738 var old = $.fn.collapse
11739
11740 $.fn.collapse = Plugin
11741 $.fn.collapse.Constructor = Collapse
11742
11743
11744 // COLLAPSE NO CONFLICT
11745 // ====================
11746
11747 $.fn.collapse.noConflict = function () {
11748 $.fn.collapse = old
11749 return this
11750 }
11751
11752
11753 // COLLAPSE DATA-API
11754 // =================
11755
11756 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
11757 var $this = $(this)
11758
11759 if (!$this.attr('data-target')) e.preventDefault()
11760
11761 var $target = getTargetFromTrigger($this)
11762 var data = $target.data('bs.collapse')
11763 var option = data ? 'toggle' : $this.data()
11764
11765 Plugin.call($target, option)
11766 })
11767
11768}(jQuery);
11769
11770/* ========================================================================
11771 * Bootstrap: dropdown.js v3.4.1
11772 * https://getbootstrap.com/docs/3.4/javascript/#dropdowns
11773 * ========================================================================
11774 * Copyright 2011-2019 Twitter, Inc.
11775 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11776 * ======================================================================== */
11777
11778
11779+function ($) {
11780 'use strict';
11781
11782 // DROPDOWN CLASS DEFINITION
11783 // =========================
11784
11785 var backdrop = '.dropdown-backdrop'
11786 var toggle = '[data-toggle="dropdown"]'
11787 var Dropdown = function (element) {
11788 $(element).on('click.bs.dropdown', this.toggle)
11789 }
11790
11791 Dropdown.VERSION = '3.4.1'
11792
11793 function getParent($this) {
11794 var selector = $this.attr('data-target')
11795
11796 if (!selector) {
11797 selector = $this.attr('href')
11798 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
11799 }
11800
11801 var $parent = selector !== '#' ? $(document).find(selector) : null
11802
11803 return $parent && $parent.length ? $parent : $this.parent()
11804 }
11805
11806 function clearMenus(e) {
11807 if (e && e.which === 3) return
11808 $(backdrop).remove()
11809 $(toggle).each(function () {
11810 var $this = $(this)
11811 var $parent = getParent($this)
11812 var relatedTarget = { relatedTarget: this }
11813
11814 if (!$parent.hasClass('open')) return
11815
11816 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
11817
11818 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
11819
11820 if (e.isDefaultPrevented()) return
11821
11822 $this.attr('aria-expanded', 'false')
11823 $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
11824 })
11825 }
11826
11827 Dropdown.prototype.toggle = function (e) {
11828 var $this = $(this)
11829
11830 if ($this.is('.disabled, :disabled')) return
11831
11832 var $parent = getParent($this)
11833 var isActive = $parent.hasClass('open')
11834
11835 clearMenus()
11836
11837 if (!isActive) {
11838 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
11839 // if mobile we use a backdrop because click events don't delegate
11840 $(document.createElement('div'))
11841 .addClass('dropdown-backdrop')
11842 .insertAfter($(this))
11843 .on('click', clearMenus)
11844 }
11845
11846 var relatedTarget = { relatedTarget: this }
11847 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
11848
11849 if (e.isDefaultPrevented()) return
11850
11851 $this
11852 .trigger('focus')
11853 .attr('aria-expanded', 'true')
11854
11855 $parent
11856 .toggleClass('open')
11857 .trigger($.Event('shown.bs.dropdown', relatedTarget))
11858 }
11859
11860 return false
11861 }
11862
11863 Dropdown.prototype.keydown = function (e) {
11864 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
11865
11866 var $this = $(this)
11867
11868 e.preventDefault()
11869 e.stopPropagation()
11870
11871 if ($this.is('.disabled, :disabled')) return
11872
11873 var $parent = getParent($this)
11874 var isActive = $parent.hasClass('open')
11875
11876 if (!isActive && e.which != 27 || isActive && e.which == 27) {
11877 if (e.which == 27) $parent.find(toggle).trigger('focus')
11878 return $this.trigger('click')
11879 }
11880
11881 var desc = ' li:not(.disabled):visible a'
11882 var $items = $parent.find('.dropdown-menu' + desc)
11883
11884 if (!$items.length) return
11885
11886 var index = $items.index(e.target)
11887
11888 if (e.which == 38 && index > 0) index-- // up
11889 if (e.which == 40 && index < $items.length - 1) index++ // down
11890 if (!~index) index = 0
11891
11892 $items.eq(index).trigger('focus')
11893 }
11894
11895
11896 // DROPDOWN PLUGIN DEFINITION
11897 // ==========================
11898
11899 function Plugin(option) {
11900 return this.each(function () {
11901 var $this = $(this)
11902 var data = $this.data('bs.dropdown')
11903
11904 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
11905 if (typeof option == 'string') data[option].call($this)
11906 })
11907 }
11908
11909 var old = $.fn.dropdown
11910
11911 $.fn.dropdown = Plugin
11912 $.fn.dropdown.Constructor = Dropdown
11913
11914
11915 // DROPDOWN NO CONFLICT
11916 // ====================
11917
11918 $.fn.dropdown.noConflict = function () {
11919 $.fn.dropdown = old
11920 return this
11921 }
11922
11923
11924 // APPLY TO STANDARD DROPDOWN ELEMENTS
11925 // ===================================
11926
11927 $(document)
11928 .on('click.bs.dropdown.data-api', clearMenus)
11929 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
11930 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
11931 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
11932 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
11933
11934}(jQuery);
11935
11936/* ========================================================================
11937 * Bootstrap: modal.js v3.4.1
11938 * https://getbootstrap.com/docs/3.4/javascript/#modals
11939 * ========================================================================
11940 * Copyright 2011-2019 Twitter, Inc.
11941 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11942 * ======================================================================== */
11943
11944
11945+function ($) {
11946 'use strict';
11947
11948 // MODAL CLASS DEFINITION
11949 // ======================
11950
11951 var Modal = function (element, options) {
11952 this.options = options
11953 this.$body = $(document.body)
11954 this.$element = $(element)
11955 this.$dialog = this.$element.find('.modal-dialog')
11956 this.$backdrop = null
11957 this.isShown = null
11958 this.originalBodyPad = null
11959 this.scrollbarWidth = 0
11960 this.ignoreBackdropClick = false
11961 this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom'
11962
11963 if (this.options.remote) {
11964 this.$element
11965 .find('.modal-content')
11966 .load(this.options.remote, $.proxy(function () {
11967 this.$element.trigger('loaded.bs.modal')
11968 }, this))
11969 }
11970 }
11971
11972 Modal.VERSION = '3.4.1'
11973
11974 Modal.TRANSITION_DURATION = 300
11975 Modal.BACKDROP_TRANSITION_DURATION = 150
11976
11977 Modal.DEFAULTS = {
11978 backdrop: true,
11979 keyboard: true,
11980 show: true
11981 }
11982
11983 Modal.prototype.toggle = function (_relatedTarget) {
11984 return this.isShown ? this.hide() : this.show(_relatedTarget)
11985 }
11986
11987 Modal.prototype.show = function (_relatedTarget) {
11988 var that = this
11989 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
11990
11991 this.$element.trigger(e)
11992
11993 if (this.isShown || e.isDefaultPrevented()) return
11994
11995 this.isShown = true
11996
11997 this.checkScrollbar()
11998 this.setScrollbar()
11999 this.$body.addClass('modal-open')
12000
12001 this.escape()
12002 this.resize()
12003
12004 this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
12005
12006 this.$dialog.on('mousedown.dismiss.bs.modal', function () {
12007 that.$element.one('mouseup.dismiss.bs.modal', function (e) {
12008 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
12009 })
12010 })
12011
12012 this.backdrop(function () {
12013 var transition = $.support.transition && that.$element.hasClass('fade')
12014
12015 if (!that.$element.parent().length) {
12016 that.$element.appendTo(that.$body) // don't move modals dom position
12017 }
12018
12019 that.$element
12020 .show()
12021 .scrollTop(0)
12022
12023 that.adjustDialog()
12024
12025 if (transition) {
12026 that.$element[0].offsetWidth // force reflow
12027 }
12028
12029 that.$element.addClass('in')
12030
12031 that.enforceFocus()
12032
12033 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
12034
12035 transition ?
12036 that.$dialog // wait for modal to slide in
12037 .one('bsTransitionEnd', function () {
12038 that.$element.trigger('focus').trigger(e)
12039 })
12040 .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
12041 that.$element.trigger('focus').trigger(e)
12042 })
12043 }
12044
12045 Modal.prototype.hide = function (e) {
12046 if (e) e.preventDefault()
12047
12048 e = $.Event('hide.bs.modal')
12049
12050 this.$element.trigger(e)
12051
12052 if (!this.isShown || e.isDefaultPrevented()) return
12053
12054 this.isShown = false
12055
12056 this.escape()
12057 this.resize()
12058
12059 $(document).off('focusin.bs.modal')
12060
12061 this.$element
12062 .removeClass('in')
12063 .off('click.dismiss.bs.modal')
12064 .off('mouseup.dismiss.bs.modal')
12065
12066 this.$dialog.off('mousedown.dismiss.bs.modal')
12067
12068 $.support.transition && this.$element.hasClass('fade') ?
12069 this.$element
12070 .one('bsTransitionEnd', $.proxy(this.hideModal, this))
12071 .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
12072 this.hideModal()
12073 }
12074
12075 Modal.prototype.enforceFocus = function () {
12076 $(document)
12077 .off('focusin.bs.modal') // guard against infinite focus loop
12078 .on('focusin.bs.modal', $.proxy(function (e) {
12079 if (document !== e.target &&
12080 this.$element[0] !== e.target &&
12081 !this.$element.has(e.target).length) {
12082 this.$element.trigger('focus')
12083 }
12084 }, this))
12085 }
12086
12087 Modal.prototype.escape = function () {
12088 if (this.isShown && this.options.keyboard) {
12089 this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
12090 e.which == 27 && this.hide()
12091 }, this))
12092 } else if (!this.isShown) {
12093 this.$element.off('keydown.dismiss.bs.modal')
12094 }
12095 }
12096
12097 Modal.prototype.resize = function () {
12098 if (this.isShown) {
12099 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
12100 } else {
12101 $(window).off('resize.bs.modal')
12102 }
12103 }
12104
12105 Modal.prototype.hideModal = function () {
12106 var that = this
12107 this.$element.hide()
12108 this.backdrop(function () {
12109 that.$body.removeClass('modal-open')
12110 that.resetAdjustments()
12111 that.resetScrollbar()
12112 that.$element.trigger('hidden.bs.modal')
12113 })
12114 }
12115
12116 Modal.prototype.removeBackdrop = function () {
12117 this.$backdrop && this.$backdrop.remove()
12118 this.$backdrop = null
12119 }
12120
12121 Modal.prototype.backdrop = function (callback) {
12122 var that = this
12123 var animate = this.$element.hasClass('fade') ? 'fade' : ''
12124
12125 if (this.isShown && this.options.backdrop) {
12126 var doAnimate = $.support.transition && animate
12127
12128 this.$backdrop = $(document.createElement('div'))
12129 .addClass('modal-backdrop ' + animate)
12130 .appendTo(this.$body)
12131
12132 this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
12133 if (this.ignoreBackdropClick) {
12134 this.ignoreBackdropClick = false
12135 return
12136 }
12137 if (e.target !== e.currentTarget) return
12138 this.options.backdrop == 'static'
12139 ? this.$element[0].focus()
12140 : this.hide()
12141 }, this))
12142
12143 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
12144
12145 this.$backdrop.addClass('in')
12146
12147 if (!callback) return
12148
12149 doAnimate ?
12150 this.$backdrop
12151 .one('bsTransitionEnd', callback)
12152 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
12153 callback()
12154
12155 } else if (!this.isShown && this.$backdrop) {
12156 this.$backdrop.removeClass('in')
12157
12158 var callbackRemove = function () {
12159 that.removeBackdrop()
12160 callback && callback()
12161 }
12162 $.support.transition && this.$element.hasClass('fade') ?
12163 this.$backdrop
12164 .one('bsTransitionEnd', callbackRemove)
12165 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
12166 callbackRemove()
12167
12168 } else if (callback) {
12169 callback()
12170 }
12171 }
12172
12173 // these following methods are used to handle overflowing modals
12174
12175 Modal.prototype.handleUpdate = function () {
12176 this.adjustDialog()
12177 }
12178
12179 Modal.prototype.adjustDialog = function () {
12180 var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
12181
12182 this.$element.css({
12183 paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
12184 paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
12185 })
12186 }
12187
12188 Modal.prototype.resetAdjustments = function () {
12189 this.$element.css({
12190 paddingLeft: '',
12191 paddingRight: ''
12192 })
12193 }
12194
12195 Modal.prototype.checkScrollbar = function () {
12196 var fullWindowWidth = window.innerWidth
12197 if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
12198 var documentElementRect = document.documentElement.getBoundingClientRect()
12199 fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
12200 }
12201 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
12202 this.scrollbarWidth = this.measureScrollbar()
12203 }
12204
12205 Modal.prototype.setScrollbar = function () {
12206 var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
12207 this.originalBodyPad = document.body.style.paddingRight || ''
12208 var scrollbarWidth = this.scrollbarWidth
12209 if (this.bodyIsOverflowing) {
12210 this.$body.css('padding-right', bodyPad + scrollbarWidth)
12211 $(this.fixedContent).each(function (index, element) {
12212 var actualPadding = element.style.paddingRight
12213 var calculatedPadding = $(element).css('padding-right')
12214 $(element)
12215 .data('padding-right', actualPadding)
12216 .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px')
12217 })
12218 }
12219 }
12220
12221 Modal.prototype.resetScrollbar = function () {
12222 this.$body.css('padding-right', this.originalBodyPad)
12223 $(this.fixedContent).each(function (index, element) {
12224 var padding = $(element).data('padding-right')
12225 $(element).removeData('padding-right')
12226 element.style.paddingRight = padding ? padding : ''
12227 })
12228 }
12229
12230 Modal.prototype.measureScrollbar = function () { // thx walsh
12231 var scrollDiv = document.createElement('div')
12232 scrollDiv.className = 'modal-scrollbar-measure'
12233 this.$body.append(scrollDiv)
12234 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
12235 this.$body[0].removeChild(scrollDiv)
12236 return scrollbarWidth
12237 }
12238
12239
12240 // MODAL PLUGIN DEFINITION
12241 // =======================
12242
12243 function Plugin(option, _relatedTarget) {
12244 return this.each(function () {
12245 var $this = $(this)
12246 var data = $this.data('bs.modal')
12247 var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
12248
12249 if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
12250 if (typeof option == 'string') data[option](_relatedTarget)
12251 else if (options.show) data.show(_relatedTarget)
12252 })
12253 }
12254
12255 var old = $.fn.modal
12256
12257 $.fn.modal = Plugin
12258 $.fn.modal.Constructor = Modal
12259
12260
12261 // MODAL NO CONFLICT
12262 // =================
12263
12264 $.fn.modal.noConflict = function () {
12265 $.fn.modal = old
12266 return this
12267 }
12268
12269
12270 // MODAL DATA-API
12271 // ==============
12272
12273 $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
12274 var $this = $(this)
12275 var href = $this.attr('href')
12276 var target = $this.attr('data-target') ||
12277 (href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
12278
12279 var $target = $(document).find(target)
12280 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
12281
12282 if ($this.is('a')) e.preventDefault()
12283
12284 $target.one('show.bs.modal', function (showEvent) {
12285 if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
12286 $target.one('hidden.bs.modal', function () {
12287 $this.is(':visible') && $this.trigger('focus')
12288 })
12289 })
12290 Plugin.call($target, option, this)
12291 })
12292
12293}(jQuery);
12294
12295/* ========================================================================
12296 * Bootstrap: tooltip.js v3.4.1
12297 * https://getbootstrap.com/docs/3.4/javascript/#tooltip
12298 * Inspired by the original jQuery.tipsy by Jason Frame
12299 * ========================================================================
12300 * Copyright 2011-2019 Twitter, Inc.
12301 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12302 * ======================================================================== */
12303
12304+function ($) {
12305 'use strict';
12306
12307 var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
12308
12309 var uriAttrs = [
12310 'background',
12311 'cite',
12312 'href',
12313 'itemtype',
12314 'longdesc',
12315 'poster',
12316 'src',
12317 'xlink:href'
12318 ]
12319
12320 var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
12321
12322 var DefaultWhitelist = {
12323 // Global attributes allowed on any supplied element below.
12324 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
12325 a: ['target', 'href', 'title', 'rel'],
12326 area: [],
12327 b: [],
12328 br: [],
12329 col: [],
12330 code: [],
12331 div: [],
12332 em: [],
12333 hr: [],
12334 h1: [],
12335 h2: [],
12336 h3: [],
12337 h4: [],
12338 h5: [],
12339 h6: [],
12340 i: [],
12341 img: ['src', 'alt', 'title', 'width', 'height'],
12342 li: [],
12343 ol: [],
12344 p: [],
12345 pre: [],
12346 s: [],
12347 small: [],
12348 span: [],
12349 sub: [],
12350 sup: [],
12351 strong: [],
12352 u: [],
12353 ul: []
12354 }
12355
12356 /**
12357 * A pattern that recognizes a commonly useful subset of URLs that are safe.
12358 *
12359 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
12360 */
12361 var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi
12362
12363 /**
12364 * A pattern that matches safe data URLs. Only matches image, video and audio types.
12365 *
12366 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
12367 */
12368 var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i
12369
12370 function allowedAttribute(attr, allowedAttributeList) {
12371 var attrName = attr.nodeName.toLowerCase()
12372
12373 if ($.inArray(attrName, allowedAttributeList) !== -1) {
12374 if ($.inArray(attrName, uriAttrs) !== -1) {
12375 return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
12376 }
12377
12378 return true
12379 }
12380
12381 var regExp = $(allowedAttributeList).filter(function (index, value) {
12382 return value instanceof RegExp
12383 })
12384
12385 // Check if a regular expression validates the attribute.
12386 for (var i = 0, l = regExp.length; i < l; i++) {
12387 if (attrName.match(regExp[i])) {
12388 return true
12389 }
12390 }
12391
12392 return false
12393 }
12394
12395 function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
12396 if (unsafeHtml.length === 0) {
12397 return unsafeHtml
12398 }
12399
12400 if (sanitizeFn && typeof sanitizeFn === 'function') {
12401 return sanitizeFn(unsafeHtml)
12402 }
12403
12404 // IE 8 and below don't support createHTMLDocument
12405 if (!document.implementation || !document.implementation.createHTMLDocument) {
12406 return unsafeHtml
12407 }
12408
12409 var createdDocument = document.implementation.createHTMLDocument('sanitization')
12410 createdDocument.body.innerHTML = unsafeHtml
12411
12412 var whitelistKeys = $.map(whiteList, function (el, i) { return i })
12413 var elements = $(createdDocument.body).find('*')
12414
12415 for (var i = 0, len = elements.length; i < len; i++) {
12416 var el = elements[i]
12417 var elName = el.nodeName.toLowerCase()
12418
12419 if ($.inArray(elName, whitelistKeys) === -1) {
12420 el.parentNode.removeChild(el)
12421
12422 continue
12423 }
12424
12425 var attributeList = $.map(el.attributes, function (el) { return el })
12426 var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])
12427
12428 for (var j = 0, len2 = attributeList.length; j < len2; j++) {
12429 if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {
12430 el.removeAttribute(attributeList[j].nodeName)
12431 }
12432 }
12433 }
12434
12435 return createdDocument.body.innerHTML
12436 }
12437
12438 // TOOLTIP PUBLIC CLASS DEFINITION
12439 // ===============================
12440
12441 var Tooltip = function (element, options) {
12442 this.type = null
12443 this.options = null
12444 this.enabled = null
12445 this.timeout = null
12446 this.hoverState = null
12447 this.$element = null
12448 this.inState = null
12449
12450 this.init('tooltip', element, options)
12451 }
12452
12453 Tooltip.VERSION = '3.4.1'
12454
12455 Tooltip.TRANSITION_DURATION = 150
12456
12457 Tooltip.DEFAULTS = {
12458 animation: true,
12459 placement: 'top',
12460 selector: false,
12461 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
12462 trigger: 'hover focus',
12463 title: '',
12464 delay: 0,
12465 html: false,
12466 container: false,
12467 viewport: {
12468 selector: 'body',
12469 padding: 0
12470 },
12471 sanitize : true,
12472 sanitizeFn : null,
12473 whiteList : DefaultWhitelist
12474 }
12475
12476 Tooltip.prototype.init = function (type, element, options) {
12477 this.enabled = true
12478 this.type = type
12479 this.$element = $(element)
12480 this.options = this.getOptions(options)
12481 this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
12482 this.inState = { click: false, hover: false, focus: false }
12483
12484 if (this.$element[0] instanceof document.constructor && !this.options.selector) {
12485 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
12486 }
12487
12488 var triggers = this.options.trigger.split(' ')
12489
12490 for (var i = triggers.length; i--;) {
12491 var trigger = triggers[i]
12492
12493 if (trigger == 'click') {
12494 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
12495 } else if (trigger != 'manual') {
12496 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
12497 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
12498
12499 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
12500 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
12501 }
12502 }
12503
12504 this.options.selector ?
12505 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
12506 this.fixTitle()
12507 }
12508
12509 Tooltip.prototype.getDefaults = function () {
12510 return Tooltip.DEFAULTS
12511 }
12512
12513 Tooltip.prototype.getOptions = function (options) {
12514 var dataAttributes = this.$element.data()
12515
12516 for (var dataAttr in dataAttributes) {
12517 if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
12518 delete dataAttributes[dataAttr]
12519 }
12520 }
12521
12522 options = $.extend({}, this.getDefaults(), dataAttributes, options)
12523
12524 if (options.delay && typeof options.delay == 'number') {
12525 options.delay = {
12526 show: options.delay,
12527 hide: options.delay
12528 }
12529 }
12530
12531 if (options.sanitize) {
12532 options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)
12533 }
12534
12535 return options
12536 }
12537
12538 Tooltip.prototype.getDelegateOptions = function () {
12539 var options = {}
12540 var defaults = this.getDefaults()
12541
12542 this._options && $.each(this._options, function (key, value) {
12543 if (defaults[key] != value) options[key] = value
12544 })
12545
12546 return options
12547 }
12548
12549 Tooltip.prototype.enter = function (obj) {
12550 var self = obj instanceof this.constructor ?
12551 obj : $(obj.currentTarget).data('bs.' + this.type)
12552
12553 if (!self) {
12554 self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
12555 $(obj.currentTarget).data('bs.' + this.type, self)
12556 }
12557
12558 if (obj instanceof $.Event) {
12559 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
12560 }
12561
12562 if (self.tip().hasClass('in') || self.hoverState == 'in') {
12563 self.hoverState = 'in'
12564 return
12565 }
12566
12567 clearTimeout(self.timeout)
12568
12569 self.hoverState = 'in'
12570
12571 if (!self.options.delay || !self.options.delay.show) return self.show()
12572
12573 self.timeout = setTimeout(function () {
12574 if (self.hoverState == 'in') self.show()
12575 }, self.options.delay.show)
12576 }
12577
12578 Tooltip.prototype.isInStateTrue = function () {
12579 for (var key in this.inState) {
12580 if (this.inState[key]) return true
12581 }
12582
12583 return false
12584 }
12585
12586 Tooltip.prototype.leave = function (obj) {
12587 var self = obj instanceof this.constructor ?
12588 obj : $(obj.currentTarget).data('bs.' + this.type)
12589
12590 if (!self) {
12591 self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
12592 $(obj.currentTarget).data('bs.' + this.type, self)
12593 }
12594
12595 if (obj instanceof $.Event) {
12596 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
12597 }
12598
12599 if (self.isInStateTrue()) return
12600
12601 clearTimeout(self.timeout)
12602
12603 self.hoverState = 'out'
12604
12605 if (!self.options.delay || !self.options.delay.hide) return self.hide()
12606
12607 self.timeout = setTimeout(function () {
12608 if (self.hoverState == 'out') self.hide()
12609 }, self.options.delay.hide)
12610 }
12611
12612 Tooltip.prototype.show = function () {
12613 var e = $.Event('show.bs.' + this.type)
12614
12615 if (this.hasContent() && this.enabled) {
12616 this.$element.trigger(e)
12617
12618 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
12619 if (e.isDefaultPrevented() || !inDom) return
12620 var that = this
12621
12622 var $tip = this.tip()
12623
12624 var tipId = this.getUID(this.type)
12625
12626 this.setContent()
12627 $tip.attr('id', tipId)
12628 this.$element.attr('aria-describedby', tipId)
12629
12630 if (this.options.animation) $tip.addClass('fade')
12631
12632 var placement = typeof this.options.placement == 'function' ?
12633 this.options.placement.call(this, $tip[0], this.$element[0]) :
12634 this.options.placement
12635
12636 var autoToken = /\s?auto?\s?/i
12637 var autoPlace = autoToken.test(placement)
12638 if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
12639
12640 $tip
12641 .detach()
12642 .css({ top: 0, left: 0, display: 'block' })
12643 .addClass(placement)
12644 .data('bs.' + this.type, this)
12645
12646 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
12647 this.$element.trigger('inserted.bs.' + this.type)
12648
12649 var pos = this.getPosition()
12650 var actualWidth = $tip[0].offsetWidth
12651 var actualHeight = $tip[0].offsetHeight
12652
12653 if (autoPlace) {
12654 var orgPlacement = placement
12655 var viewportDim = this.getPosition(this.$viewport)
12656
12657 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
12658 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
12659 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
12660 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
12661 placement
12662
12663 $tip
12664 .removeClass(orgPlacement)
12665 .addClass(placement)
12666 }
12667
12668 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
12669
12670 this.applyPlacement(calculatedOffset, placement)
12671
12672 var complete = function () {
12673 var prevHoverState = that.hoverState
12674 that.$element.trigger('shown.bs.' + that.type)
12675 that.hoverState = null
12676
12677 if (prevHoverState == 'out') that.leave(that)
12678 }
12679
12680 $.support.transition && this.$tip.hasClass('fade') ?
12681 $tip
12682 .one('bsTransitionEnd', complete)
12683 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
12684 complete()
12685 }
12686 }
12687
12688 Tooltip.prototype.applyPlacement = function (offset, placement) {
12689 var $tip = this.tip()
12690 var width = $tip[0].offsetWidth
12691 var height = $tip[0].offsetHeight
12692
12693 // manually read margins because getBoundingClientRect includes difference
12694 var marginTop = parseInt($tip.css('margin-top'), 10)
12695 var marginLeft = parseInt($tip.css('margin-left'), 10)
12696
12697 // we must check for NaN for ie 8/9
12698 if (isNaN(marginTop)) marginTop = 0
12699 if (isNaN(marginLeft)) marginLeft = 0
12700
12701 offset.top += marginTop
12702 offset.left += marginLeft
12703
12704 // $.fn.offset doesn't round pixel values
12705 // so we use setOffset directly with our own function B-0
12706 $.offset.setOffset($tip[0], $.extend({
12707 using: function (props) {
12708 $tip.css({
12709 top: Math.round(props.top),
12710 left: Math.round(props.left)
12711 })
12712 }
12713 }, offset), 0)
12714
12715 $tip.addClass('in')
12716
12717 // check to see if placing tip in new offset caused the tip to resize itself
12718 var actualWidth = $tip[0].offsetWidth
12719 var actualHeight = $tip[0].offsetHeight
12720
12721 if (placement == 'top' && actualHeight != height) {
12722 offset.top = offset.top + height - actualHeight
12723 }
12724
12725 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
12726
12727 if (delta.left) offset.left += delta.left
12728 else offset.top += delta.top
12729
12730 var isVertical = /top|bottom/.test(placement)
12731 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
12732 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
12733
12734 $tip.offset(offset)
12735 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
12736 }
12737
12738 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
12739 this.arrow()
12740 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
12741 .css(isVertical ? 'top' : 'left', '')
12742 }
12743
12744 Tooltip.prototype.setContent = function () {
12745 var $tip = this.tip()
12746 var title = this.getTitle()
12747
12748 if (this.options.html) {
12749 if (this.options.sanitize) {
12750 title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)
12751 }
12752
12753 $tip.find('.tooltip-inner').html(title)
12754 } else {
12755 $tip.find('.tooltip-inner').text(title)
12756 }
12757
12758 $tip.removeClass('fade in top bottom left right')
12759 }
12760
12761 Tooltip.prototype.hide = function (callback) {
12762 var that = this
12763 var $tip = $(this.$tip)
12764 var e = $.Event('hide.bs.' + this.type)
12765
12766 function complete() {
12767 if (that.hoverState != 'in') $tip.detach()
12768 if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
12769 that.$element
12770 .removeAttr('aria-describedby')
12771 .trigger('hidden.bs.' + that.type)
12772 }
12773 callback && callback()
12774 }
12775
12776 this.$element.trigger(e)
12777
12778 if (e.isDefaultPrevented()) return
12779
12780 $tip.removeClass('in')
12781
12782 $.support.transition && $tip.hasClass('fade') ?
12783 $tip
12784 .one('bsTransitionEnd', complete)
12785 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
12786 complete()
12787
12788 this.hoverState = null
12789
12790 return this
12791 }
12792
12793 Tooltip.prototype.fixTitle = function () {
12794 var $e = this.$element
12795 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
12796 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
12797 }
12798 }
12799
12800 Tooltip.prototype.hasContent = function () {
12801 return this.getTitle()
12802 }
12803
12804 Tooltip.prototype.getPosition = function ($element) {
12805 $element = $element || this.$element
12806
12807 var el = $element[0]
12808 var isBody = el.tagName == 'BODY'
12809
12810 var elRect = el.getBoundingClientRect()
12811 if (elRect.width == null) {
12812 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
12813 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
12814 }
12815 var isSvg = window.SVGElement && el instanceof window.SVGElement
12816 // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
12817 // See https://github.com/twbs/bootstrap/issues/20280
12818 var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
12819 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
12820 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
12821
12822 return $.extend({}, elRect, scroll, outerDims, elOffset)
12823 }
12824
12825 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
12826 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
12827 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
12828 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
12829 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
12830
12831 }
12832
12833 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
12834 var delta = { top: 0, left: 0 }
12835 if (!this.$viewport) return delta
12836
12837 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
12838 var viewportDimensions = this.getPosition(this.$viewport)
12839
12840 if (/right|left/.test(placement)) {
12841 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
12842 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
12843 if (topEdgeOffset < viewportDimensions.top) { // top overflow
12844 delta.top = viewportDimensions.top - topEdgeOffset
12845 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
12846 delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
12847 }
12848 } else {
12849 var leftEdgeOffset = pos.left - viewportPadding
12850 var rightEdgeOffset = pos.left + viewportPadding + actualWidth
12851 if (leftEdgeOffset < viewportDimensions.left) { // left overflow
12852 delta.left = viewportDimensions.left - leftEdgeOffset
12853 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
12854 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
12855 }
12856 }
12857
12858 return delta
12859 }
12860
12861 Tooltip.prototype.getTitle = function () {
12862 var title
12863 var $e = this.$element
12864 var o = this.options
12865
12866 title = $e.attr('data-original-title')
12867 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
12868
12869 return title
12870 }
12871
12872 Tooltip.prototype.getUID = function (prefix) {
12873 do prefix += ~~(Math.random() * 1000000)
12874 while (document.getElementById(prefix))
12875 return prefix
12876 }
12877
12878 Tooltip.prototype.tip = function () {
12879 if (!this.$tip) {
12880 this.$tip = $(this.options.template)
12881 if (this.$tip.length != 1) {
12882 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
12883 }
12884 }
12885 return this.$tip
12886 }
12887
12888 Tooltip.prototype.arrow = function () {
12889 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
12890 }
12891
12892 Tooltip.prototype.enable = function () {
12893 this.enabled = true
12894 }
12895
12896 Tooltip.prototype.disable = function () {
12897 this.enabled = false
12898 }
12899
12900 Tooltip.prototype.toggleEnabled = function () {
12901 this.enabled = !this.enabled
12902 }
12903
12904 Tooltip.prototype.toggle = function (e) {
12905 var self = this
12906 if (e) {
12907 self = $(e.currentTarget).data('bs.' + this.type)
12908 if (!self) {
12909 self = new this.constructor(e.currentTarget, this.getDelegateOptions())
12910 $(e.currentTarget).data('bs.' + this.type, self)
12911 }
12912 }
12913
12914 if (e) {
12915 self.inState.click = !self.inState.click
12916 if (self.isInStateTrue()) self.enter(self)
12917 else self.leave(self)
12918 } else {
12919 self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
12920 }
12921 }
12922
12923 Tooltip.prototype.destroy = function () {
12924 var that = this
12925 clearTimeout(this.timeout)
12926 this.hide(function () {
12927 that.$element.off('.' + that.type).removeData('bs.' + that.type)
12928 if (that.$tip) {
12929 that.$tip.detach()
12930 }
12931 that.$tip = null
12932 that.$arrow = null
12933 that.$viewport = null
12934 that.$element = null
12935 })
12936 }
12937
12938 Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {
12939 return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)
12940 }
12941
12942 // TOOLTIP PLUGIN DEFINITION
12943 // =========================
12944
12945 function Plugin(option) {
12946 return this.each(function () {
12947 var $this = $(this)
12948 var data = $this.data('bs.tooltip')
12949 var options = typeof option == 'object' && option
12950
12951 if (!data && /destroy|hide/.test(option)) return
12952 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
12953 if (typeof option == 'string') data[option]()
12954 })
12955 }
12956
12957 var old = $.fn.tooltip
12958
12959 $.fn.tooltip = Plugin
12960 $.fn.tooltip.Constructor = Tooltip
12961
12962
12963 // TOOLTIP NO CONFLICT
12964 // ===================
12965
12966 $.fn.tooltip.noConflict = function () {
12967 $.fn.tooltip = old
12968 return this
12969 }
12970
12971}(jQuery);
12972
12973/* ========================================================================
12974 * Bootstrap: popover.js v3.4.1
12975 * https://getbootstrap.com/docs/3.4/javascript/#popovers
12976 * ========================================================================
12977 * Copyright 2011-2019 Twitter, Inc.
12978 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12979 * ======================================================================== */
12980
12981
12982+function ($) {
12983 'use strict';
12984
12985 // POPOVER PUBLIC CLASS DEFINITION
12986 // ===============================
12987
12988 var Popover = function (element, options) {
12989 this.init('popover', element, options)
12990 }
12991
12992 if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
12993
12994 Popover.VERSION = '3.4.1'
12995
12996 Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
12997 placement: 'right',
12998 trigger: 'click',
12999 content: '',
13000 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
13001 })
13002
13003
13004 // NOTE: POPOVER EXTENDS tooltip.js
13005 // ================================
13006
13007 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
13008
13009 Popover.prototype.constructor = Popover
13010
13011 Popover.prototype.getDefaults = function () {
13012 return Popover.DEFAULTS
13013 }
13014
13015 Popover.prototype.setContent = function () {
13016 var $tip = this.tip()
13017 var title = this.getTitle()
13018 var content = this.getContent()
13019
13020 if (this.options.html) {
13021 var typeContent = typeof content
13022
13023 if (this.options.sanitize) {
13024 title = this.sanitizeHtml(title)
13025
13026 if (typeContent === 'string') {
13027 content = this.sanitizeHtml(content)
13028 }
13029 }
13030
13031 $tip.find('.popover-title').html(title)
13032 $tip.find('.popover-content').children().detach().end()[
13033 typeContent === 'string' ? 'html' : 'append'
13034 ](content)
13035 } else {
13036 $tip.find('.popover-title').text(title)
13037 $tip.find('.popover-content').children().detach().end().text(content)
13038 }
13039
13040 $tip.removeClass('fade top bottom left right in')
13041
13042 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
13043 // this manually by checking the contents.
13044 if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
13045 }
13046
13047 Popover.prototype.hasContent = function () {
13048 return this.getTitle() || this.getContent()
13049 }
13050
13051 Popover.prototype.getContent = function () {
13052 var $e = this.$element
13053 var o = this.options
13054
13055 return $e.attr('data-content')
13056 || (typeof o.content == 'function' ?
13057 o.content.call($e[0]) :
13058 o.content)
13059 }
13060
13061 Popover.prototype.arrow = function () {
13062 return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
13063 }
13064
13065
13066 // POPOVER PLUGIN DEFINITION
13067 // =========================
13068
13069 function Plugin(option) {
13070 return this.each(function () {
13071 var $this = $(this)
13072 var data = $this.data('bs.popover')
13073 var options = typeof option == 'object' && option
13074
13075 if (!data && /destroy|hide/.test(option)) return
13076 if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
13077 if (typeof option == 'string') data[option]()
13078 })
13079 }
13080
13081 var old = $.fn.popover
13082
13083 $.fn.popover = Plugin
13084 $.fn.popover.Constructor = Popover
13085
13086
13087 // POPOVER NO CONFLICT
13088 // ===================
13089
13090 $.fn.popover.noConflict = function () {
13091 $.fn.popover = old
13092 return this
13093 }
13094
13095}(jQuery);
13096
13097/* ========================================================================
13098 * Bootstrap: scrollspy.js v3.4.1
13099 * https://getbootstrap.com/docs/3.4/javascript/#scrollspy
13100 * ========================================================================
13101 * Copyright 2011-2019 Twitter, Inc.
13102 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13103 * ======================================================================== */
13104
13105
13106+function ($) {
13107 'use strict';
13108
13109 // SCROLLSPY CLASS DEFINITION
13110 // ==========================
13111
13112 function ScrollSpy(element, options) {
13113 this.$body = $(document.body)
13114 this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
13115 this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
13116 this.selector = (this.options.target || '') + ' .nav li > a'
13117 this.offsets = []
13118 this.targets = []
13119 this.activeTarget = null
13120 this.scrollHeight = 0
13121
13122 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
13123 this.refresh()
13124 this.process()
13125 }
13126
13127 ScrollSpy.VERSION = '3.4.1'
13128
13129 ScrollSpy.DEFAULTS = {
13130 offset: 10
13131 }
13132
13133 ScrollSpy.prototype.getScrollHeight = function () {
13134 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
13135 }
13136
13137 ScrollSpy.prototype.refresh = function () {
13138 var that = this
13139 var offsetMethod = 'offset'
13140 var offsetBase = 0
13141
13142 this.offsets = []
13143 this.targets = []
13144 this.scrollHeight = this.getScrollHeight()
13145
13146 if (!$.isWindow(this.$scrollElement[0])) {
13147 offsetMethod = 'position'
13148 offsetBase = this.$scrollElement.scrollTop()
13149 }
13150
13151 this.$body
13152 .find(this.selector)
13153 .map(function () {
13154 var $el = $(this)
13155 var href = $el.data('target') || $el.attr('href')
13156 var $href = /^#./.test(href) && $(href)
13157
13158 return ($href
13159 && $href.length
13160 && $href.is(':visible')
13161 && [[$href[offsetMethod]().top + offsetBase, href]]) || null
13162 })
13163 .sort(function (a, b) { return a[0] - b[0] })
13164 .each(function () {
13165 that.offsets.push(this[0])
13166 that.targets.push(this[1])
13167 })
13168 }
13169
13170 ScrollSpy.prototype.process = function () {
13171 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
13172 var scrollHeight = this.getScrollHeight()
13173 var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
13174 var offsets = this.offsets
13175 var targets = this.targets
13176 var activeTarget = this.activeTarget
13177 var i
13178
13179 if (this.scrollHeight != scrollHeight) {
13180 this.refresh()
13181 }
13182
13183 if (scrollTop >= maxScroll) {
13184 return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
13185 }
13186
13187 if (activeTarget && scrollTop < offsets[0]) {
13188 this.activeTarget = null
13189 return this.clear()
13190 }
13191
13192 for (i = offsets.length; i--;) {
13193 activeTarget != targets[i]
13194 && scrollTop >= offsets[i]
13195 && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
13196 && this.activate(targets[i])
13197 }
13198 }
13199
13200 ScrollSpy.prototype.activate = function (target) {
13201 this.activeTarget = target
13202
13203 this.clear()
13204
13205 var selector = this.selector +
13206 '[data-target="' + target + '"],' +
13207 this.selector + '[href="' + target + '"]'
13208
13209 var active = $(selector)
13210 .parents('li')
13211 .addClass('active')
13212
13213 if (active.parent('.dropdown-menu').length) {
13214 active = active
13215 .closest('li.dropdown')
13216 .addClass('active')
13217 }
13218
13219 active.trigger('activate.bs.scrollspy')
13220 }
13221
13222 ScrollSpy.prototype.clear = function () {
13223 $(this.selector)
13224 .parentsUntil(this.options.target, '.active')
13225 .removeClass('active')
13226 }
13227
13228
13229 // SCROLLSPY PLUGIN DEFINITION
13230 // ===========================
13231
13232 function Plugin(option) {
13233 return this.each(function () {
13234 var $this = $(this)
13235 var data = $this.data('bs.scrollspy')
13236 var options = typeof option == 'object' && option
13237
13238 if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
13239 if (typeof option == 'string') data[option]()
13240 })
13241 }
13242
13243 var old = $.fn.scrollspy
13244
13245 $.fn.scrollspy = Plugin
13246 $.fn.scrollspy.Constructor = ScrollSpy
13247
13248
13249 // SCROLLSPY NO CONFLICT
13250 // =====================
13251
13252 $.fn.scrollspy.noConflict = function () {
13253 $.fn.scrollspy = old
13254 return this
13255 }
13256
13257
13258 // SCROLLSPY DATA-API
13259 // ==================
13260
13261 $(window).on('load.bs.scrollspy.data-api', function () {
13262 $('[data-spy="scroll"]').each(function () {
13263 var $spy = $(this)
13264 Plugin.call($spy, $spy.data())
13265 })
13266 })
13267
13268}(jQuery);
13269
13270/* ========================================================================
13271 * Bootstrap: tab.js v3.4.1
13272 * https://getbootstrap.com/docs/3.4/javascript/#tabs
13273 * ========================================================================
13274 * Copyright 2011-2019 Twitter, Inc.
13275 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13276 * ======================================================================== */
13277
13278
13279+function ($) {
13280 'use strict';
13281
13282 // TAB CLASS DEFINITION
13283 // ====================
13284
13285 var Tab = function (element) {
13286 // jscs:disable requireDollarBeforejQueryAssignment
13287 this.element = $(element)
13288 // jscs:enable requireDollarBeforejQueryAssignment
13289 }
13290
13291 Tab.VERSION = '3.4.1'
13292
13293 Tab.TRANSITION_DURATION = 150
13294
13295 Tab.prototype.show = function () {
13296 var $this = this.element
13297 var $ul = $this.closest('ul:not(.dropdown-menu)')
13298 var selector = $this.data('target')
13299
13300 if (!selector) {
13301 selector = $this.attr('href')
13302 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
13303 }
13304
13305 if ($this.parent('li').hasClass('active')) return
13306
13307 var $previous = $ul.find('.active:last a')
13308 var hideEvent = $.Event('hide.bs.tab', {
13309 relatedTarget: $this[0]
13310 })
13311 var showEvent = $.Event('show.bs.tab', {
13312 relatedTarget: $previous[0]
13313 })
13314
13315 $previous.trigger(hideEvent)
13316 $this.trigger(showEvent)
13317
13318 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
13319
13320 var $target = $(document).find(selector)
13321
13322 this.activate($this.closest('li'), $ul)
13323 this.activate($target, $target.parent(), function () {
13324 $previous.trigger({
13325 type: 'hidden.bs.tab',
13326 relatedTarget: $this[0]
13327 })
13328 $this.trigger({
13329 type: 'shown.bs.tab',
13330 relatedTarget: $previous[0]
13331 })
13332 })
13333 }
13334
13335 Tab.prototype.activate = function (element, container, callback) {
13336 var $active = container.find('> .active')
13337 var transition = callback
13338 && $.support.transition
13339 && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
13340
13341 function next() {
13342 $active
13343 .removeClass('active')
13344 .find('> .dropdown-menu > .active')
13345 .removeClass('active')
13346 .end()
13347 .find('[data-toggle="tab"]')
13348 .attr('aria-expanded', false)
13349
13350 element
13351 .addClass('active')
13352 .find('[data-toggle="tab"]')
13353 .attr('aria-expanded', true)
13354
13355 if (transition) {
13356 element[0].offsetWidth // reflow for transition
13357 element.addClass('in')
13358 } else {
13359 element.removeClass('fade')
13360 }
13361
13362 if (element.parent('.dropdown-menu').length) {
13363 element
13364 .closest('li.dropdown')
13365 .addClass('active')
13366 .end()
13367 .find('[data-toggle="tab"]')
13368 .attr('aria-expanded', true)
13369 }
13370
13371 callback && callback()
13372 }
13373
13374 $active.length && transition ?
13375 $active
13376 .one('bsTransitionEnd', next)
13377 .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
13378 next()
13379
13380 $active.removeClass('in')
13381 }
13382
13383
13384 // TAB PLUGIN DEFINITION
13385 // =====================
13386
13387 function Plugin(option) {
13388 return this.each(function () {
13389 var $this = $(this)
13390 var data = $this.data('bs.tab')
13391
13392 if (!data) $this.data('bs.tab', (data = new Tab(this)))
13393 if (typeof option == 'string') data[option]()
13394 })
13395 }
13396
13397 var old = $.fn.tab
13398
13399 $.fn.tab = Plugin
13400 $.fn.tab.Constructor = Tab
13401
13402
13403 // TAB NO CONFLICT
13404 // ===============
13405
13406 $.fn.tab.noConflict = function () {
13407 $.fn.tab = old
13408 return this
13409 }
13410
13411
13412 // TAB DATA-API
13413 // ============
13414
13415 var clickHandler = function (e) {
13416 e.preventDefault()
13417 Plugin.call($(this), 'show')
13418 }
13419
13420 $(document)
13421 .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
13422 .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
13423
13424}(jQuery);
13425
13426/* ========================================================================
13427 * Bootstrap: affix.js v3.4.1
13428 * https://getbootstrap.com/docs/3.4/javascript/#affix
13429 * ========================================================================
13430 * Copyright 2011-2019 Twitter, Inc.
13431 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13432 * ======================================================================== */
13433
13434
13435+function ($) {
13436 'use strict';
13437
13438 // AFFIX CLASS DEFINITION
13439 // ======================
13440
13441 var Affix = function (element, options) {
13442 this.options = $.extend({}, Affix.DEFAULTS, options)
13443
13444 var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)
13445
13446 this.$target = target
13447 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
13448 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
13449
13450 this.$element = $(element)
13451 this.affixed = null
13452 this.unpin = null
13453 this.pinnedOffset = null
13454
13455 this.checkPosition()
13456 }
13457
13458 Affix.VERSION = '3.4.1'
13459
13460 Affix.RESET = 'affix affix-top affix-bottom'
13461
13462 Affix.DEFAULTS = {
13463 offset: 0,
13464 target: window
13465 }
13466
13467 Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
13468 var scrollTop = this.$target.scrollTop()
13469 var position = this.$element.offset()
13470 var targetHeight = this.$target.height()
13471
13472 if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
13473
13474 if (this.affixed == 'bottom') {
13475 if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
13476 return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
13477 }
13478
13479 var initializing = this.affixed == null
13480 var colliderTop = initializing ? scrollTop : position.top
13481 var colliderHeight = initializing ? targetHeight : height
13482
13483 if (offsetTop != null && scrollTop <= offsetTop) return 'top'
13484 if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
13485
13486 return false
13487 }
13488
13489 Affix.prototype.getPinnedOffset = function () {
13490 if (this.pinnedOffset) return this.pinnedOffset
13491 this.$element.removeClass(Affix.RESET).addClass('affix')
13492 var scrollTop = this.$target.scrollTop()
13493 var position = this.$element.offset()
13494 return (this.pinnedOffset = position.top - scrollTop)
13495 }
13496
13497 Affix.prototype.checkPositionWithEventLoop = function () {
13498 setTimeout($.proxy(this.checkPosition, this), 1)
13499 }
13500
13501 Affix.prototype.checkPosition = function () {
13502 if (!this.$element.is(':visible')) return
13503
13504 var height = this.$element.height()
13505 var offset = this.options.offset
13506 var offsetTop = offset.top
13507 var offsetBottom = offset.bottom
13508 var scrollHeight = Math.max($(document).height(), $(document.body).height())
13509
13510 if (typeof offset != 'object') offsetBottom = offsetTop = offset
13511 if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
13512 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
13513
13514 var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
13515
13516 if (this.affixed != affix) {
13517 if (this.unpin != null) this.$element.css('top', '')
13518
13519 var affixType = 'affix' + (affix ? '-' + affix : '')
13520 var e = $.Event(affixType + '.bs.affix')
13521
13522 this.$element.trigger(e)
13523
13524 if (e.isDefaultPrevented()) return
13525
13526 this.affixed = affix
13527 this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
13528
13529 this.$element
13530 .removeClass(Affix.RESET)
13531 .addClass(affixType)
13532 .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
13533 }
13534
13535 if (affix == 'bottom') {
13536 this.$element.offset({
13537 top: scrollHeight - height - offsetBottom
13538 })
13539 }
13540 }
13541
13542
13543 // AFFIX PLUGIN DEFINITION
13544 // =======================
13545
13546 function Plugin(option) {
13547 return this.each(function () {
13548 var $this = $(this)
13549 var data = $this.data('bs.affix')
13550 var options = typeof option == 'object' && option
13551
13552 if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
13553 if (typeof option == 'string') data[option]()
13554 })
13555 }
13556
13557 var old = $.fn.affix
13558
13559 $.fn.affix = Plugin
13560 $.fn.affix.Constructor = Affix
13561
13562
13563 // AFFIX NO CONFLICT
13564 // =================
13565
13566 $.fn.affix.noConflict = function () {
13567 $.fn.affix = old
13568 return this
13569 }
13570
13571
13572 // AFFIX DATA-API
13573 // ==============
13574
13575 $(window).on('load', function () {
13576 $('[data-spy="affix"]').each(function () {
13577 var $spy = $(this)
13578 var data = $spy.data()
13579
13580 data.offset = data.offset || {}
13581
13582 if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
13583 if (data.offsetTop != null) data.offset.top = data.offsetTop
13584
13585 Plugin.call($spy, data)
13586 })
13587 })
13588
13589}(jQuery);
13590
13591/*!
13592 * iCheck v1.0.3, http://git.io/arlzeA
13593 * ===================================
13594 * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization
13595 *
13596 * (c) 2013 Damir Sultanov, http://fronteed.com
13597 * MIT Licensed
13598 */
13599
13600(function($) {
13601
13602 // Cached vars
13603 var _iCheck = 'iCheck',
13604 _iCheckHelper = _iCheck + '-helper',
13605 _checkbox = 'checkbox',
13606 _radio = 'radio',
13607 _checked = 'checked',
13608 _unchecked = 'un' + _checked,
13609 _disabled = 'disabled',
13610 _determinate = 'determinate',
13611 _indeterminate = 'in' + _determinate,
13612 _update = 'update',
13613 _type = 'type',
13614 _click = 'click',
13615 _touch = 'touchbegin.i touchend.i',
13616 _add = 'addClass',
13617 _remove = 'removeClass',
13618 _callback = 'trigger',
13619 _label = 'label',
13620 _cursor = 'cursor',
13621 _mobile = /ip(hone|od|ad)|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
13622
13623 // Plugin init
13624 $.fn[_iCheck] = function(options, fire) {
13625
13626 // Walker
13627 var handle = 'input[type="' + _checkbox + '"], input[type="' + _radio + '"]',
13628 stack = $(),
13629 walker = function(object) {
13630 object.each(function() {
13631 var self = $(this);
13632
13633 if (self.is(handle)) {
13634 stack = stack.add(self);
13635 } else {
13636 stack = stack.add(self.find(handle));
13637 }
13638 });
13639 };
13640
13641 // Check if we should operate with some method
13642 if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
13643
13644 // Normalize method's name
13645 options = options.toLowerCase();
13646
13647 // Find checkboxes and radio buttons
13648 walker(this);
13649
13650 return stack.each(function() {
13651 var self = $(this);
13652
13653 if (options == 'destroy') {
13654 tidy(self, 'ifDestroyed');
13655 } else {
13656 operate(self, true, options);
13657 }
13658
13659 // Fire method's callback
13660 if ($.isFunction(fire)) {
13661 fire();
13662 }
13663 });
13664
13665 // Customization
13666 } else if (typeof options == 'object' || !options) {
13667
13668 // Check if any options were passed
13669 var settings = $.extend({
13670 checkedClass: _checked,
13671 disabledClass: _disabled,
13672 indeterminateClass: _indeterminate,
13673 labelHover: true
13674 }, options),
13675
13676 selector = settings.handle,
13677 hoverClass = settings.hoverClass || 'hover',
13678 focusClass = settings.focusClass || 'focus',
13679 activeClass = settings.activeClass || 'active',
13680 labelHover = !!settings.labelHover,
13681 labelHoverClass = settings.labelHoverClass || 'hover',
13682
13683 // Setup clickable area
13684 area = ('' + settings.increaseArea).replace('%', '') | 0;
13685
13686 // Selector limit
13687 if (selector == _checkbox || selector == _radio) {
13688 handle = 'input[type="' + selector + '"]';
13689 }
13690
13691 // Clickable area limit
13692 if (area < -50) {
13693 area = -50;
13694 }
13695
13696 // Walk around the selector
13697 walker(this);
13698
13699 return stack.each(function() {
13700 var self = $(this);
13701
13702 // If already customized
13703 tidy(self);
13704
13705 var node = this,
13706 id = node.id,
13707
13708 // Layer styles
13709 offset = -area + '%',
13710 size = 100 + (area * 2) + '%',
13711 layer = {
13712 position: 'absolute',
13713 top: offset,
13714 left: offset,
13715 display: 'block',
13716 width: size,
13717 height: size,
13718 margin: 0,
13719 padding: 0,
13720 background: '#fff',
13721 border: 0,
13722 opacity: 0
13723 },
13724
13725 // Choose how to hide input
13726 hide = _mobile ? {
13727 position: 'absolute',
13728 visibility: 'hidden'
13729 } : area ? layer : {
13730 position: 'absolute',
13731 opacity: 0
13732 },
13733
13734 // Get proper class
13735 className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
13736
13737 // Find assigned labels
13738 label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
13739
13740 // Check ARIA option
13741 aria = !!settings.aria,
13742
13743 // Set ARIA placeholder
13744 ariaID = _iCheck + '-' + Math.random().toString(36).substr(2,6),
13745
13746 // Parent & helper
13747 parent = '<div class="' + className + '" ' + (aria ? 'role="' + node[_type] + '" ' : ''),
13748 helper;
13749
13750 // Set ARIA "labelledby"
13751 if (aria) {
13752 label.each(function() {
13753 parent += 'aria-labelledby="';
13754
13755 if (this.id) {
13756 parent += this.id;
13757 } else {
13758 this.id = ariaID;
13759 parent += ariaID;
13760 }
13761
13762 parent += '"';
13763 });
13764 }
13765
13766 // Wrap input
13767 parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);
13768
13769 // Layer addition
13770 helper = $('<ins class="' + _iCheckHelper + '"/>').css(layer).appendTo(parent);
13771
13772 // Finalize customization
13773 self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
13774 !!settings.inheritClass && parent[_add](node.className || '');
13775 !!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
13776 parent.css('position') == 'static' && parent.css('position', 'relative');
13777 operate(self, true, _update);
13778
13779 // Label events
13780 if (label.length) {
13781 label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {
13782 var type = event[_type],
13783 item = $(this);
13784
13785 // Do nothing if input is disabled
13786 if (!node[_disabled]) {
13787
13788 // Click
13789 if (type == _click) {
13790 if ($(event.target).is('a')) {
13791 return;
13792 }
13793 operate(self, false, true);
13794
13795 // Hover state
13796 } else if (labelHover) {
13797
13798 // mouseout|touchend
13799 if (/ut|nd/.test(type)) {
13800 parent[_remove](hoverClass);
13801 item[_remove](labelHoverClass);
13802 } else {
13803 parent[_add](hoverClass);
13804 item[_add](labelHoverClass);
13805 }
13806 }
13807
13808 if (_mobile) {
13809 event.stopPropagation();
13810 } else {
13811 return false;
13812 }
13813 }
13814 });
13815 }
13816
13817 // Input events
13818 self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
13819 var type = event[_type],
13820 key = event.keyCode;
13821
13822 // Click
13823 if (type == _click) {
13824 return false;
13825
13826 // Keydown
13827 } else if (type == 'keydown' && key == 32) {
13828 if (!(node[_type] == _radio && node[_checked])) {
13829 if (node[_checked]) {
13830 off(self, _checked);
13831 } else {
13832 on(self, _checked);
13833 }
13834 }
13835
13836 return false;
13837
13838 // Keyup
13839 } else if (type == 'keyup' && node[_type] == _radio) {
13840 !node[_checked] && on(self, _checked);
13841
13842 // Focus/blur
13843 } else if (/us|ur/.test(type)) {
13844 parent[type == 'blur' ? _remove : _add](focusClass);
13845 }
13846 });
13847
13848 // Helper events
13849 helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
13850 var type = event[_type],
13851
13852 // mousedown|mouseup
13853 toggle = /wn|up/.test(type) ? activeClass : hoverClass;
13854
13855 // Do nothing if input is disabled
13856 if (!node[_disabled]) {
13857
13858 // Click
13859 if (type == _click) {
13860 operate(self, false, true);
13861
13862 // Active and hover states
13863 } else {
13864
13865 // State is on
13866 if (/wn|er|in/.test(type)) {
13867
13868 // mousedown|mouseover|touchbegin
13869 parent[_add](toggle);
13870
13871 // State is off
13872 } else {
13873 parent[_remove](toggle + ' ' + activeClass);
13874 }
13875
13876 // Label hover
13877 if (label.length && labelHover && toggle == hoverClass) {
13878
13879 // mouseout|touchend
13880 label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
13881 }
13882 }
13883
13884 if (_mobile) {
13885 event.stopPropagation();
13886 } else {
13887 return false;
13888 }
13889 }
13890 });
13891 });
13892 } else {
13893 return this;
13894 }
13895 };
13896
13897 // Do something with inputs
13898 function operate(input, direct, method) {
13899 var node = input[0],
13900 state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
13901 active = method == _update ? {
13902 checked: node[_checked],
13903 disabled: node[_disabled],
13904 indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
13905 } : node[state];
13906
13907 // Check, disable or indeterminate
13908 if (/^(ch|di|in)/.test(method) && !active) {
13909 on(input, state);
13910
13911 // Uncheck, enable or determinate
13912 } else if (/^(un|en|de)/.test(method) && active) {
13913 off(input, state);
13914
13915 // Update
13916 } else if (method == _update) {
13917
13918 // Handle states
13919 for (var each in active) {
13920 if (active[each]) {
13921 on(input, each, true);
13922 } else {
13923 off(input, each, true);
13924 }
13925 }
13926
13927 } else if (!direct || method == 'toggle') {
13928
13929 // Helper or label was clicked
13930 if (!direct) {
13931 input[_callback]('ifClicked');
13932 }
13933
13934 // Toggle checked state
13935 if (active) {
13936 if (node[_type] !== _radio) {
13937 off(input, state);
13938 }
13939 } else {
13940 on(input, state);
13941 }
13942 }
13943 }
13944
13945 // Add checked, disabled or indeterminate state
13946 function on(input, state, keep) {
13947 var node = input[0],
13948 parent = input.parent(),
13949 checked = state == _checked,
13950 indeterminate = state == _indeterminate,
13951 disabled = state == _disabled,
13952 callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
13953 regular = option(input, callback + capitalize(node[_type])),
13954 specific = option(input, state + capitalize(node[_type]));
13955
13956 // Prevent unnecessary actions
13957 if (node[state] !== true) {
13958
13959 // Toggle assigned radio buttons
13960 if (!keep && state == _checked && node[_type] == _radio && node.name) {
13961 var form = input.closest('form'),
13962 inputs = 'input[name="' + node.name + '"]';
13963
13964 inputs = form.length ? form.find(inputs) : $(inputs);
13965
13966 inputs.each(function() {
13967 if (this !== node && $(this).data(_iCheck)) {
13968 off($(this), state);
13969 }
13970 });
13971 }
13972
13973 // Indeterminate state
13974 if (indeterminate) {
13975
13976 // Add indeterminate state
13977 node[state] = true;
13978
13979 // Remove checked state
13980 if (node[_checked]) {
13981 off(input, _checked, 'force');
13982 }
13983
13984 // Checked or disabled state
13985 } else {
13986
13987 // Add checked or disabled state
13988 if (!keep) {
13989 node[state] = true;
13990 }
13991
13992 // Remove indeterminate state
13993 if (checked && node[_indeterminate]) {
13994 off(input, _indeterminate, false);
13995 }
13996 }
13997
13998 // Trigger callbacks
13999 callbacks(input, checked, state, keep);
14000 }
14001
14002 // Add proper cursor
14003 if (node[_disabled] && !!option(input, _cursor, true)) {
14004 parent.find('.' + _iCheckHelper).css(_cursor, 'default');
14005 }
14006
14007 // Add state class
14008 parent[_add](specific || option(input, state) || '');
14009
14010 // Set ARIA attribute
14011 if (!!parent.attr('role') && !indeterminate) {
14012 parent.attr('aria-' + (disabled ? _disabled : _checked), 'true');
14013 }
14014
14015 // Remove regular state class
14016 parent[_remove](regular || option(input, callback) || '');
14017 }
14018
14019 // Remove checked, disabled or indeterminate state
14020 function off(input, state, keep) {
14021 var node = input[0],
14022 parent = input.parent(),
14023 checked = state == _checked,
14024 indeterminate = state == _indeterminate,
14025 disabled = state == _disabled,
14026 callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
14027 regular = option(input, callback + capitalize(node[_type])),
14028 specific = option(input, state + capitalize(node[_type]));
14029
14030 // Prevent unnecessary actions
14031 if (node[state] !== false) {
14032
14033 // Toggle state
14034 if (indeterminate || !keep || keep == 'force') {
14035 node[state] = false;
14036 }
14037
14038 // Trigger callbacks
14039 callbacks(input, checked, callback, keep);
14040 }
14041
14042 // Add proper cursor
14043 if (!node[_disabled] && !!option(input, _cursor, true)) {
14044 parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
14045 }
14046
14047 // Remove state class
14048 parent[_remove](specific || option(input, state) || '');
14049
14050 // Set ARIA attribute
14051 if (!!parent.attr('role') && !indeterminate) {
14052 parent.attr('aria-' + (disabled ? _disabled : _checked), 'false');
14053 }
14054
14055 // Add regular state class
14056 parent[_add](regular || option(input, callback) || '');
14057 }
14058
14059 // Remove all traces
14060 function tidy(input, callback) {
14061 if (input.data(_iCheck)) {
14062
14063 // Remove everything except input
14064 input.parent().html(input.attr('style', input.data(_iCheck).s || ''));
14065
14066 // Callback
14067 if (callback) {
14068 input[_callback](callback);
14069 }
14070
14071 // Unbind events
14072 input.off('.i').unwrap();
14073 $(_label + '[for="' + input[0].id + '"]').add(input.closest(_label)).off('.i');
14074 }
14075 }
14076
14077 // Get some option
14078 function option(input, state, regular) {
14079 if (input.data(_iCheck)) {
14080 return input.data(_iCheck).o[state + (regular ? '' : 'Class')];
14081 }
14082 }
14083
14084 // Capitalize some string
14085 function capitalize(string) {
14086 return string.charAt(0).toUpperCase() + string.slice(1);
14087 }
14088
14089 // Executable handlers
14090 function callbacks(input, checked, callback, keep) {
14091 if (!keep) {
14092 if (checked) {
14093 input[_callback]('ifToggled');
14094 }
14095
14096 input[_callback]('change')[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
14097 }
14098 }
14099})(window.jQuery || window.Zepto);
14100
14101/**
14102 * WHMCS core JS library reference
14103 *
14104 * @copyright Copyright (c) WHMCS Limited 2005-2017
14105 * @license http://www.whmcs.com/license/ WHMCS Eula
14106 */
14107
14108(function (window, factory) {
14109 if (typeof window.WHMCS !== 'object') {
14110 window.WHMCS = factory;
14111 }
14112}(
14113 window,
14114 {
14115 hasModule: function (name) {
14116 return (typeof WHMCS[name] !== 'undefined'
14117 && Object.getOwnPropertyNames(WHMCS[name]).length > 0);
14118 },
14119 loadModule: function (name, module) {
14120 if (this.hasModule(name)) {
14121 return;
14122 }
14123
14124 WHMCS[name] = {};
14125 if (typeof module === 'function') {
14126 (module).apply(WHMCS[name]);
14127 } else {
14128 for (var key in module) {
14129 if (module.hasOwnProperty(key)) {
14130 WHMCS[name][key] = {};
14131 (module[key]).apply(WHMCS[name][key]);
14132 }
14133 }
14134 }
14135 }
14136 }
14137));
14138
14139jQuery(document).ready(function() {
14140 jQuery(document).on('click', '.disable-on-click', function () {
14141 jQuery(this).addClass('disabled');
14142
14143 if (jQuery(this).hasClass('spinner-on-click')) {
14144 var icon = $(this).find('i.fas,i.far,i.fal,i.fab');
14145
14146 jQuery(icon)
14147 .removeAttr('class')
14148 .addClass('fas fa-spinner fa-spin');
14149 }
14150 })
14151 .on('click', '#openTicketSubmit.disabled', function () {
14152 return false;
14153 });
14154});
14155
14156function scrollToGatewayInputError() {
14157 var displayError = jQuery('.gateway-errors,.assisted-cc-input-feedback').first(),
14158 frm = displayError.closest('form');
14159 if (!frm) {
14160 frm = jQuery('form').first();
14161 }
14162 frm.find('button[type="submit"],input[type="submit"]')
14163 .prop('disabled', false)
14164 .removeClass('disabled')
14165 .find('i.fas,i.far,i.fal,i.fab')
14166 .removeAttr('class')
14167 .addClass('fas fa-arrow-circle-right')
14168 .find('span').toggle();
14169
14170 if (displayError.length) {
14171 if (elementOutOfViewPort(displayError[0])) {
14172 jQuery('html, body').animate(
14173 {
14174 scrollTop: displayError.offset().top - 50
14175 },
14176 500
14177 );
14178 }
14179 }
14180}
14181
14182function elementOutOfViewPort(element) {
14183 // Get element's bounding
14184 var bounding = element.getBoundingClientRect();
14185 // Check if it's out of the viewport on each side
14186 var out = {};
14187 out.top = bounding.top < 0;
14188 out.left = bounding.left < 0;
14189 out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
14190 out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
14191 out.any = out.top || out.left || out.bottom || out.right;
14192
14193 return out.any;
14194};
14195
14196/**
14197 * WHMCS authentication module
14198 *
14199 * @copyright Copyright (c) WHMCS Limited 2005-2017
14200 * @license http://www.whmcs.com/license/ WHMCS Eula
14201 */
14202
14203(function(module) {
14204 if (!WHMCS.hasModule('authn')) {
14205 WHMCS.loadModule('authn', module);
14206 }
14207})({
14208provider: function () {
14209 var callbackFired = false;
14210
14211 /**
14212 * @return {jQuery}
14213 */
14214 this.feedbackContainer = function () {
14215 return jQuery(".providerLinkingFeedback");
14216 };
14217
14218 /**
14219 * @returns {jQuery}
14220 */
14221 this.btnContainer = function () {
14222 return jQuery(".providerPreLinking");
14223 };
14224
14225 this.feedbackMessage = function (context) {
14226 if (typeof context === 'undefined') {
14227 context = 'complete_sign_in';
14228 }
14229 var msgContainer = jQuery('p.providerLinkingMsg-preLink-' + context);
14230 if (msgContainer.length) {
14231 return msgContainer.first().html();
14232 }
14233
14234 return '';
14235 };
14236
14237 this.showProgressMessage = function(callback) {
14238 this.feedbackContainer().fadeIn('fast', function () {
14239 if (typeof callback === 'function' && !callbackFired) {
14240 callbackFired = true;
14241 callback();
14242 }
14243 });
14244 };
14245
14246 this.preLinkInit = function (callback) {
14247 var icon = '<i class="fas fa-fw fa-spinner fa-spin"></i> ';
14248
14249 this.feedbackContainer()
14250 .removeClass('alert-danger alert-success')
14251 .addClass('alert alert-info')
14252 .html(icon + this.feedbackMessage())
14253 .hide();
14254
14255 var btnContainer = this.btnContainer();
14256 if (btnContainer.length) {
14257 if (btnContainer.data('hideOnPrelink')) {
14258 var self = this;
14259 btnContainer.fadeOut('false', function ()
14260 {
14261 self.showProgressMessage(callback)
14262 });
14263 } else if (btnContainer.data('disableOnPrelink')) {
14264 btnContainer.find('.btn').addClass('disabled');
14265 this.showProgressMessage(callback);
14266 } else {
14267 this.showProgressMessage(callback);
14268 }
14269 } else {
14270 this.showProgressMessage(callback);
14271 }
14272 };
14273
14274 this.displayError = function (provider, errorCondition, providerErrorText){
14275 jQuery('#providerLinkingMessages .provider-name').html(provider);
14276
14277 var feedbackMsg = this.feedbackMessage('connect_error');
14278 if (errorCondition) {
14279 var errorMsg = this.feedbackMessage(errorCondition);
14280 if (errorMsg) {
14281 feedbackMsg = errorMsg
14282 }
14283 }
14284
14285 if (providerErrorText && $('.btn-logged-in-admin').length > 0) {
14286 feedbackMsg += ' Error: ' + providerErrorText;
14287 }
14288
14289 this.feedbackContainer().removeClass('alert-info alert-success')
14290 .addClass('alert alert-danger')
14291 .html(feedbackMsg).slideDown();
14292 };
14293
14294 this.displaySuccess = function (data, context, provider) {
14295 var icon = provider.icon;
14296 var htmlTarget = context.htmlTarget;
14297 var targetLogin = context.targetLogin;
14298 var targetRegister = context.targetRegister;
14299 var displayName = provider.name;
14300 var feedbackMsg = '';
14301
14302 switch (data.result) {
14303 case "logged_in":
14304 case "2fa_needed":
14305 feedbackMsg = this.feedbackMessage('2fa_needed');
14306 this.feedbackContainer().removeClass('alert-danger alert-warning alert-success')
14307 .addClass('alert alert-info')
14308 .html(feedbackMsg);
14309
14310 window.location = data.redirect_url
14311 ? decodeURIComponent(data.redirect_url)
14312 : decodeURIComponent(context.redirectUrl);
14313
14314 break;
14315
14316 case "linking_complete":
14317 var accountInfo = '';
14318 if (data.remote_account.email) {
14319 accountInfo = data.remote_account.email;
14320 } else {
14321 accountInfo = data.remote_account.firstname + " " + data.remote_account.lastname;
14322 }
14323
14324 accountInfo = accountInfo.trim();
14325
14326 feedbackMsg = this.feedbackMessage('linking_complete').trim().replace(':displayName', displayName);
14327 if (accountInfo) {
14328 feedbackMsg = feedbackMsg.replace(/\.$/, ' (' + accountInfo + ').');
14329 }
14330
14331 this.feedbackContainer().removeClass('alert-danger alert-warning alert-info')
14332 .addClass('alert alert-success')
14333 .html(icon + feedbackMsg);
14334 break;
14335
14336 case "login_to_link":
14337 if (htmlTarget === targetLogin) {
14338 feedbackMsg = this.feedbackMessage('login_to_link-signin-required');
14339 this.feedbackContainer().removeClass('alert-danger alert-success alert-info')
14340 .addClass('alert alert-warning')
14341 .html(icon + feedbackMsg);
14342 } else {
14343 var emailField = jQuery("input[name=email]");
14344 var firstNameField = jQuery("input[name=firstname]");
14345 var lastNameField = jQuery("input[name=lastname]");
14346
14347 if (emailField.val() === "") {
14348 emailField.val(data.remote_account.email);
14349 }
14350
14351 if (firstNameField.val() === "") {
14352 firstNameField.val(data.remote_account.firstname);
14353 }
14354
14355 if (lastNameField.val() === "") {
14356 lastNameField.val(data.remote_account.lastname);
14357 }
14358
14359 if (htmlTarget === targetRegister) {
14360 if (typeof WHMCS.client.registration === 'object') {
14361 WHMCS.client.registration.prefillPassword();
14362 }
14363 feedbackMsg = this.feedbackMessage('login_to_link-registration-required');
14364 this.feedbackContainer().fadeOut('slow', function () {
14365 $(this).removeClass('alert-danger alert-success alert-info')
14366 .addClass('alert alert-warning')
14367 .html(icon + feedbackMsg).fadeIn('fast');
14368 });
14369
14370 } else {
14371 // this is checkout
14372 if (typeof WHMCS.client.registration === 'object') {
14373 WHMCS.client.registration.prefillPassword();
14374 }
14375
14376 var self = this;
14377 this.feedbackContainer().each(function (i, el) {
14378 var container = $(el);
14379 var linkContext = container.siblings('div .providerPreLinking').data('linkContext');
14380
14381 container.fadeOut('slow', function () {
14382 if (linkContext === 'checkout-new') {
14383 feedbackMsg = self.feedbackMessage('checkout-new');
14384 } else {
14385 feedbackMsg = self.feedbackMessage('login_to_link-signin-required');
14386 }
14387 container.removeClass('alert-danger alert-success alert-info')
14388 .addClass('alert alert-warning')
14389 .html(icon + feedbackMsg).fadeIn('fast');
14390 });
14391 });
14392 }
14393 }
14394
14395 break;
14396
14397 case "other_user_exists":
14398 feedbackMsg = this.feedbackMessage('other_user_exists');
14399 this.feedbackContainer().removeClass('alert-info alert-success')
14400 .addClass('alert alert-danger')
14401 .html(icon + feedbackMsg).slideDown();
14402 break;
14403
14404 case "already_linked":
14405 feedbackMsg = this.feedbackMessage('already_linked');
14406 this.feedbackContainer().removeClass('alert-info alert-success')
14407 .addClass('alert alert-danger')
14408 .html(icon + feedbackMsg).slideDown();
14409 break;
14410
14411 default:
14412 feedbackMsg = this.feedbackMessage('default');
14413 this.feedbackContainer().removeClass('alert-info alert-success')
14414 .addClass('alert alert-danger')
14415 .html(icon + feedbackMsg).slideDown();
14416 break;
14417 }
14418 };
14419
14420 this.signIn = function (config, context, provider, providerDone, providerError) {
14421 jQuery.ajax(config).done(function(data) {
14422 providerDone();
14423 WHMCS.authn.provider.displaySuccess(data, context, provider);
14424 var table = jQuery('#tableLinkedAccounts');
14425 if (table.length) {
14426 WHMCS.ui.dataTable.getTableById('tableLinkedAccounts').ajax.reload();
14427 }
14428 }).error(function() {
14429 providerError();
14430 WHMCS.authn.provider.displayError();
14431 });
14432 };
14433
14434 return this;
14435}});
14436
14437/**
14438 * WHMCS client module
14439 *
14440 * @copyright Copyright (c) WHMCS Limited 2005-2017
14441 * @license http://www.whmcs.com/license/ WHMCS Eula
14442 */
14443(function(module) {
14444 if (!WHMCS.hasModule('client')) {
14445 WHMCS.loadModule('client', module);
14446 }
14447})({
14448registration: function () {
14449 this.prefillPassword = function (params) {
14450 params = params || {};
14451 if (typeof params.hideContainer === 'undefined') {
14452 var id = (jQuery('#inputSecurityQId').attr('id')) ? '#containerPassword' : '#containerNewUserSecurity';
14453 params.hideContainer = jQuery(id);
14454 params.hideInputs = true;
14455 } else if (typeof params.hideContainer === 'string' && params.hideContainer.length) {
14456 params.hideContainer = jQuery(params.hideContainer);
14457 }
14458
14459 if (typeof params.form === 'undefined') {
14460 params.form = {
14461 password: [
14462 {id: 'inputNewPassword1'},
14463 {id: 'inputNewPassword2'}
14464 ]
14465 };
14466 }
14467
14468 var prefillFunc = function () {
14469 var $randomPasswd = WHMCS.utils.simpleRNG();
14470 for (var i = 0, len = params.form.password.length; i < len; i++) {
14471 jQuery('#' + params.form.password[i].id)
14472 .val($randomPasswd).trigger('keyup');
14473 }
14474 };
14475
14476 if (params.hideInputs) {
14477 params.hideContainer.slideUp('fast', prefillFunc);
14478 } else {
14479 prefillFunc();
14480 }
14481 };
14482
14483 return this;
14484}});
14485
14486/**
14487 * WHMCS HTTP module
14488 *
14489 * @copyright Copyright (c) WHMCS Limited 2005-2018
14490 * @license http://www.whmcs.com/license/ WHMCS Eula
14491 */
14492(function(module) {
14493 if (!WHMCS.hasModule('http')) {
14494 WHMCS.loadModule('http', module);
14495 }
14496})({
14497jqClient: function () {
14498 _getSettings = function (url, data, success, dataType)
14499 {
14500 if (typeof url === 'object') {
14501 /*
14502 Settings may be the only argument
14503 */
14504 return url;
14505 }
14506
14507 if (typeof data === 'function') {
14508 /*
14509 If 'data' is omitted, 'success' will come in its place
14510 */
14511 success = data;
14512 data = null;
14513 }
14514
14515 return {
14516 url: url,
14517 data: data,
14518 success: success,
14519 dataType: dataType
14520 };
14521 };
14522
14523 /**
14524 * @param url
14525 * @param data
14526 * @param success
14527 * @param dataType
14528 * @returns {*}
14529 */
14530 this.get = function (url, data, success, dataType)
14531 {
14532 return WHMCS.http.client.request(
14533 jQuery.extend(
14534 _getSettings(url, data, success, dataType),
14535 {
14536 type: 'GET'
14537 }
14538 )
14539 );
14540 };
14541
14542 /**
14543 * @param url
14544 * @param data
14545 * @param success
14546 * @param dataType
14547 * @returns {*}
14548 */
14549 this.post = function (url, data, success, dataType)
14550 {
14551 return WHMCS.http.client.request(
14552 jQuery.extend(
14553 _getSettings(url, data, success, dataType),
14554 {
14555 type: 'POST'
14556 }
14557 )
14558 );
14559 };
14560
14561 /**
14562 * @param options
14563 * @returns {*}
14564 */
14565 this.jsonGet = function (options) {
14566 options = options || {};
14567 this.get(options.url, options.data, function(response) {
14568 if (response.warning) {
14569 console.log('[WHMCS] Warning: ' + response.warning);
14570 if (typeof options.warning === 'function') {
14571 options.warning(response.warning);
14572 }
14573 } else if (response.error) {
14574 console.log('[WHMCS] Error: ' + response.error);
14575 if (typeof options.error === 'function') {
14576 options.error(response.error);
14577 }
14578 } else {
14579 if (typeof options.success === 'function') {
14580 options.success(response);
14581 }
14582 }
14583 }, 'json').error(function(xhr, errorMsg){
14584 console.log('[WHMCS] Error: ' + errorMsg);
14585 if (typeof options.fail === 'function') {
14586 options.fail(errorMsg);
14587 }
14588 }).always(function() {
14589 if (typeof options.always === 'function') {
14590 options.always();
14591 }
14592 });
14593 };
14594
14595 /**
14596 * @param options
14597 * @returns {*}
14598 */
14599 this.jsonPost = function (options) {
14600 options = options || {};
14601 this.post(options.url, options.data, function(response) {
14602 if (response.warning) {
14603 console.log('[WHMCS] Warning: ' + response.warning);
14604 if (typeof options.warning === 'function') {
14605 options.warning(response.warning);
14606 }
14607 } else if (response.error) {
14608 console.log('[WHMCS] Error: ' + response.error);
14609 if (typeof options.error === 'function') {
14610 options.error(response.error);
14611 }
14612 } else {
14613 if (typeof options.success === 'function') {
14614 options.success(response);
14615 }
14616 }
14617 }, 'json').fail(function(xhr, errorMsg){
14618 console.log('[WHMCS] Fail: ' + errorMsg);
14619 if (typeof options.fail === 'function') {
14620 options.fail(errorMsg, xhr);
14621 }
14622 }).always(function() {
14623 if (typeof options.always === 'function') {
14624 options.always();
14625 }
14626 });
14627 };
14628
14629 return this;
14630},
14631
14632client: function () {
14633 var methods = ['get', 'post', 'put', 'delete'];
14634 var client = this;
14635
14636 _beforeRequest = function (settings)
14637 {
14638 /*
14639 Enforcing dataType was found to break many invocations expecting HTML back.
14640 If/when those are refactored, this may be uncommented to enforce a safer
14641 data transit.
14642 */
14643 /*if (typeof settings.dataType === 'undefined') {
14644 settings.dataType = 'json';
14645 }*/
14646
14647 if (typeof settings.type === 'undefined') {
14648 // default request type is GET
14649 settings.type = 'GET';
14650 }
14651
14652 /*
14653 Add other preprocessing here if required
14654 */
14655
14656 return settings;
14657 };
14658
14659 this.request = function (settings)
14660 {
14661 settings = _beforeRequest(settings || {});
14662 return jQuery.ajax(settings);
14663 };
14664
14665 /*
14666 Create shortcut methods for methods[] array above
14667 */
14668 jQuery.each(methods, function(index, method) {
14669 client[method] = (function(method, client) {
14670 return function (settings)
14671 {
14672 settings = settings || {};
14673
14674 settings.type = method.toUpperCase();
14675
14676 return client.request(settings);
14677 }
14678 })(method, client);
14679 });
14680
14681 return this;
14682}
14683
14684});
14685
14686/**
14687 * WHMCS UI module
14688 *
14689 * @copyright Copyright (c) WHMCS Limited 2005-2017
14690 * @license http://www.whmcs.com/license/ WHMCS Eula
14691 */
14692(function(module) {
14693 if (!WHMCS.hasModule('ui')) {
14694 WHMCS.loadModule('ui', module);
14695 }
14696})({
14697/**
14698 * Confirmation PopUp
14699 */
14700confirmation: function () {
14701
14702 /**
14703 * @type {Array} Registered confirmation root selectors
14704 */
14705 var toggles = [];
14706
14707 /**
14708 * Register/Re-Register all confirmation elements with jQuery
14709 * By default all elements of data toggle "confirmation" will be registered
14710 *
14711 * @param {(string|undefined)} rootSelector
14712 * @return {Array} array of registered toggles
14713 */
14714 this.register = function (rootSelector) {
14715 if (typeof rootSelector === 'undefined') {
14716 rootSelector = '[data-toggle=confirmation]';
14717 }
14718 if (toggles.indexOf(rootSelector) < 0) {
14719 toggles.push(rootSelector);
14720 }
14721
14722 jQuery(rootSelector).confirmation({
14723 rootSelector: rootSelector
14724 });
14725
14726 return toggles;
14727 };
14728
14729 return this;
14730},
14731
14732/**
14733 * Data Driven Table
14734 */
14735dataTable: function () {
14736
14737 /**
14738 * @type {{}}
14739 */
14740 this.tables = {};
14741
14742 /**
14743 * Register all tables on page with the class "data-driven"
14744 */
14745 this.register = function () {
14746 var self = this;
14747 jQuery('table.data-driven').each(function (i, table) {
14748 self.getTableById(table.id, undefined);
14749 });
14750 };
14751
14752 /**
14753 * Get a table by id; create table object on fly as necessary
14754 *
14755 * @param {string} id
14756 * @param {({}|undefined)} options
14757 * @returns {DataTable}
14758 */
14759 this.getTableById = function (id, options) {
14760 var self = this;
14761 var el = jQuery('#' + id);
14762 if (typeof self.tables[id] === 'undefined') {
14763 if (typeof options === 'undefined') {
14764 options = {
14765 dom: '<"listtable"ift>pl',
14766 paging: false,
14767 lengthChange: false,
14768 searching: false,
14769 ordering: true,
14770 info: false,
14771 autoWidth: true,
14772 columns: [],
14773 lengthMenu: [10, 25, 50, 100, 500, 1000],
14774 language: {
14775 emptyTable: (el.data('langEmptyTable')) ? el.data('langEmptyTable') : "No records found"
14776 }
14777 };
14778 }
14779 jQuery.each(el.data(), function (key, value) {
14780 if (typeof value === 'undefined') {
14781 return;
14782 }
14783 if (key === 'ajaxUrl') {
14784 options.ajax = {
14785 url: value
14786 };
14787 return;
14788 }
14789 if (key === 'lengthChange') {
14790 options.lengthChange = value;
14791 return;
14792 }
14793 if (key === 'pageLength') {
14794 options.pageLength = value;
14795 return;
14796 }
14797 if (key === 'langEmptyTable') {
14798 if (typeof options.language === "undefined") {
14799 options.language = {};
14800 }
14801 options.language.emptyTable = value;
14802 return
14803 }
14804 if (key === 'langZeroRecords') {
14805 if (typeof options.language === "undefined") {
14806 options.language = {};
14807 }
14808 options.language.zeroRecords = value;
14809 return
14810 }
14811 options.key = value;
14812 });
14813 jQuery.each(el.find('th'), function() {
14814 if (typeof options.columns === "undefined") {
14815 options.columns = [];
14816 }
14817 options.columns.push({data:jQuery(this).data('name')});
14818 });
14819 self.tables[id] = self.initTable(el, options);
14820 } else if (typeof options !== 'undefined') {
14821 var oldTable = self.tables[id];
14822 var initOpts = oldTable.init();
14823 var newOpts = jQuery.extend( initOpts, options);
14824 oldTable.destroy();
14825 self.tables[id] = self.initTable(el, newOpts);
14826 }
14827
14828 return self.tables[id];
14829 };
14830
14831 this.initTable = function (el, options) {
14832 var table = el.DataTable(options);
14833 var self = this;
14834 if (el.data('on-draw')) {
14835 table.on('draw.dt', function (e, settings) {
14836 var namedCallback = el.data('on-draw');
14837 if (typeof window[namedCallback] === 'function') {
14838 window[namedCallback](e, settings);
14839 }
14840 });
14841 } else if (el.data('on-draw-rebind-confirmation')) {
14842 table.on('draw.dt', function (e) {
14843 self.rebindConfirmation(e);
14844 });
14845 }
14846
14847 return table;
14848 };
14849
14850 this.rebindConfirmation = function (e) {
14851 var self = this;
14852 var tableId = e.target.id;
14853 var toggles = WHMCS.ui.confirmation.register();
14854 for(var i = 0, len = toggles.length; i < len; i++ ) {
14855 jQuery(toggles[i]).on(
14856 'confirmed.bs.confirmation',
14857 function (e)
14858 {
14859 e.preventDefault();
14860 WHMCS.http.jqClient.post(
14861 jQuery(e.target).data('target-url'),
14862 {
14863 'token': csrfToken
14864 }
14865 ).done(function (data)
14866 {
14867 if (data.status === 'success' || data.status === 'okay') {
14868 self.getTableById(tableId, undefined).ajax.reload();
14869 }
14870 });
14871
14872 }
14873 );
14874 }
14875 };
14876
14877 return this;
14878},
14879
14880clipboard: function() {
14881 this.copy = function(e) {
14882 e.preventDefault();
14883
14884 var trigger = $(e.currentTarget);
14885 var contentElement = $(trigger).data('clipboard-target');
14886 var container = $(contentElement).parent();
14887
14888 try {
14889 var tempElement = $('<textarea>')
14890 .css('position', 'fixed')
14891 .css('opacity', '0')
14892 .css('width', '1px')
14893 .css('height', '1px')
14894 .val($(contentElement).val());
14895
14896 container.append(tempElement);
14897 tempElement.focus().select();
14898 document.execCommand('copy');
14899 } finally {
14900 tempElement.remove();
14901 }
14902
14903 trigger.tooltip({
14904 trigger: 'click',
14905 placement: 'bottom'
14906 });
14907 WHMCS.ui.toolTip.setTip(trigger, 'Copied!');
14908 WHMCS.ui.toolTip.hideTip(trigger);
14909 };
14910
14911 return this;
14912},
14913
14914/**
14915 * ToolTip and Clipboard behaviors
14916 */
14917toolTip: function () {
14918 this.setTip = function (btn, message) {
14919 var tip = btn.data('bs.tooltip');
14920 if (tip.hoverState !== 'in') {
14921 tip.hoverState = 'in';
14922 }
14923 btn.attr('data-original-title', message);
14924 tip.show();
14925
14926 return tip;
14927 };
14928
14929 this.hideTip = function (btn, timeout) {
14930 if (!timeout) {
14931 timeout = 2000;
14932 }
14933 return setTimeout(function() {
14934 btn.data('bs.tooltip').hide()
14935 }, timeout);
14936 }
14937},
14938
14939jsonForm: function() {
14940 this.managedElements = 'input,textarea,select';
14941
14942 this.initFields = function (form) {
14943 var self = this;
14944 $(form).find(self.managedElements).each(function () {
14945 var field = this;
14946
14947 $(field).on('keypress change', function () {
14948 if (self.fieldHasError(field)) {
14949 self.clearFieldError(field);
14950 }
14951 });
14952 });
14953 };
14954
14955 this.init = function (form) {
14956 var self = this;
14957
14958 self.initFields(form);
14959
14960 $(form).on('submit', function(e) {
14961 e.preventDefault();
14962 e.stopPropagation();
14963
14964 self.clearErrors(form);
14965
14966 var formModal = $(form).parents('.modal[role="dialog"]').first();
14967
14968 if ($(formModal).length) {
14969 $(formModal).on('show.bs.modal hidden.bs.modal', function() {
14970 self.clearErrors(form);
14971 });
14972
14973 /*
14974 * Make this optional if the form is used for editing
14975 */
14976 $(formModal).on('show.bs.modal', function() {
14977 $(form)[0].reset();
14978 });
14979 }
14980
14981 WHMCS.http.client.post({
14982 url: $(form).attr('action'),
14983 data: $(form).serializeArray(),
14984 })
14985 .done(function (response) {
14986 self.onSuccess(form, response);
14987 })
14988 .fail(function (jqXHR) {
14989 self.onError(form, jqXHR);
14990 })
14991 .always(function (data) {
14992 self.onRequestComplete(form, data);
14993 });
14994 });
14995 };
14996
14997 this.initAll = function () {
14998 var self = this;
14999
15000 $('form[data-role="json-form"]').each(function() {
15001 var formElement = this;
15002 self.init(formElement);
15003 });
15004 };
15005
15006 this.markFieldErrors = function (form, fields)
15007 {
15008 var self = this;
15009 var errorMessage = null;
15010 var field, fieldLookup;
15011
15012 for (var fieldName in fields) {
15013 if (fields.hasOwnProperty(fieldName)) {
15014 errorMessage = fields[fieldName];
15015 }
15016
15017 fieldLookup = self.managedElements.split(',').map(function(element) {
15018 return element + '[name="' + fieldName + '"]';
15019 }).join(',');
15020
15021 field = $(form).find(fieldLookup);
15022
15023 if (errorMessage) {
15024 $(field).parents('.form-group').addClass('has-error');
15025 $(field).attr('title', errorMessage);
15026 $(field).tooltip();
15027 }
15028 }
15029
15030 $(form).find('.form-group.has-error input[title]').first().tooltip('show');
15031 };
15032
15033 this.fieldHasError = function (field) {
15034 return $(field).parents('.form-group').hasClass('has-error');
15035 };
15036
15037 this.clearFieldError = function (field) {
15038 /**
15039 * Try dispose first for BS 4, which will raise error
15040 * on BS 3 or older, then we use destroy instead
15041 */
15042 try {
15043 $(field).tooltip('dispose');
15044 } catch (err) {
15045 $(field).tooltip('destroy');
15046 }
15047 $(field).parents('.form-group').removeClass('has-error');
15048 };
15049
15050 this.onSuccess = function (form, response) {
15051 var formOnSuccess = $(form).data('on-success');
15052
15053 if (typeof formOnSuccess === 'function') {
15054 formOnSuccess(response.data);
15055 }
15056 };
15057
15058 this.onError = function (form, jqXHR) {
15059 if (jqXHR.responseJSON && jqXHR.responseJSON.fields && typeof jqXHR.responseJSON.fields === 'object') {
15060 this.markFieldErrors(form, jqXHR.responseJSON.fields);
15061 } else {
15062 // TODO: replace with client-accessible generic error messaging
15063 console.log('Unknown error - please try again later.');
15064 }
15065
15066 var formOnError = $(form).data('on-error');
15067
15068 if (typeof formOnError === 'function') {
15069 formOnError(jqXHR);
15070 }
15071 };
15072
15073 this.clearErrors = function (form) {
15074 var self = this;
15075
15076 $(form).find(self.managedElements).each(function () {
15077 self.clearFieldError(this);
15078 })
15079 };
15080
15081 this.onRequestComplete = function (form, data) {
15082 // implement as needed
15083 };
15084
15085 return this;
15086},
15087
15088effects: function () {
15089 this.errorShake = function (element) {
15090 /**
15091 * Shake effect without jQuery UI inspired by Hiren Patel | ninty9notout:
15092 * @see https://github.com/ninty9notout/jquery-shake/blob/51f3dcf625970c78505bcac831fd9e28fc85d374/jquery.ui.shake.js
15093 */
15094 options = options || {};
15095 var options = $.extend({
15096 direction: "left",
15097 distance: 8,
15098 times: 3,
15099 speed: 90
15100 }, options);
15101
15102 return element.each(function () {
15103 var el = $(this), props = {
15104 position: el.css("position"),
15105 top: el.css("top"),
15106 bottom: el.css("bottom"),
15107 left: el.css("left"),
15108 right: el.css("right")
15109 };
15110
15111 el.css("position", "relative");
15112
15113 var ref = (options.direction === "up" || options.direction === "down") ? "top" : "left";
15114 var motion = (options.direction === "up" || options.direction === "left") ? "pos" : "neg";
15115
15116 var animation = {}, animation1 = {}, animation2 = {};
15117 animation[ref] = (motion === "pos" ? "-=" : "+=") + options.distance;
15118 animation1[ref] = (motion === "pos" ? "+=" : "-=") + options.distance * 2;
15119 animation2[ref] = (motion === "pos" ? "-=" : "+=") + options.distance * 2;
15120
15121 el.animate(animation, options.speed);
15122 for (var i = 1; i < options.times; i++) {
15123 el.animate(animation1, options.speed).animate(animation2, options.speed);
15124 }
15125
15126 el.animate(animation1, options.speed).animate(animation, options.speed / 2, function () {
15127 el.css(props);
15128 });
15129 });
15130 };
15131
15132}
15133});
15134
15135/**
15136 * Form module
15137 *
15138 * @copyright Copyright (c) WHMCS Limited 2005-2017
15139 * @license http://www.whmcs.com/license/ WHMCS Eula
15140 */
15141(function(module) {
15142 if (!WHMCS.hasModule('form')) {
15143 WHMCS.loadModule('form', module);
15144 }
15145})(
15146function () {
15147 this.checkAllBound = false;
15148
15149 this.register = function () {
15150 if (!this.checkAllBound) {
15151 this.bindCheckAll();
15152 this.checkAllBound = true;
15153 }
15154 };
15155
15156 this.bindCheckAll = function ()
15157 {
15158 var huntSelector = '.btn-check-all';
15159 jQuery('body').on('click', huntSelector, function (e) {
15160 var btn = jQuery(e.target);
15161 var targetInputs = jQuery(
15162 '#' + btn.data('checkbox-container') + ' input[type="checkbox"]'
15163 );
15164 if (btn.data('btn-check-toggle')) {
15165 // one control that changes
15166 var textDeselect = 'Deselect All';
15167 var textSelect = 'Select All';
15168 if (btn.data('label-text-deselect')) {
15169 textDeselect = btn.data('label-text-deselect');
15170 }
15171 if (btn.data('label-text-select')) {
15172 textSelect = btn.data('label-text-select');
15173 }
15174
15175 if (btn.hasClass('toggle-active')) {
15176 targetInputs.prop('checked',false);
15177 btn.text(textSelect);
15178 btn.removeClass('toggle-active');
15179 } else {
15180 targetInputs.prop('checked',true);
15181 btn.text(textDeselect);
15182 btn.addClass('toggle-active');
15183 }
15184 } else {
15185 // two controls that are static
15186 if (btn.data('btn-toggle-on')) {
15187 targetInputs.prop('checked',true);
15188 } else {
15189 targetInputs.prop('checked',false);
15190 }
15191 }
15192 });
15193 };
15194
15195 this.reloadCaptcha = function (element)
15196 {
15197 if (typeof grecaptcha !== 'undefined') {
15198 grecaptcha.reset();
15199 } else {
15200 if (!element) {
15201 element = jQuery('#inputCaptchaImage');
15202 }
15203
15204 var src = jQuery(element).data('src');
15205 jQuery(element).attr('src', src + '?nocache=' + (new Date()).getTime());
15206
15207 var userInput = jQuery('#inputCaptcha');
15208 if (userInput.length) {
15209 userInput.val('');
15210 }
15211 }
15212 };
15213
15214 return this;
15215});
15216
15217/**
15218 * reCaptcha module
15219 *
15220 * @copyright Copyright (c) WHMCS Limited 2005-2020
15221 * @license http://www.whmcs.com/license/ WHMCS Eula
15222 */
15223var recaptchaLoadComplete = false,
15224 recaptchaCount = 0,
15225 recaptchaType = 'recaptcha',
15226 recaptchaValidationComplete = false;
15227
15228(function(module) {
15229 if (!WHMCS.hasModule('recaptcha')) {
15230 WHMCS.loadModule('recaptcha', module);
15231 }
15232})(
15233 function () {
15234
15235 this.register = function () {
15236 if (recaptchaLoadComplete) {
15237 return;
15238 }
15239 var postLoad = [],
15240 recaptchaForms = jQuery(".btn-recaptcha").parents('form'),
15241 isInvisible = false;
15242 recaptchaForms.each(function (i, el){
15243 if (typeof recaptchaSiteKey === 'undefined') {
15244 console.log('Recaptcha site key not defined');
15245 return;
15246 }
15247 recaptchaCount += 1;
15248 var frm = jQuery(el),
15249 btnRecaptcha = frm.find(".btn-recaptcha"),
15250 required = (typeof requiredText !== 'undefined') ? requiredText : 'Required',
15251 recaptchaId = 'divDynamicRecaptcha' + recaptchaCount;
15252
15253 isInvisible = btnRecaptcha.hasClass('btn-recaptcha-invisible')
15254
15255 // if no recaptcha element, make one
15256 var recaptchaContent = frm.find('#' + recaptchaId + ' .g-recaptcha'),
15257 recaptchaElement = frm.find('.recaptcha-container'),
15258 appendElement = frm;
15259
15260 if (recaptchaElement.length) {
15261 recaptchaElement.attr('id', recaptchaElement.attr('id') + recaptchaCount);
15262 appendElement = recaptchaElement;
15263 }
15264 if (!recaptchaContent.length) {
15265 appendElement.append('<div id="#' + recaptchaId + '" class="g-recaptcha"></div>');
15266 recaptchaContent = appendElement.find('#' + recaptchaId);
15267 }
15268 // propagate invisible recaptcha if necessary
15269 if (!isInvisible) {
15270 recaptchaContent.data('toggle', 'tooltip')
15271 .data('placement', 'bottom')
15272 .data('trigger', 'manual')
15273 .attr('title', required)
15274 .hide();
15275 }
15276
15277
15278 // alter form to work around JS behavior on .submit() when there
15279 // there is an input with the name 'submit'
15280 var btnSubmit = frm.find("input[name='submit']");
15281 if (btnSubmit.length) {
15282 var action = frm.prop('action');
15283 frm.prop('action', action + '&submit=1');
15284 btnSubmit.remove();
15285 }
15286
15287 // make callback for grecaptcha to invoke after
15288 // injecting token & make it known via data-callback
15289 var funcName = recaptchaId + 'Callback';
15290 window[funcName] = function () {
15291 if (isInvisible) {
15292 frm.submit();
15293 }
15294 };
15295
15296 // setup an on form submit event to ensure that we
15297 // are allowing required field validation to occur before
15298 // we do the invisible recaptcha checking
15299 if (isInvisible) {
15300 recaptchaType = 'invisible';
15301 frm.on('submit.recaptcha', function (event) {
15302 var recaptchaId = frm.find('.g-recaptcha').data('recaptcha-id');
15303 if (!grecaptcha.getResponse(recaptchaId).trim()) {
15304 event.preventDefault();
15305 grecaptcha.execute(recaptchaId);
15306 recaptchaValidationComplete = false;
15307 } else {
15308 recaptchaValidationComplete = true;
15309 }
15310 });
15311 } else {
15312 postLoad.push(function () {
15313 recaptchaContent.slideDown('fast', function() {
15314 // just in case there's a delay in DOM; rare
15315 recaptchaContent.find(':first').addClass('center-block');
15316 });
15317 });
15318 postLoad.push(function() {
15319 recaptchaContent.find(':first').addClass('center-block');
15320 });
15321 }
15322 });
15323
15324 window.recaptchaLoadCallback = function() {
15325 jQuery('.g-recaptcha').each(function(i, el) {
15326 var element = jQuery(el),
15327 frm = element.closest('form'),
15328 btn = frm.find('.btn-recaptcha'),
15329 idToUse = element.attr('id').substring(1);
15330 var recaptchaId = grecaptcha.render(
15331 el,
15332 {
15333 sitekey: recaptchaSiteKey,
15334 size: (btn.hasClass('btn-recaptcha-invisible')) ? 'invisible' : 'normal',
15335 callback: idToUse + 'Callback'
15336 }
15337 );
15338 element.data('recaptcha-id', recaptchaId);
15339 });
15340 }
15341
15342 // fetch/invoke the grecaptcha lib
15343 if (recaptchaForms.length) {
15344 var gUrl = "https://www.google.com/recaptcha/api.js?onload=recaptchaLoadCallback&render=explicit";
15345 jQuery.getScript(gUrl, function () {
15346 for(var i = postLoad.length - 1; i >= 0 ; i--){
15347 postLoad[i]();
15348 }
15349 });
15350 }
15351 recaptchaLoadComplete = true;
15352 };
15353
15354 return this;
15355 });
15356
15357/**
15358 * microplugin.js
15359 * Copyright (c) 2013 Brian Reavis & contributors
15360 *
15361 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
15362 * file except in compliance with the License. You may obtain a copy of the License at:
15363 * http://www.apache.org/licenses/LICENSE-2.0
15364 *
15365 * Unless required by applicable law or agreed to in writing, software distributed under
15366 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
15367 * ANY KIND, either express or implied. See the License for the specific language
15368 * governing permissions and limitations under the License.
15369 *
15370 * @author Brian Reavis <brian@thirdroute.com>
15371 */
15372
15373(function(root, factory) {
15374 if (typeof define === 'function' && define.amd) {
15375 define(factory);
15376 } else if (typeof exports === 'object') {
15377 module.exports = factory();
15378 } else {
15379 root.MicroPlugin = factory();
15380 }
15381}(this, function() {
15382 var MicroPlugin = {};
15383
15384 MicroPlugin.mixin = function(Interface) {
15385 Interface.plugins = {};
15386
15387 /**
15388 * Initializes the listed plugins (with options).
15389 * Acceptable formats:
15390 *
15391 * List (without options):
15392 * ['a', 'b', 'c']
15393 *
15394 * List (with options):
15395 * [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
15396 *
15397 * Hash (with options):
15398 * {'a': { ... }, 'b': { ... }, 'c': { ... }}
15399 *
15400 * @param {mixed} plugins
15401 */
15402 Interface.prototype.initializePlugins = function(plugins) {
15403 var i, n, key;
15404 var self = this;
15405 var queue = [];
15406
15407 self.plugins = {
15408 names : [],
15409 settings : {},
15410 requested : {},
15411 loaded : {}
15412 };
15413
15414 if (utils.isArray(plugins)) {
15415 for (i = 0, n = plugins.length; i < n; i++) {
15416 if (typeof plugins[i] === 'string') {
15417 queue.push(plugins[i]);
15418 } else {
15419 self.plugins.settings[plugins[i].name] = plugins[i].options;
15420 queue.push(plugins[i].name);
15421 }
15422 }
15423 } else if (plugins) {
15424 for (key in plugins) {
15425 if (plugins.hasOwnProperty(key)) {
15426 self.plugins.settings[key] = plugins[key];
15427 queue.push(key);
15428 }
15429 }
15430 }
15431
15432 while (queue.length) {
15433 self.require(queue.shift());
15434 }
15435 };
15436
15437 Interface.prototype.loadPlugin = function(name) {
15438 var self = this;
15439 var plugins = self.plugins;
15440 var plugin = Interface.plugins[name];
15441
15442 if (!Interface.plugins.hasOwnProperty(name)) {
15443 throw new Error('Unable to find "' + name + '" plugin');
15444 }
15445
15446 plugins.requested[name] = true;
15447 plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
15448 plugins.names.push(name);
15449 };
15450
15451 /**
15452 * Initializes a plugin.
15453 *
15454 * @param {string} name
15455 */
15456 Interface.prototype.require = function(name) {
15457 var self = this;
15458 var plugins = self.plugins;
15459
15460 if (!self.plugins.loaded.hasOwnProperty(name)) {
15461 if (plugins.requested[name]) {
15462 throw new Error('Plugin has circular dependency ("' + name + '")');
15463 }
15464 self.loadPlugin(name);
15465 }
15466
15467 return plugins.loaded[name];
15468 };
15469
15470 /**
15471 * Registers a plugin.
15472 *
15473 * @param {string} name
15474 * @param {function} fn
15475 */
15476 Interface.define = function(name, fn) {
15477 Interface.plugins[name] = {
15478 'name' : name,
15479 'fn' : fn
15480 };
15481 };
15482 };
15483
15484 var utils = {
15485 isArray: Array.isArray || function(vArg) {
15486 return Object.prototype.toString.call(vArg) === '[object Array]';
15487 }
15488 };
15489
15490 return MicroPlugin;
15491}));
15492/**
15493 * sifter.js
15494 * Copyright (c) 2013 Brian Reavis & contributors
15495 *
15496 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
15497 * file except in compliance with the License. You may obtain a copy of the License at:
15498 * http://www.apache.org/licenses/LICENSE-2.0
15499 *
15500 * Unless required by applicable law or agreed to in writing, software distributed under
15501 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
15502 * ANY KIND, either express or implied. See the License for the specific language
15503 * governing permissions and limitations under the License.
15504 *
15505 * @author Brian Reavis <brian@thirdroute.com>
15506 */
15507
15508(function(root, factory) {
15509 if (typeof define === 'function' && define.amd) {
15510 define(factory);
15511 } else if (typeof exports === 'object') {
15512 module.exports = factory();
15513 } else {
15514 root.Sifter = factory();
15515 }
15516}(this, function() {
15517
15518 /**
15519 * Textually searches arrays and hashes of objects
15520 * by property (or multiple properties). Designed
15521 * specifically for autocomplete.
15522 *
15523 * @constructor
15524 * @param {array|object} items
15525 * @param {object} items
15526 */
15527 var Sifter = function(items, settings) {
15528 this.items = items;
15529 this.settings = settings || {diacritics: true};
15530 };
15531
15532 /**
15533 * Splits a search string into an array of individual
15534 * regexps to be used to match results.
15535 *
15536 * @param {string} query
15537 * @returns {array}
15538 */
15539 Sifter.prototype.tokenize = function(query) {
15540 query = trim(String(query || '').toLowerCase());
15541 if (!query || !query.length) return [];
15542
15543 var i, n, regex, letter;
15544 var tokens = [];
15545 var words = query.split(/ +/);
15546
15547 for (i = 0, n = words.length; i < n; i++) {
15548 regex = escape_regex(words[i]);
15549 if (this.settings.diacritics) {
15550 for (letter in DIACRITICS) {
15551 if (DIACRITICS.hasOwnProperty(letter)) {
15552 regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]);
15553 }
15554 }
15555 }
15556 tokens.push({
15557 string : words[i],
15558 regex : new RegExp(regex, 'i')
15559 });
15560 }
15561
15562 return tokens;
15563 };
15564
15565 /**
15566 * Iterates over arrays and hashes.
15567 *
15568 * ```
15569 * this.iterator(this.items, function(item, id) {
15570 * // invoked for each item
15571 * });
15572 * ```
15573 *
15574 * @param {array|object} object
15575 */
15576 Sifter.prototype.iterator = function(object, callback) {
15577 var iterator;
15578 if (is_array(object)) {
15579 iterator = Array.prototype.forEach || function(callback) {
15580 for (var i = 0, n = this.length; i < n; i++) {
15581 callback(this[i], i, this);
15582 }
15583 };
15584 } else {
15585 iterator = function(callback) {
15586 for (var key in this) {
15587 if (this.hasOwnProperty(key)) {
15588 callback(this[key], key, this);
15589 }
15590 }
15591 };
15592 }
15593
15594 iterator.apply(object, [callback]);
15595 };
15596
15597 /**
15598 * Returns a function to be used to score individual results.
15599 *
15600 * Good matches will have a higher score than poor matches.
15601 * If an item is not a match, 0 will be returned by the function.
15602 *
15603 * @param {object|string} search
15604 * @param {object} options (optional)
15605 * @returns {function}
15606 */
15607 Sifter.prototype.getScoreFunction = function(search, options) {
15608 var self, fields, tokens, token_count, nesting;
15609
15610 self = this;
15611 search = self.prepareSearch(search, options);
15612 tokens = search.tokens;
15613 fields = search.options.fields;
15614 token_count = tokens.length;
15615 nesting = search.options.nesting;
15616
15617 /**
15618 * Calculates how close of a match the
15619 * given value is against a search token.
15620 *
15621 * @param {mixed} value
15622 * @param {object} token
15623 * @return {number}
15624 */
15625 var scoreValue = function(value, token) {
15626 var score, pos;
15627
15628 if (!value) return 0;
15629 value = String(value || '');
15630 pos = value.search(token.regex);
15631 if (pos === -1) return 0;
15632 score = token.string.length / value.length;
15633 if (pos === 0) score += 0.5;
15634 return score;
15635 };
15636
15637 /**
15638 * Calculates the score of an object
15639 * against the search query.
15640 *
15641 * @param {object} token
15642 * @param {object} data
15643 * @return {number}
15644 */
15645 var scoreObject = (function() {
15646 var field_count = fields.length;
15647 if (!field_count) {
15648 return function() { return 0; };
15649 }
15650 if (field_count === 1) {
15651 return function(token, data) {
15652 return scoreValue(getattr(data, fields[0], nesting), token);
15653 };
15654 }
15655 return function(token, data) {
15656 for (var i = 0, sum = 0; i < field_count; i++) {
15657 sum += scoreValue(getattr(data, fields[i], nesting), token);
15658 }
15659 return sum / field_count;
15660 };
15661 })();
15662
15663 if (!token_count) {
15664 return function() { return 0; };
15665 }
15666 if (token_count === 1) {
15667 return function(data) {
15668 return scoreObject(tokens[0], data);
15669 };
15670 }
15671
15672 if (search.options.conjunction === 'and') {
15673 return function(data) {
15674 var score;
15675 for (var i = 0, sum = 0; i < token_count; i++) {
15676 score = scoreObject(tokens[i], data);
15677 if (score <= 0) return 0;
15678 sum += score;
15679 }
15680 return sum / token_count;
15681 };
15682 } else {
15683 return function(data) {
15684 for (var i = 0, sum = 0; i < token_count; i++) {
15685 sum += scoreObject(tokens[i], data);
15686 }
15687 return sum / token_count;
15688 };
15689 }
15690 };
15691
15692 /**
15693 * Returns a function that can be used to compare two
15694 * results, for sorting purposes. If no sorting should
15695 * be performed, `null` will be returned.
15696 *
15697 * @param {string|object} search
15698 * @param {object} options
15699 * @return function(a,b)
15700 */
15701 Sifter.prototype.getSortFunction = function(search, options) {
15702 var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort;
15703
15704 self = this;
15705 search = self.prepareSearch(search, options);
15706 sort = (!search.query && options.sort_empty) || options.sort;
15707
15708 /**
15709 * Fetches the specified sort field value
15710 * from a search result item.
15711 *
15712 * @param {string} name
15713 * @param {object} result
15714 * @return {mixed}
15715 */
15716 get_field = function(name, result) {
15717 if (name === '$score') return result.score;
15718 return getattr(self.items[result.id], name, options.nesting);
15719 };
15720
15721 // parse options
15722 fields = [];
15723 if (sort) {
15724 for (i = 0, n = sort.length; i < n; i++) {
15725 if (search.query || sort[i].field !== '$score') {
15726 fields.push(sort[i]);
15727 }
15728 }
15729 }
15730
15731 // the "$score" field is implied to be the primary
15732 // sort field, unless it's manually specified
15733 if (search.query) {
15734 implicit_score = true;
15735 for (i = 0, n = fields.length; i < n; i++) {
15736 if (fields[i].field === '$score') {
15737 implicit_score = false;
15738 break;
15739 }
15740 }
15741 if (implicit_score) {
15742 fields.unshift({field: '$score', direction: 'desc'});
15743 }
15744 } else {
15745 for (i = 0, n = fields.length; i < n; i++) {
15746 if (fields[i].field === '$score') {
15747 fields.splice(i, 1);
15748 break;
15749 }
15750 }
15751 }
15752
15753 multipliers = [];
15754 for (i = 0, n = fields.length; i < n; i++) {
15755 multipliers.push(fields[i].direction === 'desc' ? -1 : 1);
15756 }
15757
15758 // build function
15759 fields_count = fields.length;
15760 if (!fields_count) {
15761 return null;
15762 } else if (fields_count === 1) {
15763 field = fields[0].field;
15764 multiplier = multipliers[0];
15765 return function(a, b) {
15766 return multiplier * cmp(
15767 get_field(field, a),
15768 get_field(field, b)
15769 );
15770 };
15771 } else {
15772 return function(a, b) {
15773 var i, result, a_value, b_value, field;
15774 for (i = 0; i < fields_count; i++) {
15775 field = fields[i].field;
15776 result = multipliers[i] * cmp(
15777 get_field(field, a),
15778 get_field(field, b)
15779 );
15780 if (result) return result;
15781 }
15782 return 0;
15783 };
15784 }
15785 };
15786
15787 /**
15788 * Parses a search query and returns an object
15789 * with tokens and fields ready to be populated
15790 * with results.
15791 *
15792 * @param {string} query
15793 * @param {object} options
15794 * @returns {object}
15795 */
15796 Sifter.prototype.prepareSearch = function(query, options) {
15797 if (typeof query === 'object') return query;
15798
15799 options = extend({}, options);
15800
15801 var option_fields = options.fields;
15802 var option_sort = options.sort;
15803 var option_sort_empty = options.sort_empty;
15804
15805 if (option_fields && !is_array(option_fields)) options.fields = [option_fields];
15806 if (option_sort && !is_array(option_sort)) options.sort = [option_sort];
15807 if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty];
15808
15809 return {
15810 options : options,
15811 query : String(query || '').toLowerCase(),
15812 tokens : this.tokenize(query),
15813 total : 0,
15814 items : []
15815 };
15816 };
15817
15818 /**
15819 * Searches through all items and returns a sorted array of matches.
15820 *
15821 * The `options` parameter can contain:
15822 *
15823 * - fields {string|array}
15824 * - sort {array}
15825 * - score {function}
15826 * - filter {bool}
15827 * - limit {integer}
15828 *
15829 * Returns an object containing:
15830 *
15831 * - options {object}
15832 * - query {string}
15833 * - tokens {array}
15834 * - total {int}
15835 * - items {array}
15836 *
15837 * @param {string} query
15838 * @param {object} options
15839 * @returns {object}
15840 */
15841 Sifter.prototype.search = function(query, options) {
15842 var self = this, value, score, search, calculateScore;
15843 var fn_sort;
15844 var fn_score;
15845
15846 search = this.prepareSearch(query, options);
15847 options = search.options;
15848 query = search.query;
15849
15850 // generate result scoring function
15851 fn_score = options.score || self.getScoreFunction(search);
15852
15853 // perform search and sort
15854 if (query.length) {
15855 self.iterator(self.items, function(item, id) {
15856 score = fn_score(item);
15857 if (options.filter === false || score > 0) {
15858 search.items.push({'score': score, 'id': id});
15859 }
15860 });
15861 } else {
15862 self.iterator(self.items, function(item, id) {
15863 search.items.push({'score': 1, 'id': id});
15864 });
15865 }
15866
15867 fn_sort = self.getSortFunction(search, options);
15868 if (fn_sort) search.items.sort(fn_sort);
15869
15870 // apply limits
15871 search.total = search.items.length;
15872 if (typeof options.limit === 'number') {
15873 search.items = search.items.slice(0, options.limit);
15874 }
15875
15876 return search;
15877 };
15878
15879 // utilities
15880 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15881
15882 var cmp = function(a, b) {
15883 if (typeof a === 'number' && typeof b === 'number') {
15884 return a > b ? 1 : (a < b ? -1 : 0);
15885 }
15886 a = asciifold(String(a || ''));
15887 b = asciifold(String(b || ''));
15888 if (a > b) return 1;
15889 if (b > a) return -1;
15890 return 0;
15891 };
15892
15893 var extend = function(a, b) {
15894 var i, n, k, object;
15895 for (i = 1, n = arguments.length; i < n; i++) {
15896 object = arguments[i];
15897 if (!object) continue;
15898 for (k in object) {
15899 if (object.hasOwnProperty(k)) {
15900 a[k] = object[k];
15901 }
15902 }
15903 }
15904 return a;
15905 };
15906
15907 /**
15908 * A property getter resolving dot-notation
15909 * @param {Object} obj The root object to fetch property on
15910 * @param {String} name The optionally dotted property name to fetch
15911 * @param {Boolean} nesting Handle nesting or not
15912 * @return {Object} The resolved property value
15913 */
15914 var getattr = function(obj, name, nesting) {
15915 if (!obj || !name) return;
15916 if (!nesting) return obj[name];
15917 var names = name.split(".");
15918 while(names.length && (obj = obj[names.shift()]));
15919 return obj;
15920 };
15921
15922 var trim = function(str) {
15923 return (str + '').replace(/^\s+|\s+$|/g, '');
15924 };
15925
15926 var escape_regex = function(str) {
15927 return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
15928 };
15929
15930 var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function(object) {
15931 return Object.prototype.toString.call(object) === '[object Array]';
15932 };
15933
15934 var DIACRITICS = {
15935 'a': '[aḀḁĂăÂâǍǎȺⱥȦȧẠạÄäÀàÁáĀāÃãÅåąĄÃąĄ]',
15936 'b': '[b␢βΒB฿𐌁ᛒ]',
15937 'c': '[cĆćĈĉČčĊċC̄c̄ÇçḈḉȻȼƇƈɕᴄCc]',
15938 'd': '[dĎďḊḋḐḑḌḍḒḓḎḏĐđD̦d̦ƉɖƊɗƋƌᵭᶁᶑȡᴅDdð]',
15939 'e': '[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀềỄễỂểḜḝḖḗḔḕȆȇẸẹỆệⱸᴇEeɘǝƏƐε]',
15940 'f': '[fƑƒḞḟ]',
15941 'g': '[gɢ₲ǤǥĜĝĞğĢģƓɠĠġ]',
15942 'h': '[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]',
15943 'i': '[iÍíÌìĬĭÎîǏǐÏïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪIi]',
15944 'j': '[jȷĴĵɈɉʝɟʲ]',
15945 'k': '[kƘƙꝀꝁḰḱǨǩḲḳḴḵκϰ₭]',
15946 'l': '[lŁłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟLl]',
15947 'n': '[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲȠƞᵰᶇɳȵɴNnŊŋ]',
15948 'o': '[oØøÖöÓóÒòÔôǑǒŐőŎŏȮȯỌọƟɵƠơỎỏŌōÕõǪǫȌȍՕօ]',
15949 'p': '[pṔṕṖṗⱣᵽƤƥᵱ]',
15950 'q': '[qꝖꝗʠɊɋꝘꝙq̃]',
15951 'r': '[rŔŕɌɍŘřŖŗṘṙȐȑȒȓṚṛⱤɽ]',
15952 's': '[sŚśṠṡṢṣꞨꞩŜŝŠšŞşȘșS̈s̈]',
15953 't': '[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]',
15954 'u': '[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]',
15955 'v': '[vṼṽṾṿƲʋꝞꝟⱱʋ]',
15956 'w': '[wẂẃẀẁŴŵẄẅẆẇẈẉ]',
15957 'x': '[xẌẍẊẋχ]',
15958 'y': '[yÝýỲỳŶŷŸÿỸỹẎẏỴỵɎɏƳƴ]',
15959 'z': '[zŹźẐẑŽžŻżẒẓẔẕƵƶ]'
15960 };
15961
15962 var asciifold = (function() {
15963 var i, n, k, chunk;
15964 var foreignletters = '';
15965 var lookup = {};
15966 for (k in DIACRITICS) {
15967 if (DIACRITICS.hasOwnProperty(k)) {
15968 chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1);
15969 foreignletters += chunk;
15970 for (i = 0, n = chunk.length; i < n; i++) {
15971 lookup[chunk.charAt(i)] = k;
15972 }
15973 }
15974 }
15975 var regexp = new RegExp('[' + foreignletters + ']', 'g');
15976 return function(str) {
15977 return str.replace(regexp, function(foreignletter) {
15978 return lookup[foreignletter];
15979 }).toLowerCase();
15980 };
15981 })();
15982
15983
15984 // export
15985 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15986
15987 return Sifter;
15988}));
15989
15990
15991/**
15992 * General utilities module
15993 *
15994 * @copyright Copyright (c) WHMCS Limited 2005-2017
15995 * @license http://www.whmcs.com/license/ WHMCS Eula
15996 */
15997(function(module) {
15998 if (!WHMCS.hasModule('utils')) {
15999 WHMCS.loadModule('utils', module);
16000 }
16001})(
16002function () {
16003 /**
16004 * Not crypto strong; server-side must discard for
16005 * something with more entropy; the value is sufficient
16006 * for strong client-side validation check
16007 */
16008 this.simpleRNG = function () {
16009 var chars = './$_-#!,^*()|';
16010 var r = 0;
16011 for (var i = 0; r < 3; i++) {
16012 r += Math.floor((Math.random() * 10) / 2);
16013 }
16014 r = Math.floor(r);
16015 var s = '';
16016 for (var x = 0; x < r; x++) {
16017 v = (Math.random() + 1).toString(24).split('.')[1];
16018 if ((Math.random()) > 0.5) {
16019 s += btoa(v).substr(0,4)
16020 } else {
16021 s += v
16022 }
16023
16024 if ((Math.random()) > 0.5) {
16025 s += chars.substr(
16026 Math.floor(Math.random() * 13),
16027 1
16028 );
16029 }
16030 }
16031
16032 return s;
16033 };
16034
16035 this.getRouteUrl = function (path) {
16036 return whmcsBaseUrl + "/index.php?rp=" + path;
16037 };
16038
16039 this.validateBaseUrl = function() {
16040 if (typeof window.whmcsBaseUrl === 'undefined') {
16041 console.log('Warning: The WHMCS Base URL definition is missing '
16042 + 'from your active template. Please refer to '
16043 + 'https://docs.whmcs.com/WHMCS_Base_URL_Template_Variable '
16044 + 'for more information and details of how to resolve this '
16045 + 'warning.');
16046 window.whmcsBaseUrl = this.autoDetermineBaseUrl();
16047 window.whmcsBaseUrlAutoSet = true;
16048 } else if (window.whmcsBaseUrl === ''
16049 && typeof window.whmcsBaseUrlAutoSet !== 'undefined'
16050 && window.whmcsBaseUrlAutoSet === true
16051 ) {
16052 window.whmcsBaseUrl = this.autoDetermineBaseUrl();
16053 }
16054 };
16055
16056 this.autoDetermineBaseUrl = function() {
16057 var windowLocation = window.location.href;
16058 var phpExtensionLocation = -1;
16059
16060 if (typeof windowLocation !== 'undefined') {
16061 phpExtensionLocation = windowLocation.indexOf('.php');
16062 }
16063
16064 if (phpExtensionLocation === -1) {
16065 windowLocation = jQuery('#Primary_Navbar-Home a').attr('href');
16066 if (typeof windowLocation !== 'undefined') {
16067 phpExtensionLocation = windowLocation.indexOf('.php');
16068 }
16069 }
16070
16071 if (phpExtensionLocation !== -1) {
16072 windowLocation = windowLocation.substring(0, phpExtensionLocation);
16073 var lastTrailingSlash = windowLocation.lastIndexOf('/');
16074 if (lastTrailingSlash !== false) {
16075 return windowLocation.substring(0, lastTrailingSlash);
16076 }
16077 }
16078
16079 return '';
16080 };
16081
16082 this.normaliseStringValue = function(status) {
16083 return status ? status.toLowerCase().replace(/\s/g, '-') : '';
16084 };
16085
16086 this.generatePassword = function(len) {
16087 var charset = this.getPasswordCharacterSet();
16088 var result = "";
16089 for (var i = 0; len > i; i++)
16090 result += charset[this.randomInt(charset.length)];
16091 return result;
16092 };
16093 this.getPasswordCharacterSet = function() {
16094 var rawCharset = '0123456789'
16095 + 'abcdefghijklmnopqrstuvwxyz'
16096 + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
16097 + '!#$%()*+,-.:;=@_|{ldelim}{rdelim}~';
16098
16099 // Parse UTF-16, remove duplicates, convert to array of strings
16100 var charset = [];
16101 for (var i = 0; rawCharset.length > i; i++) {
16102 var c = rawCharset.charCodeAt(i);
16103 if (0xD800 > c || c >= 0xE000) { // Regular UTF-16 character
16104 var s = rawCharset.charAt(i);
16105 if (charset.indexOf(s) == -1)
16106 charset.push(s);
16107 continue;
16108 }
16109 if (0xDC00 > c ? rawCharset.length > i + 1 : false) { // High surrogate
16110 var d = rawCharset.charCodeAt(i + 1);
16111 if (d >= 0xDC00 ? 0xE000 > d : false) { // Low surrogate
16112 var s = rawCharset.substring(i, i + 2);
16113 i++;
16114 if (charset.indexOf(s) == -1)
16115 charset.push(s);
16116 continue;
16117 }
16118 }
16119 throw "Invalid UTF-16";
16120 }
16121 return charset;
16122 };
16123 this.randomInt = function(n) {
16124 var x = this.randomIntMathRandom(n);
16125 x = (x + this.randomIntBrowserCrypto(n)) % n;
16126 return x;
16127 };
16128 this.randomIntMathRandom = function(n) {
16129 var x = Math.floor(Math.random() * n);
16130 if (0 > x || x >= n)
16131 throw "Arithmetic exception";
16132 return x;
16133 };
16134 this.randomIntBrowserCrypto = function(n) {
16135 var cryptoObject = null;
16136
16137 if ("crypto" in window)
16138 cryptoObject = crypto;
16139 else if ("msCrypto" in window)
16140 cryptoObject = msCrypto;
16141 else
16142 return 0;
16143
16144 if (!("getRandomValues" in cryptoObject) || !("Uint32Array" in window) || typeof Uint32Array != "function")
16145 cryptoObject = null;
16146
16147 if (cryptoObject == null)
16148 return 0;
16149
16150 // Generate an unbiased sample
16151 var x = new Uint32Array(1);
16152 do cryptoObject.getRandomValues(x);
16153 while (x[0] - x[0] % n > 4294967296 - n);
16154 return x[0] % n;
16155 };
16156
16157 return this;
16158});
16159
16160WHMCS.utils.validateBaseUrl();
16161
16162/**
16163 * Javascript functions utilised by the client area templates.
16164 *
16165 * @file WHMCS Six Theme Javascript Library
16166 * @copyright Copyright 2015 WHMCS Limited
16167 */
16168
16169jQuery(document).ready(function() {
16170
16171 if (jQuery('#lightbox').length === 0) {
16172 lightbox.init();
16173 }
16174
16175 // Language chooser popover
16176 jQuery('#languageChooser').popover({
16177 container: 'body',
16178 placement: 'bottom',
16179 template: '<div class="popover language-popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>',
16180 html: true,
16181 content: function() {
16182 return jQuery("#languageChooserContent").html();
16183 },
16184 });
16185
16186 // Login or register popover
16187 jQuery('#loginOrRegister').popover({
16188 container: 'body',
16189 placement: 'bottom',
16190 template: '<div class="popover login-popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>',
16191 html: true,
16192 content: function() {
16193 return jQuery("#loginOrRegisterContent").html();
16194 },
16195 });
16196
16197 // Account notifications popover
16198 jQuery("#accountNotifications").popover({
16199 container: 'body',
16200 placement: 'bottom',
16201 template: '<div class="popover popover-user-notifications" role="tooltip"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>',
16202 html: true,
16203 content: function() {
16204 return jQuery("#accountNotificationsContent").html();
16205 },
16206 });
16207
16208 jQuery('.panel-sidebar .truncate').each(function () {
16209 jQuery(this).attr('title', jQuery(this).text())
16210 .attr('data-toggle', 'tooltip')
16211 .attr('data-placement', 'bottom');
16212 });
16213
16214 // Default catch for all other popovers
16215 jQuery('[data-toggle="popover"]').popover({
16216 html: true
16217 });
16218
16219 // Enable tooltips
16220 // Attach function to body so tooltips inserted by ajax will load
16221 jQuery(function(jQuery){
16222 jQuery('body').tooltip({
16223 selector: '[data-toggle="tooltip"]'
16224 });
16225 });
16226
16227 // Logic to dismiss popovers on click outside
16228 jQuery('body').on('click', function (e) {
16229 jQuery('[data-toggle="popover"]').each(function () {
16230 if (!jQuery(this).is(e.target) && jQuery(this).has(e.target).length === 0 && jQuery('.popover').has(e.target).length === 0) {
16231 jQuery(this).popover('hide');
16232 }
16233 });
16234 });
16235
16236 // Sidebar active class toggle
16237 jQuery(".list-group-tab-nav a").click(function() {
16238 if (jQuery(this).hasClass('disabled')) {
16239 return false;
16240 }
16241 jQuery(".list-group-tab-nav a").removeClass('active');
16242 jQuery(this).addClass('active');
16243 var urlFragment = this.href.split('#')[1];
16244 if (urlFragment) {
16245 // set the fragment in the URL bar for bookmarking and such.
16246 window.location.hash = '#' + urlFragment;
16247 }
16248 });
16249
16250 // Sidebar minimise/maximise
16251 jQuery('.panel-minimise').click(function(e) {
16252 e.preventDefault();
16253 if (jQuery(this).hasClass('minimised')) {
16254 jQuery(this).parents('.panel').find('.panel-body, .list-group').slideDown();
16255 jQuery(this).removeClass('minimised');
16256 } else {
16257 jQuery(this).parents('.panel').find('.panel-body, .list-group').slideUp();
16258 jQuery(this).addClass('minimised');
16259 }
16260 });
16261
16262 // Minimise sidebar panels by default on small devices
16263 if (jQuery('.container').width() <= 720) {
16264 jQuery('.panel-sidebar').find('.panel-body, .list-group').hide();
16265 jQuery('.panel-sidebar').find('.panel-minimise').addClass('minimised');
16266 }
16267
16268 // Internal page tab selection handling via location hash
16269 if (jQuery(location).attr('hash').substr(1) != "") {
16270 var activeTab = jQuery(location).attr('hash');
16271 jQuery(".tab-pane").removeClass('active');
16272 jQuery(activeTab).removeClass('fade').addClass('active');
16273 jQuery(".list-group-tab-nav a").removeClass('active');
16274 jQuery('a[href="' + activeTab + '"]').addClass('active');
16275 setTimeout(function() {
16276 // Browsers automatically scroll on page load with a fragment.
16277 // This scrolls back to the top right after page complete, but
16278 // just before render (no perceptible scroll).
16279 window.scrollTo(0, 0);
16280 }, 1);
16281 }
16282
16283 // Enable Switches for Checkboxes
16284 if (jQuery.prototype.bootstrapSwitch) {
16285 jQuery(".toggle-switch-success").bootstrapSwitch({
16286 onColor: 'success'
16287 });
16288 }
16289
16290 // Collapsable Panels
16291 jQuery(".panel-collapsable .panel-heading").click(function(e) {
16292 var $this = jQuery(this);
16293 if (!$this.parents('.panel').hasClass('panel-collapsed')) {
16294 $this.parents('.panel').addClass('panel-collapsed').find('.panel-body').slideUp();
16295 $this.find('.collapse-icon i').removeClass('fa-minus').addClass('fa-plus');
16296 } else {
16297 $this.parents('.panel').removeClass('panel-collapsed').find('.panel-body').slideDown();
16298 $this.find('.collapse-icon i').removeClass('fa-plus').addClass('fa-minus');
16299 }
16300 });
16301
16302 // Two-Factor Authentication Auto Focus Rules
16303 if (("#frmLogin").length > 0) {
16304 jQuery("#frmLogin input:text:visible:first").focus();
16305 }
16306 if (("#twofaactivation").length > 0) {
16307 jQuery("#twofaactivation input:text:visible:first,#twofaactivation input:password:visible:first").focus();
16308 }
16309
16310 // Sub-Account Activation Toggle
16311 jQuery("#inputSubaccountActivate").click(function () {
16312 if (jQuery("#inputSubaccountActivate:checked").val() != null) {
16313 jQuery("#subacct-container").removeClass('hidden');
16314 } else {
16315 jQuery("#subacct-container").addClass('hidden');
16316 }
16317 });
16318
16319 // Mass Domain Management Bulk Action Handling
16320 jQuery(".setBulkAction").click(function(event) {
16321 event.preventDefault();
16322 var id = jQuery(this).attr('id').replace('Link', ''),
16323 domainForm = jQuery('#domainForm');
16324
16325 if (id === 'renewDomains') {
16326 domainForm.attr('action', WHMCS.utils.getRouteUrl('/cart/domain/renew'));
16327 } else {
16328 if (jQuery('#' + id).length !== 0) {
16329 var action = domainForm.attr('action');
16330 domainForm.attr('action', action + '#' + id);
16331 }
16332 jQuery('#bulkaction').val(id);
16333 }
16334 domainForm.submit();
16335 });
16336
16337 // Stop events on objects with this class from bubbling up the dom
16338 jQuery('.stopEventBubble').click( function(event) {
16339 event.stopPropagation();
16340 });
16341
16342 // Tab Control Link handling for tab switching via regular links
16343 jQuery('.tabControlLink').on(
16344 'click',
16345 function(event) {
16346 event.preventDefault();
16347 var id = jQuery(this).attr('href');
16348 jQuery("a[href='/"+id+"']").click();
16349 }
16350 );
16351
16352 jQuery(document).on('click', '.delete-cc-email', function() {
16353 var self = jQuery(this),
16354 email = self.data('email'),
16355 feedback = jQuery('#divCcEmailFeedback');
16356
16357 if (feedback.is(':visible')) {
16358 feedback.slideUp('fast');
16359 }
16360
16361 WHMCS.http.jqClient.jsonPost({
16362 url: window.location.href,
16363 data: {
16364 action: 'delete',
16365 email: email,
16366 token: csrfToken
16367 },
16368 success: function (data) {
16369 if (data.success) {
16370 self.closest('.ticket-cc-email').parent('div').slideUp('fast').remove();
16371 feedback.slideUp('fast')
16372 .removeClass('alert-danger hidden')
16373 .addClass('alert-success')
16374 .html(data.message)
16375 .slideDown('fast');
16376 }
16377 },
16378 error: function (error) {
16379 if (error) {
16380 feedback.slideUp('fast')
16381 .removeClass('alert-success hidden')
16382 .addClass('alert-danger')
16383 .html(error)
16384 .slideDown('fast');
16385 }
16386 }
16387 });
16388 }).on('submit', '#frmAddCcEmail', function(e) {
16389 e.preventDefault();
16390 var frm = jQuery(this),
16391 cloneRow = jQuery('#ccCloneRow').clone().removeAttr('id'),
16392 email = jQuery('#inputAddCcEmail'),
16393 feedback = jQuery('#divCcEmailFeedback');
16394
16395 if (feedback.is(':visible')) {
16396 feedback.slideUp('fast');
16397 }
16398 WHMCS.http.jqClient.jsonPost({
16399 url: frm.attr('action'),
16400 data: frm.serialize(),
16401 success: function (data) {
16402 if (data.success) {
16403 cloneRow.find('span.email')
16404 .html(email.val())
16405 .find('button')
16406 .data('email', email.val())
16407 .end();
16408
16409 cloneRow.removeClass('hidden')
16410 .appendTo(jQuery('#sidebarTicketCc').find('.list-group'));
16411 email.val('');
16412 feedback.slideUp('fast')
16413 .removeClass('alert-danger hidden')
16414 .addClass('alert-success')
16415 .html(data.message)
16416 .slideDown('fast');
16417 }
16418 },
16419 error: function (error) {
16420 if (error) {
16421 feedback.slideUp('fast')
16422 .removeClass('alert-success hidden')
16423 .addClass('alert-danger')
16424 .html(error)
16425 .slideDown('fast');
16426 }
16427 }
16428 });
16429 });
16430
16431 // Ticket Rating Click Handler
16432 jQuery('.ticket-reply .rating span.star').click( function(event) {
16433 window.location = 'viewticket.php?tid='
16434 + jQuery(this).parent('.rating').attr("ticketid")
16435 + '&c=' + jQuery(this).parent('.rating').attr("ticketkey")
16436 + '&rating=rate' + jQuery(this).parent('.rating').attr("ticketreplyid")
16437 + '_' + jQuery(this).attr("rate");
16438 });
16439
16440 // Prevent malicious window.opener activity from auto-linked URLs
16441 jQuery('a.autoLinked').click(function (e) {
16442 e.preventDefault();
16443 if (jQuery(this).hasClass('disabled')) {
16444 return false;
16445 }
16446
16447 var child = window.open();
16448 child.opener = null;
16449 child.location = e.target.href;
16450 });
16451
16452 // Handle Single Sign-On Toggle Setting
16453 jQuery("#inputAllowSso").on('switchChange.bootstrapSwitch', function(event, isChecked) {
16454 if (isChecked) {
16455 jQuery("#ssoStatusTextEnabled").removeClass('hidden').show();
16456 jQuery("#ssoStatusTextDisabled").hide();
16457 } else {
16458 jQuery("#ssoStatusTextDisabled").removeClass('hidden').show();
16459 jQuery("#ssoStatusTextEnabled").hide();
16460 }
16461 WHMCS.http.jqClient.post("clientarea.php", jQuery("#frmSingleSignOn").serialize());
16462 });
16463
16464 // Single Sign-On call for Product/Service
16465 jQuery('.btn-service-sso').on('click', function(e) {
16466 e.preventDefault();
16467 var button = jQuery(this);
16468
16469 var form = button.parents('form');
16470
16471 if (form.length === 0) {
16472 form = button.find('form');
16473 }
16474 if (form.hasClass('disabled') || button.hasClass('disabled')) {
16475 return;
16476 }
16477 var url = form.data('href');
16478 if (!url) {
16479 url = window.location.href;
16480 }
16481
16482 button.attr('disabled', 'disabled').addClass('disabled');
16483 jQuery('.loading', button).removeClass('hidden').show().end();
16484 jQuery('.login-feedback', form).slideUp();
16485 WHMCS.http.jqClient.post(
16486 url,
16487 form.serialize(),
16488 function (data) {
16489 jQuery('.loading', button).hide().end().removeAttr('disabled');
16490 jQuery('.login-feedback', form).html('');
16491 if (data.error) {
16492 jQuery('.login-feedback', form).hide().html(data.error).slideDown();
16493 }
16494 if (data.redirect !== undefined && data.redirect.substr(0, 7) === 'window|') {
16495 window.open(data.redirect.substr(7), '_blank');
16496 }
16497 },
16498 'json'
16499 ).always(function() {
16500 button.removeAttr('disabled').removeClass('disabled');
16501 jQuery('.loading', button).hide().end();
16502 });
16503 });
16504 jQuery('.btn-sidebar-form-submit').on('click', function(e) {
16505 e.preventDefault();
16506 jQuery(this).find('.loading').removeClass('hidden').show().end()
16507 .attr('disabled', 'disabled');
16508
16509 var form = jQuery(this).parents('form');
16510
16511 if (form.length == 0) {
16512 form = jQuery(this).find('form');
16513 }
16514
16515 if (form.length !== 0 && form.hasClass('disabled') === false) {
16516 form.submit();
16517 } else {
16518 jQuery(this).find('.loading').hide().end().removeAttr('disabled');
16519 }
16520 });
16521
16522 // Back to top animated scroll
16523 jQuery('.back-to-top').click(function(e) {
16524 e.preventDefault();
16525 jQuery('body,html').animate({scrollTop: 0}, 500);
16526 });
16527
16528 // Prevent page scroll on language choose click
16529 jQuery('.choose-language').click(function(e) {
16530 e.preventDefault();
16531 });
16532
16533 // Activate copy to clipboard functionality
16534 jQuery('.copy-to-clipboard').click(WHMCS.ui.clipboard.copy);
16535
16536 // Password Generator
16537 jQuery('.generate-password').click(function(e) {
16538 jQuery('#frmGeneratePassword').submit();
16539 jQuery('#modalGeneratePassword')
16540 .data('targetfields', jQuery(this).data('targetfields'))
16541 .modal('show');
16542 });
16543 jQuery('#frmGeneratePassword').submit(function(e) {
16544 e.preventDefault();
16545 var length = parseInt(jQuery('#inputGeneratePasswordLength').val(), 10);
16546
16547 // Check length
16548 if (length < 8 || length > 64) {
16549 jQuery('#generatePwLengthError').removeClass('hidden').show();
16550 return;
16551 }
16552
16553 jQuery('#inputGeneratePasswordOutput').val(WHMCS.utils.generatePassword(length));
16554 });
16555 jQuery('#btnGeneratePasswordInsert')
16556 .click(WHMCS.ui.clipboard.copy)
16557 .click(function(e) {
16558 jQuery(this).closest('.modal').modal('hide');
16559 var targetFields = jQuery(this).closest('.modal').data('targetfields');
16560 targetFields = targetFields.split(',');
16561 for(var i = 0; i < targetFields.length; i++) {
16562 jQuery('#' + targetFields[i]).val(jQuery('#inputGeneratePasswordOutput').val())
16563 .trigger('keyup');
16564 }
16565 // Remove the generated password.
16566 jQuery('#inputGeneratePasswordOutput').val('');
16567 });
16568
16569 /**
16570 * Code will loop through each element that has the class markdown-editor and
16571 * enable the Markdown editor.
16572 */
16573 var count = 0,
16574 editorName = 'clientMDE',
16575 counter = 0;
16576 jQuery(".markdown-editor").each(function( index ) {
16577 count++;
16578 var autoSaveName = jQuery(this).data('auto-save-name'),
16579 footerId = jQuery(this).attr('id') + '-footer';
16580 if (typeof autoSaveName == "undefined") {
16581 autoSaveName = 'client_area';
16582 }
16583 window[editorName + count.toString()] = jQuery(this).markdown(
16584 {
16585 footer: '<div id="' + footerId + '" class="markdown-editor-status"></div>',
16586 autofocus: false,
16587 savable: false,
16588 resize: 'vertical',
16589 iconlibrary: 'glyph',
16590 language: locale,
16591 onShow: function(e){
16592 var content = '',
16593 save_enabled = false;
16594 if(typeof(Storage) !== "undefined") {
16595 // Code for localStorage/sessionStorage.
16596 content = localStorage.getItem(autoSaveName);
16597 save_enabled = true;
16598 if (content && typeof(content) !== "undefined") {
16599 e.setContent(content);
16600 }
16601 }
16602 jQuery("#" + footerId).html(parseMdeFooter(content, save_enabled, saved));
16603 },
16604 onChange: function(e){
16605 var content = e.getContent(),
16606 save_enabled = false;
16607 if(typeof(Storage) !== "undefined") {
16608 counter = 3;
16609 save_enabled = true;
16610 localStorage.setItem(autoSaveName, content);
16611 doCountdown();
16612 }
16613 jQuery("#" + footerId).html(parseMdeFooter(content, save_enabled));
16614 },
16615 onPreview: function(e){
16616 var originalContent = e.getContent(),
16617 parsedContent;
16618
16619 jQuery.ajax({
16620 url: WHMCS.utils.getRouteUrl('/clientarea/message/preview'),
16621 async: false,
16622 data: {token: csrfToken, content: originalContent},
16623 dataType: 'json',
16624 success: function (data) {
16625 parsedContent = data;
16626 }
16627 });
16628
16629 return parsedContent.body ? parsedContent.body : '';
16630 },
16631 additionalButtons: [
16632 [{
16633 name: "groupCustom",
16634 data: [{
16635 name: "cmdHelp",
16636 title: "Help",
16637 hotkey: "Ctrl+F1",
16638 btnClass: "btn open-modal",
16639 icon: {
16640 glyph: 'fas fa-question-circle',
16641 fa: 'fas fa-question-circle',
16642 'fa-3': 'icon-question-sign'
16643 },
16644 callback: function(e) {
16645 e.$editor.removeClass("md-fullscreen-mode");
16646 }
16647 }]
16648 }]
16649 ],
16650 hiddenButtons: [
16651 'cmdImage'
16652 ]
16653 });
16654
16655 jQuery('button[data-handler="bootstrap-markdown-cmdHelp"]')
16656 .attr('data-modal-title', markdownGuide)
16657 .attr('href', 'submitticket.php?action=markdown');
16658
16659 jQuery(this).closest("form").bind({
16660 submit: function() {
16661 if(typeof(Storage) !== "undefined") {
16662 localStorage.removeItem(autoSaveName);
16663 }
16664 }
16665 });
16666 });
16667
16668 // Email verification
16669 var btnResendEmail = jQuery('.btn-resend-verify-email');
16670 jQuery(btnResendEmail).click(function() {
16671 $(this).prop('disabled', true).find('.loader').removeClass('hidden').show();
16672 WHMCS.http.jqClient.post(
16673 jQuery(this).data('uri'),
16674 {
16675 'token': csrfToken,
16676 }).done(function(data) {
16677 btnResendEmail.find('.loader').hide();
16678 if (data.success) {
16679 btnResendEmail.text(btnResendEmail.data('email-sent'));
16680 } else {
16681 btnResendEmail.text(btnResendEmail.data('error-msg'));
16682 }
16683 });
16684 });
16685 jQuery('#btnEmailVerificationClose').click(function(e) {
16686 e.preventDefault();
16687 WHMCS.http.jqClient.post(jQuery(this).data('uri'),
16688 {
16689 'token': csrfToken
16690 });
16691 jQuery('.verification-banner.email-verification').hide();
16692 });
16693
16694 jQuery('#btnUserValidationClose').click(function(e) {
16695 e.preventDefault();
16696 WHMCS.http.jqClient.post(jQuery(this).data('uri'),
16697 {
16698 'token': csrfToken
16699 });
16700 jQuery('.verification-banner.user-validation').hide();
16701 });
16702
16703 var ssoDropdown = jQuery('#servicesPanel').find('.list-group');
16704 if (parseInt(ssoDropdown.css('height'), 10) < parseInt(ssoDropdown.css('max-height'), 10)) {
16705 ssoDropdown.css('overflow', 'unset');
16706 }
16707
16708
16709 /**
16710 * Parse the content to populate the markdown editor footer.
16711 *
16712 * @param {string} content
16713 * @param {bool} auto_save
16714 * @param {string} [saveText]
16715 * @returns {string}
16716 */
16717 function parseMdeFooter(content, auto_save, saveText)
16718 {
16719 saveText = saveText || saving;
16720 var pattern = /[^\s]+/g,
16721 m = [],
16722 word_count = 0,
16723 line_count = 0;
16724 if (content) {
16725 m = content.match(pattern);
16726 line_count = content.split(/\\r\\n|\\r|\\n/).length;
16727 }
16728 if (m) {
16729 for (var i = 0; i < m.length; i++) {
16730 if (m[i].charCodeAt(0) >= 0x4E00) {
16731 word_count += m[i].length;
16732 } else {
16733 word_count += 1;
16734 }
16735 }
16736 }
16737 return '<div class="small-font">lines: ' + line_count
16738 + ' words: ' + word_count + ''
16739 + (auto_save ? ' <span class="markdown-save">' + saveText + '</span>' : '')
16740 + '</div>';
16741 }
16742
16743 /**
16744 * Countdown the save timeout. When zero, the span will update to show saved.
16745 */
16746 function doCountdown()
16747 {
16748 if (counter >= 0) {
16749 if (counter == 0) {
16750 jQuery("span.markdown-save").html(saved);
16751 }
16752 counter--;
16753 setTimeout(doCountdown, 1000);
16754 }
16755 }
16756
16757 // Two-Factor Activation Process Modal Handler.
16758 var frmTwoFactorActivation = jQuery('input[name=2fasetup]').parent('form');
16759 frmTwoFactorActivation.submit(function(e) {
16760 e.preventDefault();
16761 openModal(frmTwoFactorActivation.attr('action'), frmTwoFactorActivation.serialize(), 'Loading...');
16762 });
16763
16764 $.fn.setInputError = function(error) {
16765 this.parents('.form-group').addClass('has-error').find('.field-error-msg').text(error);
16766 return this;
16767 };
16768
16769 jQuery.fn.showInputError = function () {
16770 this.parents('.form-group').addClass('has-error').find('.field-error-msg').show();
16771 return this;
16772 };
16773
16774 jQuery('#frmPayment').on('submit', function() {
16775 var btn = jQuery('#btnSubmit');
16776 btn.find('span').toggle();
16777 btn.prop('disabled', true).addClass('disabled');
16778 });
16779
16780 // SSL Manage Action Button.
16781 jQuery('.btn-resend-approver-email').click(function () {
16782 WHMCS.http.jqClient.post(
16783 jQuery(this).data('url'),
16784 {
16785 addonId: jQuery(this).data('addonid'),
16786 serviceId: jQuery(this).data('serviceid'),
16787 },
16788 function(data) {
16789 if (data.success == true) {
16790 jQuery('.alert-table-ssl-manage').addClass('alert-success').text('Approver Email Resent').removeClass('hidden');
16791 } else {
16792 jQuery('.alert-table-ssl-manage').addClass('alert-danger').text('Error: ' + data.message).removeClass('hidden');
16793 }
16794 }
16795 );
16796 });
16797
16798 // Domain Pricing Table Filters
16799 jQuery(".tld-filters a").click(function(e) {
16800 e.preventDefault();
16801
16802 var noTlds = jQuery('.tld-row.no-tlds');
16803
16804 if (jQuery(this).hasClass('badge-success')) {
16805 jQuery(this).removeClass('badge-success');
16806 } else {
16807 jQuery(this).addClass('badge-success');
16808 }
16809 if (noTlds.is(':visible')) {
16810 noTlds.hide();
16811 }
16812
16813 jQuery('.tld-row').removeClass('filtered-row');
16814 jQuery('.tld-filters a.badge-success').each(function(index) {
16815 var filterValue = jQuery(this).data('category');
16816 jQuery('.tld-row[data-category*="' + filterValue + '"]').addClass('filtered-row');
16817 });
16818 jQuery(".filtered-row:even").removeClass('highlighted');
16819 jQuery(".filtered-row:odd").addClass('highlighted');
16820
16821 var rowsToHide = jQuery('.tld-row:not(".filtered-row")');
16822 rowsToHide.fadeOut('fast');
16823 rowsToHide.promise().done(function () {
16824 if (jQuery('.filtered-row').length === 0) {
16825 noTlds.show();
16826 } else {
16827 jQuery('.tld-row.filtered-row').show();
16828 }
16829 });
16830 });
16831 jQuery(".filtered-row:even").removeClass('highlighted');
16832 jQuery(".filtered-row:odd").addClass('highlighted');
16833
16834 // DataTable data-driven auto object registration
16835 WHMCS.ui.dataTable.register();
16836
16837 WHMCS.ui.jsonForm.initAll();
16838
16839 jQuery('#frmReply').submit(function(e) {
16840 jQuery('#frmReply').find('input[type="submit"]').addClass('disabled').prop('disabled', true);
16841 });
16842
16843 jQuery('#frmDomainContactModification').on('submit', function(){
16844 if (!allowSubmit) {
16845 var changed = false;
16846 jQuery('.irtp-field').each(function() {
16847 var value = jQuery(this).val(),
16848 originalValue = jQuery(this).data('original-value');
16849 if (value !== originalValue) {
16850 changed = true;
16851 }
16852 });
16853 if (changed) {
16854 jQuery('#modalIRTPConfirmation').modal('show');
16855 return false;
16856 }
16857 }
16858 return true;
16859 });
16860
16861 jQuery('.ssl-state.ssl-sync').each(function () {
16862 var self = jQuery(this),
16863 type = getSslAttribute(self, 'type'),
16864 domain = getSslAttribute(self, 'domain');
16865 WHMCS.http.jqClient.post(
16866 WHMCS.utils.getRouteUrl('/domain/ssl-check'),
16867 {
16868 'type': type,
16869 'domain': domain,
16870 'token': csrfToken
16871 },
16872 function (data) {
16873 if (data.invalid) {
16874 self.hide();
16875 } else {
16876 var width = '',
16877 statusDisplayLabel = '';
16878 if (self.attr('width')) {
16879 width = ' width="' + self.attr('width') + '"';
16880 }
16881 if (self.data('showlabel')) {
16882 statusDisplayLabel = ' ' + data.statusDisplayLabel;
16883 }
16884 self.replaceWith(
16885 '<img src="' + data.image + '" data-toggle="tooltip" title="' + data.tooltip + '" class="' + data.class + '"' + width + '>'
16886 );
16887 if (data.ssl.status === 'active') {
16888 jQuery('#ssl-startdate').text(data.ssl.startDate);
16889 jQuery('#ssl-expirydate').text(data.ssl.expiryDate);
16890 jQuery('#ssl-issuer').text(data.ssl.issuer);
16891 } else {
16892 jQuery('#ssl-startdate').parent('div').hide();
16893 jQuery('#ssl-expirydate').parent('div').hide();
16894 jQuery('#ssl-issuer').parent('div').hide();
16895 }
16896
16897 jQuery('#statusDisplayLabel').text(statusDisplayLabel);
16898 }
16899 }
16900 );
16901 });
16902
16903 jQuery(document).on('click', '.ssl-state.ssl-inactive', function(e) {
16904 e.preventDefault();
16905 window.location.href = WHMCS.utils.getRouteUrl('/ssl-purchase');
16906 });
16907
16908 WHMCS.recaptcha.register();
16909
16910 var dynamicRecaptchaContainer = jQuery('#divDynamicRecaptcha');
16911 var homepageHasRecaptcha = jQuery(dynamicRecaptchaContainer).length > 0;
16912 var homepageHasInvisibleRecaptcha = homepageHasRecaptcha && jQuery(dynamicRecaptchaContainer).data('size') === 'invisible';
16913
16914 var frmDomainHomepage = jQuery('#frmDomainHomepage');
16915
16916 jQuery(frmDomainHomepage).find('#btnTransfer').click(function () {
16917 jQuery(frmDomainHomepage).find('input[name="transfer"]').val('1');
16918 });
16919
16920 if (homepageHasRecaptcha && !homepageHasInvisibleRecaptcha) {
16921 jQuery('section#home-banner').addClass('with-recaptcha');
16922 }
16923
16924 if (jQuery('.domainchecker-homepage-captcha').length && !homepageHasInvisibleRecaptcha) {
16925 // invisible reCaptcha doesn't play well with onsubmit() handlers on all submissions following a prevented one
16926
16927 jQuery(frmDomainHomepage).submit(function (e) {
16928 var inputDomain = jQuery(frmDomainHomepage).find('input[name="domain"]'),
16929 reCaptchaContainer = jQuery('#divDynamicRecaptcha'),
16930 reCaptcha = jQuery('#g-recaptcha-response'),
16931 captcha = jQuery('#inputCaptcha');
16932
16933 if (reCaptcha.length && !reCaptcha.val()) {
16934 reCaptchaContainer.tooltip('show');
16935
16936 e.preventDefault();
16937 return;
16938 }
16939
16940 if (captcha.length && !captcha.val()) {
16941 captcha.tooltip('show');
16942
16943 e.preventDefault();
16944 return;
16945 }
16946 });
16947 }
16948
16949 $('.icheck-button').iCheck({
16950 inheritID: true,
16951 checkboxClass: 'icheckbox_square-blue',
16952 radioClass: 'iradio_square-blue',
16953 increaseArea: '20%'
16954 });
16955
16956 jQuery('#inputNoStore').on('switchChange.bootstrapSwitch', function(event, state) {
16957 var descContainer = jQuery('#inputDescription');
16958 if (!state) {
16959 descContainer.prop('disabled', true).addClass('disabled');
16960 }
16961 if (state) {
16962 descContainer.removeClass('disabled').prop('disabled', false);
16963 }
16964 });
16965
16966 jQuery(document).on('click', '#btnConfirmModalConfirmBtn', function () {
16967 var confirmButton = jQuery(this),
16968 confirmationModal = confirmButton.closest('div.modal'),
16969 targetUrl = confirmButton.data('target-url'),
16970 dataTable = confirmButton.closest('table.dataTable[data-on-draw-rebind-confirmation-modal="true"]');
16971 WHMCS.http.jqClient.jsonPost(
16972 {
16973 url: targetUrl,
16974 data: {
16975 token: csrfToken
16976 },
16977 success: function(data) {
16978 if (data.status === 'success' || data.status === 'okay') {
16979 if (dataTable.length > 0) {
16980 dataTable.DataTable().ajax.reload();
16981 }
16982 }
16983 }
16984 }
16985 );
16986 confirmationModal.modal('toggle');
16987 });
16988 jQuery('input[name="approval_method"]').on('ifChecked', function(event) {
16989 var fileMethod = $('#containerApprovalMethodFile'),
16990 emailMethod = $('#containerApprovalMethodEmail'),
16991 dnsMethod = $('#containerApprovalMethodDns');
16992 if (jQuery(this).attr('value') == 'file') {
16993 fileMethod.show();
16994 dnsMethod.hide();
16995 emailMethod.hide();
16996 } else if (jQuery(this).attr('value') == 'dns-txt-token') {
16997 dnsMethod.show();
16998 fileMethod.hide();
16999 emailMethod.hide();
17000 } else {
17001 fileMethod.hide();
17002 dnsMethod.hide();
17003 emailMethod.show();
17004 }
17005 });
17006
17007 (function () {
17008 jQuery('.div-service-status').css(
17009 'width',
17010 (jQuery('.div-service-status .label-placeholder').outerWidth() + 5)
17011 );
17012 jQuery('div[menuitemname="Active Products/Services"] .list-group-item:visible')
17013 .last()
17014 .css('border-bottom', '1px solid #ddd');
17015 }());
17016 jQuery('div[menuitemname="Active Products/Services"] .btn-view-more').on('click', function(event) {
17017 var hiddenItems = jQuery('div[menuitemname="Active Products/Services"] .list-group-item:hidden');
17018 var itemAmount = 8;
17019 event.preventDefault();
17020 hiddenItems.slice(0,itemAmount).css('display', 'block');
17021 if ((hiddenItems.length - itemAmount) <= 0) {
17022 jQuery(event.target).addClass('disabled').attr("aria-disabled", true);
17023 }
17024 jQuery('div[menuitemname="Active Products/Services"] .list-group-item:visible')
17025 .css('border-bottom', '')
17026 .last()
17027 .css('border-bottom', '1px solid #ddd');
17028 })
17029 jQuery('div[menuitemname="Service Details Actions"] a[data-identifier][data-serviceid][data-active="1"]').on('click', function(event) {
17030 return customActionAjaxCall(event, jQuery(event.target))
17031 });
17032 jQuery('.div-service-item').on('click', function (event) {
17033 var element = jQuery(event.target);
17034 if (element.is('.dropdown-toggle, .dropdown-menu, .caret')) {
17035 return true;
17036 }
17037 if (element.hasClass('btn-custom-action')) {
17038 return customActionAjaxCall(event, element);
17039 }
17040 window.location.href = element.closest('.div-service-item').data('href');
17041 return false;
17042 });
17043});
17044
17045/**
17046 * Control disabled/enabled state of elements by class name.
17047 *
17048 * @param {string} className Common element class name.
17049 * @param {bool} disabledState Whether the elements should be disabled or not.
17050 */
17051function disableFields(className, disabledState) {
17052 if (className[0] != '.') {
17053 className = '.' + className;
17054 }
17055 var elements = jQuery(className);
17056 elements.prop('disabled', disabledState);
17057 if (disabledState) {
17058 elements.addClass('disabled');
17059 } else {
17060 elements.removeClass('disabled');
17061 }
17062}
17063
17064/**
17065 * Check all checkboxes with a given class.
17066 *
17067 * @param {string} className Common class name.
17068 * @param {domElement} masterControl Parent checkbox to which the other checkboxes should mirror.
17069 */
17070function checkAll(className, masterControl) {
17071 if (className[0] != '.') {
17072 className = '.' + className;
17073 }
17074 // In jQuery, if you set the checked attribute directly, the dom
17075 // element is changed, but browsers don't show the check box as
17076 // checked. Using the click event will properly display.
17077 jQuery(className).removeAttr('checked');
17078 if(jQuery(masterControl).is(":checked")) {
17079 jQuery(className).click();
17080 }
17081}
17082
17083/**
17084 * Redirect on click if an element is not a button or link.
17085 *
17086 * Where table rows are clickable, we only want to redirect if the row
17087 * itself is clicked. If a button or link within the row is clicked,
17088 * the event tied to that object should be executed. This function
17089 * stops the standard JS event bubbling required to make that happen.
17090 *
17091 * @param {object} clickEvent jQuery click event
17092 * @param {string} target Redirect location
17093 * @param {bool} newWindow Open link in new window
17094 */
17095function clickableSafeRedirect(clickEvent, target, newWindow) {
17096 var eventSource = clickEvent.target.tagName.toLowerCase();
17097 var eventParent = clickEvent.target.parentNode.tagName.toLowerCase();
17098 var eventTable = clickEvent.target.parentNode.parentNode.parentNode;
17099 if (jQuery(eventTable).hasClass('collapsed')) {
17100 // This is a mobile device sized display, and datatables has triggered folding
17101 return false;
17102 }
17103 if (eventSource === 'i' && jQuery(clickEvent.target).hasClass('ssl-required')) {
17104 return false;
17105 }
17106 if(eventSource != 'button' && eventSource != 'a') {
17107 if(eventParent != 'button' && eventParent != 'a') {
17108 if (newWindow) {
17109 window.open(target);
17110 } else {
17111 window.location.href = target;
17112 }
17113 }
17114 }
17115}
17116
17117/**
17118 * Open a centered popup window.
17119 *
17120 * @param {string} addr The URL to navigate to
17121 * @param {string} popname The name to assign the window
17122 * @param {number} w The width
17123 * @param {number} h The height
17124 * @param {string} features Any additional settings to apply
17125 */
17126function popupWindow(addr, popname, w, h, features) {
17127 var winl = (screen.width-w) / 2;
17128 var wint = (screen.height-h) / 2;
17129 if (winl < 0) winl = 0;
17130 if (wint < 0) wint = 0;
17131 var settings = 'height=' + h + ',';
17132 settings += 'width=' + w + ',';
17133 settings += 'top=' + wint + ',';
17134 settings += 'left=' + winl + ',';
17135 settings += features;
17136 win = window.open(addr, popname, settings);
17137 win.window.focus();
17138}
17139
17140/**
17141 * Add domain renewal to shopping cart.
17142 *
17143 * @param {number} renewalID The domain ID to be added
17144 * @param {domElement} selfThis The object triggering the add
17145 */
17146function addRenewalToCart(renewalID, selfThis) {
17147 jQuery("#domainRow" + renewalID).attr('disabled', 'disabled');
17148 jQuery("#domainRow" + renewalID).find("select,button").attr("disabled", "disabled");
17149 jQuery(selfThis).html('<span class="glyphicon glyphicon-shopping-cart"></span> Adding...');
17150 var renewalPeriod = jQuery("#renewalPeriod" + renewalID).val();
17151 WHMCS.http.jqClient.post(
17152 "clientarea.php",
17153 "addRenewalToCart=1&token=" + csrfToken + "&renewID="+ renewalID + "&period=" + renewalPeriod,
17154 function( data ) {
17155 jQuery("#cartItemCount").html(((jQuery("#cartItemCount").html() * 1) + 1));
17156 jQuery(selfThis).html('<span class="glyphicon glyphicon-shopping-cart"></span> Added');
17157 jQuery("#btnCheckout").fadeIn();
17158 }
17159 );
17160}
17161
17162/**
17163 * Navigate to a page on dropdown change.
17164 *
17165 * This is implemented onblur() for a dropdown. When the dropdown
17166 * changes state, the value is pulled and the browser navigated to
17167 * the selected page.
17168 *
17169 * @param {domElement} select The dropdown triggering the event
17170 */
17171function selectChangeNavigate(select) {
17172 window.location.href = $(select).val();
17173}
17174
17175/**
17176 * Append additional file upload input field.
17177 */
17178function extraTicketAttachment() {
17179 jQuery("#fileUploadsContainer").append('<input type="file" name="attachments[]" class="form-control" />');
17180}
17181
17182/**
17183 * Fetch load and uptime for a given server.
17184 *
17185 * @param {number} num Server Id
17186 */
17187function getStats(num) {
17188 WHMCS.http.jqClient.post('serverstatus.php', 'getstats=1&num=' + num, function(data) {
17189 jQuery("#load"+num).html(data.load);
17190 jQuery("#uptime"+num).html(data.uptime);
17191 },'json');
17192}
17193
17194/**
17195 * Determine status of a given port for a given server.
17196 *
17197 * @param {number} num Server Id
17198 * @param {number} port Port Number
17199 */
17200function checkPort(num, port) {
17201 WHMCS.http.jqClient.post('serverstatus.php', 'ping=1&num=' + num + '&port=' + port, function(data) {
17202 jQuery("#port" + port + "_" + num).html(data);
17203 });
17204}
17205
17206/**
17207 * Fetch automated knowledgebase suggestions for ticket content.
17208 */
17209function getticketsuggestions() {
17210 currentcheckcontent = jQuery("#message").val();
17211 if (currentcheckcontent != lastcheckcontent && currentcheckcontent != "") {
17212 WHMCS.http.jqClient.post("submitticket.php", { action: "getkbarticles", text: currentcheckcontent },
17213 function(data){
17214 if (data) {
17215 jQuery("#searchresults").html(data);
17216 jQuery("#searchresults").hide().removeClass('hidden').slideDown();
17217 }
17218 });
17219 lastcheckcontent = currentcheckcontent;
17220 }
17221 setTimeout('getticketsuggestions();', 3000);
17222}
17223
17224/**
17225 * Update custom fields upon department change.
17226 *
17227 * @param {domElement} input The department selector dropdown object
17228 */
17229function refreshCustomFields(input) {
17230 jQuery("#customFieldsContainer").load(
17231 "submitticket.php",
17232 { action: "getcustomfields", deptid: $(input).val() }
17233 );
17234}
17235
17236/**
17237 * Submit the first form that exists within a given container.
17238 *
17239 * @param {string} containerId The ID name of the container
17240 */
17241function autoSubmitFormByContainer(containerId) {
17242 if (typeof noAutoSubmit === "undefined" || noAutoSubmit === false) {
17243 jQuery("#" + containerId).find("form:first").submit();
17244 }
17245}
17246
17247/**
17248 * Submit default whois info and disable custom fields.
17249 *
17250 * @param {string} regType The contact registration type
17251 */
17252function useDefaultWhois(regType) {
17253 jQuery("." + regType.substr(0, regType.length - 1) + "customwhois").attr("disabled", true);
17254 jQuery("." + regType.substr(0, regType.length - 1) + "defaultwhois").attr("disabled", false);
17255 jQuery('#' + regType.substr(0, regType.length - 1) + '1').attr("checked", "checked");
17256}
17257
17258/**
17259 * Submit custom fields and disable default whois info.
17260 *
17261 * @param {string} regType The contact registration type
17262 */
17263function useCustomWhois(regType) {
17264 jQuery("." + regType.substr(0, regType.length - 1) + "customwhois").attr("disabled", false);
17265 jQuery("." + regType.substr(0, regType.length - 1) + "defaultwhois").attr("disabled", true);
17266 jQuery('#' + regType.substr(0, regType.length - 1) + '2').attr("checked", "checked");
17267}
17268
17269function showNewBillingAddressFields() {
17270 jQuery('#newBillingAddress').slideDown();
17271}
17272
17273function hideNewBillingAddressFields() {
17274 jQuery('#newBillingAddress').slideUp();
17275}
17276
17277/**
17278 * Show new credit card input fields.
17279 */
17280function showNewCardInputFields() {
17281 var ccDetails = jQuery('.cc-details'),
17282 ccNumber = jQuery('#inputCardNumber'),
17283 billAddress = jQuery('#billingAddressChoice');
17284
17285 if (ccDetails.hasClass("hidden")) {
17286 ccDetails.hide().removeClass("hidden");
17287 }
17288 ccDetails.slideDown();
17289 ccNumber.focus();
17290
17291 billAddress.slideDown()
17292 .find('input[name="billingcontact"]')
17293 .first()
17294 .iCheck('check');
17295}
17296
17297/**
17298 * Show new bank account input fields.
17299 */
17300function showNewAccountInputFields() {
17301 if (jQuery(".bank-details").hasClass("hidden")) {
17302 jQuery(".bank-details").hide().removeClass("hidden");
17303 }
17304 jQuery(".bank-details").slideDown();
17305
17306 jQuery("#billingAddressChoice")
17307 .slideDown()
17308 .find('input[name="billingcontact"]')
17309 .first()
17310 .iCheck('check');
17311}
17312
17313/**
17314 * Hide new credit card input fields.
17315 */
17316function hideNewCardInputFields() {
17317 hideNewBillingAddressFields();
17318 jQuery(".cc-details").slideUp();
17319 jQuery("#billingAddressChoice").slideUp();
17320 var contactId = jQuery('input[name="ccinfo"]:checked').data('billing-contact-id');
17321 if (contactId != undefined) {
17322 jQuery('#billingAddressChoice label.billing-contact-' + contactId)
17323 .iCheck('check');
17324 }
17325 jQuery('#inputCardCvv').focus();
17326}
17327
17328/**
17329 * Hide new bank account input fields.
17330 */
17331function hideNewAccountInputFields() {
17332 hideNewBillingAddressFields();
17333
17334 jQuery(".bank-details").slideUp();
17335 jQuery("#billingAddressChoice").slideUp();
17336
17337 var selectedAccount = jQuery('input[name="paymethod"]:checked'),
17338 selectedContactId = jQuery(selectedAccount).data('billing-contact-id'),
17339 selectedContactData = jQuery('.billing-contact-info[data-billing-contact-id="' + selectedContactId + '"]');
17340
17341 if (selectedContactData.length) {
17342 jQuery('.billing-contact-info').hide();
17343 jQuery(selectedContactData).show();
17344 }
17345}
17346
17347/**
17348 * Get automatic knowledgebase suggestions for support ticket message.
17349 */
17350var lastTicketMsg;
17351function getTicketSuggestions() {
17352 var userMsg = jQuery("#inputMessage").val();
17353 if (userMsg != lastTicketMsg && userMsg != '') {
17354 WHMCS.http.jqClient.post("submitticket.php", { action: "getkbarticles", text: userMsg },
17355 function (data) {
17356 if (data) {
17357 jQuery("#autoAnswerSuggestions").html(data);
17358 if (!jQuery("#autoAnswerSuggestions").is(":visible")) {
17359 jQuery("#autoAnswerSuggestions").hide().removeClass('hidden').slideDown();
17360 }
17361 }
17362 });
17363 lastTicketMsg = userMsg;
17364 }
17365 setTimeout('getTicketSuggestions()', 3000);
17366}
17367
17368/**
17369 * Smooth scroll to named element.
17370 */
17371function smoothScroll(element) {
17372 $('html, body').animate({
17373 scrollTop: $(element).offset().top
17374 }, 500);
17375}
17376
17377function irtpSubmit() {
17378 allowSubmit = true;
17379 var optOut = 0,
17380 optOutCheckbox = jQuery('#modalIrtpOptOut'),
17381 optOutReason = jQuery('#modalReason'),
17382 formOptOut = jQuery('#irtpOptOut'),
17383 formOptOutReason = jQuery('#irtpOptOutReason');
17384
17385 if (optOutCheckbox.is(':checked')) {
17386 optOut = 1;
17387 }
17388 formOptOut.val(optOut);
17389 formOptOutReason.val(optOutReason.val());
17390 jQuery('#frmDomainContactModification').submit();
17391}
17392
17393function showOverlay(msg) {
17394 jQuery('#fullpage-overlay .msg').html(msg);
17395 jQuery('#fullpage-overlay').removeClass('hidden').show();
17396}
17397
17398function hideOverlay() {
17399 jQuery('#fullpage-overlay').hide();
17400}
17401
17402function getSslAttribute(element, attribute) {
17403 if (element.data(attribute)) {
17404 return element.data(attribute);
17405 }
17406 return element.parent('td').data(attribute);
17407}
17408
17409function openValidationSubmitModal(caller)
17410{
17411 var validationSubmitModal = jQuery('#validationSubmitModal');
17412 validationSubmitModal.find('.modal-body iframe').attr('src', caller.dataset.url);
17413 validationSubmitModal.modal('show');
17414}
17415
17416function completeValidationComClientWorkflow()
17417{
17418 var submitDocsRequestBanner = jQuery('.user-validation'),
17419 secondarySidebarStatus = jQuery('.validation-status-label'),
17420 submitDiv = jQuery('.validation-submit-div'),
17421 redirectUser = true;
17422
17423 $('#validationSubmitModal').modal('hide');
17424 if (submitDocsRequestBanner.length !== 0) {
17425 submitDocsRequestBanner.slideUp();
17426 redirectUser = false;
17427 }
17428 if (secondarySidebarStatus.length !== 0) {
17429 var submitString = submitDiv.find('a').data('submitted-string');
17430 secondarySidebarStatus.text(submitString).removeClass('label-default').addClass('label-warning');
17431 submitDiv.hide();
17432 redirectUser = false;
17433 }
17434
17435 if (redirectUser) {
17436 window.location.href = WHMCS.utils.autoDetermineBaseUrl();
17437 }
17438 return false;
17439}
17440
17441/**
17442 * Perform the AjaxCall for a CustomAction.
17443 *
17444 * @param event
17445 * @param element
17446 * @returns {boolean}
17447 */
17448function customActionAjaxCall(event, element) {
17449 event.stopPropagation();
17450 if (!element.data('active')) {
17451 return false;
17452 }
17453 element.attr('disabled', 'disabled').addClass('disabled');
17454 jQuery('.loading', element).show();
17455 WHMCS.http.jqClient.jsonPost({
17456 url: WHMCS.utils.getRouteUrl(
17457 '/clientarea/service/' + element.data('serviceid') + '/custom-action/' + element.data('identifier')
17458 ),
17459 data: {
17460 'token': csrfToken
17461 },
17462 success: function(data) {
17463 if (data.success) {
17464 window.open(data.redirectTo);
17465 } else {
17466 window.open('clientarea.php?action=productdetails&id=' + element.data('serviceid') + '&customaction_error=1');
17467 }
17468 },
17469 fail: function () {
17470 window.open('clientarea.php?action=productdetails&id=' + element.data('serviceid') + '&customaction_ajax_error=1');
17471 },
17472 always: function() {
17473 jQuery('.loading', element).hide();
17474 element.removeAttr('disabled').removeClass('disabled');
17475 if (element.hasClass('dropdown-item')) {
17476 element.closest('.dropdown-menu').removeClass('show');
17477 }
17478 },
17479 });
17480 return true;
17481}
17482
17483/*!
17484 * WHMCS Ajax Driven Modal Framework
17485 *
17486 * @copyright Copyright (c) WHMCS Limited 2005-2021
17487 * @license https://www.whmcs.com/license/ WHMCS Eula
17488 */
17489var ajaxModalSubmitEvents = [],
17490 ajaxModalPostSubmitEvents = [];
17491jQuery(document).ready(function(){
17492 jQuery(document).on('click', '.open-modal', function(e) {
17493 e.preventDefault();
17494 var url = jQuery(this).attr('href'),
17495 modalSize = jQuery(this).data('modal-size'),
17496 modalClass = jQuery(this).data('modal-class'),
17497 modalTitle = jQuery(this).data('modal-title'),
17498 submitId = jQuery(this).data('btn-submit-id'),
17499 submitLabel = jQuery(this).data('btn-submit-label'),
17500 submitColor = jQuery(this).data('btn-submit-color'),
17501 hideClose = jQuery(this).data('btn-close-hide'),
17502 disabled = jQuery(this).attr('disabled'),
17503 successDataTable = jQuery(this).data('datatable-reload-success');
17504
17505 var postData = '';
17506 if (csrfToken) {
17507 postData = {token: csrfToken};
17508 }
17509 if (!disabled) {
17510 openModal(url, postData, modalTitle, modalSize, modalClass, submitLabel, submitId, submitColor, hideClose, successDataTable);
17511 }
17512 });
17513
17514 // define modal close reset action
17515 jQuery('#modalAjax').on('hidden.bs.modal', function (e) {
17516 if (jQuery(this).hasClass('modal-feature-highlights')) {
17517 var dismissForVersion = jQuery('#cbFeatureHighlightsDismissForVersion').is(':checked');
17518 WHMCS.http.jqClient.post(
17519 'whatsnew.php',
17520 {
17521 dismiss: "1",
17522 until_next_update: dismissForVersion ? '1' : '0',
17523 token: csrfToken
17524 }
17525 );
17526 }
17527
17528 jQuery('#modalAjax').find('.modal-body').empty();
17529 jQuery('#modalAjax').children('div.modal-dialog').removeClass('modal-lg');
17530 jQuery('#modalAjax').removeClass().addClass('modal whmcs-modal fade');
17531 jQuery('#modalAjax .modal-title').html('Title');
17532 jQuery('#modalAjax .modal-submit').html('Submit')
17533 .removeClass()
17534 .addClass('btn btn-primary modal-submit')
17535 .removeAttr('id')
17536 .removeAttr('disabled');
17537 jQuery('#modalAjax .loader').show();
17538 });
17539});
17540
17541function openModal(url, postData, modalTitle, modalSize, modalClass, submitLabel, submitId, submitColor, hideClose, successDataTable) {
17542 //set the text of the modal title
17543 jQuery('#modalAjax .modal-title').html(modalTitle);
17544
17545 // set the modal size via a class attribute
17546 if (modalSize) {
17547 jQuery('#modalAjax').children('div[class="modal-dialog"]').addClass(modalSize);
17548 }
17549 // set the modal class
17550 if (modalClass) {
17551 jQuery('#modalAjax').addClass(modalClass);
17552 }
17553
17554 // set the text of the submit button
17555 if(!submitLabel){
17556 jQuery('#modalAjax .modal-submit').hide();
17557 } else {
17558 jQuery('#modalAjax .modal-submit').show().html(submitLabel);
17559 // set the button id so we can target the click function of it.
17560 if (submitId) {
17561 jQuery('#modalAjax .modal-submit').attr('id', submitId);
17562 }
17563 }
17564
17565 if (hideClose) {
17566 jQuery('#modalAjaxClose').hide();
17567 }
17568
17569 if (submitColor) {
17570 jQuery('#modalAjax .modal-submit').removeClass('btn-primary')
17571 .addClass('btn-' + submitColor);
17572 }
17573
17574 jQuery('#modalAjax .modal-body').html('');
17575
17576 jQuery('#modalSkip').hide();
17577 disableSubmit();
17578
17579 // show modal
17580 jQuery('#modalAjax').modal({
17581 show: true,
17582 keyboard: true,
17583 backdrop: jQuery('#modalAjax').hasClass('static') ? 'static' : true
17584 });
17585
17586 // fetch modal content
17587 WHMCS.http.jqClient.post(url, postData, function(data) {
17588 updateAjaxModal(data);
17589 }, 'json').fail(function() {
17590 jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.');
17591 jQuery('#modalAjax .loader').fadeOut();
17592 }).always(function () {
17593 var modalForm = jQuery('#modalAjax').find('form');
17594 // If a submitId is present, then we're working with a form and need to override the default event
17595 if (submitId) {
17596 modalForm.submit(function (event) {
17597 submitIdAjaxModalClickEvent();
17598 return false;
17599 });
17600 }
17601 if (successDataTable) {
17602 modalForm.data('successDataTable', successDataTable);
17603 }
17604
17605 // Since the content is dynamically fetched, we have to check for the elements we want here too
17606 var inputs = jQuery(modalForm).find('input:not(input[type=checkbox],input[type=radio],input[type=hidden])');
17607
17608 if (inputs.length > 0) {
17609 jQuery(inputs).first().focus();
17610 }
17611 });
17612
17613 //define modal submit button click
17614 if (submitId) {
17615 /**
17616 * Reloading ajax modal multiple times on the same page can add
17617 * multiple "on" click events which submits the same form over
17618 * and over.
17619 * Remove the on click event with "off" to avoid multiple growl
17620 * and save events being run.
17621 *
17622 * @see http://api.jquery.com/off/
17623 */
17624 var submitButton = jQuery('#' + submitId);
17625 submitButton.off('click');
17626 submitButton.on('click', submitIdAjaxModalClickEvent);
17627 }
17628}
17629
17630function submitIdAjaxModalClickEvent ()
17631{
17632 var canContinue = true,
17633 loader = jQuery('#modalAjax .loader');
17634 disableSubmit();
17635 loader.show();
17636 if (ajaxModalSubmitEvents.length) {
17637 jQuery.each(ajaxModalSubmitEvents, function (index, value) {
17638 var fn = window[value];
17639 if (canContinue && typeof fn === 'function') {
17640 canContinue = fn();
17641 }
17642 });
17643 }
17644 if (!canContinue) {
17645 enableSubmit();
17646 loader.hide();
17647 return;
17648 }
17649 var modalForm = jQuery('#modalAjax').find('form');
17650 var modalBody = jQuery('#modalAjax .modal-body');
17651 var modalErrorContainer = jQuery(modalBody).find('.admin-modal-error');
17652
17653 jQuery(modalErrorContainer).slideUp();
17654
17655 var modalPost = WHMCS.http.jqClient.post(
17656 modalForm.attr('action'),
17657 modalForm.serialize(),
17658 function(data) {
17659 if (modalForm.data('successDataTable')) {
17660 data.successDataTable = modalForm.data('successDataTable');
17661 }
17662 /**
17663 * When actions should occur before the ajax modal is updated
17664 * that do not fall into the standard actions.
17665 * Calling code (ie the function defined in fn) should validate
17666 * that the ajax modal being updated is the one that the code should
17667 * run for, as there is potential for multiple ajax modals on the
17668 * same page.
17669 */
17670 if (ajaxModalPostSubmitEvents.length) {
17671 jQuery.each(ajaxModalPostSubmitEvents, function (index, value) {
17672 var fn = window[value];
17673 if (typeof fn === 'function') {
17674 fn(data, modalForm);
17675 }
17676 });
17677 }
17678 updateAjaxModal(data);
17679 },
17680 'json'
17681 ).fail(function(xhr) {
17682 var data = xhr.responseJSON;
17683 var genericErrorMsg = 'An error occurred while communicating with the server. Please try again.';
17684 if (data && data.data) {
17685 data = data.data;
17686 if (data.errorMsg) {
17687 if (modalErrorContainer.length > 0) {
17688 jQuery(modalErrorContainer)
17689 .html(data.errorMsg)
17690 .slideDown();
17691 } else {
17692 jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg});
17693 }
17694 } else if (data.data.body) {
17695 jQuery(modalBody).html(data.body);
17696 } else {
17697 jQuery(modalBody).html(genericErrorMsg);
17698 }
17699 } else {
17700 jQuery(modalBody).html(genericErrorMsg);
17701 }
17702 jQuery('#modalAjax .loader').fadeOut();
17703 enableSubmit();
17704 });
17705}
17706
17707function updateAjaxModal(data) {
17708 if (data.reloadPage) {
17709 if (typeof data.reloadPage === 'string') {
17710 window.location = data.reloadPage;
17711 } else {
17712 window.location.reload();
17713 }
17714 return;
17715 }
17716 if (data.successDataTable) {
17717 WHMCS.ui.dataTable.getTableById(data.successDataTable, undefined).ajax.reload();
17718 }
17719 if (data.redirect) {
17720 window.location = data.redirect;
17721 }
17722 if (data.successWindow && typeof window[data.successWindow] === "function") {
17723 window[data.successWindow]();
17724 }
17725 if (data.dismiss) {
17726 dialogClose();
17727 }
17728 if (data.successMsg) {
17729 jQuery.growl.notice({ title: data.successMsgTitle, message: data.successMsg });
17730 }
17731 if (data.errorMsg) {
17732 var inModalErrorContainer = jQuery('#modalAjax .modal-body .admin-modal-error');
17733
17734 if (inModalErrorContainer.length > 0 && !data.dismiss) {
17735 jQuery(inModalErrorContainer)
17736 .html(data.errorMsg)
17737 .slideDown();
17738 } else {
17739 jQuery.growl.warning({title: data.errorMsgTitle, message: data.errorMsg});
17740 }
17741 }
17742 if (data.title) {
17743 jQuery('#modalAjax .modal-title').html(data.title);
17744 }
17745 if (data.body) {
17746 jQuery('#modalAjax .modal-body').html(data.body);
17747 } else {
17748 if (data.url) {
17749 WHMCS.http.jqClient.post(data.url, '', function(data2) {
17750 jQuery('#modalAjax').find('.modal-body').html(data2.body);
17751 }, 'json').fail(function() {
17752 jQuery('#modalAjax').find('.modal-body').html('An error occurred while communicating with the server. Please try again.');
17753 jQuery('#modalAjax').find('.loader').fadeOut();
17754 });
17755 }
17756 }
17757 if (data.submitlabel) {
17758 jQuery('#modalAjax .modal-submit').html(data.submitlabel).show();
17759 if (data.submitId) {
17760 jQuery('#modalAjax').find('.modal-submit').attr('id', data.submitId);
17761 }
17762 }
17763
17764 if (data.submitId) {
17765 /**
17766 * Reloading ajax modal multiple times on the same page can add
17767 * multiple "on" click events which submits the same form over
17768 * and over.
17769 * Remove the on click event with "off" to avoid multiple growl
17770 * and save events being run.
17771 *
17772 * @see http://api.jquery.com/off/
17773 */
17774 var submitButton = jQuery('#' + data.submitId);
17775 submitButton.off('click');
17776 submitButton.on('click', submitIdAjaxModalClickEvent);
17777 }
17778
17779 if (data.disableSubmit) {
17780 disableSubmit();
17781 } else {
17782 enableSubmit();
17783 }
17784
17785 var dismissLoader = true;
17786 if (typeof data.dismissLoader !== 'undefined') {
17787 dismissLoader = data.dismissLoader;
17788 }
17789
17790 dismissLoaderAfterRender(dismissLoader);
17791
17792 if (data.hideSubmit) {
17793 ajaxModalHideSubmit();
17794 }
17795}
17796
17797// backwards compat for older dialog implementations
17798
17799function dialogSubmit() {
17800 disableSubmit();
17801 jQuery('#modalAjax .loader').show();
17802 var postUrl = jQuery('#modalAjax').find('form').attr('action');
17803 WHMCS.http.jqClient.post(postUrl, jQuery('#modalAjax').find('form').serialize(),
17804 function(data) {
17805 updateAjaxModal(data);
17806 }, 'json').fail(function() {
17807 jQuery('#modalAjax .modal-body').html('An error occurred while communicating with the server. Please try again.');
17808 jQuery('#modalAjax .loader').fadeOut();
17809 });
17810}
17811
17812function dialogClose() {
17813 jQuery('#modalAjax').modal('hide');
17814}
17815
17816function addAjaxModalSubmitEvents(functionName) {
17817 if (functionName) {
17818 ajaxModalSubmitEvents.push(functionName);
17819 }
17820}
17821
17822function removeAjaxModalSubmitEvents(functionName) {
17823 if (functionName) {
17824 var index = ajaxModalSubmitEvents.indexOf(functionName);
17825 if (index >= 0) {
17826 ajaxModalSubmitEvents.splice(index, 1);
17827 }
17828 }
17829}
17830
17831function addAjaxModalPostSubmitEvents(functionName) {
17832 if (functionName) {
17833 ajaxModalPostSubmitEvents.push(functionName);
17834 }
17835}
17836
17837function removeAjaxModalPostSubmitEvents(functionName) {
17838 if (functionName) {
17839 var index = ajaxModalPostSubmitEvents.indexOf(functionName);
17840 if (index >= 0) {
17841 ajaxModalPostSubmitEvents.splice(index, 1);
17842 }
17843 }
17844}
17845
17846function disableSubmit()
17847{
17848 jQuery('#modalAjax .modal-submit').prop('disabled', true).addClass('disabled');
17849}
17850
17851function enableSubmit()
17852{
17853 jQuery('#modalAjax .modal-submit').prop('disabled', false).removeClass('disabled');
17854}
17855
17856function ajaxModalHideSubmit()
17857{
17858 jQuery('#modalAjax .modal-submit').hide();
17859}
17860
17861function dismissLoaderAfterRender(showLoader)
17862{
17863 if (showLoader === false) {
17864 jQuery('#modalAjax .loader').show();
17865 } else {
17866 jQuery('#modalAjax .loader').fadeOut();
17867 }
17868}
17869
17870/**
17871 * bootstrap-switch - Turn checkboxes and radio buttons into toggle switches.
17872 *
17873 * @version v3.3.4
17874 * @homepage https://bttstrp.github.io/bootstrap-switch
17875 * @author Mattia Larentis <mattia@larentis.eu> (http://larentis.eu)
17876 * @license Apache-2.0
17877 */
17878
17879(function (global, factory) {
17880 if (typeof define === "function" && define.amd) {
17881 define(['jquery'], factory);
17882 } else if (typeof exports !== "undefined") {
17883 factory(require('jquery'));
17884 } else {
17885 var mod = {
17886 exports: {}
17887 };
17888 factory(global.jquery);
17889 global.bootstrapSwitch = mod.exports;
17890 }
17891})(this, function (_jquery) {
17892 'use strict';
17893
17894 var _jquery2 = _interopRequireDefault(_jquery);
17895
17896 function _interopRequireDefault(obj) {
17897 return obj && obj.__esModule ? obj : {
17898 default: obj
17899 };
17900 }
17901
17902 var _extends = Object.assign || function (target) {
17903 for (var i = 1; i < arguments.length; i++) {
17904 var source = arguments[i];
17905
17906 for (var key in source) {
17907 if (Object.prototype.hasOwnProperty.call(source, key)) {
17908 target[key] = source[key];
17909 }
17910 }
17911 }
17912
17913 return target;
17914 };
17915
17916 function _classCallCheck(instance, Constructor) {
17917 if (!(instance instanceof Constructor)) {
17918 throw new TypeError("Cannot call a class as a function");
17919 }
17920 }
17921
17922 var _createClass = function () {
17923 function defineProperties(target, props) {
17924 for (var i = 0; i < props.length; i++) {
17925 var descriptor = props[i];
17926 descriptor.enumerable = descriptor.enumerable || false;
17927 descriptor.configurable = true;
17928 if ("value" in descriptor) descriptor.writable = true;
17929 Object.defineProperty(target, descriptor.key, descriptor);
17930 }
17931 }
17932
17933 return function (Constructor, protoProps, staticProps) {
17934 if (protoProps) defineProperties(Constructor.prototype, protoProps);
17935 if (staticProps) defineProperties(Constructor, staticProps);
17936 return Constructor;
17937 };
17938 }();
17939
17940 var $ = _jquery2.default || window.jQuery || window.$;
17941
17942 var BootstrapSwitch = function () {
17943 function BootstrapSwitch(element) {
17944 var _this = this;
17945
17946 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
17947
17948 _classCallCheck(this, BootstrapSwitch);
17949
17950 this.$element = $(element);
17951 this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, this._getElementOptions(), options);
17952 this.prevOptions = {};
17953 this.$wrapper = $('<div>', {
17954 class: function _class() {
17955 var classes = [];
17956 classes.push(_this.options.state ? 'on' : 'off');
17957 if (_this.options.size) {
17958 classes.push(_this.options.size);
17959 }
17960 if (_this.options.disabled) {
17961 classes.push('disabled');
17962 }
17963 if (_this.options.readonly) {
17964 classes.push('readonly');
17965 }
17966 if (_this.options.indeterminate) {
17967 classes.push('indeterminate');
17968 }
17969 if (_this.options.inverse) {
17970 classes.push('inverse');
17971 }
17972 if (_this.$element.attr('id')) {
17973 classes.push('id-' + _this.$element.attr('id'));
17974 }
17975 return classes.map(_this._getClass.bind(_this)).concat([_this.options.baseClass], _this._getClasses(_this.options.wrapperClass)).join(' ');
17976 }
17977 });
17978 this.$container = $('<div>', { class: this._getClass('container') });
17979 this.$on = $('<span>', {
17980 html: this.options.onText,
17981 class: this._getClass('handle-on') + ' ' + this._getClass(this.options.onColor)
17982 });
17983 this.$off = $('<span>', {
17984 html: this.options.offText,
17985 class: this._getClass('handle-off') + ' ' + this._getClass(this.options.offColor)
17986 });
17987 this.$label = $('<span>', {
17988 html: this.options.labelText,
17989 class: this._getClass('label')
17990 });
17991
17992 this.$element.on('init.bootstrapSwitch', this.options.onInit.bind(this, element));
17993 this.$element.on('switchChange.bootstrapSwitch', function () {
17994 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
17995 args[_key] = arguments[_key];
17996 }
17997
17998 if (_this.options.onSwitchChange.apply(element, args) === false) {
17999 if (_this.$element.is(':radio')) {
18000 $('[name="' + _this.$element.attr('name') + '"]').trigger('previousState.bootstrapSwitch', true);
18001 } else {
18002 _this.$element.trigger('previousState.bootstrapSwitch', true);
18003 }
18004 }
18005 });
18006
18007 this.$container = this.$element.wrap(this.$container).parent();
18008 this.$wrapper = this.$container.wrap(this.$wrapper).parent();
18009 this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off);
18010
18011 if (this.options.indeterminate) {
18012 this.$element.prop('indeterminate', true);
18013 }
18014
18015 this._init();
18016 this._elementHandlers();
18017 this._handleHandlers();
18018 this._labelHandlers();
18019 this._formHandler();
18020 this._externalLabelHandler();
18021 this.$element.trigger('init.bootstrapSwitch', this.options.state);
18022 }
18023
18024 _createClass(BootstrapSwitch, [{
18025 key: 'setPrevOptions',
18026 value: function setPrevOptions() {
18027 this.prevOptions = _extends({}, this.options);
18028 }
18029 }, {
18030 key: 'state',
18031 value: function state(value, skip) {
18032 if (typeof value === 'undefined') {
18033 return this.options.state;
18034 }
18035 if (this.options.disabled || this.options.readonly || this.options.state && !this.options.radioAllOff && this.$element.is(':radio')) {
18036 return this.$element;
18037 }
18038 if (this.$element.is(':radio')) {
18039 $('[name="' + this.$element.attr('name') + '"]').trigger('setPreviousOptions.bootstrapSwitch');
18040 } else {
18041 this.$element.trigger('setPreviousOptions.bootstrapSwitch');
18042 }
18043 if (this.options.indeterminate) {
18044 this.indeterminate(false);
18045 }
18046 this.$element.prop('checked', Boolean(value)).trigger('change.bootstrapSwitch', skip);
18047 return this.$element;
18048 }
18049 }, {
18050 key: 'toggleState',
18051 value: function toggleState(skip) {
18052 if (this.options.disabled || this.options.readonly) {
18053 return this.$element;
18054 }
18055 if (this.options.indeterminate) {
18056 this.indeterminate(false);
18057 return this.state(true);
18058 } else {
18059 return this.$element.prop('checked', !this.options.state).trigger('change.bootstrapSwitch', skip);
18060 }
18061 }
18062 }, {
18063 key: 'size',
18064 value: function size(value) {
18065 if (typeof value === 'undefined') {
18066 return this.options.size;
18067 }
18068 if (this.options.size != null) {
18069 this.$wrapper.removeClass(this._getClass(this.options.size));
18070 }
18071 if (value) {
18072 this.$wrapper.addClass(this._getClass(value));
18073 }
18074 this._width();
18075 this._containerPosition();
18076 this.options.size = value;
18077 return this.$element;
18078 }
18079 }, {
18080 key: 'animate',
18081 value: function animate(value) {
18082 if (typeof value === 'undefined') {
18083 return this.options.animate;
18084 }
18085 if (this.options.animate === Boolean(value)) {
18086 return this.$element;
18087 }
18088 return this.toggleAnimate();
18089 }
18090 }, {
18091 key: 'toggleAnimate',
18092 value: function toggleAnimate() {
18093 this.options.animate = !this.options.animate;
18094 this.$wrapper.toggleClass(this._getClass('animate'));
18095 return this.$element;
18096 }
18097 }, {
18098 key: 'disabled',
18099 value: function disabled(value) {
18100 if (typeof value === 'undefined') {
18101 return this.options.disabled;
18102 }
18103 if (this.options.disabled === Boolean(value)) {
18104 return this.$element;
18105 }
18106 return this.toggleDisabled();
18107 }
18108 }, {
18109 key: 'toggleDisabled',
18110 value: function toggleDisabled() {
18111 this.options.disabled = !this.options.disabled;
18112 this.$element.prop('disabled', this.options.disabled);
18113 this.$wrapper.toggleClass(this._getClass('disabled'));
18114 return this.$element;
18115 }
18116 }, {
18117 key: 'readonly',
18118 value: function readonly(value) {
18119 if (typeof value === 'undefined') {
18120 return this.options.readonly;
18121 }
18122 if (this.options.readonly === Boolean(value)) {
18123 return this.$element;
18124 }
18125 return this.toggleReadonly();
18126 }
18127 }, {
18128 key: 'toggleReadonly',
18129 value: function toggleReadonly() {
18130 this.options.readonly = !this.options.readonly;
18131 this.$element.prop('readonly', this.options.readonly);
18132 this.$wrapper.toggleClass(this._getClass('readonly'));
18133 return this.$element;
18134 }
18135 }, {
18136 key: 'indeterminate',
18137 value: function indeterminate(value) {
18138 if (typeof value === 'undefined') {
18139 return this.options.indeterminate;
18140 }
18141 if (this.options.indeterminate === Boolean(value)) {
18142 return this.$element;
18143 }
18144 return this.toggleIndeterminate();
18145 }
18146 }, {
18147 key: 'toggleIndeterminate',
18148 value: function toggleIndeterminate() {
18149 this.options.indeterminate = !this.options.indeterminate;
18150 this.$element.prop('indeterminate', this.options.indeterminate);
18151 this.$wrapper.toggleClass(this._getClass('indeterminate'));
18152 this._containerPosition();
18153 return this.$element;
18154 }
18155 }, {
18156 key: 'inverse',
18157 value: function inverse(value) {
18158 if (typeof value === 'undefined') {
18159 return this.options.inverse;
18160 }
18161 if (this.options.inverse === Boolean(value)) {
18162 return this.$element;
18163 }
18164 return this.toggleInverse();
18165 }
18166 }, {
18167 key: 'toggleInverse',
18168 value: function toggleInverse() {
18169 this.$wrapper.toggleClass(this._getClass('inverse'));
18170 var $on = this.$on.clone(true);
18171 var $off = this.$off.clone(true);
18172 this.$on.replaceWith($off);
18173 this.$off.replaceWith($on);
18174 this.$on = $off;
18175 this.$off = $on;
18176 this.options.inverse = !this.options.inverse;
18177 return this.$element;
18178 }
18179 }, {
18180 key: 'onColor',
18181 value: function onColor(value) {
18182 if (typeof value === 'undefined') {
18183 return this.options.onColor;
18184 }
18185 if (this.options.onColor) {
18186 this.$on.removeClass(this._getClass(this.options.onColor));
18187 }
18188 this.$on.addClass(this._getClass(value));
18189 this.options.onColor = value;
18190 return this.$element;
18191 }
18192 }, {
18193 key: 'offColor',
18194 value: function offColor(value) {
18195 if (typeof value === 'undefined') {
18196 return this.options.offColor;
18197 }
18198 if (this.options.offColor) {
18199 this.$off.removeClass(this._getClass(this.options.offColor));
18200 }
18201 this.$off.addClass(this._getClass(value));
18202 this.options.offColor = value;
18203 return this.$element;
18204 }
18205 }, {
18206 key: 'onText',
18207 value: function onText(value) {
18208 if (typeof value === 'undefined') {
18209 return this.options.onText;
18210 }
18211 this.$on.html(value);
18212 this._width();
18213 this._containerPosition();
18214 this.options.onText = value;
18215 return this.$element;
18216 }
18217 }, {
18218 key: 'offText',
18219 value: function offText(value) {
18220 if (typeof value === 'undefined') {
18221 return this.options.offText;
18222 }
18223 this.$off.html(value);
18224 this._width();
18225 this._containerPosition();
18226 this.options.offText = value;
18227 return this.$element;
18228 }
18229 }, {
18230 key: 'labelText',
18231 value: function labelText(value) {
18232 if (typeof value === 'undefined') {
18233 return this.options.labelText;
18234 }
18235 this.$label.html(value);
18236 this._width();
18237 this.options.labelText = value;
18238 return this.$element;
18239 }
18240 }, {
18241 key: 'handleWidth',
18242 value: function handleWidth(value) {
18243 if (typeof value === 'undefined') {
18244 return this.options.handleWidth;
18245 }
18246 this.options.handleWidth = value;
18247 this._width();
18248 this._containerPosition();
18249 return this.$element;
18250 }
18251 }, {
18252 key: 'labelWidth',
18253 value: function labelWidth(value) {
18254 if (typeof value === 'undefined') {
18255 return this.options.labelWidth;
18256 }
18257 this.options.labelWidth = value;
18258 this._width();
18259 this._containerPosition();
18260 return this.$element;
18261 }
18262 }, {
18263 key: 'baseClass',
18264 value: function baseClass(value) {
18265 return this.options.baseClass;
18266 }
18267 }, {
18268 key: 'wrapperClass',
18269 value: function wrapperClass(value) {
18270 if (typeof value === 'undefined') {
18271 return this.options.wrapperClass;
18272 }
18273 if (!value) {
18274 value = $.fn.bootstrapSwitch.defaults.wrapperClass;
18275 }
18276 this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(' '));
18277 this.$wrapper.addClass(this._getClasses(value).join(' '));
18278 this.options.wrapperClass = value;
18279 return this.$element;
18280 }
18281 }, {
18282 key: 'radioAllOff',
18283 value: function radioAllOff(value) {
18284 if (typeof value === 'undefined') {
18285 return this.options.radioAllOff;
18286 }
18287 var val = Boolean(value);
18288 if (this.options.radioAllOff === val) {
18289 return this.$element;
18290 }
18291 this.options.radioAllOff = val;
18292 return this.$element;
18293 }
18294 }, {
18295 key: 'onInit',
18296 value: function onInit(value) {
18297 if (typeof value === 'undefined') {
18298 return this.options.onInit;
18299 }
18300 if (!value) {
18301 value = $.fn.bootstrapSwitch.defaults.onInit;
18302 }
18303 this.options.onInit = value;
18304 return this.$element;
18305 }
18306 }, {
18307 key: 'onSwitchChange',
18308 value: function onSwitchChange(value) {
18309 if (typeof value === 'undefined') {
18310 return this.options.onSwitchChange;
18311 }
18312 if (!value) {
18313 value = $.fn.bootstrapSwitch.defaults.onSwitchChange;
18314 }
18315 this.options.onSwitchChange = value;
18316 return this.$element;
18317 }
18318 }, {
18319 key: 'destroy',
18320 value: function destroy() {
18321 var $form = this.$element.closest('form');
18322 if ($form.length) {
18323 $form.off('reset.bootstrapSwitch').removeData('bootstrap-switch');
18324 }
18325 this.$container.children().not(this.$element).remove();
18326 this.$element.unwrap().unwrap().off('.bootstrapSwitch').removeData('bootstrap-switch');
18327 return this.$element;
18328 }
18329 }, {
18330 key: '_getElementOptions',
18331 value: function _getElementOptions() {
18332 return {
18333 state: this.$element.is(':checked'),
18334 size: this.$element.data('size'),
18335 animate: this.$element.data('animate'),
18336 disabled: this.$element.is(':disabled'),
18337 readonly: this.$element.is('[readonly]'),
18338 indeterminate: this.$element.data('indeterminate'),
18339 inverse: this.$element.data('inverse'),
18340 radioAllOff: this.$element.data('radio-all-off'),
18341 onColor: this.$element.data('on-color'),
18342 offColor: this.$element.data('off-color'),
18343 onText: this.$element.data('on-text'),
18344 offText: this.$element.data('off-text'),
18345 labelText: this.$element.data('label-text'),
18346 handleWidth: this.$element.data('handle-width'),
18347 labelWidth: this.$element.data('label-width'),
18348 baseClass: this.$element.data('base-class'),
18349 wrapperClass: this.$element.data('wrapper-class')
18350 };
18351 }
18352 }, {
18353 key: '_width',
18354 value: function _width() {
18355 var _this2 = this;
18356
18357 var $handles = this.$on.add(this.$off).add(this.$label).css('width', '');
18358 var handleWidth = this.options.handleWidth === 'auto' ? Math.round(Math.max(this.$on.width(), this.$off.width())) : this.options.handleWidth;
18359 $handles.width(handleWidth);
18360 this.$label.width(function (index, width) {
18361 if (_this2.options.labelWidth !== 'auto') {
18362 return _this2.options.labelWidth;
18363 }
18364 if (width < handleWidth) {
18365 return handleWidth;
18366 }
18367 return width;
18368 });
18369 this._handleWidth = this.$on.outerWidth();
18370 this._labelWidth = this.$label.outerWidth();
18371 this.$container.width(this._handleWidth * 2 + this._labelWidth);
18372 return this.$wrapper.width(this._handleWidth + this._labelWidth);
18373 }
18374 }, {
18375 key: '_containerPosition',
18376 value: function _containerPosition() {
18377 var _this3 = this;
18378
18379 var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.state;
18380 var callback = arguments[1];
18381
18382 this.$container.css('margin-left', function () {
18383 var values = [0, '-' + _this3._handleWidth + 'px'];
18384 if (_this3.options.indeterminate) {
18385 return '-' + _this3._handleWidth / 2 + 'px';
18386 }
18387 if (state) {
18388 if (_this3.options.inverse) {
18389 return values[1];
18390 } else {
18391 return values[0];
18392 }
18393 } else {
18394 if (_this3.options.inverse) {
18395 return values[0];
18396 } else {
18397 return values[1];
18398 }
18399 }
18400 });
18401 }
18402 }, {
18403 key: '_init',
18404 value: function _init() {
18405 var _this4 = this;
18406
18407 var init = function init() {
18408 _this4.setPrevOptions();
18409 _this4._width();
18410 _this4._containerPosition();
18411 setTimeout(function () {
18412 if (_this4.options.animate) {
18413 return _this4.$wrapper.addClass(_this4._getClass('animate'));
18414 }
18415 }, 50);
18416 };
18417 if (this.$wrapper.is(':visible')) {
18418 init();
18419 return;
18420 }
18421 var initInterval = window.setInterval(function () {
18422 if (_this4.$wrapper.is(':visible')) {
18423 init();
18424 return window.clearInterval(initInterval);
18425 }
18426 }, 50);
18427 }
18428 }, {
18429 key: '_elementHandlers',
18430 value: function _elementHandlers() {
18431 var _this5 = this;
18432
18433 return this.$element.on({
18434 'setPreviousOptions.bootstrapSwitch': this.setPrevOptions.bind(this),
18435
18436 'previousState.bootstrapSwitch': function previousStateBootstrapSwitch() {
18437 _this5.options = _this5.prevOptions;
18438 if (_this5.options.indeterminate) {
18439 _this5.$wrapper.addClass(_this5._getClass('indeterminate'));
18440 }
18441 _this5.$element.prop('checked', _this5.options.state).trigger('change.bootstrapSwitch', true);
18442 },
18443
18444 'change.bootstrapSwitch': function changeBootstrapSwitch(event, skip) {
18445 event.preventDefault();
18446 event.stopImmediatePropagation();
18447 var state = _this5.$element.is(':checked');
18448 _this5._containerPosition(state);
18449 if (state === _this5.options.state) {
18450 return;
18451 }
18452 _this5.options.state = state;
18453 _this5.$wrapper.toggleClass(_this5._getClass('off')).toggleClass(_this5._getClass('on'));
18454 if (!skip) {
18455 if (_this5.$element.is(':radio')) {
18456 $('[name="' + _this5.$element.attr('name') + '"]').not(_this5.$element).prop('checked', false).trigger('change.bootstrapSwitch', true);
18457 }
18458 _this5.$element.trigger('switchChange.bootstrapSwitch', [state]);
18459 }
18460 },
18461
18462 'focus.bootstrapSwitch': function focusBootstrapSwitch(event) {
18463 event.preventDefault();
18464 _this5.$wrapper.addClass(_this5._getClass('focused'));
18465 },
18466
18467 'blur.bootstrapSwitch': function blurBootstrapSwitch(event) {
18468 event.preventDefault();
18469 _this5.$wrapper.removeClass(_this5._getClass('focused'));
18470 },
18471
18472 'keydown.bootstrapSwitch': function keydownBootstrapSwitch(event) {
18473 if (!event.which || _this5.options.disabled || _this5.options.readonly) {
18474 return;
18475 }
18476 if (event.which === 37 || event.which === 39) {
18477 event.preventDefault();
18478 event.stopImmediatePropagation();
18479 _this5.state(event.which === 39);
18480 }
18481 }
18482 });
18483 }
18484 }, {
18485 key: '_handleHandlers',
18486 value: function _handleHandlers() {
18487 var _this6 = this;
18488
18489 this.$on.on('click.bootstrapSwitch', function (event) {
18490 event.preventDefault();
18491 event.stopPropagation();
18492 _this6.state(false);
18493 return _this6.$element.trigger('focus.bootstrapSwitch');
18494 });
18495 return this.$off.on('click.bootstrapSwitch', function (event) {
18496 event.preventDefault();
18497 event.stopPropagation();
18498 _this6.state(true);
18499 return _this6.$element.trigger('focus.bootstrapSwitch');
18500 });
18501 }
18502 }, {
18503 key: '_labelHandlers',
18504 value: function _labelHandlers() {
18505 var _this7 = this;
18506
18507 var handlers = {
18508 click: function click(event) {
18509 event.stopPropagation();
18510 },
18511
18512
18513 'mousedown.bootstrapSwitch touchstart.bootstrapSwitch': function mousedownBootstrapSwitchTouchstartBootstrapSwitch(event) {
18514 if (_this7._dragStart || _this7.options.disabled || _this7.options.readonly) {
18515 return;
18516 }
18517 event.preventDefault();
18518 event.stopPropagation();
18519 _this7._dragStart = (event.pageX || event.originalEvent.touches[0].pageX) - parseInt(_this7.$container.css('margin-left'), 10);
18520 if (_this7.options.animate) {
18521 _this7.$wrapper.removeClass(_this7._getClass('animate'));
18522 }
18523 _this7.$element.trigger('focus.bootstrapSwitch');
18524 },
18525
18526 'mousemove.bootstrapSwitch touchmove.bootstrapSwitch': function mousemoveBootstrapSwitchTouchmoveBootstrapSwitch(event) {
18527 if (_this7._dragStart == null) {
18528 return;
18529 }
18530 var difference = (event.pageX || event.originalEvent.touches[0].pageX) - _this7._dragStart;
18531 event.preventDefault();
18532 if (difference < -_this7._handleWidth || difference > 0) {
18533 return;
18534 }
18535 _this7._dragEnd = difference;
18536 _this7.$container.css('margin-left', _this7._dragEnd + 'px');
18537 },
18538
18539 'mouseup.bootstrapSwitch touchend.bootstrapSwitch': function mouseupBootstrapSwitchTouchendBootstrapSwitch(event) {
18540 if (!_this7._dragStart) {
18541 return;
18542 }
18543 event.preventDefault();
18544 if (_this7.options.animate) {
18545 _this7.$wrapper.addClass(_this7._getClass('animate'));
18546 }
18547 if (_this7._dragEnd) {
18548 var state = _this7._dragEnd > -(_this7._handleWidth / 2);
18549 _this7._dragEnd = false;
18550 _this7.state(_this7.options.inverse ? !state : state);
18551 } else {
18552 _this7.state(!_this7.options.state);
18553 }
18554 _this7._dragStart = false;
18555 },
18556
18557 'mouseleave.bootstrapSwitch': function mouseleaveBootstrapSwitch() {
18558 _this7.$label.trigger('mouseup.bootstrapSwitch');
18559 }
18560 };
18561 this.$label.on(handlers);
18562 }
18563 }, {
18564 key: '_externalLabelHandler',
18565 value: function _externalLabelHandler() {
18566 var _this8 = this;
18567
18568 var $externalLabel = this.$element.closest('label');
18569 $externalLabel.on('click', function (event) {
18570 event.preventDefault();
18571 event.stopImmediatePropagation();
18572 if (event.target === $externalLabel[0]) {
18573 _this8.toggleState();
18574 }
18575 });
18576 }
18577 }, {
18578 key: '_formHandler',
18579 value: function _formHandler() {
18580 var $form = this.$element.closest('form');
18581 if ($form.data('bootstrap-switch')) {
18582 return;
18583 }
18584 $form.on('reset.bootstrapSwitch', function () {
18585 window.setTimeout(function () {
18586 $form.find('input').filter(function () {
18587 return $(this).data('bootstrap-switch');
18588 }).each(function () {
18589 return $(this).bootstrapSwitch('state', this.checked);
18590 });
18591 }, 1);
18592 }).data('bootstrap-switch', true);
18593 }
18594 }, {
18595 key: '_getClass',
18596 value: function _getClass(name) {
18597 return this.options.baseClass + '-' + name;
18598 }
18599 }, {
18600 key: '_getClasses',
18601 value: function _getClasses(classes) {
18602 if (!$.isArray(classes)) {
18603 return [this._getClass(classes)];
18604 }
18605 return classes.map(this._getClass.bind(this));
18606 }
18607 }]);
18608
18609 return BootstrapSwitch;
18610 }();
18611
18612 $.fn.bootstrapSwitch = function (option) {
18613 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
18614 args[_key2 - 1] = arguments[_key2];
18615 }
18616
18617 function reducer(ret, next) {
18618 var $this = $(next);
18619 var existingData = $this.data('bootstrap-switch');
18620 var data = existingData || new BootstrapSwitch(next, option);
18621 if (!existingData) {
18622 $this.data('bootstrap-switch', data);
18623 }
18624 if (typeof option === 'string') {
18625 return data[option].apply(data, args);
18626 }
18627 return ret;
18628 }
18629 return Array.prototype.reduce.call(this, reducer, this);
18630 };
18631 $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
18632 $.fn.bootstrapSwitch.defaults = {
18633 state: true,
18634 size: null,
18635 animate: true,
18636 disabled: false,
18637 readonly: false,
18638 indeterminate: false,
18639 inverse: false,
18640 radioAllOff: false,
18641 onColor: 'primary',
18642 offColor: 'default',
18643 onText: 'ON',
18644 offText: 'OFF',
18645 labelText: ' ',
18646 handleWidth: 'auto',
18647 labelWidth: 'auto',
18648 baseClass: 'bootstrap-switch',
18649 wrapperClass: 'wrapper',
18650 onInit: function onInit() {},
18651 onSwitchChange: function onSwitchChange() {}
18652 };
18653});
18654
18655/* ===================================================
18656 * bootstrap-markdown.js v2.10.0
18657 * http://github.com/toopay/bootstrap-markdown
18658 * ===================================================
18659 * Copyright 2013-2016 Taufan Aditya
18660 *
18661 * Licensed under the Apache License, Version 2.0 (the "License");
18662 * you may not use this file except in compliance with the License.
18663 * You may obtain a copy of the License at
18664 *
18665 * http://www.apache.org/licenses/LICENSE-2.0
18666 *
18667 * Unless required by applicable law or agreed to in writing, software
18668 * distributed under the License is distributed on an "AS IS" BASIS,
18669 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18670 * See the License for the specific language governing permissions and
18671 * limitations under the License.
18672 * ========================================================== */
18673(function(factory) {
18674 if (typeof define === "function" && define.amd) {
18675 // RequireJS
18676 define(["jquery"], factory);
18677 } else if (typeof exports === 'object') {
18678 // Backbone.js
18679 factory(require('jquery'));
18680 } else {
18681 // jQuery plugin
18682 factory(jQuery);
18683 }
18684}(function($) {
18685 "use strict";
18686
18687 /* MARKDOWN CLASS DEFINITION
18688 * ========================== */
18689
18690 var Markdown = function(element, options) {
18691 // @TODO : remove this BC on next major release
18692 // @see : https://github.com/toopay/bootstrap-markdown/issues/109
18693 var opts = ['autofocus', 'savable', 'hideable', 'width',
18694 'height', 'resize', 'iconlibrary', 'language',
18695 'footer', 'fullscreen', 'hiddenButtons', 'disabledButtons'
18696 ];
18697 $.each(opts, function(_, opt) {
18698 if (typeof $(element).data(opt) !== 'undefined') {
18699 options = typeof options == 'object' ? options : {};
18700 options[opt] = $(element).data(opt);
18701 }
18702 });
18703 // End BC
18704
18705 // Class Properties
18706 this.$ns = 'bootstrap-markdown';
18707 this.$element = $(element);
18708 this.$editable = {
18709 el: null,
18710 type: null,
18711 attrKeys: [],
18712 attrValues: [],
18713 content: null
18714 };
18715 this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data('options'));
18716 this.$oldContent = null;
18717 this.$isPreview = false;
18718 this.$isFullscreen = false;
18719 this.$editor = null;
18720 this.$textarea = null;
18721 this.$handler = [];
18722 this.$callback = [];
18723 this.$nextTab = [];
18724
18725 this.showEditor();
18726 };
18727
18728 Markdown.prototype = {
18729
18730 constructor: Markdown,
18731 __alterButtons: function(name, alter) {
18732 var handler = this.$handler,
18733 isAll = (name == 'all'),
18734 that = this;
18735
18736 $.each(handler, function(k, v) {
18737 var halt = true;
18738 if (isAll) {
18739 halt = false;
18740 } else {
18741 halt = v.indexOf(name) < 0;
18742 }
18743
18744 if (halt === false) {
18745 alter(that.$editor.find('button[data-handler="' + v + '"]'));
18746 }
18747 });
18748 },
18749 __buildButtons: function(buttonsArray, container) {
18750 var i,
18751 ns = this.$ns,
18752 handler = this.$handler,
18753 callback = this.$callback;
18754
18755 for (i = 0; i < buttonsArray.length; i++) {
18756 // Build each group container
18757 var y, btnGroups = buttonsArray[i];
18758 for (y = 0; y < btnGroups.length; y++) {
18759 // Build each button group
18760 var z,
18761 buttons = btnGroups[y].data,
18762 btnGroupContainer = $('<div/>', {
18763 'class': 'btn-group'
18764 });
18765
18766 for (z = 0; z < buttons.length; z++) {
18767 var button = buttons[z],
18768 buttonContainer, buttonIconContainer,
18769 buttonHandler = ns + '-' + button.name,
18770 buttonIcon = this.__getIcon(button),
18771 btnText = button.btnText ? button.btnText : '',
18772 btnClass = button.btnClass ? button.btnClass : 'btn',
18773 tabIndex = button.tabIndex ? button.tabIndex : '-1',
18774 hotkey = typeof button.hotkey !== 'undefined' ? button.hotkey : '',
18775 hotkeyCaption = typeof jQuery.hotkeys !== 'undefined' && hotkey !== '' ? ' (' + hotkey + ')' : '';
18776
18777 // Construct the button object
18778 buttonContainer = $('<button></button>');
18779 buttonContainer.text(' ' + this.__localize(btnText)).addClass('btn-default btn-sm').addClass(btnClass);
18780 if (btnClass.match(/btn\-(primary|success|info|warning|danger|link)/)) {
18781 buttonContainer.removeClass('btn-default');
18782 }
18783 buttonContainer.attr({
18784 'type': 'button',
18785 'title': this.__localize(button.title) + hotkeyCaption,
18786 'tabindex': tabIndex,
18787 'data-provider': ns,
18788 'data-handler': buttonHandler,
18789 'data-hotkey': hotkey
18790 });
18791 if (button.toggle === true) {
18792 buttonContainer.attr('data-toggle', 'button');
18793 }
18794 buttonIconContainer = $('<span/>');
18795 buttonIconContainer.addClass(buttonIcon);
18796 buttonIconContainer.prependTo(buttonContainer);
18797
18798 // Attach the button object
18799 btnGroupContainer.append(buttonContainer);
18800
18801 // Register handler and callback
18802 handler.push(buttonHandler);
18803 callback.push(button.callback);
18804 }
18805
18806 // Attach the button group into container DOM
18807 container.append(btnGroupContainer);
18808 }
18809 }
18810
18811 return container;
18812 },
18813 __setListener: function() {
18814 // Set size and resizable Properties
18815 var hasRows = typeof this.$textarea.attr('rows') !== 'undefined',
18816 maxRows = this.$textarea.val().split("\n").length > 5 ? this.$textarea.val().split("\n").length : '5',
18817 rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows;
18818
18819 this.$textarea.attr('rows', rowsVal);
18820 if (this.$options.resize) {
18821 this.$textarea.css('resize', this.$options.resize);
18822 }
18823
18824 // Re-attach markdown data
18825 this.$textarea.data('markdown', this);
18826 },
18827 __setEventListeners: function() {
18828 this.$textarea.on({
18829 'focus': $.proxy(this.focus, this),
18830 'keyup': $.proxy(this.keyup, this),
18831 'change': $.proxy(this.change, this),
18832 'select': $.proxy(this.select, this)
18833 });
18834
18835 if (this.eventSupported('keydown')) {
18836 this.$textarea.on('keydown', $.proxy(this.keydown, this));
18837 }
18838
18839 if (this.eventSupported('keypress')) {
18840 this.$textarea.on('keypress', $.proxy(this.keypress, this));
18841 }
18842 },
18843 __handle: function(e) {
18844 var target = $(e.currentTarget),
18845 handler = this.$handler,
18846 callback = this.$callback,
18847 handlerName = target.attr('data-handler'),
18848 callbackIndex = handler.indexOf(handlerName),
18849 callbackHandler = callback[callbackIndex];
18850
18851 // Trigger the focusin
18852 $(e.currentTarget).focus();
18853
18854 callbackHandler(this);
18855
18856 // Trigger onChange for each button handle
18857 this.change(this);
18858
18859 // Unless it was the save handler,
18860 // focusin the textarea
18861 if (handlerName.indexOf('cmdSave') < 0) {
18862 this.$textarea.focus();
18863 }
18864
18865 e.preventDefault();
18866 },
18867 __localize: function(string) {
18868 var messages = $.fn.markdown.messages,
18869 language = this.$options.language;
18870 if (
18871 typeof messages !== 'undefined' &&
18872 typeof messages[language] !== 'undefined' &&
18873 typeof messages[language][string] !== 'undefined'
18874 ) {
18875 return messages[language][string];
18876 }
18877 return string;
18878 },
18879 __getIcon: function(src) {
18880 if(typeof src == 'object'){
18881 var customIcon = this.$options.customIcons[src.name];
18882 return typeof customIcon == 'undefined' ? src.icon[this.$options.iconlibrary] : customIcon;
18883 } else {
18884 return src;
18885 }
18886 },
18887 setFullscreen: function(mode) {
18888 var $editor = this.$editor,
18889 $textarea = this.$textarea;
18890
18891 if (mode === true) {
18892 $editor.addClass('md-fullscreen-mode');
18893 $('body').addClass('md-nooverflow');
18894 this.$options.onFullscreen(this);
18895 } else {
18896 $editor.removeClass('md-fullscreen-mode');
18897 $('body').removeClass('md-nooverflow');
18898 this.$options.onFullscreenExit(this);
18899
18900 if (this.$isPreview === true)
18901 this.hidePreview().showPreview();
18902 }
18903
18904 this.$isFullscreen = mode;
18905 $textarea.focus();
18906 },
18907 showEditor: function() {
18908 var instance = this,
18909 textarea,
18910 ns = this.$ns,
18911 container = this.$element,
18912 originalHeigth = container.css('height'),
18913 originalWidth = container.css('width'),
18914 editable = this.$editable,
18915 handler = this.$handler,
18916 callback = this.$callback,
18917 options = this.$options,
18918 editor = $('<div/>', {
18919 'class': 'md-editor',
18920 click: function() {
18921 instance.focus();
18922 }
18923 });
18924
18925 // Prepare the editor
18926 if (this.$editor === null) {
18927 // Create the panel
18928 var editorHeader = $('<div/>', {
18929 'class': 'md-header btn-toolbar'
18930 });
18931
18932 // Merge the main & additional button groups together
18933 var allBtnGroups = [];
18934 if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0]);
18935 if (options.additionalButtons.length > 0) {
18936 // iterate the additional button groups
18937 $.each(options.additionalButtons[0], function(idx, buttonGroup) {
18938
18939 // see if the group name of the additional group matches an existing group
18940 var matchingGroups = $.grep(allBtnGroups, function(allButtonGroup, allIdx) {
18941 return allButtonGroup.name === buttonGroup.name;
18942 });
18943
18944 // if it matches add the additional buttons to that group, if not just add it to the all buttons group
18945 if (matchingGroups.length > 0) {
18946 matchingGroups[0].data = matchingGroups[0].data.concat(buttonGroup.data);
18947 } else {
18948 allBtnGroups.push(options.additionalButtons[0][idx]);
18949 }
18950
18951 });
18952 }
18953
18954 // Reduce and/or reorder the button groups
18955 if (options.reorderButtonGroups.length > 0) {
18956 allBtnGroups = allBtnGroups
18957 .filter(function(btnGroup) {
18958 return options.reorderButtonGroups.indexOf(btnGroup.name) > -1;
18959 })
18960 .sort(function(a, b) {
18961 if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1;
18962 if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1;
18963 return 0;
18964 });
18965 }
18966
18967 // Build the buttons
18968 if (allBtnGroups.length > 0) {
18969 editorHeader = this.__buildButtons([allBtnGroups], editorHeader);
18970 }
18971
18972 if (options.fullscreen.enable) {
18973 editorHeader.append('<div class="md-controls"><a class="md-control md-control-fullscreen" href="#"><span class="' + this.__getIcon(options.fullscreen.icons.fullscreenOn) + '"></span></a></div>').on('click', '.md-control-fullscreen', function(e) {
18974 e.preventDefault();
18975 instance.setFullscreen(true);
18976 });
18977 }
18978
18979 editor.append(editorHeader);
18980
18981 // Wrap the textarea
18982 if (container.is('textarea')) {
18983 container.before(editor);
18984 textarea = container;
18985 textarea.addClass('md-input');
18986 editor.append(textarea);
18987 } else {
18988 var rawContent = (typeof toMarkdown == 'function') ? toMarkdown(container.html()) : container.html(),
18989 currentContent = $.trim(rawContent);
18990
18991 // This is some arbitrary content that could be edited
18992 textarea = $('<textarea/>', {
18993 'class': 'md-input',
18994 'val': currentContent
18995 });
18996
18997 editor.append(textarea);
18998
18999 // Save the editable
19000 editable.el = container;
19001 editable.type = container.prop('tagName').toLowerCase();
19002 editable.content = container.html();
19003
19004 $(container[0].attributes).each(function() {
19005 editable.attrKeys.push(this.nodeName);
19006 editable.attrValues.push(this.nodeValue);
19007 });
19008
19009 // Set editor to block the original container
19010 container.replaceWith(editor);
19011 }
19012
19013 var editorFooter = $('<div/>', {
19014 'class': 'md-footer'
19015 }),
19016 createFooter = false,
19017 footer = '';
19018 // Create the footer if savable
19019 if (options.savable) {
19020 createFooter = true;
19021 var saveHandler = 'cmdSave';
19022
19023 // Register handler and callback
19024 handler.push(saveHandler);
19025 callback.push(options.onSave);
19026
19027 editorFooter.append('<button class="btn btn-success" data-provider="' +
19028 ns +
19029 '" data-handler="' +
19030 saveHandler +
19031 '"><i class="icon icon-white icon-ok"></i> ' +
19032 this.__localize('Save') +
19033 '</button>');
19034
19035
19036 }
19037
19038 footer = typeof options.footer === 'function' ? options.footer(this) : options.footer;
19039
19040 if ($.trim(footer) !== '') {
19041 createFooter = true;
19042 editorFooter.append(footer);
19043 }
19044
19045 if (createFooter) editor.append(editorFooter);
19046
19047 // Set width
19048 if (options.width && options.width !== 'inherit') {
19049 if (jQuery.isNumeric(options.width)) {
19050 editor.css('display', 'table');
19051 textarea.css('width', options.width + 'px');
19052 } else {
19053 editor.addClass(options.width);
19054 }
19055 }
19056
19057 // Set height
19058 if (options.height && options.height !== 'inherit') {
19059 if (jQuery.isNumeric(options.height)) {
19060 var height = options.height;
19061 if (editorHeader) height = Math.max(0, height - editorHeader.outerHeight());
19062 if (editorFooter) height = Math.max(0, height - editorFooter.outerHeight());
19063 textarea.css('height', height + 'px');
19064 } else {
19065 editor.addClass(options.height);
19066 }
19067 }
19068
19069 // Reference
19070 this.$editor = editor;
19071 this.$textarea = textarea;
19072 this.$editable = editable;
19073 this.$oldContent = this.getContent();
19074
19075 this.__setListener();
19076 this.__setEventListeners();
19077
19078 // Set editor attributes, data short-hand API and listener
19079 this.$editor.attr('id', (new Date()).getTime());
19080 this.$editor.on('click', '[data-provider="bootstrap-markdown"]', $.proxy(this.__handle, this));
19081
19082 if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
19083 this.$editor.addClass('md-editor-disabled');
19084 this.disableButtons('all');
19085 }
19086
19087 if (this.eventSupported('keydown') && typeof jQuery.hotkeys === 'object') {
19088 editorHeader.find('[data-provider="bootstrap-markdown"]').each(function() {
19089 var $button = $(this),
19090 hotkey = $button.attr('data-hotkey');
19091 if (hotkey.toLowerCase() !== '') {
19092 textarea.bind('keydown', hotkey, function() {
19093 $button.trigger('click');
19094 return false;
19095 });
19096 }
19097 });
19098 }
19099
19100 if (options.initialstate === 'preview') {
19101 this.showPreview();
19102 } else if (options.initialstate === 'fullscreen' && options.fullscreen.enable) {
19103 this.setFullscreen(true);
19104 }
19105
19106 } else {
19107 this.$editor.show();
19108 }
19109
19110 if (options.autofocus) {
19111 this.$textarea.focus();
19112 this.$editor.addClass('active');
19113 }
19114
19115 if (options.fullscreen.enable && options.fullscreen !== false) {
19116 this.$editor.append('<div class="md-fullscreen-controls">' +
19117 '<a href="#" class="exit-fullscreen" title="Exit fullscreen"><span class="' + this.__getIcon(options.fullscreen.icons.fullscreenOff) + '">' +
19118 '</span></a>' +
19119 '</div>');
19120 this.$editor.on('click', '.exit-fullscreen', function(e) {
19121 e.preventDefault();
19122 instance.setFullscreen(false);
19123 });
19124 }
19125
19126 // hide hidden buttons from options
19127 this.hideButtons(options.hiddenButtons);
19128
19129 // disable disabled buttons from options
19130 this.disableButtons(options.disabledButtons);
19131
19132 // enable dropZone if available and configured
19133 if (options.dropZoneOptions) {
19134 if (this.$editor.dropzone) {
19135 if(!options.dropZoneOptions.init) {
19136 options.dropZoneOptions.init = function() {
19137 var caretPos = 0;
19138 this.on('drop', function(e) {
19139 caretPos = textarea.prop('selectionStart');
19140 });
19141 this.on('success', function(file, path) {
19142 var text = textarea.val();
19143 textarea.val(text.substring(0, caretPos) + '\n\n' + text.substring(caretPos));
19144 });
19145 this.on('error', function(file, error, xhr) {
19146 console.log('Error:', error);
19147 });
19148 };
19149 }
19150 this.$editor.addClass('dropzone');
19151 this.$editor.dropzone(options.dropZoneOptions);
19152 } else {
19153 console.log('dropZoneOptions was configured, but DropZone was not detected.');
19154 }
19155 }
19156
19157 // enable data-uris via drag and drop
19158 if (options.enableDropDataUri === true) {
19159 this.$editor.on('drop', function(e) {
19160 var caretPos = textarea.prop('selectionStart');
19161 e.stopPropagation();
19162 e.preventDefault();
19163 $.each(e.originalEvent.dataTransfer.files, function(index, file){
19164 var fileReader = new FileReader();
19165 fileReader.onload = (function(file) {
19166 var type = file.type.split('/')[0];
19167 return function(e) {
19168 var text = textarea.val();
19169 if (type === 'image')
19170 textarea.val(text.substring(0, caretPos) + '\n<img src="'+ e.target.result +'" />\n' + text.substring(caretPos) );
19171 else
19172 textarea.val(text.substring(0, caretPos) + '\n<a href="'+ e.target.result +'">Download ' + file.name + '</a>\n' + text.substring(caretPos) );
19173 };
19174 })(file);
19175 fileReader.readAsDataURL(file);
19176 });
19177 });
19178 }
19179
19180 // Trigger the onShow hook
19181 options.onShow(this);
19182
19183 return this;
19184 },
19185 parseContent: function(val) {
19186 var content;
19187
19188 // parse with supported markdown parser
19189 val = val || this.$textarea.val();
19190
19191 if (this.$options.parser) {
19192 content = this.$options.parser(val);
19193 } else if (typeof markdown == 'object') {
19194 content = markdown.toHTML(val);
19195 } else if (typeof marked == 'function') {
19196 content = marked(val);
19197 } else {
19198 content = val;
19199 }
19200
19201 return content;
19202 },
19203 showPreview: function() {
19204 var options = this.$options,
19205 container = this.$textarea,
19206 afterContainer = container.next(),
19207 replacementContainer = $('<div/>', {
19208 'class': 'md-preview',
19209 'data-provider': 'markdown-preview'
19210 }),
19211 content,
19212 callbackContent;
19213
19214 if (this.$isPreview === true) {
19215 // Avoid sequenced element creation on misused scenario
19216 // @see https://github.com/toopay/bootstrap-markdown/issues/170
19217 return this;
19218 }
19219
19220 // Give flag that tells the editor to enter preview mode
19221 this.$isPreview = true;
19222 // Disable all buttons
19223 this.disableButtons('all').enableButtons('cmdPreview');
19224
19225 // Try to get the content from callback
19226 callbackContent = options.onPreview(this, replacementContainer);
19227 // Set the content based on the callback content if string, otherwise parse value from textarea
19228 content = typeof callbackContent == 'string' ? callbackContent : this.parseContent();
19229
19230 // Build preview element
19231 replacementContainer.html(content);
19232
19233 if (afterContainer && afterContainer.attr('class') == 'md-footer') {
19234 // If there is footer element, insert the preview container before it
19235 replacementContainer.insertBefore(afterContainer);
19236 } else {
19237 // Otherwise, just append it after textarea
19238 container.parent().append(replacementContainer);
19239 }
19240
19241 // Set the preview element dimensions
19242 replacementContainer.css({
19243 "width": container.outerWidth() + 'px',
19244 "min-height": container.outerHeight() + 'px',
19245 "height": "auto"
19246 });
19247
19248 if (this.$options.resize) {
19249 replacementContainer.css('resize', this.$options.resize);
19250 }
19251
19252 // Hide the last-active textarea
19253 container.hide();
19254
19255 // Attach the editor instances
19256 replacementContainer.data('markdown', this);
19257
19258 if (this.$element.is(':disabled') || this.$element.is('[readonly]')) {
19259 this.$editor.addClass('md-editor-disabled');
19260 this.disableButtons('all');
19261 }
19262
19263 return this;
19264 },
19265 hidePreview: function() {
19266 // Give flag that tells the editor to quit preview mode
19267 this.$isPreview = false;
19268
19269 // Obtain the preview container
19270 var container = this.$editor.find('div[data-provider="markdown-preview"]');
19271
19272 // Remove the preview container
19273 container.remove();
19274
19275 // Enable all buttons
19276 this.enableButtons('all');
19277 // Disable configured disabled buttons
19278 this.disableButtons(this.$options.disabledButtons);
19279
19280 // Perform any callbacks
19281 this.$options.onPreviewEnd(this);
19282
19283 // Back to the editor
19284 this.$textarea.show();
19285 this.__setListener();
19286
19287 return this;
19288 },
19289 isDirty: function() {
19290 return this.$oldContent != this.getContent();
19291 },
19292 getContent: function() {
19293 return this.$textarea.val();
19294 },
19295 setContent: function(content) {
19296 this.$textarea.val(content);
19297
19298 return this;
19299 },
19300 findSelection: function(chunk) {
19301 var content = this.getContent(),
19302 startChunkPosition;
19303
19304 if (startChunkPosition = content.indexOf(chunk), startChunkPosition >= 0 && chunk.length > 0) {
19305 var oldSelection = this.getSelection(),
19306 selection;
19307
19308 this.setSelection(startChunkPosition, startChunkPosition + chunk.length);
19309 selection = this.getSelection();
19310
19311 this.setSelection(oldSelection.start, oldSelection.end);
19312
19313 return selection;
19314 } else {
19315 return null;
19316 }
19317 },
19318 getSelection: function() {
19319
19320 var e = this.$textarea[0];
19321
19322 return (
19323
19324 ('selectionStart' in e && function() {
19325 var l = e.selectionEnd - e.selectionStart;
19326 return {
19327 start: e.selectionStart,
19328 end: e.selectionEnd,
19329 length: l,
19330 text: e.value.substr(e.selectionStart, l)
19331 };
19332 }) ||
19333
19334 /* browser not supported */
19335 function() {
19336 return null;
19337 }
19338
19339 )();
19340
19341 },
19342 setSelection: function(start, end) {
19343
19344 var e = this.$textarea[0];
19345
19346 return (
19347
19348 ('selectionStart' in e && function() {
19349 e.selectionStart = start;
19350 e.selectionEnd = end;
19351 return;
19352 }) ||
19353
19354 /* browser not supported */
19355 function() {
19356 return null;
19357 }
19358
19359 )();
19360
19361 },
19362 replaceSelection: function(text) {
19363
19364 var e = this.$textarea[0];
19365
19366 return (
19367
19368 ('selectionStart' in e && function() {
19369 e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length);
19370 // Set cursor to the last replacement end
19371 e.selectionStart = e.value.length;
19372 return this;
19373 }) ||
19374
19375 /* browser not supported */
19376 function() {
19377 e.value += text;
19378 return jQuery(e);
19379 }
19380
19381 )();
19382 },
19383 getNextTab: function() {
19384 // Shift the nextTab
19385 if (this.$nextTab.length === 0) {
19386 return null;
19387 } else {
19388 var nextTab, tab = this.$nextTab.shift();
19389
19390 if (typeof tab == 'function') {
19391 nextTab = tab();
19392 } else if (typeof tab == 'object' && tab.length > 0) {
19393 nextTab = tab;
19394 }
19395
19396 return nextTab;
19397 }
19398 },
19399 setNextTab: function(start, end) {
19400 // Push new selection into nextTab collections
19401 if (typeof start == 'string') {
19402 var that = this;
19403 this.$nextTab.push(function() {
19404 return that.findSelection(start);
19405 });
19406 } else if (typeof start == 'number' && typeof end == 'number') {
19407 var oldSelection = this.getSelection();
19408
19409 this.setSelection(start, end);
19410 this.$nextTab.push(this.getSelection());
19411
19412 this.setSelection(oldSelection.start, oldSelection.end);
19413 }
19414
19415 return;
19416 },
19417 __parseButtonNameParam: function(names) {
19418 return typeof names == 'string' ?
19419 names.split(' ') :
19420 names;
19421
19422 },
19423 enableButtons: function(name) {
19424 var buttons = this.__parseButtonNameParam(name),
19425 that = this;
19426
19427 $.each(buttons, function(i, v) {
19428 that.__alterButtons(buttons[i], function(el) {
19429 el.removeAttr('disabled');
19430 });
19431 });
19432
19433 return this;
19434 },
19435 disableButtons: function(name) {
19436 var buttons = this.__parseButtonNameParam(name),
19437 that = this;
19438
19439 $.each(buttons, function(i, v) {
19440 that.__alterButtons(buttons[i], function(el) {
19441 el.attr('disabled', 'disabled');
19442 });
19443 });
19444
19445 return this;
19446 },
19447 hideButtons: function(name) {
19448 var buttons = this.__parseButtonNameParam(name),
19449 that = this;
19450
19451 $.each(buttons, function(i, v) {
19452 that.__alterButtons(buttons[i], function(el) {
19453 el.addClass('hidden');
19454 });
19455 });
19456
19457 return this;
19458 },
19459 showButtons: function(name) {
19460 var buttons = this.__parseButtonNameParam(name),
19461 that = this;
19462
19463 $.each(buttons, function(i, v) {
19464 that.__alterButtons(buttons[i], function(el) {
19465 el.removeClass('hidden');
19466 });
19467 });
19468
19469 return this;
19470 },
19471 eventSupported: function(eventName) {
19472 var isSupported = eventName in this.$element;
19473 if (!isSupported) {
19474 this.$element.setAttribute(eventName, 'return;');
19475 isSupported = typeof this.$element[eventName] === 'function';
19476 }
19477 return isSupported;
19478 },
19479 keyup: function(e) {
19480 var blocked = false;
19481 switch (e.keyCode) {
19482 case 40: // down arrow
19483 case 38: // up arrow
19484 case 16: // shift
19485 case 17: // ctrl
19486 case 18: // alt
19487 break;
19488
19489 case 9: // tab
19490 var nextTab;
19491 if (nextTab = this.getNextTab(), nextTab !== null) {
19492 // Get the nextTab if exists
19493 var that = this;
19494 setTimeout(function() {
19495 that.setSelection(nextTab.start, nextTab.end);
19496 }, 500);
19497
19498 blocked = true;
19499 } else {
19500 // The next tab's memory contains nothing...
19501 // check the cursor position to determine tab action
19502 var cursor = this.getSelection();
19503
19504 if (cursor.start == cursor.end && cursor.end == this.getContent().length) {
19505 // The cursor has reached the end of the content
19506 blocked = false;
19507 } else {
19508 // Put the cursor to the end
19509 this.setSelection(this.getContent().length, this.getContent().length);
19510
19511 blocked = true;
19512 }
19513 }
19514
19515 break;
19516
19517 case 13: // enter
19518 blocked = false;
19519 var chars = this.getContent().split('');
19520 var enterIndex = this.getSelection().start;
19521 var priorNewlineIndex = -1; // initial line break at before index 0
19522
19523 // traverse backwards through chars to check if last line break was num/bullet item
19524 for (var i = enterIndex - 2; i >= 0; i--) {
19525 if (chars[i] === '\n') {
19526 priorNewlineIndex = i;
19527 break;
19528 }
19529 }
19530
19531 if (chars.slice(priorNewlineIndex + 1, priorNewlineIndex + 4).join('') == '---') {
19532 break;
19533 }
19534
19535 var charFollowingLastLineBreak = chars[priorNewlineIndex + 1];
19536 if (charFollowingLastLineBreak === '-') {
19537 this.addBullet(enterIndex);
19538 } else if ($.isNumeric(charFollowingLastLineBreak)) {
19539 var numBullet = this.getBulletNumber(priorNewlineIndex + 1);
19540 if (numBullet) {
19541 this.addNumberedBullet(enterIndex, numBullet);
19542 }
19543 }
19544 break;
19545
19546 case 27: // escape
19547 if (this.$isFullscreen) this.setFullscreen(false);
19548 blocked = false;
19549 break;
19550
19551 default:
19552 blocked = false;
19553 }
19554
19555 if (blocked) {
19556 e.stopPropagation();
19557 e.preventDefault();
19558 }
19559
19560 this.$options.onChange(this);
19561 },
19562 insertContent: function(index, content) {
19563 var firstHalf = this.getContent().slice(0, index);
19564 var secondHalf = this.getContent().slice(index + 1);
19565 this.setContent(firstHalf.concat(content).concat(secondHalf));
19566 },
19567 addBullet: function(index) {
19568 this.insertContent(index, '- \n');
19569 this.setSelection(index + 2, index + 2); // Put the cursor after the bullet
19570 },
19571 addNumberedBullet: function(index, num) {
19572 var numBullet = (num + 1) + '. \n';
19573 this.insertContent(index, numBullet);
19574
19575 var prefixLength = num.toString().length + 2;
19576 this.setSelection(index + prefixLength, index + prefixLength); // Put the cursor after the number
19577 },
19578 getBulletNumber: function(startIndex) {
19579 var bulletNum = this.getContent().slice(startIndex).split('.')[0];
19580 return $.isNumeric(bulletNum) ? parseInt(bulletNum) : null;
19581 },
19582 change: function(e) {
19583 this.$options.onChange(this);
19584 return this;
19585 },
19586 select: function(e) {
19587 this.$options.onSelect(this);
19588 return this;
19589 },
19590 focus: function(e) {
19591 var options = this.$options,
19592 isHideable = options.hideable,
19593 editor = this.$editor;
19594
19595 editor.addClass('active');
19596
19597 // Blur other markdown(s)
19598 $(document).find('.md-editor').each(function() {
19599 if ($(this).attr('id') !== editor.attr('id')) {
19600 var attachedMarkdown;
19601
19602 if (attachedMarkdown = $(this).find('textarea').data('markdown'),
19603 attachedMarkdown === null) {
19604 attachedMarkdown = $(this).find('div[data-provider="markdown-preview"]').data('markdown');
19605 }
19606
19607 if (attachedMarkdown) {
19608 attachedMarkdown.blur();
19609 }
19610 }
19611 });
19612
19613 // Trigger the onFocus hook
19614 options.onFocus(this);
19615
19616 return this;
19617 },
19618 blur: function(e) {
19619 var options = this.$options,
19620 isHideable = options.hideable,
19621 editor = this.$editor,
19622 editable = this.$editable;
19623
19624 if (editor.hasClass('active') || this.$element.parent().length === 0) {
19625 editor.removeClass('active');
19626
19627 if (isHideable) {
19628 // Check for editable elements
19629 if (editable.el !== null) {
19630 // Build the original element
19631 var oldElement = $('<' + editable.type + '/>'),
19632 content = this.getContent(),
19633 currentContent = this.parseContent(content);
19634
19635 $(editable.attrKeys).each(function(k, v) {
19636 oldElement.attr(editable.attrKeys[k], editable.attrValues[k]);
19637 });
19638
19639 // Get the editor content
19640 oldElement.html(currentContent);
19641
19642 editor.replaceWith(oldElement);
19643 } else {
19644 editor.hide();
19645 }
19646 }
19647
19648 // Trigger the onBlur hook
19649 options.onBlur(this);
19650 }
19651
19652 return this;
19653 }
19654
19655 };
19656
19657 /* MARKDOWN PLUGIN DEFINITION
19658 * ========================== */
19659
19660 var old = $.fn.markdown;
19661
19662 $.fn.markdown = function(option) {
19663 return this.each(function() {
19664 var $this = $(this),
19665 data = $this.data('markdown'),
19666 options = typeof option == 'object' && option;
19667 if (!data)
19668 $this.data('markdown', (data = new Markdown(this, options)));
19669 });
19670 };
19671
19672 $.fn.markdown.messages = {};
19673
19674 $.fn.markdown.defaults = {
19675 /* Editor Properties */
19676 autofocus: false,
19677 hideable: false,
19678 savable: false,
19679 width: 'inherit',
19680 height: 'inherit',
19681 resize: 'none',
19682 iconlibrary: 'glyph',
19683 language: 'en',
19684 initialstate: 'editor',
19685 parser: null,
19686 dropZoneOptions: null,
19687 enableDropDataUri: false,
19688
19689 /* Buttons Properties */
19690 buttons: [
19691 [{
19692 name: 'groupFont',
19693 data: [{
19694 name: 'cmdBold',
19695 hotkey: 'Ctrl+B',
19696 title: 'Bold',
19697 icon: {
19698 glyph: 'glyphicon glyphicon-bold',
19699 fa: 'fa fa-bold',
19700 'fa-3': 'icon-bold',
19701 'fa-5': 'fas fa-bold',
19702 octicons: 'octicon octicon-bold'
19703 },
19704 callback: function(e) {
19705 // Give/remove ** surround the selection
19706 var chunk, cursor, selected = e.getSelection(),
19707 content = e.getContent();
19708
19709 if (selected.length === 0) {
19710 // Give extra word
19711 chunk = e.__localize('strong text');
19712 } else {
19713 chunk = selected.text;
19714 }
19715
19716 // transform selection and set the cursor into chunked text
19717 if (content.substr(selected.start - 2, 2) === '**' &&
19718 content.substr(selected.end, 2) === '**') {
19719 e.setSelection(selected.start - 2, selected.end + 2);
19720 e.replaceSelection(chunk);
19721 cursor = selected.start - 2;
19722 } else {
19723 e.replaceSelection('**' + chunk + '**');
19724 cursor = selected.start + 2;
19725 }
19726
19727 // Set the cursor
19728 e.setSelection(cursor, cursor + chunk.length);
19729 }
19730 }, {
19731 name: 'cmdItalic',
19732 title: 'Italic',
19733 hotkey: 'Ctrl+I',
19734 icon: {
19735 glyph: 'glyphicon glyphicon-italic',
19736 fa: 'fa fa-italic',
19737 'fa-3': 'icon-italic',
19738 'fa-5': 'fas fa-italic',
19739 octicons: 'octicon octicon-italic'
19740 },
19741 callback: function(e) {
19742 // Give/remove * surround the selection
19743 var chunk, cursor, selected = e.getSelection(),
19744 content = e.getContent();
19745
19746 if (selected.length === 0) {
19747 // Give extra word
19748 chunk = e.__localize('emphasized text');
19749 } else {
19750 chunk = selected.text;
19751 }
19752
19753 // transform selection and set the cursor into chunked text
19754 if (content.substr(selected.start - 1, 1) === '_' &&
19755 content.substr(selected.end, 1) === '_') {
19756 e.setSelection(selected.start - 1, selected.end + 1);
19757 e.replaceSelection(chunk);
19758 cursor = selected.start - 1;
19759 } else {
19760 e.replaceSelection('_' + chunk + '_');
19761 cursor = selected.start + 1;
19762 }
19763
19764 // Set the cursor
19765 e.setSelection(cursor, cursor + chunk.length);
19766 }
19767 }, {
19768 name: 'cmdHeading',
19769 title: 'Heading',
19770 hotkey: 'Ctrl+H',
19771 icon: {
19772 glyph: 'glyphicon glyphicon-header',
19773 fa: 'fa fa-header',
19774 'fa-3': 'icon-font',
19775 'fa-5': 'fas fa-heading',
19776 octicons: 'octicon octicon-text-size'
19777 },
19778 callback: function(e) {
19779 // Append/remove ### surround the selection
19780 var chunk, cursor, selected = e.getSelection(),
19781 content = e.getContent(),
19782 pointer, prevChar;
19783
19784 if (selected.length === 0) {
19785 // Give extra word
19786 chunk = e.__localize('heading text');
19787 } else {
19788 chunk = selected.text + '\n';
19789 }
19790
19791 // transform selection and set the cursor into chunked text
19792 if ((pointer = 4, content.substr(selected.start - pointer, pointer) === '### ') ||
19793 (pointer = 3, content.substr(selected.start - pointer, pointer) === '###')) {
19794 e.setSelection(selected.start - pointer, selected.end);
19795 e.replaceSelection(chunk);
19796 cursor = selected.start - pointer;
19797 } else if (selected.start > 0 && (prevChar = content.substr(selected.start - 1, 1), !!prevChar && prevChar != '\n')) {
19798 e.replaceSelection('\n\n### ' + chunk);
19799 cursor = selected.start + 6;
19800 } else {
19801 // Empty string before element
19802 e.replaceSelection('### ' + chunk);
19803 cursor = selected.start + 4;
19804 }
19805
19806 // Set the cursor
19807 e.setSelection(cursor, cursor + chunk.length);
19808 }
19809 }]
19810 }, {
19811 name: 'groupLink',
19812 data: [{
19813 name: 'cmdUrl',
19814 title: 'URL/Link',
19815 hotkey: 'Ctrl+L',
19816 icon: {
19817 glyph: 'glyphicon glyphicon-link',
19818 fa: 'fa fa-link',
19819 'fa-3': 'icon-link',
19820 'fa-5': 'fas fa-link',
19821 octicons: 'octicon octicon-link'
19822 },
19823 callback: function(e) {
19824 // Give [] surround the selection and prepend the link
19825 var chunk, cursor, selected = e.getSelection(),
19826 content = e.getContent(),
19827 link;
19828
19829 if (selected.length === 0) {
19830 // Give extra word
19831 chunk = e.__localize('enter link description here');
19832 } else {
19833 chunk = selected.text;
19834 }
19835
19836 link = prompt(e.__localize('Insert Hyperlink'), 'http://');
19837
19838 var urlRegex = new RegExp('^((http|https)://|(mailto:)|(//))[a-z0-9]', 'i');
19839 if (link !== null && link !== '' && link !== 'http://' && urlRegex.test(link)) {
19840 // transform selection and set the cursor into chunked text
19841 e.replaceSelection('[' + chunk + '](' + link + ')');
19842 cursor = selected.start + 1;
19843
19844 // Set the cursor
19845 e.setSelection(cursor, cursor + chunk.length);
19846 }
19847 }
19848 }, {
19849 name: 'cmdImage',
19850 title: 'Image',
19851 hotkey: 'Ctrl+G',
19852 icon: {
19853 glyph: 'glyphicon glyphicon-picture',
19854 fa: 'fa fa-picture-o',
19855 'fa-3': 'icon-picture',
19856 'fa-5': 'far fa-image',
19857 octicons: 'octicon octicon-file-media'
19858 },
19859 callback: function(e) {
19860 // Give ![] surround the selection and prepend the image link
19861 var chunk, cursor, selected = e.getSelection(),
19862 content = e.getContent(),
19863 link;
19864
19865 if (selected.length === 0) {
19866 // Give extra word
19867 chunk = e.__localize('enter image description here');
19868 } else {
19869 chunk = selected.text;
19870 }
19871
19872 link = prompt(e.__localize('Insert Image Hyperlink'), 'http://');
19873
19874 var urlRegex = new RegExp('^((http|https)://|(//))[a-z0-9]', 'i');
19875 if (link !== null && link !== '' && link !== 'http://' && urlRegex.test(link)) {
19876 var sanitizedLink = $('<div>' + link + '</div>').text();
19877
19878 // transform selection and set the cursor into chunked text
19879 e.replaceSelection(' + '")');
19880 cursor = selected.start + 2;
19881
19882 // Set the next tab
19883 e.setNextTab(e.__localize('enter image title here'));
19884
19885 // Set the cursor
19886 e.setSelection(cursor, cursor + chunk.length);
19887 }
19888 }
19889 }]
19890 }, {
19891 name: 'groupMisc',
19892 data: [{
19893 name: 'cmdList',
19894 hotkey: 'Ctrl+U',
19895 title: 'Unordered List',
19896 icon: {
19897 glyph: 'glyphicon glyphicon-list',
19898 fa: 'fa fa-list',
19899 'fa-3': 'icon-list-ul',
19900 'fa-5': 'fas fa-list-ul',
19901 octicons: 'octicon octicon-list-unordered'
19902 },
19903 callback: function(e) {
19904 // Prepend/Give - surround the selection
19905 var chunk, cursor, selected = e.getSelection(),
19906 content = e.getContent();
19907
19908 // transform selection and set the cursor into chunked text
19909 if (selected.length === 0) {
19910 // Give extra word
19911 chunk = e.__localize('list text here');
19912
19913 e.replaceSelection('- ' + chunk);
19914 // Set the cursor
19915 cursor = selected.start + 2;
19916 } else {
19917 if (selected.text.indexOf('\n') < 0) {
19918 chunk = selected.text;
19919
19920 e.replaceSelection('- ' + chunk);
19921
19922 // Set the cursor
19923 cursor = selected.start + 2;
19924 } else {
19925 var list = [];
19926
19927 list = selected.text.split('\n');
19928 chunk = list[0];
19929
19930 $.each(list, function(k, v) {
19931 list[k] = '- ' + v;
19932 });
19933
19934 e.replaceSelection('\n\n' + list.join('\n'));
19935
19936 // Set the cursor
19937 cursor = selected.start + 4;
19938 }
19939 }
19940
19941 // Set the cursor
19942 e.setSelection(cursor, cursor + chunk.length);
19943 }
19944 }, {
19945 name: 'cmdListO',
19946 hotkey: 'Ctrl+O',
19947 title: 'Ordered List',
19948 icon: {
19949 glyph: 'glyphicon glyphicon-th-list',
19950 fa: 'fa fa-list-ol',
19951 'fa-3': 'icon-list-ol',
19952 'fa-5': 'fas fa-list-ol',
19953 octicons: 'octicon octicon-list-ordered'
19954 },
19955 callback: function(e) {
19956
19957 // Prepend/Give - surround the selection
19958 var chunk, cursor, selected = e.getSelection(),
19959 content = e.getContent();
19960
19961 // transform selection and set the cursor into chunked text
19962 if (selected.length === 0) {
19963 // Give extra word
19964 chunk = e.__localize('list text here');
19965 e.replaceSelection('1. ' + chunk);
19966 // Set the cursor
19967 cursor = selected.start + 3;
19968 } else {
19969 if (selected.text.indexOf('\n') < 0) {
19970 chunk = selected.text;
19971
19972 e.replaceSelection('1. ' + chunk);
19973
19974 // Set the cursor
19975 cursor = selected.start + 3;
19976 } else {
19977 var i = 1;
19978 var list = [];
19979
19980 list = selected.text.split('\n');
19981 chunk = list[0];
19982
19983 $.each(list, function(k, v) {
19984 list[k] = i + '. ' + v;
19985 i++;
19986 });
19987
19988 e.replaceSelection('\n\n' + list.join('\n'));
19989
19990 // Set the cursor
19991 cursor = selected.start + 5;
19992 }
19993 }
19994
19995 // Set the cursor
19996 e.setSelection(cursor, cursor + chunk.length);
19997 }
19998 }, {
19999 name: 'cmdCode',
20000 hotkey: 'Ctrl+K',
20001 title: 'Code',
20002 icon: {
20003 glyph: 'glyphicon glyphicon-console',
20004 fa: 'fa fa-code',
20005 'fa-3': 'icon-code',
20006 'fa-5': 'fas fa-code',
20007 octicons: 'octicon octicon-code'
20008 },
20009 callback: function(e) {
20010 // Give/remove ** surround the selection
20011 var chunk, cursor, selected = e.getSelection(),
20012 content = e.getContent();
20013
20014 if (selected.length === 0) {
20015 // Give extra word
20016 chunk = e.__localize('code text here');
20017 } else {
20018 chunk = selected.text;
20019 }
20020
20021 // transform selection and set the cursor into chunked text
20022 if (content.substr(selected.start - 4, 4) === '```\n' &&
20023 content.substr(selected.end, 4) === '\n```') {
20024 e.setSelection(selected.start - 4, selected.end + 4);
20025 e.replaceSelection(chunk);
20026 cursor = selected.start - 4;
20027 } else if (content.substr(selected.start - 1, 1) === '`' &&
20028 content.substr(selected.end, 1) === '`') {
20029 e.setSelection(selected.start - 1, selected.end + 1);
20030 e.replaceSelection(chunk);
20031 cursor = selected.start - 1;
20032 } else if (content.indexOf('\n') > -1) {
20033 e.replaceSelection('```\n' + chunk + '\n```');
20034 cursor = selected.start + 4;
20035 } else {
20036 e.replaceSelection('`' + chunk + '`');
20037 cursor = selected.start + 1;
20038 }
20039
20040 // Set the cursor
20041 e.setSelection(cursor, cursor + chunk.length);
20042 }
20043 }, {
20044 name: 'cmdQuote',
20045 hotkey: 'Ctrl+Q',
20046 title: 'Quote',
20047 icon: {
20048 glyph: 'glyphicon glyphicon-comment',
20049 fa: 'fa fa-quote-left',
20050 'fa-3': 'icon-quote-left',
20051 'fa-5': 'fas fa-quote-left',
20052 octicons: 'octicon octicon-quote'
20053 },
20054 callback: function(e) {
20055 // Prepend/Give - surround the selection
20056 var chunk, cursor, selected = e.getSelection(),
20057 content = e.getContent();
20058
20059 // transform selection and set the cursor into chunked text
20060 if (selected.length === 0) {
20061 // Give extra word
20062 chunk = e.__localize('quote here');
20063
20064 e.replaceSelection('> ' + chunk);
20065
20066 // Set the cursor
20067 cursor = selected.start + 2;
20068 } else {
20069 if (selected.text.indexOf('\n') < 0) {
20070 chunk = selected.text;
20071
20072 e.replaceSelection('> ' + chunk);
20073
20074 // Set the cursor
20075 cursor = selected.start + 2;
20076 } else {
20077 var list = [];
20078
20079 list = selected.text.split('\n');
20080 chunk = list[0];
20081
20082 $.each(list, function(k, v) {
20083 list[k] = '> ' + v;
20084 });
20085
20086 e.replaceSelection('\n\n' + list.join('\n'));
20087
20088 // Set the cursor
20089 cursor = selected.start + 4;
20090 }
20091 }
20092
20093 // Set the cursor
20094 e.setSelection(cursor, cursor + chunk.length);
20095 }
20096 }]
20097 }, {
20098 name: 'groupUtil',
20099 data: [{
20100 name: 'cmdPreview',
20101 toggle: true,
20102 hotkey: 'Ctrl+P',
20103 title: 'Preview',
20104 btnText: 'Preview',
20105 btnClass: 'btn btn-primary btn-sm',
20106 icon: {
20107 glyph: 'glyphicon glyphicon-search',
20108 fa: 'fa fa-search',
20109 'fa-3': 'icon-search',
20110 'fa-5': 'fas fa-search',
20111 octicons: 'octicon octicon-search'
20112 },
20113 callback: function(e) {
20114 // Check the preview mode and toggle based on this flag
20115 var isPreview = e.$isPreview,
20116 content;
20117
20118 if (isPreview === false) {
20119 // Give flag that tells the editor to enter preview mode
20120 e.showPreview();
20121 } else {
20122 e.hidePreview();
20123 }
20124 }
20125 }]
20126 }]
20127 ],
20128 customIcons: {},
20129 additionalButtons: [], // Place to hook more buttons by code
20130 reorderButtonGroups: [],
20131 hiddenButtons: [], // Default hidden buttons
20132 disabledButtons: [], // Default disabled buttons
20133 footer: '',
20134 fullscreen: {
20135 enable: true,
20136 icons: {
20137 fullscreenOn: {
20138 name: "fullscreenOn",
20139 icon: {
20140 fa: 'fa fa-expand',
20141 glyph: 'glyphicon glyphicon-fullscreen',
20142 'fa-3': 'icon-resize-full',
20143 'fa-5': 'fas fa-expand-arrows-alt',
20144 octicons: 'octicon octicon-link-external'
20145 }
20146 },
20147 fullscreenOff: {
20148 name: "fullscreenOff",
20149 icon: {
20150 fa: 'fa fa-compress',
20151 glyph: 'glyphicon glyphicon-fullscreen',
20152 'fa-3': 'icon-resize-small',
20153 'fa-5': 'fas fa-compress',
20154 octicons: 'octicon octicon-browser'
20155 }
20156 }
20157 }
20158 },
20159
20160 /* Events hook */
20161 onShow: function(e) {},
20162 onPreview: function(e) {},
20163 onPreviewEnd: function(e) {},
20164 onSave: function(e) {},
20165 onBlur: function(e) {},
20166 onFocus: function(e) {},
20167 onChange: function(e) {},
20168 onFullscreen: function(e) {},
20169 onFullscreenExit: function(e) {},
20170 onSelect: function(e) {}
20171 };
20172
20173 $.fn.markdown.Constructor = Markdown;
20174
20175
20176 /* MARKDOWN NO CONFLICT
20177 * ==================== */
20178
20179 $.fn.markdown.noConflict = function() {
20180 $.fn.markdown = old;
20181 return this;
20182 };
20183
20184 /* MARKDOWN GLOBAL FUNCTION & DATA-API
20185 * ==================================== */
20186 var initMarkdown = function(el) {
20187 var $this = el;
20188
20189 if ($this.data('markdown')) {
20190 $this.data('markdown').showEditor();
20191 return;
20192 }
20193
20194 $this.markdown();
20195 };
20196
20197 var blurNonFocused = function(e) {
20198 var $activeElement = $(document.activeElement);
20199
20200 // Blur event
20201 $(document).find('.md-editor').each(function() {
20202 var $this = $(this),
20203 focused = $activeElement.closest('.md-editor')[0] === this,
20204 attachedMarkdown = $this.find('textarea').data('markdown') ||
20205 $this.find('div[data-provider="markdown-preview"]').data('markdown');
20206
20207 if (attachedMarkdown && !focused) {
20208 attachedMarkdown.blur();
20209 }
20210 });
20211 };
20212
20213 $(document)
20214 .on('click.markdown.data-api', '[data-provide="markdown-editable"]', function(e) {
20215 initMarkdown($(this));
20216 e.preventDefault();
20217 })
20218 .on('click focusin', function(e) {
20219 blurNonFocused(e);
20220 })
20221 .ready(function() {
20222 $('textarea[data-provide="markdown"]').each(function() {
20223 initMarkdown($(this));
20224 });
20225 });
20226
20227}));
20228
20229/*
20230 * Arabic translation for bootstrap-markdown
20231 * George Ajam <george.ejaam@gmail.com>
20232 */
20233(function ($) {
20234 $.fn.markdown.messages.nl = {
20235 'Bold': "غامق",
20236 'Italic': "مائل",
20237 'Heading': "عنوان",
20238 'URL/Link': "URL/رابط",
20239 'Image': "صورة",
20240 'List': "قائمة",
20241 'Preview': "استعراض",
20242 'strong text': "نص غامق",
20243 'emphasized text': "نص هام",
20244 'heading text': "العنوان",
20245 'enter link description here': "ادخل وصف الرابط هنا",
20246 'Insert Hyperlink': "ادخل الرابط هنا",
20247 'enter image description here': "ادخل وصف الصورة هنا",
20248 'Insert Image Hyperlink': "ادخل رابط الصورة هنا",
20249 'enter image title here': "ادخل عنوان الصورة هنا",
20250 'list text here': "اكتب النص هنا"
20251 };
20252}(jQuery));
20253
20254/**
20255 * Czech translation for bootstrap-markdown
20256 * Vít Kabele <vit@kabele.me>
20257 */
20258(function ($) {
20259 $.fn.markdown.messages.cs = {
20260 'Bold': "Tučně",
20261 'Italic': "Kurzíva",
20262 'Heading': "Nadpis",
20263 'URL/Link': "URL/Odkaz",
20264 'Image': "Obrázek",
20265 'Unordered List': "Seznam",
20266 'Ordered List': "Seřazený seznam",
20267 'Code': "Úsek kódu",
20268 'Quote': "Citace",
20269 'Preview': "Náhled",
20270 'strong text': "tučný text",
20271 'emphasized text': "zdůrazněný text",
20272 'heading text': "text nadpisu",
20273 'enter link description here': "sem vlož popis odkazu",
20274 'Insert Hyperlink': "Vložit Hyperlink",
20275 'enter image description here': "sem vlož popis obrázku",
20276 'Insert Image Hyperlink': "Vlož adresu obrázku",
20277 'enter image title here': "sem vlož popis obrázku",
20278 'list text here': "položka seznamu"
20279 };
20280}(jQuery));
20281
20282/**
20283 * Danish translation for bootstrap-markdown
20284 * Dan Storm <storm@catalystcode.net>
20285 */
20286(function ($) {
20287 $.fn.markdown.messages.da = {
20288 'Bold': 'Fed',
20289 'Italic': 'Kursiv',
20290 'Heading': 'Overskrift',
20291 'URL/Link': 'URL/Link',
20292 'Image': 'Billede',
20293 'List': 'Liste',
20294 'Preview': 'Forhåndsvisning',
20295 'strong text': 'stærk tekst',
20296 'emphasized text': 'fremhævet tekst',
20297 'heading text': 'overskrift tekst',
20298 'enter link description here': 'Skriv link beskrivelse her',
20299 'Insert Hyperlink': 'Indsæt link',
20300 'enter image description here': 'Indsæt billede beskrivelse her',
20301 'Insert Image Hyperlink': 'Indsæt billede link',
20302 'enter image title here': 'Indsæt billede titel',
20303 'list text here': 'Indsæt liste tekst her',
20304 'quote here': 'Indsæt citat her',
20305 'code text here': 'Indsæt kode her'
20306 };
20307}(jQuery));
20308
20309/**
20310 * German translation for bootstrap-markdown
20311 * Tobias Nitsche <tobias-nitsche@gmx.net>
20312 */
20313(function ($) {
20314 $.fn.markdown.messages.de = {
20315 'Bold': "Fett",
20316 'Italic': "Kursiv",
20317 'Heading': "Überschrift",
20318 'URL/Link': "Link hinzufügen",
20319 'Image': "Bild hinzufügen",
20320 'Unordered List': "Unnummerierte Liste",
20321 'Ordered List': "Nummerierte Liste",
20322 'Code': "Quelltext",
20323 'code text here': "Quelltext hier einfügen",
20324 'Quote': "Zitat",
20325 'quote here': "Zitat hier einfügen",
20326 'Preview': "Vorschau",
20327 'Save': "Speichern",
20328 'strong text': "Sehr betonter Text",
20329 'emphasized text': "Betonter Text",
20330 'heading text': "Überschrift Text",
20331 'enter link description here': "Linkbeschreibung",
20332 'Insert Hyperlink': "URL",
20333 'enter image description here': "Bildbeschreibung",
20334 'Insert Image Hyperlink': "Bild-URL",
20335 'enter image title here': "Titel des Bildes",
20336 'list text here': "Aufzählungs-Text"
20337 };
20338}(jQuery));
20339
20340/**
20341 * Spanish translation for bootstrap-markdown
20342 * by Leandro Poblet <leandrodrhouse@gmail.com>
20343 */
20344(function ($) {
20345 $.fn.markdown.messages.es = {
20346 'Bold': "Negrita",
20347 'Italic': "Itálica",
20348 'Heading': "Título",
20349 'URL/Link': "Inserte un link",
20350 'Image': "Inserte una imagen",
20351 'List': "Lista de items",
20352 'Unordered List': "Lista desordenada",
20353 'Ordered List': "Lista ordenada",
20354 'Code': "Código",
20355 'Quote': "Cita",
20356 'Preview': "Previsualizar",
20357 'strong text': "Texto importante",
20358 'emphasized text': "Texto con énfasis",
20359 'heading text': "Texto de título",
20360 'enter link description here': "Descripción del link",
20361 'Insert Hyperlink': "Inserte un hipervínculo",
20362 'enter image description here': "Descripción de la imagen",
20363 'Insert Image Hyperlink': "Inserte una imagen con un hipervínculo",
20364 'enter image title here': "Inserte una imagen con título",
20365 'list text here': "Texto de lista aquí",
20366 'code text here': "Código aquí",
20367 'quote here': "Cita aquí",
20368 'Save': "Guardar"
20369 };
20370}(jQuery));
20371
20372/**
20373 * Persian(Farsi) translation for bootstrap-markdown
20374 * Sajad Dehshiri <Pelakweb.ir>
20375 */
20376(function ($) {
20377 $.fn.markdown.messages.fa = {
20378 'Bold': "توپر",
20379 'Italic': "مورب",
20380 'Heading': "عنوان",
20381 'URL/Link': "پیوند",
20382 'Image': "تصویر",
20383 'List': "فهرست",
20384 'Preview': "پیش نمایش",
20385 'strong text': "متن ضخیم",
20386 'emphasized text': "نوشته تاکیدی",
20387 'heading text': "عنوان",
20388 'enter link description here': "توضیحات پیوند را بنویسید.",
20389 'Insert Hyperlink': "پیوند را درج نمایید:",
20390 'enter image description here': "توضیحی برای تصوی بنویسید.",
20391 'Insert Image Hyperlink': "آدرس تصویر را بنویسید.",
20392 'enter image title here': "عنوان تصویر را اینجا بنویسید",
20393 'list text here': "محل متن فهرست"
20394 };
20395}(jQuery));
20396
20397/**
20398 * French translation for bootstrap-markdown
20399 * Benoît Bourgeois <bierdok@gmail.com>
20400 */
20401(function ($) {
20402 $.fn.markdown.messages.fr = {
20403 'Bold': "Gras",
20404 'Italic': "Italique",
20405 'Heading': "Titre",
20406 'URL/Link': "Insérer un lien HTTP",
20407 'Image': "Insérer une image",
20408 'List': "Liste à puces",
20409 'Preview': "Prévisualiser",
20410 'strong text': "texte important",
20411 'emphasized text': "texte en italique",
20412 'heading text': "texte d'entête",
20413 'enter link description here': "entrez la description du lien ici",
20414 'Insert Hyperlink': "Insérez le lien hypertexte",
20415 'enter image description here': "entrez la description de l'image ici",
20416 'Insert Image Hyperlink': "Insérez le lien hypertexte de l'image",
20417 'enter image title here': "entrez le titre de l'image ici",
20418 'list text here': "texte à puce ici",
20419 'Save': "Sauvegarder",
20420 'Ordered List': "Liste ordonnée",
20421 'Unordered List': "Liste désordonnée",
20422 'Quote': "Citation",
20423 'quote here': "Votre citation",
20424 'Code': "Code",
20425 'code text here': "écrire du code ici"
20426 };
20427}(jQuery));
20428
20429/**
20430 * Japanese translation for bootstrap-markdown
20431 * Kenta Murakami <kntmrkm@gmail.com>
20432 */
20433(function ($) {
20434 $.fn.markdown.messages.ja = {
20435 'Bold': "太字",
20436 'Italic': "斜体",
20437 'Heading': "見出し",
20438 'URL/Link': "リンク",
20439 'Image': "画像",
20440 'Unordered List': "リスト",
20441 'Ordered List': "数字リスト",
20442 'Code': "コード",
20443 'Quote': "引用",
20444 'Preview': "プレビュー",
20445 'strong text': "太字",
20446 'emphasized text': "強調",
20447 'heading text': "見出し",
20448 'enter link description here': "リンク説明",
20449 'Insert Hyperlink': "リンク挿入",
20450 'enter image description here': "画像説明",
20451 'Insert Image Hyperlink': "画像挿入",
20452 'enter image title here': "画像タイトル",
20453 'list text here': "リスト挿入",
20454 'code text here': "コード",
20455 'quote here': "引用挿入"
20456 };
20457}(jQuery));
20458
20459/**
20460 + * Korean translation for bootstrap-markdown
20461 + * WoongBi Kim <ssinss@gmail.com>
20462 + */
20463(function ($) {
20464 $.fn.markdown.messages.kr = {
20465 'Bold': "진하게",
20466 'Italic': "이탤릭체",
20467 'Heading': "머리글",
20468 'URL/Link': "링크주소",
20469 'Image': "이미지",
20470 'List': "리스트",
20471 'Preview': "미리보기",
20472 'strong text': "강한 강조 텍스트",
20473 'emphasized text': "강조 텍스트",
20474 'heading text': "머리글 텍스트",
20475 'enter link description here': "여기에 링크의 설명을 적으세요",
20476 'Insert Hyperlink': "하이퍼링크 삽입",
20477 'enter image description here': "여기세 이미지 설명을 적으세요",
20478 'Insert Image Hyperlink': "이미지 링크 삽입",
20479 'enter image title here': "여기에 이미지 제목을 적으세요",
20480 'list text here': "리스트 텍스트"
20481 };
20482}(jQuery));
20483
20484/**
20485 * Norwegian bokmål translation for bootstrap-markdown
20486 * Tobias Bohwalli <hi@futhr.io>
20487 */
20488(function ($) {
20489 $.fn.markdown.messages.nb = {
20490 'Bold': 'Fet',
20491 'Italic': 'Kursiv',
20492 'Heading': 'Overskrift',
20493 'URL/Link': 'URL/Lenke',
20494 'Image': 'Bilde',
20495 'List': 'Liste',
20496 'Preview': 'Forhåndsvisning',
20497 'strong text': 'sterk tekst',
20498 'emphasized text': 'streket tekst',
20499 'heading text': 'overskriften tekst',
20500 'enter link description here': 'Skriv linken beskrivelse her',
20501 'Insert Hyperlink': 'Sett inn lenke',
20502 'enter image description here': 'Angi bildebeskrivelse her',
20503 'Insert Image Hyperlink': 'Sett inn lenke for bilde',
20504 'enter image title here': 'Angi bildetittel her',
20505 'list text here': 'liste tekst her'
20506 };
20507}(jQuery));
20508
20509/**
20510 * Dutch translation for bootstrap-markdown
20511 * Jeroen Thora <jeroenthora@gmail.com>
20512 */
20513(function ($) {
20514 $.fn.markdown.messages.nl = {
20515 'Bold': "Vet",
20516 'Italic': "Cursief",
20517 'Heading': "Titel",
20518 'URL/Link': "URL/Link",
20519 'Image': "Afbeelding",
20520 'List': "Lijst",
20521 'Preview': "Voorbeeld",
20522 'strong text': "vet gedrukte tekst",
20523 'emphasized text': "schuin gedrukte tekst",
20524 'heading text': "Titel",
20525 'enter link description here': "Voer een link beschrijving in",
20526 'Insert Hyperlink': "Voer een http link in",
20527 'enter image description here': "Voer een afbeelding beschrijving in",
20528 'Insert Image Hyperlink': "Voer een afbeelding link in",
20529 'enter image title here': "Voer de afbeelding titel in",
20530 'list text here': "lijst item"
20531 };
20532}(jQuery));
20533
20534/**
20535 * Polish translation for bootstrap-markdown
20536 * Marek Kaput
20537 */
20538(function ($) {
20539 $.fn.markdown.messages.pl = {
20540 'Bold': "Pogrubienie",
20541 'Italic': "Kursywa",
20542 'Heading': "Nagłówek",
20543 'URL/Link': "Wstaw link",
20544 'Image': "Wstaw obrazek",
20545 'Unordered List': "Lista punktowana",
20546 'Ordered List': "Lista numerowana",
20547 'Code': "Kod źródłowy",
20548 'Quote': "Cytat",
20549 'Preview': "Podgląd",
20550 'strong text': "pogrubiony tekst",
20551 'emphasized text': "pochylony tekst",
20552 'heading text': "nagłówek",
20553 'enter link description here': "opis linka",
20554 'Insert Hyperlink': "Wstaw link",
20555 'enter image description here': "opis obrazka",
20556 'Insert Image Hyperlink': "Wstaw obrazek",
20557 'enter image title here': "tytuł obrazka",
20558 'list text here': "lista"
20559 };
20560}(jQuery));
20561
20562/**
20563 * Slovenian translation for bootstrap-markdown
20564 * Davor Padovan <davor.padovan@gmail.com>
20565 */
20566(function ($) {
20567 $.fn.markdown.messages.sl = {
20568 'Bold': "Odebeljeno",
20569 'Italic': "Poševno",
20570 'Heading': "Naslov",
20571 'URL/Link': "Povezava",
20572 'Image': "Slika",
20573 'Unordered List': "Neurejen seznam",
20574 'Ordered List': "Urejen seznam",
20575 'Code': "Koda",
20576 'Quote': "Citat",
20577 'Preview': "Predogled",
20578 'strong text': "odebeljeno besedilo",
20579 'emphasized text': "poševno besedilo",
20580 'heading text': "naslov",
20581 'enter link description here': "opis povezave",
20582 'Insert Hyperlink': "Vstavi povezavo",
20583 'enter image description here': "opis slike",
20584 'Insert Image Hyperlink': "Vstavi povezavo do slike",
20585 'enter image title here': "naslov slike",
20586 'list text here': "seznam"
20587 };
20588}(jQuery));
20589
20590/**
20591 * Swedish translation for bootstrap-markdown
20592 * Tobias Bohwalli <hi@futhr.io>
20593 */
20594(function ($) {
20595 $.fn.markdown.messages.sv = {
20596 'Bold': 'Fet',
20597 'Italic': 'Kursiv',
20598 'Heading': 'Rubrik',
20599 'URL/Link': 'URL/Länk',
20600 'Image': 'Bild',
20601 'List': 'Lista',
20602 'Preview': 'Förhandsgranska',
20603 'strong text': 'fet text',
20604 'emphasized text': 'överstruken text',
20605 'heading text': 'Rubrik',
20606 'enter link description here': 'Ange länk beskrivning här',
20607 'Insert Hyperlink': 'Sätt in länk',
20608 'enter image description here': 'Ange bild beskrivning här',
20609 'Insert Image Hyperlink': 'Sätt in länk för bild',
20610 'enter image title here': 'Ange bild rubrik här',
20611 'list text here': 'list text'
20612 };
20613}(jQuery));
20614
20615/**
20616 * Turkish translation for bootstrap-markdown
20617 * Serkan Algur <info@wpadami.com>
20618 */
20619(function ($) {
20620 $.fn.markdown.messages.tr = {
20621 'Bold': "Kalın",
20622 'Italic': "İtalik",
20623 'Heading': "Başlık",
20624 'URL/Link': "Link ekle",
20625 'Image': "Resim ekle",
20626 'List': "Liste Oluşturun",
20627 'Preview': "Önizleme",
20628 'strong text': "kalın yazı",
20629 'emphasized text': "italik yazı",
20630 'heading text': "Başlık Yazısı",
20631 'enter link description here': "Link açıklamasını buraya girin",
20632 'Insert Hyperlink': "İnternet adresi girin",
20633 'enter image description here': "resim açıklamasını buraya ekleyin",
20634 'Insert Image Hyperlink': "Resim linkini ekleyin",
20635 'enter image title here': "resim başlığını buraya ekleyin",
20636 'list text here': "liste yazısı",
20637 'Save' : "Kaydet",
20638 'Ordered List' : "Numaralı Liste",
20639 'Unordered List' : "Madde imli liste",
20640 'Quote' : "Alıntı",
20641 'quote here' : "alıntıyı buraya ekleyin",
20642 'Code' : "Kod",
20643 'code text here' : "kodu buraya ekleyin"
20644 };
20645}(jQuery));
20646
20647/**
20648 * Chinese translation for bootstrap-markdown
20649 * benhaile <denghaier@163.com>
20650 */
20651(function ($) {
20652 $.fn.markdown.messages.zh = {
20653 'Bold': "粗体",
20654 'Italic': "斜体",
20655 'Heading': "标题",
20656 'URL/Link': "链接",
20657 'Image': "图片",
20658 'List': "列表",
20659 'Unordered List': "无序列表",
20660 'Ordered List': "有序列表",
20661 'Code': "代码",
20662 'Quote': "引用",
20663 'Preview': "预览",
20664 'strong text': "粗体",
20665 'emphasized text': "强调",
20666 'heading text': "标题",
20667 'enter link description here': "输入链接说明",
20668 'Insert Hyperlink': "URL地址",
20669 'enter image description here': "输入图片说明",
20670 'Insert Image Hyperlink': "图片URL地址",
20671 'enter image title here': "在这里输入图片标题",
20672 'list text here': "这里是列表文本",
20673 'code text here': "这里输入代码",
20674 'quote here': "这里输入引用文本"
20675 };
20676}(jQuery));
20677
20678/*! DataTables 1.10.12
20679 * ©2008-2015 SpryMedia Ltd - datatables.net/license
20680 */
20681
20682/**
20683 * @summary DataTables
20684 * @description Paginate, search and order HTML tables
20685 * @version 1.10.12
20686 * @file jquery.dataTables.js
20687 * @author SpryMedia Ltd (www.sprymedia.co.uk)
20688 * @contact www.sprymedia.co.uk/contact
20689 * @copyright Copyright 2008-2015 SpryMedia Ltd.
20690 *
20691 * This source file is free software, available under the following license:
20692 * MIT license - http://datatables.net/license
20693 *
20694 * This source file is distributed in the hope that it will be useful, but
20695 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20696 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20697 *
20698 * For details please refer to: http://www.datatables.net
20699 */
20700
20701/*jslint evil: true, undef: true, browser: true */
20702/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
20703
20704(function( factory ) {
20705 "use strict";
20706
20707 if ( typeof define === 'function' && define.amd ) {
20708 // AMD
20709 define( ['jquery'], function ( $ ) {
20710 return factory( $, window, document );
20711 } );
20712 }
20713 else if ( typeof exports === 'object' ) {
20714 // CommonJS
20715 module.exports = function (root, $) {
20716 if ( ! root ) {
20717 // CommonJS environments without a window global must pass a
20718 // root. This will give an error otherwise
20719 root = window;
20720 }
20721
20722 if ( ! $ ) {
20723 $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
20724 require('jquery') :
20725 require('jquery')( root );
20726 }
20727
20728 return factory( $, root, root.document );
20729 };
20730 }
20731 else {
20732 // Browser
20733 factory( jQuery, window, document );
20734 }
20735}
20736(function( $, window, document, undefined ) {
20737 "use strict";
20738
20739 /**
20740 * DataTables is a plug-in for the jQuery Javascript library. It is a highly
20741 * flexible tool, based upon the foundations of progressive enhancement,
20742 * which will add advanced interaction controls to any HTML table. For a
20743 * full list of features please refer to
20744 * [DataTables.net](href="http://datatables.net).
20745 *
20746 * Note that the `DataTable` object is not a global variable but is aliased
20747 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
20748 * be accessed.
20749 *
20750 * @class
20751 * @param {object} [init={}] Configuration object for DataTables. Options
20752 * are defined by {@link DataTable.defaults}
20753 * @requires jQuery 1.7+
20754 *
20755 * @example
20756 * // Basic initialisation
20757 * $(document).ready( function {
20758 * $('#example').dataTable();
20759 * } );
20760 *
20761 * @example
20762 * // Initialisation with configuration options - in this case, disable
20763 * // pagination and sorting.
20764 * $(document).ready( function {
20765 * $('#example').dataTable( {
20766 * "paginate": false,
20767 * "sort": false
20768 * } );
20769 * } );
20770 */
20771 var DataTable = function ( options )
20772 {
20773 /**
20774 * Perform a jQuery selector action on the table's TR elements (from the tbody) and
20775 * return the resulting jQuery object.
20776 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
20777 * @param {object} [oOpts] Optional parameters for modifying the rows to be included
20778 * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
20779 * criterion ("applied") or all TR elements (i.e. no filter).
20780 * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
20781 * Can be either 'current', whereby the current sorting of the table is used, or
20782 * 'original' whereby the original order the data was read into the table is used.
20783 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
20784 * ("current") or not ("all"). If 'current' is given, then order is assumed to be
20785 * 'current' and filter is 'applied', regardless of what they might be given as.
20786 * @returns {object} jQuery object, filtered by the given selector.
20787 * @dtopt API
20788 * @deprecated Since v1.10
20789 *
20790 * @example
20791 * $(document).ready(function() {
20792 * var oTable = $('#example').dataTable();
20793 *
20794 * // Highlight every second row
20795 * oTable.$('tr:odd').css('backgroundColor', 'blue');
20796 * } );
20797 *
20798 * @example
20799 * $(document).ready(function() {
20800 * var oTable = $('#example').dataTable();
20801 *
20802 * // Filter to rows with 'Webkit' in them, add a background colour and then
20803 * // remove the filter, thus highlighting the 'Webkit' rows only.
20804 * oTable.fnFilter('Webkit');
20805 * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
20806 * oTable.fnFilter('');
20807 * } );
20808 */
20809 this.$ = function ( sSelector, oOpts )
20810 {
20811 return this.api(true).$( sSelector, oOpts );
20812 };
20813
20814
20815 /**
20816 * Almost identical to $ in operation, but in this case returns the data for the matched
20817 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
20818 * rather than any descendants, so the data can be obtained for the row/cell. If matching
20819 * rows are found, the data returned is the original data array/object that was used to
20820 * create the row (or a generated array if from a DOM source).
20821 *
20822 * This method is often useful in-combination with $ where both functions are given the
20823 * same parameters and the array indexes will match identically.
20824 * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
20825 * @param {object} [oOpts] Optional parameters for modifying the rows to be included
20826 * @param {string} [oOpts.filter=none] Select elements that meet the current filter
20827 * criterion ("applied") or all elements (i.e. no filter).
20828 * @param {string} [oOpts.order=current] Order of the data in the processed array.
20829 * Can be either 'current', whereby the current sorting of the table is used, or
20830 * 'original' whereby the original order the data was read into the table is used.
20831 * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
20832 * ("current") or not ("all"). If 'current' is given, then order is assumed to be
20833 * 'current' and filter is 'applied', regardless of what they might be given as.
20834 * @returns {array} Data for the matched elements. If any elements, as a result of the
20835 * selector, were not TR, TD or TH elements in the DataTable, they will have a null
20836 * entry in the array.
20837 * @dtopt API
20838 * @deprecated Since v1.10
20839 *
20840 * @example
20841 * $(document).ready(function() {
20842 * var oTable = $('#example').dataTable();
20843 *
20844 * // Get the data from the first row in the table
20845 * var data = oTable._('tr:first');
20846 *
20847 * // Do something useful with the data
20848 * alert( "First cell is: "+data[0] );
20849 * } );
20850 *
20851 * @example
20852 * $(document).ready(function() {
20853 * var oTable = $('#example').dataTable();
20854 *
20855 * // Filter to 'Webkit' and get all data for
20856 * oTable.fnFilter('Webkit');
20857 * var data = oTable._('tr', {"search": "applied"});
20858 *
20859 * // Do something with the data
20860 * alert( data.length+" rows matched the search" );
20861 * } );
20862 */
20863 this._ = function ( sSelector, oOpts )
20864 {
20865 return this.api(true).rows( sSelector, oOpts ).data();
20866 };
20867
20868
20869 /**
20870 * Create a DataTables Api instance, with the currently selected tables for
20871 * the Api's context.
20872 * @param {boolean} [traditional=false] Set the API instance's context to be
20873 * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
20874 * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
20875 * or if all tables captured in the jQuery object should be used.
20876 * @return {DataTables.Api}
20877 */
20878 this.api = function ( traditional )
20879 {
20880 return traditional ?
20881 new _Api(
20882 _fnSettingsFromNode( this[ _ext.iApiIndex ] )
20883 ) :
20884 new _Api( this );
20885 };
20886
20887
20888 /**
20889 * Add a single new row or multiple rows of data to the table. Please note
20890 * that this is suitable for client-side processing only - if you are using
20891 * server-side processing (i.e. "bServerSide": true), then to add data, you
20892 * must add it to the data source, i.e. the server-side, through an Ajax call.
20893 * @param {array|object} data The data to be added to the table. This can be:
20894 * <ul>
20895 * <li>1D array of data - add a single row with the data provided</li>
20896 * <li>2D array of arrays - add multiple rows in a single call</li>
20897 * <li>object - data object when using <i>mData</i></li>
20898 * <li>array of objects - multiple data objects when using <i>mData</i></li>
20899 * </ul>
20900 * @param {bool} [redraw=true] redraw the table or not
20901 * @returns {array} An array of integers, representing the list of indexes in
20902 * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
20903 * the table.
20904 * @dtopt API
20905 * @deprecated Since v1.10
20906 *
20907 * @example
20908 * // Global var for counter
20909 * var giCount = 2;
20910 *
20911 * $(document).ready(function() {
20912 * $('#example').dataTable();
20913 * } );
20914 *
20915 * function fnClickAddRow() {
20916 * $('#example').dataTable().fnAddData( [
20917 * giCount+".1",
20918 * giCount+".2",
20919 * giCount+".3",
20920 * giCount+".4" ]
20921 * );
20922 *
20923 * giCount++;
20924 * }
20925 */
20926 this.fnAddData = function( data, redraw )
20927 {
20928 var api = this.api( true );
20929
20930 /* Check if we want to add multiple rows or not */
20931 var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
20932 api.rows.add( data ) :
20933 api.row.add( data );
20934
20935 if ( redraw === undefined || redraw ) {
20936 api.draw();
20937 }
20938
20939 return rows.flatten().toArray();
20940 };
20941
20942
20943 /**
20944 * This function will make DataTables recalculate the column sizes, based on the data
20945 * contained in the table and the sizes applied to the columns (in the DOM, CSS or
20946 * through the sWidth parameter). This can be useful when the width of the table's
20947 * parent element changes (for example a window resize).
20948 * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
20949 * @dtopt API
20950 * @deprecated Since v1.10
20951 *
20952 * @example
20953 * $(document).ready(function() {
20954 * var oTable = $('#example').dataTable( {
20955 * "sScrollY": "200px",
20956 * "bPaginate": false
20957 * } );
20958 *
20959 * $(window).bind('resize', function () {
20960 * oTable.fnAdjustColumnSizing();
20961 * } );
20962 * } );
20963 */
20964 this.fnAdjustColumnSizing = function ( bRedraw )
20965 {
20966 var api = this.api( true ).columns.adjust();
20967 var settings = api.settings()[0];
20968 var scroll = settings.oScroll;
20969
20970 if ( bRedraw === undefined || bRedraw ) {
20971 api.draw( false );
20972 }
20973 else if ( scroll.sX !== "" || scroll.sY !== "" ) {
20974 /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
20975 _fnScrollDraw( settings );
20976 }
20977 };
20978
20979
20980 /**
20981 * Quickly and simply clear a table
20982 * @param {bool} [bRedraw=true] redraw the table or not
20983 * @dtopt API
20984 * @deprecated Since v1.10
20985 *
20986 * @example
20987 * $(document).ready(function() {
20988 * var oTable = $('#example').dataTable();
20989 *
20990 * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
20991 * oTable.fnClearTable();
20992 * } );
20993 */
20994 this.fnClearTable = function( bRedraw )
20995 {
20996 var api = this.api( true ).clear();
20997
20998 if ( bRedraw === undefined || bRedraw ) {
20999 api.draw();
21000 }
21001 };
21002
21003
21004 /**
21005 * The exact opposite of 'opening' a row, this function will close any rows which
21006 * are currently 'open'.
21007 * @param {node} nTr the table row to 'close'
21008 * @returns {int} 0 on success, or 1 if failed (can't find the row)
21009 * @dtopt API
21010 * @deprecated Since v1.10
21011 *
21012 * @example
21013 * $(document).ready(function() {
21014 * var oTable;
21015 *
21016 * // 'open' an information row when a row is clicked on
21017 * $('#example tbody tr').click( function () {
21018 * if ( oTable.fnIsOpen(this) ) {
21019 * oTable.fnClose( this );
21020 * } else {
21021 * oTable.fnOpen( this, "Temporary row opened", "info_row" );
21022 * }
21023 * } );
21024 *
21025 * oTable = $('#example').dataTable();
21026 * } );
21027 */
21028 this.fnClose = function( nTr )
21029 {
21030 this.api( true ).row( nTr ).child.hide();
21031 };
21032
21033
21034 /**
21035 * Remove a row for the table
21036 * @param {mixed} target The index of the row from aoData to be deleted, or
21037 * the TR element you want to delete
21038 * @param {function|null} [callBack] Callback function
21039 * @param {bool} [redraw=true] Redraw the table or not
21040 * @returns {array} The row that was deleted
21041 * @dtopt API
21042 * @deprecated Since v1.10
21043 *
21044 * @example
21045 * $(document).ready(function() {
21046 * var oTable = $('#example').dataTable();
21047 *
21048 * // Immediately remove the first row
21049 * oTable.fnDeleteRow( 0 );
21050 * } );
21051 */
21052 this.fnDeleteRow = function( target, callback, redraw )
21053 {
21054 var api = this.api( true );
21055 var rows = api.rows( target );
21056 var settings = rows.settings()[0];
21057 var data = settings.aoData[ rows[0][0] ];
21058
21059 rows.remove();
21060
21061 if ( callback ) {
21062 callback.call( this, settings, data );
21063 }
21064
21065 if ( redraw === undefined || redraw ) {
21066 api.draw();
21067 }
21068
21069 return data;
21070 };
21071
21072
21073 /**
21074 * Restore the table to it's original state in the DOM by removing all of DataTables
21075 * enhancements, alterations to the DOM structure of the table and event listeners.
21076 * @param {boolean} [remove=false] Completely remove the table from the DOM
21077 * @dtopt API
21078 * @deprecated Since v1.10
21079 *
21080 * @example
21081 * $(document).ready(function() {
21082 * // This example is fairly pointless in reality, but shows how fnDestroy can be used
21083 * var oTable = $('#example').dataTable();
21084 * oTable.fnDestroy();
21085 * } );
21086 */
21087 this.fnDestroy = function ( remove )
21088 {
21089 this.api( true ).destroy( remove );
21090 };
21091
21092
21093 /**
21094 * Redraw the table
21095 * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
21096 * @dtopt API
21097 * @deprecated Since v1.10
21098 *
21099 * @example
21100 * $(document).ready(function() {
21101 * var oTable = $('#example').dataTable();
21102 *
21103 * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
21104 * oTable.fnDraw();
21105 * } );
21106 */
21107 this.fnDraw = function( complete )
21108 {
21109 // Note that this isn't an exact match to the old call to _fnDraw - it takes
21110 // into account the new data, but can hold position.
21111 this.api( true ).draw( complete );
21112 };
21113
21114
21115 /**
21116 * Filter the input based on data
21117 * @param {string} sInput String to filter the table on
21118 * @param {int|null} [iColumn] Column to limit filtering to
21119 * @param {bool} [bRegex=false] Treat as regular expression or not
21120 * @param {bool} [bSmart=true] Perform smart filtering or not
21121 * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
21122 * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
21123 * @dtopt API
21124 * @deprecated Since v1.10
21125 *
21126 * @example
21127 * $(document).ready(function() {
21128 * var oTable = $('#example').dataTable();
21129 *
21130 * // Sometime later - filter...
21131 * oTable.fnFilter( 'test string' );
21132 * } );
21133 */
21134 this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
21135 {
21136 var api = this.api( true );
21137
21138 if ( iColumn === null || iColumn === undefined ) {
21139 api.search( sInput, bRegex, bSmart, bCaseInsensitive );
21140 }
21141 else {
21142 api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
21143 }
21144
21145 api.draw();
21146 };
21147
21148
21149 /**
21150 * Get the data for the whole table, an individual row or an individual cell based on the
21151 * provided parameters.
21152 * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
21153 * a TR node then the data source for the whole row will be returned. If given as a
21154 * TD/TH cell node then iCol will be automatically calculated and the data for the
21155 * cell returned. If given as an integer, then this is treated as the aoData internal
21156 * data index for the row (see fnGetPosition) and the data for that row used.
21157 * @param {int} [col] Optional column index that you want the data of.
21158 * @returns {array|object|string} If mRow is undefined, then the data for all rows is
21159 * returned. If mRow is defined, just data for that row, and is iCol is
21160 * defined, only data for the designated cell is returned.
21161 * @dtopt API
21162 * @deprecated Since v1.10
21163 *
21164 * @example
21165 * // Row data
21166 * $(document).ready(function() {
21167 * oTable = $('#example').dataTable();
21168 *
21169 * oTable.$('tr').click( function () {
21170 * var data = oTable.fnGetData( this );
21171 * // ... do something with the array / object of data for the row
21172 * } );
21173 * } );
21174 *
21175 * @example
21176 * // Individual cell data
21177 * $(document).ready(function() {
21178 * oTable = $('#example').dataTable();
21179 *
21180 * oTable.$('td').click( function () {
21181 * var sData = oTable.fnGetData( this );
21182 * alert( 'The cell clicked on had the value of '+sData );
21183 * } );
21184 * } );
21185 */
21186 this.fnGetData = function( src, col )
21187 {
21188 var api = this.api( true );
21189
21190 if ( src !== undefined ) {
21191 var type = src.nodeName ? src.nodeName.toLowerCase() : '';
21192
21193 return col !== undefined || type == 'td' || type == 'th' ?
21194 api.cell( src, col ).data() :
21195 api.row( src ).data() || null;
21196 }
21197
21198 return api.data().toArray();
21199 };
21200
21201
21202 /**
21203 * Get an array of the TR nodes that are used in the table's body. Note that you will
21204 * typically want to use the '$' API method in preference to this as it is more
21205 * flexible.
21206 * @param {int} [iRow] Optional row index for the TR element you want
21207 * @returns {array|node} If iRow is undefined, returns an array of all TR elements
21208 * in the table's body, or iRow is defined, just the TR element requested.
21209 * @dtopt API
21210 * @deprecated Since v1.10
21211 *
21212 * @example
21213 * $(document).ready(function() {
21214 * var oTable = $('#example').dataTable();
21215 *
21216 * // Get the nodes from the table
21217 * var nNodes = oTable.fnGetNodes( );
21218 * } );
21219 */
21220 this.fnGetNodes = function( iRow )
21221 {
21222 var api = this.api( true );
21223
21224 return iRow !== undefined ?
21225 api.row( iRow ).node() :
21226 api.rows().nodes().flatten().toArray();
21227 };
21228
21229
21230 /**
21231 * Get the array indexes of a particular cell from it's DOM element
21232 * and column index including hidden columns
21233 * @param {node} node this can either be a TR, TD or TH in the table's body
21234 * @returns {int} If nNode is given as a TR, then a single index is returned, or
21235 * if given as a cell, an array of [row index, column index (visible),
21236 * column index (all)] is given.
21237 * @dtopt API
21238 * @deprecated Since v1.10
21239 *
21240 * @example
21241 * $(document).ready(function() {
21242 * $('#example tbody td').click( function () {
21243 * // Get the position of the current data from the node
21244 * var aPos = oTable.fnGetPosition( this );
21245 *
21246 * // Get the data array for this row
21247 * var aData = oTable.fnGetData( aPos[0] );
21248 *
21249 * // Update the data array and return the value
21250 * aData[ aPos[1] ] = 'clicked';
21251 * this.innerHTML = 'clicked';
21252 * } );
21253 *
21254 * // Init DataTables
21255 * oTable = $('#example').dataTable();
21256 * } );
21257 */
21258 this.fnGetPosition = function( node )
21259 {
21260 var api = this.api( true );
21261 var nodeName = node.nodeName.toUpperCase();
21262
21263 if ( nodeName == 'TR' ) {
21264 return api.row( node ).index();
21265 }
21266 else if ( nodeName == 'TD' || nodeName == 'TH' ) {
21267 var cell = api.cell( node ).index();
21268
21269 return [
21270 cell.row,
21271 cell.columnVisible,
21272 cell.column
21273 ];
21274 }
21275 return null;
21276 };
21277
21278
21279 /**
21280 * Check to see if a row is 'open' or not.
21281 * @param {node} nTr the table row to check
21282 * @returns {boolean} true if the row is currently open, false otherwise
21283 * @dtopt API
21284 * @deprecated Since v1.10
21285 *
21286 * @example
21287 * $(document).ready(function() {
21288 * var oTable;
21289 *
21290 * // 'open' an information row when a row is clicked on
21291 * $('#example tbody tr').click( function () {
21292 * if ( oTable.fnIsOpen(this) ) {
21293 * oTable.fnClose( this );
21294 * } else {
21295 * oTable.fnOpen( this, "Temporary row opened", "info_row" );
21296 * }
21297 * } );
21298 *
21299 * oTable = $('#example').dataTable();
21300 * } );
21301 */
21302 this.fnIsOpen = function( nTr )
21303 {
21304 return this.api( true ).row( nTr ).child.isShown();
21305 };
21306
21307
21308 /**
21309 * This function will place a new row directly after a row which is currently
21310 * on display on the page, with the HTML contents that is passed into the
21311 * function. This can be used, for example, to ask for confirmation that a
21312 * particular record should be deleted.
21313 * @param {node} nTr The table row to 'open'
21314 * @param {string|node|jQuery} mHtml The HTML to put into the row
21315 * @param {string} sClass Class to give the new TD cell
21316 * @returns {node} The row opened. Note that if the table row passed in as the
21317 * first parameter, is not found in the table, this method will silently
21318 * return.
21319 * @dtopt API
21320 * @deprecated Since v1.10
21321 *
21322 * @example
21323 * $(document).ready(function() {
21324 * var oTable;
21325 *
21326 * // 'open' an information row when a row is clicked on
21327 * $('#example tbody tr').click( function () {
21328 * if ( oTable.fnIsOpen(this) ) {
21329 * oTable.fnClose( this );
21330 * } else {
21331 * oTable.fnOpen( this, "Temporary row opened", "info_row" );
21332 * }
21333 * } );
21334 *
21335 * oTable = $('#example').dataTable();
21336 * } );
21337 */
21338 this.fnOpen = function( nTr, mHtml, sClass )
21339 {
21340 return this.api( true )
21341 .row( nTr )
21342 .child( mHtml, sClass )
21343 .show()
21344 .child()[0];
21345 };
21346
21347
21348 /**
21349 * Change the pagination - provides the internal logic for pagination in a simple API
21350 * function. With this function you can have a DataTables table go to the next,
21351 * previous, first or last pages.
21352 * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
21353 * or page number to jump to (integer), note that page 0 is the first page.
21354 * @param {bool} [bRedraw=true] Redraw the table or not
21355 * @dtopt API
21356 * @deprecated Since v1.10
21357 *
21358 * @example
21359 * $(document).ready(function() {
21360 * var oTable = $('#example').dataTable();
21361 * oTable.fnPageChange( 'next' );
21362 * } );
21363 */
21364 this.fnPageChange = function ( mAction, bRedraw )
21365 {
21366 var api = this.api( true ).page( mAction );
21367
21368 if ( bRedraw === undefined || bRedraw ) {
21369 api.draw(false);
21370 }
21371 };
21372
21373
21374 /**
21375 * Show a particular column
21376 * @param {int} iCol The column whose display should be changed
21377 * @param {bool} bShow Show (true) or hide (false) the column
21378 * @param {bool} [bRedraw=true] Redraw the table or not
21379 * @dtopt API
21380 * @deprecated Since v1.10
21381 *
21382 * @example
21383 * $(document).ready(function() {
21384 * var oTable = $('#example').dataTable();
21385 *
21386 * // Hide the second column after initialisation
21387 * oTable.fnSetColumnVis( 1, false );
21388 * } );
21389 */
21390 this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
21391 {
21392 var api = this.api( true ).column( iCol ).visible( bShow );
21393
21394 if ( bRedraw === undefined || bRedraw ) {
21395 api.columns.adjust().draw();
21396 }
21397 };
21398
21399
21400 /**
21401 * Get the settings for a particular table for external manipulation
21402 * @returns {object} DataTables settings object. See
21403 * {@link DataTable.models.oSettings}
21404 * @dtopt API
21405 * @deprecated Since v1.10
21406 *
21407 * @example
21408 * $(document).ready(function() {
21409 * var oTable = $('#example').dataTable();
21410 * var oSettings = oTable.fnSettings();
21411 *
21412 * // Show an example parameter from the settings
21413 * alert( oSettings._iDisplayStart );
21414 * } );
21415 */
21416 this.fnSettings = function()
21417 {
21418 return _fnSettingsFromNode( this[_ext.iApiIndex] );
21419 };
21420
21421
21422 /**
21423 * Sort the table by a particular column
21424 * @param {int} iCol the data index to sort on. Note that this will not match the
21425 * 'display index' if you have hidden data entries
21426 * @dtopt API
21427 * @deprecated Since v1.10
21428 *
21429 * @example
21430 * $(document).ready(function() {
21431 * var oTable = $('#example').dataTable();
21432 *
21433 * // Sort immediately with columns 0 and 1
21434 * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
21435 * } );
21436 */
21437 this.fnSort = function( aaSort )
21438 {
21439 this.api( true ).order( aaSort ).draw();
21440 };
21441
21442
21443 /**
21444 * Attach a sort listener to an element for a given column
21445 * @param {node} nNode the element to attach the sort listener to
21446 * @param {int} iColumn the column that a click on this node will sort on
21447 * @param {function} [fnCallback] callback function when sort is run
21448 * @dtopt API
21449 * @deprecated Since v1.10
21450 *
21451 * @example
21452 * $(document).ready(function() {
21453 * var oTable = $('#example').dataTable();
21454 *
21455 * // Sort on column 1, when 'sorter' is clicked on
21456 * oTable.fnSortListener( document.getElementById('sorter'), 1 );
21457 * } );
21458 */
21459 this.fnSortListener = function( nNode, iColumn, fnCallback )
21460 {
21461 this.api( true ).order.listener( nNode, iColumn, fnCallback );
21462 };
21463
21464
21465 /**
21466 * Update a table cell or row - this method will accept either a single value to
21467 * update the cell with, an array of values with one element for each column or
21468 * an object in the same format as the original data source. The function is
21469 * self-referencing in order to make the multi column updates easier.
21470 * @param {object|array|string} mData Data to update the cell/row with
21471 * @param {node|int} mRow TR element you want to update or the aoData index
21472 * @param {int} [iColumn] The column to update, give as null or undefined to
21473 * update a whole row.
21474 * @param {bool} [bRedraw=true] Redraw the table or not
21475 * @param {bool} [bAction=true] Perform pre-draw actions or not
21476 * @returns {int} 0 on success, 1 on error
21477 * @dtopt API
21478 * @deprecated Since v1.10
21479 *
21480 * @example
21481 * $(document).ready(function() {
21482 * var oTable = $('#example').dataTable();
21483 * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
21484 * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
21485 * } );
21486 */
21487 this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
21488 {
21489 var api = this.api( true );
21490
21491 if ( iColumn === undefined || iColumn === null ) {
21492 api.row( mRow ).data( mData );
21493 }
21494 else {
21495 api.cell( mRow, iColumn ).data( mData );
21496 }
21497
21498 if ( bAction === undefined || bAction ) {
21499 api.columns.adjust();
21500 }
21501
21502 if ( bRedraw === undefined || bRedraw ) {
21503 api.draw();
21504 }
21505 return 0;
21506 };
21507
21508
21509 /**
21510 * Provide a common method for plug-ins to check the version of DataTables being used, in order
21511 * to ensure compatibility.
21512 * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
21513 * formats "X" and "X.Y" are also acceptable.
21514 * @returns {boolean} true if this version of DataTables is greater or equal to the required
21515 * version, or false if this version of DataTales is not suitable
21516 * @method
21517 * @dtopt API
21518 * @deprecated Since v1.10
21519 *
21520 * @example
21521 * $(document).ready(function() {
21522 * var oTable = $('#example').dataTable();
21523 * alert( oTable.fnVersionCheck( '1.9.0' ) );
21524 * } );
21525 */
21526 this.fnVersionCheck = _ext.fnVersionCheck;
21527
21528
21529 var _that = this;
21530 var emptyInit = options === undefined;
21531 var len = this.length;
21532
21533 if ( emptyInit ) {
21534 options = {};
21535 }
21536
21537 this.oApi = this.internal = _ext.internal;
21538
21539 // Extend with old style plug-in API methods
21540 for ( var fn in DataTable.ext.internal ) {
21541 if ( fn ) {
21542 this[fn] = _fnExternApiFunc(fn);
21543 }
21544 }
21545
21546 this.each(function() {
21547 // For each initialisation we want to give it a clean initialisation
21548 // object that can be bashed around
21549 var o = {};
21550 var oInit = len > 1 ? // optimisation for single table case
21551 _fnExtend( o, options, true ) :
21552 options;
21553
21554 /*global oInit,_that,emptyInit*/
21555 var i=0, iLen, j, jLen, k, kLen;
21556 var sId = this.getAttribute( 'id' );
21557 var bInitHandedOff = false;
21558 var defaults = DataTable.defaults;
21559 var $this = $(this);
21560
21561
21562 /* Sanity check */
21563 if ( this.nodeName.toLowerCase() != 'table' )
21564 {
21565 _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
21566 return;
21567 }
21568
21569 /* Backwards compatibility for the defaults */
21570 _fnCompatOpts( defaults );
21571 _fnCompatCols( defaults.column );
21572
21573 /* Convert the camel-case defaults to Hungarian */
21574 _fnCamelToHungarian( defaults, defaults, true );
21575 _fnCamelToHungarian( defaults.column, defaults.column, true );
21576
21577 /* Setting up the initialisation object */
21578 _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
21579
21580
21581
21582 /* Check to see if we are re-initialising a table */
21583 var allSettings = DataTable.settings;
21584 for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
21585 {
21586 var s = allSettings[i];
21587
21588 /* Base check on table node */
21589 if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
21590 {
21591 var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
21592 var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
21593
21594 if ( emptyInit || bRetrieve )
21595 {
21596 return s.oInstance;
21597 }
21598 else if ( bDestroy )
21599 {
21600 s.oInstance.fnDestroy();
21601 break;
21602 }
21603 else
21604 {
21605 _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
21606 return;
21607 }
21608 }
21609
21610 /* If the element we are initialising has the same ID as a table which was previously
21611 * initialised, but the table nodes don't match (from before) then we destroy the old
21612 * instance by simply deleting it. This is under the assumption that the table has been
21613 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
21614 */
21615 if ( s.sTableId == this.id )
21616 {
21617 allSettings.splice( i, 1 );
21618 break;
21619 }
21620 }
21621
21622 /* Ensure the table has an ID - required for accessibility */
21623 if ( sId === null || sId === "" )
21624 {
21625 sId = "DataTables_Table_"+(DataTable.ext._unique++);
21626 this.id = sId;
21627 }
21628
21629 /* Create the settings object for this table and set some of the default parameters */
21630 var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
21631 "sDestroyWidth": $this[0].style.width,
21632 "sInstance": sId,
21633 "sTableId": sId
21634 } );
21635 oSettings.nTable = this;
21636 oSettings.oApi = _that.internal;
21637 oSettings.oInit = oInit;
21638
21639 allSettings.push( oSettings );
21640
21641 // Need to add the instance after the instance after the settings object has been added
21642 // to the settings array, so we can self reference the table instance if more than one
21643 oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
21644
21645 // Backwards compatibility, before we apply all the defaults
21646 _fnCompatOpts( oInit );
21647
21648 if ( oInit.oLanguage )
21649 {
21650 _fnLanguageCompat( oInit.oLanguage );
21651 }
21652
21653 // If the length menu is given, but the init display length is not, use the length menu
21654 if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
21655 {
21656 oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
21657 oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
21658 }
21659
21660 // Apply the defaults and init options to make a single init object will all
21661 // options defined from defaults and instance options.
21662 oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
21663
21664
21665 // Map the initialisation options onto the settings object
21666 _fnMap( oSettings.oFeatures, oInit, [
21667 "bPaginate",
21668 "bLengthChange",
21669 "bFilter",
21670 "bSort",
21671 "bSortMulti",
21672 "bInfo",
21673 "bProcessing",
21674 "bAutoWidth",
21675 "bSortClasses",
21676 "bServerSide",
21677 "bDeferRender"
21678 ] );
21679 _fnMap( oSettings, oInit, [
21680 "asStripeClasses",
21681 "ajax",
21682 "fnServerData",
21683 "fnFormatNumber",
21684 "sServerMethod",
21685 "aaSorting",
21686 "aaSortingFixed",
21687 "aLengthMenu",
21688 "sPaginationType",
21689 "sAjaxSource",
21690 "sAjaxDataProp",
21691 "iStateDuration",
21692 "sDom",
21693 "bSortCellsTop",
21694 "iTabIndex",
21695 "fnStateLoadCallback",
21696 "fnStateSaveCallback",
21697 "renderer",
21698 "searchDelay",
21699 "rowId",
21700 [ "iCookieDuration", "iStateDuration" ], // backwards compat
21701 [ "oSearch", "oPreviousSearch" ],
21702 [ "aoSearchCols", "aoPreSearchCols" ],
21703 [ "iDisplayLength", "_iDisplayLength" ],
21704 [ "bJQueryUI", "bJUI" ]
21705 ] );
21706 _fnMap( oSettings.oScroll, oInit, [
21707 [ "sScrollX", "sX" ],
21708 [ "sScrollXInner", "sXInner" ],
21709 [ "sScrollY", "sY" ],
21710 [ "bScrollCollapse", "bCollapse" ]
21711 ] );
21712 _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
21713
21714 /* Callback functions which are array driven */
21715 _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
21716 _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
21717 _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
21718 _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
21719 _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
21720 _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
21721 _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
21722 _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
21723 _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
21724 _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
21725 _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
21726
21727 oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
21728
21729 /* Browser support detection */
21730 _fnBrowserDetect( oSettings );
21731
21732 var oClasses = oSettings.oClasses;
21733
21734 // @todo Remove in 1.11
21735 if ( oInit.bJQueryUI )
21736 {
21737 /* Use the JUI classes object for display. You could clone the oStdClasses object if
21738 * you want to have multiple tables with multiple independent classes
21739 */
21740 $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
21741
21742 if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
21743 {
21744 /* Set the DOM to use a layout suitable for jQuery UI's theming */
21745 oSettings.sDom = '<"H"lfr>t<"F"ip>';
21746 }
21747
21748 if ( ! oSettings.renderer ) {
21749 oSettings.renderer = 'jqueryui';
21750 }
21751 else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
21752 oSettings.renderer.header = 'jqueryui';
21753 }
21754 }
21755 else
21756 {
21757 $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
21758 }
21759 $this.addClass( oClasses.sTable );
21760
21761
21762 if ( oSettings.iInitDisplayStart === undefined )
21763 {
21764 /* Display start point, taking into account the save saving */
21765 oSettings.iInitDisplayStart = oInit.iDisplayStart;
21766 oSettings._iDisplayStart = oInit.iDisplayStart;
21767 }
21768
21769 if ( oInit.iDeferLoading !== null )
21770 {
21771 oSettings.bDeferLoading = true;
21772 var tmp = $.isArray( oInit.iDeferLoading );
21773 oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
21774 oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
21775 }
21776
21777 /* Language definitions */
21778 var oLanguage = oSettings.oLanguage;
21779 $.extend( true, oLanguage, oInit.oLanguage );
21780
21781 if ( oLanguage.sUrl !== "" )
21782 {
21783 /* Get the language definitions from a file - because this Ajax call makes the language
21784 * get async to the remainder of this function we use bInitHandedOff to indicate that
21785 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
21786 */
21787 $.ajax( {
21788 dataType: 'json',
21789 url: oLanguage.sUrl,
21790 success: function ( json ) {
21791 _fnLanguageCompat( json );
21792 _fnCamelToHungarian( defaults.oLanguage, json );
21793 $.extend( true, oLanguage, json );
21794 _fnInitialise( oSettings );
21795 },
21796 error: function () {
21797 // Error occurred loading language file, continue on as best we can
21798 _fnInitialise( oSettings );
21799 }
21800 } );
21801 bInitHandedOff = true;
21802 }
21803
21804 /*
21805 * Stripes
21806 */
21807 if ( oInit.asStripeClasses === null )
21808 {
21809 oSettings.asStripeClasses =[
21810 oClasses.sStripeOdd,
21811 oClasses.sStripeEven
21812 ];
21813 }
21814
21815 /* Remove row stripe classes if they are already on the table row */
21816 var stripeClasses = oSettings.asStripeClasses;
21817 var rowOne = $this.children('tbody').find('tr').eq(0);
21818 if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
21819 return rowOne.hasClass(el);
21820 } ) ) !== -1 ) {
21821 $('tbody tr', this).removeClass( stripeClasses.join(' ') );
21822 oSettings.asDestroyStripes = stripeClasses.slice();
21823 }
21824
21825 /*
21826 * Columns
21827 * See if we should load columns automatically or use defined ones
21828 */
21829 var anThs = [];
21830 var aoColumnsInit;
21831 var nThead = this.getElementsByTagName('thead');
21832 if ( nThead.length !== 0 )
21833 {
21834 _fnDetectHeader( oSettings.aoHeader, nThead[0] );
21835 anThs = _fnGetUniqueThs( oSettings );
21836 }
21837
21838 /* If not given a column array, generate one with nulls */
21839 if ( oInit.aoColumns === null )
21840 {
21841 aoColumnsInit = [];
21842 for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
21843 {
21844 aoColumnsInit.push( null );
21845 }
21846 }
21847 else
21848 {
21849 aoColumnsInit = oInit.aoColumns;
21850 }
21851
21852 /* Add the columns */
21853 for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
21854 {
21855 _fnAddColumn( oSettings, anThs ? anThs[i] : null );
21856 }
21857
21858 /* Apply the column definitions */
21859 _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
21860 _fnColumnOptions( oSettings, iCol, oDef );
21861 } );
21862
21863 /* HTML5 attribute detection - build an mData object automatically if the
21864 * attributes are found
21865 */
21866 if ( rowOne.length ) {
21867 var a = function ( cell, name ) {
21868 return cell.getAttribute( 'data-'+name ) !== null ? name : null;
21869 };
21870
21871 $( rowOne[0] ).children('th, td').each( function (i, cell) {
21872 var col = oSettings.aoColumns[i];
21873
21874 if ( col.mData === i ) {
21875 var sort = a( cell, 'sort' ) || a( cell, 'order' );
21876 var filter = a( cell, 'filter' ) || a( cell, 'search' );
21877
21878 if ( sort !== null || filter !== null ) {
21879 col.mData = {
21880 _: i+'.display',
21881 sort: sort !== null ? i+'.@data-'+sort : undefined,
21882 type: sort !== null ? i+'.@data-'+sort : undefined,
21883 filter: filter !== null ? i+'.@data-'+filter : undefined
21884 };
21885
21886 _fnColumnOptions( oSettings, i );
21887 }
21888 }
21889 } );
21890 }
21891
21892 var features = oSettings.oFeatures;
21893
21894 /* Must be done after everything which can be overridden by the state saving! */
21895 if ( oInit.bStateSave )
21896 {
21897 features.bStateSave = true;
21898 _fnLoadState( oSettings, oInit );
21899 _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
21900 }
21901
21902
21903 /*
21904 * Sorting
21905 * @todo For modularisation (1.11) this needs to do into a sort start up handler
21906 */
21907
21908 // If aaSorting is not defined, then we use the first indicator in asSorting
21909 // in case that has been altered, so the default sort reflects that option
21910 if ( oInit.aaSorting === undefined )
21911 {
21912 var sorting = oSettings.aaSorting;
21913 for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
21914 {
21915 sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
21916 }
21917 }
21918
21919 /* Do a first pass on the sorting classes (allows any size changes to be taken into
21920 * account, and also will apply sorting disabled classes if disabled
21921 */
21922 _fnSortingClasses( oSettings );
21923
21924 if ( features.bSort )
21925 {
21926 _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
21927 if ( oSettings.bSorted ) {
21928 var aSort = _fnSortFlatten( oSettings );
21929 var sortedColumns = {};
21930
21931 $.each( aSort, function (i, val) {
21932 sortedColumns[ val.src ] = val.dir;
21933 } );
21934
21935 _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
21936 _fnSortAria( oSettings );
21937 }
21938 } );
21939 }
21940
21941 _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
21942 if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
21943 _fnSortingClasses( oSettings );
21944 }
21945 }, 'sc' );
21946
21947
21948 /*
21949 * Final init
21950 * Cache the header, body and footer as required, creating them if needed
21951 */
21952
21953 // Work around for Webkit bug 83867 - store the caption-side before removing from doc
21954 var captions = $this.children('caption').each( function () {
21955 this._captionSide = $this.css('caption-side');
21956 } );
21957
21958 var thead = $this.children('thead');
21959 if ( thead.length === 0 )
21960 {
21961 thead = $('<thead/>').appendTo(this);
21962 }
21963 oSettings.nTHead = thead[0];
21964
21965 var tbody = $this.children('tbody');
21966 if ( tbody.length === 0 )
21967 {
21968 tbody = $('<tbody/>').appendTo(this);
21969 }
21970 oSettings.nTBody = tbody[0];
21971
21972 var tfoot = $this.children('tfoot');
21973 if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
21974 {
21975 // If we are a scrolling table, and no footer has been given, then we need to create
21976 // a tfoot element for the caption element to be appended to
21977 tfoot = $('<tfoot/>').appendTo(this);
21978 }
21979
21980 if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
21981 $this.addClass( oClasses.sNoFooter );
21982 }
21983 else if ( tfoot.length > 0 ) {
21984 oSettings.nTFoot = tfoot[0];
21985 _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
21986 }
21987
21988 /* Check if there is data passing into the constructor */
21989 if ( oInit.aaData )
21990 {
21991 for ( i=0 ; i<oInit.aaData.length ; i++ )
21992 {
21993 _fnAddData( oSettings, oInit.aaData[ i ] );
21994 }
21995 }
21996 else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
21997 {
21998 /* Grab the data from the page - only do this when deferred loading or no Ajax
21999 * source since there is no point in reading the DOM data if we are then going
22000 * to replace it with Ajax data
22001 */
22002 _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
22003 }
22004
22005 /* Copy the data index array */
22006 oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
22007
22008 /* Initialisation complete - table can be drawn */
22009 oSettings.bInitialised = true;
22010
22011 /* Check if we need to initialise the table (it might not have been handed off to the
22012 * language processor)
22013 */
22014 if ( bInitHandedOff === false )
22015 {
22016 _fnInitialise( oSettings );
22017 }
22018 } );
22019 _that = null;
22020 return this;
22021 };
22022
22023
22024 /*
22025 * It is useful to have variables which are scoped locally so only the
22026 * DataTables functions can access them and they don't leak into global space.
22027 * At the same time these functions are often useful over multiple files in the
22028 * core and API, so we list, or at least document, all variables which are used
22029 * by DataTables as private variables here. This also ensures that there is no
22030 * clashing of variable names and that they can easily referenced for reuse.
22031 */
22032
22033
22034 // Defined else where
22035 // _selector_run
22036 // _selector_opts
22037 // _selector_first
22038 // _selector_row_indexes
22039
22040 var _ext; // DataTable.ext
22041 var _Api; // DataTable.Api
22042 var _api_register; // DataTable.Api.register
22043 var _api_registerPlural; // DataTable.Api.registerPlural
22044
22045 var _re_dic = {};
22046 var _re_new_lines = /[\r\n]/g;
22047 var _re_html = /<.*?>/g;
22048 var _re_date_start = /^[\w\+\-]/;
22049 var _re_date_end = /[\w\+\-]$/;
22050
22051 // Escape regular expression special characters
22052 var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
22053
22054 // http://en.wikipedia.org/wiki/Foreign_exchange_market
22055 // - \u20BD - Russian ruble.
22056 // - \u20a9 - South Korean Won
22057 // - \u20BA - Turkish Lira
22058 // - \u20B9 - Indian Rupee
22059 // - R - Brazil (R$) and South Africa
22060 // - fr - Swiss Franc
22061 // - kr - Swedish krona, Norwegian krone and Danish krone
22062 // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
22063 // standards as thousands separators.
22064 var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
22065
22066
22067 var _empty = function ( d ) {
22068 return !d || d === true || d === '-' ? true : false;
22069 };
22070
22071
22072 var _intVal = function ( s ) {
22073 var integer = parseInt( s, 10 );
22074 return !isNaN(integer) && isFinite(s) ? integer : null;
22075 };
22076
22077 // Convert from a formatted number with characters other than `.` as the
22078 // decimal place, to a Javascript number
22079 var _numToDecimal = function ( num, decimalPoint ) {
22080 // Cache created regular expressions for speed as this function is called often
22081 if ( ! _re_dic[ decimalPoint ] ) {
22082 _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
22083 }
22084 return typeof num === 'string' && decimalPoint !== '.' ?
22085 num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
22086 num;
22087 };
22088
22089
22090 var _isNumber = function ( d, decimalPoint, formatted ) {
22091 var strType = typeof d === 'string';
22092
22093 // If empty return immediately so there must be a number if it is a
22094 // formatted string (this stops the string "k", or "kr", etc being detected
22095 // as a formatted number for currency
22096 if ( _empty( d ) ) {
22097 return true;
22098 }
22099
22100 if ( decimalPoint && strType ) {
22101 d = _numToDecimal( d, decimalPoint );
22102 }
22103
22104 if ( formatted && strType ) {
22105 d = d.replace( _re_formatted_numeric, '' );
22106 }
22107
22108 return !isNaN( parseFloat(d) ) && isFinite( d );
22109 };
22110
22111
22112 // A string without HTML in it can be considered to be HTML still
22113 var _isHtml = function ( d ) {
22114 return _empty( d ) || typeof d === 'string';
22115 };
22116
22117
22118 var _htmlNumeric = function ( d, decimalPoint, formatted ) {
22119 if ( _empty( d ) ) {
22120 return true;
22121 }
22122
22123 var html = _isHtml( d );
22124 return ! html ?
22125 null :
22126 _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
22127 true :
22128 null;
22129 };
22130
22131
22132 var _pluck = function ( a, prop, prop2 ) {
22133 var out = [];
22134 var i=0, ien=a.length;
22135
22136 // Could have the test in the loop for slightly smaller code, but speed
22137 // is essential here
22138 if ( prop2 !== undefined ) {
22139 for ( ; i<ien ; i++ ) {
22140 if ( a[i] && a[i][ prop ] ) {
22141 out.push( a[i][ prop ][ prop2 ] );
22142 }
22143 }
22144 }
22145 else {
22146 for ( ; i<ien ; i++ ) {
22147 if ( a[i] ) {
22148 out.push( a[i][ prop ] );
22149 }
22150 }
22151 }
22152
22153 return out;
22154 };
22155
22156
22157 // Basically the same as _pluck, but rather than looping over `a` we use `order`
22158 // as the indexes to pick from `a`
22159 var _pluck_order = function ( a, order, prop, prop2 )
22160 {
22161 var out = [];
22162 var i=0, ien=order.length;
22163
22164 // Could have the test in the loop for slightly smaller code, but speed
22165 // is essential here
22166 if ( prop2 !== undefined ) {
22167 for ( ; i<ien ; i++ ) {
22168 if ( a[ order[i] ][ prop ] ) {
22169 out.push( a[ order[i] ][ prop ][ prop2 ] );
22170 }
22171 }
22172 }
22173 else {
22174 for ( ; i<ien ; i++ ) {
22175 out.push( a[ order[i] ][ prop ] );
22176 }
22177 }
22178
22179 return out;
22180 };
22181
22182
22183 var _range = function ( len, start )
22184 {
22185 var out = [];
22186 var end;
22187
22188 if ( start === undefined ) {
22189 start = 0;
22190 end = len;
22191 }
22192 else {
22193 end = start;
22194 start = len;
22195 }
22196
22197 for ( var i=start ; i<end ; i++ ) {
22198 out.push( i );
22199 }
22200
22201 return out;
22202 };
22203
22204
22205 var _removeEmpty = function ( a )
22206 {
22207 var out = [];
22208
22209 for ( var i=0, ien=a.length ; i<ien ; i++ ) {
22210 if ( a[i] ) { // careful - will remove all falsy values!
22211 out.push( a[i] );
22212 }
22213 }
22214
22215 return out;
22216 };
22217
22218
22219 var _stripHtml = function ( d ) {
22220 return d.replace( _re_html, '' );
22221 };
22222
22223
22224 /**
22225 * Find the unique elements in a source array.
22226 *
22227 * @param {array} src Source array
22228 * @return {array} Array of unique items
22229 * @ignore
22230 */
22231 var _unique = function ( src )
22232 {
22233 // A faster unique method is to use object keys to identify used values,
22234 // but this doesn't work with arrays or objects, which we must also
22235 // consider. See jsperf.com/compare-array-unique-versions/4 for more
22236 // information.
22237 var
22238 out = [],
22239 val,
22240 i, ien=src.length,
22241 j, k=0;
22242
22243 again: for ( i=0 ; i<ien ; i++ ) {
22244 val = src[i];
22245
22246 for ( j=0 ; j<k ; j++ ) {
22247 if ( out[j] === val ) {
22248 continue again;
22249 }
22250 }
22251
22252 out.push( val );
22253 k++;
22254 }
22255
22256 return out;
22257 };
22258
22259
22260 /**
22261 * DataTables utility methods
22262 *
22263 * This namespace provides helper methods that DataTables uses internally to
22264 * create a DataTable, but which are not exclusively used only for DataTables.
22265 * These methods can be used by extension authors to save the duplication of
22266 * code.
22267 *
22268 * @namespace
22269 */
22270 DataTable.util = {
22271 /**
22272 * Throttle the calls to a function. Arguments and context are maintained
22273 * for the throttled function.
22274 *
22275 * @param {function} fn Function to be called
22276 * @param {integer} freq Call frequency in mS
22277 * @return {function} Wrapped function
22278 */
22279 throttle: function ( fn, freq ) {
22280 var
22281 frequency = freq !== undefined ? freq : 200,
22282 last,
22283 timer;
22284
22285 return function () {
22286 var
22287 that = this,
22288 now = +new Date(),
22289 args = arguments;
22290
22291 if ( last && now < last + frequency ) {
22292 clearTimeout( timer );
22293
22294 timer = setTimeout( function () {
22295 last = undefined;
22296 fn.apply( that, args );
22297 }, frequency );
22298 }
22299 else {
22300 last = now;
22301 fn.apply( that, args );
22302 }
22303 };
22304 },
22305
22306
22307 /**
22308 * Escape a string such that it can be used in a regular expression
22309 *
22310 * @param {string} val string to escape
22311 * @returns {string} escaped string
22312 */
22313 escapeRegex: function ( val ) {
22314 return val.replace( _re_escape_regex, '\\$1' );
22315 }
22316 };
22317
22318
22319
22320 /**
22321 * Create a mapping object that allows camel case parameters to be looked up
22322 * for their Hungarian counterparts. The mapping is stored in a private
22323 * parameter called `_hungarianMap` which can be accessed on the source object.
22324 * @param {object} o
22325 * @memberof DataTable#oApi
22326 */
22327 function _fnHungarianMap ( o )
22328 {
22329 var
22330 hungarian = 'a aa ai ao as b fn i m o s ',
22331 match,
22332 newKey,
22333 map = {};
22334
22335 $.each( o, function (key, val) {
22336 match = key.match(/^([^A-Z]+?)([A-Z])/);
22337
22338 if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
22339 {
22340 newKey = key.replace( match[0], match[2].toLowerCase() );
22341 map[ newKey ] = key;
22342
22343 if ( match[1] === 'o' )
22344 {
22345 _fnHungarianMap( o[key] );
22346 }
22347 }
22348 } );
22349
22350 o._hungarianMap = map;
22351 }
22352
22353
22354 /**
22355 * Convert from camel case parameters to Hungarian, based on a Hungarian map
22356 * created by _fnHungarianMap.
22357 * @param {object} src The model object which holds all parameters that can be
22358 * mapped.
22359 * @param {object} user The object to convert from camel case to Hungarian.
22360 * @param {boolean} force When set to `true`, properties which already have a
22361 * Hungarian value in the `user` object will be overwritten. Otherwise they
22362 * won't be.
22363 * @memberof DataTable#oApi
22364 */
22365 function _fnCamelToHungarian ( src, user, force )
22366 {
22367 if ( ! src._hungarianMap ) {
22368 _fnHungarianMap( src );
22369 }
22370
22371 var hungarianKey;
22372
22373 $.each( user, function (key, val) {
22374 hungarianKey = src._hungarianMap[ key ];
22375
22376 if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
22377 {
22378 // For objects, we need to buzz down into the object to copy parameters
22379 if ( hungarianKey.charAt(0) === 'o' )
22380 {
22381 // Copy the camelCase options over to the hungarian
22382 if ( ! user[ hungarianKey ] ) {
22383 user[ hungarianKey ] = {};
22384 }
22385 $.extend( true, user[hungarianKey], user[key] );
22386
22387 _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
22388 }
22389 else {
22390 user[hungarianKey] = user[ key ];
22391 }
22392 }
22393 } );
22394 }
22395
22396
22397 /**
22398 * Language compatibility - when certain options are given, and others aren't, we
22399 * need to duplicate the values over, in order to provide backwards compatibility
22400 * with older language files.
22401 * @param {object} oSettings dataTables settings object
22402 * @memberof DataTable#oApi
22403 */
22404 function _fnLanguageCompat( lang )
22405 {
22406 var defaults = DataTable.defaults.oLanguage;
22407 var zeroRecords = lang.sZeroRecords;
22408
22409 /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
22410 * sZeroRecords - assuming that is given.
22411 */
22412 if ( ! lang.sEmptyTable && zeroRecords &&
22413 defaults.sEmptyTable === "No data available in table" )
22414 {
22415 _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
22416 }
22417
22418 /* Likewise with loading records */
22419 if ( ! lang.sLoadingRecords && zeroRecords &&
22420 defaults.sLoadingRecords === "Loading..." )
22421 {
22422 _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
22423 }
22424
22425 // Old parameter name of the thousands separator mapped onto the new
22426 if ( lang.sInfoThousands ) {
22427 lang.sThousands = lang.sInfoThousands;
22428 }
22429
22430 var decimal = lang.sDecimal;
22431 if ( decimal ) {
22432 _addNumericSort( decimal );
22433 }
22434 }
22435
22436
22437 /**
22438 * Map one parameter onto another
22439 * @param {object} o Object to map
22440 * @param {*} knew The new parameter name
22441 * @param {*} old The old parameter name
22442 */
22443 var _fnCompatMap = function ( o, knew, old ) {
22444 if ( o[ knew ] !== undefined ) {
22445 o[ old ] = o[ knew ];
22446 }
22447 };
22448
22449
22450 /**
22451 * Provide backwards compatibility for the main DT options. Note that the new
22452 * options are mapped onto the old parameters, so this is an external interface
22453 * change only.
22454 * @param {object} init Object to map
22455 */
22456 function _fnCompatOpts ( init )
22457 {
22458 _fnCompatMap( init, 'ordering', 'bSort' );
22459 _fnCompatMap( init, 'orderMulti', 'bSortMulti' );
22460 _fnCompatMap( init, 'orderClasses', 'bSortClasses' );
22461 _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
22462 _fnCompatMap( init, 'order', 'aaSorting' );
22463 _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
22464 _fnCompatMap( init, 'paging', 'bPaginate' );
22465 _fnCompatMap( init, 'pagingType', 'sPaginationType' );
22466 _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
22467 _fnCompatMap( init, 'searching', 'bFilter' );
22468
22469 // Boolean initialisation of x-scrolling
22470 if ( typeof init.sScrollX === 'boolean' ) {
22471 init.sScrollX = init.sScrollX ? '100%' : '';
22472 }
22473 if ( typeof init.scrollX === 'boolean' ) {
22474 init.scrollX = init.scrollX ? '100%' : '';
22475 }
22476
22477 // Column search objects are in an array, so it needs to be converted
22478 // element by element
22479 var searchCols = init.aoSearchCols;
22480
22481 if ( searchCols ) {
22482 for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
22483 if ( searchCols[i] ) {
22484 _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
22485 }
22486 }
22487 }
22488 }
22489
22490
22491 /**
22492 * Provide backwards compatibility for column options. Note that the new options
22493 * are mapped onto the old parameters, so this is an external interface change
22494 * only.
22495 * @param {object} init Object to map
22496 */
22497 function _fnCompatCols ( init )
22498 {
22499 _fnCompatMap( init, 'orderable', 'bSortable' );
22500 _fnCompatMap( init, 'orderData', 'aDataSort' );
22501 _fnCompatMap( init, 'orderSequence', 'asSorting' );
22502 _fnCompatMap( init, 'orderDataType', 'sortDataType' );
22503
22504 // orderData can be given as an integer
22505 var dataSort = init.aDataSort;
22506 if ( dataSort && ! $.isArray( dataSort ) ) {
22507 init.aDataSort = [ dataSort ];
22508 }
22509 }
22510
22511
22512 /**
22513 * Browser feature detection for capabilities, quirks
22514 * @param {object} settings dataTables settings object
22515 * @memberof DataTable#oApi
22516 */
22517 function _fnBrowserDetect( settings )
22518 {
22519 // We don't need to do this every time DataTables is constructed, the values
22520 // calculated are specific to the browser and OS configuration which we
22521 // don't expect to change between initialisations
22522 if ( ! DataTable.__browser ) {
22523 var browser = {};
22524 DataTable.__browser = browser;
22525
22526 // Scrolling feature / quirks detection
22527 var n = $('<div/>')
22528 .css( {
22529 position: 'fixed',
22530 top: 0,
22531 left: 0,
22532 height: 1,
22533 width: 1,
22534 overflow: 'hidden'
22535 } )
22536 .append(
22537 $('<div/>')
22538 .css( {
22539 position: 'absolute',
22540 top: 1,
22541 left: 1,
22542 width: 100,
22543 overflow: 'scroll'
22544 } )
22545 .append(
22546 $('<div/>')
22547 .css( {
22548 width: '100%',
22549 height: 10
22550 } )
22551 )
22552 )
22553 .appendTo( 'body' );
22554
22555 var outer = n.children();
22556 var inner = outer.children();
22557
22558 // Numbers below, in order, are:
22559 // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
22560 //
22561 // IE6 XP: 100 100 100 83
22562 // IE7 Vista: 100 100 100 83
22563 // IE 8+ Windows: 83 83 100 83
22564 // Evergreen Windows: 83 83 100 83
22565 // Evergreen Mac with scrollbars: 85 85 100 85
22566 // Evergreen Mac without scrollbars: 100 100 100 100
22567
22568 // Get scrollbar width
22569 browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
22570
22571 // IE6/7 will oversize a width 100% element inside a scrolling element, to
22572 // include the width of the scrollbar, while other browsers ensure the inner
22573 // element is contained without forcing scrolling
22574 browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
22575
22576 // In rtl text layout, some browsers (most, but not all) will place the
22577 // scrollbar on the left, rather than the right.
22578 browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
22579
22580 // IE8- don't provide height and width for getBoundingClientRect
22581 browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
22582
22583 n.remove();
22584 }
22585
22586 $.extend( settings.oBrowser, DataTable.__browser );
22587 settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
22588 }
22589
22590
22591 /**
22592 * Array.prototype reduce[Right] method, used for browsers which don't support
22593 * JS 1.6. Done this way to reduce code size, since we iterate either way
22594 * @param {object} settings dataTables settings object
22595 * @memberof DataTable#oApi
22596 */
22597 function _fnReduce ( that, fn, init, start, end, inc )
22598 {
22599 var
22600 i = start,
22601 value,
22602 isSet = false;
22603
22604 if ( init !== undefined ) {
22605 value = init;
22606 isSet = true;
22607 }
22608
22609 while ( i !== end ) {
22610 if ( ! that.hasOwnProperty(i) ) {
22611 continue;
22612 }
22613
22614 value = isSet ?
22615 fn( value, that[i], i, that ) :
22616 that[i];
22617
22618 isSet = true;
22619 i += inc;
22620 }
22621
22622 return value;
22623 }
22624
22625 /**
22626 * Add a column to the list used for the table with default values
22627 * @param {object} oSettings dataTables settings object
22628 * @param {node} nTh The th element for this column
22629 * @memberof DataTable#oApi
22630 */
22631 function _fnAddColumn( oSettings, nTh )
22632 {
22633 // Add column to aoColumns array
22634 var oDefaults = DataTable.defaults.column;
22635 var iCol = oSettings.aoColumns.length;
22636 var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
22637 "nTh": nTh ? nTh : document.createElement('th'),
22638 "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
22639 "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
22640 "mData": oDefaults.mData ? oDefaults.mData : iCol,
22641 idx: iCol
22642 } );
22643 oSettings.aoColumns.push( oCol );
22644
22645 // Add search object for column specific search. Note that the `searchCols[ iCol ]`
22646 // passed into extend can be undefined. This allows the user to give a default
22647 // with only some of the parameters defined, and also not give a default
22648 var searchCols = oSettings.aoPreSearchCols;
22649 searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
22650
22651 // Use the default column options function to initialise classes etc
22652 _fnColumnOptions( oSettings, iCol, $(nTh).data() );
22653 }
22654
22655
22656 /**
22657 * Apply options for a column
22658 * @param {object} oSettings dataTables settings object
22659 * @param {int} iCol column index to consider
22660 * @param {object} oOptions object with sType, bVisible and bSearchable etc
22661 * @memberof DataTable#oApi
22662 */
22663 function _fnColumnOptions( oSettings, iCol, oOptions )
22664 {
22665 var oCol = oSettings.aoColumns[ iCol ];
22666 var oClasses = oSettings.oClasses;
22667 var th = $(oCol.nTh);
22668
22669 // Try to get width information from the DOM. We can't get it from CSS
22670 // as we'd need to parse the CSS stylesheet. `width` option can override
22671 if ( ! oCol.sWidthOrig ) {
22672 // Width attribute
22673 oCol.sWidthOrig = th.attr('width') || null;
22674
22675 // Style attribute
22676 var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
22677 if ( t ) {
22678 oCol.sWidthOrig = t[1];
22679 }
22680 }
22681
22682 /* User specified column options */
22683 if ( oOptions !== undefined && oOptions !== null )
22684 {
22685 // Backwards compatibility
22686 _fnCompatCols( oOptions );
22687
22688 // Map camel case parameters to their Hungarian counterparts
22689 _fnCamelToHungarian( DataTable.defaults.column, oOptions );
22690
22691 /* Backwards compatibility for mDataProp */
22692 if ( oOptions.mDataProp !== undefined && !oOptions.mData )
22693 {
22694 oOptions.mData = oOptions.mDataProp;
22695 }
22696
22697 if ( oOptions.sType )
22698 {
22699 oCol._sManualType = oOptions.sType;
22700 }
22701
22702 // `class` is a reserved word in Javascript, so we need to provide
22703 // the ability to use a valid name for the camel case input
22704 if ( oOptions.className && ! oOptions.sClass )
22705 {
22706 oOptions.sClass = oOptions.className;
22707 }
22708
22709 $.extend( oCol, oOptions );
22710 _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
22711
22712 /* iDataSort to be applied (backwards compatibility), but aDataSort will take
22713 * priority if defined
22714 */
22715 if ( oOptions.iDataSort !== undefined )
22716 {
22717 oCol.aDataSort = [ oOptions.iDataSort ];
22718 }
22719 _fnMap( oCol, oOptions, "aDataSort" );
22720 }
22721
22722 /* Cache the data get and set functions for speed */
22723 var mDataSrc = oCol.mData;
22724 var mData = _fnGetObjectDataFn( mDataSrc );
22725 var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
22726
22727 var attrTest = function( src ) {
22728 return typeof src === 'string' && src.indexOf('@') !== -1;
22729 };
22730 oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
22731 attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
22732 );
22733 oCol._setter = null;
22734
22735 oCol.fnGetData = function (rowData, type, meta) {
22736 var innerData = mData( rowData, type, undefined, meta );
22737
22738 return mRender && type ?
22739 mRender( innerData, type, rowData, meta ) :
22740 innerData;
22741 };
22742 oCol.fnSetData = function ( rowData, val, meta ) {
22743 return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
22744 };
22745
22746 // Indicate if DataTables should read DOM data as an object or array
22747 // Used in _fnGetRowElements
22748 if ( typeof mDataSrc !== 'number' ) {
22749 oSettings._rowReadObject = true;
22750 }
22751
22752 /* Feature sorting overrides column specific when off */
22753 if ( !oSettings.oFeatures.bSort )
22754 {
22755 oCol.bSortable = false;
22756 th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
22757 }
22758
22759 /* Check that the class assignment is correct for sorting */
22760 var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
22761 var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
22762 if ( !oCol.bSortable || (!bAsc && !bDesc) )
22763 {
22764 oCol.sSortingClass = oClasses.sSortableNone;
22765 oCol.sSortingClassJUI = "";
22766 }
22767 else if ( bAsc && !bDesc )
22768 {
22769 oCol.sSortingClass = oClasses.sSortableAsc;
22770 oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
22771 }
22772 else if ( !bAsc && bDesc )
22773 {
22774 oCol.sSortingClass = oClasses.sSortableDesc;
22775 oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
22776 }
22777 else
22778 {
22779 oCol.sSortingClass = oClasses.sSortable;
22780 oCol.sSortingClassJUI = oClasses.sSortJUI;
22781 }
22782 }
22783
22784
22785 /**
22786 * Adjust the table column widths for new data. Note: you would probably want to
22787 * do a redraw after calling this function!
22788 * @param {object} settings dataTables settings object
22789 * @memberof DataTable#oApi
22790 */
22791 function _fnAdjustColumnSizing ( settings )
22792 {
22793 /* Not interested in doing column width calculation if auto-width is disabled */
22794 if ( settings.oFeatures.bAutoWidth !== false )
22795 {
22796 var columns = settings.aoColumns;
22797
22798 _fnCalculateColumnWidths( settings );
22799 for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
22800 {
22801 columns[i].nTh.style.width = columns[i].sWidth;
22802 }
22803 }
22804
22805 var scroll = settings.oScroll;
22806 if ( scroll.sY !== '' || scroll.sX !== '')
22807 {
22808 _fnScrollDraw( settings );
22809 }
22810
22811 _fnCallbackFire( settings, null, 'column-sizing', [settings] );
22812 }
22813
22814
22815 /**
22816 * Covert the index of a visible column to the index in the data array (take account
22817 * of hidden columns)
22818 * @param {object} oSettings dataTables settings object
22819 * @param {int} iMatch Visible column index to lookup
22820 * @returns {int} i the data index
22821 * @memberof DataTable#oApi
22822 */
22823 function _fnVisibleToColumnIndex( oSettings, iMatch )
22824 {
22825 var aiVis = _fnGetColumns( oSettings, 'bVisible' );
22826
22827 return typeof aiVis[iMatch] === 'number' ?
22828 aiVis[iMatch] :
22829 null;
22830 }
22831
22832
22833 /**
22834 * Covert the index of an index in the data array and convert it to the visible
22835 * column index (take account of hidden columns)
22836 * @param {int} iMatch Column index to lookup
22837 * @param {object} oSettings dataTables settings object
22838 * @returns {int} i the data index
22839 * @memberof DataTable#oApi
22840 */
22841 function _fnColumnIndexToVisible( oSettings, iMatch )
22842 {
22843 var aiVis = _fnGetColumns( oSettings, 'bVisible' );
22844 var iPos = $.inArray( iMatch, aiVis );
22845
22846 return iPos !== -1 ? iPos : null;
22847 }
22848
22849
22850 /**
22851 * Get the number of visible columns
22852 * @param {object} oSettings dataTables settings object
22853 * @returns {int} i the number of visible columns
22854 * @memberof DataTable#oApi
22855 */
22856 function _fnVisbleColumns( oSettings )
22857 {
22858 var vis = 0;
22859
22860 // No reduce in IE8, use a loop for now
22861 $.each( oSettings.aoColumns, function ( i, col ) {
22862 if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
22863 vis++;
22864 }
22865 } );
22866
22867 return vis;
22868 }
22869
22870
22871 /**
22872 * Get an array of column indexes that match a given property
22873 * @param {object} oSettings dataTables settings object
22874 * @param {string} sParam Parameter in aoColumns to look for - typically
22875 * bVisible or bSearchable
22876 * @returns {array} Array of indexes with matched properties
22877 * @memberof DataTable#oApi
22878 */
22879 function _fnGetColumns( oSettings, sParam )
22880 {
22881 var a = [];
22882
22883 $.map( oSettings.aoColumns, function(val, i) {
22884 if ( val[sParam] ) {
22885 a.push( i );
22886 }
22887 } );
22888
22889 return a;
22890 }
22891
22892
22893 /**
22894 * Calculate the 'type' of a column
22895 * @param {object} settings dataTables settings object
22896 * @memberof DataTable#oApi
22897 */
22898 function _fnColumnTypes ( settings )
22899 {
22900 var columns = settings.aoColumns;
22901 var data = settings.aoData;
22902 var types = DataTable.ext.type.detect;
22903 var i, ien, j, jen, k, ken;
22904 var col, cell, detectedType, cache;
22905
22906 // For each column, spin over the
22907 for ( i=0, ien=columns.length ; i<ien ; i++ ) {
22908 col = columns[i];
22909 cache = [];
22910
22911 if ( ! col.sType && col._sManualType ) {
22912 col.sType = col._sManualType;
22913 }
22914 else if ( ! col.sType ) {
22915 for ( j=0, jen=types.length ; j<jen ; j++ ) {
22916 for ( k=0, ken=data.length ; k<ken ; k++ ) {
22917 // Use a cache array so we only need to get the type data
22918 // from the formatter once (when using multiple detectors)
22919 if ( cache[k] === undefined ) {
22920 cache[k] = _fnGetCellData( settings, k, i, 'type' );
22921 }
22922
22923 detectedType = types[j]( cache[k], settings );
22924
22925 // If null, then this type can't apply to this column, so
22926 // rather than testing all cells, break out. There is an
22927 // exception for the last type which is `html`. We need to
22928 // scan all rows since it is possible to mix string and HTML
22929 // types
22930 if ( ! detectedType && j !== types.length-1 ) {
22931 break;
22932 }
22933
22934 // Only a single match is needed for html type since it is
22935 // bottom of the pile and very similar to string
22936 if ( detectedType === 'html' ) {
22937 break;
22938 }
22939 }
22940
22941 // Type is valid for all data points in the column - use this
22942 // type
22943 if ( detectedType ) {
22944 col.sType = detectedType;
22945 break;
22946 }
22947 }
22948
22949 // Fall back - if no type was detected, always use string
22950 if ( ! col.sType ) {
22951 col.sType = 'string';
22952 }
22953 }
22954 }
22955 }
22956
22957
22958 /**
22959 * Take the column definitions and static columns arrays and calculate how
22960 * they relate to column indexes. The callback function will then apply the
22961 * definition found for a column to a suitable configuration object.
22962 * @param {object} oSettings dataTables settings object
22963 * @param {array} aoColDefs The aoColumnDefs array that is to be applied
22964 * @param {array} aoCols The aoColumns array that defines columns individually
22965 * @param {function} fn Callback function - takes two parameters, the calculated
22966 * column index and the definition for that column.
22967 * @memberof DataTable#oApi
22968 */
22969 function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
22970 {
22971 var i, iLen, j, jLen, k, kLen, def;
22972 var columns = oSettings.aoColumns;
22973
22974 // Column definitions with aTargets
22975 if ( aoColDefs )
22976 {
22977 /* Loop over the definitions array - loop in reverse so first instance has priority */
22978 for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
22979 {
22980 def = aoColDefs[i];
22981
22982 /* Each definition can target multiple columns, as it is an array */
22983 var aTargets = def.targets !== undefined ?
22984 def.targets :
22985 def.aTargets;
22986
22987 if ( ! $.isArray( aTargets ) )
22988 {
22989 aTargets = [ aTargets ];
22990 }
22991
22992 for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
22993 {
22994 if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
22995 {
22996 /* Add columns that we don't yet know about */
22997 while( columns.length <= aTargets[j] )
22998 {
22999 _fnAddColumn( oSettings );
23000 }
23001
23002 /* Integer, basic index */
23003 fn( aTargets[j], def );
23004 }
23005 else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
23006 {
23007 /* Negative integer, right to left column counting */
23008 fn( columns.length+aTargets[j], def );
23009 }
23010 else if ( typeof aTargets[j] === 'string' )
23011 {
23012 /* Class name matching on TH element */
23013 for ( k=0, kLen=columns.length ; k<kLen ; k++ )
23014 {
23015 if ( aTargets[j] == "_all" ||
23016 $(columns[k].nTh).hasClass( aTargets[j] ) )
23017 {
23018 fn( k, def );
23019 }
23020 }
23021 }
23022 }
23023 }
23024 }
23025
23026 // Statically defined columns array
23027 if ( aoCols )
23028 {
23029 for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
23030 {
23031 fn( i, aoCols[i] );
23032 }
23033 }
23034 }
23035
23036 /**
23037 * Add a data array to the table, creating DOM node etc. This is the parallel to
23038 * _fnGatherData, but for adding rows from a Javascript source, rather than a
23039 * DOM source.
23040 * @param {object} oSettings dataTables settings object
23041 * @param {array} aData data array to be added
23042 * @param {node} [nTr] TR element to add to the table - optional. If not given,
23043 * DataTables will create a row automatically
23044 * @param {array} [anTds] Array of TD|TH elements for the row - must be given
23045 * if nTr is.
23046 * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
23047 * @memberof DataTable#oApi
23048 */
23049 function _fnAddData ( oSettings, aDataIn, nTr, anTds )
23050 {
23051 /* Create the object for storing information about this new row */
23052 var iRow = oSettings.aoData.length;
23053 var oData = $.extend( true, {}, DataTable.models.oRow, {
23054 src: nTr ? 'dom' : 'data',
23055 idx: iRow
23056 } );
23057
23058 oData._aData = aDataIn;
23059 oSettings.aoData.push( oData );
23060
23061 /* Create the cells */
23062 var nTd, sThisType;
23063 var columns = oSettings.aoColumns;
23064
23065 // Invalidate the column types as the new data needs to be revalidated
23066 for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
23067 {
23068 columns[i].sType = null;
23069 }
23070
23071 /* Add to the display array */
23072 oSettings.aiDisplayMaster.push( iRow );
23073
23074 var id = oSettings.rowIdFn( aDataIn );
23075 if ( id !== undefined ) {
23076 oSettings.aIds[ id ] = oData;
23077 }
23078
23079 /* Create the DOM information, or register it if already present */
23080 if ( nTr || ! oSettings.oFeatures.bDeferRender )
23081 {
23082 _fnCreateTr( oSettings, iRow, nTr, anTds );
23083 }
23084
23085 return iRow;
23086 }
23087
23088
23089 /**
23090 * Add one or more TR elements to the table. Generally we'd expect to
23091 * use this for reading data from a DOM sourced table, but it could be
23092 * used for an TR element. Note that if a TR is given, it is used (i.e.
23093 * it is not cloned).
23094 * @param {object} settings dataTables settings object
23095 * @param {array|node|jQuery} trs The TR element(s) to add to the table
23096 * @returns {array} Array of indexes for the added rows
23097 * @memberof DataTable#oApi
23098 */
23099 function _fnAddTr( settings, trs )
23100 {
23101 var row;
23102
23103 // Allow an individual node to be passed in
23104 if ( ! (trs instanceof $) ) {
23105 trs = $(trs);
23106 }
23107
23108 return trs.map( function (i, el) {
23109 row = _fnGetRowElements( settings, el );
23110 return _fnAddData( settings, row.data, el, row.cells );
23111 } );
23112 }
23113
23114
23115 /**
23116 * Take a TR element and convert it to an index in aoData
23117 * @param {object} oSettings dataTables settings object
23118 * @param {node} n the TR element to find
23119 * @returns {int} index if the node is found, null if not
23120 * @memberof DataTable#oApi
23121 */
23122 function _fnNodeToDataIndex( oSettings, n )
23123 {
23124 return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
23125 }
23126
23127
23128 /**
23129 * Take a TD element and convert it into a column data index (not the visible index)
23130 * @param {object} oSettings dataTables settings object
23131 * @param {int} iRow The row number the TD/TH can be found in
23132 * @param {node} n The TD/TH element to find
23133 * @returns {int} index if the node is found, -1 if not
23134 * @memberof DataTable#oApi
23135 */
23136 function _fnNodeToColumnIndex( oSettings, iRow, n )
23137 {
23138 return $.inArray( n, oSettings.aoData[ iRow ].anCells );
23139 }
23140
23141
23142 /**
23143 * Get the data for a given cell from the internal cache, taking into account data mapping
23144 * @param {object} settings dataTables settings object
23145 * @param {int} rowIdx aoData row id
23146 * @param {int} colIdx Column index
23147 * @param {string} type data get type ('display', 'type' 'filter' 'sort')
23148 * @returns {*} Cell data
23149 * @memberof DataTable#oApi
23150 */
23151 function _fnGetCellData( settings, rowIdx, colIdx, type )
23152 {
23153 var draw = settings.iDraw;
23154 var col = settings.aoColumns[colIdx];
23155 var rowData = settings.aoData[rowIdx]._aData;
23156 var defaultContent = col.sDefaultContent;
23157 var cellData = col.fnGetData( rowData, type, {
23158 settings: settings,
23159 row: rowIdx,
23160 col: colIdx
23161 } );
23162
23163 if ( cellData === undefined ) {
23164 if ( settings.iDrawError != draw && defaultContent === null ) {
23165 _fnLog( settings, 0, "Requested unknown parameter "+
23166 (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
23167 " for row "+rowIdx+", column "+colIdx, 4 );
23168 settings.iDrawError = draw;
23169 }
23170 return defaultContent;
23171 }
23172
23173 // When the data source is null and a specific data type is requested (i.e.
23174 // not the original data), we can use default column data
23175 if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
23176 cellData = defaultContent;
23177 }
23178 else if ( typeof cellData === 'function' ) {
23179 // If the data source is a function, then we run it and use the return,
23180 // executing in the scope of the data object (for instances)
23181 return cellData.call( rowData );
23182 }
23183
23184 if ( cellData === null && type == 'display' ) {
23185 return '';
23186 }
23187 return cellData;
23188 }
23189
23190
23191 /**
23192 * Set the value for a specific cell, into the internal data cache
23193 * @param {object} settings dataTables settings object
23194 * @param {int} rowIdx aoData row id
23195 * @param {int} colIdx Column index
23196 * @param {*} val Value to set
23197 * @memberof DataTable#oApi
23198 */
23199 function _fnSetCellData( settings, rowIdx, colIdx, val )
23200 {
23201 var col = settings.aoColumns[colIdx];
23202 var rowData = settings.aoData[rowIdx]._aData;
23203
23204 col.fnSetData( rowData, val, {
23205 settings: settings,
23206 row: rowIdx,
23207 col: colIdx
23208 } );
23209 }
23210
23211
23212 // Private variable that is used to match action syntax in the data property object
23213 var __reArray = /\[.*?\]$/;
23214 var __reFn = /\(\)$/;
23215
23216 /**
23217 * Split string on periods, taking into account escaped periods
23218 * @param {string} str String to split
23219 * @return {array} Split string
23220 */
23221 function _fnSplitObjNotation( str )
23222 {
23223 return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
23224 return s.replace(/\\./g, '.');
23225 } );
23226 }
23227
23228
23229 /**
23230 * Return a function that can be used to get data from a source object, taking
23231 * into account the ability to use nested objects as a source
23232 * @param {string|int|function} mSource The data source for the object
23233 * @returns {function} Data get function
23234 * @memberof DataTable#oApi
23235 */
23236 function _fnGetObjectDataFn( mSource )
23237 {
23238 if ( $.isPlainObject( mSource ) )
23239 {
23240 /* Build an object of get functions, and wrap them in a single call */
23241 var o = {};
23242 $.each( mSource, function (key, val) {
23243 if ( val ) {
23244 o[key] = _fnGetObjectDataFn( val );
23245 }
23246 } );
23247
23248 return function (data, type, row, meta) {
23249 var t = o[type] || o._;
23250 return t !== undefined ?
23251 t(data, type, row, meta) :
23252 data;
23253 };
23254 }
23255 else if ( mSource === null )
23256 {
23257 /* Give an empty string for rendering / sorting etc */
23258 return function (data) { // type, row and meta also passed, but not used
23259 return data;
23260 };
23261 }
23262 else if ( typeof mSource === 'function' )
23263 {
23264 return function (data, type, row, meta) {
23265 return mSource( data, type, row, meta );
23266 };
23267 }
23268 else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
23269 mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
23270 {
23271 /* If there is a . in the source string then the data source is in a
23272 * nested object so we loop over the data for each level to get the next
23273 * level down. On each loop we test for undefined, and if found immediately
23274 * return. This allows entire objects to be missing and sDefaultContent to
23275 * be used if defined, rather than throwing an error
23276 */
23277 var fetchData = function (data, type, src) {
23278 var arrayNotation, funcNotation, out, innerSrc;
23279
23280 if ( src !== "" )
23281 {
23282 var a = _fnSplitObjNotation( src );
23283
23284 for ( var i=0, iLen=a.length ; i<iLen ; i++ )
23285 {
23286 // Check if we are dealing with special notation
23287 arrayNotation = a[i].match(__reArray);
23288 funcNotation = a[i].match(__reFn);
23289
23290 if ( arrayNotation )
23291 {
23292 // Array notation
23293 a[i] = a[i].replace(__reArray, '');
23294
23295 // Condition allows simply [] to be passed in
23296 if ( a[i] !== "" ) {
23297 data = data[ a[i] ];
23298 }
23299 out = [];
23300
23301 // Get the remainder of the nested object to get
23302 a.splice( 0, i+1 );
23303 innerSrc = a.join('.');
23304
23305 // Traverse each entry in the array getting the properties requested
23306 if ( $.isArray( data ) ) {
23307 for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
23308 out.push( fetchData( data[j], type, innerSrc ) );
23309 }
23310 }
23311
23312 // If a string is given in between the array notation indicators, that
23313 // is used to join the strings together, otherwise an array is returned
23314 var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
23315 data = (join==="") ? out : out.join(join);
23316
23317 // The inner call to fetchData has already traversed through the remainder
23318 // of the source requested, so we exit from the loop
23319 break;
23320 }
23321 else if ( funcNotation )
23322 {
23323 // Function call
23324 a[i] = a[i].replace(__reFn, '');
23325 data = data[ a[i] ]();
23326 continue;
23327 }
23328
23329 if ( data === null || data[ a[i] ] === undefined )
23330 {
23331 return undefined;
23332 }
23333 data = data[ a[i] ];
23334 }
23335 }
23336
23337 return data;
23338 };
23339
23340 return function (data, type) { // row and meta also passed, but not used
23341 return fetchData( data, type, mSource );
23342 };
23343 }
23344 else
23345 {
23346 /* Array or flat object mapping */
23347 return function (data, type) { // row and meta also passed, but not used
23348 return data[mSource];
23349 };
23350 }
23351 }
23352
23353
23354 /**
23355 * Return a function that can be used to set data from a source object, taking
23356 * into account the ability to use nested objects as a source
23357 * @param {string|int|function} mSource The data source for the object
23358 * @returns {function} Data set function
23359 * @memberof DataTable#oApi
23360 */
23361 function _fnSetObjectDataFn( mSource )
23362 {
23363 if ( $.isPlainObject( mSource ) )
23364 {
23365 /* Unlike get, only the underscore (global) option is used for for
23366 * setting data since we don't know the type here. This is why an object
23367 * option is not documented for `mData` (which is read/write), but it is
23368 * for `mRender` which is read only.
23369 */
23370 return _fnSetObjectDataFn( mSource._ );
23371 }
23372 else if ( mSource === null )
23373 {
23374 /* Nothing to do when the data source is null */
23375 return function () {};
23376 }
23377 else if ( typeof mSource === 'function' )
23378 {
23379 return function (data, val, meta) {
23380 mSource( data, 'set', val, meta );
23381 };
23382 }
23383 else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
23384 mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
23385 {
23386 /* Like the get, we need to get data from a nested object */
23387 var setData = function (data, val, src) {
23388 var a = _fnSplitObjNotation( src ), b;
23389 var aLast = a[a.length-1];
23390 var arrayNotation, funcNotation, o, innerSrc;
23391
23392 for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
23393 {
23394 // Check if we are dealing with an array notation request
23395 arrayNotation = a[i].match(__reArray);
23396 funcNotation = a[i].match(__reFn);
23397
23398 if ( arrayNotation )
23399 {
23400 a[i] = a[i].replace(__reArray, '');
23401 data[ a[i] ] = [];
23402
23403 // Get the remainder of the nested object to set so we can recurse
23404 b = a.slice();
23405 b.splice( 0, i+1 );
23406 innerSrc = b.join('.');
23407
23408 // Traverse each entry in the array setting the properties requested
23409 if ( $.isArray( val ) )
23410 {
23411 for ( var j=0, jLen=val.length ; j<jLen ; j++ )
23412 {
23413 o = {};
23414 setData( o, val[j], innerSrc );
23415 data[ a[i] ].push( o );
23416 }
23417 }
23418 else
23419 {
23420 // We've been asked to save data to an array, but it
23421 // isn't array data to be saved. Best that can be done
23422 // is to just save the value.
23423 data[ a[i] ] = val;
23424 }
23425
23426 // The inner call to setData has already traversed through the remainder
23427 // of the source and has set the data, thus we can exit here
23428 return;
23429 }
23430 else if ( funcNotation )
23431 {
23432 // Function call
23433 a[i] = a[i].replace(__reFn, '');
23434 data = data[ a[i] ]( val );
23435 }
23436
23437 // If the nested object doesn't currently exist - since we are
23438 // trying to set the value - create it
23439 if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
23440 {
23441 data[ a[i] ] = {};
23442 }
23443 data = data[ a[i] ];
23444 }
23445
23446 // Last item in the input - i.e, the actual set
23447 if ( aLast.match(__reFn ) )
23448 {
23449 // Function call
23450 data = data[ aLast.replace(__reFn, '') ]( val );
23451 }
23452 else
23453 {
23454 // If array notation is used, we just want to strip it and use the property name
23455 // and assign the value. If it isn't used, then we get the result we want anyway
23456 data[ aLast.replace(__reArray, '') ] = val;
23457 }
23458 };
23459
23460 return function (data, val) { // meta is also passed in, but not used
23461 return setData( data, val, mSource );
23462 };
23463 }
23464 else
23465 {
23466 /* Array or flat object mapping */
23467 return function (data, val) { // meta is also passed in, but not used
23468 data[mSource] = val;
23469 };
23470 }
23471 }
23472
23473
23474 /**
23475 * Return an array with the full table data
23476 * @param {object} oSettings dataTables settings object
23477 * @returns array {array} aData Master data array
23478 * @memberof DataTable#oApi
23479 */
23480 function _fnGetDataMaster ( settings )
23481 {
23482 return _pluck( settings.aoData, '_aData' );
23483 }
23484
23485
23486 /**
23487 * Nuke the table
23488 * @param {object} oSettings dataTables settings object
23489 * @memberof DataTable#oApi
23490 */
23491 function _fnClearTable( settings )
23492 {
23493 settings.aoData.length = 0;
23494 settings.aiDisplayMaster.length = 0;
23495 settings.aiDisplay.length = 0;
23496 settings.aIds = {};
23497 }
23498
23499
23500 /**
23501 * Take an array of integers (index array) and remove a target integer (value - not
23502 * the key!)
23503 * @param {array} a Index array to target
23504 * @param {int} iTarget value to find
23505 * @memberof DataTable#oApi
23506 */
23507 function _fnDeleteIndex( a, iTarget, splice )
23508 {
23509 var iTargetIndex = -1;
23510
23511 for ( var i=0, iLen=a.length ; i<iLen ; i++ )
23512 {
23513 if ( a[i] == iTarget )
23514 {
23515 iTargetIndex = i;
23516 }
23517 else if ( a[i] > iTarget )
23518 {
23519 a[i]--;
23520 }
23521 }
23522
23523 if ( iTargetIndex != -1 && splice === undefined )
23524 {
23525 a.splice( iTargetIndex, 1 );
23526 }
23527 }
23528
23529
23530 /**
23531 * Mark cached data as invalid such that a re-read of the data will occur when
23532 * the cached data is next requested. Also update from the data source object.
23533 *
23534 * @param {object} settings DataTables settings object
23535 * @param {int} rowIdx Row index to invalidate
23536 * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
23537 * or 'data'
23538 * @param {int} [colIdx] Column index to invalidate. If undefined the whole
23539 * row will be invalidated
23540 * @memberof DataTable#oApi
23541 *
23542 * @todo For the modularisation of v1.11 this will need to become a callback, so
23543 * the sort and filter methods can subscribe to it. That will required
23544 * initialisation options for sorting, which is why it is not already baked in
23545 */
23546 function _fnInvalidate( settings, rowIdx, src, colIdx )
23547 {
23548 var row = settings.aoData[ rowIdx ];
23549 var i, ien;
23550 var cellWrite = function ( cell, col ) {
23551 // This is very frustrating, but in IE if you just write directly
23552 // to innerHTML, and elements that are overwritten are GC'ed,
23553 // even if there is a reference to them elsewhere
23554 while ( cell.childNodes.length ) {
23555 cell.removeChild( cell.firstChild );
23556 }
23557
23558 cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
23559 };
23560
23561 // Are we reading last data from DOM or the data object?
23562 if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
23563 // Read the data from the DOM
23564 row._aData = _fnGetRowElements(
23565 settings, row, colIdx, colIdx === undefined ? undefined : row._aData
23566 )
23567 .data;
23568 }
23569 else {
23570 // Reading from data object, update the DOM
23571 var cells = row.anCells;
23572
23573 if ( cells ) {
23574 if ( colIdx !== undefined ) {
23575 cellWrite( cells[colIdx], colIdx );
23576 }
23577 else {
23578 for ( i=0, ien=cells.length ; i<ien ; i++ ) {
23579 cellWrite( cells[i], i );
23580 }
23581 }
23582 }
23583 }
23584
23585 // For both row and cell invalidation, the cached data for sorting and
23586 // filtering is nulled out
23587 row._aSortData = null;
23588 row._aFilterData = null;
23589
23590 // Invalidate the type for a specific column (if given) or all columns since
23591 // the data might have changed
23592 var cols = settings.aoColumns;
23593 if ( colIdx !== undefined ) {
23594 cols[ colIdx ].sType = null;
23595 }
23596 else {
23597 for ( i=0, ien=cols.length ; i<ien ; i++ ) {
23598 cols[i].sType = null;
23599 }
23600
23601 // Update DataTables special `DT_*` attributes for the row
23602 _fnRowAttributes( settings, row );
23603 }
23604 }
23605
23606
23607 /**
23608 * Build a data source object from an HTML row, reading the contents of the
23609 * cells that are in the row.
23610 *
23611 * @param {object} settings DataTables settings object
23612 * @param {node|object} TR element from which to read data or existing row
23613 * object from which to re-read the data from the cells
23614 * @param {int} [colIdx] Optional column index
23615 * @param {array|object} [d] Data source object. If `colIdx` is given then this
23616 * parameter should also be given and will be used to write the data into.
23617 * Only the column in question will be written
23618 * @returns {object} Object with two parameters: `data` the data read, in
23619 * document order, and `cells` and array of nodes (they can be useful to the
23620 * caller, so rather than needing a second traversal to get them, just return
23621 * them from here).
23622 * @memberof DataTable#oApi
23623 */
23624 function _fnGetRowElements( settings, row, colIdx, d )
23625 {
23626 var
23627 tds = [],
23628 td = row.firstChild,
23629 name, col, o, i=0, contents,
23630 columns = settings.aoColumns,
23631 objectRead = settings._rowReadObject;
23632
23633 // Allow the data object to be passed in, or construct
23634 d = d !== undefined ?
23635 d :
23636 objectRead ?
23637 {} :
23638 [];
23639
23640 var attr = function ( str, td ) {
23641 if ( typeof str === 'string' ) {
23642 var idx = str.indexOf('@');
23643
23644 if ( idx !== -1 ) {
23645 var attr = str.substring( idx+1 );
23646 var setter = _fnSetObjectDataFn( str );
23647 setter( d, td.getAttribute( attr ) );
23648 }
23649 }
23650 };
23651
23652 // Read data from a cell and store into the data object
23653 var cellProcess = function ( cell ) {
23654 if ( colIdx === undefined || colIdx === i ) {
23655 col = columns[i];
23656 contents = $.trim(cell.innerHTML);
23657
23658 if ( col && col._bAttrSrc ) {
23659 var setter = _fnSetObjectDataFn( col.mData._ );
23660 setter( d, contents );
23661
23662 attr( col.mData.sort, cell );
23663 attr( col.mData.type, cell );
23664 attr( col.mData.filter, cell );
23665 }
23666 else {
23667 // Depending on the `data` option for the columns the data can
23668 // be read to either an object or an array.
23669 if ( objectRead ) {
23670 if ( ! col._setter ) {
23671 // Cache the setter function
23672 col._setter = _fnSetObjectDataFn( col.mData );
23673 }
23674 col._setter( d, contents );
23675 }
23676 else {
23677 d[i] = contents;
23678 }
23679 }
23680 }
23681
23682 i++;
23683 };
23684
23685 if ( td ) {
23686 // `tr` element was passed in
23687 while ( td ) {
23688 name = td.nodeName.toUpperCase();
23689
23690 if ( name == "TD" || name == "TH" ) {
23691 cellProcess( td );
23692 tds.push( td );
23693 }
23694
23695 td = td.nextSibling;
23696 }
23697 }
23698 else {
23699 // Existing row object passed in
23700 tds = row.anCells;
23701
23702 for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
23703 cellProcess( tds[j] );
23704 }
23705 }
23706
23707 // Read the ID from the DOM if present
23708 var rowNode = row.firstChild ? row : row.nTr;
23709
23710 if ( rowNode ) {
23711 var id = rowNode.getAttribute( 'id' );
23712
23713 if ( id ) {
23714 _fnSetObjectDataFn( settings.rowId )( d, id );
23715 }
23716 }
23717
23718 return {
23719 data: d,
23720 cells: tds
23721 };
23722 }
23723 /**
23724 * Create a new TR element (and it's TD children) for a row
23725 * @param {object} oSettings dataTables settings object
23726 * @param {int} iRow Row to consider
23727 * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
23728 * DataTables will create a row automatically
23729 * @param {array} [anTds] Array of TD|TH elements for the row - must be given
23730 * if nTr is.
23731 * @memberof DataTable#oApi
23732 */
23733 function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
23734 {
23735 var
23736 row = oSettings.aoData[iRow],
23737 rowData = row._aData,
23738 cells = [],
23739 nTr, nTd, oCol,
23740 i, iLen;
23741
23742 if ( row.nTr === null )
23743 {
23744 nTr = nTrIn || document.createElement('tr');
23745
23746 row.nTr = nTr;
23747 row.anCells = cells;
23748
23749 /* Use a private property on the node to allow reserve mapping from the node
23750 * to the aoData array for fast look up
23751 */
23752 nTr._DT_RowIndex = iRow;
23753
23754 /* Special parameters can be given by the data source to be used on the row */
23755 _fnRowAttributes( oSettings, row );
23756
23757 /* Process each column */
23758 for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
23759 {
23760 oCol = oSettings.aoColumns[i];
23761
23762 nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
23763 nTd._DT_CellIndex = {
23764 row: iRow,
23765 column: i
23766 };
23767
23768 cells.push( nTd );
23769
23770 // Need to create the HTML if new, or if a rendering function is defined
23771 if ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&
23772 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
23773 ) {
23774 nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
23775 }
23776
23777 /* Add user defined class */
23778 if ( oCol.sClass )
23779 {
23780 nTd.className += ' '+oCol.sClass;
23781 }
23782
23783 // Visibility - add or remove as required
23784 if ( oCol.bVisible && ! nTrIn )
23785 {
23786 nTr.appendChild( nTd );
23787 }
23788 else if ( ! oCol.bVisible && nTrIn )
23789 {
23790 nTd.parentNode.removeChild( nTd );
23791 }
23792
23793 if ( oCol.fnCreatedCell )
23794 {
23795 oCol.fnCreatedCell.call( oSettings.oInstance,
23796 nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
23797 );
23798 }
23799 }
23800
23801 _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
23802 }
23803
23804 // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
23805 // and deployed
23806 row.nTr.setAttribute( 'role', 'row' );
23807 }
23808
23809
23810 /**
23811 * Add attributes to a row based on the special `DT_*` parameters in a data
23812 * source object.
23813 * @param {object} settings DataTables settings object
23814 * @param {object} DataTables row object for the row to be modified
23815 * @memberof DataTable#oApi
23816 */
23817 function _fnRowAttributes( settings, row )
23818 {
23819 var tr = row.nTr;
23820 var data = row._aData;
23821
23822 if ( tr ) {
23823 var id = settings.rowIdFn( data );
23824
23825 if ( id ) {
23826 tr.id = id;
23827 }
23828
23829 if ( data.DT_RowClass ) {
23830 // Remove any classes added by DT_RowClass before
23831 var a = data.DT_RowClass.split(' ');
23832 row.__rowc = row.__rowc ?
23833 _unique( row.__rowc.concat( a ) ) :
23834 a;
23835
23836 $(tr)
23837 .removeClass( row.__rowc.join(' ') )
23838 .addClass( data.DT_RowClass );
23839 }
23840
23841 if ( data.DT_RowAttr ) {
23842 $(tr).attr( data.DT_RowAttr );
23843 }
23844
23845 if ( data.DT_RowData ) {
23846 $(tr).data( data.DT_RowData );
23847 }
23848 }
23849 }
23850
23851
23852 /**
23853 * Create the HTML header for the table
23854 * @param {object} oSettings dataTables settings object
23855 * @memberof DataTable#oApi
23856 */
23857 function _fnBuildHead( oSettings )
23858 {
23859 var i, ien, cell, row, column;
23860 var thead = oSettings.nTHead;
23861 var tfoot = oSettings.nTFoot;
23862 var createHeader = $('th, td', thead).length === 0;
23863 var classes = oSettings.oClasses;
23864 var columns = oSettings.aoColumns;
23865
23866 if ( createHeader ) {
23867 row = $('<tr/>').appendTo( thead );
23868 }
23869
23870 for ( i=0, ien=columns.length ; i<ien ; i++ ) {
23871 column = columns[i];
23872 cell = $( column.nTh ).addClass( column.sClass );
23873
23874 if ( createHeader ) {
23875 cell.appendTo( row );
23876 }
23877
23878 // 1.11 move into sorting
23879 if ( oSettings.oFeatures.bSort ) {
23880 cell.addClass( column.sSortingClass );
23881
23882 if ( column.bSortable !== false ) {
23883 cell
23884 .attr( 'tabindex', oSettings.iTabIndex )
23885 .attr( 'aria-controls', oSettings.sTableId );
23886
23887 _fnSortAttachListener( oSettings, column.nTh, i );
23888 }
23889 }
23890
23891 if ( column.sTitle != cell[0].innerHTML ) {
23892 cell.html( column.sTitle );
23893 }
23894
23895 _fnRenderer( oSettings, 'header' )(
23896 oSettings, cell, column, classes
23897 );
23898 }
23899
23900 if ( createHeader ) {
23901 _fnDetectHeader( oSettings.aoHeader, thead );
23902 }
23903
23904 /* ARIA role for the rows */
23905 $(thead).find('>tr').attr('role', 'row');
23906
23907 /* Deal with the footer - add classes if required */
23908 $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
23909 $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
23910
23911 // Cache the footer cells. Note that we only take the cells from the first
23912 // row in the footer. If there is more than one row the user wants to
23913 // interact with, they need to use the table().foot() method. Note also this
23914 // allows cells to be used for multiple columns using colspan
23915 if ( tfoot !== null ) {
23916 var cells = oSettings.aoFooter[0];
23917
23918 for ( i=0, ien=cells.length ; i<ien ; i++ ) {
23919 column = columns[i];
23920 column.nTf = cells[i].cell;
23921
23922 if ( column.sClass ) {
23923 $(column.nTf).addClass( column.sClass );
23924 }
23925 }
23926 }
23927 }
23928
23929
23930 /**
23931 * Draw the header (or footer) element based on the column visibility states. The
23932 * methodology here is to use the layout array from _fnDetectHeader, modified for
23933 * the instantaneous column visibility, to construct the new layout. The grid is
23934 * traversed over cell at a time in a rows x columns grid fashion, although each
23935 * cell insert can cover multiple elements in the grid - which is tracks using the
23936 * aApplied array. Cell inserts in the grid will only occur where there isn't
23937 * already a cell in that position.
23938 * @param {object} oSettings dataTables settings object
23939 * @param array {objects} aoSource Layout array from _fnDetectHeader
23940 * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
23941 * @memberof DataTable#oApi
23942 */
23943 function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
23944 {
23945 var i, iLen, j, jLen, k, kLen, n, nLocalTr;
23946 var aoLocal = [];
23947 var aApplied = [];
23948 var iColumns = oSettings.aoColumns.length;
23949 var iRowspan, iColspan;
23950
23951 if ( ! aoSource )
23952 {
23953 return;
23954 }
23955
23956 if ( bIncludeHidden === undefined )
23957 {
23958 bIncludeHidden = false;
23959 }
23960
23961 /* Make a copy of the master layout array, but without the visible columns in it */
23962 for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
23963 {
23964 aoLocal[i] = aoSource[i].slice();
23965 aoLocal[i].nTr = aoSource[i].nTr;
23966
23967 /* Remove any columns which are currently hidden */
23968 for ( j=iColumns-1 ; j>=0 ; j-- )
23969 {
23970 if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
23971 {
23972 aoLocal[i].splice( j, 1 );
23973 }
23974 }
23975
23976 /* Prep the applied array - it needs an element for each row */
23977 aApplied.push( [] );
23978 }
23979
23980 for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
23981 {
23982 nLocalTr = aoLocal[i].nTr;
23983
23984 /* All cells are going to be replaced, so empty out the row */
23985 if ( nLocalTr )
23986 {
23987 while( (n = nLocalTr.firstChild) )
23988 {
23989 nLocalTr.removeChild( n );
23990 }
23991 }
23992
23993 for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
23994 {
23995 iRowspan = 1;
23996 iColspan = 1;
23997
23998 /* Check to see if there is already a cell (row/colspan) covering our target
23999 * insert point. If there is, then there is nothing to do.
24000 */
24001 if ( aApplied[i][j] === undefined )
24002 {
24003 nLocalTr.appendChild( aoLocal[i][j].cell );
24004 aApplied[i][j] = 1;
24005
24006 /* Expand the cell to cover as many rows as needed */
24007 while ( aoLocal[i+iRowspan] !== undefined &&
24008 aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
24009 {
24010 aApplied[i+iRowspan][j] = 1;
24011 iRowspan++;
24012 }
24013
24014 /* Expand the cell to cover as many columns as needed */
24015 while ( aoLocal[i][j+iColspan] !== undefined &&
24016 aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
24017 {
24018 /* Must update the applied array over the rows for the columns */
24019 for ( k=0 ; k<iRowspan ; k++ )
24020 {
24021 aApplied[i+k][j+iColspan] = 1;
24022 }
24023 iColspan++;
24024 }
24025
24026 /* Do the actual expansion in the DOM */
24027 $(aoLocal[i][j].cell)
24028 .attr('rowspan', iRowspan)
24029 .attr('colspan', iColspan);
24030 }
24031 }
24032 }
24033 }
24034
24035
24036 /**
24037 * Insert the required TR nodes into the table for display
24038 * @param {object} oSettings dataTables settings object
24039 * @memberof DataTable#oApi
24040 */
24041 function _fnDraw( oSettings )
24042 {
24043 /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
24044 var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
24045 if ( $.inArray( false, aPreDraw ) !== -1 )
24046 {
24047 _fnProcessingDisplay( oSettings, false );
24048 return;
24049 }
24050
24051 var i, iLen, n;
24052 var anRows = [];
24053 var iRowCount = 0;
24054 var asStripeClasses = oSettings.asStripeClasses;
24055 var iStripes = asStripeClasses.length;
24056 var iOpenRows = oSettings.aoOpenRows.length;
24057 var oLang = oSettings.oLanguage;
24058 var iInitDisplayStart = oSettings.iInitDisplayStart;
24059 var bServerSide = _fnDataSource( oSettings ) == 'ssp';
24060 var aiDisplay = oSettings.aiDisplay;
24061
24062 oSettings.bDrawing = true;
24063
24064 /* Check and see if we have an initial draw position from state saving */
24065 if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
24066 {
24067 oSettings._iDisplayStart = bServerSide ?
24068 iInitDisplayStart :
24069 iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
24070 0 :
24071 iInitDisplayStart;
24072
24073 oSettings.iInitDisplayStart = -1;
24074 }
24075
24076 var iDisplayStart = oSettings._iDisplayStart;
24077 var iDisplayEnd = oSettings.fnDisplayEnd();
24078
24079 /* Server-side processing draw intercept */
24080 if ( oSettings.bDeferLoading )
24081 {
24082 oSettings.bDeferLoading = false;
24083 oSettings.iDraw++;
24084 _fnProcessingDisplay( oSettings, false );
24085 }
24086 else if ( !bServerSide )
24087 {
24088 oSettings.iDraw++;
24089 }
24090 else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
24091 {
24092 return;
24093 }
24094
24095 if ( aiDisplay.length !== 0 )
24096 {
24097 var iStart = bServerSide ? 0 : iDisplayStart;
24098 var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
24099
24100 for ( var j=iStart ; j<iEnd ; j++ )
24101 {
24102 var iDataIndex = aiDisplay[j];
24103 var aoData = oSettings.aoData[ iDataIndex ];
24104 if ( aoData.nTr === null )
24105 {
24106 _fnCreateTr( oSettings, iDataIndex );
24107 }
24108
24109 var nRow = aoData.nTr;
24110
24111 /* Remove the old striping classes and then add the new one */
24112 if ( iStripes !== 0 )
24113 {
24114 var sStripe = asStripeClasses[ iRowCount % iStripes ];
24115 if ( aoData._sRowStripe != sStripe )
24116 {
24117 $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
24118 aoData._sRowStripe = sStripe;
24119 }
24120 }
24121
24122 // Row callback functions - might want to manipulate the row
24123 // iRowCount and j are not currently documented. Are they at all
24124 // useful?
24125 _fnCallbackFire( oSettings, 'aoRowCallback', null,
24126 [nRow, aoData._aData, iRowCount, j] );
24127
24128 anRows.push( nRow );
24129 iRowCount++;
24130 }
24131 }
24132 else
24133 {
24134 /* Table is empty - create a row with an empty message in it */
24135 var sZero = oLang.sZeroRecords;
24136 if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
24137 {
24138 sZero = oLang.sLoadingRecords;
24139 }
24140 else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
24141 {
24142 sZero = oLang.sEmptyTable;
24143 }
24144
24145 anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
24146 .append( $('<td />', {
24147 'valign': 'top',
24148 'colSpan': _fnVisbleColumns( oSettings ),
24149 'class': oSettings.oClasses.sRowEmpty
24150 } ).html( sZero ) )[0];
24151 }
24152
24153 /* Header and footer callbacks */
24154 _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
24155 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
24156
24157 _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
24158 _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
24159
24160 var body = $(oSettings.nTBody);
24161
24162 body.children().detach();
24163 body.append( $(anRows) );
24164
24165 /* Call all required callback functions for the end of a draw */
24166 _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
24167
24168 /* Draw is complete, sorting and filtering must be as well */
24169 oSettings.bSorted = false;
24170 oSettings.bFiltered = false;
24171 oSettings.bDrawing = false;
24172 }
24173
24174
24175 /**
24176 * Redraw the table - taking account of the various features which are enabled
24177 * @param {object} oSettings dataTables settings object
24178 * @param {boolean} [holdPosition] Keep the current paging position. By default
24179 * the paging is reset to the first page
24180 * @memberof DataTable#oApi
24181 */
24182 function _fnReDraw( settings, holdPosition )
24183 {
24184 var
24185 features = settings.oFeatures,
24186 sort = features.bSort,
24187 filter = features.bFilter;
24188
24189 if ( sort ) {
24190 _fnSort( settings );
24191 }
24192
24193 if ( filter ) {
24194 _fnFilterComplete( settings, settings.oPreviousSearch );
24195 }
24196 else {
24197 // No filtering, so we want to just use the display master
24198 settings.aiDisplay = settings.aiDisplayMaster.slice();
24199 }
24200
24201 if ( holdPosition !== true ) {
24202 settings._iDisplayStart = 0;
24203 }
24204
24205 // Let any modules know about the draw hold position state (used by
24206 // scrolling internally)
24207 settings._drawHold = holdPosition;
24208
24209 _fnDraw( settings );
24210
24211 settings._drawHold = false;
24212 }
24213
24214
24215 /**
24216 * Add the options to the page HTML for the table
24217 * @param {object} oSettings dataTables settings object
24218 * @memberof DataTable#oApi
24219 */
24220 function _fnAddOptionsHtml ( oSettings )
24221 {
24222 var classes = oSettings.oClasses;
24223 var table = $(oSettings.nTable);
24224 var holding = $('<div/>').insertBefore( table ); // Holding element for speed
24225 var features = oSettings.oFeatures;
24226
24227 // All DataTables are wrapped in a div
24228 var insert = $('<div/>', {
24229 id: oSettings.sTableId+'_wrapper',
24230 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
24231 } );
24232
24233 oSettings.nHolding = holding[0];
24234 oSettings.nTableWrapper = insert[0];
24235 oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
24236
24237 /* Loop over the user set positioning and place the elements as needed */
24238 var aDom = oSettings.sDom.split('');
24239 var featureNode, cOption, nNewNode, cNext, sAttr, j;
24240 for ( var i=0 ; i<aDom.length ; i++ )
24241 {
24242 featureNode = null;
24243 cOption = aDom[i];
24244
24245 if ( cOption == '<' )
24246 {
24247 /* New container div */
24248 nNewNode = $('<div/>')[0];
24249
24250 /* Check to see if we should append an id and/or a class name to the container */
24251 cNext = aDom[i+1];
24252 if ( cNext == "'" || cNext == '"' )
24253 {
24254 sAttr = "";
24255 j = 2;
24256 while ( aDom[i+j] != cNext )
24257 {
24258 sAttr += aDom[i+j];
24259 j++;
24260 }
24261
24262 /* Replace jQuery UI constants @todo depreciated */
24263 if ( sAttr == "H" )
24264 {
24265 sAttr = classes.sJUIHeader;
24266 }
24267 else if ( sAttr == "F" )
24268 {
24269 sAttr = classes.sJUIFooter;
24270 }
24271
24272 /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
24273 * breaks the string into parts and applies them as needed
24274 */
24275 if ( sAttr.indexOf('.') != -1 )
24276 {
24277 var aSplit = sAttr.split('.');
24278 nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
24279 nNewNode.className = aSplit[1];
24280 }
24281 else if ( sAttr.charAt(0) == "#" )
24282 {
24283 nNewNode.id = sAttr.substr(1, sAttr.length-1);
24284 }
24285 else
24286 {
24287 nNewNode.className = sAttr;
24288 }
24289
24290 i += j; /* Move along the position array */
24291 }
24292
24293 insert.append( nNewNode );
24294 insert = $(nNewNode);
24295 }
24296 else if ( cOption == '>' )
24297 {
24298 /* End container div */
24299 insert = insert.parent();
24300 }
24301 // @todo Move options into their own plugins?
24302 else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
24303 {
24304 /* Length */
24305 featureNode = _fnFeatureHtmlLength( oSettings );
24306 }
24307 else if ( cOption == 'f' && features.bFilter )
24308 {
24309 /* Filter */
24310 featureNode = _fnFeatureHtmlFilter( oSettings );
24311 }
24312 else if ( cOption == 'r' && features.bProcessing )
24313 {
24314 /* pRocessing */
24315 featureNode = _fnFeatureHtmlProcessing( oSettings );
24316 }
24317 else if ( cOption == 't' )
24318 {
24319 /* Table */
24320 featureNode = _fnFeatureHtmlTable( oSettings );
24321 }
24322 else if ( cOption == 'i' && features.bInfo )
24323 {
24324 /* Info */
24325 featureNode = _fnFeatureHtmlInfo( oSettings );
24326 }
24327 else if ( cOption == 'p' && features.bPaginate )
24328 {
24329 /* Pagination */
24330 featureNode = _fnFeatureHtmlPaginate( oSettings );
24331 }
24332 else if ( DataTable.ext.feature.length !== 0 )
24333 {
24334 /* Plug-in features */
24335 var aoFeatures = DataTable.ext.feature;
24336 for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
24337 {
24338 if ( cOption == aoFeatures[k].cFeature )
24339 {
24340 featureNode = aoFeatures[k].fnInit( oSettings );
24341 break;
24342 }
24343 }
24344 }
24345
24346 /* Add to the 2D features array */
24347 if ( featureNode )
24348 {
24349 var aanFeatures = oSettings.aanFeatures;
24350
24351 if ( ! aanFeatures[cOption] )
24352 {
24353 aanFeatures[cOption] = [];
24354 }
24355
24356 aanFeatures[cOption].push( featureNode );
24357 insert.append( featureNode );
24358 }
24359 }
24360
24361 /* Built our DOM structure - replace the holding div with what we want */
24362 holding.replaceWith( insert );
24363 oSettings.nHolding = null;
24364 }
24365
24366
24367 /**
24368 * Use the DOM source to create up an array of header cells. The idea here is to
24369 * create a layout grid (array) of rows x columns, which contains a reference
24370 * to the cell that that point in the grid (regardless of col/rowspan), such that
24371 * any column / row could be removed and the new grid constructed
24372 * @param array {object} aLayout Array to store the calculated layout in
24373 * @param {node} nThead The header/footer element for the table
24374 * @memberof DataTable#oApi
24375 */
24376 function _fnDetectHeader ( aLayout, nThead )
24377 {
24378 var nTrs = $(nThead).children('tr');
24379 var nTr, nCell;
24380 var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
24381 var bUnique;
24382 var fnShiftCol = function ( a, i, j ) {
24383 var k = a[i];
24384 while ( k[j] ) {
24385 j++;
24386 }
24387 return j;
24388 };
24389
24390 aLayout.splice( 0, aLayout.length );
24391
24392 /* We know how many rows there are in the layout - so prep it */
24393 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
24394 {
24395 aLayout.push( [] );
24396 }
24397
24398 /* Calculate a layout array */
24399 for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
24400 {
24401 nTr = nTrs[i];
24402 iColumn = 0;
24403
24404 /* For every cell in the row... */
24405 nCell = nTr.firstChild;
24406 while ( nCell ) {
24407 if ( nCell.nodeName.toUpperCase() == "TD" ||
24408 nCell.nodeName.toUpperCase() == "TH" )
24409 {
24410 /* Get the col and rowspan attributes from the DOM and sanitise them */
24411 iColspan = nCell.getAttribute('colspan') * 1;
24412 iRowspan = nCell.getAttribute('rowspan') * 1;
24413 iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
24414 iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
24415
24416 /* There might be colspan cells already in this row, so shift our target
24417 * accordingly
24418 */
24419 iColShifted = fnShiftCol( aLayout, i, iColumn );
24420
24421 /* Cache calculation for unique columns */
24422 bUnique = iColspan === 1 ? true : false;
24423
24424 /* If there is col / rowspan, copy the information into the layout grid */
24425 for ( l=0 ; l<iColspan ; l++ )
24426 {
24427 for ( k=0 ; k<iRowspan ; k++ )
24428 {
24429 aLayout[i+k][iColShifted+l] = {
24430 "cell": nCell,
24431 "unique": bUnique
24432 };
24433 aLayout[i+k].nTr = nTr;
24434 }
24435 }
24436 }
24437 nCell = nCell.nextSibling;
24438 }
24439 }
24440 }
24441
24442
24443 /**
24444 * Get an array of unique th elements, one for each column
24445 * @param {object} oSettings dataTables settings object
24446 * @param {node} nHeader automatically detect the layout from this node - optional
24447 * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
24448 * @returns array {node} aReturn list of unique th's
24449 * @memberof DataTable#oApi
24450 */
24451 function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
24452 {
24453 var aReturn = [];
24454 if ( !aLayout )
24455 {
24456 aLayout = oSettings.aoHeader;
24457 if ( nHeader )
24458 {
24459 aLayout = [];
24460 _fnDetectHeader( aLayout, nHeader );
24461 }
24462 }
24463
24464 for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
24465 {
24466 for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
24467 {
24468 if ( aLayout[i][j].unique &&
24469 (!aReturn[j] || !oSettings.bSortCellsTop) )
24470 {
24471 aReturn[j] = aLayout[i][j].cell;
24472 }
24473 }
24474 }
24475
24476 return aReturn;
24477 }
24478
24479 /**
24480 * Create an Ajax call based on the table's settings, taking into account that
24481 * parameters can have multiple forms, and backwards compatibility.
24482 *
24483 * @param {object} oSettings dataTables settings object
24484 * @param {array} data Data to send to the server, required by
24485 * DataTables - may be augmented by developer callbacks
24486 * @param {function} fn Callback function to run when data is obtained
24487 */
24488 function _fnBuildAjax( oSettings, data, fn )
24489 {
24490 // Compatibility with 1.9-, allow fnServerData and event to manipulate
24491 _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
24492
24493 // Convert to object based for 1.10+ if using the old array scheme which can
24494 // come from server-side processing or serverParams
24495 if ( data && $.isArray(data) ) {
24496 var tmp = {};
24497 var rbracket = /(.*?)\[\]$/;
24498
24499 $.each( data, function (key, val) {
24500 var match = val.name.match(rbracket);
24501
24502 if ( match ) {
24503 // Support for arrays
24504 var name = match[0];
24505
24506 if ( ! tmp[ name ] ) {
24507 tmp[ name ] = [];
24508 }
24509 tmp[ name ].push( val.value );
24510 }
24511 else {
24512 tmp[val.name] = val.value;
24513 }
24514 } );
24515 data = tmp;
24516 }
24517
24518 var ajaxData;
24519 var ajax = oSettings.ajax;
24520 var instance = oSettings.oInstance;
24521 var callback = function ( json ) {
24522 _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
24523 fn( json );
24524 };
24525
24526 if ( $.isPlainObject( ajax ) && ajax.data )
24527 {
24528 ajaxData = ajax.data;
24529
24530 var newData = $.isFunction( ajaxData ) ?
24531 ajaxData( data, oSettings ) : // fn can manipulate data or return
24532 ajaxData; // an object object or array to merge
24533
24534 // If the function returned something, use that alone
24535 data = $.isFunction( ajaxData ) && newData ?
24536 newData :
24537 $.extend( true, data, newData );
24538
24539 // Remove the data property as we've resolved it already and don't want
24540 // jQuery to do it again (it is restored at the end of the function)
24541 delete ajax.data;
24542 }
24543
24544 var baseAjax = {
24545 "data": data,
24546 "success": function (json) {
24547 var error = json.error || json.sError;
24548 if ( error ) {
24549 _fnLog( oSettings, 0, error );
24550 }
24551
24552 oSettings.json = json;
24553 callback( json );
24554 },
24555 "dataType": "json",
24556 "cache": false,
24557 "type": oSettings.sServerMethod,
24558 "error": function (xhr, error, thrown) {
24559 var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
24560
24561 if ( $.inArray( true, ret ) === -1 ) {
24562 if ( error == "parsererror" ) {
24563 _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
24564 }
24565 else if ( xhr.readyState === 4 ) {
24566 _fnLog( oSettings, 0, 'Ajax error', 7 );
24567 }
24568 }
24569
24570 _fnProcessingDisplay( oSettings, false );
24571 }
24572 };
24573
24574 // Store the data submitted for the API
24575 oSettings.oAjaxData = data;
24576
24577 // Allow plug-ins and external processes to modify the data
24578 _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
24579
24580 if ( oSettings.fnServerData )
24581 {
24582 // DataTables 1.9- compatibility
24583 oSettings.fnServerData.call( instance,
24584 oSettings.sAjaxSource,
24585 $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
24586 return { name: key, value: val };
24587 } ),
24588 callback,
24589 oSettings
24590 );
24591 }
24592 else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
24593 {
24594 // DataTables 1.9- compatibility
24595 oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
24596 url: ajax || oSettings.sAjaxSource
24597 } ) );
24598 }
24599 else if ( $.isFunction( ajax ) )
24600 {
24601 // Is a function - let the caller define what needs to be done
24602 oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
24603 }
24604 else
24605 {
24606 // Object to extend the base settings
24607 oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
24608
24609 // Restore for next time around
24610 ajax.data = ajaxData;
24611 }
24612 }
24613
24614
24615 /**
24616 * Update the table using an Ajax call
24617 * @param {object} settings dataTables settings object
24618 * @returns {boolean} Block the table drawing or not
24619 * @memberof DataTable#oApi
24620 */
24621 function _fnAjaxUpdate( settings )
24622 {
24623 if ( settings.bAjaxDataGet ) {
24624 settings.iDraw++;
24625 _fnProcessingDisplay( settings, true );
24626
24627 _fnBuildAjax(
24628 settings,
24629 _fnAjaxParameters( settings ),
24630 function(json) {
24631 _fnAjaxUpdateDraw( settings, json );
24632 }
24633 );
24634
24635 return false;
24636 }
24637 return true;
24638 }
24639
24640
24641 /**
24642 * Build up the parameters in an object needed for a server-side processing
24643 * request. Note that this is basically done twice, is different ways - a modern
24644 * method which is used by default in DataTables 1.10 which uses objects and
24645 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
24646 * the sAjaxSource option is used in the initialisation, or the legacyAjax
24647 * option is set.
24648 * @param {object} oSettings dataTables settings object
24649 * @returns {bool} block the table drawing or not
24650 * @memberof DataTable#oApi
24651 */
24652 function _fnAjaxParameters( settings )
24653 {
24654 var
24655 columns = settings.aoColumns,
24656 columnCount = columns.length,
24657 features = settings.oFeatures,
24658 preSearch = settings.oPreviousSearch,
24659 preColSearch = settings.aoPreSearchCols,
24660 i, data = [], dataProp, column, columnSearch,
24661 sort = _fnSortFlatten( settings ),
24662 displayStart = settings._iDisplayStart,
24663 displayLength = features.bPaginate !== false ?
24664 settings._iDisplayLength :
24665 -1;
24666
24667 var param = function ( name, value ) {
24668 data.push( { 'name': name, 'value': value } );
24669 };
24670
24671 // DataTables 1.9- compatible method
24672 param( 'sEcho', settings.iDraw );
24673 param( 'iColumns', columnCount );
24674 param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
24675 param( 'iDisplayStart', displayStart );
24676 param( 'iDisplayLength', displayLength );
24677
24678 // DataTables 1.10+ method
24679 var d = {
24680 draw: settings.iDraw,
24681 columns: [],
24682 order: [],
24683 start: displayStart,
24684 length: displayLength,
24685 search: {
24686 value: preSearch.sSearch,
24687 regex: preSearch.bRegex
24688 }
24689 };
24690
24691 for ( i=0 ; i<columnCount ; i++ ) {
24692 column = columns[i];
24693 columnSearch = preColSearch[i];
24694 dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
24695
24696 d.columns.push( {
24697 data: dataProp,
24698 name: column.sName,
24699 searchable: column.bSearchable,
24700 orderable: column.bSortable,
24701 search: {
24702 value: columnSearch.sSearch,
24703 regex: columnSearch.bRegex
24704 }
24705 } );
24706
24707 param( "mDataProp_"+i, dataProp );
24708
24709 if ( features.bFilter ) {
24710 param( 'sSearch_'+i, columnSearch.sSearch );
24711 param( 'bRegex_'+i, columnSearch.bRegex );
24712 param( 'bSearchable_'+i, column.bSearchable );
24713 }
24714
24715 if ( features.bSort ) {
24716 param( 'bSortable_'+i, column.bSortable );
24717 }
24718 }
24719
24720 if ( features.bFilter ) {
24721 param( 'sSearch', preSearch.sSearch );
24722 param( 'bRegex', preSearch.bRegex );
24723 }
24724
24725 if ( features.bSort ) {
24726 $.each( sort, function ( i, val ) {
24727 d.order.push( { column: val.col, dir: val.dir } );
24728
24729 param( 'iSortCol_'+i, val.col );
24730 param( 'sSortDir_'+i, val.dir );
24731 } );
24732
24733 param( 'iSortingCols', sort.length );
24734 }
24735
24736 // If the legacy.ajax parameter is null, then we automatically decide which
24737 // form to use, based on sAjaxSource
24738 var legacy = DataTable.ext.legacy.ajax;
24739 if ( legacy === null ) {
24740 return settings.sAjaxSource ? data : d;
24741 }
24742
24743 // Otherwise, if legacy has been specified then we use that to decide on the
24744 // form
24745 return legacy ? data : d;
24746 }
24747
24748
24749 /**
24750 * Data the data from the server (nuking the old) and redraw the table
24751 * @param {object} oSettings dataTables settings object
24752 * @param {object} json json data return from the server.
24753 * @param {string} json.sEcho Tracking flag for DataTables to match requests
24754 * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
24755 * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
24756 * @param {array} json.aaData The data to display on this page
24757 * @param {string} [json.sColumns] Column ordering (sName, comma separated)
24758 * @memberof DataTable#oApi
24759 */
24760 function _fnAjaxUpdateDraw ( settings, json )
24761 {
24762 // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
24763 // Support both
24764 var compat = function ( old, modern ) {
24765 return json[old] !== undefined ? json[old] : json[modern];
24766 };
24767
24768 var data = _fnAjaxDataSrc( settings, json );
24769 var draw = compat( 'sEcho', 'draw' );
24770 var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
24771 var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
24772
24773 if ( draw ) {
24774 // Protect against out of sequence returns
24775 if ( draw*1 < settings.iDraw ) {
24776 return;
24777 }
24778 settings.iDraw = draw * 1;
24779 }
24780
24781 _fnClearTable( settings );
24782 settings._iRecordsTotal = parseInt(recordsTotal, 10);
24783 settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
24784
24785 for ( var i=0, ien=data.length ; i<ien ; i++ ) {
24786 _fnAddData( settings, data[i] );
24787 }
24788 settings.aiDisplay = settings.aiDisplayMaster.slice();
24789
24790 settings.bAjaxDataGet = false;
24791 _fnDraw( settings );
24792
24793 if ( ! settings._bInitComplete ) {
24794 _fnInitComplete( settings, json );
24795 }
24796
24797 settings.bAjaxDataGet = true;
24798 _fnProcessingDisplay( settings, false );
24799 }
24800
24801
24802 /**
24803 * Get the data from the JSON data source to use for drawing a table. Using
24804 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
24805 * source object, or from a processing function.
24806 * @param {object} oSettings dataTables settings object
24807 * @param {object} json Data source object / array from the server
24808 * @return {array} Array of data to use
24809 */
24810 function _fnAjaxDataSrc ( oSettings, json )
24811 {
24812 var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
24813 oSettings.ajax.dataSrc :
24814 oSettings.sAjaxDataProp; // Compatibility with 1.9-.
24815
24816 // Compatibility with 1.9-. In order to read from aaData, check if the
24817 // default has been changed, if not, check for aaData
24818 if ( dataSrc === 'data' ) {
24819 return json.aaData || json[dataSrc];
24820 }
24821
24822 return dataSrc !== "" ?
24823 _fnGetObjectDataFn( dataSrc )( json ) :
24824 json;
24825 }
24826
24827 /**
24828 * Generate the node required for filtering text
24829 * @returns {node} Filter control element
24830 * @param {object} oSettings dataTables settings object
24831 * @memberof DataTable#oApi
24832 */
24833 function _fnFeatureHtmlFilter ( settings )
24834 {
24835 var classes = settings.oClasses;
24836 var tableId = settings.sTableId;
24837 var language = settings.oLanguage;
24838 var previousSearch = settings.oPreviousSearch;
24839 var features = settings.aanFeatures;
24840 var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
24841
24842 var str = language.sSearch;
24843 str = str.match(/_INPUT_/) ?
24844 str.replace('_INPUT_', input) :
24845 str+input;
24846
24847 var filter = $('<div/>', {
24848 'id': ! features.f ? tableId+'_filter' : null,
24849 'class': classes.sFilter
24850 } )
24851 .append( $('<label/>' ).append( str ) );
24852
24853 var searchFn = function() {
24854 /* Update all other filter input elements for the new display */
24855 var n = features.f;
24856 var val = !this.value ? "" : this.value; // mental IE8 fix :-(
24857
24858 /* Now do the filter */
24859 if ( val != previousSearch.sSearch ) {
24860 _fnFilterComplete( settings, {
24861 "sSearch": val,
24862 "bRegex": previousSearch.bRegex,
24863 "bSmart": previousSearch.bSmart ,
24864 "bCaseInsensitive": previousSearch.bCaseInsensitive
24865 } );
24866
24867 // Need to redraw, without resorting
24868 settings._iDisplayStart = 0;
24869 _fnDraw( settings );
24870 }
24871 };
24872
24873 var searchDelay = settings.searchDelay !== null ?
24874 settings.searchDelay :
24875 _fnDataSource( settings ) === 'ssp' ?
24876 400 :
24877 0;
24878
24879 var jqFilter = $('input', filter)
24880 .val( previousSearch.sSearch )
24881 .attr( 'placeholder', language.sSearchPlaceholder )
24882 .bind(
24883 'keyup.DT search.DT input.DT paste.DT cut.DT',
24884 searchDelay ?
24885 _fnThrottle( searchFn, searchDelay ) :
24886 searchFn
24887 )
24888 .bind( 'keypress.DT', function(e) {
24889 /* Prevent form submission */
24890 if ( e.keyCode == 13 ) {
24891 return false;
24892 }
24893 } )
24894 .attr('aria-controls', tableId);
24895
24896 // Update the input elements whenever the table is filtered
24897 $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
24898 if ( settings === s ) {
24899 // IE9 throws an 'unknown error' if document.activeElement is used
24900 // inside an iframe or frame...
24901 try {
24902 if ( jqFilter[0] !== document.activeElement ) {
24903 jqFilter.val( previousSearch.sSearch );
24904 }
24905 }
24906 catch ( e ) {}
24907 }
24908 } );
24909
24910 return filter[0];
24911 }
24912
24913
24914 /**
24915 * Filter the table using both the global filter and column based filtering
24916 * @param {object} oSettings dataTables settings object
24917 * @param {object} oSearch search information
24918 * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
24919 * @memberof DataTable#oApi
24920 */
24921 function _fnFilterComplete ( oSettings, oInput, iForce )
24922 {
24923 var oPrevSearch = oSettings.oPreviousSearch;
24924 var aoPrevSearch = oSettings.aoPreSearchCols;
24925 var fnSaveFilter = function ( oFilter ) {
24926 /* Save the filtering values */
24927 oPrevSearch.sSearch = oFilter.sSearch;
24928 oPrevSearch.bRegex = oFilter.bRegex;
24929 oPrevSearch.bSmart = oFilter.bSmart;
24930 oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
24931 };
24932 var fnRegex = function ( o ) {
24933 // Backwards compatibility with the bEscapeRegex option
24934 return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
24935 };
24936
24937 // Resolve any column types that are unknown due to addition or invalidation
24938 // @todo As per sort - can this be moved into an event handler?
24939 _fnColumnTypes( oSettings );
24940
24941 /* In server-side processing all filtering is done by the server, so no point hanging around here */
24942 if ( _fnDataSource( oSettings ) != 'ssp' )
24943 {
24944 /* Global filter */
24945 _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
24946 fnSaveFilter( oInput );
24947
24948 /* Now do the individual column filter */
24949 for ( var i=0 ; i<aoPrevSearch.length ; i++ )
24950 {
24951 _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
24952 aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
24953 }
24954
24955 /* Custom filtering */
24956 _fnFilterCustom( oSettings );
24957 }
24958 else
24959 {
24960 fnSaveFilter( oInput );
24961 }
24962
24963 /* Tell the draw function we have been filtering */
24964 oSettings.bFiltered = true;
24965 _fnCallbackFire( oSettings, null, 'search', [oSettings] );
24966 }
24967
24968
24969 /**
24970 * Apply custom filtering functions
24971 * @param {object} oSettings dataTables settings object
24972 * @memberof DataTable#oApi
24973 */
24974 function _fnFilterCustom( settings )
24975 {
24976 var filters = DataTable.ext.search;
24977 var displayRows = settings.aiDisplay;
24978 var row, rowIdx;
24979
24980 for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
24981 var rows = [];
24982
24983 // Loop over each row and see if it should be included
24984 for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
24985 rowIdx = displayRows[ j ];
24986 row = settings.aoData[ rowIdx ];
24987
24988 if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
24989 rows.push( rowIdx );
24990 }
24991 }
24992
24993 // So the array reference doesn't break set the results into the
24994 // existing array
24995 displayRows.length = 0;
24996 $.merge( displayRows, rows );
24997 }
24998 }
24999
25000
25001 /**
25002 * Filter the table on a per-column basis
25003 * @param {object} oSettings dataTables settings object
25004 * @param {string} sInput string to filter on
25005 * @param {int} iColumn column to filter
25006 * @param {bool} bRegex treat search string as a regular expression or not
25007 * @param {bool} bSmart use smart filtering or not
25008 * @param {bool} bCaseInsensitive Do case insenstive matching or not
25009 * @memberof DataTable#oApi
25010 */
25011 function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
25012 {
25013 if ( searchStr === '' ) {
25014 return;
25015 }
25016
25017 var data;
25018 var display = settings.aiDisplay;
25019 var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
25020
25021 for ( var i=display.length-1 ; i>=0 ; i-- ) {
25022 data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
25023
25024 if ( ! rpSearch.test( data ) ) {
25025 display.splice( i, 1 );
25026 }
25027 }
25028 }
25029
25030
25031 /**
25032 * Filter the data table based on user input and draw the table
25033 * @param {object} settings dataTables settings object
25034 * @param {string} input string to filter on
25035 * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
25036 * @param {bool} regex treat as a regular expression or not
25037 * @param {bool} smart perform smart filtering or not
25038 * @param {bool} caseInsensitive Do case insenstive matching or not
25039 * @memberof DataTable#oApi
25040 */
25041 function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
25042 {
25043 var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
25044 var prevSearch = settings.oPreviousSearch.sSearch;
25045 var displayMaster = settings.aiDisplayMaster;
25046 var display, invalidated, i;
25047
25048 // Need to take account of custom filtering functions - always filter
25049 if ( DataTable.ext.search.length !== 0 ) {
25050 force = true;
25051 }
25052
25053 // Check if any of the rows were invalidated
25054 invalidated = _fnFilterData( settings );
25055
25056 // If the input is blank - we just want the full data set
25057 if ( input.length <= 0 ) {
25058 settings.aiDisplay = displayMaster.slice();
25059 }
25060 else {
25061 // New search - start from the master array
25062 if ( invalidated ||
25063 force ||
25064 prevSearch.length > input.length ||
25065 input.indexOf(prevSearch) !== 0 ||
25066 settings.bSorted // On resort, the display master needs to be
25067 // re-filtered since indexes will have changed
25068 ) {
25069 settings.aiDisplay = displayMaster.slice();
25070 }
25071
25072 // Search the display array
25073 display = settings.aiDisplay;
25074
25075 for ( i=display.length-1 ; i>=0 ; i-- ) {
25076 if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
25077 display.splice( i, 1 );
25078 }
25079 }
25080 }
25081 }
25082
25083
25084 /**
25085 * Build a regular expression object suitable for searching a table
25086 * @param {string} sSearch string to search for
25087 * @param {bool} bRegex treat as a regular expression or not
25088 * @param {bool} bSmart perform smart filtering or not
25089 * @param {bool} bCaseInsensitive Do case insensitive matching or not
25090 * @returns {RegExp} constructed object
25091 * @memberof DataTable#oApi
25092 */
25093 function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
25094 {
25095 search = regex ?
25096 search :
25097 _fnEscapeRegex( search );
25098
25099 if ( smart ) {
25100 /* For smart filtering we want to allow the search to work regardless of
25101 * word order. We also want double quoted text to be preserved, so word
25102 * order is important - a la google. So this is what we want to
25103 * generate:
25104 *
25105 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
25106 */
25107 var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
25108 if ( word.charAt(0) === '"' ) {
25109 var m = word.match( /^"(.*)"$/ );
25110 word = m ? m[1] : word;
25111 }
25112
25113 return word.replace('"', '');
25114 } );
25115
25116 search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
25117 }
25118
25119 return new RegExp( search, caseInsensitive ? 'i' : '' );
25120 }
25121
25122
25123 /**
25124 * Escape a string such that it can be used in a regular expression
25125 * @param {string} sVal string to escape
25126 * @returns {string} escaped string
25127 * @memberof DataTable#oApi
25128 */
25129 var _fnEscapeRegex = DataTable.util.escapeRegex;
25130
25131 var __filter_div = $('<div>')[0];
25132 var __filter_div_textContent = __filter_div.textContent !== undefined;
25133
25134 // Update the filtering data for each row if needed (by invalidation or first run)
25135 function _fnFilterData ( settings )
25136 {
25137 var columns = settings.aoColumns;
25138 var column;
25139 var i, j, ien, jen, filterData, cellData, row;
25140 var fomatters = DataTable.ext.type.search;
25141 var wasInvalidated = false;
25142
25143 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
25144 row = settings.aoData[i];
25145
25146 if ( ! row._aFilterData ) {
25147 filterData = [];
25148
25149 for ( j=0, jen=columns.length ; j<jen ; j++ ) {
25150 column = columns[j];
25151
25152 if ( column.bSearchable ) {
25153 cellData = _fnGetCellData( settings, i, j, 'filter' );
25154
25155 if ( fomatters[ column.sType ] ) {
25156 cellData = fomatters[ column.sType ]( cellData );
25157 }
25158
25159 // Search in DataTables 1.10 is string based. In 1.11 this
25160 // should be altered to also allow strict type checking.
25161 if ( cellData === null ) {
25162 cellData = '';
25163 }
25164
25165 if ( typeof cellData !== 'string' && cellData.toString ) {
25166 cellData = cellData.toString();
25167 }
25168 }
25169 else {
25170 cellData = '';
25171 }
25172
25173 // If it looks like there is an HTML entity in the string,
25174 // attempt to decode it so sorting works as expected. Note that
25175 // we could use a single line of jQuery to do this, but the DOM
25176 // method used here is much faster http://jsperf.com/html-decode
25177 if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
25178 __filter_div.innerHTML = cellData;
25179 cellData = __filter_div_textContent ?
25180 __filter_div.textContent :
25181 __filter_div.innerText;
25182 }
25183
25184 if ( cellData.replace ) {
25185 cellData = cellData.replace(/[\r\n]/g, '');
25186 }
25187
25188 filterData.push( cellData );
25189 }
25190
25191 row._aFilterData = filterData;
25192 row._sFilterRow = filterData.join(' ');
25193 wasInvalidated = true;
25194 }
25195 }
25196
25197 return wasInvalidated;
25198 }
25199
25200
25201 /**
25202 * Convert from the internal Hungarian notation to camelCase for external
25203 * interaction
25204 * @param {object} obj Object to convert
25205 * @returns {object} Inverted object
25206 * @memberof DataTable#oApi
25207 */
25208 function _fnSearchToCamel ( obj )
25209 {
25210 return {
25211 search: obj.sSearch,
25212 smart: obj.bSmart,
25213 regex: obj.bRegex,
25214 caseInsensitive: obj.bCaseInsensitive
25215 };
25216 }
25217
25218
25219
25220 /**
25221 * Convert from camelCase notation to the internal Hungarian. We could use the
25222 * Hungarian convert function here, but this is cleaner
25223 * @param {object} obj Object to convert
25224 * @returns {object} Inverted object
25225 * @memberof DataTable#oApi
25226 */
25227 function _fnSearchToHung ( obj )
25228 {
25229 return {
25230 sSearch: obj.search,
25231 bSmart: obj.smart,
25232 bRegex: obj.regex,
25233 bCaseInsensitive: obj.caseInsensitive
25234 };
25235 }
25236
25237 /**
25238 * Generate the node required for the info display
25239 * @param {object} oSettings dataTables settings object
25240 * @returns {node} Information element
25241 * @memberof DataTable#oApi
25242 */
25243 function _fnFeatureHtmlInfo ( settings )
25244 {
25245 var
25246 tid = settings.sTableId,
25247 nodes = settings.aanFeatures.i,
25248 n = $('<div/>', {
25249 'class': settings.oClasses.sInfo,
25250 'id': ! nodes ? tid+'_info' : null
25251 } );
25252
25253 if ( ! nodes ) {
25254 // Update display on each draw
25255 settings.aoDrawCallback.push( {
25256 "fn": _fnUpdateInfo,
25257 "sName": "information"
25258 } );
25259
25260 n
25261 .attr( 'role', 'status' )
25262 .attr( 'aria-live', 'polite' );
25263
25264 // Table is described by our info div
25265 $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
25266 }
25267
25268 return n[0];
25269 }
25270
25271
25272 /**
25273 * Update the information elements in the display
25274 * @param {object} settings dataTables settings object
25275 * @memberof DataTable#oApi
25276 */
25277 function _fnUpdateInfo ( settings )
25278 {
25279 /* Show information about the table */
25280 var nodes = settings.aanFeatures.i;
25281 if ( nodes.length === 0 ) {
25282 return;
25283 }
25284
25285 var
25286 lang = settings.oLanguage,
25287 start = settings._iDisplayStart+1,
25288 end = settings.fnDisplayEnd(),
25289 max = settings.fnRecordsTotal(),
25290 total = settings.fnRecordsDisplay(),
25291 out = total ?
25292 lang.sInfo :
25293 lang.sInfoEmpty;
25294
25295 if ( total !== max ) {
25296 /* Record set after filtering */
25297 out += ' ' + lang.sInfoFiltered;
25298 }
25299
25300 // Convert the macros
25301 out += lang.sInfoPostFix;
25302 out = _fnInfoMacros( settings, out );
25303
25304 var callback = lang.fnInfoCallback;
25305 if ( callback !== null ) {
25306 out = callback.call( settings.oInstance,
25307 settings, start, end, max, total, out
25308 );
25309 }
25310
25311 $(nodes).html( out );
25312 }
25313
25314
25315 function _fnInfoMacros ( settings, str )
25316 {
25317 // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
25318 // internally
25319 var
25320 formatter = settings.fnFormatNumber,
25321 start = settings._iDisplayStart+1,
25322 len = settings._iDisplayLength,
25323 vis = settings.fnRecordsDisplay(),
25324 all = len === -1;
25325
25326 return str.
25327 replace(/_START_/g, formatter.call( settings, start ) ).
25328 replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
25329 replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
25330 replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
25331 replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
25332 replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
25333 }
25334
25335
25336
25337 /**
25338 * Draw the table for the first time, adding all required features
25339 * @param {object} settings dataTables settings object
25340 * @memberof DataTable#oApi
25341 */
25342 function _fnInitialise ( settings )
25343 {
25344 var i, iLen, iAjaxStart=settings.iInitDisplayStart;
25345 var columns = settings.aoColumns, column;
25346 var features = settings.oFeatures;
25347 var deferLoading = settings.bDeferLoading; // value modified by the draw
25348
25349 /* Ensure that the table data is fully initialised */
25350 if ( ! settings.bInitialised ) {
25351 setTimeout( function(){ _fnInitialise( settings ); }, 200 );
25352 return;
25353 }
25354
25355 /* Show the display HTML options */
25356 _fnAddOptionsHtml( settings );
25357
25358 /* Build and draw the header / footer for the table */
25359 _fnBuildHead( settings );
25360 _fnDrawHead( settings, settings.aoHeader );
25361 _fnDrawHead( settings, settings.aoFooter );
25362
25363 /* Okay to show that something is going on now */
25364 _fnProcessingDisplay( settings, true );
25365
25366 /* Calculate sizes for columns */
25367 if ( features.bAutoWidth ) {
25368 _fnCalculateColumnWidths( settings );
25369 }
25370
25371 for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
25372 column = columns[i];
25373
25374 if ( column.sWidth ) {
25375 column.nTh.style.width = _fnStringToCss( column.sWidth );
25376 }
25377 }
25378
25379 _fnCallbackFire( settings, null, 'preInit', [settings] );
25380
25381 // If there is default sorting required - let's do it. The sort function
25382 // will do the drawing for us. Otherwise we draw the table regardless of the
25383 // Ajax source - this allows the table to look initialised for Ajax sourcing
25384 // data (show 'loading' message possibly)
25385 _fnReDraw( settings );
25386
25387 // Server-side processing init complete is done by _fnAjaxUpdateDraw
25388 var dataSrc = _fnDataSource( settings );
25389 if ( dataSrc != 'ssp' || deferLoading ) {
25390 // if there is an ajax source load the data
25391 if ( dataSrc == 'ajax' ) {
25392 _fnBuildAjax( settings, [], function(json) {
25393 var aData = _fnAjaxDataSrc( settings, json );
25394
25395 // Got the data - add it to the table
25396 for ( i=0 ; i<aData.length ; i++ ) {
25397 _fnAddData( settings, aData[i] );
25398 }
25399
25400 // Reset the init display for cookie saving. We've already done
25401 // a filter, and therefore cleared it before. So we need to make
25402 // it appear 'fresh'
25403 settings.iInitDisplayStart = iAjaxStart;
25404
25405 _fnReDraw( settings );
25406
25407 _fnProcessingDisplay( settings, false );
25408 _fnInitComplete( settings, json );
25409 }, settings );
25410 }
25411 else {
25412 _fnProcessingDisplay( settings, false );
25413 _fnInitComplete( settings );
25414 }
25415 }
25416 }
25417
25418
25419 /**
25420 * Draw the table for the first time, adding all required features
25421 * @param {object} oSettings dataTables settings object
25422 * @param {object} [json] JSON from the server that completed the table, if using Ajax source
25423 * with client-side processing (optional)
25424 * @memberof DataTable#oApi
25425 */
25426 function _fnInitComplete ( settings, json )
25427 {
25428 settings._bInitComplete = true;
25429
25430 // When data was added after the initialisation (data or Ajax) we need to
25431 // calculate the column sizing
25432 if ( json || settings.oInit.aaData ) {
25433 _fnAdjustColumnSizing( settings );
25434 }
25435
25436 _fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
25437 _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
25438 }
25439
25440
25441 function _fnLengthChange ( settings, val )
25442 {
25443 var len = parseInt( val, 10 );
25444 settings._iDisplayLength = len;
25445
25446 _fnLengthOverflow( settings );
25447
25448 // Fire length change event
25449 _fnCallbackFire( settings, null, 'length', [settings, len] );
25450 }
25451
25452
25453 /**
25454 * Generate the node required for user display length changing
25455 * @param {object} settings dataTables settings object
25456 * @returns {node} Display length feature node
25457 * @memberof DataTable#oApi
25458 */
25459 function _fnFeatureHtmlLength ( settings )
25460 {
25461 var
25462 classes = settings.oClasses,
25463 tableId = settings.sTableId,
25464 menu = settings.aLengthMenu,
25465 d2 = $.isArray( menu[0] ),
25466 lengths = d2 ? menu[0] : menu,
25467 language = d2 ? menu[1] : menu;
25468
25469 var select = $('<select/>', {
25470 'name': tableId+'_length',
25471 'aria-controls': tableId,
25472 'class': classes.sLengthSelect
25473 } );
25474
25475 for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
25476 select[0][ i ] = new Option( language[i], lengths[i] );
25477 }
25478
25479 var div = $('<div><label/></div>').addClass( classes.sLength );
25480 if ( ! settings.aanFeatures.l ) {
25481 div[0].id = tableId+'_length';
25482 }
25483
25484 div.children().append(
25485 settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
25486 );
25487
25488 // Can't use `select` variable as user might provide their own and the
25489 // reference is broken by the use of outerHTML
25490 $('select', div)
25491 .val( settings._iDisplayLength )
25492 .bind( 'change.DT', function(e) {
25493 _fnLengthChange( settings, $(this).val() );
25494 _fnDraw( settings );
25495 } );
25496
25497 // Update node value whenever anything changes the table's length
25498 $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
25499 if ( settings === s ) {
25500 $('select', div).val( len );
25501 }
25502 } );
25503
25504 return div[0];
25505 }
25506
25507
25508
25509 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
25510 * Note that most of the paging logic is done in
25511 * DataTable.ext.pager
25512 */
25513
25514 /**
25515 * Generate the node required for default pagination
25516 * @param {object} oSettings dataTables settings object
25517 * @returns {node} Pagination feature node
25518 * @memberof DataTable#oApi
25519 */
25520 function _fnFeatureHtmlPaginate ( settings )
25521 {
25522 var
25523 type = settings.sPaginationType,
25524 plugin = DataTable.ext.pager[ type ],
25525 modern = typeof plugin === 'function',
25526 redraw = function( settings ) {
25527 _fnDraw( settings );
25528 },
25529 node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
25530 features = settings.aanFeatures;
25531
25532 if ( ! modern ) {
25533 plugin.fnInit( settings, node, redraw );
25534 }
25535
25536 /* Add a draw callback for the pagination on first instance, to update the paging display */
25537 if ( ! features.p )
25538 {
25539 node.id = settings.sTableId+'_paginate';
25540
25541 settings.aoDrawCallback.push( {
25542 "fn": function( settings ) {
25543 if ( modern ) {
25544 var
25545 start = settings._iDisplayStart,
25546 len = settings._iDisplayLength,
25547 visRecords = settings.fnRecordsDisplay(),
25548 all = len === -1,
25549 page = all ? 0 : Math.ceil( start / len ),
25550 pages = all ? 1 : Math.ceil( visRecords / len ),
25551 buttons = plugin(page, pages),
25552 i, ien;
25553
25554 for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
25555 _fnRenderer( settings, 'pageButton' )(
25556 settings, features.p[i], i, buttons, page, pages
25557 );
25558 }
25559 }
25560 else {
25561 plugin.fnUpdate( settings, redraw );
25562 }
25563 },
25564 "sName": "pagination"
25565 } );
25566 }
25567
25568 return node;
25569 }
25570
25571
25572 /**
25573 * Alter the display settings to change the page
25574 * @param {object} settings DataTables settings object
25575 * @param {string|int} action Paging action to take: "first", "previous",
25576 * "next" or "last" or page number to jump to (integer)
25577 * @param [bool] redraw Automatically draw the update or not
25578 * @returns {bool} true page has changed, false - no change
25579 * @memberof DataTable#oApi
25580 */
25581 function _fnPageChange ( settings, action, redraw )
25582 {
25583 var
25584 start = settings._iDisplayStart,
25585 len = settings._iDisplayLength,
25586 records = settings.fnRecordsDisplay();
25587
25588 if ( records === 0 || len === -1 )
25589 {
25590 start = 0;
25591 }
25592 else if ( typeof action === "number" )
25593 {
25594 start = action * len;
25595
25596 if ( start > records )
25597 {
25598 start = 0;
25599 }
25600 }
25601 else if ( action == "first" )
25602 {
25603 start = 0;
25604 }
25605 else if ( action == "previous" )
25606 {
25607 start = len >= 0 ?
25608 start - len :
25609 0;
25610
25611 if ( start < 0 )
25612 {
25613 start = 0;
25614 }
25615 }
25616 else if ( action == "next" )
25617 {
25618 if ( start + len < records )
25619 {
25620 start += len;
25621 }
25622 }
25623 else if ( action == "last" )
25624 {
25625 start = Math.floor( (records-1) / len) * len;
25626 }
25627 else
25628 {
25629 _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
25630 }
25631
25632 var changed = settings._iDisplayStart !== start;
25633 settings._iDisplayStart = start;
25634
25635 if ( changed ) {
25636 _fnCallbackFire( settings, null, 'page', [settings] );
25637
25638 if ( redraw ) {
25639 _fnDraw( settings );
25640 }
25641 }
25642
25643 return changed;
25644 }
25645
25646
25647
25648 /**
25649 * Generate the node required for the processing node
25650 * @param {object} settings dataTables settings object
25651 * @returns {node} Processing element
25652 * @memberof DataTable#oApi
25653 */
25654 function _fnFeatureHtmlProcessing ( settings )
25655 {
25656 return $('<div/>', {
25657 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
25658 'class': settings.oClasses.sProcessing
25659 } )
25660 .html( settings.oLanguage.sProcessing )
25661 .insertBefore( settings.nTable )[0];
25662 }
25663
25664
25665 /**
25666 * Display or hide the processing indicator
25667 * @param {object} settings dataTables settings object
25668 * @param {bool} show Show the processing indicator (true) or not (false)
25669 * @memberof DataTable#oApi
25670 */
25671 function _fnProcessingDisplay ( settings, show )
25672 {
25673 if ( settings.oFeatures.bProcessing ) {
25674 $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
25675 }
25676
25677 _fnCallbackFire( settings, null, 'processing', [settings, show] );
25678 }
25679
25680 /**
25681 * Add any control elements for the table - specifically scrolling
25682 * @param {object} settings dataTables settings object
25683 * @returns {node} Node to add to the DOM
25684 * @memberof DataTable#oApi
25685 */
25686 function _fnFeatureHtmlTable ( settings )
25687 {
25688 var table = $(settings.nTable);
25689
25690 // Add the ARIA grid role to the table
25691 table.attr( 'role', 'grid' );
25692
25693 // Scrolling from here on in
25694 var scroll = settings.oScroll;
25695
25696 if ( scroll.sX === '' && scroll.sY === '' ) {
25697 return settings.nTable;
25698 }
25699
25700 var scrollX = scroll.sX;
25701 var scrollY = scroll.sY;
25702 var classes = settings.oClasses;
25703 var caption = table.children('caption');
25704 var captionSide = caption.length ? caption[0]._captionSide : null;
25705 var headerClone = $( table[0].cloneNode(false) );
25706 var footerClone = $( table[0].cloneNode(false) );
25707 var footer = table.children('tfoot');
25708 var _div = '<div/>';
25709 var size = function ( s ) {
25710 return !s ? null : _fnStringToCss( s );
25711 };
25712
25713 if ( ! footer.length ) {
25714 footer = null;
25715 }
25716
25717 /*
25718 * The HTML structure that we want to generate in this function is:
25719 * div - scroller
25720 * div - scroll head
25721 * div - scroll head inner
25722 * table - scroll head table
25723 * thead - thead
25724 * div - scroll body
25725 * table - table (master table)
25726 * thead - thead clone for sizing
25727 * tbody - tbody
25728 * div - scroll foot
25729 * div - scroll foot inner
25730 * table - scroll foot table
25731 * tfoot - tfoot
25732 */
25733 var scroller = $( _div, { 'class': classes.sScrollWrapper } )
25734 .append(
25735 $(_div, { 'class': classes.sScrollHead } )
25736 .css( {
25737 overflow: 'hidden',
25738 position: 'relative',
25739 border: 0,
25740 width: scrollX ? size(scrollX) : '100%'
25741 } )
25742 .append(
25743 $(_div, { 'class': classes.sScrollHeadInner } )
25744 .css( {
25745 'box-sizing': 'content-box',
25746 width: scroll.sXInner || '100%'
25747 } )
25748 .append(
25749 headerClone
25750 .removeAttr('id')
25751 .css( 'margin-left', 0 )
25752 .append( captionSide === 'top' ? caption : null )
25753 .append(
25754 table.children('thead')
25755 )
25756 )
25757 )
25758 )
25759 .append(
25760 $(_div, { 'class': classes.sScrollBody } )
25761 .css( {
25762 position: 'relative',
25763 overflow: 'auto',
25764 width: size( scrollX )
25765 } )
25766 .append( table )
25767 );
25768
25769 if ( footer ) {
25770 scroller.append(
25771 $(_div, { 'class': classes.sScrollFoot } )
25772 .css( {
25773 overflow: 'hidden',
25774 border: 0,
25775 width: scrollX ? size(scrollX) : '100%'
25776 } )
25777 .append(
25778 $(_div, { 'class': classes.sScrollFootInner } )
25779 .append(
25780 footerClone
25781 .removeAttr('id')
25782 .css( 'margin-left', 0 )
25783 .append( captionSide === 'bottom' ? caption : null )
25784 .append(
25785 table.children('tfoot')
25786 )
25787 )
25788 )
25789 );
25790 }
25791
25792 var children = scroller.children();
25793 var scrollHead = children[0];
25794 var scrollBody = children[1];
25795 var scrollFoot = footer ? children[2] : null;
25796
25797 // When the body is scrolled, then we also want to scroll the headers
25798 if ( scrollX ) {
25799 $(scrollBody).on( 'scroll.DT', function (e) {
25800 var scrollLeft = this.scrollLeft;
25801
25802 scrollHead.scrollLeft = scrollLeft;
25803
25804 if ( footer ) {
25805 scrollFoot.scrollLeft = scrollLeft;
25806 }
25807 } );
25808 }
25809
25810 $(scrollBody).css(
25811 scrollY && scroll.bCollapse ? 'max-height' : 'height',
25812 scrollY
25813 );
25814
25815 settings.nScrollHead = scrollHead;
25816 settings.nScrollBody = scrollBody;
25817 settings.nScrollFoot = scrollFoot;
25818
25819 // On redraw - align columns
25820 settings.aoDrawCallback.push( {
25821 "fn": _fnScrollDraw,
25822 "sName": "scrolling"
25823 } );
25824
25825 return scroller[0];
25826 }
25827
25828
25829
25830 /**
25831 * Update the header, footer and body tables for resizing - i.e. column
25832 * alignment.
25833 *
25834 * Welcome to the most horrible function DataTables. The process that this
25835 * function follows is basically:
25836 * 1. Re-create the table inside the scrolling div
25837 * 2. Take live measurements from the DOM
25838 * 3. Apply the measurements to align the columns
25839 * 4. Clean up
25840 *
25841 * @param {object} settings dataTables settings object
25842 * @memberof DataTable#oApi
25843 */
25844 function _fnScrollDraw ( settings )
25845 {
25846 // Given that this is such a monster function, a lot of variables are use
25847 // to try and keep the minimised size as small as possible
25848 var
25849 scroll = settings.oScroll,
25850 scrollX = scroll.sX,
25851 scrollXInner = scroll.sXInner,
25852 scrollY = scroll.sY,
25853 barWidth = scroll.iBarWidth,
25854 divHeader = $(settings.nScrollHead),
25855 divHeaderStyle = divHeader[0].style,
25856 divHeaderInner = divHeader.children('div'),
25857 divHeaderInnerStyle = divHeaderInner[0].style,
25858 divHeaderTable = divHeaderInner.children('table'),
25859 divBodyEl = settings.nScrollBody,
25860 divBody = $(divBodyEl),
25861 divBodyStyle = divBodyEl.style,
25862 divFooter = $(settings.nScrollFoot),
25863 divFooterInner = divFooter.children('div'),
25864 divFooterTable = divFooterInner.children('table'),
25865 header = $(settings.nTHead),
25866 table = $(settings.nTable),
25867 tableEl = table[0],
25868 tableStyle = tableEl.style,
25869 footer = settings.nTFoot ? $(settings.nTFoot) : null,
25870 browser = settings.oBrowser,
25871 ie67 = browser.bScrollOversize,
25872 dtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),
25873 headerTrgEls, footerTrgEls,
25874 headerSrcEls, footerSrcEls,
25875 headerCopy, footerCopy,
25876 headerWidths=[], footerWidths=[],
25877 headerContent=[], footerContent=[],
25878 idx, correction, sanityWidth,
25879 zeroOut = function(nSizer) {
25880 var style = nSizer.style;
25881 style.paddingTop = "0";
25882 style.paddingBottom = "0";
25883 style.borderTopWidth = "0";
25884 style.borderBottomWidth = "0";
25885 style.height = 0;
25886 };
25887
25888 // If the scrollbar visibility has changed from the last draw, we need to
25889 // adjust the column sizes as the table width will have changed to account
25890 // for the scrollbar
25891 var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
25892
25893 if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
25894 settings.scrollBarVis = scrollBarVis;
25895 _fnAdjustColumnSizing( settings );
25896 return; // adjust column sizing will call this function again
25897 }
25898 else {
25899 settings.scrollBarVis = scrollBarVis;
25900 }
25901
25902 /*
25903 * 1. Re-create the table inside the scrolling div
25904 */
25905
25906 // Remove the old minimised thead and tfoot elements in the inner table
25907 table.children('thead, tfoot').remove();
25908
25909 if ( footer ) {
25910 footerCopy = footer.clone().prependTo( table );
25911 footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
25912 footerSrcEls = footerCopy.find('tr');
25913 }
25914
25915 // Clone the current header and footer elements and then place it into the inner table
25916 headerCopy = header.clone().prependTo( table );
25917 headerTrgEls = header.find('tr'); // original header is in its own table
25918 headerSrcEls = headerCopy.find('tr');
25919 headerCopy.find('th, td').removeAttr('tabindex');
25920
25921
25922 /*
25923 * 2. Take live measurements from the DOM - do not alter the DOM itself!
25924 */
25925
25926 // Remove old sizing and apply the calculated column widths
25927 // Get the unique column headers in the newly created (cloned) header. We want to apply the
25928 // calculated sizes to this header
25929 if ( ! scrollX )
25930 {
25931 divBodyStyle.width = '100%';
25932 divHeader[0].style.width = '100%';
25933 }
25934
25935 $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
25936 idx = _fnVisibleToColumnIndex( settings, i );
25937 el.style.width = settings.aoColumns[idx].sWidth;
25938 } );
25939
25940 if ( footer ) {
25941 _fnApplyToChildren( function(n) {
25942 n.style.width = "";
25943 }, footerSrcEls );
25944 }
25945
25946 // Size the table as a whole
25947 sanityWidth = table.outerWidth();
25948 if ( scrollX === "" ) {
25949 // No x scrolling
25950 tableStyle.width = "100%";
25951
25952 // IE7 will make the width of the table when 100% include the scrollbar
25953 // - which is shouldn't. When there is a scrollbar we need to take this
25954 // into account.
25955 if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
25956 divBody.css('overflow-y') == "scroll")
25957 ) {
25958 tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
25959 }
25960
25961 // Recalculate the sanity width
25962 sanityWidth = table.outerWidth();
25963 }
25964 else if ( scrollXInner !== "" ) {
25965 // legacy x scroll inner has been given - use it
25966 tableStyle.width = _fnStringToCss(scrollXInner);
25967
25968 // Recalculate the sanity width
25969 sanityWidth = table.outerWidth();
25970 }
25971
25972 // Hidden header should have zero height, so remove padding and borders. Then
25973 // set the width based on the real headers
25974
25975 // Apply all styles in one pass
25976 _fnApplyToChildren( zeroOut, headerSrcEls );
25977
25978 // Read all widths in next pass
25979 _fnApplyToChildren( function(nSizer) {
25980 headerContent.push( nSizer.innerHTML );
25981 headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
25982 }, headerSrcEls );
25983
25984 // Apply all widths in final pass
25985 _fnApplyToChildren( function(nToSize, i) {
25986 // Only apply widths to the DataTables detected header cells - this
25987 // prevents complex headers from having contradictory sizes applied
25988 if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
25989 nToSize.style.width = headerWidths[i];
25990 }
25991 }, headerTrgEls );
25992
25993 $(headerSrcEls).height(0);
25994
25995 /* Same again with the footer if we have one */
25996 if ( footer )
25997 {
25998 _fnApplyToChildren( zeroOut, footerSrcEls );
25999
26000 _fnApplyToChildren( function(nSizer) {
26001 footerContent.push( nSizer.innerHTML );
26002 footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
26003 }, footerSrcEls );
26004
26005 _fnApplyToChildren( function(nToSize, i) {
26006 nToSize.style.width = footerWidths[i];
26007 }, footerTrgEls );
26008
26009 $(footerSrcEls).height(0);
26010 }
26011
26012
26013 /*
26014 * 3. Apply the measurements
26015 */
26016
26017 // "Hide" the header and footer that we used for the sizing. We need to keep
26018 // the content of the cell so that the width applied to the header and body
26019 // both match, but we want to hide it completely. We want to also fix their
26020 // width to what they currently are
26021 _fnApplyToChildren( function(nSizer, i) {
26022 nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
26023 nSizer.style.width = headerWidths[i];
26024 }, headerSrcEls );
26025
26026 if ( footer )
26027 {
26028 _fnApplyToChildren( function(nSizer, i) {
26029 nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
26030 nSizer.style.width = footerWidths[i];
26031 }, footerSrcEls );
26032 }
26033
26034 // Sanity check that the table is of a sensible width. If not then we are going to get
26035 // misalignment - try to prevent this by not allowing the table to shrink below its min width
26036 if ( table.outerWidth() < sanityWidth )
26037 {
26038 // The min width depends upon if we have a vertical scrollbar visible or not */
26039 correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
26040 divBody.css('overflow-y') == "scroll")) ?
26041 sanityWidth+barWidth :
26042 sanityWidth;
26043
26044 // IE6/7 are a law unto themselves...
26045 if ( ie67 && (divBodyEl.scrollHeight >
26046 divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
26047 ) {
26048 tableStyle.width = _fnStringToCss( correction-barWidth );
26049 }
26050
26051 // And give the user a warning that we've stopped the table getting too small
26052 if ( scrollX === "" || scrollXInner !== "" ) {
26053 _fnLog( settings, 1, 'Possible column misalignment', 6 );
26054 }
26055 }
26056 else
26057 {
26058 correction = '100%';
26059 }
26060
26061 // Apply to the container elements
26062 divBodyStyle.width = _fnStringToCss( correction );
26063 divHeaderStyle.width = _fnStringToCss( correction );
26064
26065 if ( footer ) {
26066 settings.nScrollFoot.style.width = _fnStringToCss( correction );
26067 }
26068
26069
26070 /*
26071 * 4. Clean up
26072 */
26073 if ( ! scrollY ) {
26074 /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
26075 * the scrollbar height from the visible display, rather than adding it on. We need to
26076 * set the height in order to sort this. Don't want to do it in any other browsers.
26077 */
26078 if ( ie67 ) {
26079 divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
26080 }
26081 }
26082
26083 /* Finally set the width's of the header and footer tables */
26084 var iOuterWidth = table.outerWidth();
26085 divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
26086 divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
26087
26088 // Figure out if there are scrollbar present - if so then we need a the header and footer to
26089 // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
26090 var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
26091 var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
26092 divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
26093
26094 if ( footer ) {
26095 divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
26096 divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
26097 divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
26098 }
26099
26100 // Correct DOM ordering for colgroup - comes before the thead
26101 table.children('colgroup').insertBefore( table.children('thead') );
26102
26103 /* Adjust the position of the header in case we loose the y-scrollbar */
26104 divBody.scroll();
26105
26106 // If sorting or filtering has occurred, jump the scrolling back to the top
26107 // only if we aren't holding the position
26108 if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
26109 divBodyEl.scrollTop = 0;
26110 }
26111 }
26112
26113
26114
26115 /**
26116 * Apply a given function to the display child nodes of an element array (typically
26117 * TD children of TR rows
26118 * @param {function} fn Method to apply to the objects
26119 * @param array {nodes} an1 List of elements to look through for display children
26120 * @param array {nodes} an2 Another list (identical structure to the first) - optional
26121 * @memberof DataTable#oApi
26122 */
26123 function _fnApplyToChildren( fn, an1, an2 )
26124 {
26125 var index=0, i=0, iLen=an1.length;
26126 var nNode1, nNode2;
26127
26128 while ( i < iLen ) {
26129 nNode1 = an1[i].firstChild;
26130 nNode2 = an2 ? an2[i].firstChild : null;
26131
26132 while ( nNode1 ) {
26133 if ( nNode1.nodeType === 1 ) {
26134 if ( an2 ) {
26135 fn( nNode1, nNode2, index );
26136 }
26137 else {
26138 fn( nNode1, index );
26139 }
26140
26141 index++;
26142 }
26143
26144 nNode1 = nNode1.nextSibling;
26145 nNode2 = an2 ? nNode2.nextSibling : null;
26146 }
26147
26148 i++;
26149 }
26150 }
26151
26152
26153
26154 var __re_html_remove = /<.*?>/g;
26155
26156
26157 /**
26158 * Calculate the width of columns for the table
26159 * @param {object} oSettings dataTables settings object
26160 * @memberof DataTable#oApi
26161 */
26162 function _fnCalculateColumnWidths ( oSettings )
26163 {
26164 var
26165 table = oSettings.nTable,
26166 columns = oSettings.aoColumns,
26167 scroll = oSettings.oScroll,
26168 scrollY = scroll.sY,
26169 scrollX = scroll.sX,
26170 scrollXInner = scroll.sXInner,
26171 columnCount = columns.length,
26172 visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
26173 headerCells = $('th', oSettings.nTHead),
26174 tableWidthAttr = table.getAttribute('width'), // from DOM element
26175 tableContainer = table.parentNode,
26176 userInputs = false,
26177 i, column, columnIdx, width, outerWidth,
26178 browser = oSettings.oBrowser,
26179 ie67 = browser.bScrollOversize;
26180
26181 var styleWidth = table.style.width;
26182 if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
26183 tableWidthAttr = styleWidth;
26184 }
26185
26186 /* Convert any user input sizes into pixel sizes */
26187 for ( i=0 ; i<visibleColumns.length ; i++ ) {
26188 column = columns[ visibleColumns[i] ];
26189
26190 if ( column.sWidth !== null ) {
26191 column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
26192
26193 userInputs = true;
26194 }
26195 }
26196
26197 /* If the number of columns in the DOM equals the number that we have to
26198 * process in DataTables, then we can use the offsets that are created by
26199 * the web- browser. No custom sizes can be set in order for this to happen,
26200 * nor scrolling used
26201 */
26202 if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
26203 columnCount == _fnVisbleColumns( oSettings ) &&
26204 columnCount == headerCells.length
26205 ) {
26206 for ( i=0 ; i<columnCount ; i++ ) {
26207 var colIdx = _fnVisibleToColumnIndex( oSettings, i );
26208
26209 if ( colIdx !== null ) {
26210 columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
26211 }
26212 }
26213 }
26214 else
26215 {
26216 // Otherwise construct a single row, worst case, table with the widest
26217 // node in the data, assign any user defined widths, then insert it into
26218 // the DOM and allow the browser to do all the hard work of calculating
26219 // table widths
26220 var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
26221 .css( 'visibility', 'hidden' )
26222 .removeAttr( 'id' );
26223
26224 // Clean up the table body
26225 tmpTable.find('tbody tr').remove();
26226 var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
26227
26228 // Clone the table header and footer - we can't use the header / footer
26229 // from the cloned table, since if scrolling is active, the table's
26230 // real header and footer are contained in different table tags
26231 tmpTable.find('thead, tfoot').remove();
26232 tmpTable
26233 .append( $(oSettings.nTHead).clone() )
26234 .append( $(oSettings.nTFoot).clone() );
26235
26236 // Remove any assigned widths from the footer (from scrolling)
26237 tmpTable.find('tfoot th, tfoot td').css('width', '');
26238
26239 // Apply custom sizing to the cloned header
26240 headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
26241
26242 for ( i=0 ; i<visibleColumns.length ; i++ ) {
26243 column = columns[ visibleColumns[i] ];
26244
26245 headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
26246 _fnStringToCss( column.sWidthOrig ) :
26247 '';
26248
26249 // For scrollX we need to force the column width otherwise the
26250 // browser will collapse it. If this width is smaller than the
26251 // width the column requires, then it will have no effect
26252 if ( column.sWidthOrig && scrollX ) {
26253 $( headerCells[i] ).append( $('<div/>').css( {
26254 width: column.sWidthOrig,
26255 margin: 0,
26256 padding: 0,
26257 border: 0,
26258 height: 1
26259 } ) );
26260 }
26261 }
26262
26263 // Find the widest cell for each column and put it into the table
26264 if ( oSettings.aoData.length ) {
26265 for ( i=0 ; i<visibleColumns.length ; i++ ) {
26266 columnIdx = visibleColumns[i];
26267 column = columns[ columnIdx ];
26268
26269 $( _fnGetWidestNode( oSettings, columnIdx ) )
26270 .clone( false )
26271 .append( column.sContentPadding )
26272 .appendTo( tr );
26273 }
26274 }
26275
26276 // Tidy the temporary table - remove name attributes so there aren't
26277 // duplicated in the dom (radio elements for example)
26278 $('[name]', tmpTable).removeAttr('name');
26279
26280 // Table has been built, attach to the document so we can work with it.
26281 // A holding element is used, positioned at the top of the container
26282 // with minimal height, so it has no effect on if the container scrolls
26283 // or not. Otherwise it might trigger scrolling when it actually isn't
26284 // needed
26285 var holder = $('<div/>').css( scrollX || scrollY ?
26286 {
26287 position: 'absolute',
26288 top: 0,
26289 left: 0,
26290 height: 1,
26291 right: 0,
26292 overflow: 'hidden'
26293 } :
26294 {}
26295 )
26296 .append( tmpTable )
26297 .appendTo( tableContainer );
26298
26299 // When scrolling (X or Y) we want to set the width of the table as
26300 // appropriate. However, when not scrolling leave the table width as it
26301 // is. This results in slightly different, but I think correct behaviour
26302 if ( scrollX && scrollXInner ) {
26303 tmpTable.width( scrollXInner );
26304 }
26305 else if ( scrollX ) {
26306 tmpTable.css( 'width', 'auto' );
26307 tmpTable.removeAttr('width');
26308
26309 // If there is no width attribute or style, then allow the table to
26310 // collapse
26311 if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
26312 tmpTable.width( tableContainer.clientWidth );
26313 }
26314 }
26315 else if ( scrollY ) {
26316 tmpTable.width( tableContainer.clientWidth );
26317 }
26318 else if ( tableWidthAttr ) {
26319 tmpTable.width( tableWidthAttr );
26320 }
26321
26322 // Get the width of each column in the constructed table - we need to
26323 // know the inner width (so it can be assigned to the other table's
26324 // cells) and the outer width so we can calculate the full width of the
26325 // table. This is safe since DataTables requires a unique cell for each
26326 // column, but if ever a header can span multiple columns, this will
26327 // need to be modified.
26328 var total = 0;
26329 for ( i=0 ; i<visibleColumns.length ; i++ ) {
26330 var cell = $(headerCells[i]);
26331 var border = cell.outerWidth() - cell.width();
26332
26333 // Use getBounding... where possible (not IE8-) because it can give
26334 // sub-pixel accuracy, which we then want to round up!
26335 var bounding = browser.bBounding ?
26336 Math.ceil( headerCells[i].getBoundingClientRect().width ) :
26337 cell.outerWidth();
26338
26339 // Total is tracked to remove any sub-pixel errors as the outerWidth
26340 // of the table might not equal the total given here (IE!).
26341 total += bounding;
26342
26343 // Width for each column to use
26344 columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
26345 }
26346
26347 table.style.width = _fnStringToCss( total );
26348
26349 // Finished with the table - ditch it
26350 holder.remove();
26351 }
26352
26353 // If there is a width attr, we want to attach an event listener which
26354 // allows the table sizing to automatically adjust when the window is
26355 // resized. Use the width attr rather than CSS, since we can't know if the
26356 // CSS is a relative value or absolute - DOM read is always px.
26357 if ( tableWidthAttr ) {
26358 table.style.width = _fnStringToCss( tableWidthAttr );
26359 }
26360
26361 if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
26362 var bindResize = function () {
26363 $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
26364 _fnAdjustColumnSizing( oSettings );
26365 } ) );
26366 };
26367
26368 // IE6/7 will crash if we bind a resize event handler on page load.
26369 // To be removed in 1.11 which drops IE6/7 support
26370 if ( ie67 ) {
26371 setTimeout( bindResize, 1000 );
26372 }
26373 else {
26374 bindResize();
26375 }
26376
26377 oSettings._reszEvt = true;
26378 }
26379 }
26380
26381
26382 /**
26383 * Throttle the calls to a function. Arguments and context are maintained for
26384 * the throttled function
26385 * @param {function} fn Function to be called
26386 * @param {int} [freq=200] call frequency in mS
26387 * @returns {function} wrapped function
26388 * @memberof DataTable#oApi
26389 */
26390 var _fnThrottle = DataTable.util.throttle;
26391
26392
26393 /**
26394 * Convert a CSS unit width to pixels (e.g. 2em)
26395 * @param {string} width width to be converted
26396 * @param {node} parent parent to get the with for (required for relative widths) - optional
26397 * @returns {int} width in pixels
26398 * @memberof DataTable#oApi
26399 */
26400 function _fnConvertToWidth ( width, parent )
26401 {
26402 if ( ! width ) {
26403 return 0;
26404 }
26405
26406 var n = $('<div/>')
26407 .css( 'width', _fnStringToCss( width ) )
26408 .appendTo( parent || document.body );
26409
26410 var val = n[0].offsetWidth;
26411 n.remove();
26412
26413 return val;
26414 }
26415
26416
26417 /**
26418 * Get the widest node
26419 * @param {object} settings dataTables settings object
26420 * @param {int} colIdx column of interest
26421 * @returns {node} widest table node
26422 * @memberof DataTable#oApi
26423 */
26424 function _fnGetWidestNode( settings, colIdx )
26425 {
26426 var idx = _fnGetMaxLenString( settings, colIdx );
26427 if ( idx < 0 ) {
26428 return null;
26429 }
26430
26431 var data = settings.aoData[ idx ];
26432 return ! data.nTr ? // Might not have been created when deferred rendering
26433 $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
26434 data.anCells[ colIdx ];
26435 }
26436
26437
26438 /**
26439 * Get the maximum strlen for each data column
26440 * @param {object} settings dataTables settings object
26441 * @param {int} colIdx column of interest
26442 * @returns {string} max string length for each column
26443 * @memberof DataTable#oApi
26444 */
26445 function _fnGetMaxLenString( settings, colIdx )
26446 {
26447 var s, max=-1, maxIdx = -1;
26448
26449 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
26450 s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
26451 s = s.replace( __re_html_remove, '' );
26452 s = s.replace( / /g, ' ' );
26453
26454 if ( s.length > max ) {
26455 max = s.length;
26456 maxIdx = i;
26457 }
26458 }
26459
26460 return maxIdx;
26461 }
26462
26463
26464 /**
26465 * Append a CSS unit (only if required) to a string
26466 * @param {string} value to css-ify
26467 * @returns {string} value with css unit
26468 * @memberof DataTable#oApi
26469 */
26470 function _fnStringToCss( s )
26471 {
26472 if ( s === null ) {
26473 return '0px';
26474 }
26475
26476 if ( typeof s == 'number' ) {
26477 return s < 0 ?
26478 '0px' :
26479 s+'px';
26480 }
26481
26482 // Check it has a unit character already
26483 return s.match(/\d$/) ?
26484 s+'px' :
26485 s;
26486 }
26487
26488
26489
26490 function _fnSortFlatten ( settings )
26491 {
26492 var
26493 i, iLen, k, kLen,
26494 aSort = [],
26495 aiOrig = [],
26496 aoColumns = settings.aoColumns,
26497 aDataSort, iCol, sType, srcCol,
26498 fixed = settings.aaSortingFixed,
26499 fixedObj = $.isPlainObject( fixed ),
26500 nestedSort = [],
26501 add = function ( a ) {
26502 if ( a.length && ! $.isArray( a[0] ) ) {
26503 // 1D array
26504 nestedSort.push( a );
26505 }
26506 else {
26507 // 2D array
26508 $.merge( nestedSort, a );
26509 }
26510 };
26511
26512 // Build the sort array, with pre-fix and post-fix options if they have been
26513 // specified
26514 if ( $.isArray( fixed ) ) {
26515 add( fixed );
26516 }
26517
26518 if ( fixedObj && fixed.pre ) {
26519 add( fixed.pre );
26520 }
26521
26522 add( settings.aaSorting );
26523
26524 if (fixedObj && fixed.post ) {
26525 add( fixed.post );
26526 }
26527
26528 for ( i=0 ; i<nestedSort.length ; i++ )
26529 {
26530 srcCol = nestedSort[i][0];
26531 aDataSort = aoColumns[ srcCol ].aDataSort;
26532
26533 for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
26534 {
26535 iCol = aDataSort[k];
26536 sType = aoColumns[ iCol ].sType || 'string';
26537
26538 if ( nestedSort[i]._idx === undefined ) {
26539 nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
26540 }
26541
26542 aSort.push( {
26543 src: srcCol,
26544 col: iCol,
26545 dir: nestedSort[i][1],
26546 index: nestedSort[i]._idx,
26547 type: sType,
26548 formatter: DataTable.ext.type.order[ sType+"-pre" ]
26549 } );
26550 }
26551 }
26552
26553 return aSort;
26554 }
26555
26556 /**
26557 * Change the order of the table
26558 * @param {object} oSettings dataTables settings object
26559 * @memberof DataTable#oApi
26560 * @todo This really needs split up!
26561 */
26562 function _fnSort ( oSettings )
26563 {
26564 var
26565 i, ien, iLen, j, jLen, k, kLen,
26566 sDataType, nTh,
26567 aiOrig = [],
26568 oExtSort = DataTable.ext.type.order,
26569 aoData = oSettings.aoData,
26570 aoColumns = oSettings.aoColumns,
26571 aDataSort, data, iCol, sType, oSort,
26572 formatters = 0,
26573 sortCol,
26574 displayMaster = oSettings.aiDisplayMaster,
26575 aSort;
26576
26577 // Resolve any column types that are unknown due to addition or invalidation
26578 // @todo Can this be moved into a 'data-ready' handler which is called when
26579 // data is going to be used in the table?
26580 _fnColumnTypes( oSettings );
26581
26582 aSort = _fnSortFlatten( oSettings );
26583
26584 for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
26585 sortCol = aSort[i];
26586
26587 // Track if we can use the fast sort algorithm
26588 if ( sortCol.formatter ) {
26589 formatters++;
26590 }
26591
26592 // Load the data needed for the sort, for each cell
26593 _fnSortData( oSettings, sortCol.col );
26594 }
26595
26596 /* No sorting required if server-side or no sorting array */
26597 if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
26598 {
26599 // Create a value - key array of the current row positions such that we can use their
26600 // current position during the sort, if values match, in order to perform stable sorting
26601 for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
26602 aiOrig[ displayMaster[i] ] = i;
26603 }
26604
26605 /* Do the sort - here we want multi-column sorting based on a given data source (column)
26606 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
26607 * follow on it's own, but this is what we want (example two column sorting):
26608 * fnLocalSorting = function(a,b){
26609 * var iTest;
26610 * iTest = oSort['string-asc']('data11', 'data12');
26611 * if (iTest !== 0)
26612 * return iTest;
26613 * iTest = oSort['numeric-desc']('data21', 'data22');
26614 * if (iTest !== 0)
26615 * return iTest;
26616 * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
26617 * }
26618 * Basically we have a test for each sorting column, if the data in that column is equal,
26619 * test the next column. If all columns match, then we use a numeric sort on the row
26620 * positions in the original data array to provide a stable sort.
26621 *
26622 * Note - I know it seems excessive to have two sorting methods, but the first is around
26623 * 15% faster, so the second is only maintained for backwards compatibility with sorting
26624 * methods which do not have a pre-sort formatting function.
26625 */
26626 if ( formatters === aSort.length ) {
26627 // All sort types have formatting functions
26628 displayMaster.sort( function ( a, b ) {
26629 var
26630 x, y, k, test, sort,
26631 len=aSort.length,
26632 dataA = aoData[a]._aSortData,
26633 dataB = aoData[b]._aSortData;
26634
26635 for ( k=0 ; k<len ; k++ ) {
26636 sort = aSort[k];
26637
26638 x = dataA[ sort.col ];
26639 y = dataB[ sort.col ];
26640
26641 test = x<y ? -1 : x>y ? 1 : 0;
26642 if ( test !== 0 ) {
26643 return sort.dir === 'asc' ? test : -test;
26644 }
26645 }
26646
26647 x = aiOrig[a];
26648 y = aiOrig[b];
26649 return x<y ? -1 : x>y ? 1 : 0;
26650 } );
26651 }
26652 else {
26653 // Depreciated - remove in 1.11 (providing a plug-in option)
26654 // Not all sort types have formatting methods, so we have to call their sorting
26655 // methods.
26656 displayMaster.sort( function ( a, b ) {
26657 var
26658 x, y, k, l, test, sort, fn,
26659 len=aSort.length,
26660 dataA = aoData[a]._aSortData,
26661 dataB = aoData[b]._aSortData;
26662
26663 for ( k=0 ; k<len ; k++ ) {
26664 sort = aSort[k];
26665
26666 x = dataA[ sort.col ];
26667 y = dataB[ sort.col ];
26668
26669 fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
26670 test = fn( x, y );
26671 if ( test !== 0 ) {
26672 return test;
26673 }
26674 }
26675
26676 x = aiOrig[a];
26677 y = aiOrig[b];
26678 return x<y ? -1 : x>y ? 1 : 0;
26679 } );
26680 }
26681 }
26682
26683 /* Tell the draw function that we have sorted the data */
26684 oSettings.bSorted = true;
26685 }
26686
26687
26688 function _fnSortAria ( settings )
26689 {
26690 var label;
26691 var nextSort;
26692 var columns = settings.aoColumns;
26693 var aSort = _fnSortFlatten( settings );
26694 var oAria = settings.oLanguage.oAria;
26695
26696 // ARIA attributes - need to loop all columns, to update all (removing old
26697 // attributes as needed)
26698 for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
26699 {
26700 var col = columns[i];
26701 var asSorting = col.asSorting;
26702 var sTitle = col.sTitle.replace( /<.*?>/g, "" );
26703 var th = col.nTh;
26704
26705 // IE7 is throwing an error when setting these properties with jQuery's
26706 // attr() and removeAttr() methods...
26707 th.removeAttribute('aria-sort');
26708
26709 /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
26710 if ( col.bSortable ) {
26711 if ( aSort.length > 0 && aSort[0].col == i ) {
26712 th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
26713 nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
26714 }
26715 else {
26716 nextSort = asSorting[0];
26717 }
26718
26719 label = sTitle + ( nextSort === "asc" ?
26720 oAria.sSortAscending :
26721 oAria.sSortDescending
26722 );
26723 }
26724 else {
26725 label = sTitle;
26726 }
26727
26728 th.setAttribute('aria-label', label);
26729 }
26730 }
26731
26732
26733 /**
26734 * Function to run on user sort request
26735 * @param {object} settings dataTables settings object
26736 * @param {node} attachTo node to attach the handler to
26737 * @param {int} colIdx column sorting index
26738 * @param {boolean} [append=false] Append the requested sort to the existing
26739 * sort if true (i.e. multi-column sort)
26740 * @param {function} [callback] callback function
26741 * @memberof DataTable#oApi
26742 */
26743 function _fnSortListener ( settings, colIdx, append, callback )
26744 {
26745 var col = settings.aoColumns[ colIdx ];
26746 var sorting = settings.aaSorting;
26747 var asSorting = col.asSorting;
26748 var nextSortIdx;
26749 var next = function ( a, overflow ) {
26750 var idx = a._idx;
26751 if ( idx === undefined ) {
26752 idx = $.inArray( a[1], asSorting );
26753 }
26754
26755 return idx+1 < asSorting.length ?
26756 idx+1 :
26757 overflow ?
26758 null :
26759 0;
26760 };
26761
26762 // Convert to 2D array if needed
26763 if ( typeof sorting[0] === 'number' ) {
26764 sorting = settings.aaSorting = [ sorting ];
26765 }
26766
26767 // If appending the sort then we are multi-column sorting
26768 if ( append && settings.oFeatures.bSortMulti ) {
26769 // Are we already doing some kind of sort on this column?
26770 var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
26771
26772 if ( sortIdx !== -1 ) {
26773 // Yes, modify the sort
26774 nextSortIdx = next( sorting[sortIdx], true );
26775
26776 if ( nextSortIdx === null && sorting.length === 1 ) {
26777 nextSortIdx = 0; // can't remove sorting completely
26778 }
26779
26780 if ( nextSortIdx === null ) {
26781 sorting.splice( sortIdx, 1 );
26782 }
26783 else {
26784 sorting[sortIdx][1] = asSorting[ nextSortIdx ];
26785 sorting[sortIdx]._idx = nextSortIdx;
26786 }
26787 }
26788 else {
26789 // No sort on this column yet
26790 sorting.push( [ colIdx, asSorting[0], 0 ] );
26791 sorting[sorting.length-1]._idx = 0;
26792 }
26793 }
26794 else if ( sorting.length && sorting[0][0] == colIdx ) {
26795 // Single column - already sorting on this column, modify the sort
26796 nextSortIdx = next( sorting[0] );
26797
26798 sorting.length = 1;
26799 sorting[0][1] = asSorting[ nextSortIdx ];
26800 sorting[0]._idx = nextSortIdx;
26801 }
26802 else {
26803 // Single column - sort only on this column
26804 sorting.length = 0;
26805 sorting.push( [ colIdx, asSorting[0] ] );
26806 sorting[0]._idx = 0;
26807 }
26808
26809 // Run the sort by calling a full redraw
26810 _fnReDraw( settings );
26811
26812 // callback used for async user interaction
26813 if ( typeof callback == 'function' ) {
26814 callback( settings );
26815 }
26816 }
26817
26818
26819 /**
26820 * Attach a sort handler (click) to a node
26821 * @param {object} settings dataTables settings object
26822 * @param {node} attachTo node to attach the handler to
26823 * @param {int} colIdx column sorting index
26824 * @param {function} [callback] callback function
26825 * @memberof DataTable#oApi
26826 */
26827 function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
26828 {
26829 var col = settings.aoColumns[ colIdx ];
26830
26831 _fnBindAction( attachTo, {}, function (e) {
26832 /* If the column is not sortable - don't to anything */
26833 if ( col.bSortable === false ) {
26834 return;
26835 }
26836
26837 // If processing is enabled use a timeout to allow the processing
26838 // display to be shown - otherwise to it synchronously
26839 if ( settings.oFeatures.bProcessing ) {
26840 _fnProcessingDisplay( settings, true );
26841
26842 setTimeout( function() {
26843 _fnSortListener( settings, colIdx, e.shiftKey, callback );
26844
26845 // In server-side processing, the draw callback will remove the
26846 // processing display
26847 if ( _fnDataSource( settings ) !== 'ssp' ) {
26848 _fnProcessingDisplay( settings, false );
26849 }
26850 }, 0 );
26851 }
26852 else {
26853 _fnSortListener( settings, colIdx, e.shiftKey, callback );
26854 }
26855 } );
26856 }
26857
26858
26859 /**
26860 * Set the sorting classes on table's body, Note: it is safe to call this function
26861 * when bSort and bSortClasses are false
26862 * @param {object} oSettings dataTables settings object
26863 * @memberof DataTable#oApi
26864 */
26865 function _fnSortingClasses( settings )
26866 {
26867 var oldSort = settings.aLastSort;
26868 var sortClass = settings.oClasses.sSortColumn;
26869 var sort = _fnSortFlatten( settings );
26870 var features = settings.oFeatures;
26871 var i, ien, colIdx;
26872
26873 if ( features.bSort && features.bSortClasses ) {
26874 // Remove old sorting classes
26875 for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
26876 colIdx = oldSort[i].src;
26877
26878 // Remove column sorting
26879 $( _pluck( settings.aoData, 'anCells', colIdx ) )
26880 .removeClass( sortClass + (i<2 ? i+1 : 3) );
26881 }
26882
26883 // Add new column sorting
26884 for ( i=0, ien=sort.length ; i<ien ; i++ ) {
26885 colIdx = sort[i].src;
26886
26887 $( _pluck( settings.aoData, 'anCells', colIdx ) )
26888 .addClass( sortClass + (i<2 ? i+1 : 3) );
26889 }
26890 }
26891
26892 settings.aLastSort = sort;
26893 }
26894
26895
26896 // Get the data to sort a column, be it from cache, fresh (populating the
26897 // cache), or from a sort formatter
26898 function _fnSortData( settings, idx )
26899 {
26900 // Custom sorting function - provided by the sort data type
26901 var column = settings.aoColumns[ idx ];
26902 var customSort = DataTable.ext.order[ column.sSortDataType ];
26903 var customData;
26904
26905 if ( customSort ) {
26906 customData = customSort.call( settings.oInstance, settings, idx,
26907 _fnColumnIndexToVisible( settings, idx )
26908 );
26909 }
26910
26911 // Use / populate cache
26912 var row, cellData;
26913 var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
26914
26915 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
26916 row = settings.aoData[i];
26917
26918 if ( ! row._aSortData ) {
26919 row._aSortData = [];
26920 }
26921
26922 if ( ! row._aSortData[idx] || customSort ) {
26923 cellData = customSort ?
26924 customData[i] : // If there was a custom sort function, use data from there
26925 _fnGetCellData( settings, i, idx, 'sort' );
26926
26927 row._aSortData[ idx ] = formatter ?
26928 formatter( cellData ) :
26929 cellData;
26930 }
26931 }
26932 }
26933
26934
26935
26936 /**
26937 * Save the state of a table
26938 * @param {object} oSettings dataTables settings object
26939 * @memberof DataTable#oApi
26940 */
26941 function _fnSaveState ( settings )
26942 {
26943 if ( !settings.oFeatures.bStateSave || settings.bDestroying )
26944 {
26945 return;
26946 }
26947
26948 /* Store the interesting variables */
26949 var state = {
26950 time: +new Date(),
26951 start: settings._iDisplayStart,
26952 length: settings._iDisplayLength,
26953 order: $.extend( true, [], settings.aaSorting ),
26954 search: _fnSearchToCamel( settings.oPreviousSearch ),
26955 columns: $.map( settings.aoColumns, function ( col, i ) {
26956 return {
26957 visible: col.bVisible,
26958 search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
26959 };
26960 } )
26961 };
26962
26963 _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
26964
26965 settings.oSavedState = state;
26966 settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
26967 }
26968
26969
26970 /**
26971 * Attempt to load a saved table state
26972 * @param {object} oSettings dataTables settings object
26973 * @param {object} oInit DataTables init object so we can override settings
26974 * @memberof DataTable#oApi
26975 */
26976 function _fnLoadState ( settings, oInit )
26977 {
26978 var i, ien;
26979 var columns = settings.aoColumns;
26980
26981 if ( ! settings.oFeatures.bStateSave ) {
26982 return;
26983 }
26984
26985 var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
26986 if ( ! state || ! state.time ) {
26987 return;
26988 }
26989
26990 /* Allow custom and plug-in manipulation functions to alter the saved data set and
26991 * cancelling of loading by returning false
26992 */
26993 var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
26994 if ( $.inArray( false, abStateLoad ) !== -1 ) {
26995 return;
26996 }
26997
26998 /* Reject old data */
26999 var duration = settings.iStateDuration;
27000 if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
27001 return;
27002 }
27003
27004 // Number of columns have changed - all bets are off, no restore of settings
27005 if ( columns.length !== state.columns.length ) {
27006 return;
27007 }
27008
27009 // Store the saved state so it might be accessed at any time
27010 settings.oLoadedState = $.extend( true, {}, state );
27011
27012 // Restore key features - todo - for 1.11 this needs to be done by
27013 // subscribed events
27014 if ( state.start !== undefined ) {
27015 settings._iDisplayStart = state.start;
27016 settings.iInitDisplayStart = state.start;
27017 }
27018 if ( state.length !== undefined ) {
27019 settings._iDisplayLength = state.length;
27020 }
27021
27022 // Order
27023 if ( state.order !== undefined ) {
27024 settings.aaSorting = [];
27025 $.each( state.order, function ( i, col ) {
27026 settings.aaSorting.push( col[0] >= columns.length ?
27027 [ 0, col[1] ] :
27028 col
27029 );
27030 } );
27031 }
27032
27033 // Search
27034 if ( state.search !== undefined ) {
27035 $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
27036 }
27037
27038 // Columns
27039 for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
27040 var col = state.columns[i];
27041
27042 // Visibility
27043 if ( col.visible !== undefined ) {
27044 columns[i].bVisible = col.visible;
27045 }
27046
27047 // Search
27048 if ( col.search !== undefined ) {
27049 $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
27050 }
27051 }
27052
27053 _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
27054 }
27055
27056
27057 /**
27058 * Return the settings object for a particular table
27059 * @param {node} table table we are using as a dataTable
27060 * @returns {object} Settings object - or null if not found
27061 * @memberof DataTable#oApi
27062 */
27063 function _fnSettingsFromNode ( table )
27064 {
27065 var settings = DataTable.settings;
27066 var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
27067
27068 return idx !== -1 ?
27069 settings[ idx ] :
27070 null;
27071 }
27072
27073
27074 /**
27075 * Log an error message
27076 * @param {object} settings dataTables settings object
27077 * @param {int} level log error messages, or display them to the user
27078 * @param {string} msg error message
27079 * @param {int} tn Technical note id to get more information about the error.
27080 * @memberof DataTable#oApi
27081 */
27082 function _fnLog( settings, level, msg, tn )
27083 {
27084 msg = 'DataTables warning: '+
27085 (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
27086
27087 if ( tn ) {
27088 msg += '. For more information about this error, please see '+
27089 'http://datatables.net/tn/'+tn;
27090 }
27091
27092 if ( ! level ) {
27093 // Backwards compatibility pre 1.10
27094 var ext = DataTable.ext;
27095 var type = ext.sErrMode || ext.errMode;
27096
27097 if ( settings ) {
27098 _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
27099 }
27100
27101 if ( type == 'alert' ) {
27102 alert( msg );
27103 }
27104 else if ( type == 'throw' ) {
27105 throw new Error(msg);
27106 }
27107 else if ( typeof type == 'function' ) {
27108 type( settings, tn, msg );
27109 }
27110 }
27111 else if ( window.console && console.log ) {
27112 console.log( msg );
27113 }
27114 }
27115
27116
27117 /**
27118 * See if a property is defined on one object, if so assign it to the other object
27119 * @param {object} ret target object
27120 * @param {object} src source object
27121 * @param {string} name property
27122 * @param {string} [mappedName] name to map too - optional, name used if not given
27123 * @memberof DataTable#oApi
27124 */
27125 function _fnMap( ret, src, name, mappedName )
27126 {
27127 if ( $.isArray( name ) ) {
27128 $.each( name, function (i, val) {
27129 if ( $.isArray( val ) ) {
27130 _fnMap( ret, src, val[0], val[1] );
27131 }
27132 else {
27133 _fnMap( ret, src, val );
27134 }
27135 } );
27136
27137 return;
27138 }
27139
27140 if ( mappedName === undefined ) {
27141 mappedName = name;
27142 }
27143
27144 if ( src[name] !== undefined ) {
27145 ret[mappedName] = src[name];
27146 }
27147 }
27148
27149
27150 /**
27151 * Extend objects - very similar to jQuery.extend, but deep copy objects, and
27152 * shallow copy arrays. The reason we need to do this, is that we don't want to
27153 * deep copy array init values (such as aaSorting) since the dev wouldn't be
27154 * able to override them, but we do want to deep copy arrays.
27155 * @param {object} out Object to extend
27156 * @param {object} extender Object from which the properties will be applied to
27157 * out
27158 * @param {boolean} breakRefs If true, then arrays will be sliced to take an
27159 * independent copy with the exception of the `data` or `aaData` parameters
27160 * if they are present. This is so you can pass in a collection to
27161 * DataTables and have that used as your data source without breaking the
27162 * references
27163 * @returns {object} out Reference, just for convenience - out === the return.
27164 * @memberof DataTable#oApi
27165 * @todo This doesn't take account of arrays inside the deep copied objects.
27166 */
27167 function _fnExtend( out, extender, breakRefs )
27168 {
27169 var val;
27170
27171 for ( var prop in extender ) {
27172 if ( extender.hasOwnProperty(prop) ) {
27173 val = extender[prop];
27174
27175 if ( $.isPlainObject( val ) ) {
27176 if ( ! $.isPlainObject( out[prop] ) ) {
27177 out[prop] = {};
27178 }
27179 $.extend( true, out[prop], val );
27180 }
27181 else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
27182 out[prop] = val.slice();
27183 }
27184 else {
27185 out[prop] = val;
27186 }
27187 }
27188 }
27189
27190 return out;
27191 }
27192
27193
27194 /**
27195 * Bind an event handers to allow a click or return key to activate the callback.
27196 * This is good for accessibility since a return on the keyboard will have the
27197 * same effect as a click, if the element has focus.
27198 * @param {element} n Element to bind the action to
27199 * @param {object} oData Data object to pass to the triggered function
27200 * @param {function} fn Callback function for when the event is triggered
27201 * @memberof DataTable#oApi
27202 */
27203 function _fnBindAction( n, oData, fn )
27204 {
27205 $(n)
27206 .bind( 'click.DT', oData, function (e) {
27207 n.blur(); // Remove focus outline for mouse users
27208 fn(e);
27209 } )
27210 .bind( 'keypress.DT', oData, function (e){
27211 if ( e.which === 13 ) {
27212 e.preventDefault();
27213 fn(e);
27214 }
27215 } )
27216 .bind( 'selectstart.DT', function () {
27217 /* Take the brutal approach to cancelling text selection */
27218 return false;
27219 } );
27220 }
27221
27222
27223 /**
27224 * Register a callback function. Easily allows a callback function to be added to
27225 * an array store of callback functions that can then all be called together.
27226 * @param {object} oSettings dataTables settings object
27227 * @param {string} sStore Name of the array storage for the callbacks in oSettings
27228 * @param {function} fn Function to be called back
27229 * @param {string} sName Identifying name for the callback (i.e. a label)
27230 * @memberof DataTable#oApi
27231 */
27232 function _fnCallbackReg( oSettings, sStore, fn, sName )
27233 {
27234 if ( fn )
27235 {
27236 oSettings[sStore].push( {
27237 "fn": fn,
27238 "sName": sName
27239 } );
27240 }
27241 }
27242
27243
27244 /**
27245 * Fire callback functions and trigger events. Note that the loop over the
27246 * callback array store is done backwards! Further note that you do not want to
27247 * fire off triggers in time sensitive applications (for example cell creation)
27248 * as its slow.
27249 * @param {object} settings dataTables settings object
27250 * @param {string} callbackArr Name of the array storage for the callbacks in
27251 * oSettings
27252 * @param {string} eventName Name of the jQuery custom event to trigger. If
27253 * null no trigger is fired
27254 * @param {array} args Array of arguments to pass to the callback function /
27255 * trigger
27256 * @memberof DataTable#oApi
27257 */
27258 function _fnCallbackFire( settings, callbackArr, eventName, args )
27259 {
27260 var ret = [];
27261
27262 if ( callbackArr ) {
27263 ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
27264 return val.fn.apply( settings.oInstance, args );
27265 } );
27266 }
27267
27268 if ( eventName !== null ) {
27269 var e = $.Event( eventName+'.dt' );
27270
27271 $(settings.nTable).trigger( e, args );
27272
27273 ret.push( e.result );
27274 }
27275
27276 return ret;
27277 }
27278
27279
27280 function _fnLengthOverflow ( settings )
27281 {
27282 var
27283 start = settings._iDisplayStart,
27284 end = settings.fnDisplayEnd(),
27285 len = settings._iDisplayLength;
27286
27287 /* If we have space to show extra rows (backing up from the end point - then do so */
27288 if ( start >= end )
27289 {
27290 start = end - len;
27291 }
27292
27293 // Keep the start record on the current page
27294 start -= (start % len);
27295
27296 if ( len === -1 || start < 0 )
27297 {
27298 start = 0;
27299 }
27300
27301 settings._iDisplayStart = start;
27302 }
27303
27304
27305 function _fnRenderer( settings, type )
27306 {
27307 var renderer = settings.renderer;
27308 var host = DataTable.ext.renderer[type];
27309
27310 if ( $.isPlainObject( renderer ) && renderer[type] ) {
27311 // Specific renderer for this type. If available use it, otherwise use
27312 // the default.
27313 return host[renderer[type]] || host._;
27314 }
27315 else if ( typeof renderer === 'string' ) {
27316 // Common renderer - if there is one available for this type use it,
27317 // otherwise use the default
27318 return host[renderer] || host._;
27319 }
27320
27321 // Use the default
27322 return host._;
27323 }
27324
27325
27326 /**
27327 * Detect the data source being used for the table. Used to simplify the code
27328 * a little (ajax) and to make it compress a little smaller.
27329 *
27330 * @param {object} settings dataTables settings object
27331 * @returns {string} Data source
27332 * @memberof DataTable#oApi
27333 */
27334 function _fnDataSource ( settings )
27335 {
27336 if ( settings.oFeatures.bServerSide ) {
27337 return 'ssp';
27338 }
27339 else if ( settings.ajax || settings.sAjaxSource ) {
27340 return 'ajax';
27341 }
27342 return 'dom';
27343 }
27344
27345
27346
27347
27348 /**
27349 * Computed structure of the DataTables API, defined by the options passed to
27350 * `DataTable.Api.register()` when building the API.
27351 *
27352 * The structure is built in order to speed creation and extension of the Api
27353 * objects since the extensions are effectively pre-parsed.
27354 *
27355 * The array is an array of objects with the following structure, where this
27356 * base array represents the Api prototype base:
27357 *
27358 * [
27359 * {
27360 * name: 'data' -- string - Property name
27361 * val: function () {}, -- function - Api method (or undefined if just an object
27362 * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
27363 * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
27364 * },
27365 * {
27366 * name: 'row'
27367 * val: {},
27368 * methodExt: [ ... ],
27369 * propExt: [
27370 * {
27371 * name: 'data'
27372 * val: function () {},
27373 * methodExt: [ ... ],
27374 * propExt: [ ... ]
27375 * },
27376 * ...
27377 * ]
27378 * }
27379 * ]
27380 *
27381 * @type {Array}
27382 * @ignore
27383 */
27384 var __apiStruct = [];
27385
27386
27387 /**
27388 * `Array.prototype` reference.
27389 *
27390 * @type object
27391 * @ignore
27392 */
27393 var __arrayProto = Array.prototype;
27394
27395
27396 /**
27397 * Abstraction for `context` parameter of the `Api` constructor to allow it to
27398 * take several different forms for ease of use.
27399 *
27400 * Each of the input parameter types will be converted to a DataTables settings
27401 * object where possible.
27402 *
27403 * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
27404 * of:
27405 *
27406 * * `string` - jQuery selector. Any DataTables' matching the given selector
27407 * with be found and used.
27408 * * `node` - `TABLE` node which has already been formed into a DataTable.
27409 * * `jQuery` - A jQuery object of `TABLE` nodes.
27410 * * `object` - DataTables settings object
27411 * * `DataTables.Api` - API instance
27412 * @return {array|null} Matching DataTables settings objects. `null` or
27413 * `undefined` is returned if no matching DataTable is found.
27414 * @ignore
27415 */
27416 var _toSettings = function ( mixed )
27417 {
27418 var idx, jq;
27419 var settings = DataTable.settings;
27420 var tables = $.map( settings, function (el, i) {
27421 return el.nTable;
27422 } );
27423
27424 if ( ! mixed ) {
27425 return [];
27426 }
27427 else if ( mixed.nTable && mixed.oApi ) {
27428 // DataTables settings object
27429 return [ mixed ];
27430 }
27431 else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
27432 // Table node
27433 idx = $.inArray( mixed, tables );
27434 return idx !== -1 ? [ settings[idx] ] : null;
27435 }
27436 else if ( mixed && typeof mixed.settings === 'function' ) {
27437 return mixed.settings().toArray();
27438 }
27439 else if ( typeof mixed === 'string' ) {
27440 // jQuery selector
27441 jq = $(mixed);
27442 }
27443 else if ( mixed instanceof $ ) {
27444 // jQuery object (also DataTables instance)
27445 jq = mixed;
27446 }
27447
27448 if ( jq ) {
27449 return jq.map( function(i) {
27450 idx = $.inArray( this, tables );
27451 return idx !== -1 ? settings[idx] : null;
27452 } ).toArray();
27453 }
27454 };
27455
27456
27457 /**
27458 * DataTables API class - used to control and interface with one or more
27459 * DataTables enhanced tables.
27460 *
27461 * The API class is heavily based on jQuery, presenting a chainable interface
27462 * that you can use to interact with tables. Each instance of the API class has
27463 * a "context" - i.e. the tables that it will operate on. This could be a single
27464 * table, all tables on a page or a sub-set thereof.
27465 *
27466 * Additionally the API is designed to allow you to easily work with the data in
27467 * the tables, retrieving and manipulating it as required. This is done by
27468 * presenting the API class as an array like interface. The contents of the
27469 * array depend upon the actions requested by each method (for example
27470 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
27471 * return an array of objects or arrays depending upon your table's
27472 * configuration). The API object has a number of array like methods (`push`,
27473 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
27474 * `unique` etc) to assist your working with the data held in a table.
27475 *
27476 * Most methods (those which return an Api instance) are chainable, which means
27477 * the return from a method call also has all of the methods available that the
27478 * top level object had. For example, these two calls are equivalent:
27479 *
27480 * // Not chained
27481 * api.row.add( {...} );
27482 * api.draw();
27483 *
27484 * // Chained
27485 * api.row.add( {...} ).draw();
27486 *
27487 * @class DataTable.Api
27488 * @param {array|object|string|jQuery} context DataTable identifier. This is
27489 * used to define which DataTables enhanced tables this API will operate on.
27490 * Can be one of:
27491 *
27492 * * `string` - jQuery selector. Any DataTables' matching the given selector
27493 * with be found and used.
27494 * * `node` - `TABLE` node which has already been formed into a DataTable.
27495 * * `jQuery` - A jQuery object of `TABLE` nodes.
27496 * * `object` - DataTables settings object
27497 * @param {array} [data] Data to initialise the Api instance with.
27498 *
27499 * @example
27500 * // Direct initialisation during DataTables construction
27501 * var api = $('#example').DataTable();
27502 *
27503 * @example
27504 * // Initialisation using a DataTables jQuery object
27505 * var api = $('#example').dataTable().api();
27506 *
27507 * @example
27508 * // Initialisation as a constructor
27509 * var api = new $.fn.DataTable.Api( 'table.dataTable' );
27510 */
27511 _Api = function ( context, data )
27512 {
27513 if ( ! (this instanceof _Api) ) {
27514 return new _Api( context, data );
27515 }
27516
27517 var settings = [];
27518 var ctxSettings = function ( o ) {
27519 var a = _toSettings( o );
27520 if ( a ) {
27521 settings = settings.concat( a );
27522 }
27523 };
27524
27525 if ( $.isArray( context ) ) {
27526 for ( var i=0, ien=context.length ; i<ien ; i++ ) {
27527 ctxSettings( context[i] );
27528 }
27529 }
27530 else {
27531 ctxSettings( context );
27532 }
27533
27534 // Remove duplicates
27535 this.context = _unique( settings );
27536
27537 // Initial data
27538 if ( data ) {
27539 $.merge( this, data );
27540 }
27541
27542 // selector
27543 this.selector = {
27544 rows: null,
27545 cols: null,
27546 opts: null
27547 };
27548
27549 _Api.extend( this, this, __apiStruct );
27550 };
27551
27552 DataTable.Api = _Api;
27553
27554 // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
27555 // isPlainObject.
27556 $.extend( _Api.prototype, {
27557 any: function ()
27558 {
27559 return this.count() !== 0;
27560 },
27561
27562
27563 concat: __arrayProto.concat,
27564
27565
27566 context: [], // array of table settings objects
27567
27568
27569 count: function ()
27570 {
27571 return this.flatten().length;
27572 },
27573
27574
27575 each: function ( fn )
27576 {
27577 for ( var i=0, ien=this.length ; i<ien; i++ ) {
27578 fn.call( this, this[i], i, this );
27579 }
27580
27581 return this;
27582 },
27583
27584
27585 eq: function ( idx )
27586 {
27587 var ctx = this.context;
27588
27589 return ctx.length > idx ?
27590 new _Api( ctx[idx], this[idx] ) :
27591 null;
27592 },
27593
27594
27595 filter: function ( fn )
27596 {
27597 var a = [];
27598
27599 if ( __arrayProto.filter ) {
27600 a = __arrayProto.filter.call( this, fn, this );
27601 }
27602 else {
27603 // Compatibility for browsers without EMCA-252-5 (JS 1.6)
27604 for ( var i=0, ien=this.length ; i<ien ; i++ ) {
27605 if ( fn.call( this, this[i], i, this ) ) {
27606 a.push( this[i] );
27607 }
27608 }
27609 }
27610
27611 return new _Api( this.context, a );
27612 },
27613
27614
27615 flatten: function ()
27616 {
27617 var a = [];
27618 return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
27619 },
27620
27621
27622 join: __arrayProto.join,
27623
27624
27625 indexOf: __arrayProto.indexOf || function (obj, start)
27626 {
27627 for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
27628 if ( this[i] === obj ) {
27629 return i;
27630 }
27631 }
27632 return -1;
27633 },
27634
27635 iterator: function ( flatten, type, fn, alwaysNew ) {
27636 var
27637 a = [], ret,
27638 i, ien, j, jen,
27639 context = this.context,
27640 rows, items, item,
27641 selector = this.selector;
27642
27643 // Argument shifting
27644 if ( typeof flatten === 'string' ) {
27645 alwaysNew = fn;
27646 fn = type;
27647 type = flatten;
27648 flatten = false;
27649 }
27650
27651 for ( i=0, ien=context.length ; i<ien ; i++ ) {
27652 var apiInst = new _Api( context[i] );
27653
27654 if ( type === 'table' ) {
27655 ret = fn.call( apiInst, context[i], i );
27656
27657 if ( ret !== undefined ) {
27658 a.push( ret );
27659 }
27660 }
27661 else if ( type === 'columns' || type === 'rows' ) {
27662 // this has same length as context - one entry for each table
27663 ret = fn.call( apiInst, context[i], this[i], i );
27664
27665 if ( ret !== undefined ) {
27666 a.push( ret );
27667 }
27668 }
27669 else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
27670 // columns and rows share the same structure.
27671 // 'this' is an array of column indexes for each context
27672 items = this[i];
27673
27674 if ( type === 'column-rows' ) {
27675 rows = _selector_row_indexes( context[i], selector.opts );
27676 }
27677
27678 for ( j=0, jen=items.length ; j<jen ; j++ ) {
27679 item = items[j];
27680
27681 if ( type === 'cell' ) {
27682 ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
27683 }
27684 else {
27685 ret = fn.call( apiInst, context[i], item, i, j, rows );
27686 }
27687
27688 if ( ret !== undefined ) {
27689 a.push( ret );
27690 }
27691 }
27692 }
27693 }
27694
27695 if ( a.length || alwaysNew ) {
27696 var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
27697 var apiSelector = api.selector;
27698 apiSelector.rows = selector.rows;
27699 apiSelector.cols = selector.cols;
27700 apiSelector.opts = selector.opts;
27701 return api;
27702 }
27703 return this;
27704 },
27705
27706
27707 lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
27708 {
27709 // Bit cheeky...
27710 return this.indexOf.apply( this.toArray.reverse(), arguments );
27711 },
27712
27713
27714 length: 0,
27715
27716
27717 map: function ( fn )
27718 {
27719 var a = [];
27720
27721 if ( __arrayProto.map ) {
27722 a = __arrayProto.map.call( this, fn, this );
27723 }
27724 else {
27725 // Compatibility for browsers without EMCA-252-5 (JS 1.6)
27726 for ( var i=0, ien=this.length ; i<ien ; i++ ) {
27727 a.push( fn.call( this, this[i], i ) );
27728 }
27729 }
27730
27731 return new _Api( this.context, a );
27732 },
27733
27734
27735 pluck: function ( prop )
27736 {
27737 return this.map( function ( el ) {
27738 return el[ prop ];
27739 } );
27740 },
27741
27742 pop: __arrayProto.pop,
27743
27744
27745 push: __arrayProto.push,
27746
27747
27748 // Does not return an API instance
27749 reduce: __arrayProto.reduce || function ( fn, init )
27750 {
27751 return _fnReduce( this, fn, init, 0, this.length, 1 );
27752 },
27753
27754
27755 reduceRight: __arrayProto.reduceRight || function ( fn, init )
27756 {
27757 return _fnReduce( this, fn, init, this.length-1, -1, -1 );
27758 },
27759
27760
27761 reverse: __arrayProto.reverse,
27762
27763
27764 // Object with rows, columns and opts
27765 selector: null,
27766
27767
27768 shift: __arrayProto.shift,
27769
27770
27771 sort: __arrayProto.sort, // ? name - order?
27772
27773
27774 splice: __arrayProto.splice,
27775
27776
27777 toArray: function ()
27778 {
27779 return __arrayProto.slice.call( this );
27780 },
27781
27782
27783 to$: function ()
27784 {
27785 return $( this );
27786 },
27787
27788
27789 toJQuery: function ()
27790 {
27791 return $( this );
27792 },
27793
27794
27795 unique: function ()
27796 {
27797 return new _Api( this.context, _unique(this) );
27798 },
27799
27800
27801 unshift: __arrayProto.unshift
27802 } );
27803
27804
27805 _Api.extend = function ( scope, obj, ext )
27806 {
27807 // Only extend API instances and static properties of the API
27808 if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
27809 return;
27810 }
27811
27812 var
27813 i, ien,
27814 j, jen,
27815 struct, inner,
27816 methodScoping = function ( scope, fn, struc ) {
27817 return function () {
27818 var ret = fn.apply( scope, arguments );
27819
27820 // Method extension
27821 _Api.extend( ret, ret, struc.methodExt );
27822 return ret;
27823 };
27824 };
27825
27826 for ( i=0, ien=ext.length ; i<ien ; i++ ) {
27827 struct = ext[i];
27828
27829 // Value
27830 obj[ struct.name ] = typeof struct.val === 'function' ?
27831 methodScoping( scope, struct.val, struct ) :
27832 $.isPlainObject( struct.val ) ?
27833 {} :
27834 struct.val;
27835
27836 obj[ struct.name ].__dt_wrapper = true;
27837
27838 // Property extension
27839 _Api.extend( scope, obj[ struct.name ], struct.propExt );
27840 }
27841 };
27842
27843
27844 // @todo - Is there need for an augment function?
27845 // _Api.augment = function ( inst, name )
27846 // {
27847 // // Find src object in the structure from the name
27848 // var parts = name.split('.');
27849
27850 // _Api.extend( inst, obj );
27851 // };
27852
27853
27854 // [
27855 // {
27856 // name: 'data' -- string - Property name
27857 // val: function () {}, -- function - Api method (or undefined if just an object
27858 // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
27859 // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
27860 // },
27861 // {
27862 // name: 'row'
27863 // val: {},
27864 // methodExt: [ ... ],
27865 // propExt: [
27866 // {
27867 // name: 'data'
27868 // val: function () {},
27869 // methodExt: [ ... ],
27870 // propExt: [ ... ]
27871 // },
27872 // ...
27873 // ]
27874 // }
27875 // ]
27876
27877 _Api.register = _api_register = function ( name, val )
27878 {
27879 if ( $.isArray( name ) ) {
27880 for ( var j=0, jen=name.length ; j<jen ; j++ ) {
27881 _Api.register( name[j], val );
27882 }
27883 return;
27884 }
27885
27886 var
27887 i, ien,
27888 heir = name.split('.'),
27889 struct = __apiStruct,
27890 key, method;
27891
27892 var find = function ( src, name ) {
27893 for ( var i=0, ien=src.length ; i<ien ; i++ ) {
27894 if ( src[i].name === name ) {
27895 return src[i];
27896 }
27897 }
27898 return null;
27899 };
27900
27901 for ( i=0, ien=heir.length ; i<ien ; i++ ) {
27902 method = heir[i].indexOf('()') !== -1;
27903 key = method ?
27904 heir[i].replace('()', '') :
27905 heir[i];
27906
27907 var src = find( struct, key );
27908 if ( ! src ) {
27909 src = {
27910 name: key,
27911 val: {},
27912 methodExt: [],
27913 propExt: []
27914 };
27915 struct.push( src );
27916 }
27917
27918 if ( i === ien-1 ) {
27919 src.val = val;
27920 }
27921 else {
27922 struct = method ?
27923 src.methodExt :
27924 src.propExt;
27925 }
27926 }
27927 };
27928
27929
27930 _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
27931 _Api.register( pluralName, val );
27932
27933 _Api.register( singularName, function () {
27934 var ret = val.apply( this, arguments );
27935
27936 if ( ret === this ) {
27937 // Returned item is the API instance that was passed in, return it
27938 return this;
27939 }
27940 else if ( ret instanceof _Api ) {
27941 // New API instance returned, want the value from the first item
27942 // in the returned array for the singular result.
27943 return ret.length ?
27944 $.isArray( ret[0] ) ?
27945 new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
27946 ret[0] :
27947 undefined;
27948 }
27949
27950 // Non-API return - just fire it back
27951 return ret;
27952 } );
27953 };
27954
27955
27956 /**
27957 * Selector for HTML tables. Apply the given selector to the give array of
27958 * DataTables settings objects.
27959 *
27960 * @param {string|integer} [selector] jQuery selector string or integer
27961 * @param {array} Array of DataTables settings objects to be filtered
27962 * @return {array}
27963 * @ignore
27964 */
27965 var __table_selector = function ( selector, a )
27966 {
27967 // Integer is used to pick out a table by index
27968 if ( typeof selector === 'number' ) {
27969 return [ a[ selector ] ];
27970 }
27971
27972 // Perform a jQuery selector on the table nodes
27973 var nodes = $.map( a, function (el, i) {
27974 return el.nTable;
27975 } );
27976
27977 return $(nodes)
27978 .filter( selector )
27979 .map( function (i) {
27980 // Need to translate back from the table node to the settings
27981 var idx = $.inArray( this, nodes );
27982 return a[ idx ];
27983 } )
27984 .toArray();
27985 };
27986
27987
27988
27989 /**
27990 * Context selector for the API's context (i.e. the tables the API instance
27991 * refers to.
27992 *
27993 * @name DataTable.Api#tables
27994 * @param {string|integer} [selector] Selector to pick which tables the iterator
27995 * should operate on. If not given, all tables in the current context are
27996 * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
27997 * select multiple tables or as an integer to select a single table.
27998 * @returns {DataTable.Api} Returns a new API instance if a selector is given.
27999 */
28000 _api_register( 'tables()', function ( selector ) {
28001 // A new instance is created if there was a selector specified
28002 return selector ?
28003 new _Api( __table_selector( selector, this.context ) ) :
28004 this;
28005 } );
28006
28007
28008 _api_register( 'table()', function ( selector ) {
28009 var tables = this.tables( selector );
28010 var ctx = tables.context;
28011
28012 // Truncate to the first matched table
28013 return ctx.length ?
28014 new _Api( ctx[0] ) :
28015 tables;
28016 } );
28017
28018
28019 _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
28020 return this.iterator( 'table', function ( ctx ) {
28021 return ctx.nTable;
28022 }, 1 );
28023 } );
28024
28025
28026 _api_registerPlural( 'tables().body()', 'table().body()' , function () {
28027 return this.iterator( 'table', function ( ctx ) {
28028 return ctx.nTBody;
28029 }, 1 );
28030 } );
28031
28032
28033 _api_registerPlural( 'tables().header()', 'table().header()' , function () {
28034 return this.iterator( 'table', function ( ctx ) {
28035 return ctx.nTHead;
28036 }, 1 );
28037 } );
28038
28039
28040 _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
28041 return this.iterator( 'table', function ( ctx ) {
28042 return ctx.nTFoot;
28043 }, 1 );
28044 } );
28045
28046
28047 _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
28048 return this.iterator( 'table', function ( ctx ) {
28049 return ctx.nTableWrapper;
28050 }, 1 );
28051 } );
28052
28053
28054
28055 /**
28056 * Redraw the tables in the current context.
28057 */
28058 _api_register( 'draw()', function ( paging ) {
28059 return this.iterator( 'table', function ( settings ) {
28060 if ( paging === 'page' ) {
28061 _fnDraw( settings );
28062 }
28063 else {
28064 if ( typeof paging === 'string' ) {
28065 paging = paging === 'full-hold' ?
28066 false :
28067 true;
28068 }
28069
28070 _fnReDraw( settings, paging===false );
28071 }
28072 } );
28073 } );
28074
28075
28076
28077 /**
28078 * Get the current page index.
28079 *
28080 * @return {integer} Current page index (zero based)
28081 *//**
28082 * Set the current page.
28083 *
28084 * Note that if you attempt to show a page which does not exist, DataTables will
28085 * not throw an error, but rather reset the paging.
28086 *
28087 * @param {integer|string} action The paging action to take. This can be one of:
28088 * * `integer` - The page index to jump to
28089 * * `string` - An action to take:
28090 * * `first` - Jump to first page.
28091 * * `next` - Jump to the next page
28092 * * `previous` - Jump to previous page
28093 * * `last` - Jump to the last page.
28094 * @returns {DataTables.Api} this
28095 */
28096 _api_register( 'page()', function ( action ) {
28097 if ( action === undefined ) {
28098 return this.page.info().page; // not an expensive call
28099 }
28100
28101 // else, have an action to take on all tables
28102 return this.iterator( 'table', function ( settings ) {
28103 _fnPageChange( settings, action );
28104 } );
28105 } );
28106
28107
28108 /**
28109 * Paging information for the first table in the current context.
28110 *
28111 * If you require paging information for another table, use the `table()` method
28112 * with a suitable selector.
28113 *
28114 * @return {object} Object with the following properties set:
28115 * * `page` - Current page index (zero based - i.e. the first page is `0`)
28116 * * `pages` - Total number of pages
28117 * * `start` - Display index for the first record shown on the current page
28118 * * `end` - Display index for the last record shown on the current page
28119 * * `length` - Display length (number of records). Note that generally `start
28120 * + length = end`, but this is not always true, for example if there are
28121 * only 2 records to show on the final page, with a length of 10.
28122 * * `recordsTotal` - Full data set length
28123 * * `recordsDisplay` - Data set length once the current filtering criterion
28124 * are applied.
28125 */
28126 _api_register( 'page.info()', function ( action ) {
28127 if ( this.context.length === 0 ) {
28128 return undefined;
28129 }
28130
28131 var
28132 settings = this.context[0],
28133 start = settings._iDisplayStart,
28134 len = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
28135 visRecords = settings.fnRecordsDisplay(),
28136 all = len === -1;
28137
28138 return {
28139 "page": all ? 0 : Math.floor( start / len ),
28140 "pages": all ? 1 : Math.ceil( visRecords / len ),
28141 "start": start,
28142 "end": settings.fnDisplayEnd(),
28143 "length": len,
28144 "recordsTotal": settings.fnRecordsTotal(),
28145 "recordsDisplay": visRecords,
28146 "serverSide": _fnDataSource( settings ) === 'ssp'
28147 };
28148 } );
28149
28150
28151 /**
28152 * Get the current page length.
28153 *
28154 * @return {integer} Current page length. Note `-1` indicates that all records
28155 * are to be shown.
28156 *//**
28157 * Set the current page length.
28158 *
28159 * @param {integer} Page length to set. Use `-1` to show all records.
28160 * @returns {DataTables.Api} this
28161 */
28162 _api_register( 'page.len()', function ( len ) {
28163 // Note that we can't call this function 'length()' because `length`
28164 // is a Javascript property of functions which defines how many arguments
28165 // the function expects.
28166 if ( len === undefined ) {
28167 return this.context.length !== 0 ?
28168 this.context[0]._iDisplayLength :
28169 undefined;
28170 }
28171
28172 // else, set the page length
28173 return this.iterator( 'table', function ( settings ) {
28174 _fnLengthChange( settings, len );
28175 } );
28176 } );
28177
28178
28179
28180 var __reload = function ( settings, holdPosition, callback ) {
28181 // Use the draw event to trigger a callback
28182 if ( callback ) {
28183 var api = new _Api( settings );
28184
28185 api.one( 'draw', function () {
28186 callback( api.ajax.json() );
28187 } );
28188 }
28189
28190 if ( _fnDataSource( settings ) == 'ssp' ) {
28191 _fnReDraw( settings, holdPosition );
28192 }
28193 else {
28194 _fnProcessingDisplay( settings, true );
28195
28196 // Cancel an existing request
28197 var xhr = settings.jqXHR;
28198 if ( xhr && xhr.readyState !== 4 ) {
28199 xhr.abort();
28200 }
28201
28202 // Trigger xhr
28203 _fnBuildAjax( settings, [], function( json ) {
28204 _fnClearTable( settings );
28205
28206 var data = _fnAjaxDataSrc( settings, json );
28207 for ( var i=0, ien=data.length ; i<ien ; i++ ) {
28208 _fnAddData( settings, data[i] );
28209 }
28210
28211 _fnReDraw( settings, holdPosition );
28212 _fnProcessingDisplay( settings, false );
28213 } );
28214 }
28215 };
28216
28217
28218 /**
28219 * Get the JSON response from the last Ajax request that DataTables made to the
28220 * server. Note that this returns the JSON from the first table in the current
28221 * context.
28222 *
28223 * @return {object} JSON received from the server.
28224 */
28225 _api_register( 'ajax.json()', function () {
28226 var ctx = this.context;
28227
28228 if ( ctx.length > 0 ) {
28229 return ctx[0].json;
28230 }
28231
28232 // else return undefined;
28233 } );
28234
28235
28236 /**
28237 * Get the data submitted in the last Ajax request
28238 */
28239 _api_register( 'ajax.params()', function () {
28240 var ctx = this.context;
28241
28242 if ( ctx.length > 0 ) {
28243 return ctx[0].oAjaxData;
28244 }
28245
28246 // else return undefined;
28247 } );
28248
28249
28250 /**
28251 * Reload tables from the Ajax data source. Note that this function will
28252 * automatically re-draw the table when the remote data has been loaded.
28253 *
28254 * @param {boolean} [reset=true] Reset (default) or hold the current paging
28255 * position. A full re-sort and re-filter is performed when this method is
28256 * called, which is why the pagination reset is the default action.
28257 * @returns {DataTables.Api} this
28258 */
28259 _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
28260 return this.iterator( 'table', function (settings) {
28261 __reload( settings, resetPaging===false, callback );
28262 } );
28263 } );
28264
28265
28266 /**
28267 * Get the current Ajax URL. Note that this returns the URL from the first
28268 * table in the current context.
28269 *
28270 * @return {string} Current Ajax source URL
28271 *//**
28272 * Set the Ajax URL. Note that this will set the URL for all tables in the
28273 * current context.
28274 *
28275 * @param {string} url URL to set.
28276 * @returns {DataTables.Api} this
28277 */
28278 _api_register( 'ajax.url()', function ( url ) {
28279 var ctx = this.context;
28280
28281 if ( url === undefined ) {
28282 // get
28283 if ( ctx.length === 0 ) {
28284 return undefined;
28285 }
28286 ctx = ctx[0];
28287
28288 return ctx.ajax ?
28289 $.isPlainObject( ctx.ajax ) ?
28290 ctx.ajax.url :
28291 ctx.ajax :
28292 ctx.sAjaxSource;
28293 }
28294
28295 // set
28296 return this.iterator( 'table', function ( settings ) {
28297 if ( $.isPlainObject( settings.ajax ) ) {
28298 settings.ajax.url = url;
28299 }
28300 else {
28301 settings.ajax = url;
28302 }
28303 // No need to consider sAjaxSource here since DataTables gives priority
28304 // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
28305 // value of `sAjaxSource` redundant.
28306 } );
28307 } );
28308
28309
28310 /**
28311 * Load data from the newly set Ajax URL. Note that this method is only
28312 * available when `ajax.url()` is used to set a URL. Additionally, this method
28313 * has the same effect as calling `ajax.reload()` but is provided for
28314 * convenience when setting a new URL. Like `ajax.reload()` it will
28315 * automatically redraw the table once the remote data has been loaded.
28316 *
28317 * @returns {DataTables.Api} this
28318 */
28319 _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
28320 // Same as a reload, but makes sense to present it for easy access after a
28321 // url change
28322 return this.iterator( 'table', function ( ctx ) {
28323 __reload( ctx, resetPaging===false, callback );
28324 } );
28325 } );
28326
28327
28328
28329
28330 var _selector_run = function ( type, selector, selectFn, settings, opts )
28331 {
28332 var
28333 out = [], res,
28334 a, i, ien, j, jen,
28335 selectorType = typeof selector;
28336
28337 // Can't just check for isArray here, as an API or jQuery instance might be
28338 // given with their array like look
28339 if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
28340 selector = [ selector ];
28341 }
28342
28343 for ( i=0, ien=selector.length ; i<ien ; i++ ) {
28344 a = selector[i] && selector[i].split ?
28345 selector[i].split(',') :
28346 [ selector[i] ];
28347
28348 for ( j=0, jen=a.length ; j<jen ; j++ ) {
28349 res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
28350
28351 if ( res && res.length ) {
28352 out = out.concat( res );
28353 }
28354 }
28355 }
28356
28357 // selector extensions
28358 var ext = _ext.selector[ type ];
28359 if ( ext.length ) {
28360 for ( i=0, ien=ext.length ; i<ien ; i++ ) {
28361 out = ext[i]( settings, opts, out );
28362 }
28363 }
28364
28365 return _unique( out );
28366 };
28367
28368
28369 var _selector_opts = function ( opts )
28370 {
28371 if ( ! opts ) {
28372 opts = {};
28373 }
28374
28375 // Backwards compatibility for 1.9- which used the terminology filter rather
28376 // than search
28377 if ( opts.filter && opts.search === undefined ) {
28378 opts.search = opts.filter;
28379 }
28380
28381 return $.extend( {
28382 search: 'none',
28383 order: 'current',
28384 page: 'all'
28385 }, opts );
28386 };
28387
28388
28389 var _selector_first = function ( inst )
28390 {
28391 // Reduce the API instance to the first item found
28392 for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
28393 if ( inst[i].length > 0 ) {
28394 // Assign the first element to the first item in the instance
28395 // and truncate the instance and context
28396 inst[0] = inst[i];
28397 inst[0].length = 1;
28398 inst.length = 1;
28399 inst.context = [ inst.context[i] ];
28400
28401 return inst;
28402 }
28403 }
28404
28405 // Not found - return an empty instance
28406 inst.length = 0;
28407 return inst;
28408 };
28409
28410
28411 var _selector_row_indexes = function ( settings, opts )
28412 {
28413 var
28414 i, ien, tmp, a=[],
28415 displayFiltered = settings.aiDisplay,
28416 displayMaster = settings.aiDisplayMaster;
28417
28418 var
28419 search = opts.search, // none, applied, removed
28420 order = opts.order, // applied, current, index (original - compatibility with 1.9)
28421 page = opts.page; // all, current
28422
28423 if ( _fnDataSource( settings ) == 'ssp' ) {
28424 // In server-side processing mode, most options are irrelevant since
28425 // rows not shown don't exist and the index order is the applied order
28426 // Removed is a special case - for consistency just return an empty
28427 // array
28428 return search === 'removed' ?
28429 [] :
28430 _range( 0, displayMaster.length );
28431 }
28432 else if ( page == 'current' ) {
28433 // Current page implies that order=current and fitler=applied, since it is
28434 // fairly senseless otherwise, regardless of what order and search actually
28435 // are
28436 for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
28437 a.push( displayFiltered[i] );
28438 }
28439 }
28440 else if ( order == 'current' || order == 'applied' ) {
28441 a = search == 'none' ?
28442 displayMaster.slice() : // no search
28443 search == 'applied' ?
28444 displayFiltered.slice() : // applied search
28445 $.map( displayMaster, function (el, i) { // removed search
28446 return $.inArray( el, displayFiltered ) === -1 ? el : null;
28447 } );
28448 }
28449 else if ( order == 'index' || order == 'original' ) {
28450 for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
28451 if ( search == 'none' ) {
28452 a.push( i );
28453 }
28454 else { // applied | removed
28455 tmp = $.inArray( i, displayFiltered );
28456
28457 if ((tmp === -1 && search == 'removed') ||
28458 (tmp >= 0 && search == 'applied') )
28459 {
28460 a.push( i );
28461 }
28462 }
28463 }
28464 }
28465
28466 return a;
28467 };
28468
28469
28470 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
28471 * Rows
28472 *
28473 * {} - no selector - use all available rows
28474 * {integer} - row aoData index
28475 * {node} - TR node
28476 * {string} - jQuery selector to apply to the TR elements
28477 * {array} - jQuery array of nodes, or simply an array of TR nodes
28478 *
28479 */
28480
28481
28482 var __row_selector = function ( settings, selector, opts )
28483 {
28484 var run = function ( sel ) {
28485 var selInt = _intVal( sel );
28486 var i, ien;
28487
28488 // Short cut - selector is a number and no options provided (default is
28489 // all records, so no need to check if the index is in there, since it
28490 // must be - dev error if the index doesn't exist).
28491 if ( selInt !== null && ! opts ) {
28492 return [ selInt ];
28493 }
28494
28495 var rows = _selector_row_indexes( settings, opts );
28496
28497 if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
28498 // Selector - integer
28499 return [ selInt ];
28500 }
28501 else if ( ! sel ) {
28502 // Selector - none
28503 return rows;
28504 }
28505
28506 // Selector - function
28507 if ( typeof sel === 'function' ) {
28508 return $.map( rows, function (idx) {
28509 var row = settings.aoData[ idx ];
28510 return sel( idx, row._aData, row.nTr ) ? idx : null;
28511 } );
28512 }
28513
28514 // Get nodes in the order from the `rows` array with null values removed
28515 var nodes = _removeEmpty(
28516 _pluck_order( settings.aoData, rows, 'nTr' )
28517 );
28518
28519 // Selector - node
28520 if ( sel.nodeName ) {
28521 if ( sel._DT_RowIndex !== undefined ) {
28522 return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
28523 }
28524 else if ( sel._DT_CellIndex ) {
28525 return [ sel._DT_CellIndex.row ];
28526 }
28527 else {
28528 var host = $(sel).closest('*[data-dt-row]');
28529 return host.length ?
28530 [ host.data('dt-row') ] :
28531 [];
28532 }
28533 }
28534
28535 // ID selector. Want to always be able to select rows by id, regardless
28536 // of if the tr element has been created or not, so can't rely upon
28537 // jQuery here - hence a custom implementation. This does not match
28538 // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
28539 // but to select it using a CSS selector engine (like Sizzle or
28540 // querySelect) it would need to need to be escaped for some characters.
28541 // DataTables simplifies this for row selectors since you can select
28542 // only a row. A # indicates an id any anything that follows is the id -
28543 // unescaped.
28544 if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
28545 // get row index from id
28546 var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
28547 if ( rowObj !== undefined ) {
28548 return [ rowObj.idx ];
28549 }
28550
28551 // need to fall through to jQuery in case there is DOM id that
28552 // matches
28553 }
28554
28555 // Selector - jQuery selector string, array of nodes or jQuery object/
28556 // As jQuery's .filter() allows jQuery objects to be passed in filter,
28557 // it also allows arrays, so this will cope with all three options
28558 return $(nodes)
28559 .filter( sel )
28560 .map( function () {
28561 return this._DT_RowIndex;
28562 } )
28563 .toArray();
28564 };
28565
28566 return _selector_run( 'row', selector, run, settings, opts );
28567 };
28568
28569
28570 _api_register( 'rows()', function ( selector, opts ) {
28571 // argument shifting
28572 if ( selector === undefined ) {
28573 selector = '';
28574 }
28575 else if ( $.isPlainObject( selector ) ) {
28576 opts = selector;
28577 selector = '';
28578 }
28579
28580 opts = _selector_opts( opts );
28581
28582 var inst = this.iterator( 'table', function ( settings ) {
28583 return __row_selector( settings, selector, opts );
28584 }, 1 );
28585
28586 // Want argument shifting here and in __row_selector?
28587 inst.selector.rows = selector;
28588 inst.selector.opts = opts;
28589
28590 return inst;
28591 } );
28592
28593 _api_register( 'rows().nodes()', function () {
28594 return this.iterator( 'row', function ( settings, row ) {
28595 return settings.aoData[ row ].nTr || undefined;
28596 }, 1 );
28597 } );
28598
28599 _api_register( 'rows().data()', function () {
28600 return this.iterator( true, 'rows', function ( settings, rows ) {
28601 return _pluck_order( settings.aoData, rows, '_aData' );
28602 }, 1 );
28603 } );
28604
28605 _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
28606 return this.iterator( 'row', function ( settings, row ) {
28607 var r = settings.aoData[ row ];
28608 return type === 'search' ? r._aFilterData : r._aSortData;
28609 }, 1 );
28610 } );
28611
28612 _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
28613 return this.iterator( 'row', function ( settings, row ) {
28614 _fnInvalidate( settings, row, src );
28615 } );
28616 } );
28617
28618 _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
28619 return this.iterator( 'row', function ( settings, row ) {
28620 return row;
28621 }, 1 );
28622 } );
28623
28624 _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
28625 var a = [];
28626 var context = this.context;
28627
28628 // `iterator` will drop undefined values, but in this case we want them
28629 for ( var i=0, ien=context.length ; i<ien ; i++ ) {
28630 for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
28631 var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
28632 a.push( (hash === true ? '#' : '' )+ id );
28633 }
28634 }
28635
28636 return new _Api( context, a );
28637 } );
28638
28639 _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
28640 var that = this;
28641
28642 this.iterator( 'row', function ( settings, row, thatIdx ) {
28643 var data = settings.aoData;
28644 var rowData = data[ row ];
28645 var i, ien, j, jen;
28646 var loopRow, loopCells;
28647
28648 data.splice( row, 1 );
28649
28650 // Update the cached indexes
28651 for ( i=0, ien=data.length ; i<ien ; i++ ) {
28652 loopRow = data[i];
28653 loopCells = loopRow.anCells;
28654
28655 // Rows
28656 if ( loopRow.nTr !== null ) {
28657 loopRow.nTr._DT_RowIndex = i;
28658 }
28659
28660 // Cells
28661 if ( loopCells !== null ) {
28662 for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
28663 loopCells[j]._DT_CellIndex.row = i;
28664 }
28665 }
28666 }
28667
28668 // Delete from the display arrays
28669 _fnDeleteIndex( settings.aiDisplayMaster, row );
28670 _fnDeleteIndex( settings.aiDisplay, row );
28671 _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
28672
28673 // Check for an 'overflow' they case for displaying the table
28674 _fnLengthOverflow( settings );
28675
28676 // Remove the row's ID reference if there is one
28677 var id = settings.rowIdFn( rowData._aData );
28678 if ( id !== undefined ) {
28679 delete settings.aIds[ id ];
28680 }
28681 } );
28682
28683 this.iterator( 'table', function ( settings ) {
28684 for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
28685 settings.aoData[i].idx = i;
28686 }
28687 } );
28688
28689 return this;
28690 } );
28691
28692
28693 _api_register( 'rows.add()', function ( rows ) {
28694 var newRows = this.iterator( 'table', function ( settings ) {
28695 var row, i, ien;
28696 var out = [];
28697
28698 for ( i=0, ien=rows.length ; i<ien ; i++ ) {
28699 row = rows[i];
28700
28701 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
28702 out.push( _fnAddTr( settings, row )[0] );
28703 }
28704 else {
28705 out.push( _fnAddData( settings, row ) );
28706 }
28707 }
28708
28709 return out;
28710 }, 1 );
28711
28712 // Return an Api.rows() extended instance, so rows().nodes() etc can be used
28713 var modRows = this.rows( -1 );
28714 modRows.pop();
28715 $.merge( modRows, newRows );
28716
28717 return modRows;
28718 } );
28719
28720
28721
28722
28723
28724 /**
28725 *
28726 */
28727 _api_register( 'row()', function ( selector, opts ) {
28728 return _selector_first( this.rows( selector, opts ) );
28729 } );
28730
28731
28732 _api_register( 'row().data()', function ( data ) {
28733 var ctx = this.context;
28734
28735 if ( data === undefined ) {
28736 // Get
28737 return ctx.length && this.length ?
28738 ctx[0].aoData[ this[0] ]._aData :
28739 undefined;
28740 }
28741
28742 // Set
28743 ctx[0].aoData[ this[0] ]._aData = data;
28744
28745 // Automatically invalidate
28746 _fnInvalidate( ctx[0], this[0], 'data' );
28747
28748 return this;
28749 } );
28750
28751
28752 _api_register( 'row().node()', function () {
28753 var ctx = this.context;
28754
28755 return ctx.length && this.length ?
28756 ctx[0].aoData[ this[0] ].nTr || null :
28757 null;
28758 } );
28759
28760
28761 _api_register( 'row.add()', function ( row ) {
28762 // Allow a jQuery object to be passed in - only a single row is added from
28763 // it though - the first element in the set
28764 if ( row instanceof $ && row.length ) {
28765 row = row[0];
28766 }
28767
28768 var rows = this.iterator( 'table', function ( settings ) {
28769 if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
28770 return _fnAddTr( settings, row )[0];
28771 }
28772 return _fnAddData( settings, row );
28773 } );
28774
28775 // Return an Api.rows() extended instance, with the newly added row selected
28776 return this.row( rows[0] );
28777 } );
28778
28779
28780
28781 var __details_add = function ( ctx, row, data, klass )
28782 {
28783 // Convert to array of TR elements
28784 var rows = [];
28785 var addRow = function ( r, k ) {
28786 // Recursion to allow for arrays of jQuery objects
28787 if ( $.isArray( r ) || r instanceof $ ) {
28788 for ( var i=0, ien=r.length ; i<ien ; i++ ) {
28789 addRow( r[i], k );
28790 }
28791 return;
28792 }
28793
28794 // If we get a TR element, then just add it directly - up to the dev
28795 // to add the correct number of columns etc
28796 if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
28797 rows.push( r );
28798 }
28799 else {
28800 // Otherwise create a row with a wrapper
28801 var created = $('<tr><td/></tr>').addClass( k );
28802 $('td', created)
28803 .addClass( k )
28804 .html( r )
28805 [0].colSpan = _fnVisbleColumns( ctx );
28806
28807 rows.push( created[0] );
28808 }
28809 };
28810
28811 addRow( data, klass );
28812
28813 if ( row._details ) {
28814 row._details.remove();
28815 }
28816
28817 row._details = $(rows);
28818
28819 // If the children were already shown, that state should be retained
28820 if ( row._detailsShow ) {
28821 row._details.insertAfter( row.nTr );
28822 }
28823 };
28824
28825
28826 var __details_remove = function ( api, idx )
28827 {
28828 var ctx = api.context;
28829
28830 if ( ctx.length ) {
28831 var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
28832
28833 if ( row && row._details ) {
28834 row._details.remove();
28835
28836 row._detailsShow = undefined;
28837 row._details = undefined;
28838 }
28839 }
28840 };
28841
28842
28843 var __details_display = function ( api, show ) {
28844 var ctx = api.context;
28845
28846 if ( ctx.length && api.length ) {
28847 var row = ctx[0].aoData[ api[0] ];
28848
28849 if ( row._details ) {
28850 row._detailsShow = show;
28851
28852 if ( show ) {
28853 row._details.insertAfter( row.nTr );
28854 }
28855 else {
28856 row._details.detach();
28857 }
28858
28859 __details_events( ctx[0] );
28860 }
28861 }
28862 };
28863
28864
28865 var __details_events = function ( settings )
28866 {
28867 var api = new _Api( settings );
28868 var namespace = '.dt.DT_details';
28869 var drawEvent = 'draw'+namespace;
28870 var colvisEvent = 'column-visibility'+namespace;
28871 var destroyEvent = 'destroy'+namespace;
28872 var data = settings.aoData;
28873
28874 api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
28875
28876 if ( _pluck( data, '_details' ).length > 0 ) {
28877 // On each draw, insert the required elements into the document
28878 api.on( drawEvent, function ( e, ctx ) {
28879 if ( settings !== ctx ) {
28880 return;
28881 }
28882
28883 api.rows( {page:'current'} ).eq(0).each( function (idx) {
28884 // Internal data grab
28885 var row = data[ idx ];
28886
28887 if ( row._detailsShow ) {
28888 row._details.insertAfter( row.nTr );
28889 }
28890 } );
28891 } );
28892
28893 // Column visibility change - update the colspan
28894 api.on( colvisEvent, function ( e, ctx, idx, vis ) {
28895 if ( settings !== ctx ) {
28896 return;
28897 }
28898
28899 // Update the colspan for the details rows (note, only if it already has
28900 // a colspan)
28901 var row, visible = _fnVisbleColumns( ctx );
28902
28903 for ( var i=0, ien=data.length ; i<ien ; i++ ) {
28904 row = data[i];
28905
28906 if ( row._details ) {
28907 row._details.children('td[colspan]').attr('colspan', visible );
28908 }
28909 }
28910 } );
28911
28912 // Table destroyed - nuke any child rows
28913 api.on( destroyEvent, function ( e, ctx ) {
28914 if ( settings !== ctx ) {
28915 return;
28916 }
28917
28918 for ( var i=0, ien=data.length ; i<ien ; i++ ) {
28919 if ( data[i]._details ) {
28920 __details_remove( api, i );
28921 }
28922 }
28923 } );
28924 }
28925 };
28926
28927 // Strings for the method names to help minification
28928 var _emp = '';
28929 var _child_obj = _emp+'row().child';
28930 var _child_mth = _child_obj+'()';
28931
28932 // data can be:
28933 // tr
28934 // string
28935 // jQuery or array of any of the above
28936 _api_register( _child_mth, function ( data, klass ) {
28937 var ctx = this.context;
28938
28939 if ( data === undefined ) {
28940 // get
28941 return ctx.length && this.length ?
28942 ctx[0].aoData[ this[0] ]._details :
28943 undefined;
28944 }
28945 else if ( data === true ) {
28946 // show
28947 this.child.show();
28948 }
28949 else if ( data === false ) {
28950 // remove
28951 __details_remove( this );
28952 }
28953 else if ( ctx.length && this.length ) {
28954 // set
28955 __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
28956 }
28957
28958 return this;
28959 } );
28960
28961
28962 _api_register( [
28963 _child_obj+'.show()',
28964 _child_mth+'.show()' // only when `child()` was called with parameters (without
28965 ], function ( show ) { // it returns an object and this method is not executed)
28966 __details_display( this, true );
28967 return this;
28968 } );
28969
28970
28971 _api_register( [
28972 _child_obj+'.hide()',
28973 _child_mth+'.hide()' // only when `child()` was called with parameters (without
28974 ], function () { // it returns an object and this method is not executed)
28975 __details_display( this, false );
28976 return this;
28977 } );
28978
28979
28980 _api_register( [
28981 _child_obj+'.remove()',
28982 _child_mth+'.remove()' // only when `child()` was called with parameters (without
28983 ], function () { // it returns an object and this method is not executed)
28984 __details_remove( this );
28985 return this;
28986 } );
28987
28988
28989 _api_register( _child_obj+'.isShown()', function () {
28990 var ctx = this.context;
28991
28992 if ( ctx.length && this.length ) {
28993 // _detailsShown as false or undefined will fall through to return false
28994 return ctx[0].aoData[ this[0] ]._detailsShow || false;
28995 }
28996 return false;
28997 } );
28998
28999
29000
29001 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
29002 * Columns
29003 *
29004 * {integer} - column index (>=0 count from left, <0 count from right)
29005 * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
29006 * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
29007 * "{string}:name" - column name
29008 * "{string}" - jQuery selector on column header nodes
29009 *
29010 */
29011
29012 // can be an array of these items, comma separated list, or an array of comma
29013 // separated lists
29014
29015 var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
29016
29017
29018 // r1 and r2 are redundant - but it means that the parameters match for the
29019 // iterator callback in columns().data()
29020 var __columnData = function ( settings, column, r1, r2, rows ) {
29021 var a = [];
29022 for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
29023 a.push( _fnGetCellData( settings, rows[row], column ) );
29024 }
29025 return a;
29026 };
29027
29028
29029 var __column_selector = function ( settings, selector, opts )
29030 {
29031 var
29032 columns = settings.aoColumns,
29033 names = _pluck( columns, 'sName' ),
29034 nodes = _pluck( columns, 'nTh' );
29035
29036 var run = function ( s ) {
29037 var selInt = _intVal( s );
29038
29039 // Selector - all
29040 if ( s === '' ) {
29041 return _range( columns.length );
29042 }
29043
29044 // Selector - index
29045 if ( selInt !== null ) {
29046 return [ selInt >= 0 ?
29047 selInt : // Count from left
29048 columns.length + selInt // Count from right (+ because its a negative value)
29049 ];
29050 }
29051
29052 // Selector = function
29053 if ( typeof s === 'function' ) {
29054 var rows = _selector_row_indexes( settings, opts );
29055
29056 return $.map( columns, function (col, idx) {
29057 return s(
29058 idx,
29059 __columnData( settings, idx, 0, 0, rows ),
29060 nodes[ idx ]
29061 ) ? idx : null;
29062 } );
29063 }
29064
29065 // jQuery or string selector
29066 var match = typeof s === 'string' ?
29067 s.match( __re_column_selector ) :
29068 '';
29069
29070 if ( match ) {
29071 switch( match[2] ) {
29072 case 'visIdx':
29073 case 'visible':
29074 var idx = parseInt( match[1], 10 );
29075 // Visible index given, convert to column index
29076 if ( idx < 0 ) {
29077 // Counting from the right
29078 var visColumns = $.map( columns, function (col,i) {
29079 return col.bVisible ? i : null;
29080 } );
29081 return [ visColumns[ visColumns.length + idx ] ];
29082 }
29083 // Counting from the left
29084 return [ _fnVisibleToColumnIndex( settings, idx ) ];
29085
29086 case 'name':
29087 // match by name. `names` is column index complete and in order
29088 return $.map( names, function (name, i) {
29089 return name === match[1] ? i : null;
29090 } );
29091
29092 default:
29093 return [];
29094 }
29095 }
29096
29097 // Cell in the table body
29098 if ( s.nodeName && s._DT_CellIndex ) {
29099 return [ s._DT_CellIndex.column ];
29100 }
29101
29102 // jQuery selector on the TH elements for the columns
29103 var jqResult = $( nodes )
29104 .filter( s )
29105 .map( function () {
29106 return $.inArray( this, nodes ); // `nodes` is column index complete and in order
29107 } )
29108 .toArray();
29109
29110 if ( jqResult.length || ! s.nodeName ) {
29111 return jqResult;
29112 }
29113
29114 // Otherwise a node which might have a `dt-column` data attribute, or be
29115 // a child or such an element
29116 var host = $(s).closest('*[data-dt-column]');
29117 return host.length ?
29118 [ host.data('dt-column') ] :
29119 [];
29120 };
29121
29122 return _selector_run( 'column', selector, run, settings, opts );
29123 };
29124
29125
29126 var __setColumnVis = function ( settings, column, vis ) {
29127 var
29128 cols = settings.aoColumns,
29129 col = cols[ column ],
29130 data = settings.aoData,
29131 row, cells, i, ien, tr;
29132
29133 // Get
29134 if ( vis === undefined ) {
29135 return col.bVisible;
29136 }
29137
29138 // Set
29139 // No change
29140 if ( col.bVisible === vis ) {
29141 return;
29142 }
29143
29144 if ( vis ) {
29145 // Insert column
29146 // Need to decide if we should use appendChild or insertBefore
29147 var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
29148
29149 for ( i=0, ien=data.length ; i<ien ; i++ ) {
29150 tr = data[i].nTr;
29151 cells = data[i].anCells;
29152
29153 if ( tr ) {
29154 // insertBefore can act like appendChild if 2nd arg is null
29155 tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
29156 }
29157 }
29158 }
29159 else {
29160 // Remove column
29161 $( _pluck( settings.aoData, 'anCells', column ) ).detach();
29162 }
29163
29164 // Common actions
29165 col.bVisible = vis;
29166 _fnDrawHead( settings, settings.aoHeader );
29167 _fnDrawHead( settings, settings.aoFooter );
29168
29169 _fnSaveState( settings );
29170 };
29171
29172
29173 _api_register( 'columns()', function ( selector, opts ) {
29174 // argument shifting
29175 if ( selector === undefined ) {
29176 selector = '';
29177 }
29178 else if ( $.isPlainObject( selector ) ) {
29179 opts = selector;
29180 selector = '';
29181 }
29182
29183 opts = _selector_opts( opts );
29184
29185 var inst = this.iterator( 'table', function ( settings ) {
29186 return __column_selector( settings, selector, opts );
29187 }, 1 );
29188
29189 // Want argument shifting here and in _row_selector?
29190 inst.selector.cols = selector;
29191 inst.selector.opts = opts;
29192
29193 return inst;
29194 } );
29195
29196 _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
29197 return this.iterator( 'column', function ( settings, column ) {
29198 return settings.aoColumns[column].nTh;
29199 }, 1 );
29200 } );
29201
29202 _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
29203 return this.iterator( 'column', function ( settings, column ) {
29204 return settings.aoColumns[column].nTf;
29205 }, 1 );
29206 } );
29207
29208 _api_registerPlural( 'columns().data()', 'column().data()', function () {
29209 return this.iterator( 'column-rows', __columnData, 1 );
29210 } );
29211
29212 _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
29213 return this.iterator( 'column', function ( settings, column ) {
29214 return settings.aoColumns[column].mData;
29215 }, 1 );
29216 } );
29217
29218 _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
29219 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
29220 return _pluck_order( settings.aoData, rows,
29221 type === 'search' ? '_aFilterData' : '_aSortData', column
29222 );
29223 }, 1 );
29224 } );
29225
29226 _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
29227 return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
29228 return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
29229 }, 1 );
29230 } );
29231
29232 _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
29233 var ret = this.iterator( 'column', function ( settings, column ) {
29234 if ( vis === undefined ) {
29235 return settings.aoColumns[ column ].bVisible;
29236 } // else
29237 __setColumnVis( settings, column, vis );
29238 } );
29239
29240 // Group the column visibility changes
29241 if ( vis !== undefined ) {
29242 // Second loop once the first is done for events
29243 this.iterator( 'column', function ( settings, column ) {
29244 _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
29245 } );
29246
29247 if ( calc === undefined || calc ) {
29248 this.columns.adjust();
29249 }
29250 }
29251
29252 return ret;
29253 } );
29254
29255 _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
29256 return this.iterator( 'column', function ( settings, column ) {
29257 return type === 'visible' ?
29258 _fnColumnIndexToVisible( settings, column ) :
29259 column;
29260 }, 1 );
29261 } );
29262
29263 _api_register( 'columns.adjust()', function () {
29264 return this.iterator( 'table', function ( settings ) {
29265 _fnAdjustColumnSizing( settings );
29266 }, 1 );
29267 } );
29268
29269 _api_register( 'column.index()', function ( type, idx ) {
29270 if ( this.context.length !== 0 ) {
29271 var ctx = this.context[0];
29272
29273 if ( type === 'fromVisible' || type === 'toData' ) {
29274 return _fnVisibleToColumnIndex( ctx, idx );
29275 }
29276 else if ( type === 'fromData' || type === 'toVisible' ) {
29277 return _fnColumnIndexToVisible( ctx, idx );
29278 }
29279 }
29280 } );
29281
29282 _api_register( 'column()', function ( selector, opts ) {
29283 return _selector_first( this.columns( selector, opts ) );
29284 } );
29285
29286
29287
29288 var __cell_selector = function ( settings, selector, opts )
29289 {
29290 var data = settings.aoData;
29291 var rows = _selector_row_indexes( settings, opts );
29292 var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
29293 var allCells = $( [].concat.apply([], cells) );
29294 var row;
29295 var columns = settings.aoColumns.length;
29296 var a, i, ien, j, o, host;
29297
29298 var run = function ( s ) {
29299 var fnSelector = typeof s === 'function';
29300
29301 if ( s === null || s === undefined || fnSelector ) {
29302 // All cells and function selectors
29303 a = [];
29304
29305 for ( i=0, ien=rows.length ; i<ien ; i++ ) {
29306 row = rows[i];
29307
29308 for ( j=0 ; j<columns ; j++ ) {
29309 o = {
29310 row: row,
29311 column: j
29312 };
29313
29314 if ( fnSelector ) {
29315 // Selector - function
29316 host = data[ row ];
29317
29318 if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
29319 a.push( o );
29320 }
29321 }
29322 else {
29323 // Selector - all
29324 a.push( o );
29325 }
29326 }
29327 }
29328
29329 return a;
29330 }
29331
29332 // Selector - index
29333 if ( $.isPlainObject( s ) ) {
29334 return [s];
29335 }
29336
29337 // Selector - jQuery filtered cells
29338 var jqResult = allCells
29339 .filter( s )
29340 .map( function (i, el) {
29341 return { // use a new object, in case someone changes the values
29342 row: el._DT_CellIndex.row,
29343 column: el._DT_CellIndex.column
29344 };
29345 } )
29346 .toArray();
29347
29348 if ( jqResult.length || ! s.nodeName ) {
29349 return jqResult;
29350 }
29351
29352 // Otherwise the selector is a node, and there is one last option - the
29353 // element might be a child of an element which has dt-row and dt-column
29354 // data attributes
29355 host = $(s).closest('*[data-dt-row]');
29356 return host.length ?
29357 [ {
29358 row: host.data('dt-row'),
29359 column: host.data('dt-column')
29360 } ] :
29361 [];
29362 };
29363
29364 return _selector_run( 'cell', selector, run, settings, opts );
29365 };
29366
29367
29368
29369
29370 _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
29371 // Argument shifting
29372 if ( $.isPlainObject( rowSelector ) ) {
29373 // Indexes
29374 if ( rowSelector.row === undefined ) {
29375 // Selector options in first parameter
29376 opts = rowSelector;
29377 rowSelector = null;
29378 }
29379 else {
29380 // Cell index objects in first parameter
29381 opts = columnSelector;
29382 columnSelector = null;
29383 }
29384 }
29385 if ( $.isPlainObject( columnSelector ) ) {
29386 opts = columnSelector;
29387 columnSelector = null;
29388 }
29389
29390 // Cell selector
29391 if ( columnSelector === null || columnSelector === undefined ) {
29392 return this.iterator( 'table', function ( settings ) {
29393 return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
29394 } );
29395 }
29396
29397 // Row + column selector
29398 var columns = this.columns( columnSelector, opts );
29399 var rows = this.rows( rowSelector, opts );
29400 var a, i, ien, j, jen;
29401
29402 var cells = this.iterator( 'table', function ( settings, idx ) {
29403 a = [];
29404
29405 for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
29406 for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
29407 a.push( {
29408 row: rows[idx][i],
29409 column: columns[idx][j]
29410 } );
29411 }
29412 }
29413
29414 return a;
29415 }, 1 );
29416
29417 $.extend( cells.selector, {
29418 cols: columnSelector,
29419 rows: rowSelector,
29420 opts: opts
29421 } );
29422
29423 return cells;
29424 } );
29425
29426
29427 _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
29428 return this.iterator( 'cell', function ( settings, row, column ) {
29429 var data = settings.aoData[ row ];
29430
29431 return data && data.anCells ?
29432 data.anCells[ column ] :
29433 undefined;
29434 }, 1 );
29435 } );
29436
29437
29438 _api_register( 'cells().data()', function () {
29439 return this.iterator( 'cell', function ( settings, row, column ) {
29440 return _fnGetCellData( settings, row, column );
29441 }, 1 );
29442 } );
29443
29444
29445 _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
29446 type = type === 'search' ? '_aFilterData' : '_aSortData';
29447
29448 return this.iterator( 'cell', function ( settings, row, column ) {
29449 return settings.aoData[ row ][ type ][ column ];
29450 }, 1 );
29451 } );
29452
29453
29454 _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
29455 return this.iterator( 'cell', function ( settings, row, column ) {
29456 return _fnGetCellData( settings, row, column, type );
29457 }, 1 );
29458 } );
29459
29460
29461 _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
29462 return this.iterator( 'cell', function ( settings, row, column ) {
29463 return {
29464 row: row,
29465 column: column,
29466 columnVisible: _fnColumnIndexToVisible( settings, column )
29467 };
29468 }, 1 );
29469 } );
29470
29471
29472 _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
29473 return this.iterator( 'cell', function ( settings, row, column ) {
29474 _fnInvalidate( settings, row, src, column );
29475 } );
29476 } );
29477
29478
29479
29480 _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
29481 return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
29482 } );
29483
29484
29485 _api_register( 'cell().data()', function ( data ) {
29486 var ctx = this.context;
29487 var cell = this[0];
29488
29489 if ( data === undefined ) {
29490 // Get
29491 return ctx.length && cell.length ?
29492 _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
29493 undefined;
29494 }
29495
29496 // Set
29497 _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
29498 _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
29499
29500 return this;
29501 } );
29502
29503
29504
29505 /**
29506 * Get current ordering (sorting) that has been applied to the table.
29507 *
29508 * @returns {array} 2D array containing the sorting information for the first
29509 * table in the current context. Each element in the parent array represents
29510 * a column being sorted upon (i.e. multi-sorting with two columns would have
29511 * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
29512 * the column index that the sorting condition applies to, the second is the
29513 * direction of the sort (`desc` or `asc`) and, optionally, the third is the
29514 * index of the sorting order from the `column.sorting` initialisation array.
29515 *//**
29516 * Set the ordering for the table.
29517 *
29518 * @param {integer} order Column index to sort upon.
29519 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
29520 * @returns {DataTables.Api} this
29521 *//**
29522 * Set the ordering for the table.
29523 *
29524 * @param {array} order 1D array of sorting information to be applied.
29525 * @param {array} [...] Optional additional sorting conditions
29526 * @returns {DataTables.Api} this
29527 *//**
29528 * Set the ordering for the table.
29529 *
29530 * @param {array} order 2D array of sorting information to be applied.
29531 * @returns {DataTables.Api} this
29532 */
29533 _api_register( 'order()', function ( order, dir ) {
29534 var ctx = this.context;
29535
29536 if ( order === undefined ) {
29537 // get
29538 return ctx.length !== 0 ?
29539 ctx[0].aaSorting :
29540 undefined;
29541 }
29542
29543 // set
29544 if ( typeof order === 'number' ) {
29545 // Simple column / direction passed in
29546 order = [ [ order, dir ] ];
29547 }
29548 else if ( order.length && ! $.isArray( order[0] ) ) {
29549 // Arguments passed in (list of 1D arrays)
29550 order = Array.prototype.slice.call( arguments );
29551 }
29552 // otherwise a 2D array was passed in
29553
29554 return this.iterator( 'table', function ( settings ) {
29555 settings.aaSorting = order.slice();
29556 } );
29557 } );
29558
29559
29560 /**
29561 * Attach a sort listener to an element for a given column
29562 *
29563 * @param {node|jQuery|string} node Identifier for the element(s) to attach the
29564 * listener to. This can take the form of a single DOM node, a jQuery
29565 * collection of nodes or a jQuery selector which will identify the node(s).
29566 * @param {integer} column the column that a click on this node will sort on
29567 * @param {function} [callback] callback function when sort is run
29568 * @returns {DataTables.Api} this
29569 */
29570 _api_register( 'order.listener()', function ( node, column, callback ) {
29571 return this.iterator( 'table', function ( settings ) {
29572 _fnSortAttachListener( settings, node, column, callback );
29573 } );
29574 } );
29575
29576
29577 _api_register( 'order.fixed()', function ( set ) {
29578 if ( ! set ) {
29579 var ctx = this.context;
29580 var fixed = ctx.length ?
29581 ctx[0].aaSortingFixed :
29582 undefined;
29583
29584 return $.isArray( fixed ) ?
29585 { pre: fixed } :
29586 fixed;
29587 }
29588
29589 return this.iterator( 'table', function ( settings ) {
29590 settings.aaSortingFixed = $.extend( true, {}, set );
29591 } );
29592 } );
29593
29594
29595 // Order by the selected column(s)
29596 _api_register( [
29597 'columns().order()',
29598 'column().order()'
29599 ], function ( dir ) {
29600 var that = this;
29601
29602 return this.iterator( 'table', function ( settings, i ) {
29603 var sort = [];
29604
29605 $.each( that[i], function (j, col) {
29606 sort.push( [ col, dir ] );
29607 } );
29608
29609 settings.aaSorting = sort;
29610 } );
29611 } );
29612
29613
29614
29615 _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
29616 var ctx = this.context;
29617
29618 if ( input === undefined ) {
29619 // get
29620 return ctx.length !== 0 ?
29621 ctx[0].oPreviousSearch.sSearch :
29622 undefined;
29623 }
29624
29625 // set
29626 return this.iterator( 'table', function ( settings ) {
29627 if ( ! settings.oFeatures.bFilter ) {
29628 return;
29629 }
29630
29631 _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
29632 "sSearch": input+"",
29633 "bRegex": regex === null ? false : regex,
29634 "bSmart": smart === null ? true : smart,
29635 "bCaseInsensitive": caseInsen === null ? true : caseInsen
29636 } ), 1 );
29637 } );
29638 } );
29639
29640
29641 _api_registerPlural(
29642 'columns().search()',
29643 'column().search()',
29644 function ( input, regex, smart, caseInsen ) {
29645 return this.iterator( 'column', function ( settings, column ) {
29646 var preSearch = settings.aoPreSearchCols;
29647
29648 if ( input === undefined ) {
29649 // get
29650 return preSearch[ column ].sSearch;
29651 }
29652
29653 // set
29654 if ( ! settings.oFeatures.bFilter ) {
29655 return;
29656 }
29657
29658 $.extend( preSearch[ column ], {
29659 "sSearch": input+"",
29660 "bRegex": regex === null ? false : regex,
29661 "bSmart": smart === null ? true : smart,
29662 "bCaseInsensitive": caseInsen === null ? true : caseInsen
29663 } );
29664
29665 _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
29666 } );
29667 }
29668 );
29669
29670 /*
29671 * State API methods
29672 */
29673
29674 _api_register( 'state()', function () {
29675 return this.context.length ?
29676 this.context[0].oSavedState :
29677 null;
29678 } );
29679
29680
29681 _api_register( 'state.clear()', function () {
29682 return this.iterator( 'table', function ( settings ) {
29683 // Save an empty object
29684 settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
29685 } );
29686 } );
29687
29688
29689 _api_register( 'state.loaded()', function () {
29690 return this.context.length ?
29691 this.context[0].oLoadedState :
29692 null;
29693 } );
29694
29695
29696 _api_register( 'state.save()', function () {
29697 return this.iterator( 'table', function ( settings ) {
29698 _fnSaveState( settings );
29699 } );
29700 } );
29701
29702
29703
29704 /**
29705 * Provide a common method for plug-ins to check the version of DataTables being
29706 * used, in order to ensure compatibility.
29707 *
29708 * @param {string} version Version string to check for, in the format "X.Y.Z".
29709 * Note that the formats "X" and "X.Y" are also acceptable.
29710 * @returns {boolean} true if this version of DataTables is greater or equal to
29711 * the required version, or false if this version of DataTales is not
29712 * suitable
29713 * @static
29714 * @dtopt API-Static
29715 *
29716 * @example
29717 * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
29718 */
29719 DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
29720 {
29721 var aThis = DataTable.version.split('.');
29722 var aThat = version.split('.');
29723 var iThis, iThat;
29724
29725 for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
29726 iThis = parseInt( aThis[i], 10 ) || 0;
29727 iThat = parseInt( aThat[i], 10 ) || 0;
29728
29729 // Parts are the same, keep comparing
29730 if (iThis === iThat) {
29731 continue;
29732 }
29733
29734 // Parts are different, return immediately
29735 return iThis > iThat;
29736 }
29737
29738 return true;
29739 };
29740
29741
29742 /**
29743 * Check if a `<table>` node is a DataTable table already or not.
29744 *
29745 * @param {node|jquery|string} table Table node, jQuery object or jQuery
29746 * selector for the table to test. Note that if more than more than one
29747 * table is passed on, only the first will be checked
29748 * @returns {boolean} true the table given is a DataTable, or false otherwise
29749 * @static
29750 * @dtopt API-Static
29751 *
29752 * @example
29753 * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
29754 * $('#example').dataTable();
29755 * }
29756 */
29757 DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
29758 {
29759 var t = $(table).get(0);
29760 var is = false;
29761
29762 $.each( DataTable.settings, function (i, o) {
29763 var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
29764 var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
29765
29766 if ( o.nTable === t || head === t || foot === t ) {
29767 is = true;
29768 }
29769 } );
29770
29771 return is;
29772 };
29773
29774
29775 /**
29776 * Get all DataTable tables that have been initialised - optionally you can
29777 * select to get only currently visible tables.
29778 *
29779 * @param {boolean} [visible=false] Flag to indicate if you want all (default)
29780 * or visible tables only.
29781 * @returns {array} Array of `table` nodes (not DataTable instances) which are
29782 * DataTables
29783 * @static
29784 * @dtopt API-Static
29785 *
29786 * @example
29787 * $.each( $.fn.dataTable.tables(true), function () {
29788 * $(table).DataTable().columns.adjust();
29789 * } );
29790 */
29791 DataTable.tables = DataTable.fnTables = function ( visible )
29792 {
29793 var api = false;
29794
29795 if ( $.isPlainObject( visible ) ) {
29796 api = visible.api;
29797 visible = visible.visible;
29798 }
29799
29800 var a = $.map( DataTable.settings, function (o) {
29801 if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
29802 return o.nTable;
29803 }
29804 } );
29805
29806 return api ?
29807 new _Api( a ) :
29808 a;
29809 };
29810
29811
29812 /**
29813 * Convert from camel case parameters to Hungarian notation. This is made public
29814 * for the extensions to provide the same ability as DataTables core to accept
29815 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
29816 * parameters.
29817 *
29818 * @param {object} src The model object which holds all parameters that can be
29819 * mapped.
29820 * @param {object} user The object to convert from camel case to Hungarian.
29821 * @param {boolean} force When set to `true`, properties which already have a
29822 * Hungarian value in the `user` object will be overwritten. Otherwise they
29823 * won't be.
29824 */
29825 DataTable.camelToHungarian = _fnCamelToHungarian;
29826
29827
29828
29829 /**
29830 *
29831 */
29832 _api_register( '$()', function ( selector, opts ) {
29833 var
29834 rows = this.rows( opts ).nodes(), // Get all rows
29835 jqRows = $(rows);
29836
29837 return $( [].concat(
29838 jqRows.filter( selector ).toArray(),
29839 jqRows.find( selector ).toArray()
29840 ) );
29841 } );
29842
29843
29844 // jQuery functions to operate on the tables
29845 $.each( [ 'on', 'one', 'off' ], function (i, key) {
29846 _api_register( key+'()', function ( /* event, handler */ ) {
29847 var args = Array.prototype.slice.call(arguments);
29848
29849 // Add the `dt` namespace automatically if it isn't already present
29850 if ( ! args[0].match(/\.dt\b/) ) {
29851 args[0] += '.dt';
29852 }
29853
29854 var inst = $( this.tables().nodes() );
29855 inst[key].apply( inst, args );
29856 return this;
29857 } );
29858 } );
29859
29860
29861 _api_register( 'clear()', function () {
29862 return this.iterator( 'table', function ( settings ) {
29863 _fnClearTable( settings );
29864 } );
29865 } );
29866
29867
29868 _api_register( 'settings()', function () {
29869 return new _Api( this.context, this.context );
29870 } );
29871
29872
29873 _api_register( 'init()', function () {
29874 var ctx = this.context;
29875 return ctx.length ? ctx[0].oInit : null;
29876 } );
29877
29878
29879 _api_register( 'data()', function () {
29880 return this.iterator( 'table', function ( settings ) {
29881 return _pluck( settings.aoData, '_aData' );
29882 } ).flatten();
29883 } );
29884
29885
29886 _api_register( 'destroy()', function ( remove ) {
29887 remove = remove || false;
29888
29889 return this.iterator( 'table', function ( settings ) {
29890 var orig = settings.nTableWrapper.parentNode;
29891 var classes = settings.oClasses;
29892 var table = settings.nTable;
29893 var tbody = settings.nTBody;
29894 var thead = settings.nTHead;
29895 var tfoot = settings.nTFoot;
29896 var jqTable = $(table);
29897 var jqTbody = $(tbody);
29898 var jqWrapper = $(settings.nTableWrapper);
29899 var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
29900 var i, ien;
29901
29902 // Flag to note that the table is currently being destroyed - no action
29903 // should be taken
29904 settings.bDestroying = true;
29905
29906 // Fire off the destroy callbacks for plug-ins etc
29907 _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
29908
29909 // If not being removed from the document, make all columns visible
29910 if ( ! remove ) {
29911 new _Api( settings ).columns().visible( true );
29912 }
29913
29914 // Blitz all `DT` namespaced events (these are internal events, the
29915 // lowercase, `dt` events are user subscribed and they are responsible
29916 // for removing them
29917 jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
29918 $(window).unbind('.DT-'+settings.sInstance);
29919
29920 // When scrolling we had to break the table up - restore it
29921 if ( table != thead.parentNode ) {
29922 jqTable.children('thead').detach();
29923 jqTable.append( thead );
29924 }
29925
29926 if ( tfoot && table != tfoot.parentNode ) {
29927 jqTable.children('tfoot').detach();
29928 jqTable.append( tfoot );
29929 }
29930
29931 settings.aaSorting = [];
29932 settings.aaSortingFixed = [];
29933 _fnSortingClasses( settings );
29934
29935 $( rows ).removeClass( settings.asStripeClasses.join(' ') );
29936
29937 $('th, td', thead).removeClass( classes.sSortable+' '+
29938 classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
29939 );
29940
29941 if ( settings.bJUI ) {
29942 $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
29943 $('th, td', thead).each( function () {
29944 var wrapper = $('div.'+classes.sSortJUIWrapper, this);
29945 $(this).append( wrapper.contents() );
29946 wrapper.detach();
29947 } );
29948 }
29949
29950 // Add the TR elements back into the table in their original order
29951 jqTbody.children().detach();
29952 jqTbody.append( rows );
29953
29954 // Remove the DataTables generated nodes, events and classes
29955 var removedMethod = remove ? 'remove' : 'detach';
29956 jqTable[ removedMethod ]();
29957 jqWrapper[ removedMethod ]();
29958
29959 // If we need to reattach the table to the document
29960 if ( ! remove && orig ) {
29961 // insertBefore acts like appendChild if !arg[1]
29962 orig.insertBefore( table, settings.nTableReinsertBefore );
29963
29964 // Restore the width of the original table - was read from the style property,
29965 // so we can restore directly to that
29966 jqTable
29967 .css( 'width', settings.sDestroyWidth )
29968 .removeClass( classes.sTable );
29969
29970 // If the were originally stripe classes - then we add them back here.
29971 // Note this is not fool proof (for example if not all rows had stripe
29972 // classes - but it's a good effort without getting carried away
29973 ien = settings.asDestroyStripes.length;
29974
29975 if ( ien ) {
29976 jqTbody.children().each( function (i) {
29977 $(this).addClass( settings.asDestroyStripes[i % ien] );
29978 } );
29979 }
29980 }
29981
29982 /* Remove the settings object from the settings array */
29983 var idx = $.inArray( settings, DataTable.settings );
29984 if ( idx !== -1 ) {
29985 DataTable.settings.splice( idx, 1 );
29986 }
29987 } );
29988 } );
29989
29990
29991 // Add the `every()` method for rows, columns and cells in a compact form
29992 $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
29993 _api_register( type+'s().every()', function ( fn ) {
29994 var opts = this.selector.opts;
29995 var api = this;
29996
29997 return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
29998 // Rows and columns:
29999 // arg1 - index
30000 // arg2 - table counter
30001 // arg3 - loop counter
30002 // arg4 - undefined
30003 // Cells:
30004 // arg1 - row index
30005 // arg2 - column index
30006 // arg3 - table counter
30007 // arg4 - loop counter
30008 fn.call(
30009 api[ type ](
30010 arg1,
30011 type==='cell' ? arg2 : opts,
30012 type==='cell' ? opts : undefined
30013 ),
30014 arg1, arg2, arg3, arg4
30015 );
30016 } );
30017 } );
30018 } );
30019
30020
30021 // i18n method for extensions to be able to use the language object from the
30022 // DataTable
30023 _api_register( 'i18n()', function ( token, def, plural ) {
30024 var ctx = this.context[0];
30025 var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
30026
30027 if ( resolved === undefined ) {
30028 resolved = def;
30029 }
30030
30031 if ( plural !== undefined && $.isPlainObject( resolved ) ) {
30032 resolved = resolved[ plural ] !== undefined ?
30033 resolved[ plural ] :
30034 resolved._;
30035 }
30036
30037 return resolved.replace( '%d', plural ); // nb: plural might be undefined,
30038 } );
30039 /**
30040 * Version string for plug-ins to check compatibility. Allowed format is
30041 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
30042 * only for non-release builds. See http://semver.org/ for more information.
30043 * @member
30044 * @type string
30045 * @default Version number
30046 */
30047 DataTable.version = "1.10.12";
30048
30049 /**
30050 * Private data store, containing all of the settings objects that are
30051 * created for the tables on a given page.
30052 *
30053 * Note that the `DataTable.settings` object is aliased to
30054 * `jQuery.fn.dataTableExt` through which it may be accessed and
30055 * manipulated, or `jQuery.fn.dataTable.settings`.
30056 * @member
30057 * @type array
30058 * @default []
30059 * @private
30060 */
30061 DataTable.settings = [];
30062
30063 /**
30064 * Object models container, for the various models that DataTables has
30065 * available to it. These models define the objects that are used to hold
30066 * the active state and configuration of the table.
30067 * @namespace
30068 */
30069 DataTable.models = {};
30070
30071
30072
30073 /**
30074 * Template object for the way in which DataTables holds information about
30075 * search information for the global filter and individual column filters.
30076 * @namespace
30077 */
30078 DataTable.models.oSearch = {
30079 /**
30080 * Flag to indicate if the filtering should be case insensitive or not
30081 * @type boolean
30082 * @default true
30083 */
30084 "bCaseInsensitive": true,
30085
30086 /**
30087 * Applied search term
30088 * @type string
30089 * @default <i>Empty string</i>
30090 */
30091 "sSearch": "",
30092
30093 /**
30094 * Flag to indicate if the search term should be interpreted as a
30095 * regular expression (true) or not (false) and therefore and special
30096 * regex characters escaped.
30097 * @type boolean
30098 * @default false
30099 */
30100 "bRegex": false,
30101
30102 /**
30103 * Flag to indicate if DataTables is to use its smart filtering or not.
30104 * @type boolean
30105 * @default true
30106 */
30107 "bSmart": true
30108 };
30109
30110
30111
30112
30113 /**
30114 * Template object for the way in which DataTables holds information about
30115 * each individual row. This is the object format used for the settings
30116 * aoData array.
30117 * @namespace
30118 */
30119 DataTable.models.oRow = {
30120 /**
30121 * TR element for the row
30122 * @type node
30123 * @default null
30124 */
30125 "nTr": null,
30126
30127 /**
30128 * Array of TD elements for each row. This is null until the row has been
30129 * created.
30130 * @type array nodes
30131 * @default []
30132 */
30133 "anCells": null,
30134
30135 /**
30136 * Data object from the original data source for the row. This is either
30137 * an array if using the traditional form of DataTables, or an object if
30138 * using mData options. The exact type will depend on the passed in
30139 * data from the data source, or will be an array if using DOM a data
30140 * source.
30141 * @type array|object
30142 * @default []
30143 */
30144 "_aData": [],
30145
30146 /**
30147 * Sorting data cache - this array is ostensibly the same length as the
30148 * number of columns (although each index is generated only as it is
30149 * needed), and holds the data that is used for sorting each column in the
30150 * row. We do this cache generation at the start of the sort in order that
30151 * the formatting of the sort data need be done only once for each cell
30152 * per sort. This array should not be read from or written to by anything
30153 * other than the master sorting methods.
30154 * @type array
30155 * @default null
30156 * @private
30157 */
30158 "_aSortData": null,
30159
30160 /**
30161 * Per cell filtering data cache. As per the sort data cache, used to
30162 * increase the performance of the filtering in DataTables
30163 * @type array
30164 * @default null
30165 * @private
30166 */
30167 "_aFilterData": null,
30168
30169 /**
30170 * Filtering data cache. This is the same as the cell filtering cache, but
30171 * in this case a string rather than an array. This is easily computed with
30172 * a join on `_aFilterData`, but is provided as a cache so the join isn't
30173 * needed on every search (memory traded for performance)
30174 * @type array
30175 * @default null
30176 * @private
30177 */
30178 "_sFilterRow": null,
30179
30180 /**
30181 * Cache of the class name that DataTables has applied to the row, so we
30182 * can quickly look at this variable rather than needing to do a DOM check
30183 * on className for the nTr property.
30184 * @type string
30185 * @default <i>Empty string</i>
30186 * @private
30187 */
30188 "_sRowStripe": "",
30189
30190 /**
30191 * Denote if the original data source was from the DOM, or the data source
30192 * object. This is used for invalidating data, so DataTables can
30193 * automatically read data from the original source, unless uninstructed
30194 * otherwise.
30195 * @type string
30196 * @default null
30197 * @private
30198 */
30199 "src": null,
30200
30201 /**
30202 * Index in the aoData array. This saves an indexOf lookup when we have the
30203 * object, but want to know the index
30204 * @type integer
30205 * @default -1
30206 * @private
30207 */
30208 "idx": -1
30209 };
30210
30211
30212 /**
30213 * Template object for the column information object in DataTables. This object
30214 * is held in the settings aoColumns array and contains all the information that
30215 * DataTables needs about each individual column.
30216 *
30217 * Note that this object is related to {@link DataTable.defaults.column}
30218 * but this one is the internal data store for DataTables's cache of columns.
30219 * It should NOT be manipulated outside of DataTables. Any configuration should
30220 * be done through the initialisation options.
30221 * @namespace
30222 */
30223 DataTable.models.oColumn = {
30224 /**
30225 * Column index. This could be worked out on-the-fly with $.inArray, but it
30226 * is faster to just hold it as a variable
30227 * @type integer
30228 * @default null
30229 */
30230 "idx": null,
30231
30232 /**
30233 * A list of the columns that sorting should occur on when this column
30234 * is sorted. That this property is an array allows multi-column sorting
30235 * to be defined for a column (for example first name / last name columns
30236 * would benefit from this). The values are integers pointing to the
30237 * columns to be sorted on (typically it will be a single integer pointing
30238 * at itself, but that doesn't need to be the case).
30239 * @type array
30240 */
30241 "aDataSort": null,
30242
30243 /**
30244 * Define the sorting directions that are applied to the column, in sequence
30245 * as the column is repeatedly sorted upon - i.e. the first value is used
30246 * as the sorting direction when the column if first sorted (clicked on).
30247 * Sort it again (click again) and it will move on to the next index.
30248 * Repeat until loop.
30249 * @type array
30250 */
30251 "asSorting": null,
30252
30253 /**
30254 * Flag to indicate if the column is searchable, and thus should be included
30255 * in the filtering or not.
30256 * @type boolean
30257 */
30258 "bSearchable": null,
30259
30260 /**
30261 * Flag to indicate if the column is sortable or not.
30262 * @type boolean
30263 */
30264 "bSortable": null,
30265
30266 /**
30267 * Flag to indicate if the column is currently visible in the table or not
30268 * @type boolean
30269 */
30270 "bVisible": null,
30271
30272 /**
30273 * Store for manual type assignment using the `column.type` option. This
30274 * is held in store so we can manipulate the column's `sType` property.
30275 * @type string
30276 * @default null
30277 * @private
30278 */
30279 "_sManualType": null,
30280
30281 /**
30282 * Flag to indicate if HTML5 data attributes should be used as the data
30283 * source for filtering or sorting. True is either are.
30284 * @type boolean
30285 * @default false
30286 * @private
30287 */
30288 "_bAttrSrc": false,
30289
30290 /**
30291 * Developer definable function that is called whenever a cell is created (Ajax source,
30292 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
30293 * allowing you to modify the DOM element (add background colour for example) when the
30294 * element is available.
30295 * @type function
30296 * @param {element} nTd The TD node that has been created
30297 * @param {*} sData The Data for the cell
30298 * @param {array|object} oData The data for the whole row
30299 * @param {int} iRow The row index for the aoData data store
30300 * @default null
30301 */
30302 "fnCreatedCell": null,
30303
30304 /**
30305 * Function to get data from a cell in a column. You should <b>never</b>
30306 * access data directly through _aData internally in DataTables - always use
30307 * the method attached to this property. It allows mData to function as
30308 * required. This function is automatically assigned by the column
30309 * initialisation method
30310 * @type function
30311 * @param {array|object} oData The data array/object for the array
30312 * (i.e. aoData[]._aData)
30313 * @param {string} sSpecific The specific data type you want to get -
30314 * 'display', 'type' 'filter' 'sort'
30315 * @returns {*} The data for the cell from the given row's data
30316 * @default null
30317 */
30318 "fnGetData": null,
30319
30320 /**
30321 * Function to set data for a cell in the column. You should <b>never</b>
30322 * set the data directly to _aData internally in DataTables - always use
30323 * this method. It allows mData to function as required. This function
30324 * is automatically assigned by the column initialisation method
30325 * @type function
30326 * @param {array|object} oData The data array/object for the array
30327 * (i.e. aoData[]._aData)
30328 * @param {*} sValue Value to set
30329 * @default null
30330 */
30331 "fnSetData": null,
30332
30333 /**
30334 * Property to read the value for the cells in the column from the data
30335 * source array / object. If null, then the default content is used, if a
30336 * function is given then the return from the function is used.
30337 * @type function|int|string|null
30338 * @default null
30339 */
30340 "mData": null,
30341
30342 /**
30343 * Partner property to mData which is used (only when defined) to get
30344 * the data - i.e. it is basically the same as mData, but without the
30345 * 'set' option, and also the data fed to it is the result from mData.
30346 * This is the rendering method to match the data method of mData.
30347 * @type function|int|string|null
30348 * @default null
30349 */
30350 "mRender": null,
30351
30352 /**
30353 * Unique header TH/TD element for this column - this is what the sorting
30354 * listener is attached to (if sorting is enabled.)
30355 * @type node
30356 * @default null
30357 */
30358 "nTh": null,
30359
30360 /**
30361 * Unique footer TH/TD element for this column (if there is one). Not used
30362 * in DataTables as such, but can be used for plug-ins to reference the
30363 * footer for each column.
30364 * @type node
30365 * @default null
30366 */
30367 "nTf": null,
30368
30369 /**
30370 * The class to apply to all TD elements in the table's TBODY for the column
30371 * @type string
30372 * @default null
30373 */
30374 "sClass": null,
30375
30376 /**
30377 * When DataTables calculates the column widths to assign to each column,
30378 * it finds the longest string in each column and then constructs a
30379 * temporary table and reads the widths from that. The problem with this
30380 * is that "mmm" is much wider then "iiii", but the latter is a longer
30381 * string - thus the calculation can go wrong (doing it properly and putting
30382 * it into an DOM object and measuring that is horribly(!) slow). Thus as
30383 * a "work around" we provide this option. It will append its value to the
30384 * text that is found to be the longest string for the column - i.e. padding.
30385 * @type string
30386 */
30387 "sContentPadding": null,
30388
30389 /**
30390 * Allows a default value to be given for a column's data, and will be used
30391 * whenever a null data source is encountered (this can be because mData
30392 * is set to null, or because the data source itself is null).
30393 * @type string
30394 * @default null
30395 */
30396 "sDefaultContent": null,
30397
30398 /**
30399 * Name for the column, allowing reference to the column by name as well as
30400 * by index (needs a lookup to work by name).
30401 * @type string
30402 */
30403 "sName": null,
30404
30405 /**
30406 * Custom sorting data type - defines which of the available plug-ins in
30407 * afnSortData the custom sorting will use - if any is defined.
30408 * @type string
30409 * @default std
30410 */
30411 "sSortDataType": 'std',
30412
30413 /**
30414 * Class to be applied to the header element when sorting on this column
30415 * @type string
30416 * @default null
30417 */
30418 "sSortingClass": null,
30419
30420 /**
30421 * Class to be applied to the header element when sorting on this column -
30422 * when jQuery UI theming is used.
30423 * @type string
30424 * @default null
30425 */
30426 "sSortingClassJUI": null,
30427
30428 /**
30429 * Title of the column - what is seen in the TH element (nTh).
30430 * @type string
30431 */
30432 "sTitle": null,
30433
30434 /**
30435 * Column sorting and filtering type
30436 * @type string
30437 * @default null
30438 */
30439 "sType": null,
30440
30441 /**
30442 * Width of the column
30443 * @type string
30444 * @default null
30445 */
30446 "sWidth": null,
30447
30448 /**
30449 * Width of the column when it was first "encountered"
30450 * @type string
30451 * @default null
30452 */
30453 "sWidthOrig": null
30454 };
30455
30456
30457 /*
30458 * Developer note: The properties of the object below are given in Hungarian
30459 * notation, that was used as the interface for DataTables prior to v1.10, however
30460 * from v1.10 onwards the primary interface is camel case. In order to avoid
30461 * breaking backwards compatibility utterly with this change, the Hungarian
30462 * version is still, internally the primary interface, but is is not documented
30463 * - hence the @name tags in each doc comment. This allows a Javascript function
30464 * to create a map from Hungarian notation to camel case (going the other direction
30465 * would require each property to be listed, which would at around 3K to the size
30466 * of DataTables, while this method is about a 0.5K hit.
30467 *
30468 * Ultimately this does pave the way for Hungarian notation to be dropped
30469 * completely, but that is a massive amount of work and will break current
30470 * installs (therefore is on-hold until v2).
30471 */
30472
30473 /**
30474 * Initialisation options that can be given to DataTables at initialisation
30475 * time.
30476 * @namespace
30477 */
30478 DataTable.defaults = {
30479 /**
30480 * An array of data to use for the table, passed in at initialisation which
30481 * will be used in preference to any data which is already in the DOM. This is
30482 * particularly useful for constructing tables purely in Javascript, for
30483 * example with a custom Ajax call.
30484 * @type array
30485 * @default null
30486 *
30487 * @dtopt Option
30488 * @name DataTable.defaults.data
30489 *
30490 * @example
30491 * // Using a 2D array data source
30492 * $(document).ready( function () {
30493 * $('#example').dataTable( {
30494 * "data": [
30495 * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
30496 * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
30497 * ],
30498 * "columns": [
30499 * { "title": "Engine" },
30500 * { "title": "Browser" },
30501 * { "title": "Platform" },
30502 * { "title": "Version" },
30503 * { "title": "Grade" }
30504 * ]
30505 * } );
30506 * } );
30507 *
30508 * @example
30509 * // Using an array of objects as a data source (`data`)
30510 * $(document).ready( function () {
30511 * $('#example').dataTable( {
30512 * "data": [
30513 * {
30514 * "engine": "Trident",
30515 * "browser": "Internet Explorer 4.0",
30516 * "platform": "Win 95+",
30517 * "version": 4,
30518 * "grade": "X"
30519 * },
30520 * {
30521 * "engine": "Trident",
30522 * "browser": "Internet Explorer 5.0",
30523 * "platform": "Win 95+",
30524 * "version": 5,
30525 * "grade": "C"
30526 * }
30527 * ],
30528 * "columns": [
30529 * { "title": "Engine", "data": "engine" },
30530 * { "title": "Browser", "data": "browser" },
30531 * { "title": "Platform", "data": "platform" },
30532 * { "title": "Version", "data": "version" },
30533 * { "title": "Grade", "data": "grade" }
30534 * ]
30535 * } );
30536 * } );
30537 */
30538 "aaData": null,
30539
30540
30541 /**
30542 * If ordering is enabled, then DataTables will perform a first pass sort on
30543 * initialisation. You can define which column(s) the sort is performed
30544 * upon, and the sorting direction, with this variable. The `sorting` array
30545 * should contain an array for each column to be sorted initially containing
30546 * the column's index and a direction string ('asc' or 'desc').
30547 * @type array
30548 * @default [[0,'asc']]
30549 *
30550 * @dtopt Option
30551 * @name DataTable.defaults.order
30552 *
30553 * @example
30554 * // Sort by 3rd column first, and then 4th column
30555 * $(document).ready( function() {
30556 * $('#example').dataTable( {
30557 * "order": [[2,'asc'], [3,'desc']]
30558 * } );
30559 * } );
30560 *
30561 * // No initial sorting
30562 * $(document).ready( function() {
30563 * $('#example').dataTable( {
30564 * "order": []
30565 * } );
30566 * } );
30567 */
30568 "aaSorting": [[0,'asc']],
30569
30570
30571 /**
30572 * This parameter is basically identical to the `sorting` parameter, but
30573 * cannot be overridden by user interaction with the table. What this means
30574 * is that you could have a column (visible or hidden) which the sorting
30575 * will always be forced on first - any sorting after that (from the user)
30576 * will then be performed as required. This can be useful for grouping rows
30577 * together.
30578 * @type array
30579 * @default null
30580 *
30581 * @dtopt Option
30582 * @name DataTable.defaults.orderFixed
30583 *
30584 * @example
30585 * $(document).ready( function() {
30586 * $('#example').dataTable( {
30587 * "orderFixed": [[0,'asc']]
30588 * } );
30589 * } )
30590 */
30591 "aaSortingFixed": [],
30592
30593
30594 /**
30595 * DataTables can be instructed to load data to display in the table from a
30596 * Ajax source. This option defines how that Ajax call is made and where to.
30597 *
30598 * The `ajax` property has three different modes of operation, depending on
30599 * how it is defined. These are:
30600 *
30601 * * `string` - Set the URL from where the data should be loaded from.
30602 * * `object` - Define properties for `jQuery.ajax`.
30603 * * `function` - Custom data get function
30604 *
30605 * `string`
30606 * --------
30607 *
30608 * As a string, the `ajax` property simply defines the URL from which
30609 * DataTables will load data.
30610 *
30611 * `object`
30612 * --------
30613 *
30614 * As an object, the parameters in the object are passed to
30615 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
30616 * of the Ajax request. DataTables has a number of default parameters which
30617 * you can override using this option. Please refer to the jQuery
30618 * documentation for a full description of the options available, although
30619 * the following parameters provide additional options in DataTables or
30620 * require special consideration:
30621 *
30622 * * `data` - As with jQuery, `data` can be provided as an object, but it
30623 * can also be used as a function to manipulate the data DataTables sends
30624 * to the server. The function takes a single parameter, an object of
30625 * parameters with the values that DataTables has readied for sending. An
30626 * object may be returned which will be merged into the DataTables
30627 * defaults, or you can add the items to the object that was passed in and
30628 * not return anything from the function. This supersedes `fnServerParams`
30629 * from DataTables 1.9-.
30630 *
30631 * * `dataSrc` - By default DataTables will look for the property `data` (or
30632 * `aaData` for compatibility with DataTables 1.9-) when obtaining data
30633 * from an Ajax source or for server-side processing - this parameter
30634 * allows that property to be changed. You can use Javascript dotted
30635 * object notation to get a data source for multiple levels of nesting, or
30636 * it my be used as a function. As a function it takes a single parameter,
30637 * the JSON returned from the server, which can be manipulated as
30638 * required, with the returned value being that used by DataTables as the
30639 * data source for the table. This supersedes `sAjaxDataProp` from
30640 * DataTables 1.9-.
30641 *
30642 * * `success` - Should not be overridden it is used internally in
30643 * DataTables. To manipulate / transform the data returned by the server
30644 * use `ajax.dataSrc`, or use `ajax` as a function (see below).
30645 *
30646 * `function`
30647 * ----------
30648 *
30649 * As a function, making the Ajax call is left up to yourself allowing
30650 * complete control of the Ajax request. Indeed, if desired, a method other
30651 * than Ajax could be used to obtain the required data, such as Web storage
30652 * or an AIR database.
30653 *
30654 * The function is given four parameters and no return is required. The
30655 * parameters are:
30656 *
30657 * 1. _object_ - Data to send to the server
30658 * 2. _function_ - Callback function that must be executed when the required
30659 * data has been obtained. That data should be passed into the callback
30660 * as the only parameter
30661 * 3. _object_ - DataTables settings object for the table
30662 *
30663 * Note that this supersedes `fnServerData` from DataTables 1.9-.
30664 *
30665 * @type string|object|function
30666 * @default null
30667 *
30668 * @dtopt Option
30669 * @name DataTable.defaults.ajax
30670 * @since 1.10.0
30671 *
30672 * @example
30673 * // Get JSON data from a file via Ajax.
30674 * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
30675 * $('#example').dataTable( {
30676 * "ajax": "data.json"
30677 * } );
30678 *
30679 * @example
30680 * // Get JSON data from a file via Ajax, using `dataSrc` to change
30681 * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
30682 * $('#example').dataTable( {
30683 * "ajax": {
30684 * "url": "data.json",
30685 * "dataSrc": "tableData"
30686 * }
30687 * } );
30688 *
30689 * @example
30690 * // Get JSON data from a file via Ajax, using `dataSrc` to read data
30691 * // from a plain array rather than an array in an object
30692 * $('#example').dataTable( {
30693 * "ajax": {
30694 * "url": "data.json",
30695 * "dataSrc": ""
30696 * }
30697 * } );
30698 *
30699 * @example
30700 * // Manipulate the data returned from the server - add a link to data
30701 * // (note this can, should, be done using `render` for the column - this
30702 * // is just a simple example of how the data can be manipulated).
30703 * $('#example').dataTable( {
30704 * "ajax": {
30705 * "url": "data.json",
30706 * "dataSrc": function ( json ) {
30707 * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
30708 * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
30709 * }
30710 * return json;
30711 * }
30712 * }
30713 * } );
30714 *
30715 * @example
30716 * // Add data to the request
30717 * $('#example').dataTable( {
30718 * "ajax": {
30719 * "url": "data.json",
30720 * "data": function ( d ) {
30721 * return {
30722 * "extra_search": $('#extra').val()
30723 * };
30724 * }
30725 * }
30726 * } );
30727 *
30728 * @example
30729 * // Send request as POST
30730 * $('#example').dataTable( {
30731 * "ajax": {
30732 * "url": "data.json",
30733 * "type": "POST"
30734 * }
30735 * } );
30736 *
30737 * @example
30738 * // Get the data from localStorage (could interface with a form for
30739 * // adding, editing and removing rows).
30740 * $('#example').dataTable( {
30741 * "ajax": function (data, callback, settings) {
30742 * callback(
30743 * JSON.parse( localStorage.getItem('dataTablesData') )
30744 * );
30745 * }
30746 * } );
30747 */
30748 "ajax": null,
30749
30750
30751 /**
30752 * This parameter allows you to readily specify the entries in the length drop
30753 * down menu that DataTables shows when pagination is enabled. It can be
30754 * either a 1D array of options which will be used for both the displayed
30755 * option and the value, or a 2D array which will use the array in the first
30756 * position as the value, and the array in the second position as the
30757 * displayed options (useful for language strings such as 'All').
30758 *
30759 * Note that the `pageLength` property will be automatically set to the
30760 * first value given in this array, unless `pageLength` is also provided.
30761 * @type array
30762 * @default [ 10, 25, 50, 100 ]
30763 *
30764 * @dtopt Option
30765 * @name DataTable.defaults.lengthMenu
30766 *
30767 * @example
30768 * $(document).ready( function() {
30769 * $('#example').dataTable( {
30770 * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
30771 * } );
30772 * } );
30773 */
30774 "aLengthMenu": [ 10, 25, 50, 100 ],
30775
30776
30777 /**
30778 * The `columns` option in the initialisation parameter allows you to define
30779 * details about the way individual columns behave. For a full list of
30780 * column options that can be set, please see
30781 * {@link DataTable.defaults.column}. Note that if you use `columns` to
30782 * define your columns, you must have an entry in the array for every single
30783 * column that you have in your table (these can be null if you don't which
30784 * to specify any options).
30785 * @member
30786 *
30787 * @name DataTable.defaults.column
30788 */
30789 "aoColumns": null,
30790
30791 /**
30792 * Very similar to `columns`, `columnDefs` allows you to target a specific
30793 * column, multiple columns, or all columns, using the `targets` property of
30794 * each object in the array. This allows great flexibility when creating
30795 * tables, as the `columnDefs` arrays can be of any length, targeting the
30796 * columns you specifically want. `columnDefs` may use any of the column
30797 * options available: {@link DataTable.defaults.column}, but it _must_
30798 * have `targets` defined in each object in the array. Values in the `targets`
30799 * array may be:
30800 * <ul>
30801 * <li>a string - class name will be matched on the TH for the column</li>
30802 * <li>0 or a positive integer - column index counting from the left</li>
30803 * <li>a negative integer - column index counting from the right</li>
30804 * <li>the string "_all" - all columns (i.e. assign a default)</li>
30805 * </ul>
30806 * @member
30807 *
30808 * @name DataTable.defaults.columnDefs
30809 */
30810 "aoColumnDefs": null,
30811
30812
30813 /**
30814 * Basically the same as `search`, this parameter defines the individual column
30815 * filtering state at initialisation time. The array must be of the same size
30816 * as the number of columns, and each element be an object with the parameters
30817 * `search` and `escapeRegex` (the latter is optional). 'null' is also
30818 * accepted and the default will be used.
30819 * @type array
30820 * @default []
30821 *
30822 * @dtopt Option
30823 * @name DataTable.defaults.searchCols
30824 *
30825 * @example
30826 * $(document).ready( function() {
30827 * $('#example').dataTable( {
30828 * "searchCols": [
30829 * null,
30830 * { "search": "My filter" },
30831 * null,
30832 * { "search": "^[0-9]", "escapeRegex": false }
30833 * ]
30834 * } );
30835 * } )
30836 */
30837 "aoSearchCols": [],
30838
30839
30840 /**
30841 * An array of CSS classes that should be applied to displayed rows. This
30842 * array may be of any length, and DataTables will apply each class
30843 * sequentially, looping when required.
30844 * @type array
30845 * @default null <i>Will take the values determined by the `oClasses.stripe*`
30846 * options</i>
30847 *
30848 * @dtopt Option
30849 * @name DataTable.defaults.stripeClasses
30850 *
30851 * @example
30852 * $(document).ready( function() {
30853 * $('#example').dataTable( {
30854 * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
30855 * } );
30856 * } )
30857 */
30858 "asStripeClasses": null,
30859
30860
30861 /**
30862 * Enable or disable automatic column width calculation. This can be disabled
30863 * as an optimisation (it takes some time to calculate the widths) if the
30864 * tables widths are passed in using `columns`.
30865 * @type boolean
30866 * @default true
30867 *
30868 * @dtopt Features
30869 * @name DataTable.defaults.autoWidth
30870 *
30871 * @example
30872 * $(document).ready( function () {
30873 * $('#example').dataTable( {
30874 * "autoWidth": false
30875 * } );
30876 * } );
30877 */
30878 "bAutoWidth": true,
30879
30880
30881 /**
30882 * Deferred rendering can provide DataTables with a huge speed boost when you
30883 * are using an Ajax or JS data source for the table. This option, when set to
30884 * true, will cause DataTables to defer the creation of the table elements for
30885 * each row until they are needed for a draw - saving a significant amount of
30886 * time.
30887 * @type boolean
30888 * @default false
30889 *
30890 * @dtopt Features
30891 * @name DataTable.defaults.deferRender
30892 *
30893 * @example
30894 * $(document).ready( function() {
30895 * $('#example').dataTable( {
30896 * "ajax": "sources/arrays.txt",
30897 * "deferRender": true
30898 * } );
30899 * } );
30900 */
30901 "bDeferRender": false,
30902
30903
30904 /**
30905 * Replace a DataTable which matches the given selector and replace it with
30906 * one which has the properties of the new initialisation object passed. If no
30907 * table matches the selector, then the new DataTable will be constructed as
30908 * per normal.
30909 * @type boolean
30910 * @default false
30911 *
30912 * @dtopt Options
30913 * @name DataTable.defaults.destroy
30914 *
30915 * @example
30916 * $(document).ready( function() {
30917 * $('#example').dataTable( {
30918 * "srollY": "200px",
30919 * "paginate": false
30920 * } );
30921 *
30922 * // Some time later....
30923 * $('#example').dataTable( {
30924 * "filter": false,
30925 * "destroy": true
30926 * } );
30927 * } );
30928 */
30929 "bDestroy": false,
30930
30931
30932 /**
30933 * Enable or disable filtering of data. Filtering in DataTables is "smart" in
30934 * that it allows the end user to input multiple words (space separated) and
30935 * will match a row containing those words, even if not in the order that was
30936 * specified (this allow matching across multiple columns). Note that if you
30937 * wish to use filtering in DataTables this must remain 'true' - to remove the
30938 * default filtering input box and retain filtering abilities, please use
30939 * {@link DataTable.defaults.dom}.
30940 * @type boolean
30941 * @default true
30942 *
30943 * @dtopt Features
30944 * @name DataTable.defaults.searching
30945 *
30946 * @example
30947 * $(document).ready( function () {
30948 * $('#example').dataTable( {
30949 * "searching": false
30950 * } );
30951 * } );
30952 */
30953 "bFilter": true,
30954
30955
30956 /**
30957 * Enable or disable the table information display. This shows information
30958 * about the data that is currently visible on the page, including information
30959 * about filtered data if that action is being performed.
30960 * @type boolean
30961 * @default true
30962 *
30963 * @dtopt Features
30964 * @name DataTable.defaults.info
30965 *
30966 * @example
30967 * $(document).ready( function () {
30968 * $('#example').dataTable( {
30969 * "info": false
30970 * } );
30971 * } );
30972 */
30973 "bInfo": true,
30974
30975
30976 /**
30977 * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
30978 * slightly different and additional mark-up from what DataTables has
30979 * traditionally used).
30980 * @type boolean
30981 * @default false
30982 *
30983 * @dtopt Features
30984 * @name DataTable.defaults.jQueryUI
30985 *
30986 * @example
30987 * $(document).ready( function() {
30988 * $('#example').dataTable( {
30989 * "jQueryUI": true
30990 * } );
30991 * } );
30992 */
30993 "bJQueryUI": false,
30994
30995
30996 /**
30997 * Allows the end user to select the size of a formatted page from a select
30998 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
30999 * @type boolean
31000 * @default true
31001 *
31002 * @dtopt Features
31003 * @name DataTable.defaults.lengthChange
31004 *
31005 * @example
31006 * $(document).ready( function () {
31007 * $('#example').dataTable( {
31008 * "lengthChange": false
31009 * } );
31010 * } );
31011 */
31012 "bLengthChange": true,
31013
31014
31015 /**
31016 * Enable or disable pagination.
31017 * @type boolean
31018 * @default true
31019 *
31020 * @dtopt Features
31021 * @name DataTable.defaults.paging
31022 *
31023 * @example
31024 * $(document).ready( function () {
31025 * $('#example').dataTable( {
31026 * "paging": false
31027 * } );
31028 * } );
31029 */
31030 "bPaginate": true,
31031
31032
31033 /**
31034 * Enable or disable the display of a 'processing' indicator when the table is
31035 * being processed (e.g. a sort). This is particularly useful for tables with
31036 * large amounts of data where it can take a noticeable amount of time to sort
31037 * the entries.
31038 * @type boolean
31039 * @default false
31040 *
31041 * @dtopt Features
31042 * @name DataTable.defaults.processing
31043 *
31044 * @example
31045 * $(document).ready( function () {
31046 * $('#example').dataTable( {
31047 * "processing": true
31048 * } );
31049 * } );
31050 */
31051 "bProcessing": false,
31052
31053
31054 /**
31055 * Retrieve the DataTables object for the given selector. Note that if the
31056 * table has already been initialised, this parameter will cause DataTables
31057 * to simply return the object that has already been set up - it will not take
31058 * account of any changes you might have made to the initialisation object
31059 * passed to DataTables (setting this parameter to true is an acknowledgement
31060 * that you understand this). `destroy` can be used to reinitialise a table if
31061 * you need.
31062 * @type boolean
31063 * @default false
31064 *
31065 * @dtopt Options
31066 * @name DataTable.defaults.retrieve
31067 *
31068 * @example
31069 * $(document).ready( function() {
31070 * initTable();
31071 * tableActions();
31072 * } );
31073 *
31074 * function initTable ()
31075 * {
31076 * return $('#example').dataTable( {
31077 * "scrollY": "200px",
31078 * "paginate": false,
31079 * "retrieve": true
31080 * } );
31081 * }
31082 *
31083 * function tableActions ()
31084 * {
31085 * var table = initTable();
31086 * // perform API operations with oTable
31087 * }
31088 */
31089 "bRetrieve": false,
31090
31091
31092 /**
31093 * When vertical (y) scrolling is enabled, DataTables will force the height of
31094 * the table's viewport to the given height at all times (useful for layout).
31095 * However, this can look odd when filtering data down to a small data set,
31096 * and the footer is left "floating" further down. This parameter (when
31097 * enabled) will cause DataTables to collapse the table's viewport down when
31098 * the result set will fit within the given Y height.
31099 * @type boolean
31100 * @default false
31101 *
31102 * @dtopt Options
31103 * @name DataTable.defaults.scrollCollapse
31104 *
31105 * @example
31106 * $(document).ready( function() {
31107 * $('#example').dataTable( {
31108 * "scrollY": "200",
31109 * "scrollCollapse": true
31110 * } );
31111 * } );
31112 */
31113 "bScrollCollapse": false,
31114
31115
31116 /**
31117 * Configure DataTables to use server-side processing. Note that the
31118 * `ajax` parameter must also be given in order to give DataTables a
31119 * source to obtain the required data for each draw.
31120 * @type boolean
31121 * @default false
31122 *
31123 * @dtopt Features
31124 * @dtopt Server-side
31125 * @name DataTable.defaults.serverSide
31126 *
31127 * @example
31128 * $(document).ready( function () {
31129 * $('#example').dataTable( {
31130 * "serverSide": true,
31131 * "ajax": "xhr.php"
31132 * } );
31133 * } );
31134 */
31135 "bServerSide": false,
31136
31137
31138 /**
31139 * Enable or disable sorting of columns. Sorting of individual columns can be
31140 * disabled by the `sortable` option for each column.
31141 * @type boolean
31142 * @default true
31143 *
31144 * @dtopt Features
31145 * @name DataTable.defaults.ordering
31146 *
31147 * @example
31148 * $(document).ready( function () {
31149 * $('#example').dataTable( {
31150 * "ordering": false
31151 * } );
31152 * } );
31153 */
31154 "bSort": true,
31155
31156
31157 /**
31158 * Enable or display DataTables' ability to sort multiple columns at the
31159 * same time (activated by shift-click by the user).
31160 * @type boolean
31161 * @default true
31162 *
31163 * @dtopt Options
31164 * @name DataTable.defaults.orderMulti
31165 *
31166 * @example
31167 * // Disable multiple column sorting ability
31168 * $(document).ready( function () {
31169 * $('#example').dataTable( {
31170 * "orderMulti": false
31171 * } );
31172 * } );
31173 */
31174 "bSortMulti": true,
31175
31176
31177 /**
31178 * Allows control over whether DataTables should use the top (true) unique
31179 * cell that is found for a single column, or the bottom (false - default).
31180 * This is useful when using complex headers.
31181 * @type boolean
31182 * @default false
31183 *
31184 * @dtopt Options
31185 * @name DataTable.defaults.orderCellsTop
31186 *
31187 * @example
31188 * $(document).ready( function() {
31189 * $('#example').dataTable( {
31190 * "orderCellsTop": true
31191 * } );
31192 * } );
31193 */
31194 "bSortCellsTop": false,
31195
31196
31197 /**
31198 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
31199 * `sorting\_3` to the columns which are currently being sorted on. This is
31200 * presented as a feature switch as it can increase processing time (while
31201 * classes are removed and added) so for large data sets you might want to
31202 * turn this off.
31203 * @type boolean
31204 * @default true
31205 *
31206 * @dtopt Features
31207 * @name DataTable.defaults.orderClasses
31208 *
31209 * @example
31210 * $(document).ready( function () {
31211 * $('#example').dataTable( {
31212 * "orderClasses": false
31213 * } );
31214 * } );
31215 */
31216 "bSortClasses": true,
31217
31218
31219 /**
31220 * Enable or disable state saving. When enabled HTML5 `localStorage` will be
31221 * used to save table display information such as pagination information,
31222 * display length, filtering and sorting. As such when the end user reloads
31223 * the page the display display will match what thy had previously set up.
31224 *
31225 * Due to the use of `localStorage` the default state saving is not supported
31226 * in IE6 or 7. If state saving is required in those browsers, use
31227 * `stateSaveCallback` to provide a storage solution such as cookies.
31228 * @type boolean
31229 * @default false
31230 *
31231 * @dtopt Features
31232 * @name DataTable.defaults.stateSave
31233 *
31234 * @example
31235 * $(document).ready( function () {
31236 * $('#example').dataTable( {
31237 * "stateSave": true
31238 * } );
31239 * } );
31240 */
31241 "bStateSave": false,
31242
31243
31244 /**
31245 * This function is called when a TR element is created (and all TD child
31246 * elements have been inserted), or registered if using a DOM source, allowing
31247 * manipulation of the TR element (adding classes etc).
31248 * @type function
31249 * @param {node} row "TR" element for the current row
31250 * @param {array} data Raw data array for this row
31251 * @param {int} dataIndex The index of this row in the internal aoData array
31252 *
31253 * @dtopt Callbacks
31254 * @name DataTable.defaults.createdRow
31255 *
31256 * @example
31257 * $(document).ready( function() {
31258 * $('#example').dataTable( {
31259 * "createdRow": function( row, data, dataIndex ) {
31260 * // Bold the grade for all 'A' grade browsers
31261 * if ( data[4] == "A" )
31262 * {
31263 * $('td:eq(4)', row).html( '<b>A</b>' );
31264 * }
31265 * }
31266 * } );
31267 * } );
31268 */
31269 "fnCreatedRow": null,
31270
31271
31272 /**
31273 * This function is called on every 'draw' event, and allows you to
31274 * dynamically modify any aspect you want about the created DOM.
31275 * @type function
31276 * @param {object} settings DataTables settings object
31277 *
31278 * @dtopt Callbacks
31279 * @name DataTable.defaults.drawCallback
31280 *
31281 * @example
31282 * $(document).ready( function() {
31283 * $('#example').dataTable( {
31284 * "drawCallback": function( settings ) {
31285 * alert( 'DataTables has redrawn the table' );
31286 * }
31287 * } );
31288 * } );
31289 */
31290 "fnDrawCallback": null,
31291
31292
31293 /**
31294 * Identical to fnHeaderCallback() but for the table footer this function
31295 * allows you to modify the table footer on every 'draw' event.
31296 * @type function
31297 * @param {node} foot "TR" element for the footer
31298 * @param {array} data Full table data (as derived from the original HTML)
31299 * @param {int} start Index for the current display starting point in the
31300 * display array
31301 * @param {int} end Index for the current display ending point in the
31302 * display array
31303 * @param {array int} display Index array to translate the visual position
31304 * to the full data array
31305 *
31306 * @dtopt Callbacks
31307 * @name DataTable.defaults.footerCallback
31308 *
31309 * @example
31310 * $(document).ready( function() {
31311 * $('#example').dataTable( {
31312 * "footerCallback": function( tfoot, data, start, end, display ) {
31313 * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
31314 * }
31315 * } );
31316 * } )
31317 */
31318 "fnFooterCallback": null,
31319
31320
31321 /**
31322 * When rendering large numbers in the information element for the table
31323 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
31324 * to have a comma separator for the 'thousands' units (e.g. 1 million is
31325 * rendered as "1,000,000") to help readability for the end user. This
31326 * function will override the default method DataTables uses.
31327 * @type function
31328 * @member
31329 * @param {int} toFormat number to be formatted
31330 * @returns {string} formatted string for DataTables to show the number
31331 *
31332 * @dtopt Callbacks
31333 * @name DataTable.defaults.formatNumber
31334 *
31335 * @example
31336 * // Format a number using a single quote for the separator (note that
31337 * // this can also be done with the language.thousands option)
31338 * $(document).ready( function() {
31339 * $('#example').dataTable( {
31340 * "formatNumber": function ( toFormat ) {
31341 * return toFormat.toString().replace(
31342 * /\B(?=(\d{3})+(?!\d))/g, "'"
31343 * );
31344 * };
31345 * } );
31346 * } );
31347 */
31348 "fnFormatNumber": function ( toFormat ) {
31349 return toFormat.toString().replace(
31350 /\B(?=(\d{3})+(?!\d))/g,
31351 this.oLanguage.sThousands
31352 );
31353 },
31354
31355
31356 /**
31357 * This function is called on every 'draw' event, and allows you to
31358 * dynamically modify the header row. This can be used to calculate and
31359 * display useful information about the table.
31360 * @type function
31361 * @param {node} head "TR" element for the header
31362 * @param {array} data Full table data (as derived from the original HTML)
31363 * @param {int} start Index for the current display starting point in the
31364 * display array
31365 * @param {int} end Index for the current display ending point in the
31366 * display array
31367 * @param {array int} display Index array to translate the visual position
31368 * to the full data array
31369 *
31370 * @dtopt Callbacks
31371 * @name DataTable.defaults.headerCallback
31372 *
31373 * @example
31374 * $(document).ready( function() {
31375 * $('#example').dataTable( {
31376 * "fheaderCallback": function( head, data, start, end, display ) {
31377 * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
31378 * }
31379 * } );
31380 * } )
31381 */
31382 "fnHeaderCallback": null,
31383
31384
31385 /**
31386 * The information element can be used to convey information about the current
31387 * state of the table. Although the internationalisation options presented by
31388 * DataTables are quite capable of dealing with most customisations, there may
31389 * be times where you wish to customise the string further. This callback
31390 * allows you to do exactly that.
31391 * @type function
31392 * @param {object} oSettings DataTables settings object
31393 * @param {int} start Starting position in data for the draw
31394 * @param {int} end End position in data for the draw
31395 * @param {int} max Total number of rows in the table (regardless of
31396 * filtering)
31397 * @param {int} total Total number of rows in the data set, after filtering
31398 * @param {string} pre The string that DataTables has formatted using it's
31399 * own rules
31400 * @returns {string} The string to be displayed in the information element.
31401 *
31402 * @dtopt Callbacks
31403 * @name DataTable.defaults.infoCallback
31404 *
31405 * @example
31406 * $('#example').dataTable( {
31407 * "infoCallback": function( settings, start, end, max, total, pre ) {
31408 * return start +" to "+ end;
31409 * }
31410 * } );
31411 */
31412 "fnInfoCallback": null,
31413
31414
31415 /**
31416 * Called when the table has been initialised. Normally DataTables will
31417 * initialise sequentially and there will be no need for this function,
31418 * however, this does not hold true when using external language information
31419 * since that is obtained using an async XHR call.
31420 * @type function
31421 * @param {object} settings DataTables settings object
31422 * @param {object} json The JSON object request from the server - only
31423 * present if client-side Ajax sourced data is used
31424 *
31425 * @dtopt Callbacks
31426 * @name DataTable.defaults.initComplete
31427 *
31428 * @example
31429 * $(document).ready( function() {
31430 * $('#example').dataTable( {
31431 * "initComplete": function(settings, json) {
31432 * alert( 'DataTables has finished its initialisation.' );
31433 * }
31434 * } );
31435 * } )
31436 */
31437 "fnInitComplete": null,
31438
31439
31440 /**
31441 * Called at the very start of each table draw and can be used to cancel the
31442 * draw by returning false, any other return (including undefined) results in
31443 * the full draw occurring).
31444 * @type function
31445 * @param {object} settings DataTables settings object
31446 * @returns {boolean} False will cancel the draw, anything else (including no
31447 * return) will allow it to complete.
31448 *
31449 * @dtopt Callbacks
31450 * @name DataTable.defaults.preDrawCallback
31451 *
31452 * @example
31453 * $(document).ready( function() {
31454 * $('#example').dataTable( {
31455 * "preDrawCallback": function( settings ) {
31456 * if ( $('#test').val() == 1 ) {
31457 * return false;
31458 * }
31459 * }
31460 * } );
31461 * } );
31462 */
31463 "fnPreDrawCallback": null,
31464
31465
31466 /**
31467 * This function allows you to 'post process' each row after it have been
31468 * generated for each table draw, but before it is rendered on screen. This
31469 * function might be used for setting the row class name etc.
31470 * @type function
31471 * @param {node} row "TR" element for the current row
31472 * @param {array} data Raw data array for this row
31473 * @param {int} displayIndex The display index for the current table draw
31474 * @param {int} displayIndexFull The index of the data in the full list of
31475 * rows (after filtering)
31476 *
31477 * @dtopt Callbacks
31478 * @name DataTable.defaults.rowCallback
31479 *
31480 * @example
31481 * $(document).ready( function() {
31482 * $('#example').dataTable( {
31483 * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
31484 * // Bold the grade for all 'A' grade browsers
31485 * if ( data[4] == "A" ) {
31486 * $('td:eq(4)', row).html( '<b>A</b>' );
31487 * }
31488 * }
31489 * } );
31490 * } );
31491 */
31492 "fnRowCallback": null,
31493
31494
31495 /**
31496 * __Deprecated__ The functionality provided by this parameter has now been
31497 * superseded by that provided through `ajax`, which should be used instead.
31498 *
31499 * This parameter allows you to override the default function which obtains
31500 * the data from the server so something more suitable for your application.
31501 * For example you could use POST data, or pull information from a Gears or
31502 * AIR database.
31503 * @type function
31504 * @member
31505 * @param {string} source HTTP source to obtain the data from (`ajax`)
31506 * @param {array} data A key/value pair object containing the data to send
31507 * to the server
31508 * @param {function} callback to be called on completion of the data get
31509 * process that will draw the data on the page.
31510 * @param {object} settings DataTables settings object
31511 *
31512 * @dtopt Callbacks
31513 * @dtopt Server-side
31514 * @name DataTable.defaults.serverData
31515 *
31516 * @deprecated 1.10. Please use `ajax` for this functionality now.
31517 */
31518 "fnServerData": null,
31519
31520
31521 /**
31522 * __Deprecated__ The functionality provided by this parameter has now been
31523 * superseded by that provided through `ajax`, which should be used instead.
31524 *
31525 * It is often useful to send extra data to the server when making an Ajax
31526 * request - for example custom filtering information, and this callback
31527 * function makes it trivial to send extra information to the server. The
31528 * passed in parameter is the data set that has been constructed by
31529 * DataTables, and you can add to this or modify it as you require.
31530 * @type function
31531 * @param {array} data Data array (array of objects which are name/value
31532 * pairs) that has been constructed by DataTables and will be sent to the
31533 * server. In the case of Ajax sourced data with server-side processing
31534 * this will be an empty array, for server-side processing there will be a
31535 * significant number of parameters!
31536 * @returns {undefined} Ensure that you modify the data array passed in,
31537 * as this is passed by reference.
31538 *
31539 * @dtopt Callbacks
31540 * @dtopt Server-side
31541 * @name DataTable.defaults.serverParams
31542 *
31543 * @deprecated 1.10. Please use `ajax` for this functionality now.
31544 */
31545 "fnServerParams": null,
31546
31547
31548 /**
31549 * Load the table state. With this function you can define from where, and how, the
31550 * state of a table is loaded. By default DataTables will load from `localStorage`
31551 * but you might wish to use a server-side database or cookies.
31552 * @type function
31553 * @member
31554 * @param {object} settings DataTables settings object
31555 * @return {object} The DataTables state object to be loaded
31556 *
31557 * @dtopt Callbacks
31558 * @name DataTable.defaults.stateLoadCallback
31559 *
31560 * @example
31561 * $(document).ready( function() {
31562 * $('#example').dataTable( {
31563 * "stateSave": true,
31564 * "stateLoadCallback": function (settings) {
31565 * var o;
31566 *
31567 * // Send an Ajax request to the server to get the data. Note that
31568 * // this is a synchronous request.
31569 * $.ajax( {
31570 * "url": "/state_load",
31571 * "async": false,
31572 * "dataType": "json",
31573 * "success": function (json) {
31574 * o = json;
31575 * }
31576 * } );
31577 *
31578 * return o;
31579 * }
31580 * } );
31581 * } );
31582 */
31583 "fnStateLoadCallback": function ( settings ) {
31584 try {
31585 return JSON.parse(
31586 (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
31587 'DataTables_'+settings.sInstance+'_'+location.pathname
31588 )
31589 );
31590 } catch (e) {}
31591 },
31592
31593
31594 /**
31595 * Callback which allows modification of the saved state prior to loading that state.
31596 * This callback is called when the table is loading state from the stored data, but
31597 * prior to the settings object being modified by the saved state. Note that for
31598 * plug-in authors, you should use the `stateLoadParams` event to load parameters for
31599 * a plug-in.
31600 * @type function
31601 * @param {object} settings DataTables settings object
31602 * @param {object} data The state object that is to be loaded
31603 *
31604 * @dtopt Callbacks
31605 * @name DataTable.defaults.stateLoadParams
31606 *
31607 * @example
31608 * // Remove a saved filter, so filtering is never loaded
31609 * $(document).ready( function() {
31610 * $('#example').dataTable( {
31611 * "stateSave": true,
31612 * "stateLoadParams": function (settings, data) {
31613 * data.oSearch.sSearch = "";
31614 * }
31615 * } );
31616 * } );
31617 *
31618 * @example
31619 * // Disallow state loading by returning false
31620 * $(document).ready( function() {
31621 * $('#example').dataTable( {
31622 * "stateSave": true,
31623 * "stateLoadParams": function (settings, data) {
31624 * return false;
31625 * }
31626 * } );
31627 * } );
31628 */
31629 "fnStateLoadParams": null,
31630
31631
31632 /**
31633 * Callback that is called when the state has been loaded from the state saving method
31634 * and the DataTables settings object has been modified as a result of the loaded state.
31635 * @type function
31636 * @param {object} settings DataTables settings object
31637 * @param {object} data The state object that was loaded
31638 *
31639 * @dtopt Callbacks
31640 * @name DataTable.defaults.stateLoaded
31641 *
31642 * @example
31643 * // Show an alert with the filtering value that was saved
31644 * $(document).ready( function() {
31645 * $('#example').dataTable( {
31646 * "stateSave": true,
31647 * "stateLoaded": function (settings, data) {
31648 * alert( 'Saved filter was: '+data.oSearch.sSearch );
31649 * }
31650 * } );
31651 * } );
31652 */
31653 "fnStateLoaded": null,
31654
31655
31656 /**
31657 * Save the table state. This function allows you to define where and how the state
31658 * information for the table is stored By default DataTables will use `localStorage`
31659 * but you might wish to use a server-side database or cookies.
31660 * @type function
31661 * @member
31662 * @param {object} settings DataTables settings object
31663 * @param {object} data The state object to be saved
31664 *
31665 * @dtopt Callbacks
31666 * @name DataTable.defaults.stateSaveCallback
31667 *
31668 * @example
31669 * $(document).ready( function() {
31670 * $('#example').dataTable( {
31671 * "stateSave": true,
31672 * "stateSaveCallback": function (settings, data) {
31673 * // Send an Ajax request to the server with the state object
31674 * $.ajax( {
31675 * "url": "/state_save",
31676 * "data": data,
31677 * "dataType": "json",
31678 * "method": "POST"
31679 * "success": function () {}
31680 * } );
31681 * }
31682 * } );
31683 * } );
31684 */
31685 "fnStateSaveCallback": function ( settings, data ) {
31686 try {
31687 (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
31688 'DataTables_'+settings.sInstance+'_'+location.pathname,
31689 JSON.stringify( data )
31690 );
31691 } catch (e) {}
31692 },
31693
31694
31695 /**
31696 * Callback which allows modification of the state to be saved. Called when the table
31697 * has changed state a new state save is required. This method allows modification of
31698 * the state saving object prior to actually doing the save, including addition or
31699 * other state properties or modification. Note that for plug-in authors, you should
31700 * use the `stateSaveParams` event to save parameters for a plug-in.
31701 * @type function
31702 * @param {object} settings DataTables settings object
31703 * @param {object} data The state object to be saved
31704 *
31705 * @dtopt Callbacks
31706 * @name DataTable.defaults.stateSaveParams
31707 *
31708 * @example
31709 * // Remove a saved filter, so filtering is never saved
31710 * $(document).ready( function() {
31711 * $('#example').dataTable( {
31712 * "stateSave": true,
31713 * "stateSaveParams": function (settings, data) {
31714 * data.oSearch.sSearch = "";
31715 * }
31716 * } );
31717 * } );
31718 */
31719 "fnStateSaveParams": null,
31720
31721
31722 /**
31723 * Duration for which the saved state information is considered valid. After this period
31724 * has elapsed the state will be returned to the default.
31725 * Value is given in seconds.
31726 * @type int
31727 * @default 7200 <i>(2 hours)</i>
31728 *
31729 * @dtopt Options
31730 * @name DataTable.defaults.stateDuration
31731 *
31732 * @example
31733 * $(document).ready( function() {
31734 * $('#example').dataTable( {
31735 * "stateDuration": 60*60*24; // 1 day
31736 * } );
31737 * } )
31738 */
31739 "iStateDuration": 7200,
31740
31741
31742 /**
31743 * When enabled DataTables will not make a request to the server for the first
31744 * page draw - rather it will use the data already on the page (no sorting etc
31745 * will be applied to it), thus saving on an XHR at load time. `deferLoading`
31746 * is used to indicate that deferred loading is required, but it is also used
31747 * to tell DataTables how many records there are in the full table (allowing
31748 * the information element and pagination to be displayed correctly). In the case
31749 * where a filtering is applied to the table on initial load, this can be
31750 * indicated by giving the parameter as an array, where the first element is
31751 * the number of records available after filtering and the second element is the
31752 * number of records without filtering (allowing the table information element
31753 * to be shown correctly).
31754 * @type int | array
31755 * @default null
31756 *
31757 * @dtopt Options
31758 * @name DataTable.defaults.deferLoading
31759 *
31760 * @example
31761 * // 57 records available in the table, no filtering applied
31762 * $(document).ready( function() {
31763 * $('#example').dataTable( {
31764 * "serverSide": true,
31765 * "ajax": "scripts/server_processing.php",
31766 * "deferLoading": 57
31767 * } );
31768 * } );
31769 *
31770 * @example
31771 * // 57 records after filtering, 100 without filtering (an initial filter applied)
31772 * $(document).ready( function() {
31773 * $('#example').dataTable( {
31774 * "serverSide": true,
31775 * "ajax": "scripts/server_processing.php",
31776 * "deferLoading": [ 57, 100 ],
31777 * "search": {
31778 * "search": "my_filter"
31779 * }
31780 * } );
31781 * } );
31782 */
31783 "iDeferLoading": null,
31784
31785
31786 /**
31787 * Number of rows to display on a single page when using pagination. If
31788 * feature enabled (`lengthChange`) then the end user will be able to override
31789 * this to a custom setting using a pop-up menu.
31790 * @type int
31791 * @default 10
31792 *
31793 * @dtopt Options
31794 * @name DataTable.defaults.pageLength
31795 *
31796 * @example
31797 * $(document).ready( function() {
31798 * $('#example').dataTable( {
31799 * "pageLength": 50
31800 * } );
31801 * } )
31802 */
31803 "iDisplayLength": 10,
31804
31805
31806 /**
31807 * Define the starting point for data display when using DataTables with
31808 * pagination. Note that this parameter is the number of records, rather than
31809 * the page number, so if you have 10 records per page and want to start on
31810 * the third page, it should be "20".
31811 * @type int
31812 * @default 0
31813 *
31814 * @dtopt Options
31815 * @name DataTable.defaults.displayStart
31816 *
31817 * @example
31818 * $(document).ready( function() {
31819 * $('#example').dataTable( {
31820 * "displayStart": 20
31821 * } );
31822 * } )
31823 */
31824 "iDisplayStart": 0,
31825
31826
31827 /**
31828 * By default DataTables allows keyboard navigation of the table (sorting, paging,
31829 * and filtering) by adding a `tabindex` attribute to the required elements. This
31830 * allows you to tab through the controls and press the enter key to activate them.
31831 * The tabindex is default 0, meaning that the tab follows the flow of the document.
31832 * You can overrule this using this parameter if you wish. Use a value of -1 to
31833 * disable built-in keyboard navigation.
31834 * @type int
31835 * @default 0
31836 *
31837 * @dtopt Options
31838 * @name DataTable.defaults.tabIndex
31839 *
31840 * @example
31841 * $(document).ready( function() {
31842 * $('#example').dataTable( {
31843 * "tabIndex": 1
31844 * } );
31845 * } );
31846 */
31847 "iTabIndex": 0,
31848
31849
31850 /**
31851 * Classes that DataTables assigns to the various components and features
31852 * that it adds to the HTML table. This allows classes to be configured
31853 * during initialisation in addition to through the static
31854 * {@link DataTable.ext.oStdClasses} object).
31855 * @namespace
31856 * @name DataTable.defaults.classes
31857 */
31858 "oClasses": {},
31859
31860
31861 /**
31862 * All strings that DataTables uses in the user interface that it creates
31863 * are defined in this object, allowing you to modified them individually or
31864 * completely replace them all as required.
31865 * @namespace
31866 * @name DataTable.defaults.language
31867 */
31868 "oLanguage": {
31869 /**
31870 * Strings that are used for WAI-ARIA labels and controls only (these are not
31871 * actually visible on the page, but will be read by screenreaders, and thus
31872 * must be internationalised as well).
31873 * @namespace
31874 * @name DataTable.defaults.language.aria
31875 */
31876 "oAria": {
31877 /**
31878 * ARIA label that is added to the table headers when the column may be
31879 * sorted ascending by activing the column (click or return when focused).
31880 * Note that the column header is prefixed to this string.
31881 * @type string
31882 * @default : activate to sort column ascending
31883 *
31884 * @dtopt Language
31885 * @name DataTable.defaults.language.aria.sortAscending
31886 *
31887 * @example
31888 * $(document).ready( function() {
31889 * $('#example').dataTable( {
31890 * "language": {
31891 * "aria": {
31892 * "sortAscending": " - click/return to sort ascending"
31893 * }
31894 * }
31895 * } );
31896 * } );
31897 */
31898 "sSortAscending": ": activate to sort column ascending",
31899
31900 /**
31901 * ARIA label that is added to the table headers when the column may be
31902 * sorted descending by activing the column (click or return when focused).
31903 * Note that the column header is prefixed to this string.
31904 * @type string
31905 * @default : activate to sort column ascending
31906 *
31907 * @dtopt Language
31908 * @name DataTable.defaults.language.aria.sortDescending
31909 *
31910 * @example
31911 * $(document).ready( function() {
31912 * $('#example').dataTable( {
31913 * "language": {
31914 * "aria": {
31915 * "sortDescending": " - click/return to sort descending"
31916 * }
31917 * }
31918 * } );
31919 * } );
31920 */
31921 "sSortDescending": ": activate to sort column descending"
31922 },
31923
31924 /**
31925 * Pagination string used by DataTables for the built-in pagination
31926 * control types.
31927 * @namespace
31928 * @name DataTable.defaults.language.paginate
31929 */
31930 "oPaginate": {
31931 /**
31932 * Text to use when using the 'full_numbers' type of pagination for the
31933 * button to take the user to the first page.
31934 * @type string
31935 * @default First
31936 *
31937 * @dtopt Language
31938 * @name DataTable.defaults.language.paginate.first
31939 *
31940 * @example
31941 * $(document).ready( function() {
31942 * $('#example').dataTable( {
31943 * "language": {
31944 * "paginate": {
31945 * "first": "First page"
31946 * }
31947 * }
31948 * } );
31949 * } );
31950 */
31951 "sFirst": "First",
31952
31953
31954 /**
31955 * Text to use when using the 'full_numbers' type of pagination for the
31956 * button to take the user to the last page.
31957 * @type string
31958 * @default Last
31959 *
31960 * @dtopt Language
31961 * @name DataTable.defaults.language.paginate.last
31962 *
31963 * @example
31964 * $(document).ready( function() {
31965 * $('#example').dataTable( {
31966 * "language": {
31967 * "paginate": {
31968 * "last": "Last page"
31969 * }
31970 * }
31971 * } );
31972 * } );
31973 */
31974 "sLast": "Last",
31975
31976
31977 /**
31978 * Text to use for the 'next' pagination button (to take the user to the
31979 * next page).
31980 * @type string
31981 * @default Next
31982 *
31983 * @dtopt Language
31984 * @name DataTable.defaults.language.paginate.next
31985 *
31986 * @example
31987 * $(document).ready( function() {
31988 * $('#example').dataTable( {
31989 * "language": {
31990 * "paginate": {
31991 * "next": "Next page"
31992 * }
31993 * }
31994 * } );
31995 * } );
31996 */
31997 "sNext": "Next",
31998
31999
32000 /**
32001 * Text to use for the 'previous' pagination button (to take the user to
32002 * the previous page).
32003 * @type string
32004 * @default Previous
32005 *
32006 * @dtopt Language
32007 * @name DataTable.defaults.language.paginate.previous
32008 *
32009 * @example
32010 * $(document).ready( function() {
32011 * $('#example').dataTable( {
32012 * "language": {
32013 * "paginate": {
32014 * "previous": "Previous page"
32015 * }
32016 * }
32017 * } );
32018 * } );
32019 */
32020 "sPrevious": "Previous"
32021 },
32022
32023 /**
32024 * This string is shown in preference to `zeroRecords` when the table is
32025 * empty of data (regardless of filtering). Note that this is an optional
32026 * parameter - if it is not given, the value of `zeroRecords` will be used
32027 * instead (either the default or given value).
32028 * @type string
32029 * @default No data available in table
32030 *
32031 * @dtopt Language
32032 * @name DataTable.defaults.language.emptyTable
32033 *
32034 * @example
32035 * $(document).ready( function() {
32036 * $('#example').dataTable( {
32037 * "language": {
32038 * "emptyTable": "No data available in table"
32039 * }
32040 * } );
32041 * } );
32042 */
32043 "sEmptyTable": "No data available in table",
32044
32045
32046 /**
32047 * This string gives information to the end user about the information
32048 * that is current on display on the page. The following tokens can be
32049 * used in the string and will be dynamically replaced as the table
32050 * display updates. This tokens can be placed anywhere in the string, or
32051 * removed as needed by the language requires:
32052 *
32053 * * `\_START\_` - Display index of the first record on the current page
32054 * * `\_END\_` - Display index of the last record on the current page
32055 * * `\_TOTAL\_` - Number of records in the table after filtering
32056 * * `\_MAX\_` - Number of records in the table without filtering
32057 * * `\_PAGE\_` - Current page number
32058 * * `\_PAGES\_` - Total number of pages of data in the table
32059 *
32060 * @type string
32061 * @default Showing _START_ to _END_ of _TOTAL_ entries
32062 *
32063 * @dtopt Language
32064 * @name DataTable.defaults.language.info
32065 *
32066 * @example
32067 * $(document).ready( function() {
32068 * $('#example').dataTable( {
32069 * "language": {
32070 * "info": "Showing page _PAGE_ of _PAGES_"
32071 * }
32072 * } );
32073 * } );
32074 */
32075 "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
32076
32077
32078 /**
32079 * Display information string for when the table is empty. Typically the
32080 * format of this string should match `info`.
32081 * @type string
32082 * @default Showing 0 to 0 of 0 entries
32083 *
32084 * @dtopt Language
32085 * @name DataTable.defaults.language.infoEmpty
32086 *
32087 * @example
32088 * $(document).ready( function() {
32089 * $('#example').dataTable( {
32090 * "language": {
32091 * "infoEmpty": "No entries to show"
32092 * }
32093 * } );
32094 * } );
32095 */
32096 "sInfoEmpty": "Showing 0 to 0 of 0 entries",
32097
32098
32099 /**
32100 * When a user filters the information in a table, this string is appended
32101 * to the information (`info`) to give an idea of how strong the filtering
32102 * is. The variable _MAX_ is dynamically updated.
32103 * @type string
32104 * @default (filtered from _MAX_ total entries)
32105 *
32106 * @dtopt Language
32107 * @name DataTable.defaults.language.infoFiltered
32108 *
32109 * @example
32110 * $(document).ready( function() {
32111 * $('#example').dataTable( {
32112 * "language": {
32113 * "infoFiltered": " - filtering from _MAX_ records"
32114 * }
32115 * } );
32116 * } );
32117 */
32118 "sInfoFiltered": "(filtered from _MAX_ total entries)",
32119
32120
32121 /**
32122 * If can be useful to append extra information to the info string at times,
32123 * and this variable does exactly that. This information will be appended to
32124 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
32125 * being used) at all times.
32126 * @type string
32127 * @default <i>Empty string</i>
32128 *
32129 * @dtopt Language
32130 * @name DataTable.defaults.language.infoPostFix
32131 *
32132 * @example
32133 * $(document).ready( function() {
32134 * $('#example').dataTable( {
32135 * "language": {
32136 * "infoPostFix": "All records shown are derived from real information."
32137 * }
32138 * } );
32139 * } );
32140 */
32141 "sInfoPostFix": "",
32142
32143
32144 /**
32145 * This decimal place operator is a little different from the other
32146 * language options since DataTables doesn't output floating point
32147 * numbers, so it won't ever use this for display of a number. Rather,
32148 * what this parameter does is modify the sort methods of the table so
32149 * that numbers which are in a format which has a character other than
32150 * a period (`.`) as a decimal place will be sorted numerically.
32151 *
32152 * Note that numbers with different decimal places cannot be shown in
32153 * the same table and still be sortable, the table must be consistent.
32154 * However, multiple different tables on the page can use different
32155 * decimal place characters.
32156 * @type string
32157 * @default
32158 *
32159 * @dtopt Language
32160 * @name DataTable.defaults.language.decimal
32161 *
32162 * @example
32163 * $(document).ready( function() {
32164 * $('#example').dataTable( {
32165 * "language": {
32166 * "decimal": ","
32167 * "thousands": "."
32168 * }
32169 * } );
32170 * } );
32171 */
32172 "sDecimal": "",
32173
32174
32175 /**
32176 * DataTables has a build in number formatter (`formatNumber`) which is
32177 * used to format large numbers that are used in the table information.
32178 * By default a comma is used, but this can be trivially changed to any
32179 * character you wish with this parameter.
32180 * @type string
32181 * @default ,
32182 *
32183 * @dtopt Language
32184 * @name DataTable.defaults.language.thousands
32185 *
32186 * @example
32187 * $(document).ready( function() {
32188 * $('#example').dataTable( {
32189 * "language": {
32190 * "thousands": "'"
32191 * }
32192 * } );
32193 * } );
32194 */
32195 "sThousands": ",",
32196
32197
32198 /**
32199 * Detail the action that will be taken when the drop down menu for the
32200 * pagination length option is changed. The '_MENU_' variable is replaced
32201 * with a default select list of 10, 25, 50 and 100, and can be replaced
32202 * with a custom select box if required.
32203 * @type string
32204 * @default Show _MENU_ entries
32205 *
32206 * @dtopt Language
32207 * @name DataTable.defaults.language.lengthMenu
32208 *
32209 * @example
32210 * // Language change only
32211 * $(document).ready( function() {
32212 * $('#example').dataTable( {
32213 * "language": {
32214 * "lengthMenu": "Display _MENU_ records"
32215 * }
32216 * } );
32217 * } );
32218 *
32219 * @example
32220 * // Language and options change
32221 * $(document).ready( function() {
32222 * $('#example').dataTable( {
32223 * "language": {
32224 * "lengthMenu": 'Display <select>'+
32225 * '<option value="10">10</option>'+
32226 * '<option value="20">20</option>'+
32227 * '<option value="30">30</option>'+
32228 * '<option value="40">40</option>'+
32229 * '<option value="50">50</option>'+
32230 * '<option value="-1">All</option>'+
32231 * '</select> records'
32232 * }
32233 * } );
32234 * } );
32235 */
32236 "sLengthMenu": "Show _MENU_ entries",
32237
32238
32239 /**
32240 * When using Ajax sourced data and during the first draw when DataTables is
32241 * gathering the data, this message is shown in an empty row in the table to
32242 * indicate to the end user the the data is being loaded. Note that this
32243 * parameter is not used when loading data by server-side processing, just
32244 * Ajax sourced data with client-side processing.
32245 * @type string
32246 * @default Loading...
32247 *
32248 * @dtopt Language
32249 * @name DataTable.defaults.language.loadingRecords
32250 *
32251 * @example
32252 * $(document).ready( function() {
32253 * $('#example').dataTable( {
32254 * "language": {
32255 * "loadingRecords": "Please wait - loading..."
32256 * }
32257 * } );
32258 * } );
32259 */
32260 "sLoadingRecords": "Loading...",
32261
32262
32263 /**
32264 * Text which is displayed when the table is processing a user action
32265 * (usually a sort command or similar).
32266 * @type string
32267 * @default Processing...
32268 *
32269 * @dtopt Language
32270 * @name DataTable.defaults.language.processing
32271 *
32272 * @example
32273 * $(document).ready( function() {
32274 * $('#example').dataTable( {
32275 * "language": {
32276 * "processing": "DataTables is currently busy"
32277 * }
32278 * } );
32279 * } );
32280 */
32281 "sProcessing": "Processing...",
32282
32283
32284 /**
32285 * Details the actions that will be taken when the user types into the
32286 * filtering input text box. The variable "_INPUT_", if used in the string,
32287 * is replaced with the HTML text box for the filtering input allowing
32288 * control over where it appears in the string. If "_INPUT_" is not given
32289 * then the input box is appended to the string automatically.
32290 * @type string
32291 * @default Search:
32292 *
32293 * @dtopt Language
32294 * @name DataTable.defaults.language.search
32295 *
32296 * @example
32297 * // Input text box will be appended at the end automatically
32298 * $(document).ready( function() {
32299 * $('#example').dataTable( {
32300 * "language": {
32301 * "search": "Filter records:"
32302 * }
32303 * } );
32304 * } );
32305 *
32306 * @example
32307 * // Specify where the filter should appear
32308 * $(document).ready( function() {
32309 * $('#example').dataTable( {
32310 * "language": {
32311 * "search": "Apply filter _INPUT_ to table"
32312 * }
32313 * } );
32314 * } );
32315 */
32316 "sSearch": "Search:",
32317
32318
32319 /**
32320 * Assign a `placeholder` attribute to the search `input` element
32321 * @type string
32322 * @default
32323 *
32324 * @dtopt Language
32325 * @name DataTable.defaults.language.searchPlaceholder
32326 */
32327 "sSearchPlaceholder": "",
32328
32329
32330 /**
32331 * All of the language information can be stored in a file on the
32332 * server-side, which DataTables will look up if this parameter is passed.
32333 * It must store the URL of the language file, which is in a JSON format,
32334 * and the object has the same properties as the oLanguage object in the
32335 * initialiser object (i.e. the above parameters). Please refer to one of
32336 * the example language files to see how this works in action.
32337 * @type string
32338 * @default <i>Empty string - i.e. disabled</i>
32339 *
32340 * @dtopt Language
32341 * @name DataTable.defaults.language.url
32342 *
32343 * @example
32344 * $(document).ready( function() {
32345 * $('#example').dataTable( {
32346 * "language": {
32347 * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
32348 * }
32349 * } );
32350 * } );
32351 */
32352 "sUrl": "",
32353
32354
32355 /**
32356 * Text shown inside the table records when the is no information to be
32357 * displayed after filtering. `emptyTable` is shown when there is simply no
32358 * information in the table at all (regardless of filtering).
32359 * @type string
32360 * @default No matching records found
32361 *
32362 * @dtopt Language
32363 * @name DataTable.defaults.language.zeroRecords
32364 *
32365 * @example
32366 * $(document).ready( function() {
32367 * $('#example').dataTable( {
32368 * "language": {
32369 * "zeroRecords": "No records to display"
32370 * }
32371 * } );
32372 * } );
32373 */
32374 "sZeroRecords": "No matching records found"
32375 },
32376
32377
32378 /**
32379 * This parameter allows you to have define the global filtering state at
32380 * initialisation time. As an object the `search` parameter must be
32381 * defined, but all other parameters are optional. When `regex` is true,
32382 * the search string will be treated as a regular expression, when false
32383 * (default) it will be treated as a straight string. When `smart`
32384 * DataTables will use it's smart filtering methods (to word match at
32385 * any point in the data), when false this will not be done.
32386 * @namespace
32387 * @extends DataTable.models.oSearch
32388 *
32389 * @dtopt Options
32390 * @name DataTable.defaults.search
32391 *
32392 * @example
32393 * $(document).ready( function() {
32394 * $('#example').dataTable( {
32395 * "search": {"search": "Initial search"}
32396 * } );
32397 * } )
32398 */
32399 "oSearch": $.extend( {}, DataTable.models.oSearch ),
32400
32401
32402 /**
32403 * __Deprecated__ The functionality provided by this parameter has now been
32404 * superseded by that provided through `ajax`, which should be used instead.
32405 *
32406 * By default DataTables will look for the property `data` (or `aaData` for
32407 * compatibility with DataTables 1.9-) when obtaining data from an Ajax
32408 * source or for server-side processing - this parameter allows that
32409 * property to be changed. You can use Javascript dotted object notation to
32410 * get a data source for multiple levels of nesting.
32411 * @type string
32412 * @default data
32413 *
32414 * @dtopt Options
32415 * @dtopt Server-side
32416 * @name DataTable.defaults.ajaxDataProp
32417 *
32418 * @deprecated 1.10. Please use `ajax` for this functionality now.
32419 */
32420 "sAjaxDataProp": "data",
32421
32422
32423 /**
32424 * __Deprecated__ The functionality provided by this parameter has now been
32425 * superseded by that provided through `ajax`, which should be used instead.
32426 *
32427 * You can instruct DataTables to load data from an external
32428 * source using this parameter (use aData if you want to pass data in you
32429 * already have). Simply provide a url a JSON object can be obtained from.
32430 * @type string
32431 * @default null
32432 *
32433 * @dtopt Options
32434 * @dtopt Server-side
32435 * @name DataTable.defaults.ajaxSource
32436 *
32437 * @deprecated 1.10. Please use `ajax` for this functionality now.
32438 */
32439 "sAjaxSource": null,
32440
32441
32442 /**
32443 * This initialisation variable allows you to specify exactly where in the
32444 * DOM you want DataTables to inject the various controls it adds to the page
32445 * (for example you might want the pagination controls at the top of the
32446 * table). DIV elements (with or without a custom class) can also be added to
32447 * aid styling. The follow syntax is used:
32448 * <ul>
32449 * <li>The following options are allowed:
32450 * <ul>
32451 * <li>'l' - Length changing</li>
32452 * <li>'f' - Filtering input</li>
32453 * <li>'t' - The table!</li>
32454 * <li>'i' - Information</li>
32455 * <li>'p' - Pagination</li>
32456 * <li>'r' - pRocessing</li>
32457 * </ul>
32458 * </li>
32459 * <li>The following constants are allowed:
32460 * <ul>
32461 * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
32462 * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
32463 * </ul>
32464 * </li>
32465 * <li>The following syntax is expected:
32466 * <ul>
32467 * <li>'<' and '>' - div elements</li>
32468 * <li>'<"class" and '>' - div with a class</li>
32469 * <li>'<"#id" and '>' - div with an ID</li>
32470 * </ul>
32471 * </li>
32472 * <li>Examples:
32473 * <ul>
32474 * <li>'<"wrapper"flipt>'</li>
32475 * <li>'<lf<t>ip>'</li>
32476 * </ul>
32477 * </li>
32478 * </ul>
32479 * @type string
32480 * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
32481 * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
32482 *
32483 * @dtopt Options
32484 * @name DataTable.defaults.dom
32485 *
32486 * @example
32487 * $(document).ready( function() {
32488 * $('#example').dataTable( {
32489 * "dom": '<"top"i>rt<"bottom"flp><"clear">'
32490 * } );
32491 * } );
32492 */
32493 "sDom": "lfrtip",
32494
32495
32496 /**
32497 * Search delay option. This will throttle full table searches that use the
32498 * DataTables provided search input element (it does not effect calls to
32499 * `dt-api search()`, providing a delay before the search is made.
32500 * @type integer
32501 * @default 0
32502 *
32503 * @dtopt Options
32504 * @name DataTable.defaults.searchDelay
32505 *
32506 * @example
32507 * $(document).ready( function() {
32508 * $('#example').dataTable( {
32509 * "searchDelay": 200
32510 * } );
32511 * } )
32512 */
32513 "searchDelay": null,
32514
32515
32516 /**
32517 * DataTables features four different built-in options for the buttons to
32518 * display for pagination control:
32519 *
32520 * * `simple` - 'Previous' and 'Next' buttons only
32521 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
32522 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
32523 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
32524 * page numbers
32525 *
32526 * Further methods can be added using {@link DataTable.ext.oPagination}.
32527 * @type string
32528 * @default simple_numbers
32529 *
32530 * @dtopt Options
32531 * @name DataTable.defaults.pagingType
32532 *
32533 * @example
32534 * $(document).ready( function() {
32535 * $('#example').dataTable( {
32536 * "pagingType": "full_numbers"
32537 * } );
32538 * } )
32539 */
32540 "sPaginationType": "simple_numbers",
32541
32542
32543 /**
32544 * Enable horizontal scrolling. When a table is too wide to fit into a
32545 * certain layout, or you have a large number of columns in the table, you
32546 * can enable x-scrolling to show the table in a viewport, which can be
32547 * scrolled. This property can be `true` which will allow the table to
32548 * scroll horizontally when needed, or any CSS unit, or a number (in which
32549 * case it will be treated as a pixel measurement). Setting as simply `true`
32550 * is recommended.
32551 * @type boolean|string
32552 * @default <i>blank string - i.e. disabled</i>
32553 *
32554 * @dtopt Features
32555 * @name DataTable.defaults.scrollX
32556 *
32557 * @example
32558 * $(document).ready( function() {
32559 * $('#example').dataTable( {
32560 * "scrollX": true,
32561 * "scrollCollapse": true
32562 * } );
32563 * } );
32564 */
32565 "sScrollX": "",
32566
32567
32568 /**
32569 * This property can be used to force a DataTable to use more width than it
32570 * might otherwise do when x-scrolling is enabled. For example if you have a
32571 * table which requires to be well spaced, this parameter is useful for
32572 * "over-sizing" the table, and thus forcing scrolling. This property can by
32573 * any CSS unit, or a number (in which case it will be treated as a pixel
32574 * measurement).
32575 * @type string
32576 * @default <i>blank string - i.e. disabled</i>
32577 *
32578 * @dtopt Options
32579 * @name DataTable.defaults.scrollXInner
32580 *
32581 * @example
32582 * $(document).ready( function() {
32583 * $('#example').dataTable( {
32584 * "scrollX": "100%",
32585 * "scrollXInner": "110%"
32586 * } );
32587 * } );
32588 */
32589 "sScrollXInner": "",
32590
32591
32592 /**
32593 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
32594 * to the given height, and enable scrolling for any data which overflows the
32595 * current viewport. This can be used as an alternative to paging to display
32596 * a lot of data in a small area (although paging and scrolling can both be
32597 * enabled at the same time). This property can be any CSS unit, or a number
32598 * (in which case it will be treated as a pixel measurement).
32599 * @type string
32600 * @default <i>blank string - i.e. disabled</i>
32601 *
32602 * @dtopt Features
32603 * @name DataTable.defaults.scrollY
32604 *
32605 * @example
32606 * $(document).ready( function() {
32607 * $('#example').dataTable( {
32608 * "scrollY": "200px",
32609 * "paginate": false
32610 * } );
32611 * } );
32612 */
32613 "sScrollY": "",
32614
32615
32616 /**
32617 * __Deprecated__ The functionality provided by this parameter has now been
32618 * superseded by that provided through `ajax`, which should be used instead.
32619 *
32620 * Set the HTTP method that is used to make the Ajax call for server-side
32621 * processing or Ajax sourced data.
32622 * @type string
32623 * @default GET
32624 *
32625 * @dtopt Options
32626 * @dtopt Server-side
32627 * @name DataTable.defaults.serverMethod
32628 *
32629 * @deprecated 1.10. Please use `ajax` for this functionality now.
32630 */
32631 "sServerMethod": "GET",
32632
32633
32634 /**
32635 * DataTables makes use of renderers when displaying HTML elements for
32636 * a table. These renderers can be added or modified by plug-ins to
32637 * generate suitable mark-up for a site. For example the Bootstrap
32638 * integration plug-in for DataTables uses a paging button renderer to
32639 * display pagination buttons in the mark-up required by Bootstrap.
32640 *
32641 * For further information about the renderers available see
32642 * DataTable.ext.renderer
32643 * @type string|object
32644 * @default null
32645 *
32646 * @name DataTable.defaults.renderer
32647 *
32648 */
32649 "renderer": null,
32650
32651
32652 /**
32653 * Set the data property name that DataTables should use to get a row's id
32654 * to set as the `id` property in the node.
32655 * @type string
32656 * @default DT_RowId
32657 *
32658 * @name DataTable.defaults.rowId
32659 */
32660 "rowId": "DT_RowId"
32661 };
32662
32663 _fnHungarianMap( DataTable.defaults );
32664
32665
32666
32667 /*
32668 * Developer note - See note in model.defaults.js about the use of Hungarian
32669 * notation and camel case.
32670 */
32671
32672 /**
32673 * Column options that can be given to DataTables at initialisation time.
32674 * @namespace
32675 */
32676 DataTable.defaults.column = {
32677 /**
32678 * Define which column(s) an order will occur on for this column. This
32679 * allows a column's ordering to take multiple columns into account when
32680 * doing a sort or use the data from a different column. For example first
32681 * name / last name columns make sense to do a multi-column sort over the
32682 * two columns.
32683 * @type array|int
32684 * @default null <i>Takes the value of the column index automatically</i>
32685 *
32686 * @name DataTable.defaults.column.orderData
32687 * @dtopt Columns
32688 *
32689 * @example
32690 * // Using `columnDefs`
32691 * $(document).ready( function() {
32692 * $('#example').dataTable( {
32693 * "columnDefs": [
32694 * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
32695 * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
32696 * { "orderData": 2, "targets": [ 2 ] }
32697 * ]
32698 * } );
32699 * } );
32700 *
32701 * @example
32702 * // Using `columns`
32703 * $(document).ready( function() {
32704 * $('#example').dataTable( {
32705 * "columns": [
32706 * { "orderData": [ 0, 1 ] },
32707 * { "orderData": [ 1, 0 ] },
32708 * { "orderData": 2 },
32709 * null,
32710 * null
32711 * ]
32712 * } );
32713 * } );
32714 */
32715 "aDataSort": null,
32716 "iDataSort": -1,
32717
32718
32719 /**
32720 * You can control the default ordering direction, and even alter the
32721 * behaviour of the sort handler (i.e. only allow ascending ordering etc)
32722 * using this parameter.
32723 * @type array
32724 * @default [ 'asc', 'desc' ]
32725 *
32726 * @name DataTable.defaults.column.orderSequence
32727 * @dtopt Columns
32728 *
32729 * @example
32730 * // Using `columnDefs`
32731 * $(document).ready( function() {
32732 * $('#example').dataTable( {
32733 * "columnDefs": [
32734 * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
32735 * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
32736 * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
32737 * ]
32738 * } );
32739 * } );
32740 *
32741 * @example
32742 * // Using `columns`
32743 * $(document).ready( function() {
32744 * $('#example').dataTable( {
32745 * "columns": [
32746 * null,
32747 * { "orderSequence": [ "asc" ] },
32748 * { "orderSequence": [ "desc", "asc", "asc" ] },
32749 * { "orderSequence": [ "desc" ] },
32750 * null
32751 * ]
32752 * } );
32753 * } );
32754 */
32755 "asSorting": [ 'asc', 'desc' ],
32756
32757
32758 /**
32759 * Enable or disable filtering on the data in this column.
32760 * @type boolean
32761 * @default true
32762 *
32763 * @name DataTable.defaults.column.searchable
32764 * @dtopt Columns
32765 *
32766 * @example
32767 * // Using `columnDefs`
32768 * $(document).ready( function() {
32769 * $('#example').dataTable( {
32770 * "columnDefs": [
32771 * { "searchable": false, "targets": [ 0 ] }
32772 * ] } );
32773 * } );
32774 *
32775 * @example
32776 * // Using `columns`
32777 * $(document).ready( function() {
32778 * $('#example').dataTable( {
32779 * "columns": [
32780 * { "searchable": false },
32781 * null,
32782 * null,
32783 * null,
32784 * null
32785 * ] } );
32786 * } );
32787 */
32788 "bSearchable": true,
32789
32790
32791 /**
32792 * Enable or disable ordering on this column.
32793 * @type boolean
32794 * @default true
32795 *
32796 * @name DataTable.defaults.column.orderable
32797 * @dtopt Columns
32798 *
32799 * @example
32800 * // Using `columnDefs`
32801 * $(document).ready( function() {
32802 * $('#example').dataTable( {
32803 * "columnDefs": [
32804 * { "orderable": false, "targets": [ 0 ] }
32805 * ] } );
32806 * } );
32807 *
32808 * @example
32809 * // Using `columns`
32810 * $(document).ready( function() {
32811 * $('#example').dataTable( {
32812 * "columns": [
32813 * { "orderable": false },
32814 * null,
32815 * null,
32816 * null,
32817 * null
32818 * ] } );
32819 * } );
32820 */
32821 "bSortable": true,
32822
32823
32824 /**
32825 * Enable or disable the display of this column.
32826 * @type boolean
32827 * @default true
32828 *
32829 * @name DataTable.defaults.column.visible
32830 * @dtopt Columns
32831 *
32832 * @example
32833 * // Using `columnDefs`
32834 * $(document).ready( function() {
32835 * $('#example').dataTable( {
32836 * "columnDefs": [
32837 * { "visible": false, "targets": [ 0 ] }
32838 * ] } );
32839 * } );
32840 *
32841 * @example
32842 * // Using `columns`
32843 * $(document).ready( function() {
32844 * $('#example').dataTable( {
32845 * "columns": [
32846 * { "visible": false },
32847 * null,
32848 * null,
32849 * null,
32850 * null
32851 * ] } );
32852 * } );
32853 */
32854 "bVisible": true,
32855
32856
32857 /**
32858 * Developer definable function that is called whenever a cell is created (Ajax source,
32859 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
32860 * allowing you to modify the DOM element (add background colour for example) when the
32861 * element is available.
32862 * @type function
32863 * @param {element} td The TD node that has been created
32864 * @param {*} cellData The Data for the cell
32865 * @param {array|object} rowData The data for the whole row
32866 * @param {int} row The row index for the aoData data store
32867 * @param {int} col The column index for aoColumns
32868 *
32869 * @name DataTable.defaults.column.createdCell
32870 * @dtopt Columns
32871 *
32872 * @example
32873 * $(document).ready( function() {
32874 * $('#example').dataTable( {
32875 * "columnDefs": [ {
32876 * "targets": [3],
32877 * "createdCell": function (td, cellData, rowData, row, col) {
32878 * if ( cellData == "1.7" ) {
32879 * $(td).css('color', 'blue')
32880 * }
32881 * }
32882 * } ]
32883 * });
32884 * } );
32885 */
32886 "fnCreatedCell": null,
32887
32888
32889 /**
32890 * This parameter has been replaced by `data` in DataTables to ensure naming
32891 * consistency. `dataProp` can still be used, as there is backwards
32892 * compatibility in DataTables for this option, but it is strongly
32893 * recommended that you use `data` in preference to `dataProp`.
32894 * @name DataTable.defaults.column.dataProp
32895 */
32896
32897
32898 /**
32899 * This property can be used to read data from any data source property,
32900 * including deeply nested objects / properties. `data` can be given in a
32901 * number of different ways which effect its behaviour:
32902 *
32903 * * `integer` - treated as an array index for the data source. This is the
32904 * default that DataTables uses (incrementally increased for each column).
32905 * * `string` - read an object property from the data source. There are
32906 * three 'special' options that can be used in the string to alter how
32907 * DataTables reads the data from the source object:
32908 * * `.` - Dotted Javascript notation. Just as you use a `.` in
32909 * Javascript to read from nested objects, so to can the options
32910 * specified in `data`. For example: `browser.version` or
32911 * `browser.name`. If your object parameter name contains a period, use
32912 * `\\` to escape it - i.e. `first\\.name`.
32913 * * `[]` - Array notation. DataTables can automatically combine data
32914 * from and array source, joining the data with the characters provided
32915 * between the two brackets. For example: `name[, ]` would provide a
32916 * comma-space separated list from the source array. If no characters
32917 * are provided between the brackets, the original array source is
32918 * returned.
32919 * * `()` - Function notation. Adding `()` to the end of a parameter will
32920 * execute a function of the name given. For example: `browser()` for a
32921 * simple function on the data source, `browser.version()` for a
32922 * function in a nested property or even `browser().version` to get an
32923 * object property if the function called returns an object. Note that
32924 * function notation is recommended for use in `render` rather than
32925 * `data` as it is much simpler to use as a renderer.
32926 * * `null` - use the original data source for the row rather than plucking
32927 * data directly from it. This action has effects on two other
32928 * initialisation options:
32929 * * `defaultContent` - When null is given as the `data` option and
32930 * `defaultContent` is specified for the column, the value defined by
32931 * `defaultContent` will be used for the cell.
32932 * * `render` - When null is used for the `data` option and the `render`
32933 * option is specified for the column, the whole data source for the
32934 * row is used for the renderer.
32935 * * `function` - the function given will be executed whenever DataTables
32936 * needs to set or get the data for a cell in the column. The function
32937 * takes three parameters:
32938 * * Parameters:
32939 * * `{array|object}` The data source for the row
32940 * * `{string}` The type call data requested - this will be 'set' when
32941 * setting data or 'filter', 'display', 'type', 'sort' or undefined
32942 * when gathering data. Note that when `undefined` is given for the
32943 * type DataTables expects to get the raw data for the object back<
32944 * * `{*}` Data to set when the second parameter is 'set'.
32945 * * Return:
32946 * * The return value from the function is not required when 'set' is
32947 * the type of call, but otherwise the return is what will be used
32948 * for the data requested.
32949 *
32950 * Note that `data` is a getter and setter option. If you just require
32951 * formatting of data for output, you will likely want to use `render` which
32952 * is simply a getter and thus simpler to use.
32953 *
32954 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
32955 * name change reflects the flexibility of this property and is consistent
32956 * with the naming of mRender. If 'mDataProp' is given, then it will still
32957 * be used by DataTables, as it automatically maps the old name to the new
32958 * if required.
32959 *
32960 * @type string|int|function|null
32961 * @default null <i>Use automatically calculated column index</i>
32962 *
32963 * @name DataTable.defaults.column.data
32964 * @dtopt Columns
32965 *
32966 * @example
32967 * // Read table data from objects
32968 * // JSON structure for each row:
32969 * // {
32970 * // "engine": {value},
32971 * // "browser": {value},
32972 * // "platform": {value},
32973 * // "version": {value},
32974 * // "grade": {value}
32975 * // }
32976 * $(document).ready( function() {
32977 * $('#example').dataTable( {
32978 * "ajaxSource": "sources/objects.txt",
32979 * "columns": [
32980 * { "data": "engine" },
32981 * { "data": "browser" },
32982 * { "data": "platform" },
32983 * { "data": "version" },
32984 * { "data": "grade" }
32985 * ]
32986 * } );
32987 * } );
32988 *
32989 * @example
32990 * // Read information from deeply nested objects
32991 * // JSON structure for each row:
32992 * // {
32993 * // "engine": {value},
32994 * // "browser": {value},
32995 * // "platform": {
32996 * // "inner": {value}
32997 * // },
32998 * // "details": [
32999 * // {value}, {value}
33000 * // ]
33001 * // }
33002 * $(document).ready( function() {
33003 * $('#example').dataTable( {
33004 * "ajaxSource": "sources/deep.txt",
33005 * "columns": [
33006 * { "data": "engine" },
33007 * { "data": "browser" },
33008 * { "data": "platform.inner" },
33009 * { "data": "platform.details.0" },
33010 * { "data": "platform.details.1" }
33011 * ]
33012 * } );
33013 * } );
33014 *
33015 * @example
33016 * // Using `data` as a function to provide different information for
33017 * // sorting, filtering and display. In this case, currency (price)
33018 * $(document).ready( function() {
33019 * $('#example').dataTable( {
33020 * "columnDefs": [ {
33021 * "targets": [ 0 ],
33022 * "data": function ( source, type, val ) {
33023 * if (type === 'set') {
33024 * source.price = val;
33025 * // Store the computed dislay and filter values for efficiency
33026 * source.price_display = val=="" ? "" : "$"+numberFormat(val);
33027 * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
33028 * return;
33029 * }
33030 * else if (type === 'display') {
33031 * return source.price_display;
33032 * }
33033 * else if (type === 'filter') {
33034 * return source.price_filter;
33035 * }
33036 * // 'sort', 'type' and undefined all just use the integer
33037 * return source.price;
33038 * }
33039 * } ]
33040 * } );
33041 * } );
33042 *
33043 * @example
33044 * // Using default content
33045 * $(document).ready( function() {
33046 * $('#example').dataTable( {
33047 * "columnDefs": [ {
33048 * "targets": [ 0 ],
33049 * "data": null,
33050 * "defaultContent": "Click to edit"
33051 * } ]
33052 * } );
33053 * } );
33054 *
33055 * @example
33056 * // Using array notation - outputting a list from an array
33057 * $(document).ready( function() {
33058 * $('#example').dataTable( {
33059 * "columnDefs": [ {
33060 * "targets": [ 0 ],
33061 * "data": "name[, ]"
33062 * } ]
33063 * } );
33064 * } );
33065 *
33066 */
33067 "mData": null,
33068
33069
33070 /**
33071 * This property is the rendering partner to `data` and it is suggested that
33072 * when you want to manipulate data for display (including filtering,
33073 * sorting etc) without altering the underlying data for the table, use this
33074 * property. `render` can be considered to be the the read only companion to
33075 * `data` which is read / write (then as such more complex). Like `data`
33076 * this option can be given in a number of different ways to effect its
33077 * behaviour:
33078 *
33079 * * `integer` - treated as an array index for the data source. This is the
33080 * default that DataTables uses (incrementally increased for each column).
33081 * * `string` - read an object property from the data source. There are
33082 * three 'special' options that can be used in the string to alter how
33083 * DataTables reads the data from the source object:
33084 * * `.` - Dotted Javascript notation. Just as you use a `.` in
33085 * Javascript to read from nested objects, so to can the options
33086 * specified in `data`. For example: `browser.version` or
33087 * `browser.name`. If your object parameter name contains a period, use
33088 * `\\` to escape it - i.e. `first\\.name`.
33089 * * `[]` - Array notation. DataTables can automatically combine data
33090 * from and array source, joining the data with the characters provided
33091 * between the two brackets. For example: `name[, ]` would provide a
33092 * comma-space separated list from the source array. If no characters
33093 * are provided between the brackets, the original array source is
33094 * returned.
33095 * * `()` - Function notation. Adding `()` to the end of a parameter will
33096 * execute a function of the name given. For example: `browser()` for a
33097 * simple function on the data source, `browser.version()` for a
33098 * function in a nested property or even `browser().version` to get an
33099 * object property if the function called returns an object.
33100 * * `object` - use different data for the different data types requested by
33101 * DataTables ('filter', 'display', 'type' or 'sort'). The property names
33102 * of the object is the data type the property refers to and the value can
33103 * defined using an integer, string or function using the same rules as
33104 * `render` normally does. Note that an `_` option _must_ be specified.
33105 * This is the default value to use if you haven't specified a value for
33106 * the data type requested by DataTables.
33107 * * `function` - the function given will be executed whenever DataTables
33108 * needs to set or get the data for a cell in the column. The function
33109 * takes three parameters:
33110 * * Parameters:
33111 * * {array|object} The data source for the row (based on `data`)
33112 * * {string} The type call data requested - this will be 'filter',
33113 * 'display', 'type' or 'sort'.
33114 * * {array|object} The full data source for the row (not based on
33115 * `data`)
33116 * * Return:
33117 * * The return value from the function is what will be used for the
33118 * data requested.
33119 *
33120 * @type string|int|function|object|null
33121 * @default null Use the data source value.
33122 *
33123 * @name DataTable.defaults.column.render
33124 * @dtopt Columns
33125 *
33126 * @example
33127 * // Create a comma separated list from an array of objects
33128 * $(document).ready( function() {
33129 * $('#example').dataTable( {
33130 * "ajaxSource": "sources/deep.txt",
33131 * "columns": [
33132 * { "data": "engine" },
33133 * { "data": "browser" },
33134 * {
33135 * "data": "platform",
33136 * "render": "[, ].name"
33137 * }
33138 * ]
33139 * } );
33140 * } );
33141 *
33142 * @example
33143 * // Execute a function to obtain data
33144 * $(document).ready( function() {
33145 * $('#example').dataTable( {
33146 * "columnDefs": [ {
33147 * "targets": [ 0 ],
33148 * "data": null, // Use the full data source object for the renderer's source
33149 * "render": "browserName()"
33150 * } ]
33151 * } );
33152 * } );
33153 *
33154 * @example
33155 * // As an object, extracting different data for the different types
33156 * // This would be used with a data source such as:
33157 * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
33158 * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
33159 * // (which has both forms) is used for filtering for if a user inputs either format, while
33160 * // the formatted phone number is the one that is shown in the table.
33161 * $(document).ready( function() {
33162 * $('#example').dataTable( {
33163 * "columnDefs": [ {
33164 * "targets": [ 0 ],
33165 * "data": null, // Use the full data source object for the renderer's source
33166 * "render": {
33167 * "_": "phone",
33168 * "filter": "phone_filter",
33169 * "display": "phone_display"
33170 * }
33171 * } ]
33172 * } );
33173 * } );
33174 *
33175 * @example
33176 * // Use as a function to create a link from the data source
33177 * $(document).ready( function() {
33178 * $('#example').dataTable( {
33179 * "columnDefs": [ {
33180 * "targets": [ 0 ],
33181 * "data": "download_link",
33182 * "render": function ( data, type, full ) {
33183 * return '<a href="'+data+'">Download</a>';
33184 * }
33185 * } ]
33186 * } );
33187 * } );
33188 */
33189 "mRender": null,
33190
33191
33192 /**
33193 * Change the cell type created for the column - either TD cells or TH cells. This
33194 * can be useful as TH cells have semantic meaning in the table body, allowing them
33195 * to act as a header for a row (you may wish to add scope='row' to the TH elements).
33196 * @type string
33197 * @default td
33198 *
33199 * @name DataTable.defaults.column.cellType
33200 * @dtopt Columns
33201 *
33202 * @example
33203 * // Make the first column use TH cells
33204 * $(document).ready( function() {
33205 * $('#example').dataTable( {
33206 * "columnDefs": [ {
33207 * "targets": [ 0 ],
33208 * "cellType": "th"
33209 * } ]
33210 * } );
33211 * } );
33212 */
33213 "sCellType": "td",
33214
33215
33216 /**
33217 * Class to give to each cell in this column.
33218 * @type string
33219 * @default <i>Empty string</i>
33220 *
33221 * @name DataTable.defaults.column.class
33222 * @dtopt Columns
33223 *
33224 * @example
33225 * // Using `columnDefs`
33226 * $(document).ready( function() {
33227 * $('#example').dataTable( {
33228 * "columnDefs": [
33229 * { "class": "my_class", "targets": [ 0 ] }
33230 * ]
33231 * } );
33232 * } );
33233 *
33234 * @example
33235 * // Using `columns`
33236 * $(document).ready( function() {
33237 * $('#example').dataTable( {
33238 * "columns": [
33239 * { "class": "my_class" },
33240 * null,
33241 * null,
33242 * null,
33243 * null
33244 * ]
33245 * } );
33246 * } );
33247 */
33248 "sClass": "",
33249
33250 /**
33251 * When DataTables calculates the column widths to assign to each column,
33252 * it finds the longest string in each column and then constructs a
33253 * temporary table and reads the widths from that. The problem with this
33254 * is that "mmm" is much wider then "iiii", but the latter is a longer
33255 * string - thus the calculation can go wrong (doing it properly and putting
33256 * it into an DOM object and measuring that is horribly(!) slow). Thus as
33257 * a "work around" we provide this option. It will append its value to the
33258 * text that is found to be the longest string for the column - i.e. padding.
33259 * Generally you shouldn't need this!
33260 * @type string
33261 * @default <i>Empty string<i>
33262 *
33263 * @name DataTable.defaults.column.contentPadding
33264 * @dtopt Columns
33265 *
33266 * @example
33267 * // Using `columns`
33268 * $(document).ready( function() {
33269 * $('#example').dataTable( {
33270 * "columns": [
33271 * null,
33272 * null,
33273 * null,
33274 * {
33275 * "contentPadding": "mmm"
33276 * }
33277 * ]
33278 * } );
33279 * } );
33280 */
33281 "sContentPadding": "",
33282
33283
33284 /**
33285 * Allows a default value to be given for a column's data, and will be used
33286 * whenever a null data source is encountered (this can be because `data`
33287 * is set to null, or because the data source itself is null).
33288 * @type string
33289 * @default null
33290 *
33291 * @name DataTable.defaults.column.defaultContent
33292 * @dtopt Columns
33293 *
33294 * @example
33295 * // Using `columnDefs`
33296 * $(document).ready( function() {
33297 * $('#example').dataTable( {
33298 * "columnDefs": [
33299 * {
33300 * "data": null,
33301 * "defaultContent": "Edit",
33302 * "targets": [ -1 ]
33303 * }
33304 * ]
33305 * } );
33306 * } );
33307 *
33308 * @example
33309 * // Using `columns`
33310 * $(document).ready( function() {
33311 * $('#example').dataTable( {
33312 * "columns": [
33313 * null,
33314 * null,
33315 * null,
33316 * {
33317 * "data": null,
33318 * "defaultContent": "Edit"
33319 * }
33320 * ]
33321 * } );
33322 * } );
33323 */
33324 "sDefaultContent": null,
33325
33326
33327 /**
33328 * This parameter is only used in DataTables' server-side processing. It can
33329 * be exceptionally useful to know what columns are being displayed on the
33330 * client side, and to map these to database fields. When defined, the names
33331 * also allow DataTables to reorder information from the server if it comes
33332 * back in an unexpected order (i.e. if you switch your columns around on the
33333 * client-side, your server-side code does not also need updating).
33334 * @type string
33335 * @default <i>Empty string</i>
33336 *
33337 * @name DataTable.defaults.column.name
33338 * @dtopt Columns
33339 *
33340 * @example
33341 * // Using `columnDefs`
33342 * $(document).ready( function() {
33343 * $('#example').dataTable( {
33344 * "columnDefs": [
33345 * { "name": "engine", "targets": [ 0 ] },
33346 * { "name": "browser", "targets": [ 1 ] },
33347 * { "name": "platform", "targets": [ 2 ] },
33348 * { "name": "version", "targets": [ 3 ] },
33349 * { "name": "grade", "targets": [ 4 ] }
33350 * ]
33351 * } );
33352 * } );
33353 *
33354 * @example
33355 * // Using `columns`
33356 * $(document).ready( function() {
33357 * $('#example').dataTable( {
33358 * "columns": [
33359 * { "name": "engine" },
33360 * { "name": "browser" },
33361 * { "name": "platform" },
33362 * { "name": "version" },
33363 * { "name": "grade" }
33364 * ]
33365 * } );
33366 * } );
33367 */
33368 "sName": "",
33369
33370
33371 /**
33372 * Defines a data source type for the ordering which can be used to read
33373 * real-time information from the table (updating the internally cached
33374 * version) prior to ordering. This allows ordering to occur on user
33375 * editable elements such as form inputs.
33376 * @type string
33377 * @default std
33378 *
33379 * @name DataTable.defaults.column.orderDataType
33380 * @dtopt Columns
33381 *
33382 * @example
33383 * // Using `columnDefs`
33384 * $(document).ready( function() {
33385 * $('#example').dataTable( {
33386 * "columnDefs": [
33387 * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
33388 * { "type": "numeric", "targets": [ 3 ] },
33389 * { "orderDataType": "dom-select", "targets": [ 4 ] },
33390 * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
33391 * ]
33392 * } );
33393 * } );
33394 *
33395 * @example
33396 * // Using `columns`
33397 * $(document).ready( function() {
33398 * $('#example').dataTable( {
33399 * "columns": [
33400 * null,
33401 * null,
33402 * { "orderDataType": "dom-text" },
33403 * { "orderDataType": "dom-text", "type": "numeric" },
33404 * { "orderDataType": "dom-select" },
33405 * { "orderDataType": "dom-checkbox" }
33406 * ]
33407 * } );
33408 * } );
33409 */
33410 "sSortDataType": "std",
33411
33412
33413 /**
33414 * The title of this column.
33415 * @type string
33416 * @default null <i>Derived from the 'TH' value for this column in the
33417 * original HTML table.</i>
33418 *
33419 * @name DataTable.defaults.column.title
33420 * @dtopt Columns
33421 *
33422 * @example
33423 * // Using `columnDefs`
33424 * $(document).ready( function() {
33425 * $('#example').dataTable( {
33426 * "columnDefs": [
33427 * { "title": "My column title", "targets": [ 0 ] }
33428 * ]
33429 * } );
33430 * } );
33431 *
33432 * @example
33433 * // Using `columns`
33434 * $(document).ready( function() {
33435 * $('#example').dataTable( {
33436 * "columns": [
33437 * { "title": "My column title" },
33438 * null,
33439 * null,
33440 * null,
33441 * null
33442 * ]
33443 * } );
33444 * } );
33445 */
33446 "sTitle": null,
33447
33448
33449 /**
33450 * The type allows you to specify how the data for this column will be
33451 * ordered. Four types (string, numeric, date and html (which will strip
33452 * HTML tags before ordering)) are currently available. Note that only date
33453 * formats understood by Javascript's Date() object will be accepted as type
33454 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
33455 * 'numeric', 'date' or 'html' (by default). Further types can be adding
33456 * through plug-ins.
33457 * @type string
33458 * @default null <i>Auto-detected from raw data</i>
33459 *
33460 * @name DataTable.defaults.column.type
33461 * @dtopt Columns
33462 *
33463 * @example
33464 * // Using `columnDefs`
33465 * $(document).ready( function() {
33466 * $('#example').dataTable( {
33467 * "columnDefs": [
33468 * { "type": "html", "targets": [ 0 ] }
33469 * ]
33470 * } );
33471 * } );
33472 *
33473 * @example
33474 * // Using `columns`
33475 * $(document).ready( function() {
33476 * $('#example').dataTable( {
33477 * "columns": [
33478 * { "type": "html" },
33479 * null,
33480 * null,
33481 * null,
33482 * null
33483 * ]
33484 * } );
33485 * } );
33486 */
33487 "sType": null,
33488
33489
33490 /**
33491 * Defining the width of the column, this parameter may take any CSS value
33492 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
33493 * been given a specific width through this interface ensuring that the table
33494 * remains readable.
33495 * @type string
33496 * @default null <i>Automatic</i>
33497 *
33498 * @name DataTable.defaults.column.width
33499 * @dtopt Columns
33500 *
33501 * @example
33502 * // Using `columnDefs`
33503 * $(document).ready( function() {
33504 * $('#example').dataTable( {
33505 * "columnDefs": [
33506 * { "width": "20%", "targets": [ 0 ] }
33507 * ]
33508 * } );
33509 * } );
33510 *
33511 * @example
33512 * // Using `columns`
33513 * $(document).ready( function() {
33514 * $('#example').dataTable( {
33515 * "columns": [
33516 * { "width": "20%" },
33517 * null,
33518 * null,
33519 * null,
33520 * null
33521 * ]
33522 * } );
33523 * } );
33524 */
33525 "sWidth": null
33526 };
33527
33528 _fnHungarianMap( DataTable.defaults.column );
33529
33530
33531
33532 /**
33533 * DataTables settings object - this holds all the information needed for a
33534 * given table, including configuration, data and current application of the
33535 * table options. DataTables does not have a single instance for each DataTable
33536 * with the settings attached to that instance, but rather instances of the
33537 * DataTable "class" are created on-the-fly as needed (typically by a
33538 * $().dataTable() call) and the settings object is then applied to that
33539 * instance.
33540 *
33541 * Note that this object is related to {@link DataTable.defaults} but this
33542 * one is the internal data store for DataTables's cache of columns. It should
33543 * NOT be manipulated outside of DataTables. Any configuration should be done
33544 * through the initialisation options.
33545 * @namespace
33546 * @todo Really should attach the settings object to individual instances so we
33547 * don't need to create new instances on each $().dataTable() call (if the
33548 * table already exists). It would also save passing oSettings around and
33549 * into every single function. However, this is a very significant
33550 * architecture change for DataTables and will almost certainly break
33551 * backwards compatibility with older installations. This is something that
33552 * will be done in 2.0.
33553 */
33554 DataTable.models.oSettings = {
33555 /**
33556 * Primary features of DataTables and their enablement state.
33557 * @namespace
33558 */
33559 "oFeatures": {
33560
33561 /**
33562 * Flag to say if DataTables should automatically try to calculate the
33563 * optimum table and columns widths (true) or not (false).
33564 * Note that this parameter will be set by the initialisation routine. To
33565 * set a default use {@link DataTable.defaults}.
33566 * @type boolean
33567 */
33568 "bAutoWidth": null,
33569
33570 /**
33571 * Delay the creation of TR and TD elements until they are actually
33572 * needed by a driven page draw. This can give a significant speed
33573 * increase for Ajax source and Javascript source data, but makes no
33574 * difference at all fro DOM and server-side processing tables.
33575 * Note that this parameter will be set by the initialisation routine. To
33576 * set a default use {@link DataTable.defaults}.
33577 * @type boolean
33578 */
33579 "bDeferRender": null,
33580
33581 /**
33582 * Enable filtering on the table or not. Note that if this is disabled
33583 * then there is no filtering at all on the table, including fnFilter.
33584 * To just remove the filtering input use sDom and remove the 'f' option.
33585 * Note that this parameter will be set by the initialisation routine. To
33586 * set a default use {@link DataTable.defaults}.
33587 * @type boolean
33588 */
33589 "bFilter": null,
33590
33591 /**
33592 * Table information element (the 'Showing x of y records' div) enable
33593 * flag.
33594 * Note that this parameter will be set by the initialisation routine. To
33595 * set a default use {@link DataTable.defaults}.
33596 * @type boolean
33597 */
33598 "bInfo": null,
33599
33600 /**
33601 * Present a user control allowing the end user to change the page size
33602 * when pagination is enabled.
33603 * Note that this parameter will be set by the initialisation routine. To
33604 * set a default use {@link DataTable.defaults}.
33605 * @type boolean
33606 */
33607 "bLengthChange": null,
33608
33609 /**
33610 * Pagination enabled or not. Note that if this is disabled then length
33611 * changing must also be disabled.
33612 * Note that this parameter will be set by the initialisation routine. To
33613 * set a default use {@link DataTable.defaults}.
33614 * @type boolean
33615 */
33616 "bPaginate": null,
33617
33618 /**
33619 * Processing indicator enable flag whenever DataTables is enacting a
33620 * user request - typically an Ajax request for server-side processing.
33621 * Note that this parameter will be set by the initialisation routine. To
33622 * set a default use {@link DataTable.defaults}.
33623 * @type boolean
33624 */
33625 "bProcessing": null,
33626
33627 /**
33628 * Server-side processing enabled flag - when enabled DataTables will
33629 * get all data from the server for every draw - there is no filtering,
33630 * sorting or paging done on the client-side.
33631 * Note that this parameter will be set by the initialisation routine. To
33632 * set a default use {@link DataTable.defaults}.
33633 * @type boolean
33634 */
33635 "bServerSide": null,
33636
33637 /**
33638 * Sorting enablement flag.
33639 * Note that this parameter will be set by the initialisation routine. To
33640 * set a default use {@link DataTable.defaults}.
33641 * @type boolean
33642 */
33643 "bSort": null,
33644
33645 /**
33646 * Multi-column sorting
33647 * Note that this parameter will be set by the initialisation routine. To
33648 * set a default use {@link DataTable.defaults}.
33649 * @type boolean
33650 */
33651 "bSortMulti": null,
33652
33653 /**
33654 * Apply a class to the columns which are being sorted to provide a
33655 * visual highlight or not. This can slow things down when enabled since
33656 * there is a lot of DOM interaction.
33657 * Note that this parameter will be set by the initialisation routine. To
33658 * set a default use {@link DataTable.defaults}.
33659 * @type boolean
33660 */
33661 "bSortClasses": null,
33662
33663 /**
33664 * State saving enablement flag.
33665 * Note that this parameter will be set by the initialisation routine. To
33666 * set a default use {@link DataTable.defaults}.
33667 * @type boolean
33668 */
33669 "bStateSave": null
33670 },
33671
33672
33673 /**
33674 * Scrolling settings for a table.
33675 * @namespace
33676 */
33677 "oScroll": {
33678 /**
33679 * When the table is shorter in height than sScrollY, collapse the
33680 * table container down to the height of the table (when true).
33681 * Note that this parameter will be set by the initialisation routine. To
33682 * set a default use {@link DataTable.defaults}.
33683 * @type boolean
33684 */
33685 "bCollapse": null,
33686
33687 /**
33688 * Width of the scrollbar for the web-browser's platform. Calculated
33689 * during table initialisation.
33690 * @type int
33691 * @default 0
33692 */
33693 "iBarWidth": 0,
33694
33695 /**
33696 * Viewport width for horizontal scrolling. Horizontal scrolling is
33697 * disabled if an empty string.
33698 * Note that this parameter will be set by the initialisation routine. To
33699 * set a default use {@link DataTable.defaults}.
33700 * @type string
33701 */
33702 "sX": null,
33703
33704 /**
33705 * Width to expand the table to when using x-scrolling. Typically you
33706 * should not need to use this.
33707 * Note that this parameter will be set by the initialisation routine. To
33708 * set a default use {@link DataTable.defaults}.
33709 * @type string
33710 * @deprecated
33711 */
33712 "sXInner": null,
33713
33714 /**
33715 * Viewport height for vertical scrolling. Vertical scrolling is disabled
33716 * if an empty string.
33717 * Note that this parameter will be set by the initialisation routine. To
33718 * set a default use {@link DataTable.defaults}.
33719 * @type string
33720 */
33721 "sY": null
33722 },
33723
33724 /**
33725 * Language information for the table.
33726 * @namespace
33727 * @extends DataTable.defaults.oLanguage
33728 */
33729 "oLanguage": {
33730 /**
33731 * Information callback function. See
33732 * {@link DataTable.defaults.fnInfoCallback}
33733 * @type function
33734 * @default null
33735 */
33736 "fnInfoCallback": null
33737 },
33738
33739 /**
33740 * Browser support parameters
33741 * @namespace
33742 */
33743 "oBrowser": {
33744 /**
33745 * Indicate if the browser incorrectly calculates width:100% inside a
33746 * scrolling element (IE6/7)
33747 * @type boolean
33748 * @default false
33749 */
33750 "bScrollOversize": false,
33751
33752 /**
33753 * Determine if the vertical scrollbar is on the right or left of the
33754 * scrolling container - needed for rtl language layout, although not
33755 * all browsers move the scrollbar (Safari).
33756 * @type boolean
33757 * @default false
33758 */
33759 "bScrollbarLeft": false,
33760
33761 /**
33762 * Flag for if `getBoundingClientRect` is fully supported or not
33763 * @type boolean
33764 * @default false
33765 */
33766 "bBounding": false,
33767
33768 /**
33769 * Browser scrollbar width
33770 * @type integer
33771 * @default 0
33772 */
33773 "barWidth": 0
33774 },
33775
33776
33777 "ajax": null,
33778
33779
33780 /**
33781 * Array referencing the nodes which are used for the features. The
33782 * parameters of this object match what is allowed by sDom - i.e.
33783 * <ul>
33784 * <li>'l' - Length changing</li>
33785 * <li>'f' - Filtering input</li>
33786 * <li>'t' - The table!</li>
33787 * <li>'i' - Information</li>
33788 * <li>'p' - Pagination</li>
33789 * <li>'r' - pRocessing</li>
33790 * </ul>
33791 * @type array
33792 * @default []
33793 */
33794 "aanFeatures": [],
33795
33796 /**
33797 * Store data information - see {@link DataTable.models.oRow} for detailed
33798 * information.
33799 * @type array
33800 * @default []
33801 */
33802 "aoData": [],
33803
33804 /**
33805 * Array of indexes which are in the current display (after filtering etc)
33806 * @type array
33807 * @default []
33808 */
33809 "aiDisplay": [],
33810
33811 /**
33812 * Array of indexes for display - no filtering
33813 * @type array
33814 * @default []
33815 */
33816 "aiDisplayMaster": [],
33817
33818 /**
33819 * Map of row ids to data indexes
33820 * @type object
33821 * @default {}
33822 */
33823 "aIds": {},
33824
33825 /**
33826 * Store information about each column that is in use
33827 * @type array
33828 * @default []
33829 */
33830 "aoColumns": [],
33831
33832 /**
33833 * Store information about the table's header
33834 * @type array
33835 * @default []
33836 */
33837 "aoHeader": [],
33838
33839 /**
33840 * Store information about the table's footer
33841 * @type array
33842 * @default []
33843 */
33844 "aoFooter": [],
33845
33846 /**
33847 * Store the applied global search information in case we want to force a
33848 * research or compare the old search to a new one.
33849 * Note that this parameter will be set by the initialisation routine. To
33850 * set a default use {@link DataTable.defaults}.
33851 * @namespace
33852 * @extends DataTable.models.oSearch
33853 */
33854 "oPreviousSearch": {},
33855
33856 /**
33857 * Store the applied search for each column - see
33858 * {@link DataTable.models.oSearch} for the format that is used for the
33859 * filtering information for each column.
33860 * @type array
33861 * @default []
33862 */
33863 "aoPreSearchCols": [],
33864
33865 /**
33866 * Sorting that is applied to the table. Note that the inner arrays are
33867 * used in the following manner:
33868 * <ul>
33869 * <li>Index 0 - column number</li>
33870 * <li>Index 1 - current sorting direction</li>
33871 * </ul>
33872 * Note that this parameter will be set by the initialisation routine. To
33873 * set a default use {@link DataTable.defaults}.
33874 * @type array
33875 * @todo These inner arrays should really be objects
33876 */
33877 "aaSorting": null,
33878
33879 /**
33880 * Sorting that is always applied to the table (i.e. prefixed in front of
33881 * aaSorting).
33882 * Note that this parameter will be set by the initialisation routine. To
33883 * set a default use {@link DataTable.defaults}.
33884 * @type array
33885 * @default []
33886 */
33887 "aaSortingFixed": [],
33888
33889 /**
33890 * Classes to use for the striping of a table.
33891 * Note that this parameter will be set by the initialisation routine. To
33892 * set a default use {@link DataTable.defaults}.
33893 * @type array
33894 * @default []
33895 */
33896 "asStripeClasses": null,
33897
33898 /**
33899 * If restoring a table - we should restore its striping classes as well
33900 * @type array
33901 * @default []
33902 */
33903 "asDestroyStripes": [],
33904
33905 /**
33906 * If restoring a table - we should restore its width
33907 * @type int
33908 * @default 0
33909 */
33910 "sDestroyWidth": 0,
33911
33912 /**
33913 * Callback functions array for every time a row is inserted (i.e. on a draw).
33914 * @type array
33915 * @default []
33916 */
33917 "aoRowCallback": [],
33918
33919 /**
33920 * Callback functions for the header on each draw.
33921 * @type array
33922 * @default []
33923 */
33924 "aoHeaderCallback": [],
33925
33926 /**
33927 * Callback function for the footer on each draw.
33928 * @type array
33929 * @default []
33930 */
33931 "aoFooterCallback": [],
33932
33933 /**
33934 * Array of callback functions for draw callback functions
33935 * @type array
33936 * @default []
33937 */
33938 "aoDrawCallback": [],
33939
33940 /**
33941 * Array of callback functions for row created function
33942 * @type array
33943 * @default []
33944 */
33945 "aoRowCreatedCallback": [],
33946
33947 /**
33948 * Callback functions for just before the table is redrawn. A return of
33949 * false will be used to cancel the draw.
33950 * @type array
33951 * @default []
33952 */
33953 "aoPreDrawCallback": [],
33954
33955 /**
33956 * Callback functions for when the table has been initialised.
33957 * @type array
33958 * @default []
33959 */
33960 "aoInitComplete": [],
33961
33962
33963 /**
33964 * Callbacks for modifying the settings to be stored for state saving, prior to
33965 * saving state.
33966 * @type array
33967 * @default []
33968 */
33969 "aoStateSaveParams": [],
33970
33971 /**
33972 * Callbacks for modifying the settings that have been stored for state saving
33973 * prior to using the stored values to restore the state.
33974 * @type array
33975 * @default []
33976 */
33977 "aoStateLoadParams": [],
33978
33979 /**
33980 * Callbacks for operating on the settings object once the saved state has been
33981 * loaded
33982 * @type array
33983 * @default []
33984 */
33985 "aoStateLoaded": [],
33986
33987 /**
33988 * Cache the table ID for quick access
33989 * @type string
33990 * @default <i>Empty string</i>
33991 */
33992 "sTableId": "",
33993
33994 /**
33995 * The TABLE node for the main table
33996 * @type node
33997 * @default null
33998 */
33999 "nTable": null,
34000
34001 /**
34002 * Permanent ref to the thead element
34003 * @type node
34004 * @default null
34005 */
34006 "nTHead": null,
34007
34008 /**
34009 * Permanent ref to the tfoot element - if it exists
34010 * @type node
34011 * @default null
34012 */
34013 "nTFoot": null,
34014
34015 /**
34016 * Permanent ref to the tbody element
34017 * @type node
34018 * @default null
34019 */
34020 "nTBody": null,
34021
34022 /**
34023 * Cache the wrapper node (contains all DataTables controlled elements)
34024 * @type node
34025 * @default null
34026 */
34027 "nTableWrapper": null,
34028
34029 /**
34030 * Indicate if when using server-side processing the loading of data
34031 * should be deferred until the second draw.
34032 * Note that this parameter will be set by the initialisation routine. To
34033 * set a default use {@link DataTable.defaults}.
34034 * @type boolean
34035 * @default false
34036 */
34037 "bDeferLoading": false,
34038
34039 /**
34040 * Indicate if all required information has been read in
34041 * @type boolean
34042 * @default false
34043 */
34044 "bInitialised": false,
34045
34046 /**
34047 * Information about open rows. Each object in the array has the parameters
34048 * 'nTr' and 'nParent'
34049 * @type array
34050 * @default []
34051 */
34052 "aoOpenRows": [],
34053
34054 /**
34055 * Dictate the positioning of DataTables' control elements - see
34056 * {@link DataTable.model.oInit.sDom}.
34057 * Note that this parameter will be set by the initialisation routine. To
34058 * set a default use {@link DataTable.defaults}.
34059 * @type string
34060 * @default null
34061 */
34062 "sDom": null,
34063
34064 /**
34065 * Search delay (in mS)
34066 * @type integer
34067 * @default null
34068 */
34069 "searchDelay": null,
34070
34071 /**
34072 * Which type of pagination should be used.
34073 * Note that this parameter will be set by the initialisation routine. To
34074 * set a default use {@link DataTable.defaults}.
34075 * @type string
34076 * @default two_button
34077 */
34078 "sPaginationType": "two_button",
34079
34080 /**
34081 * The state duration (for `stateSave`) in seconds.
34082 * Note that this parameter will be set by the initialisation routine. To
34083 * set a default use {@link DataTable.defaults}.
34084 * @type int
34085 * @default 0
34086 */
34087 "iStateDuration": 0,
34088
34089 /**
34090 * Array of callback functions for state saving. Each array element is an
34091 * object with the following parameters:
34092 * <ul>
34093 * <li>function:fn - function to call. Takes two parameters, oSettings
34094 * and the JSON string to save that has been thus far created. Returns
34095 * a JSON string to be inserted into a json object
34096 * (i.e. '"param": [ 0, 1, 2]')</li>
34097 * <li>string:sName - name of callback</li>
34098 * </ul>
34099 * @type array
34100 * @default []
34101 */
34102 "aoStateSave": [],
34103
34104 /**
34105 * Array of callback functions for state loading. Each array element is an
34106 * object with the following parameters:
34107 * <ul>
34108 * <li>function:fn - function to call. Takes two parameters, oSettings
34109 * and the object stored. May return false to cancel state loading</li>
34110 * <li>string:sName - name of callback</li>
34111 * </ul>
34112 * @type array
34113 * @default []
34114 */
34115 "aoStateLoad": [],
34116
34117 /**
34118 * State that was saved. Useful for back reference
34119 * @type object
34120 * @default null
34121 */
34122 "oSavedState": null,
34123
34124 /**
34125 * State that was loaded. Useful for back reference
34126 * @type object
34127 * @default null
34128 */
34129 "oLoadedState": null,
34130
34131 /**
34132 * Source url for AJAX data for the table.
34133 * Note that this parameter will be set by the initialisation routine. To
34134 * set a default use {@link DataTable.defaults}.
34135 * @type string
34136 * @default null
34137 */
34138 "sAjaxSource": null,
34139
34140 /**
34141 * Property from a given object from which to read the table data from. This
34142 * can be an empty string (when not server-side processing), in which case
34143 * it is assumed an an array is given directly.
34144 * Note that this parameter will be set by the initialisation routine. To
34145 * set a default use {@link DataTable.defaults}.
34146 * @type string
34147 */
34148 "sAjaxDataProp": null,
34149
34150 /**
34151 * Note if draw should be blocked while getting data
34152 * @type boolean
34153 * @default true
34154 */
34155 "bAjaxDataGet": true,
34156
34157 /**
34158 * The last jQuery XHR object that was used for server-side data gathering.
34159 * This can be used for working with the XHR information in one of the
34160 * callbacks
34161 * @type object
34162 * @default null
34163 */
34164 "jqXHR": null,
34165
34166 /**
34167 * JSON returned from the server in the last Ajax request
34168 * @type object
34169 * @default undefined
34170 */
34171 "json": undefined,
34172
34173 /**
34174 * Data submitted as part of the last Ajax request
34175 * @type object
34176 * @default undefined
34177 */
34178 "oAjaxData": undefined,
34179
34180 /**
34181 * Function to get the server-side data.
34182 * Note that this parameter will be set by the initialisation routine. To
34183 * set a default use {@link DataTable.defaults}.
34184 * @type function
34185 */
34186 "fnServerData": null,
34187
34188 /**
34189 * Functions which are called prior to sending an Ajax request so extra
34190 * parameters can easily be sent to the server
34191 * @type array
34192 * @default []
34193 */
34194 "aoServerParams": [],
34195
34196 /**
34197 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
34198 * required).
34199 * Note that this parameter will be set by the initialisation routine. To
34200 * set a default use {@link DataTable.defaults}.
34201 * @type string
34202 */
34203 "sServerMethod": null,
34204
34205 /**
34206 * Format numbers for display.
34207 * Note that this parameter will be set by the initialisation routine. To
34208 * set a default use {@link DataTable.defaults}.
34209 * @type function
34210 */
34211 "fnFormatNumber": null,
34212
34213 /**
34214 * List of options that can be used for the user selectable length menu.
34215 * Note that this parameter will be set by the initialisation routine. To
34216 * set a default use {@link DataTable.defaults}.
34217 * @type array
34218 * @default []
34219 */
34220 "aLengthMenu": null,
34221
34222 /**
34223 * Counter for the draws that the table does. Also used as a tracker for
34224 * server-side processing
34225 * @type int
34226 * @default 0
34227 */
34228 "iDraw": 0,
34229
34230 /**
34231 * Indicate if a redraw is being done - useful for Ajax
34232 * @type boolean
34233 * @default false
34234 */
34235 "bDrawing": false,
34236
34237 /**
34238 * Draw index (iDraw) of the last error when parsing the returned data
34239 * @type int
34240 * @default -1
34241 */
34242 "iDrawError": -1,
34243
34244 /**
34245 * Paging display length
34246 * @type int
34247 * @default 10
34248 */
34249 "_iDisplayLength": 10,
34250
34251 /**
34252 * Paging start point - aiDisplay index
34253 * @type int
34254 * @default 0
34255 */
34256 "_iDisplayStart": 0,
34257
34258 /**
34259 * Server-side processing - number of records in the result set
34260 * (i.e. before filtering), Use fnRecordsTotal rather than
34261 * this property to get the value of the number of records, regardless of
34262 * the server-side processing setting.
34263 * @type int
34264 * @default 0
34265 * @private
34266 */
34267 "_iRecordsTotal": 0,
34268
34269 /**
34270 * Server-side processing - number of records in the current display set
34271 * (i.e. after filtering). Use fnRecordsDisplay rather than
34272 * this property to get the value of the number of records, regardless of
34273 * the server-side processing setting.
34274 * @type boolean
34275 * @default 0
34276 * @private
34277 */
34278 "_iRecordsDisplay": 0,
34279
34280 /**
34281 * Flag to indicate if jQuery UI marking and classes should be used.
34282 * Note that this parameter will be set by the initialisation routine. To
34283 * set a default use {@link DataTable.defaults}.
34284 * @type boolean
34285 */
34286 "bJUI": null,
34287
34288 /**
34289 * The classes to use for the table
34290 * @type object
34291 * @default {}
34292 */
34293 "oClasses": {},
34294
34295 /**
34296 * Flag attached to the settings object so you can check in the draw
34297 * callback if filtering has been done in the draw. Deprecated in favour of
34298 * events.
34299 * @type boolean
34300 * @default false
34301 * @deprecated
34302 */
34303 "bFiltered": false,
34304
34305 /**
34306 * Flag attached to the settings object so you can check in the draw
34307 * callback if sorting has been done in the draw. Deprecated in favour of
34308 * events.
34309 * @type boolean
34310 * @default false
34311 * @deprecated
34312 */
34313 "bSorted": false,
34314
34315 /**
34316 * Indicate that if multiple rows are in the header and there is more than
34317 * one unique cell per column, if the top one (true) or bottom one (false)
34318 * should be used for sorting / title by DataTables.
34319 * Note that this parameter will be set by the initialisation routine. To
34320 * set a default use {@link DataTable.defaults}.
34321 * @type boolean
34322 */
34323 "bSortCellsTop": null,
34324
34325 /**
34326 * Initialisation object that is used for the table
34327 * @type object
34328 * @default null
34329 */
34330 "oInit": null,
34331
34332 /**
34333 * Destroy callback functions - for plug-ins to attach themselves to the
34334 * destroy so they can clean up markup and events.
34335 * @type array
34336 * @default []
34337 */
34338 "aoDestroyCallback": [],
34339
34340
34341 /**
34342 * Get the number of records in the current record set, before filtering
34343 * @type function
34344 */
34345 "fnRecordsTotal": function ()
34346 {
34347 return _fnDataSource( this ) == 'ssp' ?
34348 this._iRecordsTotal * 1 :
34349 this.aiDisplayMaster.length;
34350 },
34351
34352 /**
34353 * Get the number of records in the current record set, after filtering
34354 * @type function
34355 */
34356 "fnRecordsDisplay": function ()
34357 {
34358 return _fnDataSource( this ) == 'ssp' ?
34359 this._iRecordsDisplay * 1 :
34360 this.aiDisplay.length;
34361 },
34362
34363 /**
34364 * Get the display end point - aiDisplay index
34365 * @type function
34366 */
34367 "fnDisplayEnd": function ()
34368 {
34369 var
34370 len = this._iDisplayLength,
34371 start = this._iDisplayStart,
34372 calc = start + len,
34373 records = this.aiDisplay.length,
34374 features = this.oFeatures,
34375 paginate = features.bPaginate;
34376
34377 if ( features.bServerSide ) {
34378 return paginate === false || len === -1 ?
34379 start + records :
34380 Math.min( start+len, this._iRecordsDisplay );
34381 }
34382 else {
34383 return ! paginate || calc>records || len===-1 ?
34384 records :
34385 calc;
34386 }
34387 },
34388
34389 /**
34390 * The DataTables object for this table
34391 * @type object
34392 * @default null
34393 */
34394 "oInstance": null,
34395
34396 /**
34397 * Unique identifier for each instance of the DataTables object. If there
34398 * is an ID on the table node, then it takes that value, otherwise an
34399 * incrementing internal counter is used.
34400 * @type string
34401 * @default null
34402 */
34403 "sInstance": null,
34404
34405 /**
34406 * tabindex attribute value that is added to DataTables control elements, allowing
34407 * keyboard navigation of the table and its controls.
34408 */
34409 "iTabIndex": 0,
34410
34411 /**
34412 * DIV container for the footer scrolling table if scrolling
34413 */
34414 "nScrollHead": null,
34415
34416 /**
34417 * DIV container for the footer scrolling table if scrolling
34418 */
34419 "nScrollFoot": null,
34420
34421 /**
34422 * Last applied sort
34423 * @type array
34424 * @default []
34425 */
34426 "aLastSort": [],
34427
34428 /**
34429 * Stored plug-in instances
34430 * @type object
34431 * @default {}
34432 */
34433 "oPlugins": {},
34434
34435 /**
34436 * Function used to get a row's id from the row's data
34437 * @type function
34438 * @default null
34439 */
34440 "rowIdFn": null,
34441
34442 /**
34443 * Data location where to store a row's id
34444 * @type string
34445 * @default null
34446 */
34447 "rowId": null
34448 };
34449
34450 /**
34451 * Extension object for DataTables that is used to provide all extension
34452 * options.
34453 *
34454 * Note that the `DataTable.ext` object is available through
34455 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
34456 * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
34457 * @namespace
34458 * @extends DataTable.models.ext
34459 */
34460
34461
34462 /**
34463 * DataTables extensions
34464 *
34465 * This namespace acts as a collection area for plug-ins that can be used to
34466 * extend DataTables capabilities. Indeed many of the build in methods
34467 * use this method to provide their own capabilities (sorting methods for
34468 * example).
34469 *
34470 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
34471 * reasons
34472 *
34473 * @namespace
34474 */
34475 DataTable.ext = _ext = {
34476 /**
34477 * Buttons. For use with the Buttons extension for DataTables. This is
34478 * defined here so other extensions can define buttons regardless of load
34479 * order. It is _not_ used by DataTables core.
34480 *
34481 * @type object
34482 * @default {}
34483 */
34484 buttons: {},
34485
34486
34487 /**
34488 * Element class names
34489 *
34490 * @type object
34491 * @default {}
34492 */
34493 classes: {},
34494
34495
34496 /**
34497 * DataTables build type (expanded by the download builder)
34498 *
34499 * @type string
34500 */
34501 builder: "-source-",
34502
34503
34504 /**
34505 * Error reporting.
34506 *
34507 * How should DataTables report an error. Can take the value 'alert',
34508 * 'throw', 'none' or a function.
34509 *
34510 * @type string|function
34511 * @default alert
34512 */
34513 errMode: "alert",
34514
34515
34516 /**
34517 * Feature plug-ins.
34518 *
34519 * This is an array of objects which describe the feature plug-ins that are
34520 * available to DataTables. These feature plug-ins are then available for
34521 * use through the `dom` initialisation option.
34522 *
34523 * Each feature plug-in is described by an object which must have the
34524 * following properties:
34525 *
34526 * * `fnInit` - function that is used to initialise the plug-in,
34527 * * `cFeature` - a character so the feature can be enabled by the `dom`
34528 * instillation option. This is case sensitive.
34529 *
34530 * The `fnInit` function has the following input parameters:
34531 *
34532 * 1. `{object}` DataTables settings object: see
34533 * {@link DataTable.models.oSettings}
34534 *
34535 * And the following return is expected:
34536 *
34537 * * {node|null} The element which contains your feature. Note that the
34538 * return may also be void if your plug-in does not require to inject any
34539 * DOM elements into DataTables control (`dom`) - for example this might
34540 * be useful when developing a plug-in which allows table control via
34541 * keyboard entry
34542 *
34543 * @type array
34544 *
34545 * @example
34546 * $.fn.dataTable.ext.features.push( {
34547 * "fnInit": function( oSettings ) {
34548 * return new TableTools( { "oDTSettings": oSettings } );
34549 * },
34550 * "cFeature": "T"
34551 * } );
34552 */
34553 feature: [],
34554
34555
34556 /**
34557 * Row searching.
34558 *
34559 * This method of searching is complimentary to the default type based
34560 * searching, and a lot more comprehensive as it allows you complete control
34561 * over the searching logic. Each element in this array is a function
34562 * (parameters described below) that is called for every row in the table,
34563 * and your logic decides if it should be included in the searching data set
34564 * or not.
34565 *
34566 * Searching functions have the following input parameters:
34567 *
34568 * 1. `{object}` DataTables settings object: see
34569 * {@link DataTable.models.oSettings}
34570 * 2. `{array|object}` Data for the row to be processed (same as the
34571 * original format that was passed in as the data source, or an array
34572 * from a DOM data source
34573 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
34574 * can be useful to retrieve the `TR` element if you need DOM interaction.
34575 *
34576 * And the following return is expected:
34577 *
34578 * * {boolean} Include the row in the searched result set (true) or not
34579 * (false)
34580 *
34581 * Note that as with the main search ability in DataTables, technically this
34582 * is "filtering", since it is subtractive. However, for consistency in
34583 * naming we call it searching here.
34584 *
34585 * @type array
34586 * @default []
34587 *
34588 * @example
34589 * // The following example shows custom search being applied to the
34590 * // fourth column (i.e. the data[3] index) based on two input values
34591 * // from the end-user, matching the data in a certain range.
34592 * $.fn.dataTable.ext.search.push(
34593 * function( settings, data, dataIndex ) {
34594 * var min = document.getElementById('min').value * 1;
34595 * var max = document.getElementById('max').value * 1;
34596 * var version = data[3] == "-" ? 0 : data[3]*1;
34597 *
34598 * if ( min == "" && max == "" ) {
34599 * return true;
34600 * }
34601 * else if ( min == "" && version < max ) {
34602 * return true;
34603 * }
34604 * else if ( min < version && "" == max ) {
34605 * return true;
34606 * }
34607 * else if ( min < version && version < max ) {
34608 * return true;
34609 * }
34610 * return false;
34611 * }
34612 * );
34613 */
34614 search: [],
34615
34616
34617 /**
34618 * Selector extensions
34619 *
34620 * The `selector` option can be used to extend the options available for the
34621 * selector modifier options (`selector-modifier` object data type) that
34622 * each of the three built in selector types offer (row, column and cell +
34623 * their plural counterparts). For example the Select extension uses this
34624 * mechanism to provide an option to select only rows, columns and cells
34625 * that have been marked as selected by the end user (`{selected: true}`),
34626 * which can be used in conjunction with the existing built in selector
34627 * options.
34628 *
34629 * Each property is an array to which functions can be pushed. The functions
34630 * take three attributes:
34631 *
34632 * * Settings object for the host table
34633 * * Options object (`selector-modifier` object type)
34634 * * Array of selected item indexes
34635 *
34636 * The return is an array of the resulting item indexes after the custom
34637 * selector has been applied.
34638 *
34639 * @type object
34640 */
34641 selector: {
34642 cell: [],
34643 column: [],
34644 row: []
34645 },
34646
34647
34648 /**
34649 * Internal functions, exposed for used in plug-ins.
34650 *
34651 * Please note that you should not need to use the internal methods for
34652 * anything other than a plug-in (and even then, try to avoid if possible).
34653 * The internal function may change between releases.
34654 *
34655 * @type object
34656 * @default {}
34657 */
34658 internal: {},
34659
34660
34661 /**
34662 * Legacy configuration options. Enable and disable legacy options that
34663 * are available in DataTables.
34664 *
34665 * @type object
34666 */
34667 legacy: {
34668 /**
34669 * Enable / disable DataTables 1.9 compatible server-side processing
34670 * requests
34671 *
34672 * @type boolean
34673 * @default null
34674 */
34675 ajax: null
34676 },
34677
34678
34679 /**
34680 * Pagination plug-in methods.
34681 *
34682 * Each entry in this object is a function and defines which buttons should
34683 * be shown by the pagination rendering method that is used for the table:
34684 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
34685 * buttons are displayed in the document, while the functions here tell it
34686 * what buttons to display. This is done by returning an array of button
34687 * descriptions (what each button will do).
34688 *
34689 * Pagination types (the four built in options and any additional plug-in
34690 * options defined here) can be used through the `paginationType`
34691 * initialisation parameter.
34692 *
34693 * The functions defined take two parameters:
34694 *
34695 * 1. `{int} page` The current page index
34696 * 2. `{int} pages` The number of pages in the table
34697 *
34698 * Each function is expected to return an array where each element of the
34699 * array can be one of:
34700 *
34701 * * `first` - Jump to first page when activated
34702 * * `last` - Jump to last page when activated
34703 * * `previous` - Show previous page when activated
34704 * * `next` - Show next page when activated
34705 * * `{int}` - Show page of the index given
34706 * * `{array}` - A nested array containing the above elements to add a
34707 * containing 'DIV' element (might be useful for styling).
34708 *
34709 * Note that DataTables v1.9- used this object slightly differently whereby
34710 * an object with two functions would be defined for each plug-in. That
34711 * ability is still supported by DataTables 1.10+ to provide backwards
34712 * compatibility, but this option of use is now decremented and no longer
34713 * documented in DataTables 1.10+.
34714 *
34715 * @type object
34716 * @default {}
34717 *
34718 * @example
34719 * // Show previous, next and current page buttons only
34720 * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
34721 * return [ 'previous', page, 'next' ];
34722 * };
34723 */
34724 pager: {},
34725
34726
34727 renderer: {
34728 pageButton: {},
34729 header: {}
34730 },
34731
34732
34733 /**
34734 * Ordering plug-ins - custom data source
34735 *
34736 * The extension options for ordering of data available here is complimentary
34737 * to the default type based ordering that DataTables typically uses. It
34738 * allows much greater control over the the data that is being used to
34739 * order a column, but is necessarily therefore more complex.
34740 *
34741 * This type of ordering is useful if you want to do ordering based on data
34742 * live from the DOM (for example the contents of an 'input' element) rather
34743 * than just the static string that DataTables knows of.
34744 *
34745 * The way these plug-ins work is that you create an array of the values you
34746 * wish to be ordering for the column in question and then return that
34747 * array. The data in the array much be in the index order of the rows in
34748 * the table (not the currently ordering order!). Which order data gathering
34749 * function is run here depends on the `dt-init columns.orderDataType`
34750 * parameter that is used for the column (if any).
34751 *
34752 * The functions defined take two parameters:
34753 *
34754 * 1. `{object}` DataTables settings object: see
34755 * {@link DataTable.models.oSettings}
34756 * 2. `{int}` Target column index
34757 *
34758 * Each function is expected to return an array:
34759 *
34760 * * `{array}` Data for the column to be ordering upon
34761 *
34762 * @type array
34763 *
34764 * @example
34765 * // Ordering using `input` node values
34766 * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
34767 * {
34768 * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
34769 * return $('input', td).val();
34770 * } );
34771 * }
34772 */
34773 order: {},
34774
34775
34776 /**
34777 * Type based plug-ins.
34778 *
34779 * Each column in DataTables has a type assigned to it, either by automatic
34780 * detection or by direct assignment using the `type` option for the column.
34781 * The type of a column will effect how it is ordering and search (plug-ins
34782 * can also make use of the column type if required).
34783 *
34784 * @namespace
34785 */
34786 type: {
34787 /**
34788 * Type detection functions.
34789 *
34790 * The functions defined in this object are used to automatically detect
34791 * a column's type, making initialisation of DataTables super easy, even
34792 * when complex data is in the table.
34793 *
34794 * The functions defined take two parameters:
34795 *
34796 * 1. `{*}` Data from the column cell to be analysed
34797 * 2. `{settings}` DataTables settings object. This can be used to
34798 * perform context specific type detection - for example detection
34799 * based on language settings such as using a comma for a decimal
34800 * place. Generally speaking the options from the settings will not
34801 * be required
34802 *
34803 * Each function is expected to return:
34804 *
34805 * * `{string|null}` Data type detected, or null if unknown (and thus
34806 * pass it on to the other type detection functions.
34807 *
34808 * @type array
34809 *
34810 * @example
34811 * // Currency type detection plug-in:
34812 * $.fn.dataTable.ext.type.detect.push(
34813 * function ( data, settings ) {
34814 * // Check the numeric part
34815 * if ( ! $.isNumeric( data.substring(1) ) ) {
34816 * return null;
34817 * }
34818 *
34819 * // Check prefixed by currency
34820 * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {
34821 * return 'currency';
34822 * }
34823 * return null;
34824 * }
34825 * );
34826 */
34827 detect: [],
34828
34829
34830 /**
34831 * Type based search formatting.
34832 *
34833 * The type based searching functions can be used to pre-format the
34834 * data to be search on. For example, it can be used to strip HTML
34835 * tags or to de-format telephone numbers for numeric only searching.
34836 *
34837 * Note that is a search is not defined for a column of a given type,
34838 * no search formatting will be performed.
34839 *
34840 * Pre-processing of searching data plug-ins - When you assign the sType
34841 * for a column (or have it automatically detected for you by DataTables
34842 * or a type detection plug-in), you will typically be using this for
34843 * custom sorting, but it can also be used to provide custom searching
34844 * by allowing you to pre-processing the data and returning the data in
34845 * the format that should be searched upon. This is done by adding
34846 * functions this object with a parameter name which matches the sType
34847 * for that target column. This is the corollary of <i>afnSortData</i>
34848 * for searching data.
34849 *
34850 * The functions defined take a single parameter:
34851 *
34852 * 1. `{*}` Data from the column cell to be prepared for searching
34853 *
34854 * Each function is expected to return:
34855 *
34856 * * `{string|null}` Formatted string that will be used for the searching.
34857 *
34858 * @type object
34859 * @default {}
34860 *
34861 * @example
34862 * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
34863 * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
34864 * }
34865 */
34866 search: {},
34867
34868
34869 /**
34870 * Type based ordering.
34871 *
34872 * The column type tells DataTables what ordering to apply to the table
34873 * when a column is sorted upon. The order for each type that is defined,
34874 * is defined by the functions available in this object.
34875 *
34876 * Each ordering option can be described by three properties added to
34877 * this object:
34878 *
34879 * * `{type}-pre` - Pre-formatting function
34880 * * `{type}-asc` - Ascending order function
34881 * * `{type}-desc` - Descending order function
34882 *
34883 * All three can be used together, only `{type}-pre` or only
34884 * `{type}-asc` and `{type}-desc` together. It is generally recommended
34885 * that only `{type}-pre` is used, as this provides the optimal
34886 * implementation in terms of speed, although the others are provided
34887 * for compatibility with existing Javascript sort functions.
34888 *
34889 * `{type}-pre`: Functions defined take a single parameter:
34890 *
34891 * 1. `{*}` Data from the column cell to be prepared for ordering
34892 *
34893 * And return:
34894 *
34895 * * `{*}` Data to be sorted upon
34896 *
34897 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
34898 * functions, taking two parameters:
34899 *
34900 * 1. `{*}` Data to compare to the second parameter
34901 * 2. `{*}` Data to compare to the first parameter
34902 *
34903 * And returning:
34904 *
34905 * * `{*}` Ordering match: <0 if first parameter should be sorted lower
34906 * than the second parameter, ===0 if the two parameters are equal and
34907 * >0 if the first parameter should be sorted height than the second
34908 * parameter.
34909 *
34910 * @type object
34911 * @default {}
34912 *
34913 * @example
34914 * // Numeric ordering of formatted numbers with a pre-formatter
34915 * $.extend( $.fn.dataTable.ext.type.order, {
34916 * "string-pre": function(x) {
34917 * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
34918 * return parseFloat( a );
34919 * }
34920 * } );
34921 *
34922 * @example
34923 * // Case-sensitive string ordering, with no pre-formatting method
34924 * $.extend( $.fn.dataTable.ext.order, {
34925 * "string-case-asc": function(x,y) {
34926 * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
34927 * },
34928 * "string-case-desc": function(x,y) {
34929 * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
34930 * }
34931 * } );
34932 */
34933 order: {}
34934 },
34935
34936 /**
34937 * Unique DataTables instance counter
34938 *
34939 * @type int
34940 * @private
34941 */
34942 _unique: 0,
34943
34944
34945 //
34946 // Depreciated
34947 // The following properties are retained for backwards compatiblity only.
34948 // The should not be used in new projects and will be removed in a future
34949 // version
34950 //
34951
34952 /**
34953 * Version check function.
34954 * @type function
34955 * @depreciated Since 1.10
34956 */
34957 fnVersionCheck: DataTable.fnVersionCheck,
34958
34959
34960 /**
34961 * Index for what 'this' index API functions should use
34962 * @type int
34963 * @deprecated Since v1.10
34964 */
34965 iApiIndex: 0,
34966
34967
34968 /**
34969 * jQuery UI class container
34970 * @type object
34971 * @deprecated Since v1.10
34972 */
34973 oJUIClasses: {},
34974
34975
34976 /**
34977 * Software version
34978 * @type string
34979 * @deprecated Since v1.10
34980 */
34981 sVersion: DataTable.version
34982 };
34983
34984
34985 //
34986 // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
34987 //
34988 $.extend( _ext, {
34989 afnFiltering: _ext.search,
34990 aTypes: _ext.type.detect,
34991 ofnSearch: _ext.type.search,
34992 oSort: _ext.type.order,
34993 afnSortData: _ext.order,
34994 aoFeatures: _ext.feature,
34995 oApi: _ext.internal,
34996 oStdClasses: _ext.classes,
34997 oPagination: _ext.pager
34998 } );
34999
35000
35001 $.extend( DataTable.ext.classes, {
35002 "sTable": "dataTable",
35003 "sNoFooter": "no-footer",
35004
35005 /* Paging buttons */
35006 "sPageButton": "paginate_button",
35007 "sPageButtonActive": "current",
35008 "sPageButtonDisabled": "disabled",
35009
35010 /* Striping classes */
35011 "sStripeOdd": "odd",
35012 "sStripeEven": "even",
35013
35014 /* Empty row */
35015 "sRowEmpty": "dataTables_empty",
35016
35017 /* Features */
35018 "sWrapper": "dataTables_wrapper",
35019 "sFilter": "dataTables_filter",
35020 "sInfo": "dataTables_info",
35021 "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
35022 "sLength": "dataTables_length",
35023 "sProcessing": "dataTables_processing",
35024
35025 /* Sorting */
35026 "sSortAsc": "sorting_asc",
35027 "sSortDesc": "sorting_desc",
35028 "sSortable": "sorting", /* Sortable in both directions */
35029 "sSortableAsc": "sorting_asc_disabled",
35030 "sSortableDesc": "sorting_desc_disabled",
35031 "sSortableNone": "sorting_disabled",
35032 "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
35033
35034 /* Filtering */
35035 "sFilterInput": "",
35036
35037 /* Page length */
35038 "sLengthSelect": "",
35039
35040 /* Scrolling */
35041 "sScrollWrapper": "dataTables_scroll",
35042 "sScrollHead": "dataTables_scrollHead",
35043 "sScrollHeadInner": "dataTables_scrollHeadInner",
35044 "sScrollBody": "dataTables_scrollBody",
35045 "sScrollFoot": "dataTables_scrollFoot",
35046 "sScrollFootInner": "dataTables_scrollFootInner",
35047
35048 /* Misc */
35049 "sHeaderTH": "",
35050 "sFooterTH": "",
35051
35052 // Deprecated
35053 "sSortJUIAsc": "",
35054 "sSortJUIDesc": "",
35055 "sSortJUI": "",
35056 "sSortJUIAscAllowed": "",
35057 "sSortJUIDescAllowed": "",
35058 "sSortJUIWrapper": "",
35059 "sSortIcon": "",
35060 "sJUIHeader": "",
35061 "sJUIFooter": ""
35062 } );
35063
35064
35065 (function() {
35066
35067 // Reused strings for better compression. Closure compiler appears to have a
35068 // weird edge case where it is trying to expand strings rather than use the
35069 // variable version. This results in about 200 bytes being added, for very
35070 // little preference benefit since it this run on script load only.
35071 var _empty = '';
35072 _empty = '';
35073
35074 var _stateDefault = _empty + 'ui-state-default';
35075 var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
35076 var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
35077
35078 $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
35079 /* Full numbers paging buttons */
35080 "sPageButton": "fg-button ui-button "+_stateDefault,
35081 "sPageButtonActive": "ui-state-disabled",
35082 "sPageButtonDisabled": "ui-state-disabled",
35083
35084 /* Features */
35085 "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
35086 "ui-buttonset-multi paging_", /* Note that the type is postfixed */
35087
35088 /* Sorting */
35089 "sSortAsc": _stateDefault+" sorting_asc",
35090 "sSortDesc": _stateDefault+" sorting_desc",
35091 "sSortable": _stateDefault+" sorting",
35092 "sSortableAsc": _stateDefault+" sorting_asc_disabled",
35093 "sSortableDesc": _stateDefault+" sorting_desc_disabled",
35094 "sSortableNone": _stateDefault+" sorting_disabled",
35095 "sSortJUIAsc": _sortIcon+"triangle-1-n",
35096 "sSortJUIDesc": _sortIcon+"triangle-1-s",
35097 "sSortJUI": _sortIcon+"carat-2-n-s",
35098 "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
35099 "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
35100 "sSortJUIWrapper": "DataTables_sort_wrapper",
35101 "sSortIcon": "DataTables_sort_icon",
35102
35103 /* Scrolling */
35104 "sScrollHead": "dataTables_scrollHead "+_stateDefault,
35105 "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
35106
35107 /* Misc */
35108 "sHeaderTH": _stateDefault,
35109 "sFooterTH": _stateDefault,
35110 "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
35111 "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
35112 } );
35113
35114 }());
35115
35116
35117
35118 var extPagination = DataTable.ext.pager;
35119
35120 function _numbers ( page, pages ) {
35121 var
35122 numbers = [],
35123 buttons = extPagination.numbers_length,
35124 half = Math.floor( buttons / 2 ),
35125 i = 1;
35126
35127 if ( pages <= buttons ) {
35128 numbers = _range( 0, pages );
35129 }
35130 else if ( page <= half ) {
35131 numbers = _range( 0, buttons-2 );
35132 numbers.push( 'ellipsis' );
35133 numbers.push( pages-1 );
35134 }
35135 else if ( page >= pages - 1 - half ) {
35136 numbers = _range( pages-(buttons-2), pages );
35137 numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
35138 numbers.splice( 0, 0, 0 );
35139 }
35140 else {
35141 numbers = _range( page-half+2, page+half-1 );
35142 numbers.push( 'ellipsis' );
35143 numbers.push( pages-1 );
35144 numbers.splice( 0, 0, 'ellipsis' );
35145 numbers.splice( 0, 0, 0 );
35146 }
35147
35148 numbers.DT_el = 'span';
35149 return numbers;
35150 }
35151
35152
35153 $.extend( extPagination, {
35154 simple: function ( page, pages ) {
35155 return [ 'previous', 'next' ];
35156 },
35157
35158 full: function ( page, pages ) {
35159 return [ 'first', 'previous', 'next', 'last' ];
35160 },
35161
35162 numbers: function ( page, pages ) {
35163 return [ _numbers(page, pages) ];
35164 },
35165
35166 simple_numbers: function ( page, pages ) {
35167 return [ 'previous', _numbers(page, pages), 'next' ];
35168 },
35169
35170 full_numbers: function ( page, pages ) {
35171 return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
35172 },
35173
35174 // For testing and plug-ins to use
35175 _numbers: _numbers,
35176
35177 // Number of number buttons (including ellipsis) to show. _Must be odd!_
35178 numbers_length: 7
35179 } );
35180
35181
35182 $.extend( true, DataTable.ext.renderer, {
35183 pageButton: {
35184 _: function ( settings, host, idx, buttons, page, pages ) {
35185 var classes = settings.oClasses;
35186 var lang = settings.oLanguage.oPaginate;
35187 var aria = settings.oLanguage.oAria.paginate || {};
35188 var btnDisplay, btnClass, counter=0;
35189
35190 var attach = function( container, buttons ) {
35191 var i, ien, node, button;
35192 var clickHandler = function ( e ) {
35193 _fnPageChange( settings, e.data.action, true );
35194 };
35195
35196 for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
35197 button = buttons[i];
35198
35199 if ( $.isArray( button ) ) {
35200 var inner = $( '<'+(button.DT_el || 'div')+'/>' )
35201 .appendTo( container );
35202 attach( inner, button );
35203 }
35204 else {
35205 btnDisplay = null;
35206 btnClass = '';
35207
35208 switch ( button ) {
35209 case 'ellipsis':
35210 container.append('<span class="ellipsis">…</span>');
35211 break;
35212
35213 case 'first':
35214 btnDisplay = lang.sFirst;
35215 btnClass = button + (page > 0 ?
35216 '' : ' '+classes.sPageButtonDisabled);
35217 break;
35218
35219 case 'previous':
35220 btnDisplay = lang.sPrevious;
35221 btnClass = button + (page > 0 ?
35222 '' : ' '+classes.sPageButtonDisabled);
35223 break;
35224
35225 case 'next':
35226 btnDisplay = lang.sNext;
35227 btnClass = button + (page < pages-1 ?
35228 '' : ' '+classes.sPageButtonDisabled);
35229 break;
35230
35231 case 'last':
35232 btnDisplay = lang.sLast;
35233 btnClass = button + (page < pages-1 ?
35234 '' : ' '+classes.sPageButtonDisabled);
35235 break;
35236
35237 default:
35238 btnDisplay = button + 1;
35239 btnClass = page === button ?
35240 classes.sPageButtonActive : '';
35241 break;
35242 }
35243
35244 if ( btnDisplay !== null ) {
35245 node = $('<a>', {
35246 'class': classes.sPageButton+' '+btnClass,
35247 'aria-controls': settings.sTableId,
35248 'aria-label': aria[ button ],
35249 'data-dt-idx': counter,
35250 'tabindex': settings.iTabIndex,
35251 'id': idx === 0 && typeof button === 'string' ?
35252 settings.sTableId +'_'+ button :
35253 null
35254 } )
35255 .html( btnDisplay )
35256 .appendTo( container );
35257
35258 _fnBindAction(
35259 node, {action: button}, clickHandler
35260 );
35261
35262 counter++;
35263 }
35264 }
35265 }
35266 };
35267
35268 // IE9 throws an 'unknown error' if document.activeElement is used
35269 // inside an iframe or frame. Try / catch the error. Not good for
35270 // accessibility, but neither are frames.
35271 var activeEl;
35272
35273 try {
35274 // Because this approach is destroying and recreating the paging
35275 // elements, focus is lost on the select button which is bad for
35276 // accessibility. So we want to restore focus once the draw has
35277 // completed
35278 activeEl = $(host).find(document.activeElement).data('dt-idx');
35279 }
35280 catch (e) {}
35281
35282 attach( $(host).empty(), buttons );
35283
35284 if ( activeEl ) {
35285 $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
35286 }
35287 }
35288 }
35289 } );
35290
35291
35292
35293 // Built in type detection. See model.ext.aTypes for information about
35294 // what is required from this methods.
35295 $.extend( DataTable.ext.type.detect, [
35296 // Plain numbers - first since V8 detects some plain numbers as dates
35297 // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
35298 function ( d, settings )
35299 {
35300 var decimal = settings.oLanguage.sDecimal;
35301 return _isNumber( d, decimal ) ? 'num'+decimal : null;
35302 },
35303
35304 // Dates (only those recognised by the browser's Date.parse)
35305 function ( d, settings )
35306 {
35307 // V8 will remove any unknown characters at the start and end of the
35308 // expression, leading to false matches such as `$245.12` or `10%` being
35309 // a valid date. See forum thread 18941 for detail.
35310 if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
35311 return null;
35312 }
35313 var parsed = Date.parse(d);
35314 return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
35315 },
35316
35317 // Formatted numbers
35318 function ( d, settings )
35319 {
35320 var decimal = settings.oLanguage.sDecimal;
35321 return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
35322 },
35323
35324 // HTML numeric
35325 function ( d, settings )
35326 {
35327 var decimal = settings.oLanguage.sDecimal;
35328 return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
35329 },
35330
35331 // HTML numeric, formatted
35332 function ( d, settings )
35333 {
35334 var decimal = settings.oLanguage.sDecimal;
35335 return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
35336 },
35337
35338 // HTML (this is strict checking - there must be html)
35339 function ( d, settings )
35340 {
35341 return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
35342 'html' : null;
35343 }
35344 ] );
35345
35346
35347
35348 // Filter formatting functions. See model.ext.ofnSearch for information about
35349 // what is required from these methods.
35350 //
35351 // Note that additional search methods are added for the html numbers and
35352 // html formatted numbers by `_addNumericSort()` when we know what the decimal
35353 // place is
35354
35355
35356 $.extend( DataTable.ext.type.search, {
35357 html: function ( data ) {
35358 return _empty(data) ?
35359 data :
35360 typeof data === 'string' ?
35361 data
35362 .replace( _re_new_lines, " " )
35363 .replace( _re_html, "" ) :
35364 '';
35365 },
35366
35367 string: function ( data ) {
35368 return _empty(data) ?
35369 data :
35370 typeof data === 'string' ?
35371 data.replace( _re_new_lines, " " ) :
35372 data;
35373 }
35374 } );
35375
35376
35377
35378 var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
35379 if ( d !== 0 && (!d || d === '-') ) {
35380 return -Infinity;
35381 }
35382
35383 // If a decimal place other than `.` is used, it needs to be given to the
35384 // function so we can detect it and replace with a `.` which is the only
35385 // decimal place Javascript recognises - it is not locale aware.
35386 if ( decimalPlace ) {
35387 d = _numToDecimal( d, decimalPlace );
35388 }
35389
35390 if ( d.replace ) {
35391 if ( re1 ) {
35392 d = d.replace( re1, '' );
35393 }
35394
35395 if ( re2 ) {
35396 d = d.replace( re2, '' );
35397 }
35398 }
35399
35400 return d * 1;
35401 };
35402
35403
35404 // Add the numeric 'deformatting' functions for sorting and search. This is done
35405 // in a function to provide an easy ability for the language options to add
35406 // additional methods if a non-period decimal place is used.
35407 function _addNumericSort ( decimalPlace ) {
35408 $.each(
35409 {
35410 // Plain numbers
35411 "num": function ( d ) {
35412 return __numericReplace( d, decimalPlace );
35413 },
35414
35415 // Formatted numbers
35416 "num-fmt": function ( d ) {
35417 return __numericReplace( d, decimalPlace, _re_formatted_numeric );
35418 },
35419
35420 // HTML numeric
35421 "html-num": function ( d ) {
35422 return __numericReplace( d, decimalPlace, _re_html );
35423 },
35424
35425 // HTML numeric, formatted
35426 "html-num-fmt": function ( d ) {
35427 return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
35428 }
35429 },
35430 function ( key, fn ) {
35431 // Add the ordering method
35432 _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
35433
35434 // For HTML types add a search formatter that will strip the HTML
35435 if ( key.match(/^html\-/) ) {
35436 _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
35437 }
35438 }
35439 );
35440 }
35441
35442
35443 // Default sort methods
35444 $.extend( _ext.type.order, {
35445 // Dates
35446 "date-pre": function ( d ) {
35447 return Date.parse( d ) || 0;
35448 },
35449
35450 // html
35451 "html-pre": function ( a ) {
35452 return _empty(a) ?
35453 '' :
35454 a.replace ?
35455 a.replace( /<.*?>/g, "" ).toLowerCase() :
35456 a+'';
35457 },
35458
35459 // string
35460 "string-pre": function ( a ) {
35461 // This is a little complex, but faster than always calling toString,
35462 // http://jsperf.com/tostring-v-check
35463 return _empty(a) ?
35464 '' :
35465 typeof a === 'string' ?
35466 a.toLowerCase() :
35467 ! a.toString ?
35468 '' :
35469 a.toString();
35470 },
35471
35472 // string-asc and -desc are retained only for compatibility with the old
35473 // sort methods
35474 "string-asc": function ( x, y ) {
35475 return ((x < y) ? -1 : ((x > y) ? 1 : 0));
35476 },
35477
35478 "string-desc": function ( x, y ) {
35479 return ((x < y) ? 1 : ((x > y) ? -1 : 0));
35480 }
35481 } );
35482
35483
35484 // Numeric sorting types - order doesn't matter here
35485 _addNumericSort( '' );
35486
35487
35488 $.extend( true, DataTable.ext.renderer, {
35489 header: {
35490 _: function ( settings, cell, column, classes ) {
35491 // No additional mark-up required
35492 // Attach a sort listener to update on sort - note that using the
35493 // `DT` namespace will allow the event to be removed automatically
35494 // on destroy, while the `dt` namespaced event is the one we are
35495 // listening for
35496 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
35497 if ( settings !== ctx ) { // need to check this this is the host
35498 return; // table, not a nested one
35499 }
35500
35501 var colIdx = column.idx;
35502
35503 cell
35504 .removeClass(
35505 column.sSortingClass +' '+
35506 classes.sSortAsc +' '+
35507 classes.sSortDesc
35508 )
35509 .addClass( columns[ colIdx ] == 'asc' ?
35510 classes.sSortAsc : columns[ colIdx ] == 'desc' ?
35511 classes.sSortDesc :
35512 column.sSortingClass
35513 );
35514 } );
35515 },
35516
35517 jqueryui: function ( settings, cell, column, classes ) {
35518 $('<div/>')
35519 .addClass( classes.sSortJUIWrapper )
35520 .append( cell.contents() )
35521 .append( $('<span/>')
35522 .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
35523 )
35524 .appendTo( cell );
35525
35526 // Attach a sort listener to update on sort
35527 $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
35528 if ( settings !== ctx ) {
35529 return;
35530 }
35531
35532 var colIdx = column.idx;
35533
35534 cell
35535 .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
35536 .addClass( columns[ colIdx ] == 'asc' ?
35537 classes.sSortAsc : columns[ colIdx ] == 'desc' ?
35538 classes.sSortDesc :
35539 column.sSortingClass
35540 );
35541
35542 cell
35543 .find( 'span.'+classes.sSortIcon )
35544 .removeClass(
35545 classes.sSortJUIAsc +" "+
35546 classes.sSortJUIDesc +" "+
35547 classes.sSortJUI +" "+
35548 classes.sSortJUIAscAllowed +" "+
35549 classes.sSortJUIDescAllowed
35550 )
35551 .addClass( columns[ colIdx ] == 'asc' ?
35552 classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
35553 classes.sSortJUIDesc :
35554 column.sSortingClassJUI
35555 );
35556 } );
35557 }
35558 }
35559 } );
35560
35561 /*
35562 * Public helper functions. These aren't used internally by DataTables, or
35563 * called by any of the options passed into DataTables, but they can be used
35564 * externally by developers working with DataTables. They are helper functions
35565 * to make working with DataTables a little bit easier.
35566 */
35567
35568 var __htmlEscapeEntities = function ( d ) {
35569 return typeof d === 'string' ?
35570 d.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') :
35571 d;
35572 };
35573
35574 /**
35575 * Helpers for `columns.render`.
35576 *
35577 * The options defined here can be used with the `columns.render` initialisation
35578 * option to provide a display renderer. The following functions are defined:
35579 *
35580 * * `number` - Will format numeric data (defined by `columns.data`) for
35581 * display, retaining the original unformatted data for sorting and filtering.
35582 * It takes 5 parameters:
35583 * * `string` - Thousands grouping separator
35584 * * `string` - Decimal point indicator
35585 * * `integer` - Number of decimal points to show
35586 * * `string` (optional) - Prefix.
35587 * * `string` (optional) - Postfix (/suffix).
35588 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
35589 * parameters.
35590 *
35591 * @example
35592 * // Column definition using the number renderer
35593 * {
35594 * data: "salary",
35595 * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
35596 * }
35597 *
35598 * @namespace
35599 */
35600 DataTable.render = {
35601 number: function ( thousands, decimal, precision, prefix, postfix ) {
35602 return {
35603 display: function ( d ) {
35604 if ( typeof d !== 'number' && typeof d !== 'string' ) {
35605 return d;
35606 }
35607
35608 var negative = d < 0 ? '-' : '';
35609 var flo = parseFloat( d );
35610
35611 // If NaN then there isn't much formatting that we can do - just
35612 // return immediately, escaping any HTML (this was supposed to
35613 // be a number after all)
35614 if ( isNaN( flo ) ) {
35615 return __htmlEscapeEntities( d );
35616 }
35617
35618 d = Math.abs( flo );
35619
35620 var intPart = parseInt( d, 10 );
35621 var floatPart = precision ?
35622 decimal+(d - intPart).toFixed( precision ).substring( 2 ):
35623 '';
35624
35625 return negative + (prefix||'') +
35626 intPart.toString().replace(
35627 /\B(?=(\d{3})+(?!\d))/g, thousands
35628 ) +
35629 floatPart +
35630 (postfix||'');
35631 }
35632 };
35633 },
35634
35635 text: function () {
35636 return {
35637 display: __htmlEscapeEntities
35638 };
35639 }
35640 };
35641
35642
35643 /*
35644 * This is really a good bit rubbish this method of exposing the internal methods
35645 * publicly... - To be fixed in 2.0 using methods on the prototype
35646 */
35647
35648
35649 /**
35650 * Create a wrapper function for exporting an internal functions to an external API.
35651 * @param {string} fn API function name
35652 * @returns {function} wrapped function
35653 * @memberof DataTable#internal
35654 */
35655 function _fnExternApiFunc (fn)
35656 {
35657 return function() {
35658 var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
35659 Array.prototype.slice.call(arguments)
35660 );
35661 return DataTable.ext.internal[fn].apply( this, args );
35662 };
35663 }
35664
35665
35666 /**
35667 * Reference to internal functions for use by plug-in developers. Note that
35668 * these methods are references to internal functions and are considered to be
35669 * private. If you use these methods, be aware that they are liable to change
35670 * between versions.
35671 * @namespace
35672 */
35673 $.extend( DataTable.ext.internal, {
35674 _fnExternApiFunc: _fnExternApiFunc,
35675 _fnBuildAjax: _fnBuildAjax,
35676 _fnAjaxUpdate: _fnAjaxUpdate,
35677 _fnAjaxParameters: _fnAjaxParameters,
35678 _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
35679 _fnAjaxDataSrc: _fnAjaxDataSrc,
35680 _fnAddColumn: _fnAddColumn,
35681 _fnColumnOptions: _fnColumnOptions,
35682 _fnAdjustColumnSizing: _fnAdjustColumnSizing,
35683 _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
35684 _fnColumnIndexToVisible: _fnColumnIndexToVisible,
35685 _fnVisbleColumns: _fnVisbleColumns,
35686 _fnGetColumns: _fnGetColumns,
35687 _fnColumnTypes: _fnColumnTypes,
35688 _fnApplyColumnDefs: _fnApplyColumnDefs,
35689 _fnHungarianMap: _fnHungarianMap,
35690 _fnCamelToHungarian: _fnCamelToHungarian,
35691 _fnLanguageCompat: _fnLanguageCompat,
35692 _fnBrowserDetect: _fnBrowserDetect,
35693 _fnAddData: _fnAddData,
35694 _fnAddTr: _fnAddTr,
35695 _fnNodeToDataIndex: _fnNodeToDataIndex,
35696 _fnNodeToColumnIndex: _fnNodeToColumnIndex,
35697 _fnGetCellData: _fnGetCellData,
35698 _fnSetCellData: _fnSetCellData,
35699 _fnSplitObjNotation: _fnSplitObjNotation,
35700 _fnGetObjectDataFn: _fnGetObjectDataFn,
35701 _fnSetObjectDataFn: _fnSetObjectDataFn,
35702 _fnGetDataMaster: _fnGetDataMaster,
35703 _fnClearTable: _fnClearTable,
35704 _fnDeleteIndex: _fnDeleteIndex,
35705 _fnInvalidate: _fnInvalidate,
35706 _fnGetRowElements: _fnGetRowElements,
35707 _fnCreateTr: _fnCreateTr,
35708 _fnBuildHead: _fnBuildHead,
35709 _fnDrawHead: _fnDrawHead,
35710 _fnDraw: _fnDraw,
35711 _fnReDraw: _fnReDraw,
35712 _fnAddOptionsHtml: _fnAddOptionsHtml,
35713 _fnDetectHeader: _fnDetectHeader,
35714 _fnGetUniqueThs: _fnGetUniqueThs,
35715 _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
35716 _fnFilterComplete: _fnFilterComplete,
35717 _fnFilterCustom: _fnFilterCustom,
35718 _fnFilterColumn: _fnFilterColumn,
35719 _fnFilter: _fnFilter,
35720 _fnFilterCreateSearch: _fnFilterCreateSearch,
35721 _fnEscapeRegex: _fnEscapeRegex,
35722 _fnFilterData: _fnFilterData,
35723 _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
35724 _fnUpdateInfo: _fnUpdateInfo,
35725 _fnInfoMacros: _fnInfoMacros,
35726 _fnInitialise: _fnInitialise,
35727 _fnInitComplete: _fnInitComplete,
35728 _fnLengthChange: _fnLengthChange,
35729 _fnFeatureHtmlLength: _fnFeatureHtmlLength,
35730 _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
35731 _fnPageChange: _fnPageChange,
35732 _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
35733 _fnProcessingDisplay: _fnProcessingDisplay,
35734 _fnFeatureHtmlTable: _fnFeatureHtmlTable,
35735 _fnScrollDraw: _fnScrollDraw,
35736 _fnApplyToChildren: _fnApplyToChildren,
35737 _fnCalculateColumnWidths: _fnCalculateColumnWidths,
35738 _fnThrottle: _fnThrottle,
35739 _fnConvertToWidth: _fnConvertToWidth,
35740 _fnGetWidestNode: _fnGetWidestNode,
35741 _fnGetMaxLenString: _fnGetMaxLenString,
35742 _fnStringToCss: _fnStringToCss,
35743 _fnSortFlatten: _fnSortFlatten,
35744 _fnSort: _fnSort,
35745 _fnSortAria: _fnSortAria,
35746 _fnSortListener: _fnSortListener,
35747 _fnSortAttachListener: _fnSortAttachListener,
35748 _fnSortingClasses: _fnSortingClasses,
35749 _fnSortData: _fnSortData,
35750 _fnSaveState: _fnSaveState,
35751 _fnLoadState: _fnLoadState,
35752 _fnSettingsFromNode: _fnSettingsFromNode,
35753 _fnLog: _fnLog,
35754 _fnMap: _fnMap,
35755 _fnBindAction: _fnBindAction,
35756 _fnCallbackReg: _fnCallbackReg,
35757 _fnCallbackFire: _fnCallbackFire,
35758 _fnLengthOverflow: _fnLengthOverflow,
35759 _fnRenderer: _fnRenderer,
35760 _fnDataSource: _fnDataSource,
35761 _fnRowAttributes: _fnRowAttributes,
35762 _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
35763 // in 1.10, so this dead-end function is
35764 // added to prevent errors
35765 } );
35766
35767
35768 // jQuery access
35769 $.fn.dataTable = DataTable;
35770
35771 // Provide access to the host jQuery object (circular reference)
35772 DataTable.$ = $;
35773
35774 // Legacy aliases
35775 $.fn.dataTableSettings = DataTable.settings;
35776 $.fn.dataTableExt = DataTable.ext;
35777
35778 // With a capital `D` we return a DataTables API instance rather than a
35779 // jQuery object
35780 $.fn.DataTable = function ( opts ) {
35781 return $(this).dataTable( opts ).api();
35782 };
35783
35784 // All properties that are available to $.fn.dataTable should also be
35785 // available on $.fn.DataTable
35786 $.each( DataTable, function ( prop, val ) {
35787 $.fn.DataTable[ prop ] = val;
35788 } );
35789
35790
35791 // Information about events fired by DataTables - for documentation.
35792 /**
35793 * Draw event, fired whenever the table is redrawn on the page, at the same
35794 * point as fnDrawCallback. This may be useful for binding events or
35795 * performing calculations when the table is altered at all.
35796 * @name DataTable#draw.dt
35797 * @event
35798 * @param {event} e jQuery event object
35799 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35800 */
35801
35802 /**
35803 * Search event, fired when the searching applied to the table (using the
35804 * built-in global search, or column filters) is altered.
35805 * @name DataTable#search.dt
35806 * @event
35807 * @param {event} e jQuery event object
35808 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35809 */
35810
35811 /**
35812 * Page change event, fired when the paging of the table is altered.
35813 * @name DataTable#page.dt
35814 * @event
35815 * @param {event} e jQuery event object
35816 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35817 */
35818
35819 /**
35820 * Order event, fired when the ordering applied to the table is altered.
35821 * @name DataTable#order.dt
35822 * @event
35823 * @param {event} e jQuery event object
35824 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35825 */
35826
35827 /**
35828 * DataTables initialisation complete event, fired when the table is fully
35829 * drawn, including Ajax data loaded, if Ajax data is required.
35830 * @name DataTable#init.dt
35831 * @event
35832 * @param {event} e jQuery event object
35833 * @param {object} oSettings DataTables settings object
35834 * @param {object} json The JSON object request from the server - only
35835 * present if client-side Ajax sourced data is used</li></ol>
35836 */
35837
35838 /**
35839 * State save event, fired when the table has changed state a new state save
35840 * is required. This event allows modification of the state saving object
35841 * prior to actually doing the save, including addition or other state
35842 * properties (for plug-ins) or modification of a DataTables core property.
35843 * @name DataTable#stateSaveParams.dt
35844 * @event
35845 * @param {event} e jQuery event object
35846 * @param {object} oSettings DataTables settings object
35847 * @param {object} json The state information to be saved
35848 */
35849
35850 /**
35851 * State load event, fired when the table is loading state from the stored
35852 * data, but prior to the settings object being modified by the saved state
35853 * - allowing modification of the saved state is required or loading of
35854 * state for a plug-in.
35855 * @name DataTable#stateLoadParams.dt
35856 * @event
35857 * @param {event} e jQuery event object
35858 * @param {object} oSettings DataTables settings object
35859 * @param {object} json The saved state information
35860 */
35861
35862 /**
35863 * State loaded event, fired when state has been loaded from stored data and
35864 * the settings object has been modified by the loaded data.
35865 * @name DataTable#stateLoaded.dt
35866 * @event
35867 * @param {event} e jQuery event object
35868 * @param {object} oSettings DataTables settings object
35869 * @param {object} json The saved state information
35870 */
35871
35872 /**
35873 * Processing event, fired when DataTables is doing some kind of processing
35874 * (be it, order, searcg or anything else). It can be used to indicate to
35875 * the end user that there is something happening, or that something has
35876 * finished.
35877 * @name DataTable#processing.dt
35878 * @event
35879 * @param {event} e jQuery event object
35880 * @param {object} oSettings DataTables settings object
35881 * @param {boolean} bShow Flag for if DataTables is doing processing or not
35882 */
35883
35884 /**
35885 * Ajax (XHR) event, fired whenever an Ajax request is completed from a
35886 * request to made to the server for new data. This event is called before
35887 * DataTables processed the returned data, so it can also be used to pre-
35888 * process the data returned from the server, if needed.
35889 *
35890 * Note that this trigger is called in `fnServerData`, if you override
35891 * `fnServerData` and which to use this event, you need to trigger it in you
35892 * success function.
35893 * @name DataTable#xhr.dt
35894 * @event
35895 * @param {event} e jQuery event object
35896 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35897 * @param {object} json JSON returned from the server
35898 *
35899 * @example
35900 * // Use a custom property returned from the server in another DOM element
35901 * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
35902 * $('#status').html( json.status );
35903 * } );
35904 *
35905 * @example
35906 * // Pre-process the data returned from the server
35907 * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
35908 * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
35909 * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
35910 * }
35911 * // Note no return - manipulate the data directly in the JSON object.
35912 * } );
35913 */
35914
35915 /**
35916 * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
35917 * or passing the bDestroy:true parameter in the initialisation object. This
35918 * can be used to remove bound events, added DOM nodes, etc.
35919 * @name DataTable#destroy.dt
35920 * @event
35921 * @param {event} e jQuery event object
35922 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35923 */
35924
35925 /**
35926 * Page length change event, fired when number of records to show on each
35927 * page (the length) is changed.
35928 * @name DataTable#length.dt
35929 * @event
35930 * @param {event} e jQuery event object
35931 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35932 * @param {integer} len New length
35933 */
35934
35935 /**
35936 * Column sizing has changed.
35937 * @name DataTable#column-sizing.dt
35938 * @event
35939 * @param {event} e jQuery event object
35940 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35941 */
35942
35943 /**
35944 * Column visibility has changed.
35945 * @name DataTable#column-visibility.dt
35946 * @event
35947 * @param {event} e jQuery event object
35948 * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
35949 * @param {int} column Column index
35950 * @param {bool} vis `false` if column now hidden, or `true` if visible
35951 */
35952
35953 return $.fn.dataTable;
35954}));
35955
35956/*! DataTables Bootstrap 3 integration
35957 * ©2011-2015 SpryMedia Ltd - datatables.net/license
35958 */
35959
35960/**
35961 * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and
35962 * DataTables 1.10 or newer.
35963 *
35964 * This file sets the defaults and adds options to DataTables to style its
35965 * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap
35966 * for further information.
35967 */
35968(function( factory ){
35969 if ( typeof define === 'function' && define.amd ) {
35970 // AMD
35971 define( ['jquery', 'datatables.net'], function ( $ ) {
35972 return factory( $, window, document );
35973 } );
35974 }
35975 else if ( typeof exports === 'object' ) {
35976 // CommonJS
35977 module.exports = function (root, $) {
35978 if ( ! root ) {
35979 root = window;
35980 }
35981
35982 if ( ! $ || ! $.fn.dataTable ) {
35983 // Require DataTables, which attaches to jQuery, including
35984 // jQuery if needed and have a $ property so we can access the
35985 // jQuery object that is used
35986 $ = require('datatables.net')(root, $).$;
35987 }
35988
35989 return factory( $, root, root.document );
35990 };
35991 }
35992 else {
35993 // Browser
35994 factory( jQuery, window, document );
35995 }
35996}(function( $, window, document, undefined ) {
35997'use strict';
35998var DataTable = $.fn.dataTable;
35999
36000
36001/* Set the defaults for DataTables initialisation */
36002$.extend( true, DataTable.defaults, {
36003 dom:
36004 "<'row'<'col-sm-6'l><'col-sm-6'f>>" +
36005 "<'row'<'col-sm-12'tr>>" +
36006 "<'row'<'col-sm-5'i><'col-sm-7'p>>",
36007 renderer: 'bootstrap'
36008} );
36009
36010
36011/* Default class modification */
36012$.extend( DataTable.ext.classes, {
36013 sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
36014 sFilterInput: "form-control input-sm",
36015 sLengthSelect: "form-control input-sm",
36016 sProcessing: "dataTables_processing panel panel-default"
36017} );
36018
36019
36020/* Bootstrap paging button renderer */
36021DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
36022 var api = new DataTable.Api( settings );
36023 var classes = settings.oClasses;
36024 var lang = settings.oLanguage.oPaginate;
36025 var aria = settings.oLanguage.oAria.paginate || {};
36026 var btnDisplay, btnClass, counter=0;
36027
36028 var attach = function( container, buttons ) {
36029 var i, ien, node, button;
36030 var clickHandler = function ( e ) {
36031 e.preventDefault();
36032 if ( !$(e.currentTarget).hasClass('disabled') && api.page() != e.data.action ) {
36033 api.page( e.data.action ).draw( 'page' );
36034 }
36035 };
36036
36037 for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
36038 button = buttons[i];
36039
36040 if ( $.isArray( button ) ) {
36041 attach( container, button );
36042 }
36043 else {
36044 btnDisplay = '';
36045 btnClass = '';
36046
36047 switch ( button ) {
36048 case 'ellipsis':
36049 btnDisplay = '…';
36050 btnClass = 'disabled';
36051 break;
36052
36053 case 'first':
36054 btnDisplay = lang.sFirst;
36055 btnClass = button + (page > 0 ?
36056 '' : ' disabled');
36057 break;
36058
36059 case 'previous':
36060 btnDisplay = lang.sPrevious;
36061 btnClass = button + (page > 0 ?
36062 '' : ' disabled');
36063 break;
36064
36065 case 'next':
36066 btnDisplay = lang.sNext;
36067 btnClass = button + (page < pages-1 ?
36068 '' : ' disabled');
36069 break;
36070
36071 case 'last':
36072 btnDisplay = lang.sLast;
36073 btnClass = button + (page < pages-1 ?
36074 '' : ' disabled');
36075 break;
36076
36077 default:
36078 btnDisplay = button + 1;
36079 btnClass = page === button ?
36080 'active' : '';
36081 break;
36082 }
36083
36084 if ( btnDisplay ) {
36085 node = $('<li>', {
36086 'class': classes.sPageButton+' '+btnClass,
36087 'id': idx === 0 && typeof button === 'string' ?
36088 settings.sTableId +'_'+ button :
36089 null
36090 } )
36091 .append( $('<a>', {
36092 'href': '#',
36093 'aria-controls': settings.sTableId,
36094 'aria-label': aria[ button ],
36095 'data-dt-idx': counter,
36096 'tabindex': settings.iTabIndex
36097 } )
36098 .html( btnDisplay )
36099 )
36100 .appendTo( container );
36101
36102 settings.oApi._fnBindAction(
36103 node, {action: button}, clickHandler
36104 );
36105
36106 counter++;
36107 }
36108 }
36109 }
36110 };
36111
36112 // IE9 throws an 'unknown error' if document.activeElement is used
36113 // inside an iframe or frame.
36114 var activeEl;
36115
36116 try {
36117 // Because this approach is destroying and recreating the paging
36118 // elements, focus is lost on the select button which is bad for
36119 // accessibility. So we want to restore focus once the draw has
36120 // completed
36121 activeEl = $(host).find(document.activeElement).data('dt-idx');
36122 }
36123 catch (e) {}
36124
36125 attach(
36126 $(host).empty().html('<ul class="pagination"/>').children('ul'),
36127 buttons
36128 );
36129
36130 if ( activeEl ) {
36131 $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
36132 }
36133};
36134
36135
36136return DataTable;
36137}));
36138/*! Responsive 2.1.0
36139 * 2014-2016 SpryMedia Ltd - datatables.net/license
36140 */
36141
36142/**
36143 * @summary Responsive
36144 * @description Responsive tables plug-in for DataTables
36145 * @version 2.1.0
36146 * @file dataTables.responsive.js
36147 * @author SpryMedia Ltd (www.sprymedia.co.uk)
36148 * @contact www.sprymedia.co.uk/contact
36149 * @copyright Copyright 2014-2016 SpryMedia Ltd.
36150 *
36151 * This source file is free software, available under the following license:
36152 * MIT license - http://datatables.net/license/mit
36153 *
36154 * This source file is distributed in the hope that it will be useful, but
36155 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36156 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
36157 *
36158 * For details please refer to: http://www.datatables.net
36159 */
36160(function( factory ){
36161 if ( typeof define === 'function' && define.amd ) {
36162 // AMD
36163 define( ['jquery', 'datatables.net'], function ( $ ) {
36164 return factory( $, window, document );
36165 } );
36166 }
36167 else if ( typeof exports === 'object' ) {
36168 // CommonJS
36169 module.exports = function (root, $) {
36170 if ( ! root ) {
36171 root = window;
36172 }
36173
36174 if ( ! $ || ! $.fn.dataTable ) {
36175 $ = require('datatables.net')(root, $).$;
36176 }
36177
36178 return factory( $, root, root.document );
36179 };
36180 }
36181 else {
36182 // Browser
36183 factory( jQuery, window, document );
36184 }
36185}(function( $, window, document, undefined ) {
36186'use strict';
36187var DataTable = $.fn.dataTable;
36188
36189
36190/**
36191 * Responsive is a plug-in for the DataTables library that makes use of
36192 * DataTables' ability to change the visibility of columns, changing the
36193 * visibility of columns so the displayed columns fit into the table container.
36194 * The end result is that complex tables will be dynamically adjusted to fit
36195 * into the viewport, be it on a desktop, tablet or mobile browser.
36196 *
36197 * Responsive for DataTables has two modes of operation, which can used
36198 * individually or combined:
36199 *
36200 * * Class name based control - columns assigned class names that match the
36201 * breakpoint logic can be shown / hidden as required for each breakpoint.
36202 * * Automatic control - columns are automatically hidden when there is no
36203 * room left to display them. Columns removed from the right.
36204 *
36205 * In additional to column visibility control, Responsive also has built into
36206 * options to use DataTables' child row display to show / hide the information
36207 * from the table that has been hidden. There are also two modes of operation
36208 * for this child row display:
36209 *
36210 * * Inline - when the control element that the user can use to show / hide
36211 * child rows is displayed inside the first column of the table.
36212 * * Column - where a whole column is dedicated to be the show / hide control.
36213 *
36214 * Initialisation of Responsive is performed by:
36215 *
36216 * * Adding the class `responsive` or `dt-responsive` to the table. In this case
36217 * Responsive will automatically be initialised with the default configuration
36218 * options when the DataTable is created.
36219 * * Using the `responsive` option in the DataTables configuration options. This
36220 * can also be used to specify the configuration options, or simply set to
36221 * `true` to use the defaults.
36222 *
36223 * @class
36224 * @param {object} settings DataTables settings object for the host table
36225 * @param {object} [opts] Configuration options
36226 * @requires jQuery 1.7+
36227 * @requires DataTables 1.10.3+
36228 *
36229 * @example
36230 * $('#example').DataTable( {
36231 * responsive: true
36232 * } );
36233 * } );
36234 */
36235var Responsive = function ( settings, opts ) {
36236 // Sanity check that we are using DataTables 1.10 or newer
36237 if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.3' ) ) {
36238 throw 'DataTables Responsive requires DataTables 1.10.3 or newer';
36239 }
36240
36241 this.s = {
36242 dt: new DataTable.Api( settings ),
36243 columns: [],
36244 current: []
36245 };
36246
36247 // Check if responsive has already been initialised on this table
36248 if ( this.s.dt.settings()[0].responsive ) {
36249 return;
36250 }
36251
36252 // details is an object, but for simplicity the user can give it as a string
36253 // or a boolean
36254 if ( opts && typeof opts.details === 'string' ) {
36255 opts.details = { type: opts.details };
36256 }
36257 else if ( opts && opts.details === false ) {
36258 opts.details = { type: false };
36259 }
36260 else if ( opts && opts.details === true ) {
36261 opts.details = { type: 'inline' };
36262 }
36263
36264 this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
36265 settings.responsive = this;
36266 this._constructor();
36267};
36268
36269$.extend( Responsive.prototype, {
36270 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
36271 * Constructor
36272 */
36273
36274 /**
36275 * Initialise the Responsive instance
36276 *
36277 * @private
36278 */
36279 _constructor: function ()
36280 {
36281 var that = this;
36282 var dt = this.s.dt;
36283 var dtPrivateSettings = dt.settings()[0];
36284 var oldWindowWidth = $(window).width();
36285
36286 dt.settings()[0]._responsive = this;
36287
36288 // Use DataTables' throttle function to avoid processor thrashing on
36289 // resize
36290 $(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
36291 // iOS has a bug whereby resize can fire when only scrolling
36292 // See: http://stackoverflow.com/questions/8898412
36293 var width = $(window).width();
36294
36295 if ( width !== oldWindowWidth ) {
36296 that._resize();
36297 oldWindowWidth = width;
36298 }
36299 } ) );
36300
36301 // DataTables doesn't currently trigger an event when a row is added, so
36302 // we need to hook into its private API to enforce the hidden rows when
36303 // new data is added
36304 dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
36305 if ( $.inArray( false, that.s.current ) !== -1 ) {
36306 $('td, th', tr).each( function ( i ) {
36307 var idx = dt.column.index( 'toData', i );
36308
36309 if ( that.s.current[idx] === false ) {
36310 $(this).css('display', 'none');
36311 }
36312 } );
36313 }
36314 } );
36315
36316 // Destroy event handler
36317 dt.on( 'destroy.dtr', function () {
36318 dt.off( '.dtr' );
36319 $( dt.table().body() ).off( '.dtr' );
36320 $(window).off( 'resize.dtr orientationchange.dtr' );
36321
36322 // Restore the columns that we've hidden
36323 $.each( that.s.current, function ( i, val ) {
36324 if ( val === false ) {
36325 that._setColumnVis( i, true );
36326 }
36327 } );
36328 } );
36329
36330 // Reorder the breakpoints array here in case they have been added out
36331 // of order
36332 this.c.breakpoints.sort( function (a, b) {
36333 return a.width < b.width ? 1 :
36334 a.width > b.width ? -1 : 0;
36335 } );
36336
36337 this._classLogic();
36338 this._resizeAuto();
36339
36340 // Details handler
36341 var details = this.c.details;
36342
36343 if ( details.type !== false ) {
36344 that._detailsInit();
36345
36346 // DataTables will trigger this event on every column it shows and
36347 // hides individually
36348 dt.on( 'column-visibility.dtr', function (e, ctx, col, vis) {
36349 that._classLogic();
36350 that._resizeAuto();
36351 that._resize();
36352 } );
36353
36354 // Redraw the details box on each draw which will happen if the data
36355 // has changed. This is used until DataTables implements a native
36356 // `updated` event for rows
36357 dt.on( 'draw.dtr', function () {
36358 that._redrawChildren();
36359 } );
36360
36361 $(dt.table().node()).addClass( 'dtr-'+details.type );
36362 }
36363
36364 dt.on( 'column-reorder.dtr', function (e, settings, details) {
36365 that._classLogic();
36366 that._resizeAuto();
36367 that._resize();
36368 } );
36369
36370 // Change in column sizes means we need to calc
36371 dt.on( 'column-sizing.dtr', function () {
36372 that._resizeAuto();
36373 that._resize();
36374 });
36375
36376 dt.on( 'init.dtr', function (e, settings, details) {
36377 that._resizeAuto();
36378 that._resize();
36379
36380 // If columns were hidden, then DataTables needs to adjust the
36381 // column sizing
36382 if ( $.inArray( false, that.s.current ) ) {
36383 dt.columns.adjust();
36384 }
36385 } );
36386
36387 // First pass - draw the table for the current viewport size
36388 this._resize();
36389 },
36390
36391
36392 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
36393 * Private methods
36394 */
36395
36396 /**
36397 * Calculate the visibility for the columns in a table for a given
36398 * breakpoint. The result is pre-determined based on the class logic if
36399 * class names are used to control all columns, but the width of the table
36400 * is also used if there are columns which are to be automatically shown
36401 * and hidden.
36402 *
36403 * @param {string} breakpoint Breakpoint name to use for the calculation
36404 * @return {array} Array of boolean values initiating the visibility of each
36405 * column.
36406 * @private
36407 */
36408 _columnsVisiblity: function ( breakpoint )
36409 {
36410 var dt = this.s.dt;
36411 var columns = this.s.columns;
36412 var i, ien;
36413
36414 // Create an array that defines the column ordering based first on the
36415 // column's priority, and secondly the column index. This allows the
36416 // columns to be removed from the right if the priority matches
36417 var order = columns
36418 .map( function ( col, idx ) {
36419 return {
36420 columnIdx: idx,
36421 priority: col.priority
36422 };
36423 } )
36424 .sort( function ( a, b ) {
36425 if ( a.priority !== b.priority ) {
36426 return a.priority - b.priority;
36427 }
36428 return a.columnIdx - b.columnIdx;
36429 } );
36430
36431 // Class logic - determine which columns are in this breakpoint based
36432 // on the classes. If no class control (i.e. `auto`) then `-` is used
36433 // to indicate this to the rest of the function
36434 var display = $.map( columns, function ( col ) {
36435 return col.auto && col.minWidth === null ?
36436 false :
36437 col.auto === true ?
36438 '-' :
36439 $.inArray( breakpoint, col.includeIn ) !== -1;
36440 } );
36441
36442 // Auto column control - first pass: how much width is taken by the
36443 // ones that must be included from the non-auto columns
36444 var requiredWidth = 0;
36445 for ( i=0, ien=display.length ; i<ien ; i++ ) {
36446 if ( display[i] === true ) {
36447 requiredWidth += columns[i].minWidth;
36448 }
36449 }
36450
36451 // Second pass, use up any remaining width for other columns. For
36452 // scrolling tables we need to subtract the width of the scrollbar. It
36453 // may not be requires which makes this sub-optimal, but it would
36454 // require another full redraw to make complete use of those extra few
36455 // pixels
36456 var scrolling = dt.settings()[0].oScroll;
36457 var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
36458 var widthAvailable = dt.table().container().offsetWidth - bar;
36459 var usedWidth = widthAvailable - requiredWidth;
36460
36461 // Control column needs to always be included. This makes it sub-
36462 // optimal in terms of using the available with, but to stop layout
36463 // thrashing or overflow. Also we need to account for the control column
36464 // width first so we know how much width is available for the other
36465 // columns, since the control column might not be the first one shown
36466 for ( i=0, ien=display.length ; i<ien ; i++ ) {
36467 if ( columns[i].control ) {
36468 usedWidth -= columns[i].minWidth;
36469 }
36470 }
36471
36472 // Allow columns to be shown (counting by priority and then right to
36473 // left) until we run out of room
36474 var empty = false;
36475 for ( i=0, ien=order.length ; i<ien ; i++ ) {
36476 var colIdx = order[i].columnIdx;
36477
36478 if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
36479 // Once we've found a column that won't fit we don't let any
36480 // others display either, or columns might disappear in the
36481 // middle of the table
36482 if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
36483 empty = true;
36484 display[colIdx] = false;
36485 }
36486 else {
36487 display[colIdx] = true;
36488 }
36489
36490 usedWidth -= columns[colIdx].minWidth;
36491 }
36492 }
36493
36494 // Determine if the 'control' column should be shown (if there is one).
36495 // This is the case when there is a hidden column (that is not the
36496 // control column). The two loops look inefficient here, but they are
36497 // trivial and will fly through. We need to know the outcome from the
36498 // first , before the action in the second can be taken
36499 var showControl = false;
36500
36501 for ( i=0, ien=columns.length ; i<ien ; i++ ) {
36502 if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
36503 showControl = true;
36504 break;
36505 }
36506 }
36507
36508 for ( i=0, ien=columns.length ; i<ien ; i++ ) {
36509 if ( columns[i].control ) {
36510 display[i] = showControl;
36511 }
36512 }
36513
36514 // Finally we need to make sure that there is at least one column that
36515 // is visible
36516 if ( $.inArray( true, display ) === -1 ) {
36517 display[0] = true;
36518 }
36519
36520 return display;
36521 },
36522
36523
36524 /**
36525 * Create the internal `columns` array with information about the columns
36526 * for the table. This includes determining which breakpoints the column
36527 * will appear in, based upon class names in the column, which makes up the
36528 * vast majority of this method.
36529 *
36530 * @private
36531 */
36532 _classLogic: function ()
36533 {
36534 var that = this;
36535 var calc = {};
36536 var breakpoints = this.c.breakpoints;
36537 var dt = this.s.dt;
36538 var columns = dt.columns().eq(0).map( function (i) {
36539 var column = this.column(i);
36540 var className = column.header().className;
36541 var priority = dt.settings()[0].aoColumns[i].responsivePriority;
36542
36543 if ( priority === undefined ) {
36544 var dataPriority = $(column.header()).data('priority');
36545
36546 priority = dataPriority !== undefined ?
36547 dataPriority * 1 :
36548 10000;
36549 }
36550
36551 return {
36552 className: className,
36553 includeIn: [],
36554 auto: false,
36555 control: false,
36556 never: className.match(/\bnever\b/) ? true : false,
36557 priority: priority
36558 };
36559 } );
36560
36561 // Simply add a breakpoint to `includeIn` array, ensuring that there are
36562 // no duplicates
36563 var add = function ( colIdx, name ) {
36564 var includeIn = columns[ colIdx ].includeIn;
36565
36566 if ( $.inArray( name, includeIn ) === -1 ) {
36567 includeIn.push( name );
36568 }
36569 };
36570
36571 var column = function ( colIdx, name, operator, matched ) {
36572 var size, i, ien;
36573
36574 if ( ! operator ) {
36575 columns[ colIdx ].includeIn.push( name );
36576 }
36577 else if ( operator === 'max-' ) {
36578 // Add this breakpoint and all smaller
36579 size = that._find( name ).width;
36580
36581 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
36582 if ( breakpoints[i].width <= size ) {
36583 add( colIdx, breakpoints[i].name );
36584 }
36585 }
36586 }
36587 else if ( operator === 'min-' ) {
36588 // Add this breakpoint and all larger
36589 size = that._find( name ).width;
36590
36591 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
36592 if ( breakpoints[i].width >= size ) {
36593 add( colIdx, breakpoints[i].name );
36594 }
36595 }
36596 }
36597 else if ( operator === 'not-' ) {
36598 // Add all but this breakpoint
36599 for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
36600 if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
36601 add( colIdx, breakpoints[i].name );
36602 }
36603 }
36604 }
36605 };
36606
36607 // Loop over each column and determine if it has a responsive control
36608 // class
36609 columns.each( function ( col, i ) {
36610 var classNames = col.className.split(' ');
36611 var hasClass = false;
36612
36613 // Split the class name up so multiple rules can be applied if needed
36614 for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
36615 var className = $.trim( classNames[k] );
36616
36617 if ( className === 'all' ) {
36618 // Include in all
36619 hasClass = true;
36620 col.includeIn = $.map( breakpoints, function (a) {
36621 return a.name;
36622 } );
36623 return;
36624 }
36625 else if ( className === 'none' || col.never ) {
36626 // Include in none (default) and no auto
36627 hasClass = true;
36628 return;
36629 }
36630 else if ( className === 'control' ) {
36631 // Special column that is only visible, when one of the other
36632 // columns is hidden. This is used for the details control
36633 hasClass = true;
36634 col.control = true;
36635 return;
36636 }
36637
36638 $.each( breakpoints, function ( j, breakpoint ) {
36639 // Does this column have a class that matches this breakpoint?
36640 var brokenPoint = breakpoint.name.split('-');
36641 var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
36642 var match = className.match( re );
36643
36644 if ( match ) {
36645 hasClass = true;
36646
36647 if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
36648 // Class name matches breakpoint name fully
36649 column( i, breakpoint.name, match[1], match[2]+match[3] );
36650 }
36651 else if ( match[2] === brokenPoint[0] && ! match[3] ) {
36652 // Class name matched primary breakpoint name with no qualifier
36653 column( i, breakpoint.name, match[1], match[2] );
36654 }
36655 }
36656 } );
36657 }
36658
36659 // If there was no control class, then automatic sizing is used
36660 if ( ! hasClass ) {
36661 col.auto = true;
36662 }
36663 } );
36664
36665 this.s.columns = columns;
36666 },
36667
36668
36669 /**
36670 * Show the details for the child row
36671 *
36672 * @param {DataTables.Api} row API instance for the row
36673 * @param {boolean} update Update flag
36674 * @private
36675 */
36676 _detailsDisplay: function ( row, update )
36677 {
36678 var that = this;
36679 var dt = this.s.dt;
36680 var details = this.c.details;
36681
36682 if ( details && details.type !== false ) {
36683 var res = details.display( row, update, function () {
36684 return details.renderer(
36685 dt, row[0], that._detailsObj(row[0])
36686 );
36687 } );
36688
36689 if ( res === true || res === false ) {
36690 $(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
36691 }
36692 }
36693 },
36694
36695
36696 /**
36697 * Initialisation for the details handler
36698 *
36699 * @private
36700 */
36701 _detailsInit: function ()
36702 {
36703 var that = this;
36704 var dt = this.s.dt;
36705 var details = this.c.details;
36706
36707 // The inline type always uses the first child as the target
36708 if ( details.type === 'inline' ) {
36709 details.target = 'td:first-child, th:first-child';
36710 }
36711
36712 // Keyboard accessibility
36713 dt.on( 'draw.dtr', function () {
36714 that._tabIndexes();
36715 } );
36716 that._tabIndexes(); // Initial draw has already happened
36717
36718 $( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
36719 if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
36720 $(this).click();
36721 }
36722 } );
36723
36724 // type.target can be a string jQuery selector or a column index
36725 var target = details.target;
36726 var selector = typeof target === 'string' ? target : 'td, th';
36727
36728 // Click handler to show / hide the details rows when they are available
36729 $( dt.table().body() )
36730 .on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
36731 // If the table is not collapsed (i.e. there is no hidden columns)
36732 // then take no action
36733 if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
36734 return;
36735 }
36736
36737 // Check that the row is actually a DataTable's controlled node
36738 if ( ! dt.row( $(this).closest('tr') ).length ) {
36739 return;
36740 }
36741
36742 // For column index, we determine if we should act or not in the
36743 // handler - otherwise it is already okay
36744 if ( typeof target === 'number' ) {
36745 var targetIdx = target < 0 ?
36746 dt.columns().eq(0).length + target :
36747 target;
36748
36749 if ( dt.cell( this ).index().column !== targetIdx ) {
36750 return;
36751 }
36752 }
36753
36754 // $().closest() includes itself in its check
36755 var row = dt.row( $(this).closest('tr') );
36756
36757 // Check event type to do an action
36758 if ( e.type === 'click' ) {
36759 // The renderer is given as a function so the caller can execute it
36760 // only when they need (i.e. if hiding there is no point is running
36761 // the renderer)
36762 that._detailsDisplay( row, false );
36763 }
36764 else if ( e.type === 'mousedown' ) {
36765 // For mouse users, prevent the focus ring from showing
36766 $(this).css('outline', 'none');
36767 }
36768 else if ( e.type === 'mouseup' ) {
36769 // And then re-allow at the end of the click
36770 $(this).blur().css('outline', '');
36771 }
36772 } );
36773 },
36774
36775
36776 /**
36777 * Get the details to pass to a renderer for a row
36778 * @param {int} rowIdx Row index
36779 * @private
36780 */
36781 _detailsObj: function ( rowIdx )
36782 {
36783 var that = this;
36784 var dt = this.s.dt;
36785
36786 return $.map( this.s.columns, function( col, i ) {
36787 // Never and control columns should not be passed to the renderer
36788 if ( col.never || col.control ) {
36789 return;
36790 }
36791
36792 return {
36793 title: dt.settings()[0].aoColumns[ i ].sTitle,
36794 data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
36795 hidden: dt.column( i ).visible() && !that.s.current[ i ],
36796 columnIndex: i,
36797 rowIndex: rowIdx
36798 };
36799 } );
36800 },
36801
36802
36803 /**
36804 * Find a breakpoint object from a name
36805 *
36806 * @param {string} name Breakpoint name to find
36807 * @return {object} Breakpoint description object
36808 * @private
36809 */
36810 _find: function ( name )
36811 {
36812 var breakpoints = this.c.breakpoints;
36813
36814 for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
36815 if ( breakpoints[i].name === name ) {
36816 return breakpoints[i];
36817 }
36818 }
36819 },
36820
36821
36822 /**
36823 * Re-create the contents of the child rows as the display has changed in
36824 * some way.
36825 *
36826 * @private
36827 */
36828 _redrawChildren: function ()
36829 {
36830 var that = this;
36831 var dt = this.s.dt;
36832
36833 dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
36834 var row = dt.row( idx );
36835
36836 that._detailsDisplay( dt.row( idx ), true );
36837 } );
36838 },
36839
36840
36841 /**
36842 * Alter the table display for a resized viewport. This involves first
36843 * determining what breakpoint the window currently is in, getting the
36844 * column visibilities to apply and then setting them.
36845 *
36846 * @private
36847 */
36848 _resize: function ()
36849 {
36850 var that = this;
36851 var dt = this.s.dt;
36852 var width = $(window).width();
36853 var breakpoints = this.c.breakpoints;
36854 var breakpoint = breakpoints[0].name;
36855 var columns = this.s.columns;
36856 var i, ien;
36857 var oldVis = this.s.current.slice();
36858
36859 // Determine what breakpoint we are currently at
36860 for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
36861 if ( width <= breakpoints[i].width ) {
36862 breakpoint = breakpoints[i].name;
36863 break;
36864 }
36865 }
36866
36867 // Show the columns for that break point
36868 var columnsVis = this._columnsVisiblity( breakpoint );
36869 this.s.current = columnsVis;
36870
36871 // Set the class before the column visibility is changed so event
36872 // listeners know what the state is. Need to determine if there are
36873 // any columns that are not visible but can be shown
36874 var collapsedClass = false;
36875 for ( i=0, ien=columns.length ; i<ien ; i++ ) {
36876 if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control ) {
36877 collapsedClass = true;
36878 break;
36879 }
36880 }
36881
36882 $( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
36883
36884 var changed = false;
36885
36886 dt.columns().eq(0).each( function ( colIdx, i ) {
36887 if ( columnsVis[i] !== oldVis[i] ) {
36888 changed = true;
36889 that._setColumnVis( colIdx, columnsVis[i] );
36890 }
36891 } );
36892
36893 if ( changed ) {
36894 this._redrawChildren();
36895
36896 // Inform listeners of the change
36897 $(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
36898 }
36899 },
36900
36901
36902 /**
36903 * Determine the width of each column in the table so the auto column hiding
36904 * has that information to work with. This method is never going to be 100%
36905 * perfect since column widths can change slightly per page, but without
36906 * seriously compromising performance this is quite effective.
36907 *
36908 * @private
36909 */
36910 _resizeAuto: function ()
36911 {
36912 var dt = this.s.dt;
36913 var columns = this.s.columns;
36914
36915 // Are we allowed to do auto sizing?
36916 if ( ! this.c.auto ) {
36917 return;
36918 }
36919
36920 // Are there any columns that actually need auto-sizing, or do they all
36921 // have classes defined
36922 if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
36923 return;
36924 }
36925
36926 // Clone the table with the current data in it
36927 var tableWidth = dt.table().node().offsetWidth;
36928 var columnWidths = dt.columns;
36929 var clonedTable = dt.table().node().cloneNode( false );
36930 var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
36931 var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
36932
36933 // Header
36934 var headerCells = dt.columns()
36935 .header()
36936 .filter( function (idx) {
36937 return dt.column(idx).visible();
36938 } )
36939 .to$()
36940 .clone( false )
36941 .css( 'display', 'table-cell' );
36942
36943 // Body rows - we don't need to take account of DataTables' column
36944 // visibility since we implement our own here (hence the `display` set)
36945 $(clonedBody)
36946 .append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
36947 .find( 'th, td' ).css( 'display', '' );
36948
36949 // Footer
36950 var footer = dt.table().footer();
36951 if ( footer ) {
36952 var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
36953 var footerCells = dt.columns()
36954 .footer()
36955 .filter( function (idx) {
36956 return dt.column(idx).visible();
36957 } )
36958 .to$()
36959 .clone( false )
36960 .css( 'display', 'table-cell' );
36961
36962 $('<tr/>')
36963 .append( footerCells )
36964 .appendTo( clonedFooter );
36965 }
36966
36967 $('<tr/>')
36968 .append( headerCells )
36969 .appendTo( clonedHeader );
36970
36971 // In the inline case extra padding is applied to the first column to
36972 // give space for the show / hide icon. We need to use this in the
36973 // calculation
36974 if ( this.c.details.type === 'inline' ) {
36975 $(clonedTable).addClass( 'dtr-inline collapsed' );
36976 }
36977
36978 // It is unsafe to insert elements with the same name into the DOM
36979 // multiple times. For example, cloning and inserting a checked radio
36980 // clears the chcecked state of the original radio.
36981 $( clonedTable ).find( '[name]' ).removeAttr( 'name' );
36982
36983 var inserted = $('<div/>')
36984 .css( {
36985 width: 1,
36986 height: 1,
36987 overflow: 'hidden'
36988 } )
36989 .append( clonedTable );
36990
36991 inserted.insertBefore( dt.table().node() );
36992
36993 // The cloned header now contains the smallest that each column can be
36994 headerCells.each( function (i) {
36995 var idx = dt.column.index( 'fromVisible', i );
36996 columns[ idx ].minWidth = this.offsetWidth || 0;
36997 } );
36998
36999 inserted.remove();
37000 },
37001
37002 /**
37003 * Set a column's visibility.
37004 *
37005 * We don't use DataTables' column visibility controls in order to ensure
37006 * that column visibility can Responsive can no-exist. Since only IE8+ is
37007 * supported (and all evergreen browsers of course) the control of the
37008 * display attribute works well.
37009 *
37010 * @param {integer} col Column index
37011 * @param {boolean} showHide Show or hide (true or false)
37012 * @private
37013 */
37014 _setColumnVis: function ( col, showHide )
37015 {
37016 var dt = this.s.dt;
37017 var display = showHide ? '' : 'none'; // empty string will remove the attr
37018
37019 $( dt.column( col ).header() ).css( 'display', display );
37020 $( dt.column( col ).footer() ).css( 'display', display );
37021 dt.column( col ).nodes().to$().css( 'display', display );
37022 },
37023
37024
37025 /**
37026 * Update the cell tab indexes for keyboard accessibility. This is called on
37027 * every table draw - that is potentially inefficient, but also the least
37028 * complex option given that column visibility can change on the fly. Its a
37029 * shame user-focus was removed from CSS 3 UI, as it would have solved this
37030 * issue with a single CSS statement.
37031 *
37032 * @private
37033 */
37034 _tabIndexes: function ()
37035 {
37036 var dt = this.s.dt;
37037 var cells = dt.cells( { page: 'current' } ).nodes().to$();
37038 var ctx = dt.settings()[0];
37039 var target = this.c.details.target;
37040
37041 cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
37042
37043 var selector = typeof target === 'number' ?
37044 ':eq('+target+')' :
37045 target;
37046
37047 $( selector, dt.rows( { page: 'current' } ).nodes() )
37048 .attr( 'tabIndex', ctx.iTabIndex )
37049 .data( 'dtr-keyboard', 1 );
37050 }
37051} );
37052
37053
37054/**
37055 * List of default breakpoints. Each item in the array is an object with two
37056 * properties:
37057 *
37058 * * `name` - the breakpoint name.
37059 * * `width` - the breakpoint width
37060 *
37061 * @name Responsive.breakpoints
37062 * @static
37063 */
37064Responsive.breakpoints = [
37065 { name: 'desktop', width: Infinity },
37066 { name: 'tablet-l', width: 1024 },
37067 { name: 'tablet-p', width: 768 },
37068 { name: 'mobile-l', width: 480 },
37069 { name: 'mobile-p', width: 320 }
37070];
37071
37072
37073/**
37074 * Display methods - functions which define how the hidden data should be shown
37075 * in the table.
37076 *
37077 * @namespace
37078 * @name Responsive.defaults
37079 * @static
37080 */
37081Responsive.display = {
37082 childRow: function ( row, update, render ) {
37083 if ( update ) {
37084 if ( $(row.node()).hasClass('parent') ) {
37085 row.child( render(), 'child' ).show();
37086
37087 return true;
37088 }
37089 }
37090 else {
37091 if ( ! row.child.isShown() ) {
37092 row.child( render(), 'child' ).show();
37093 $( row.node() ).addClass( 'parent' );
37094
37095 return true;
37096 }
37097 else {
37098 row.child( false );
37099 $( row.node() ).removeClass( 'parent' );
37100
37101 return false;
37102 }
37103 }
37104 },
37105
37106 childRowImmediate: function ( row, update, render ) {
37107 if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
37108 // User interaction and the row is show, or nothing to show
37109 row.child( false );
37110 $( row.node() ).removeClass( 'parent' );
37111
37112 return false;
37113 }
37114 else {
37115 // Display
37116 row.child( render(), 'child' ).show();
37117 $( row.node() ).addClass( 'parent' );
37118
37119 return true;
37120 }
37121 },
37122
37123 // This is a wrapper so the modal options for Bootstrap and jQuery UI can
37124 // have options passed into them. This specific one doesn't need to be a
37125 // function but it is for consistency in the `modal` name
37126 modal: function ( options ) {
37127 return function ( row, update, render ) {
37128 if ( ! update ) {
37129 // Show a modal
37130 var close = function () {
37131 modal.remove(); // will tidy events for us
37132 $(document).off( 'keypress.dtr' );
37133 };
37134
37135 var modal = $('<div class="dtr-modal"/>')
37136 .append( $('<div class="dtr-modal-display"/>')
37137 .append( $('<div class="dtr-modal-content"/>')
37138 .append( render() )
37139 )
37140 .append( $('<div class="dtr-modal-close">×</div>' )
37141 .click( function () {
37142 close();
37143 } )
37144 )
37145 )
37146 .append( $('<div class="dtr-modal-background"/>')
37147 .click( function () {
37148 close();
37149 } )
37150 )
37151 .appendTo( 'body' );
37152
37153 $(document).on( 'keyup.dtr', function (e) {
37154 if ( e.keyCode === 27 ) {
37155 e.stopPropagation();
37156
37157 close();
37158 }
37159 } );
37160 }
37161 else {
37162 $('div.dtr-modal-content')
37163 .empty()
37164 .append( render() );
37165 }
37166
37167 if ( options && options.header ) {
37168 $('div.dtr-modal-content').prepend(
37169 '<h2>'+options.header( row )+'</h2>'
37170 );
37171 }
37172 };
37173 }
37174};
37175
37176
37177/**
37178 * Display methods - functions which define how the hidden data should be shown
37179 * in the table.
37180 *
37181 * @namespace
37182 * @name Responsive.defaults
37183 * @static
37184 */
37185Responsive.renderer = {
37186 listHidden: function () {
37187 return function ( api, rowIdx, columns ) {
37188 var data = $.map( columns, function ( col ) {
37189 return col.hidden ?
37190 '<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
37191 '<span class="dtr-title">'+
37192 col.title+
37193 '</span> '+
37194 '<span class="dtr-data">'+
37195 col.data+
37196 '</span>'+
37197 '</li>' :
37198 '';
37199 } ).join('');
37200
37201 return data ?
37202 $('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
37203 false;
37204 }
37205 },
37206
37207 tableAll: function ( options ) {
37208 options = $.extend( {
37209 tableClass: ''
37210 }, options );
37211
37212 return function ( api, rowIdx, columns ) {
37213 var data = $.map( columns, function ( col ) {
37214 return '<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
37215 '<td>'+col.title+':'+'</td> '+
37216 '<td>'+col.data+'</td>'+
37217 '</tr>';
37218 } ).join('');
37219
37220 return $('<table class="'+options.tableClass+'" width="100%"/>').append( data );
37221 }
37222 }
37223};
37224
37225/**
37226 * Responsive default settings for initialisation
37227 *
37228 * @namespace
37229 * @name Responsive.defaults
37230 * @static
37231 */
37232Responsive.defaults = {
37233 /**
37234 * List of breakpoints for the instance. Note that this means that each
37235 * instance can have its own breakpoints. Additionally, the breakpoints
37236 * cannot be changed once an instance has been creased.
37237 *
37238 * @type {Array}
37239 * @default Takes the value of `Responsive.breakpoints`
37240 */
37241 breakpoints: Responsive.breakpoints,
37242
37243 /**
37244 * Enable / disable auto hiding calculations. It can help to increase
37245 * performance slightly if you disable this option, but all columns would
37246 * need to have breakpoint classes assigned to them
37247 *
37248 * @type {Boolean}
37249 * @default `true`
37250 */
37251 auto: true,
37252
37253 /**
37254 * Details control. If given as a string value, the `type` property of the
37255 * default object is set to that value, and the defaults used for the rest
37256 * of the object - this is for ease of implementation.
37257 *
37258 * The object consists of the following properties:
37259 *
37260 * * `display` - A function that is used to show and hide the hidden details
37261 * * `renderer` - function that is called for display of the child row data.
37262 * The default function will show the data from the hidden columns
37263 * * `target` - Used as the selector for what objects to attach the child
37264 * open / close to
37265 * * `type` - `false` to disable the details display, `inline` or `column`
37266 * for the two control types
37267 *
37268 * @type {Object|string}
37269 */
37270 details: {
37271 display: Responsive.display.childRow,
37272
37273 renderer: Responsive.renderer.listHidden(),
37274
37275 target: 0,
37276
37277 type: 'inline'
37278 },
37279
37280 /**
37281 * Orthogonal data request option. This is used to define the data type
37282 * requested when Responsive gets the data to show in the child row.
37283 *
37284 * @type {String}
37285 */
37286 orthogonal: 'display'
37287};
37288
37289
37290/*
37291 * API
37292 */
37293var Api = $.fn.dataTable.Api;
37294
37295// Doesn't do anything - work around for a bug in DT... Not documented
37296Api.register( 'responsive()', function () {
37297 return this;
37298} );
37299
37300Api.register( 'responsive.index()', function ( li ) {
37301 li = $(li);
37302
37303 return {
37304 column: li.data('dtr-index'),
37305 row: li.parent().data('dtr-index')
37306 };
37307} );
37308
37309Api.register( 'responsive.rebuild()', function () {
37310 return this.iterator( 'table', function ( ctx ) {
37311 if ( ctx._responsive ) {
37312 ctx._responsive._classLogic();
37313 }
37314 } );
37315} );
37316
37317Api.register( 'responsive.recalc()', function () {
37318 return this.iterator( 'table', function ( ctx ) {
37319 if ( ctx._responsive ) {
37320 ctx._responsive._resizeAuto();
37321 ctx._responsive._resize();
37322 }
37323 } );
37324} );
37325
37326Api.register( 'responsive.hasHidden()', function () {
37327 var ctx = this.context[0];
37328
37329 return ctx._responsive ?
37330 $.inArray( false, ctx._responsive.s.current ) !== -1 :
37331 false;
37332} );
37333
37334
37335/**
37336 * Version information
37337 *
37338 * @name Responsive.version
37339 * @static
37340 */
37341Responsive.version = '2.1.0';
37342
37343
37344$.fn.dataTable.Responsive = Responsive;
37345$.fn.DataTable.Responsive = Responsive;
37346
37347// Attach a listener to the document which listens for DataTables initialisation
37348// events so we can automatically initialise
37349$(document).on( 'preInit.dt.dtr', function (e, settings, json) {
37350 if ( e.namespace !== 'dt' ) {
37351 return;
37352 }
37353
37354 if ( $(settings.nTable).hasClass( 'responsive' ) ||
37355 $(settings.nTable).hasClass( 'dt-responsive' ) ||
37356 settings.oInit.responsive ||
37357 DataTable.defaults.responsive
37358 ) {
37359 var init = settings.oInit.responsive;
37360
37361 if ( init !== false ) {
37362 new Responsive( settings, $.isPlainObject( init ) ? init : {} );
37363 }
37364 }
37365} );
37366
37367
37368return Responsive;
37369}));
37370
37371/*! Bootstrap integration for DataTables' Responsive
37372 * ©2015-2016 SpryMedia Ltd - datatables.net/license
37373 */
37374
37375(function( factory ){
37376 if ( typeof define === 'function' && define.amd ) {
37377 // AMD
37378 define( ['jquery', 'datatables.net-bs', 'datatables.net-responsive'], function ( $ ) {
37379 return factory( $, window, document );
37380 } );
37381 }
37382 else if ( typeof exports === 'object' ) {
37383 // CommonJS
37384 module.exports = function (root, $) {
37385 if ( ! root ) {
37386 root = window;
37387 }
37388
37389 if ( ! $ || ! $.fn.dataTable ) {
37390 $ = require('datatables.net-bs')(root, $).$;
37391 }
37392
37393 if ( ! $.fn.dataTable.Responsive ) {
37394 require('datatables.net-responsive')(root, $);
37395 }
37396
37397 return factory( $, root, root.document );
37398 };
37399 }
37400 else {
37401 // Browser
37402 factory( jQuery, window, document );
37403 }
37404}(function( $, window, document, undefined ) {
37405'use strict';
37406var DataTable = $.fn.dataTable;
37407
37408
37409var _display = DataTable.Responsive.display;
37410var _original = _display.modal;
37411var _modal = $(
37412 '<div class="modal fade dtr-bs-modal" role="dialog">'+
37413 '<div class="modal-dialog" role="document">'+
37414 '<div class="modal-content">'+
37415 '<div class="modal-header">'+
37416 '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>'+
37417 '</div>'+
37418 '<div class="modal-body"/>'+
37419 '</div>'+
37420 '</div>'+
37421 '</div>'
37422);
37423
37424_display.modal = function ( options ) {
37425 return function ( row, update, render ) {
37426 if ( ! $.fn.modal ) {
37427 _original( row, update, render );
37428 }
37429 else {
37430 if ( ! update ) {
37431 if ( options && options.header ) {
37432 _modal.find('div.modal-header')
37433 .empty()
37434 .append( '<h4 class="modal-title">'+options.header( row )+'</h4>' );
37435 }
37436
37437 _modal.find( 'div.modal-body' )
37438 .empty()
37439 .append( render() );
37440
37441 _modal
37442 .appendTo( 'body' )
37443 .modal();
37444 }
37445 }
37446 };
37447};
37448
37449
37450return DataTable.Responsive;
37451}));
37452
37453/**
37454 * Bootstrap Multiselect (https://github.com/davidstutz/bootstrap-multiselect)
37455 *
37456 * Apache License, Version 2.0:
37457 * Copyright (c) 2012 - 2015 David Stutz
37458 *
37459 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37460 * use this file except in compliance with the License. You may obtain a
37461 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0
37462 *
37463 * Unless required by applicable law or agreed to in writing, software
37464 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
37465 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
37466 * License for the specific language governing permissions and limitations
37467 * under the License.
37468 *
37469 * BSD 3-Clause License:
37470 * Copyright (c) 2012 - 2015 David Stutz
37471 * All rights reserved.
37472 *
37473 * Redistribution and use in source and binary forms, with or without
37474 * modification, are permitted provided that the following conditions are met:
37475 * - Redistributions of source code must retain the above copyright notice,
37476 * this list of conditions and the following disclaimer.
37477 * - Redistributions in binary form must reproduce the above copyright notice,
37478 * this list of conditions and the following disclaimer in the documentation
37479 * and/or other materials provided with the distribution.
37480 * - Neither the name of David Stutz nor the names of its contributors may be
37481 * used to endorse or promote products derived from this software without
37482 * specific prior written permission.
37483 *
37484 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37485 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
37486 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37487 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37488 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37489 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37490 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
37491 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37492 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
37493 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37494 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37495 */
37496!function ($) {
37497 "use strict";// jshint ;_;
37498
37499 if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
37500 ko.bindingHandlers.multiselect = {
37501 after: ['options', 'value', 'selectedOptions'],
37502
37503 init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
37504 var $element = $(element);
37505 var config = ko.toJS(valueAccessor());
37506
37507 $element.multiselect(config);
37508
37509 if (allBindings.has('options')) {
37510 var options = allBindings.get('options');
37511 if (ko.isObservable(options)) {
37512 ko.computed({
37513 read: function() {
37514 options();
37515 setTimeout(function() {
37516 var ms = $element.data('multiselect');
37517 if (ms)
37518 ms.updateOriginalOptions();//Not sure how beneficial this is.
37519 $element.multiselect('rebuild');
37520 }, 1);
37521 },
37522 disposeWhenNodeIsRemoved: element
37523 });
37524 }
37525 }
37526
37527 //value and selectedOptions are two-way, so these will be triggered even by our own actions.
37528 //It needs some way to tell if they are triggered because of us or because of outside change.
37529 //It doesn't loop but it's a waste of processing.
37530 if (allBindings.has('value')) {
37531 var value = allBindings.get('value');
37532 if (ko.isObservable(value)) {
37533 ko.computed({
37534 read: function() {
37535 value();
37536 setTimeout(function() {
37537 $element.multiselect('refresh');
37538 }, 1);
37539 },
37540 disposeWhenNodeIsRemoved: element
37541 }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
37542 }
37543 }
37544
37545 //Switched from arrayChange subscription to general subscription using 'refresh'.
37546 //Not sure performance is any better using 'select' and 'deselect'.
37547 if (allBindings.has('selectedOptions')) {
37548 var selectedOptions = allBindings.get('selectedOptions');
37549 if (ko.isObservable(selectedOptions)) {
37550 ko.computed({
37551 read: function() {
37552 selectedOptions();
37553 setTimeout(function() {
37554 $element.multiselect('refresh');
37555 }, 1);
37556 },
37557 disposeWhenNodeIsRemoved: element
37558 }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
37559 }
37560 }
37561
37562 ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
37563 $element.multiselect('destroy');
37564 });
37565 },
37566
37567 update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
37568 var $element = $(element);
37569 var config = ko.toJS(valueAccessor());
37570
37571 $element.multiselect('setOptions', config);
37572 $element.multiselect('rebuild');
37573 }
37574 };
37575 }
37576
37577 function forEach(array, callback) {
37578 for (var index = 0; index < array.length; ++index) {
37579 callback(array[index], index);
37580 }
37581 }
37582
37583 /**
37584 * Constructor to create a new multiselect using the given select.
37585 *
37586 * @param {jQuery} select
37587 * @param {Object} options
37588 * @returns {Multiselect}
37589 */
37590 function Multiselect(select, options) {
37591
37592 this.$select = $(select);
37593
37594 // Placeholder via data attributes
37595 if (this.$select.attr("data-placeholder")) {
37596 options.nonSelectedText = this.$select.data("placeholder");
37597 }
37598
37599 this.options = this.mergeOptions($.extend({}, options, this.$select.data()));
37600
37601 // Initialization.
37602 // We have to clone to create a new reference.
37603 this.originalOptions = this.$select.clone()[0].options;
37604 this.query = '';
37605 this.searchTimeout = null;
37606 this.lastToggledInput = null
37607
37608 this.options.multiple = this.$select.attr('multiple') === "multiple";
37609 this.options.onChange = $.proxy(this.options.onChange, this);
37610 this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
37611 this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
37612 this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this);
37613 this.options.onDropdownHidden = $.proxy(this.options.onDropdownHidden, this);
37614
37615 // Build select all if enabled.
37616 this.buildContainer();
37617 this.buildButton();
37618 this.buildDropdown();
37619 this.buildSelectAll();
37620 this.buildDropdownOptions();
37621 this.buildFilter();
37622
37623 this.updateButtonText();
37624 this.updateSelectAll();
37625
37626 if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
37627 this.disable();
37628 }
37629
37630 this.$select.hide().after(this.$container);
37631 };
37632
37633 Multiselect.prototype = {
37634
37635 defaults: {
37636 /**
37637 * Default text function will either print 'None selected' in case no
37638 * option is selected or a list of the selected options up to a length
37639 * of 3 selected options.
37640 *
37641 * @param {jQuery} options
37642 * @param {jQuery} select
37643 * @returns {String}
37644 */
37645 buttonText: function(options, select) {
37646 if (options.length === 0) {
37647 return this.nonSelectedText;
37648 }
37649 else if (this.allSelectedText
37650 && options.length === $('option', $(select)).length
37651 && $('option', $(select)).length !== 1
37652 && this.multiple) {
37653
37654 if (this.selectAllNumber) {
37655 return this.allSelectedText + ' (' + options.length + ')';
37656 }
37657 else {
37658 return this.allSelectedText;
37659 }
37660 }
37661 else if (options.length > this.numberDisplayed) {
37662 return options.length + ' ' + this.nSelectedText;
37663 }
37664 else {
37665 var selected = '';
37666 var delimiter = this.delimiterText;
37667
37668 options.each(function() {
37669 var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
37670 selected += label + delimiter;
37671 });
37672
37673 return selected.substr(0, selected.length - 2);
37674 }
37675 },
37676 /**
37677 * Updates the title of the button similar to the buttonText function.
37678 *
37679 * @param {jQuery} options
37680 * @param {jQuery} select
37681 * @returns {@exp;selected@call;substr}
37682 */
37683 buttonTitle: function(options, select) {
37684 if (options.length === 0) {
37685 return this.nonSelectedText;
37686 }
37687 else {
37688 var selected = '';
37689 var delimiter = this.delimiterText;
37690
37691 options.each(function () {
37692 var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text();
37693 selected += label + delimiter;
37694 });
37695 return selected.substr(0, selected.length - 2);
37696 }
37697 },
37698 /**
37699 * Create a label.
37700 *
37701 * @param {jQuery} element
37702 * @returns {String}
37703 */
37704 optionLabel: function(element){
37705 return $(element).attr('label') || $(element).text();
37706 },
37707 /**
37708 * Triggered on change of the multiselect.
37709 *
37710 * Not triggered when selecting/deselecting options manually.
37711 *
37712 * @param {jQuery} option
37713 * @param {Boolean} checked
37714 */
37715 onChange : function(option, checked) {
37716
37717 },
37718 /**
37719 * Triggered when the dropdown is shown.
37720 *
37721 * @param {jQuery} event
37722 */
37723 onDropdownShow: function(event) {
37724
37725 },
37726 /**
37727 * Triggered when the dropdown is hidden.
37728 *
37729 * @param {jQuery} event
37730 */
37731 onDropdownHide: function(event) {
37732
37733 },
37734 /**
37735 * Triggered after the dropdown is shown.
37736 *
37737 * @param {jQuery} event
37738 */
37739 onDropdownShown: function(event) {
37740
37741 },
37742 /**
37743 * Triggered after the dropdown is hidden.
37744 *
37745 * @param {jQuery} event
37746 */
37747 onDropdownHidden: function(event) {
37748
37749 },
37750 /**
37751 * Triggered on select all.
37752 */
37753 onSelectAll: function() {
37754
37755 },
37756 enableHTML: false,
37757 buttonClass: 'btn btn-default',
37758 inheritClass: false,
37759 buttonWidth: 'auto',
37760 buttonContainer: '<div class="btn-group" />',
37761 dropRight: false,
37762 selectedClass: 'active',
37763 // Maximum height of the dropdown menu.
37764 // If maximum height is exceeded a scrollbar will be displayed.
37765 maxHeight: false,
37766 checkboxName: false,
37767 includeSelectAllOption: false,
37768 includeSelectAllIfMoreThan: 0,
37769 selectAllText: ' Select all',
37770 selectAllValue: 'multiselect-all',
37771 selectAllName: false,
37772 selectAllNumber: true,
37773 enableFiltering: false,
37774 enableCaseInsensitiveFiltering: false,
37775 enableClickableOptGroups: false,
37776 filterPlaceholder: 'Search',
37777 // possible options: 'text', 'value', 'both'
37778 filterBehavior: 'text',
37779 includeFilterClearBtn: true,
37780 preventInputChangeEvent: false,
37781 nonSelectedText: 'None selected',
37782 nSelectedText: 'selected',
37783 allSelectedText: 'All selected',
37784 numberDisplayed: 3,
37785 disableIfEmpty: false,
37786 delimiterText: ', ',
37787 templates: {
37788 button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"><span class="multiselect-selected-text"></span> <b class="caret"></b></button>',
37789 ul: '<ul class="multiselect-container dropdown-menu"></ul>',
37790 filter: '<li class="multiselect-item filter"><div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>',
37791 filterClearBtn: '<span class="input-group-btn"><button class="btn btn-default multiselect-clear-filter" type="button"><i class="glyphicon glyphicon-remove-circle"></i></button></span>',
37792 li: '<li><a tabindex="0"><label></label></a></li>',
37793 divider: '<li class="multiselect-item divider"></li>',
37794 liGroup: '<li class="multiselect-item multiselect-group"><label></label></li>'
37795 }
37796 },
37797
37798 constructor: Multiselect,
37799
37800 /**
37801 * Builds the container of the multiselect.
37802 */
37803 buildContainer: function() {
37804 this.$container = $(this.options.buttonContainer);
37805 this.$container.on('show.bs.dropdown', this.options.onDropdownShow);
37806 this.$container.on('hide.bs.dropdown', this.options.onDropdownHide);
37807 this.$container.on('shown.bs.dropdown', this.options.onDropdownShown);
37808 this.$container.on('hidden.bs.dropdown', this.options.onDropdownHidden);
37809 },
37810
37811 /**
37812 * Builds the button of the multiselect.
37813 */
37814 buildButton: function() {
37815 this.$button = $(this.options.templates.button).addClass(this.options.buttonClass);
37816 if (this.$select.attr('class') && this.options.inheritClass) {
37817 this.$button.addClass(this.$select.attr('class'));
37818 }
37819 // Adopt active state.
37820 if (this.$select.prop('disabled')) {
37821 this.disable();
37822 }
37823 else {
37824 this.enable();
37825 }
37826
37827 // Manually add button width if set.
37828 if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') {
37829 this.$button.css({
37830 'width' : this.options.buttonWidth,
37831 'overflow' : 'hidden',
37832 'text-overflow' : 'ellipsis'
37833 });
37834 this.$container.css({
37835 'width': this.options.buttonWidth
37836 });
37837 }
37838
37839 // Keep the tab index from the select.
37840 var tabindex = this.$select.attr('tabindex');
37841 if (tabindex) {
37842 this.$button.attr('tabindex', tabindex);
37843 }
37844
37845 this.$container.prepend(this.$button);
37846 },
37847
37848 /**
37849 * Builds the ul representing the dropdown menu.
37850 */
37851 buildDropdown: function() {
37852
37853 // Build ul.
37854 this.$ul = $(this.options.templates.ul);
37855
37856 if (this.options.dropRight) {
37857 this.$ul.addClass('pull-right');
37858 }
37859
37860 // Set max height of dropdown menu to activate auto scrollbar.
37861 if (this.options.maxHeight) {
37862 // TODO: Add a class for this option to move the css declarations.
37863 this.$ul.css({
37864 'max-height': this.options.maxHeight + 'px',
37865 'overflow-y': 'auto',
37866 'overflow-x': 'hidden'
37867 });
37868 }
37869
37870 this.$container.append(this.$ul);
37871 },
37872
37873 /**
37874 * Build the dropdown options and binds all nessecary events.
37875 *
37876 * Uses createDivider and createOptionValue to create the necessary options.
37877 */
37878 buildDropdownOptions: function() {
37879
37880 this.$select.children().each($.proxy(function(index, element) {
37881
37882 var $element = $(element);
37883 // Support optgroups and options without a group simultaneously.
37884 var tag = $element.prop('tagName')
37885 .toLowerCase();
37886
37887 if ($element.prop('value') === this.options.selectAllValue) {
37888 return;
37889 }
37890
37891 if (tag === 'optgroup') {
37892 this.createOptgroup(element);
37893 }
37894 else if (tag === 'option') {
37895
37896 if ($element.data('role') === 'divider') {
37897 this.createDivider();
37898 }
37899 else {
37900 this.createOptionValue(element);
37901 }
37902
37903 }
37904
37905 // Other illegal tags will be ignored.
37906 }, this));
37907
37908 // Bind the change event on the dropdown elements.
37909 $('li input', this.$ul).on('change', $.proxy(function(event) {
37910 var $target = $(event.target);
37911
37912 var checked = $target.prop('checked') || false;
37913 var isSelectAllOption = $target.val() === this.options.selectAllValue;
37914
37915 // Apply or unapply the configured selected class.
37916 if (this.options.selectedClass) {
37917 if (checked) {
37918 $target.closest('li')
37919 .addClass(this.options.selectedClass);
37920 }
37921 else {
37922 $target.closest('li')
37923 .removeClass(this.options.selectedClass);
37924 }
37925 }
37926
37927 // Get the corresponding option.
37928 var value = $target.val();
37929 var $option = this.getOptionByValue(value);
37930
37931 var $optionsNotThis = $('option', this.$select).not($option);
37932 var $checkboxesNotThis = $('input', this.$container).not($target);
37933
37934 if (isSelectAllOption) {
37935 if (checked) {
37936 this.selectAll();
37937 }
37938 else {
37939 this.deselectAll();
37940 }
37941 }
37942
37943 if(!isSelectAllOption){
37944 if (checked) {
37945 $option.prop('selected', true);
37946
37947 if (this.options.multiple) {
37948 // Simply select additional option.
37949 $option.prop('selected', true);
37950 }
37951 else {
37952 // Unselect all other options and corresponding checkboxes.
37953 if (this.options.selectedClass) {
37954 $($checkboxesNotThis).closest('li').removeClass(this.options.selectedClass);
37955 }
37956
37957 $($checkboxesNotThis).prop('checked', false);
37958 $optionsNotThis.prop('selected', false);
37959
37960 // It's a single selection, so close.
37961 this.$button.click();
37962 }
37963
37964 if (this.options.selectedClass === "active") {
37965 $optionsNotThis.closest("a").css("outline", "");
37966 }
37967 }
37968 else {
37969 // Unselect option.
37970 $option.prop('selected', false);
37971 }
37972 }
37973
37974 this.$select.change();
37975
37976 this.updateButtonText();
37977 this.updateSelectAll();
37978
37979 this.options.onChange($option, checked);
37980
37981 if(this.options.preventInputChangeEvent) {
37982 return false;
37983 }
37984 }, this));
37985
37986 $('li a', this.$ul).on('mousedown', function(e) {
37987 if (e.shiftKey) {
37988 // Prevent selecting text by Shift+click
37989 return false;
37990 }
37991 });
37992
37993 $('li a', this.$ul).on('touchstart click', $.proxy(function(event) {
37994 event.stopPropagation();
37995
37996 var $target = $(event.target);
37997
37998 if (event.shiftKey && this.options.multiple) {
37999 if($target.is("label")){ // Handles checkbox selection manually (see https://github.com/davidstutz/bootstrap-multiselect/issues/431)
38000 event.preventDefault();
38001 $target = $target.find("input");
38002 $target.prop("checked", !$target.prop("checked"));
38003 }
38004 var checked = $target.prop('checked') || false;
38005
38006 if (this.lastToggledInput !== null && this.lastToggledInput !== $target) { // Make sure we actually have a range
38007 var from = $target.closest("li").index();
38008 var to = this.lastToggledInput.closest("li").index();
38009
38010 if (from > to) { // Swap the indices
38011 var tmp = to;
38012 to = from;
38013 from = tmp;
38014 }
38015
38016 // Make sure we grab all elements since slice excludes the last index
38017 ++to;
38018
38019 // Change the checkboxes and underlying options
38020 var range = this.$ul.find("li").slice(from, to).find("input");
38021
38022 range.prop('checked', checked);
38023
38024 if (this.options.selectedClass) {
38025 range.closest('li')
38026 .toggleClass(this.options.selectedClass, checked);
38027 }
38028
38029 for (var i = 0, j = range.length; i < j; i++) {
38030 var $checkbox = $(range[i]);
38031
38032 var $option = this.getOptionByValue($checkbox.val());
38033
38034 $option.prop('selected', checked);
38035 }
38036 }
38037
38038 // Trigger the select "change" event
38039 $target.trigger("change");
38040 }
38041
38042 // Remembers last clicked option
38043 if($target.is("input") && !$target.closest("li").is(".multiselect-item")){
38044 this.lastToggledInput = $target;
38045 }
38046
38047 $target.blur();
38048 }, this));
38049
38050 // Keyboard support.
38051 this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
38052 if ($('input[type="text"]', this.$container).is(':focus')) {
38053 return;
38054 }
38055
38056 if (event.keyCode === 9 && this.$container.hasClass('open')) {
38057 this.$button.click();
38058 }
38059 else {
38060 var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible");
38061
38062 if (!$items.length) {
38063 return;
38064 }
38065
38066 var index = $items.index($items.filter(':focus'));
38067
38068 // Navigation up.
38069 if (event.keyCode === 38 && index > 0) {
38070 index--;
38071 }
38072 // Navigate down.
38073 else if (event.keyCode === 40 && index < $items.length - 1) {
38074 index++;
38075 }
38076 else if (!~index) {
38077 index = 0;
38078 }
38079
38080 var $current = $items.eq(index);
38081 $current.focus();
38082
38083 if (event.keyCode === 32 || event.keyCode === 13) {
38084 var $checkbox = $current.find('input');
38085
38086 $checkbox.prop("checked", !$checkbox.prop("checked"));
38087 $checkbox.change();
38088 }
38089
38090 event.stopPropagation();
38091 event.preventDefault();
38092 }
38093 }, this));
38094
38095 if(this.options.enableClickableOptGroups && this.options.multiple) {
38096 $('li.multiselect-group', this.$ul).on('click', $.proxy(function(event) {
38097 event.stopPropagation();
38098
38099 var group = $(event.target).parent();
38100
38101 // Search all option in optgroup
38102 var $options = group.nextUntil('li.multiselect-group');
38103 var $visibleOptions = $options.filter(":visible:not(.disabled)");
38104
38105 // check or uncheck items
38106 var allChecked = true;
38107 var optionInputs = $visibleOptions.find('input');
38108 optionInputs.each(function() {
38109 allChecked = allChecked && $(this).prop('checked');
38110 });
38111
38112 optionInputs.prop('checked', !allChecked).trigger('change');
38113 }, this));
38114 }
38115 },
38116
38117 /**
38118 * Create an option using the given select option.
38119 *
38120 * @param {jQuery} element
38121 */
38122 createOptionValue: function(element) {
38123 var $element = $(element);
38124 if ($element.is(':selected')) {
38125 $element.prop('selected', true);
38126 }
38127
38128 // Support the label attribute on options.
38129 var label = this.options.optionLabel(element);
38130 var value = $element.val();
38131 var inputType = this.options.multiple ? "checkbox" : "radio";
38132
38133 var $li = $(this.options.templates.li);
38134 var $label = $('label', $li);
38135 $label.addClass(inputType);
38136
38137 if (this.options.enableHTML) {
38138 $label.html(" " + label);
38139 }
38140 else {
38141 $label.text(" " + label);
38142 }
38143
38144 var $checkbox = $('<input/>').attr('type', inputType);
38145
38146 if (this.options.checkboxName) {
38147 $checkbox.attr('name', this.options.checkboxName);
38148 }
38149 $label.prepend($checkbox);
38150
38151 var selected = $element.prop('selected') || false;
38152 $checkbox.val(value);
38153
38154 if (value === this.options.selectAllValue) {
38155 $li.addClass("multiselect-item multiselect-all");
38156 $checkbox.parent().parent()
38157 .addClass('multiselect-all');
38158 }
38159
38160 $label.attr('title', $element.attr('title'));
38161
38162 this.$ul.append($li);
38163
38164 if ($element.is(':disabled')) {
38165 $checkbox.attr('disabled', 'disabled')
38166 .prop('disabled', true)
38167 .closest('a')
38168 .attr("tabindex", "-1")
38169 .closest('li')
38170 .addClass('disabled');
38171 }
38172
38173 $checkbox.prop('checked', selected);
38174
38175 if (selected && this.options.selectedClass) {
38176 $checkbox.closest('li')
38177 .addClass(this.options.selectedClass);
38178 }
38179 },
38180
38181 /**
38182 * Creates a divider using the given select option.
38183 *
38184 * @param {jQuery} element
38185 */
38186 createDivider: function(element) {
38187 var $divider = $(this.options.templates.divider);
38188 this.$ul.append($divider);
38189 },
38190
38191 /**
38192 * Creates an optgroup.
38193 *
38194 * @param {jQuery} group
38195 */
38196 createOptgroup: function(group) {
38197 var groupName = $(group).prop('label');
38198
38199 // Add a header for the group.
38200 var $li = $(this.options.templates.liGroup);
38201
38202 if (this.options.enableHTML) {
38203 $('label', $li).html(groupName);
38204 }
38205 else {
38206 $('label', $li).text(groupName);
38207 }
38208
38209 if (this.options.enableClickableOptGroups) {
38210 $li.addClass('multiselect-group-clickable');
38211 }
38212
38213 this.$ul.append($li);
38214
38215 if ($(group).is(':disabled')) {
38216 $li.addClass('disabled');
38217 }
38218
38219 // Add the options of the group.
38220 $('option', group).each($.proxy(function(index, element) {
38221 this.createOptionValue(element);
38222 }, this));
38223 },
38224
38225 /**
38226 * Build the selct all.
38227 *
38228 * Checks if a select all has already been created.
38229 */
38230 buildSelectAll: function() {
38231 if (typeof this.options.selectAllValue === 'number') {
38232 this.options.selectAllValue = this.options.selectAllValue.toString();
38233 }
38234
38235 var alreadyHasSelectAll = this.hasSelectAll();
38236
38237 if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
38238 && $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) {
38239
38240 // Check whether to add a divider after the select all.
38241 if (this.options.includeSelectAllDivider) {
38242 this.$ul.prepend($(this.options.templates.divider));
38243 }
38244
38245 var $li = $(this.options.templates.li);
38246 $('label', $li).addClass("checkbox");
38247
38248 if (this.options.enableHTML) {
38249 $('label', $li).html(" " + this.options.selectAllText);
38250 }
38251 else {
38252 $('label', $li).text(" " + this.options.selectAllText);
38253 }
38254
38255 if (this.options.selectAllName) {
38256 $('label', $li).prepend('<input type="checkbox" name="' + this.options.selectAllName + '" />');
38257 }
38258 else {
38259 $('label', $li).prepend('<input type="checkbox" />');
38260 }
38261
38262 var $checkbox = $('input', $li);
38263 $checkbox.val(this.options.selectAllValue);
38264
38265 $li.addClass("multiselect-item multiselect-all");
38266 $checkbox.parent().parent()
38267 .addClass('multiselect-all');
38268
38269 this.$ul.prepend($li);
38270
38271 $checkbox.prop('checked', false);
38272 }
38273 },
38274
38275 /**
38276 * Builds the filter.
38277 */
38278 buildFilter: function() {
38279
38280 // Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength.
38281 if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) {
38282 var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering);
38283
38284 if (this.$select.find('option').length >= enableFilterLength) {
38285
38286 this.$filter = $(this.options.templates.filter);
38287 $('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
38288
38289 // Adds optional filter clear button
38290 if(this.options.includeFilterClearBtn){
38291 var clearBtn = $(this.options.templates.filterClearBtn);
38292 clearBtn.on('click', $.proxy(function(event){
38293 clearTimeout(this.searchTimeout);
38294 this.$filter.find('.multiselect-search').val('');
38295 $('li', this.$ul).show().removeClass("filter-hidden");
38296 this.updateSelectAll();
38297 }, this));
38298 this.$filter.find('.input-group').append(clearBtn);
38299 }
38300
38301 this.$ul.prepend(this.$filter);
38302
38303 this.$filter.val(this.query).on('click', function(event) {
38304 event.stopPropagation();
38305 }).on('input keydown', $.proxy(function(event) {
38306 // Cancel enter key default behaviour
38307 if (event.which === 13) {
38308 event.preventDefault();
38309 }
38310
38311 // This is useful to catch "keydown" events after the browser has updated the control.
38312 clearTimeout(this.searchTimeout);
38313
38314 this.searchTimeout = this.asyncFunction($.proxy(function() {
38315
38316 if (this.query !== event.target.value) {
38317 this.query = event.target.value;
38318
38319 var currentGroup, currentGroupVisible;
38320 $.each($('li', this.$ul), $.proxy(function(index, element) {
38321 var value = $('input', element).length > 0 ? $('input', element).val() : "";
38322 var text = $('label', element).text();
38323
38324 var filterCandidate = '';
38325 if ((this.options.filterBehavior === 'text')) {
38326 filterCandidate = text;
38327 }
38328 else if ((this.options.filterBehavior === 'value')) {
38329 filterCandidate = value;
38330 }
38331 else if (this.options.filterBehavior === 'both') {
38332 filterCandidate = text + '\n' + value;
38333 }
38334
38335 if (value !== this.options.selectAllValue && text) {
38336 // By default lets assume that element is not
38337 // interesting for this search.
38338 var showElement = false;
38339
38340 if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) {
38341 showElement = true;
38342 }
38343 else if (filterCandidate.indexOf(this.query) > -1) {
38344 showElement = true;
38345 }
38346
38347 // Toggle current element (group or group item) according to showElement boolean.
38348 $(element).toggle(showElement).toggleClass('filter-hidden', !showElement);
38349
38350 // Differentiate groups and group items.
38351 if ($(element).hasClass('multiselect-group')) {
38352 // Remember group status.
38353 currentGroup = element;
38354 currentGroupVisible = showElement;
38355 }
38356 else {
38357 // Show group name when at least one of its items is visible.
38358 if (showElement) {
38359 $(currentGroup).show().removeClass('filter-hidden');
38360 }
38361
38362 // Show all group items when group name satisfies filter.
38363 if (!showElement && currentGroupVisible) {
38364 $(element).show().removeClass('filter-hidden');
38365 }
38366 }
38367 }
38368 }, this));
38369 }
38370
38371 this.updateSelectAll();
38372 }, this), 300, this);
38373 }, this));
38374 }
38375 }
38376 },
38377
38378 /**
38379 * Unbinds the whole plugin.
38380 */
38381 destroy: function() {
38382 this.$container.remove();
38383 this.$select.show();
38384 this.$select.data('multiselect', null);
38385 },
38386
38387 /**
38388 * Refreshs the multiselect based on the selected options of the select.
38389 */
38390 refresh: function() {
38391 $('option', this.$select).each($.proxy(function(index, element) {
38392 var $input = $('li input', this.$ul).filter(function() {
38393 return $(this).val() === $(element).val();
38394 });
38395
38396 if ($(element).is(':selected')) {
38397 $input.prop('checked', true);
38398
38399 if (this.options.selectedClass) {
38400 $input.closest('li')
38401 .addClass(this.options.selectedClass);
38402 }
38403 }
38404 else {
38405 $input.prop('checked', false);
38406
38407 if (this.options.selectedClass) {
38408 $input.closest('li')
38409 .removeClass(this.options.selectedClass);
38410 }
38411 }
38412
38413 if ($(element).is(":disabled")) {
38414 $input.attr('disabled', 'disabled')
38415 .prop('disabled', true)
38416 .closest('li')
38417 .addClass('disabled');
38418 }
38419 else {
38420 $input.prop('disabled', false)
38421 .closest('li')
38422 .removeClass('disabled');
38423 }
38424 }, this));
38425
38426 this.updateButtonText();
38427 this.updateSelectAll();
38428 },
38429
38430 /**
38431 * Select all options of the given values.
38432 *
38433 * If triggerOnChange is set to true, the on change event is triggered if
38434 * and only if one value is passed.
38435 *
38436 * @param {Array} selectValues
38437 * @param {Boolean} triggerOnChange
38438 */
38439 select: function(selectValues, triggerOnChange) {
38440 if(!$.isArray(selectValues)) {
38441 selectValues = [selectValues];
38442 }
38443
38444 for (var i = 0; i < selectValues.length; i++) {
38445 var value = selectValues[i];
38446
38447 if (value === null || value === undefined) {
38448 continue;
38449 }
38450
38451 var $option = this.getOptionByValue(value);
38452 var $checkbox = this.getInputByValue(value);
38453
38454 if($option === undefined || $checkbox === undefined) {
38455 continue;
38456 }
38457
38458 if (!this.options.multiple) {
38459 this.deselectAll(false);
38460 }
38461
38462 if (this.options.selectedClass) {
38463 $checkbox.closest('li')
38464 .addClass(this.options.selectedClass);
38465 }
38466
38467 $checkbox.prop('checked', true);
38468 $option.prop('selected', true);
38469
38470 if (triggerOnChange) {
38471 this.options.onChange($option, true);
38472 }
38473 }
38474
38475 this.updateButtonText();
38476 this.updateSelectAll();
38477 },
38478
38479 /**
38480 * Clears all selected items.
38481 */
38482 clearSelection: function () {
38483 this.deselectAll(false);
38484 this.updateButtonText();
38485 this.updateSelectAll();
38486 },
38487
38488 /**
38489 * Deselects all options of the given values.
38490 *
38491 * If triggerOnChange is set to true, the on change event is triggered, if
38492 * and only if one value is passed.
38493 *
38494 * @param {Array} deselectValues
38495 * @param {Boolean} triggerOnChange
38496 */
38497 deselect: function(deselectValues, triggerOnChange) {
38498 if(!$.isArray(deselectValues)) {
38499 deselectValues = [deselectValues];
38500 }
38501
38502 for (var i = 0; i < deselectValues.length; i++) {
38503 var value = deselectValues[i];
38504
38505 if (value === null || value === undefined) {
38506 continue;
38507 }
38508
38509 var $option = this.getOptionByValue(value);
38510 var $checkbox = this.getInputByValue(value);
38511
38512 if($option === undefined || $checkbox === undefined) {
38513 continue;
38514 }
38515
38516 if (this.options.selectedClass) {
38517 $checkbox.closest('li')
38518 .removeClass(this.options.selectedClass);
38519 }
38520
38521 $checkbox.prop('checked', false);
38522 $option.prop('selected', false);
38523
38524 if (triggerOnChange) {
38525 this.options.onChange($option, false);
38526 }
38527 }
38528
38529 this.updateButtonText();
38530 this.updateSelectAll();
38531 },
38532
38533 /**
38534 * Selects all enabled & visible options.
38535 *
38536 * If justVisible is true or not specified, only visible options are selected.
38537 *
38538 * @param {Boolean} justVisible
38539 * @param {Boolean} triggerOnSelectAll
38540 */
38541 selectAll: function (justVisible, triggerOnSelectAll) {
38542 var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
38543 var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul);
38544 var visibleCheckboxes = allCheckboxes.filter(":visible");
38545 var allCheckboxesCount = allCheckboxes.length;
38546 var visibleCheckboxesCount = visibleCheckboxes.length;
38547
38548 if(justVisible) {
38549 visibleCheckboxes.prop('checked', true);
38550 $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").addClass(this.options.selectedClass);
38551 }
38552 else {
38553 allCheckboxes.prop('checked', true);
38554 $("li:not(.divider):not(.disabled)", this.$ul).addClass(this.options.selectedClass);
38555 }
38556
38557 if (allCheckboxesCount === visibleCheckboxesCount || justVisible === false) {
38558 $("option:enabled", this.$select).prop('selected', true);
38559 }
38560 else {
38561 var values = visibleCheckboxes.map(function() {
38562 return $(this).val();
38563 }).get();
38564
38565 $("option:enabled", this.$select).filter(function(index) {
38566 return $.inArray($(this).val(), values) !== -1;
38567 }).prop('selected', true);
38568 }
38569
38570 if (triggerOnSelectAll) {
38571 this.options.onSelectAll();
38572 }
38573 },
38574
38575 /**
38576 * Deselects all options.
38577 *
38578 * If justVisible is true or not specified, only visible options are deselected.
38579 *
38580 * @param {Boolean} justVisible
38581 */
38582 deselectAll: function (justVisible) {
38583 var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
38584
38585 if(justVisible) {
38586 var visibleCheckboxes = $("li input[type='checkbox']:not(:disabled)", this.$ul).filter(":visible");
38587 visibleCheckboxes.prop('checked', false);
38588
38589 var values = visibleCheckboxes.map(function() {
38590 return $(this).val();
38591 }).get();
38592
38593 $("option:enabled", this.$select).filter(function(index) {
38594 return $.inArray($(this).val(), values) !== -1;
38595 }).prop('selected', false);
38596
38597 if (this.options.selectedClass) {
38598 $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").removeClass(this.options.selectedClass);
38599 }
38600 }
38601 else {
38602 $("li input[type='checkbox']:enabled", this.$ul).prop('checked', false);
38603 $("option:enabled", this.$select).prop('selected', false);
38604
38605 if (this.options.selectedClass) {
38606 $("li:not(.divider):not(.disabled)", this.$ul).removeClass(this.options.selectedClass);
38607 }
38608 }
38609 },
38610
38611 /**
38612 * Rebuild the plugin.
38613 *
38614 * Rebuilds the dropdown, the filter and the select all option.
38615 */
38616 rebuild: function() {
38617 this.$ul.html('');
38618
38619 // Important to distinguish between radios and checkboxes.
38620 this.options.multiple = this.$select.attr('multiple') === "multiple";
38621
38622 this.buildSelectAll();
38623 this.buildDropdownOptions();
38624 this.buildFilter();
38625
38626 this.updateButtonText();
38627 this.updateSelectAll();
38628
38629 if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) {
38630 this.disable();
38631 }
38632 else {
38633 this.enable();
38634 }
38635
38636 if (this.options.dropRight) {
38637 this.$ul.addClass('pull-right');
38638 }
38639 },
38640
38641 /**
38642 * The provided data will be used to build the dropdown.
38643 */
38644 dataprovider: function(dataprovider) {
38645
38646 var groupCounter = 0;
38647 var $select = this.$select.empty();
38648
38649 $.each(dataprovider, function (index, option) {
38650 var $tag;
38651
38652 if ($.isArray(option.children)) { // create optiongroup tag
38653 groupCounter++;
38654
38655 $tag = $('<optgroup/>').attr({
38656 label: option.label || 'Group ' + groupCounter,
38657 disabled: !!option.disabled
38658 });
38659
38660 forEach(option.children, function(subOption) { // add children option tags
38661 $tag.append($('<option/>').attr({
38662 value: subOption.value,
38663 label: subOption.label || subOption.value,
38664 title: subOption.title,
38665 selected: !!subOption.selected,
38666 disabled: !!subOption.disabled
38667 }));
38668 });
38669 }
38670 else {
38671 $tag = $('<option/>').attr({
38672 value: option.value,
38673 label: option.label || option.value,
38674 title: option.title,
38675 selected: !!option.selected,
38676 disabled: !!option.disabled
38677 });
38678 }
38679
38680 $select.append($tag);
38681 });
38682
38683 this.rebuild();
38684 },
38685
38686 /**
38687 * Enable the multiselect.
38688 */
38689 enable: function() {
38690 this.$select.prop('disabled', false);
38691 this.$button.prop('disabled', false)
38692 .removeClass('disabled');
38693 },
38694
38695 /**
38696 * Disable the multiselect.
38697 */
38698 disable: function() {
38699 this.$select.prop('disabled', true);
38700 this.$button.prop('disabled', true)
38701 .addClass('disabled');
38702 },
38703
38704 /**
38705 * Set the options.
38706 *
38707 * @param {Array} options
38708 */
38709 setOptions: function(options) {
38710 this.options = this.mergeOptions(options);
38711 },
38712
38713 /**
38714 * Merges the given options with the default options.
38715 *
38716 * @param {Array} options
38717 * @returns {Array}
38718 */
38719 mergeOptions: function(options) {
38720 return $.extend(true, {}, this.defaults, this.options, options);
38721 },
38722
38723 /**
38724 * Checks whether a select all checkbox is present.
38725 *
38726 * @returns {Boolean}
38727 */
38728 hasSelectAll: function() {
38729 return $('li.multiselect-all', this.$ul).length > 0;
38730 },
38731
38732 /**
38733 * Updates the select all checkbox based on the currently displayed and selected checkboxes.
38734 */
38735 updateSelectAll: function() {
38736 if (this.hasSelectAll()) {
38737 var allBoxes = $("li:not(.multiselect-item):not(.filter-hidden) input:enabled", this.$ul);
38738 var allBoxesLength = allBoxes.length;
38739 var checkedBoxesLength = allBoxes.filter(":checked").length;
38740 var selectAllLi = $("li.multiselect-all", this.$ul);
38741 var selectAllInput = selectAllLi.find("input");
38742
38743 if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) {
38744 selectAllInput.prop("checked", true);
38745 selectAllLi.addClass(this.options.selectedClass);
38746 this.options.onSelectAll();
38747 }
38748 else {
38749 selectAllInput.prop("checked", false);
38750 selectAllLi.removeClass(this.options.selectedClass);
38751 }
38752 }
38753 },
38754
38755 /**
38756 * Update the button text and its title based on the currently selected options.
38757 */
38758 updateButtonText: function() {
38759 var options = this.getSelected();
38760
38761 // First update the displayed button text.
38762 if (this.options.enableHTML) {
38763 $('.multiselect .multiselect-selected-text', this.$container).html(this.options.buttonText(options, this.$select));
38764 }
38765 else {
38766 $('.multiselect .multiselect-selected-text', this.$container).text(this.options.buttonText(options, this.$select));
38767 }
38768
38769 // Now update the title attribute of the button.
38770 $('.multiselect', this.$container).attr('title', this.options.buttonTitle(options, this.$select));
38771 },
38772
38773 /**
38774 * Get all selected options.
38775 *
38776 * @returns {jQUery}
38777 */
38778 getSelected: function() {
38779 return $('option', this.$select).filter(":selected");
38780 },
38781
38782 /**
38783 * Gets a select option by its value.
38784 *
38785 * @param {String} value
38786 * @returns {jQuery}
38787 */
38788 getOptionByValue: function (value) {
38789
38790 var options = $('option', this.$select);
38791 var valueToCompare = value.toString();
38792
38793 for (var i = 0; i < options.length; i = i + 1) {
38794 var option = options[i];
38795 if (option.value === valueToCompare) {
38796 return $(option);
38797 }
38798 }
38799 },
38800
38801 /**
38802 * Get the input (radio/checkbox) by its value.
38803 *
38804 * @param {String} value
38805 * @returns {jQuery}
38806 */
38807 getInputByValue: function (value) {
38808
38809 var checkboxes = $('li input', this.$ul);
38810 var valueToCompare = value.toString();
38811
38812 for (var i = 0; i < checkboxes.length; i = i + 1) {
38813 var checkbox = checkboxes[i];
38814 if (checkbox.value === valueToCompare) {
38815 return $(checkbox);
38816 }
38817 }
38818 },
38819
38820 /**
38821 * Used for knockout integration.
38822 */
38823 updateOriginalOptions: function() {
38824 this.originalOptions = this.$select.clone()[0].options;
38825 },
38826
38827 asyncFunction: function(callback, timeout, self) {
38828 var args = Array.prototype.slice.call(arguments, 3);
38829 return setTimeout(function() {
38830 callback.apply(self || window, args);
38831 }, timeout);
38832 },
38833
38834 setAllSelectedText: function(allSelectedText) {
38835 this.options.allSelectedText = allSelectedText;
38836 this.updateButtonText();
38837 }
38838 };
38839
38840 $.fn.multiselect = function(option, parameter, extraOptions) {
38841 return this.each(function() {
38842 var data = $(this).data('multiselect');
38843 var options = typeof option === 'object' && option;
38844
38845 // Initialize the multiselect.
38846 if (!data) {
38847 data = new Multiselect(this, options);
38848 $(this).data('multiselect', data);
38849 }
38850
38851 // Call multiselect method.
38852 if (typeof option === 'string') {
38853 data[option](parameter, extraOptions);
38854
38855 if (option === 'destroy') {
38856 $(this).data('multiselect', false);
38857 }
38858 }
38859 });
38860 };
38861
38862 $.fn.multiselect.Constructor = Multiselect;
38863
38864 $(function() {
38865 $("select[data-role=multiselect]").multiselect();
38866 });
38867
38868}(window.jQuery);
38869
38870/*
38871 * International Telephone Input v12.0.2
38872 * https://github.com/jackocnr/intl-tel-input.git
38873 * Licensed under the MIT license
38874 */
38875// wrap in UMD - see https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
38876(function(factory) {
38877 if (typeof define === "function" && define.amd) {
38878 define([ "jquery" ], function($) {
38879 factory($, window, document);
38880 });
38881 } else if (typeof module === "object" && module.exports) {
38882 module.exports = factory(require("jquery"), window, document);
38883 } else {
38884 factory(jQuery, window, document);
38885 }
38886})(function($, window, document, undefined) {
38887 "use strict";
38888 // these vars persist through all instances of the plugin
38889 var pluginName = "intlTelInput", id = 1, // give each instance it's own id for namespaced event handling
38890 defaults = {
38891 // whether or not to allow the dropdown
38892 allowDropdown: true,
38893 // if there is just a dial code in the input: remove it on blur, and re-add it on focus
38894 autoHideDialCode: true,
38895 // add a placeholder in the input with an example number for the selected country
38896 autoPlaceholder: "polite",
38897 // modify the auto placeholder
38898 customPlaceholder: null,
38899 // append menu to a specific element
38900 dropdownContainer: "",
38901 // don't display these countries
38902 excludeCountries: [],
38903 // format the input value during initialisation and on setNumber
38904 formatOnDisplay: true,
38905 // geoIp lookup function
38906 geoIpLookup: null,
38907 // inject a hidden input with this name, and on submit, populate it with the result of getNumber
38908 hiddenInput: "",
38909 // initial country
38910 initialCountry: "",
38911 // don't insert international dial codes
38912 nationalMode: true,
38913 // display only these countries
38914 onlyCountries: [],
38915 // number type to use for placeholders
38916 placeholderNumberType: "MOBILE",
38917 // the countries at the top of the list. defaults to united states and united kingdom
38918 preferredCountries: [ "us", "gb" ],
38919 // display the country dial code next to the selected flag so it's not part of the typed number
38920 separateDialCode: false,
38921 // specify the path to the libphonenumber script to enable validation/formatting
38922 utilsScript: ""
38923 }, keys = {
38924 UP: 38,
38925 DOWN: 40,
38926 ENTER: 13,
38927 ESC: 27,
38928 PLUS: 43,
38929 A: 65,
38930 Z: 90,
38931 SPACE: 32,
38932 TAB: 9
38933 }, // https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes#Non-geographic_area_codes
38934 regionlessNanpNumbers = [ "800", "822", "833", "844", "855", "866", "877", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889" ];
38935 // keep track of if the window.load event has fired as impossible to check after the fact
38936 $(window).on("load", function() {
38937 // UPDATE: use a public static field so we can fudge it in the tests
38938 $.fn[pluginName].windowLoaded = true;
38939 });
38940 function Plugin(element, options) {
38941 this.telInput = $(element);
38942 this.options = $.extend({}, defaults, options);
38943 // event namespace
38944 this.ns = "." + pluginName + id++;
38945 // Chrome, FF, Safari, IE9+
38946 this.isGoodBrowser = Boolean(element.setSelectionRange);
38947 this.hadInitialPlaceholder = Boolean($(element).attr("placeholder"));
38948 }
38949 Plugin.prototype = {
38950 _init: function() {
38951 // if in nationalMode, disable options relating to dial codes
38952 if (this.options.nationalMode) {
38953 this.options.autoHideDialCode = false;
38954 }
38955 // if separateDialCode then doesn't make sense to A) insert dial code into input (autoHideDialCode), and B) display national numbers (because we're displaying the country dial code next to them)
38956 if (this.options.separateDialCode) {
38957 this.options.autoHideDialCode = this.options.nationalMode = false;
38958 }
38959 // we cannot just test screen size as some smartphones/website meta tags will report desktop resolutions
38960 // Note: for some reason jasmine breaks if you put this in the main Plugin function with the rest of these declarations
38961 // Note: to target Android Mobiles (and not Tablets), we must find "Android" and "Mobile"
38962 this.isMobile = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
38963 if (this.isMobile) {
38964 // trigger the mobile dropdown css
38965 $("body").addClass("iti-mobile");
38966 // on mobile, we want a full screen dropdown, so we must append it to the body
38967 if (!this.options.dropdownContainer) {
38968 this.options.dropdownContainer = "body";
38969 }
38970 }
38971 // we return these deferred objects from the _init() call so they can be watched, and then we resolve them when each specific request returns
38972 // Note: again, jasmine breaks when I put these in the Plugin function
38973 this.autoCountryDeferred = new $.Deferred();
38974 this.utilsScriptDeferred = new $.Deferred();
38975 // in various situations there could be no country selected initially, but we need to be able to assume this variable exists
38976 this.selectedCountryData = {};
38977 // process all the data: onlyCountries, excludeCountries, preferredCountries etc
38978 this._processCountryData();
38979 // generate the markup
38980 this._generateMarkup();
38981 // set the initial state of the input value and the selected flag
38982 this._setInitialState();
38983 // start all of the event listeners: autoHideDialCode, input keydown, selectedFlag click
38984 this._initListeners();
38985 // utils script, and auto country
38986 this._initRequests();
38987 // return the deferreds
38988 return [ this.autoCountryDeferred, this.utilsScriptDeferred ];
38989 },
38990 /********************
38991 * PRIVATE METHODS
38992 ********************/
38993 // prepare all of the country data, including onlyCountries, excludeCountries and preferredCountries options
38994 _processCountryData: function() {
38995 // process onlyCountries or excludeCountries array if present
38996 this._processAllCountries();
38997 // process the countryCodes map
38998 this._processCountryCodes();
38999 // process the preferredCountries
39000 this._processPreferredCountries();
39001 },
39002 // add a country code to this.countryCodes
39003 _addCountryCode: function(iso2, dialCode, priority) {
39004 if (!(dialCode in this.countryCodes)) {
39005 this.countryCodes[dialCode] = [];
39006 }
39007 var index = priority || 0;
39008 this.countryCodes[dialCode][index] = iso2;
39009 },
39010 // process onlyCountries or excludeCountries array if present
39011 _processAllCountries: function() {
39012 if (this.options.onlyCountries.length) {
39013 var lowerCaseOnlyCountries = this.options.onlyCountries.map(function(country) {
39014 return country.toLowerCase();
39015 });
39016 this.countries = allCountries.filter(function(country) {
39017 return lowerCaseOnlyCountries.indexOf(country.iso2) > -1;
39018 });
39019 } else if (this.options.excludeCountries.length) {
39020 var lowerCaseExcludeCountries = this.options.excludeCountries.map(function(country) {
39021 return country.toLowerCase();
39022 });
39023 this.countries = allCountries.filter(function(country) {
39024 return lowerCaseExcludeCountries.indexOf(country.iso2) === -1;
39025 });
39026 } else {
39027 this.countries = allCountries;
39028 }
39029 },
39030 // process the countryCodes map
39031 _processCountryCodes: function() {
39032 this.countryCodes = {};
39033 for (var i = 0; i < this.countries.length; i++) {
39034 var c = this.countries[i];
39035 this._addCountryCode(c.iso2, c.dialCode, c.priority);
39036 // area codes
39037 if (c.areaCodes) {
39038 for (var j = 0; j < c.areaCodes.length; j++) {
39039 // full dial code is country code + dial code
39040 this._addCountryCode(c.iso2, c.dialCode + c.areaCodes[j]);
39041 }
39042 }
39043 }
39044 },
39045 // process preferred countries - iterate through the preferences, fetching the country data for each one
39046 _processPreferredCountries: function() {
39047 this.preferredCountries = [];
39048 for (var i = 0; i < this.options.preferredCountries.length; i++) {
39049 var countryCode = this.options.preferredCountries[i].toLowerCase(), countryData = this._getCountryData(countryCode, false, true);
39050 if (countryData) {
39051 this.preferredCountries.push(countryData);
39052 }
39053 }
39054 },
39055 // generate all of the markup for the plugin: the selected flag overlay, and the dropdown
39056 _generateMarkup: function() {
39057 // prevent autocomplete as there's no safe, cross-browser event we can react to, so it can easily put the plugin in an inconsistent state e.g. the wrong flag selected for the autocompleted number, which on submit could mean the wrong number is saved (esp in nationalMode)
39058 this.telInput.attr("autocomplete", "off");
39059 // containers (mostly for positioning)
39060 var parentClass = "intl-tel-input";
39061 if (this.options.allowDropdown) {
39062 parentClass += " allow-dropdown";
39063 }
39064 if (this.options.separateDialCode) {
39065 parentClass += " separate-dial-code";
39066 }
39067 this.telInput.wrap($("<div>", {
39068 "class": parentClass
39069 }));
39070 this.flagsContainer = $("<div>", {
39071 "class": "flag-container"
39072 }).insertBefore(this.telInput);
39073 // currently selected flag (displayed to left of input)
39074 var selectedFlag = $("<div>", {
39075 "class": "selected-flag"
39076 });
39077 selectedFlag.appendTo(this.flagsContainer);
39078 this.selectedFlagInner = $("<div>", {
39079 "class": "iti-flag"
39080 }).appendTo(selectedFlag);
39081 if (this.options.separateDialCode) {
39082 this.selectedDialCode = $("<div>", {
39083 "class": "selected-dial-code"
39084 }).appendTo(selectedFlag);
39085 }
39086 if (this.options.allowDropdown) {
39087 // make element focusable and tab naviagable
39088 selectedFlag.attr("tabindex", "0");
39089 // CSS triangle
39090 $("<div>", {
39091 "class": "iti-arrow"
39092 }).appendTo(selectedFlag);
39093 // country dropdown: preferred countries, then divider, then all countries
39094 this.countryList = $("<ul>", {
39095 "class": "country-list hide"
39096 });
39097 if (this.preferredCountries.length) {
39098 this._appendListItems(this.preferredCountries, "preferred");
39099 $("<li>", {
39100 "class": "divider"
39101 }).appendTo(this.countryList);
39102 }
39103 this._appendListItems(this.countries, "");
39104 // this is useful in lots of places
39105 this.countryListItems = this.countryList.children(".country");
39106 // create dropdownContainer markup
39107 if (this.options.dropdownContainer) {
39108 this.dropdown = $("<div>", {
39109 "class": "intl-tel-input iti-container"
39110 }).append(this.countryList);
39111 } else {
39112 this.countryList.appendTo(this.flagsContainer);
39113 }
39114 } else {
39115 // a little hack so we don't break anything
39116 this.countryListItems = $();
39117 }
39118 if (this.options.hiddenInput) {
39119 this.hiddenInput = $("<input>", {
39120 type: "hidden",
39121 name: this.options.hiddenInput
39122 }).insertBefore(this.telInput);
39123 }
39124 },
39125 // add a country <li> to the countryList <ul> container
39126 _appendListItems: function(countries, className) {
39127 // we create so many DOM elements, it is faster to build a temp string
39128 // and then add everything to the DOM in one go at the end
39129 var tmp = "";
39130 // for each country
39131 for (var i = 0; i < countries.length; i++) {
39132 var c = countries[i];
39133 // open the list item
39134 tmp += "<li class='country " + className + "' data-dial-code='" + c.dialCode + "' data-country-code='" + c.iso2 + "'>";
39135 // add the flag
39136 tmp += "<div class='flag-box'><div class='iti-flag " + c.iso2 + "'></div></div>";
39137 // and the country name and dial code
39138 tmp += "<span class='country-name'>" + c.name + "</span>";
39139 tmp += "<span class='dial-code'>+" + c.dialCode + "</span>";
39140 // close the list item
39141 tmp += "</li>";
39142 }
39143 this.countryList.append(tmp);
39144 },
39145 // set the initial state of the input value and the selected flag by:
39146 // 1. extracting a dial code from the given number
39147 // 2. using explicit initialCountry
39148 // 3. picking the first preferred country
39149 // 4. picking the first country
39150 _setInitialState: function() {
39151 var val = this.telInput.val();
39152 // if we already have a dial code, and it's not a regionlessNanp, we can go ahead and set the flag, else fall back to the default country
39153 // UPDATE: actually we do want to set the flag for a regionlessNanp in one situation: if we're in nationalMode and there's no initialCountry - otherwise we lose the +1 and we're left with an invalid number
39154 if (this._getDialCode(val) && (!this._isRegionlessNanp(val) || this.options.nationalMode && !this.options.initialCountry)) {
39155 this._updateFlagFromNumber(val);
39156 } else if (this.options.initialCountry !== "auto") {
39157 // see if we should select a flag
39158 if (this.options.initialCountry) {
39159 this._setFlag(this.options.initialCountry.toLowerCase());
39160 } else {
39161 // no dial code and no initialCountry, so default to first in list
39162 this.defaultCountry = this.preferredCountries.length ? this.preferredCountries[0].iso2 : this.countries[0].iso2;
39163 if (!val) {
39164 this._setFlag(this.defaultCountry);
39165 }
39166 }
39167 // if empty and no nationalMode and no autoHideDialCode then insert the default dial code
39168 if (!val && !this.options.nationalMode && !this.options.autoHideDialCode && !this.options.separateDialCode) {
39169 this.telInput.val("+" + this.selectedCountryData.dialCode);
39170 }
39171 }
39172 // NOTE: if initialCountry is set to auto, that will be handled separately
39173 // format
39174 if (val) {
39175 // this wont be run after _updateDialCode as that's only called if no val
39176 this._updateValFromNumber(val);
39177 }
39178 },
39179 // initialise the main event listeners: input keyup, and click selected flag
39180 _initListeners: function() {
39181 this._initKeyListeners();
39182 if (this.options.autoHideDialCode) {
39183 this._initFocusListeners();
39184 }
39185 if (this.options.allowDropdown) {
39186 this._initDropdownListeners();
39187 }
39188 if (this.hiddenInput) {
39189 this._initHiddenInputListener();
39190 }
39191 },
39192 // update hidden input on form submit
39193 _initHiddenInputListener: function() {
39194 var that = this;
39195 var form = this.telInput.closest("form");
39196 if (form.length) {
39197 form.submit(function() {
39198 that.hiddenInput.val(that.getNumber());
39199 });
39200 }
39201 },
39202 // initialise the dropdown listeners
39203 _initDropdownListeners: function() {
39204 var that = this;
39205 // hack for input nested inside label: clicking the selected-flag to open the dropdown would then automatically trigger a 2nd click on the input which would close it again
39206 var label = this.telInput.closest("label");
39207 if (label.length) {
39208 label.on("click" + this.ns, function(e) {
39209 // if the dropdown is closed, then focus the input, else ignore the click
39210 if (that.countryList.hasClass("hide")) {
39211 that.telInput.focus();
39212 } else {
39213 e.preventDefault();
39214 }
39215 });
39216 }
39217 // toggle country dropdown on click
39218 var selectedFlag = this.selectedFlagInner.parent();
39219 selectedFlag.on("click" + this.ns, function(e) {
39220 // only intercept this event if we're opening the dropdown
39221 // else let it bubble up to the top ("click-off-to-close" listener)
39222 // we cannot just stopPropagation as it may be needed to close another instance
39223 if (that.countryList.hasClass("hide") && !that.telInput.prop("disabled") && !that.telInput.prop("readonly")) {
39224 that._showDropdown();
39225 }
39226 });
39227 // open dropdown list if currently focused
39228 this.flagsContainer.on("keydown" + that.ns, function(e) {
39229 var isDropdownHidden = that.countryList.hasClass("hide");
39230 if (isDropdownHidden && (e.which == keys.UP || e.which == keys.DOWN || e.which == keys.SPACE || e.which == keys.ENTER)) {
39231 // prevent form from being submitted if "ENTER" was pressed
39232 e.preventDefault();
39233 // prevent event from being handled again by document
39234 e.stopPropagation();
39235 that._showDropdown();
39236 }
39237 // allow navigation from dropdown to input on TAB
39238 if (e.which == keys.TAB) {
39239 that._closeDropdown();
39240 }
39241 });
39242 },
39243 // init many requests: utils script / geo ip lookup
39244 _initRequests: function() {
39245 var that = this;
39246 // if the user has specified the path to the utils script, fetch it on window.load, else resolve
39247 if (this.options.utilsScript) {
39248 // if the plugin is being initialised after the window.load event has already been fired
39249 if ($.fn[pluginName].windowLoaded) {
39250 $.fn[pluginName].loadUtils(this.options.utilsScript, this.utilsScriptDeferred);
39251 } else {
39252 // wait until the load event so we don't block any other requests e.g. the flags image
39253 $(window).on("load", function() {
39254 $.fn[pluginName].loadUtils(that.options.utilsScript, that.utilsScriptDeferred);
39255 });
39256 }
39257 } else {
39258 this.utilsScriptDeferred.resolve();
39259 }
39260 if (this.options.initialCountry === "auto") {
39261 this._loadAutoCountry();
39262 } else {
39263 this.autoCountryDeferred.resolve();
39264 }
39265 },
39266 // perform the geo ip lookup
39267 _loadAutoCountry: function() {
39268 var that = this;
39269 // 3 options:
39270 // 1) already loaded (we're done)
39271 // 2) not already started loading (start)
39272 // 3) already started loading (do nothing - just wait for loading callback to fire)
39273 if ($.fn[pluginName].autoCountry) {
39274 this.handleAutoCountry();
39275 } else if (!$.fn[pluginName].startedLoadingAutoCountry) {
39276 // don't do this twice!
39277 $.fn[pluginName].startedLoadingAutoCountry = true;
39278 if (typeof this.options.geoIpLookup === "function") {
39279 this.options.geoIpLookup(function(countryCode) {
39280 $.fn[pluginName].autoCountry = countryCode.toLowerCase();
39281 // tell all instances the auto country is ready
39282 // TODO: this should just be the current instances
39283 // UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight away (e.g. if they have already done the geo ip lookup somewhere else). Using setTimeout means that the current thread of execution will finish before executing this, which allows the plugin to finish initialising.
39284 setTimeout(function() {
39285 $(".intl-tel-input input").intlTelInput("handleAutoCountry");
39286 });
39287 });
39288 }
39289 }
39290 },
39291 // initialize any key listeners
39292 _initKeyListeners: function() {
39293 var that = this;
39294 // update flag on keyup
39295 // (keep this listener separate otherwise the setTimeout breaks all the tests)
39296 this.telInput.on("keyup" + this.ns, function() {
39297 if (that._updateFlagFromNumber(that.telInput.val())) {
39298 that._triggerCountryChange();
39299 }
39300 });
39301 // update flag on cut/paste events (now supported in all major browsers)
39302 this.telInput.on("cut" + this.ns + " paste" + this.ns, function() {
39303 // hack because "paste" event is fired before input is updated
39304 setTimeout(function() {
39305 if (that._updateFlagFromNumber(that.telInput.val())) {
39306 that._triggerCountryChange();
39307 }
39308 });
39309 });
39310 },
39311 // adhere to the input's maxlength attr
39312 _cap: function(number) {
39313 var max = this.telInput.attr("maxlength");
39314 return max && number.length > max ? number.substr(0, max) : number;
39315 },
39316 // listen for mousedown, focus and blur
39317 _initFocusListeners: function() {
39318 var that = this;
39319 // mousedown decides where the cursor goes, so if we're focusing we must preventDefault as we'll be inserting the dial code, and we want the cursor to be at the end no matter where they click
39320 this.telInput.on("mousedown" + this.ns, function(e) {
39321 if (!that.telInput.is(":focus") && !that.telInput.val()) {
39322 e.preventDefault();
39323 // but this also cancels the focus, so we must trigger that manually
39324 that.telInput.focus();
39325 }
39326 });
39327 // on focus: if empty, insert the dial code for the currently selected flag
39328 this.telInput.on("focus" + this.ns, function(e) {
39329 if (!that.telInput.val() && !that.telInput.prop("readonly") && that.selectedCountryData.dialCode) {
39330 // insert the dial code
39331 that.telInput.val("+" + that.selectedCountryData.dialCode);
39332 // after auto-inserting a dial code, if the first key they hit is '+' then assume they are entering a new number, so remove the dial code. use keypress instead of keydown because keydown gets triggered for the shift key (required to hit the + key), and instead of keyup because that shows the new '+' before removing the old one
39333 that.telInput.one("keypress.plus" + that.ns, function(e) {
39334 if (e.which == keys.PLUS) {
39335 that.telInput.val("");
39336 }
39337 });
39338 // after tabbing in, make sure the cursor is at the end we must use setTimeout to get outside of the focus handler as it seems the selection happens after that
39339 setTimeout(function() {
39340 var input = that.telInput[0];
39341 if (that.isGoodBrowser) {
39342 var len = that.telInput.val().length;
39343 input.setSelectionRange(len, len);
39344 }
39345 });
39346 }
39347 });
39348 // on blur or form submit: if just a dial code then remove it
39349 var form = this.telInput.prop("form");
39350 if (form) {
39351 $(form).on("submit" + this.ns, function() {
39352 that._removeEmptyDialCode();
39353 });
39354 }
39355 this.telInput.on("blur" + this.ns, function() {
39356 that._removeEmptyDialCode();
39357 });
39358 },
39359 _removeEmptyDialCode: function() {
39360 var value = this.telInput.val(), startsPlus = value.charAt(0) == "+";
39361 if (startsPlus) {
39362 var numeric = this._getNumeric(value);
39363 // if just a plus, or if just a dial code
39364 if (!numeric || this.selectedCountryData.dialCode == numeric) {
39365 this.telInput.val("");
39366 }
39367 }
39368 // remove the keypress listener we added on focus
39369 this.telInput.off("keypress.plus" + this.ns);
39370 },
39371 // extract the numeric digits from the given string
39372 _getNumeric: function(s) {
39373 return s.replace(/\D/g, "");
39374 },
39375 // show the dropdown
39376 _showDropdown: function() {
39377 this._setDropdownPosition();
39378 // update highlighting and scroll to active list item
39379 var activeListItem = this.countryList.children(".active");
39380 if (activeListItem.length) {
39381 this._highlightListItem(activeListItem);
39382 this._scrollTo(activeListItem);
39383 }
39384 // bind all the dropdown-related listeners: mouseover, click, click-off, keydown
39385 this._bindDropdownListeners();
39386 // update the arrow
39387 this.selectedFlagInner.children(".iti-arrow").addClass("up");
39388 this.telInput.trigger("open:countrydropdown");
39389 },
39390 // decide where to position dropdown (depends on position within viewport, and scroll)
39391 _setDropdownPosition: function() {
39392 var that = this;
39393 if (this.options.dropdownContainer) {
39394 this.dropdown.appendTo(this.options.dropdownContainer);
39395 }
39396 // show the menu and grab the dropdown height
39397 this.dropdownHeight = this.countryList.removeClass("hide").outerHeight();
39398 if (!this.isMobile) {
39399 var pos = this.telInput.offset(), inputTop = pos.top, windowTop = $(window).scrollTop(), // dropdownFitsBelow = (dropdownBottom < windowBottom)
39400 dropdownFitsBelow = inputTop + this.telInput.outerHeight() + this.dropdownHeight < windowTop + $(window).height(), dropdownFitsAbove = inputTop - this.dropdownHeight > windowTop;
39401 // by default, the dropdown will be below the input. If we want to position it above the input, we add the dropup class.
39402 this.countryList.toggleClass("dropup", !dropdownFitsBelow && dropdownFitsAbove);
39403 // if dropdownContainer is enabled, calculate postion
39404 if (this.options.dropdownContainer) {
39405 // by default the dropdown will be directly over the input because it's not in the flow. If we want to position it below, we need to add some extra top value.
39406 var extraTop = !dropdownFitsBelow && dropdownFitsAbove ? 0 : this.telInput.innerHeight();
39407 // calculate placement
39408 this.dropdown.css({
39409 top: inputTop + extraTop,
39410 left: pos.left
39411 });
39412 // close menu on window scroll
39413 $(window).on("scroll" + this.ns, function() {
39414 that._closeDropdown();
39415 });
39416 }
39417 }
39418 },
39419 // we only bind dropdown listeners when the dropdown is open
39420 _bindDropdownListeners: function() {
39421 var that = this;
39422 // when mouse over a list item, just highlight that one
39423 // we add the class "highlight", so if they hit "enter" we know which one to select
39424 this.countryList.on("mouseover" + this.ns, ".country", function(e) {
39425 that._highlightListItem($(this));
39426 });
39427 // listen for country selection
39428 this.countryList.on("click" + this.ns, ".country", function(e) {
39429 that._selectListItem($(this));
39430 });
39431 // click off to close
39432 // (except when this initial opening click is bubbling up)
39433 // we cannot just stopPropagation as it may be needed to close another instance
39434 var isOpening = true;
39435 $("html").on("click" + this.ns, function(e) {
39436 if (!isOpening) {
39437 that._closeDropdown();
39438 }
39439 isOpening = false;
39440 });
39441 // listen for up/down scrolling, enter to select, or letters to jump to country name.
39442 // use keydown as keypress doesn't fire for non-char keys and we want to catch if they
39443 // just hit down and hold it to scroll down (no keyup event).
39444 // listen on the document because that's where key events are triggered if no input has focus
39445 var query = "", queryTimer = null;
39446 $(document).on("keydown" + this.ns, function(e) {
39447 // prevent down key from scrolling the whole page,
39448 // and enter key from submitting a form etc
39449 e.preventDefault();
39450 if (e.which == keys.UP || e.which == keys.DOWN) {
39451 // up and down to navigate
39452 that._handleUpDownKey(e.which);
39453 } else if (e.which == keys.ENTER) {
39454 // enter to select
39455 that._handleEnterKey();
39456 } else if (e.which == keys.ESC) {
39457 // esc to close
39458 that._closeDropdown();
39459 } else if (e.which >= keys.A && e.which <= keys.Z || e.which == keys.SPACE) {
39460 // upper case letters (note: keyup/keydown only return upper case letters)
39461 // jump to countries that start with the query string
39462 if (queryTimer) {
39463 clearTimeout(queryTimer);
39464 }
39465 query += String.fromCharCode(e.which);
39466 that._searchForCountry(query);
39467 // if the timer hits 1 second, reset the query
39468 queryTimer = setTimeout(function() {
39469 query = "";
39470 }, 1e3);
39471 }
39472 });
39473 },
39474 // highlight the next/prev item in the list (and ensure it is visible)
39475 _handleUpDownKey: function(key) {
39476 var current = this.countryList.children(".highlight").first();
39477 var next = key == keys.UP ? current.prev() : current.next();
39478 if (next.length) {
39479 // skip the divider
39480 if (next.hasClass("divider")) {
39481 next = key == keys.UP ? next.prev() : next.next();
39482 }
39483 this._highlightListItem(next);
39484 this._scrollTo(next);
39485 }
39486 },
39487 // select the currently highlighted item
39488 _handleEnterKey: function() {
39489 var currentCountry = this.countryList.children(".highlight").first();
39490 if (currentCountry.length) {
39491 this._selectListItem(currentCountry);
39492 }
39493 },
39494 // find the first list item whose name starts with the query string
39495 _searchForCountry: function(query) {
39496 for (var i = 0; i < this.countries.length; i++) {
39497 if (this._startsWith(this.countries[i].name, query)) {
39498 var listItem = this.countryList.children("[data-country-code=" + this.countries[i].iso2 + "]").not(".preferred");
39499 // update highlighting and scroll
39500 this._highlightListItem(listItem);
39501 this._scrollTo(listItem, true);
39502 break;
39503 }
39504 }
39505 },
39506 // check if (uppercase) string a starts with string b
39507 _startsWith: function(a, b) {
39508 return a.substr(0, b.length).toUpperCase() == b;
39509 },
39510 // update the input's value to the given val (format first if possible)
39511 // NOTE: this is called from _setInitialState, handleUtils and setNumber
39512 _updateValFromNumber: function(number) {
39513 if (this.options.formatOnDisplay && window.intlTelInputUtils && this.selectedCountryData) {
39514 var format = !this.options.separateDialCode && (this.options.nationalMode || number.charAt(0) != "+") ? intlTelInputUtils.numberFormat.NATIONAL : intlTelInputUtils.numberFormat.INTERNATIONAL;
39515 number = intlTelInputUtils.formatNumber(number, this.selectedCountryData.iso2, format);
39516 }
39517 number = this._beforeSetNumber(number);
39518 this.telInput.val(number);
39519 },
39520 // check if need to select a new flag based on the given number
39521 // Note: called from _setInitialState, keyup handler, setNumber
39522 _updateFlagFromNumber: function(number) {
39523 // if we're in nationalMode and we already have US/Canada selected, make sure the number starts with a +1 so _getDialCode will be able to extract the area code
39524 // update: if we dont yet have selectedCountryData, but we're here (trying to update the flag from the number), that means we're initialising the plugin with a number that already has a dial code, so fine to ignore this bit
39525 if (number && this.options.nationalMode && this.selectedCountryData.dialCode == "1" && number.charAt(0) != "+") {
39526 if (number.charAt(0) != "1") {
39527 number = "1" + number;
39528 }
39529 number = "+" + number;
39530 }
39531 // try and extract valid dial code from input
39532 var dialCode = this._getDialCode(number), countryCode = null, numeric = this._getNumeric(number);
39533 if (dialCode) {
39534 // check if one of the matching countries is already selected
39535 var countryCodes = this.countryCodes[this._getNumeric(dialCode)], alreadySelected = $.inArray(this.selectedCountryData.iso2, countryCodes) > -1, // check if the given number contains a NANP area code i.e. the only dialCode that could be extracted was +1 (instead of say +1204) and the actual number's length is >=4
39536 isNanpAreaCode = dialCode == "+1" && numeric.length >= 4, nanpSelected = this.selectedCountryData.dialCode == "1";
39537 // only update the flag if:
39538 // A) NOT (we currently have a NANP flag selected, and the number is a regionlessNanp)
39539 // AND
39540 // B) either a matching country is not already selected OR the number contains a NANP area code (ensure the flag is set to the first matching country)
39541 if (!(nanpSelected && this._isRegionlessNanp(numeric)) && (!alreadySelected || isNanpAreaCode)) {
39542 // if using onlyCountries option, countryCodes[0] may be empty, so we must find the first non-empty index
39543 for (var j = 0; j < countryCodes.length; j++) {
39544 if (countryCodes[j]) {
39545 countryCode = countryCodes[j];
39546 break;
39547 }
39548 }
39549 }
39550 } else if (number.charAt(0) == "+" && numeric.length) {
39551 // invalid dial code, so empty
39552 // Note: use getNumeric here because the number has not been formatted yet, so could contain bad chars
39553 countryCode = "";
39554 } else if (!number || number == "+") {
39555 // empty, or just a plus, so default
39556 countryCode = this.defaultCountry;
39557 }
39558 if (countryCode !== null) {
39559 return this._setFlag(countryCode);
39560 }
39561 return false;
39562 },
39563 // check if the given number is a regionless NANP number (expects the number to contain an international dial code)
39564 _isRegionlessNanp: function(number) {
39565 var numeric = this._getNumeric(number);
39566 if (numeric.charAt(0) == "1") {
39567 var areaCode = numeric.substr(1, 3);
39568 return $.inArray(areaCode, regionlessNanpNumbers) > -1;
39569 }
39570 return false;
39571 },
39572 // remove highlighting from other list items and highlight the given item
39573 _highlightListItem: function(listItem) {
39574 this.countryListItems.removeClass("highlight");
39575 listItem.addClass("highlight");
39576 },
39577 // find the country data for the given country code
39578 // the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array
39579 _getCountryData: function(countryCode, ignoreOnlyCountriesOption, allowFail) {
39580 var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries;
39581 for (var i = 0; i < countryList.length; i++) {
39582 if (countryList[i].iso2 == countryCode) {
39583 return countryList[i];
39584 }
39585 }
39586 if (allowFail) {
39587 return null;
39588 } else {
39589 throw new Error("No country data for '" + countryCode + "'");
39590 }
39591 },
39592 // select the given flag, update the placeholder and the active list item
39593 // Note: called from _setInitialState, _updateFlagFromNumber, _selectListItem, setCountry
39594 _setFlag: function(countryCode) {
39595 var prevCountry = this.selectedCountryData.iso2 ? this.selectedCountryData : {};
39596 // do this first as it will throw an error and stop if countryCode is invalid
39597 this.selectedCountryData = countryCode ? this._getCountryData(countryCode, false, false) : {};
39598 // update the defaultCountry - we only need the iso2 from now on, so just store that
39599 if (this.selectedCountryData.iso2) {
39600 this.defaultCountry = this.selectedCountryData.iso2;
39601 }
39602 this.selectedFlagInner.attr("class", "iti-flag " + countryCode);
39603 // update the selected country's title attribute
39604 var title = countryCode ? this.selectedCountryData.name + ": +" + this.selectedCountryData.dialCode : "Unknown";
39605 this.selectedFlagInner.parent().attr("title", title);
39606 if (this.options.separateDialCode) {
39607 var dialCode = this.selectedCountryData.dialCode ? "+" + this.selectedCountryData.dialCode : "", parent = this.telInput.parent();
39608 if (prevCountry.dialCode) {
39609 parent.removeClass("iti-sdc-" + (prevCountry.dialCode.length + 1));
39610 }
39611 if (dialCode) {
39612 parent.addClass("iti-sdc-" + dialCode.length);
39613 }
39614 this.selectedDialCode.text(dialCode);
39615 }
39616 // and the input's placeholder
39617 this._updatePlaceholder();
39618 // update the active list item
39619 this.countryListItems.removeClass("active");
39620 if (countryCode) {
39621 this.countryListItems.find(".iti-flag." + countryCode).first().closest(".country").addClass("active");
39622 }
39623 // return if the flag has changed or not
39624 return prevCountry.iso2 !== countryCode;
39625 },
39626 // update the input placeholder to an example number from the currently selected country
39627 _updatePlaceholder: function() {
39628 var shouldSetPlaceholder = this.options.autoPlaceholder === "aggressive" || !this.hadInitialPlaceholder && (this.options.autoPlaceholder === true || this.options.autoPlaceholder === "polite");
39629 if (window.intlTelInputUtils && shouldSetPlaceholder) {
39630 var numberType = intlTelInputUtils.numberType[this.options.placeholderNumberType], placeholder = this.selectedCountryData.iso2 ? intlTelInputUtils.getExampleNumber(this.selectedCountryData.iso2, this.options.nationalMode, numberType) : "";
39631 placeholder = this._beforeSetNumber(placeholder);
39632 if (typeof this.options.customPlaceholder === "function") {
39633 placeholder = this.options.customPlaceholder(placeholder, this.selectedCountryData);
39634 }
39635 this.telInput.attr("placeholder", placeholder);
39636 }
39637 },
39638 // called when the user selects a list item from the dropdown
39639 _selectListItem: function(listItem) {
39640 // update selected flag and active list item
39641 var flagChanged = this._setFlag(listItem.attr("data-country-code"));
39642 this._closeDropdown();
39643 this._updateDialCode(listItem.attr("data-dial-code"), true);
39644 // focus the input
39645 this.telInput.focus();
39646 // put cursor at end - this fix is required for FF and IE11 (with nationalMode=false i.e. auto inserting dial code), who try to put the cursor at the beginning the first time
39647 if (this.isGoodBrowser) {
39648 var len = this.telInput.val().length;
39649 this.telInput[0].setSelectionRange(len, len);
39650 }
39651 if (flagChanged) {
39652 this._triggerCountryChange();
39653 }
39654 },
39655 // close the dropdown and unbind any listeners
39656 _closeDropdown: function() {
39657 this.countryList.addClass("hide");
39658 // update the arrow
39659 this.selectedFlagInner.children(".iti-arrow").removeClass("up");
39660 // unbind key events
39661 $(document).off(this.ns);
39662 // unbind click-off-to-close
39663 $("html").off(this.ns);
39664 // unbind hover and click listeners
39665 this.countryList.off(this.ns);
39666 // remove menu from container
39667 if (this.options.dropdownContainer) {
39668 if (!this.isMobile) {
39669 $(window).off("scroll" + this.ns);
39670 }
39671 this.dropdown.detach();
39672 }
39673 this.telInput.trigger("close:countrydropdown");
39674 },
39675 // check if an element is visible within it's container, else scroll until it is
39676 _scrollTo: function(element, middle) {
39677 var container = this.countryList, containerHeight = container.height(), containerTop = container.offset().top, containerBottom = containerTop + containerHeight, elementHeight = element.outerHeight(), elementTop = element.offset().top, elementBottom = elementTop + elementHeight, newScrollTop = elementTop - containerTop + container.scrollTop(), middleOffset = containerHeight / 2 - elementHeight / 2;
39678 if (elementTop < containerTop) {
39679 // scroll up
39680 if (middle) {
39681 newScrollTop -= middleOffset;
39682 }
39683 container.scrollTop(newScrollTop);
39684 } else if (elementBottom > containerBottom) {
39685 // scroll down
39686 if (middle) {
39687 newScrollTop += middleOffset;
39688 }
39689 var heightDifference = containerHeight - elementHeight;
39690 container.scrollTop(newScrollTop - heightDifference);
39691 }
39692 },
39693 // replace any existing dial code with the new one
39694 // Note: called from _selectListItem and setCountry
39695 _updateDialCode: function(newDialCode, hasSelectedListItem) {
39696 var inputVal = this.telInput.val(), newNumber;
39697 // save having to pass this every time
39698 newDialCode = "+" + newDialCode;
39699 if (inputVal.charAt(0) == "+") {
39700 // there's a plus so we're dealing with a replacement (doesn't matter if nationalMode or not)
39701 var prevDialCode = this._getDialCode(inputVal);
39702 if (prevDialCode) {
39703 // current number contains a valid dial code, so replace it
39704 newNumber = inputVal.replace(prevDialCode, newDialCode);
39705 } else {
39706 // current number contains an invalid dial code, so ditch it
39707 // (no way to determine where the invalid dial code ends and the rest of the number begins)
39708 newNumber = newDialCode;
39709 }
39710 } else if (this.options.nationalMode || this.options.separateDialCode) {
39711 // don't do anything
39712 return;
39713 } else {
39714 // nationalMode is disabled
39715 if (inputVal) {
39716 // there is an existing value with no dial code: prefix the new dial code
39717 newNumber = newDialCode + inputVal;
39718 } else if (hasSelectedListItem || !this.options.autoHideDialCode) {
39719 // no existing value and either they've just selected a list item, or autoHideDialCode is disabled: insert new dial code
39720 newNumber = newDialCode;
39721 } else {
39722 return;
39723 }
39724 }
39725 this.telInput.val(newNumber);
39726 },
39727 // try and extract a valid international dial code from a full telephone number
39728 // Note: returns the raw string inc plus character and any whitespace/dots etc
39729 _getDialCode: function(number) {
39730 var dialCode = "";
39731 // only interested in international numbers (starting with a plus)
39732 if (number.charAt(0) == "+") {
39733 var numericChars = "";
39734 // iterate over chars
39735 for (var i = 0; i < number.length; i++) {
39736 var c = number.charAt(i);
39737 // if char is number
39738 if ($.isNumeric(c)) {
39739 numericChars += c;
39740 // if current numericChars make a valid dial code
39741 if (this.countryCodes[numericChars]) {
39742 // store the actual raw string (useful for matching later)
39743 dialCode = number.substr(0, i + 1);
39744 }
39745 // longest dial code is 4 chars
39746 if (numericChars.length == 4) {
39747 break;
39748 }
39749 }
39750 }
39751 }
39752 return dialCode;
39753 },
39754 // get the input val, adding the dial code if separateDialCode is enabled
39755 _getFullNumber: function() {
39756 var val = $.trim(this.telInput.val()), dialCode = this.selectedCountryData.dialCode, prefix, numericVal = this._getNumeric(val), // normalized means ensure starts with a 1, so we can match against the full dial code
39757 normalizedVal = numericVal.charAt(0) == "1" ? numericVal : "1" + numericVal;
39758 if (this.options.separateDialCode) {
39759 prefix = "+" + dialCode;
39760 } else if (val.charAt(0) != "+" && val.charAt(0) != "1" && dialCode && dialCode.charAt(0) == "1" && dialCode.length == 4 && dialCode != normalizedVal.substr(0, 4)) {
39761 // if the user has entered a national NANP number, then ensure it includes the full dial code / area code
39762 prefix = dialCode.substr(1);
39763 } else {
39764 prefix = "";
39765 }
39766 return prefix + val;
39767 },
39768 // remove the dial code if separateDialCode is enabled
39769 _beforeSetNumber: function(number) {
39770 if (this.options.separateDialCode) {
39771 var dialCode = this._getDialCode(number);
39772 if (dialCode) {
39773 // US dialCode is "+1", which is what we want
39774 // CA dialCode is "+1 123", which is wrong - should be "+1" (as it has multiple area codes)
39775 // AS dialCode is "+1 684", which is what we want
39776 // Solution: if the country has area codes, then revert to just the dial code
39777 if (this.selectedCountryData.areaCodes !== null) {
39778 dialCode = "+" + this.selectedCountryData.dialCode;
39779 }
39780 // a lot of numbers will have a space separating the dial code and the main number, and some NANP numbers will have a hyphen e.g. +1 684-733-1234 - in both cases we want to get rid of it
39781 // NOTE: don't just trim all non-numerics as may want to preserve an open parenthesis etc
39782 var start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
39783 number = number.substr(start);
39784 }
39785 }
39786 return this._cap(number);
39787 },
39788 // trigger the 'countrychange' event
39789 _triggerCountryChange: function() {
39790 this.telInput.trigger("countrychange", this.selectedCountryData);
39791 },
39792 /**************************
39793 * SECRET PUBLIC METHODS
39794 **************************/
39795 // this is called when the geoip call returns
39796 handleAutoCountry: function() {
39797 if (this.options.initialCountry === "auto") {
39798 // we must set this even if there is an initial val in the input: in case the initial val is invalid and they delete it - they should see their auto country
39799 this.defaultCountry = $.fn[pluginName].autoCountry;
39800 // if there's no initial value in the input, then update the flag
39801 if (!this.telInput.val()) {
39802 this.setCountry(this.defaultCountry);
39803 }
39804 this.autoCountryDeferred.resolve();
39805 }
39806 },
39807 // this is called when the utils request completes
39808 handleUtils: function() {
39809 // if the request was successful
39810 if (window.intlTelInputUtils) {
39811 // if there's an initial value in the input, then format it
39812 if (this.telInput.val()) {
39813 this._updateValFromNumber(this.telInput.val());
39814 }
39815 this._updatePlaceholder();
39816 }
39817 this.utilsScriptDeferred.resolve();
39818 },
39819 /********************
39820 * PUBLIC METHODS
39821 ********************/
39822 // remove plugin
39823 destroy: function() {
39824 if (this.allowDropdown) {
39825 // make sure the dropdown is closed (and unbind listeners)
39826 this._closeDropdown();
39827 // click event to open dropdown
39828 this.selectedFlagInner.parent().off(this.ns);
39829 // label click hack
39830 this.telInput.closest("label").off(this.ns);
39831 }
39832 // unbind submit event handler on form
39833 if (this.options.autoHideDialCode) {
39834 var form = this.telInput.prop("form");
39835 if (form) {
39836 $(form).off(this.ns);
39837 }
39838 }
39839 // unbind all events: key events, and focus/blur events if autoHideDialCode=true
39840 this.telInput.off(this.ns);
39841 // remove markup (but leave the original input)
39842 var container = this.telInput.parent();
39843 container.before(this.telInput).remove();
39844 },
39845 // get the extension from the current number
39846 getExtension: function() {
39847 if (window.intlTelInputUtils) {
39848 return intlTelInputUtils.getExtension(this._getFullNumber(), this.selectedCountryData.iso2);
39849 }
39850 return "";
39851 },
39852 // format the number to the given format
39853 getNumber: function(format) {
39854 if (window.intlTelInputUtils) {
39855 return intlTelInputUtils.formatNumber(this._getFullNumber(), this.selectedCountryData.iso2, format);
39856 }
39857 return "";
39858 },
39859 // get the type of the entered number e.g. landline/mobile
39860 getNumberType: function() {
39861 if (window.intlTelInputUtils) {
39862 return intlTelInputUtils.getNumberType(this._getFullNumber(), this.selectedCountryData.iso2);
39863 }
39864 return -99;
39865 },
39866 // get the country data for the currently selected flag
39867 getSelectedCountryData: function() {
39868 return this.selectedCountryData;
39869 },
39870 // get the validation error
39871 getValidationError: function() {
39872 if (window.intlTelInputUtils) {
39873 return intlTelInputUtils.getValidationError(this._getFullNumber(), this.selectedCountryData.iso2);
39874 }
39875 return -99;
39876 },
39877 // validate the input val - assumes the global function isValidNumber (from utilsScript)
39878 isValidNumber: function() {
39879 var val = $.trim(this._getFullNumber()), countryCode = this.options.nationalMode ? this.selectedCountryData.iso2 : "";
39880 return window.intlTelInputUtils ? intlTelInputUtils.isValidNumber(val, countryCode) : null;
39881 },
39882 // update the selected flag, and update the input val accordingly
39883 setCountry: function(countryCode) {
39884 countryCode = countryCode.toLowerCase();
39885 // check if already selected
39886 if (!this.selectedFlagInner.hasClass(countryCode)) {
39887 this._setFlag(countryCode);
39888 this._updateDialCode(this.selectedCountryData.dialCode, false);
39889 this._triggerCountryChange();
39890 }
39891 },
39892 // set the input value and update the flag
39893 setNumber: function(number) {
39894 // we must update the flag first, which updates this.selectedCountryData, which is used for formatting the number before displaying it
39895 var flagChanged = this._updateFlagFromNumber(number);
39896 this._updateValFromNumber(number);
39897 if (flagChanged) {
39898 this._triggerCountryChange();
39899 }
39900 }
39901 };
39902 // using https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate
39903 // (adapted to allow public functions)
39904 $.fn[pluginName] = function(options) {
39905 var args = arguments;
39906 // Is the first parameter an object (options), or was omitted,
39907 // instantiate a new instance of the plugin.
39908 if (options === undefined || typeof options === "object") {
39909 // collect all of the deferred objects for all instances created with this selector
39910 var deferreds = [];
39911 this.each(function() {
39912 if (!$.data(this, "plugin_" + pluginName)) {
39913 var instance = new Plugin(this, options);
39914 var instanceDeferreds = instance._init();
39915 // we now have 2 deffereds: 1 for auto country, 1 for utils script
39916 deferreds.push(instanceDeferreds[0]);
39917 deferreds.push(instanceDeferreds[1]);
39918 $.data(this, "plugin_" + pluginName, instance);
39919 }
39920 });
39921 // return the promise from the "master" deferred object that tracks all the others
39922 return $.when.apply(null, deferreds);
39923 } else if (typeof options === "string" && options[0] !== "_") {
39924 // If the first parameter is a string and it doesn't start
39925 // with an underscore or "contains" the `init`-function,
39926 // treat this as a call to a public method.
39927 // Cache the method call to make it possible to return a value
39928 var returns;
39929 this.each(function() {
39930 var instance = $.data(this, "plugin_" + pluginName);
39931 // Tests that there's already a plugin-instance
39932 // and checks that the requested public method exists
39933 if (instance instanceof Plugin && typeof instance[options] === "function") {
39934 // Call the method of our plugin instance,
39935 // and pass it the supplied arguments.
39936 returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
39937 }
39938 // Allow instances to be destroyed via the 'destroy' method
39939 if (options === "destroy") {
39940 $.data(this, "plugin_" + pluginName, null);
39941 }
39942 });
39943 // If the earlier cached method gives a value back return the value,
39944 // otherwise return this to preserve chainability.
39945 return returns !== undefined ? returns : this;
39946 }
39947 };
39948 /********************
39949 * STATIC METHODS
39950 ********************/
39951 // get the country data object
39952 $.fn[pluginName].getCountryData = function() {
39953 return allCountries;
39954 };
39955 // load the utils script
39956 $.fn[pluginName].loadUtils = function(path, utilsScriptDeferred) {
39957 if (!$.fn[pluginName].loadedUtilsScript) {
39958 // don't do this twice! (dont just check if window.intlTelInputUtils exists as if init plugin multiple times in quick succession, it may not have finished loading yet)
39959 $.fn[pluginName].loadedUtilsScript = true;
39960 // dont use $.getScript as it prevents caching
39961 $.ajax({
39962 type: "GET",
39963 url: path,
39964 complete: function() {
39965 // tell all instances that the utils request is complete
39966 $(".intl-tel-input input").intlTelInput("handleUtils");
39967 },
39968 dataType: "script",
39969 cache: true
39970 });
39971 } else if (utilsScriptDeferred) {
39972 utilsScriptDeferred.resolve();
39973 }
39974 };
39975 // default options
39976 $.fn[pluginName].defaults = defaults;
39977 // version
39978 $.fn[pluginName].version = "12.0.2";
39979 // Array of country objects for the flag dropdown.
39980 // Here is the criteria for the plugin to support a given country/territory
39981 // - It has an iso2 code: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
39982 // - It has it's own country calling code (it is not a sub-region of another country): https://en.wikipedia.org/wiki/List_of_country_calling_codes
39983 // - It has a flag in the region-flags project: https://github.com/behdad/region-flags/tree/gh-pages/png
39984 // - It is supported by libphonenumber (it must be listed on this page): https://github.com/googlei18n/libphonenumber/blob/master/resources/ShortNumberMetadata.xml
39985 // Each country array has the following information:
39986 // [
39987 // Country name,
39988 // iso2 code,
39989 // International dial code,
39990 // Order (if >1 country with same dial code),
39991 // Area codes
39992 // ]
39993 var allCountries = [ [ "Afghanistan (افغانستان)", "af", "93" ], [ "Albania (Shqipëri)", "al", "355" ], [ "Algeria (الجزائر)", "dz", "213" ], [ "American Samoa", "as", "1684" ], [ "Andorra", "ad", "376" ], [ "Angola", "ao", "244" ], [ "Anguilla", "ai", "1264" ], [ "Antigua and Barbuda", "ag", "1268" ], [ "Argentina", "ar", "54" ], [ "Armenia (Հայաստան)", "am", "374" ], [ "Aruba", "aw", "297" ], [ "Australia", "au", "61", 0 ], [ "Austria (Österreich)", "at", "43" ], [ "Azerbaijan (Azərbaycan)", "az", "994" ], [ "Bahamas", "bs", "1242" ], [ "Bahrain (البحرين)", "bh", "973" ], [ "Bangladesh (বাংলাদেশ)", "bd", "880" ], [ "Barbados", "bb", "1246" ], [ "Belarus (Беларусь)", "by", "375" ], [ "Belgium (België)", "be", "32" ], [ "Belize", "bz", "501" ], [ "Benin (Bénin)", "bj", "229" ], [ "Bermuda", "bm", "1441" ], [ "Bhutan (འབྲུག)", "bt", "975" ], [ "Bolivia", "bo", "591" ], [ "Bosnia and Herzegovina (Босна и Херцеговина)", "ba", "387" ], [ "Botswana", "bw", "267" ], [ "Brazil (Brasil)", "br", "55" ], [ "British Indian Ocean Territory", "io", "246" ], [ "British Virgin Islands", "vg", "1284" ], [ "Brunei", "bn", "673" ], [ "Bulgaria (България)", "bg", "359" ], [ "Burkina Faso", "bf", "226" ], [ "Burundi (Uburundi)", "bi", "257" ], [ "Cambodia (កម្ពុជា)", "kh", "855" ], [ "Cameroon (Cameroun)", "cm", "237" ], [ "Canada", "ca", "1", 1, [ "204", "226", "236", "249", "250", "289", "306", "343", "365", "387", "403", "416", "418", "431", "437", "438", "450", "506", "514", "519", "548", "579", "581", "587", "604", "613", "639", "647", "672", "705", "709", "742", "778", "780", "782", "807", "819", "825", "867", "873", "902", "905" ] ], [ "Cape Verde (Kabu Verdi)", "cv", "238" ], [ "Caribbean Netherlands", "bq", "599", 1 ], [ "Cayman Islands", "ky", "1345" ], [ "Central African Republic (République centrafricaine)", "cf", "236" ], [ "Chad (Tchad)", "td", "235" ], [ "Chile", "cl", "56" ], [ "China (中国)", "cn", "86" ], [ "Christmas Island", "cx", "61", 2 ], [ "Cocos (Keeling) Islands", "cc", "61", 1 ], [ "Colombia", "co", "57" ], [ "Comoros (جزر القمر)", "km", "269" ], [ "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)", "cd", "243" ], [ "Congo (Republic) (Congo-Brazzaville)", "cg", "242" ], [ "Cook Islands", "ck", "682" ], [ "Costa Rica", "cr", "506" ], [ "Côte d’Ivoire", "ci", "225" ], [ "Croatia (Hrvatska)", "hr", "385" ], [ "Cuba", "cu", "53" ], [ "Curaçao", "cw", "599", 0 ], [ "Cyprus (Κύπρος)", "cy", "357" ], [ "Czech Republic (Česká republika)", "cz", "420" ], [ "Denmark (Danmark)", "dk", "45" ], [ "Djibouti", "dj", "253" ], [ "Dominica", "dm", "1767" ], [ "Dominican Republic (República Dominicana)", "do", "1", 2, [ "809", "829", "849" ] ], [ "Ecuador", "ec", "593" ], [ "Egypt (مصر)", "eg", "20" ], [ "El Salvador", "sv", "503" ], [ "Equatorial Guinea (Guinea Ecuatorial)", "gq", "240" ], [ "Eritrea", "er", "291" ], [ "Estonia (Eesti)", "ee", "372" ], [ "Ethiopia", "et", "251" ], [ "Falkland Islands (Islas Malvinas)", "fk", "500" ], [ "Faroe Islands (Føroyar)", "fo", "298" ], [ "Fiji", "fj", "679" ], [ "Finland (Suomi)", "fi", "358", 0 ], [ "France", "fr", "33" ], [ "French Guiana (Guyane française)", "gf", "594" ], [ "French Polynesia (Polynésie française)", "pf", "689" ], [ "Gabon", "ga", "241" ], [ "Gambia", "gm", "220" ], [ "Georgia (საქართველო)", "ge", "995" ], [ "Germany (Deutschland)", "de", "49" ], [ "Ghana (Gaana)", "gh", "233" ], [ "Gibraltar", "gi", "350" ], [ "Greece (Ελλάδα)", "gr", "30" ], [ "Greenland (Kalaallit Nunaat)", "gl", "299" ], [ "Grenada", "gd", "1473" ], [ "Guadeloupe", "gp", "590", 0 ], [ "Guam", "gu", "1671" ], [ "Guatemala", "gt", "502" ], [ "Guernsey", "gg", "44", 1 ], [ "Guinea (Guinée)", "gn", "224" ], [ "Guinea-Bissau (Guiné Bissau)", "gw", "245" ], [ "Guyana", "gy", "592" ], [ "Haiti", "ht", "509" ], [ "Honduras", "hn", "504" ], [ "Hong Kong (香港)", "hk", "852" ], [ "Hungary (Magyarország)", "hu", "36" ], [ "Iceland (Ísland)", "is", "354" ], [ "India (भारत)", "in", "91" ], [ "Indonesia", "id", "62" ], [ "Iran (ایران)", "ir", "98" ], [ "Iraq (العراق)", "iq", "964" ], [ "Ireland", "ie", "353" ], [ "Isle of Man", "im", "44", 2 ], [ "Israel (ישראל)", "il", "972" ], [ "Italy (Italia)", "it", "39", 0 ], [ "Jamaica", "jm", "1876" ], [ "Japan (日本)", "jp", "81" ], [ "Jersey", "je", "44", 3 ], [ "Jordan (الأردن)", "jo", "962" ], [ "Kazakhstan (Казахстан)", "kz", "7", 1 ], [ "Kenya", "ke", "254" ], [ "Kiribati", "ki", "686" ], [ "Kosovo", "xk", "383" ], [ "Kuwait (الكويت)", "kw", "965" ], [ "Kyrgyzstan (Кыргызстан)", "kg", "996" ], [ "Laos (ລາວ)", "la", "856" ], [ "Latvia (Latvija)", "lv", "371" ], [ "Lebanon (لبنان)", "lb", "961" ], [ "Lesotho", "ls", "266" ], [ "Liberia", "lr", "231" ], [ "Libya (ليبيا)", "ly", "218" ], [ "Liechtenstein", "li", "423" ], [ "Lithuania (Lietuva)", "lt", "370" ], [ "Luxembourg", "lu", "352" ], [ "Macau (澳門)", "mo", "853" ], [ "Macedonia (FYROM) (Македонија)", "mk", "389" ], [ "Madagascar (Madagasikara)", "mg", "261" ], [ "Malawi", "mw", "265" ], [ "Malaysia", "my", "60" ], [ "Maldives", "mv", "960" ], [ "Mali", "ml", "223" ], [ "Malta", "mt", "356" ], [ "Marshall Islands", "mh", "692" ], [ "Martinique", "mq", "596" ], [ "Mauritania (موريتانيا)", "mr", "222" ], [ "Mauritius (Moris)", "mu", "230" ], [ "Mayotte", "yt", "262", 1 ], [ "Mexico (México)", "mx", "52" ], [ "Micronesia", "fm", "691" ], [ "Moldova (Republica Moldova)", "md", "373" ], [ "Monaco", "mc", "377" ], [ "Mongolia (Монгол)", "mn", "976" ], [ "Montenegro (Crna Gora)", "me", "382" ], [ "Montserrat", "ms", "1664" ], [ "Morocco (المغرب)", "ma", "212", 0 ], [ "Mozambique (Moçambique)", "mz", "258" ], [ "Myanmar (Burma) (မြန်မာ)", "mm", "95" ], [ "Namibia (Namibië)", "na", "264" ], [ "Nauru", "nr", "674" ], [ "Nepal (नेपाल)", "np", "977" ], [ "Netherlands (Nederland)", "nl", "31" ], [ "New Caledonia (Nouvelle-Calédonie)", "nc", "687" ], [ "New Zealand", "nz", "64" ], [ "Nicaragua", "ni", "505" ], [ "Niger (Nijar)", "ne", "227" ], [ "Nigeria", "ng", "234" ], [ "Niue", "nu", "683" ], [ "Norfolk Island", "nf", "672" ], [ "North Korea (조선 민주주의 인민 공화국)", "kp", "850" ], [ "Northern Mariana Islands", "mp", "1670" ], [ "Norway (Norge)", "no", "47", 0 ], [ "Oman (عُمان)", "om", "968" ], [ "Pakistan (پاکستان)", "pk", "92" ], [ "Palau", "pw", "680" ], [ "Palestine (فلسطين)", "ps", "970" ], [ "Panama (Panamá)", "pa", "507" ], [ "Papua New Guinea", "pg", "675" ], [ "Paraguay", "py", "595" ], [ "Peru (Perú)", "pe", "51" ], [ "Philippines", "ph", "63" ], [ "Poland (Polska)", "pl", "48" ], [ "Portugal", "pt", "351" ], [ "Puerto Rico", "pr", "1", 3, [ "787", "939" ] ], [ "Qatar (قطر)", "qa", "974" ], [ "Réunion (La Réunion)", "re", "262", 0 ], [ "Romania (România)", "ro", "40" ], [ "Russia (Россия)", "ru", "7", 0 ], [ "Rwanda", "rw", "250" ], [ "Saint Barthélemy", "bl", "590", 1 ], [ "Saint Helena", "sh", "290" ], [ "Saint Kitts and Nevis", "kn", "1869" ], [ "Saint Lucia", "lc", "1758" ], [ "Saint Martin (Saint-Martin (partie française))", "mf", "590", 2 ], [ "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)", "pm", "508" ], [ "Saint Vincent and the Grenadines", "vc", "1784" ], [ "Samoa", "ws", "685" ], [ "San Marino", "sm", "378" ], [ "São Tomé and Príncipe (São Tomé e Príncipe)", "st", "239" ], [ "Saudi Arabia (المملكة العربية السعودية)", "sa", "966" ], [ "Senegal (Sénégal)", "sn", "221" ], [ "Serbia (Србија)", "rs", "381" ], [ "Seychelles", "sc", "248" ], [ "Sierra Leone", "sl", "232" ], [ "Singapore", "sg", "65" ], [ "Sint Maarten", "sx", "1721" ], [ "Slovakia (Slovensko)", "sk", "421" ], [ "Slovenia (Slovenija)", "si", "386" ], [ "Solomon Islands", "sb", "677" ], [ "Somalia (Soomaaliya)", "so", "252" ], [ "South Africa", "za", "27" ], [ "South Korea (대한민국)", "kr", "82" ], [ "South Sudan (جنوب السودان)", "ss", "211" ], [ "Spain (España)", "es", "34" ], [ "Sri Lanka (ශ්රී ලංකාව)", "lk", "94" ], [ "Sudan (السودان)", "sd", "249" ], [ "Suriname", "sr", "597" ], [ "Svalbard and Jan Mayen", "sj", "47", 1 ], [ "Swaziland", "sz", "268" ], [ "Sweden (Sverige)", "se", "46" ], [ "Switzerland (Schweiz)", "ch", "41" ], [ "Syria (سوريا)", "sy", "963" ], [ "Taiwan (台灣)", "tw", "886" ], [ "Tajikistan", "tj", "992" ], [ "Tanzania", "tz", "255" ], [ "Thailand (ไทย)", "th", "66" ], [ "Timor-Leste", "tl", "670" ], [ "Togo", "tg", "228" ], [ "Tokelau", "tk", "690" ], [ "Tonga", "to", "676" ], [ "Trinidad and Tobago", "tt", "1868" ], [ "Tunisia (تونس)", "tn", "216" ], [ "Turkey (Türkiye)", "tr", "90" ], [ "Turkmenistan", "tm", "993" ], [ "Turks and Caicos Islands", "tc", "1649" ], [ "Tuvalu", "tv", "688" ], [ "U.S. Virgin Islands", "vi", "1340" ], [ "Uganda", "ug", "256" ], [ "Ukraine (Україна)", "ua", "380" ], [ "United Arab Emirates (الإمارات العربية المتحدة)", "ae", "971" ], [ "United Kingdom", "gb", "44", 0 ], [ "United States", "us", "1", 0 ], [ "Uruguay", "uy", "598" ], [ "Uzbekistan (Oʻzbekiston)", "uz", "998" ], [ "Vanuatu", "vu", "678" ], [ "Vatican City (Città del Vaticano)", "va", "39", 1 ], [ "Venezuela", "ve", "58" ], [ "Vietnam (Việt Nam)", "vn", "84" ], [ "Wallis and Futuna (Wallis-et-Futuna)", "wf", "681" ], [ "Western Sahara (الصحراء الغربية)", "eh", "212", 1 ], [ "Yemen (اليمن)", "ye", "967" ], [ "Zambia", "zm", "260" ], [ "Zimbabwe", "zw", "263" ], [ "Åland Islands", "ax", "358", 1 ] ];
39994 // loop over all of the countries above
39995 for (var i = 0; i < allCountries.length; i++) {
39996 var c = allCountries[i];
39997 allCountries[i] = {
39998 name: c[0],
39999 iso2: c[1],
40000 dialCode: c[2],
40001 priority: c[3] || 0,
40002 areaCodes: c[4] || null
40003 };
40004 }
40005});
40006(function(){for(var aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},l="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this,m=["String","prototype","repeat"],n=0;n<m.length-1;n++){var p=m[n];p in l||(l[p]={});l=l[p]}
40007var ba=m[m.length-1],r=l[ba],t=r?r:function(a){var b;if(null==this)throw new TypeError("The 'this' value for String.prototype.repeat must not be null or undefined");b=this+"";if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var c="";a;)if(a&1&&(c+=b),a>>>=1)b+=b;return c};t!=r&&null!=t&&aa(l,ba,{configurable:!0,writable:!0,value:t});var ca=this;function u(a){return"string"==typeof a}
40008function v(a,b){var c=a.split("."),d=ca;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function w(a,b){function c(){}c.prototype=b.prototype;a.aa=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.$=function(a,c,f){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};var x=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(u(a))return u(b)&&1==b.length?a.indexOf(b,c):-1;for(;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};function y(a,b){a.sort(b||da)}function da(a,b){return a>b?1:a<b?-1:0};function ea(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b};function fa(a,b){this.a=a;this.h=!!b.i;this.b=b.c;this.m=b.type;this.l=!1;switch(this.b){case ga:case ha:case ia:case ja:case ka:case la:case ma:this.l=!0}this.g=b.defaultValue}var ma=1,la=2,ga=3,ha=4,ia=6,ja=16,ka=18;function na(a,b){this.b=a;this.a={};for(var c=0;c<b.length;c++){var d=b[c];this.a[d.a]=d}}function oa(a){a=ea(a.a);y(a,function(a,c){return a.a-c.a});return a};function A(){this.a={};this.g=this.f().a;this.b=this.h=null}A.prototype.has=function(a){return null!=this.a[a.a]};A.prototype.get=function(a,b){return B(this,a.a,b)};A.prototype.set=function(a,b){C(this,a.a,b)};
40009function pa(a,b){for(var c=oa(a.f()),d=0;d<c.length;d++){var e=c[d],f=e.a;if(null!=b.a[f]){a.b&&delete a.b[e.a];var g=11==e.b||10==e.b;if(e.h)for(var e=D(b,f),h=0;h<e.length;h++){var k=a,q=f,z=g?e[h].clone():e[h];k.a[q]||(k.a[q]=[]);k.a[q].push(z);k.b&&delete k.b[q]}else e=E(b,f),g?(g=E(a,f))?pa(g,e):C(a,f,e.clone()):C(a,f,e)}}}A.prototype.clone=function(){var a=new this.constructor;a!=this&&(a.a={},a.b&&(a.b={}),pa(a,this));return a};
40010function E(a,b){var c=a.a[b];if(null==c)return null;if(a.h){if(!(b in a.b)){var d=a.h,e=a.g[b];if(null!=c)if(e.h){for(var f=[],g=0;g<c.length;g++)f[g]=d.a(e,c[g]);c=f}else c=d.a(e,c);return a.b[b]=c}return a.b[b]}return c}function B(a,b,c){var d=E(a,b);return a.g[b].h?d[c||0]:d}function F(a,b){var c;if(null!=a.a[b])c=B(a,b,void 0);else a:{c=a.g[b];if(void 0===c.g){var d=c.m;if(d===Boolean)c.g=!1;else if(d===Number)c.g=0;else if(d===String)c.g=c.l?"0":"";else{c=new d;break a}}c=c.g}return c}
40011function D(a,b){return E(a,b)||[]}function G(a,b){return a.g[b].h?null!=a.a[b]?a.a[b].length:0:null!=a.a[b]?1:0}function C(a,b,c){a.a[b]=c;a.b&&(a.b[b]=c)}function H(a,b){var c=[],d;for(d in b)0!=d&&c.push(new fa(d,b[d]));return new na(a,c)};function I(){}I.prototype.b=function(a){new a.b;throw Error("Unimplemented");};I.prototype.a=function(a,b){if(11==a.b||10==a.b)return b instanceof A?b:this.b(a.m.prototype.f(),b);if(14==a.b){if(u(b)&&qa.test(b)){var c=Number(b);if(0<c)return c}return b}if(!a.l)return b;c=a.m;if(c===String){if("number"==typeof b)return String(b)}else if(c===Number&&u(b)&&("Infinity"===b||"-Infinity"===b||"NaN"===b||qa.test(b)))return Number(b);return b};var qa=/^-?[0-9]+$/;function J(){}w(J,I);J.prototype.b=function(a,b){var c=new a.b;c.h=this;c.a=b;c.b={};return c};function ra(){}w(ra,J);ra.prototype.a=function(a,b){return 8==a.b?!!b:I.prototype.a.apply(this,arguments)};function K(a,b){null!=a&&this.a.apply(this,arguments)}K.prototype.b="";K.prototype.set=function(a){this.b=""+a};K.prototype.a=function(a,b,c){this.b+=String(a);if(null!=b)for(var d=1;d<arguments.length;d++)this.b+=arguments[d];return this};K.prototype.toString=function(){return this.b};/*
40012
40013 Protocol Buffer 2 Copyright 2008 Google Inc.
40014 All other code copyright its respective owners.
40015 Copyright (C) 2010 The Libphonenumber Authors
40016
40017 Licensed under the Apache License, Version 2.0 (the "License");
40018 you may not use this file except in compliance with the License.
40019 You may obtain a copy of the License at
40020
40021 http://www.apache.org/licenses/LICENSE-2.0
40022
40023 Unless required by applicable law or agreed to in writing, software
40024 distributed under the License is distributed on an "AS IS" BASIS,
40025 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40026 See the License for the specific language governing permissions and
40027 limitations under the License.
40028*/
40029function L(){A.call(this)}w(L,A);var sa=null;function M(){A.call(this)}w(M,A);var ta=null;function N(){A.call(this)}w(N,A);var ua=null;
40030L.prototype.f=function(){var a=sa;a||(sa=a=H(L,{0:{name:"NumberFormat",j:"i18n.phonenumbers.NumberFormat"},1:{name:"pattern",required:!0,c:9,type:String},2:{name:"format",required:!0,c:9,type:String},3:{name:"leading_digits_pattern",i:!0,c:9,type:String},4:{name:"national_prefix_formatting_rule",c:9,type:String},6:{name:"national_prefix_optional_when_formatting",c:8,defaultValue:!1,type:Boolean},5:{name:"domestic_carrier_code_formatting_rule",c:9,type:String}}));return a};L.f=L.prototype.f;
40031M.prototype.f=function(){var a=ta;a||(ta=a=H(M,{0:{name:"PhoneNumberDesc",j:"i18n.phonenumbers.PhoneNumberDesc"},2:{name:"national_number_pattern",c:9,type:String},9:{name:"possible_length",i:!0,c:5,type:Number},10:{name:"possible_length_local_only",i:!0,c:5,type:Number},6:{name:"example_number",c:9,type:String}}));return a};M.f=M.prototype.f;
40032N.prototype.f=function(){var a=ua;a||(ua=a=H(N,{0:{name:"PhoneMetadata",j:"i18n.phonenumbers.PhoneMetadata"},1:{name:"general_desc",c:11,type:M},2:{name:"fixed_line",c:11,type:M},3:{name:"mobile",c:11,type:M},4:{name:"toll_free",c:11,type:M},5:{name:"premium_rate",c:11,type:M},6:{name:"shared_cost",c:11,type:M},7:{name:"personal_number",c:11,type:M},8:{name:"voip",c:11,type:M},21:{name:"pager",c:11,type:M},25:{name:"uan",c:11,type:M},27:{name:"emergency",c:11,type:M},28:{name:"voicemail",c:11,type:M},
4003324:{name:"no_international_dialling",c:11,type:M},9:{name:"id",required:!0,c:9,type:String},10:{name:"country_code",c:5,type:Number},11:{name:"international_prefix",c:9,type:String},17:{name:"preferred_international_prefix",c:9,type:String},12:{name:"national_prefix",c:9,type:String},13:{name:"preferred_extn_prefix",c:9,type:String},15:{name:"national_prefix_for_parsing",c:9,type:String},16:{name:"national_prefix_transform_rule",c:9,type:String},18:{name:"same_mobile_and_fixed_line_pattern",c:8,defaultValue:!1,
40034type:Boolean},19:{name:"number_format",i:!0,c:11,type:L},20:{name:"intl_number_format",i:!0,c:11,type:L},22:{name:"main_country_for_code",c:8,defaultValue:!1,type:Boolean},23:{name:"leading_digits",c:9,type:String},26:{name:"leading_zero_possible",c:8,defaultValue:!1,type:Boolean}}));return a};N.f=N.prototype.f;function O(){A.call(this)}w(O,A);var va=null,wa={w:0,v:1,u:5,s:10,o:20};
40035O.prototype.f=function(){var a=va;a||(va=a=H(O,{0:{name:"PhoneNumber",j:"i18n.phonenumbers.PhoneNumber"},1:{name:"country_code",required:!0,c:5,type:Number},2:{name:"national_number",required:!0,c:4,type:Number},3:{name:"extension",c:9,type:String},4:{name:"italian_leading_zero",c:8,type:Boolean},8:{name:"number_of_leading_zeros",c:5,defaultValue:1,type:Number},5:{name:"raw_input",c:9,type:String},6:{name:"country_code_source",c:14,defaultValue:0,type:wa},7:{name:"preferred_domestic_carrier_code",
40036c:9,type:String}}));return a};O.ctor=O;O.ctor.f=O.prototype.f;/*
40037
40038 Copyright (C) 2010 The Libphonenumber Authors
40039
40040 Licensed under the Apache License, Version 2.0 (the "License");
40041 you may not use this file except in compliance with the License.
40042 You may obtain a copy of the License at
40043
40044 http://www.apache.org/licenses/LICENSE-2.0
40045
40046 Unless required by applicable law or agreed to in writing, software
40047 distributed under the License is distributed on an "AS IS" BASIS,
40048 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40049 See the License for the specific language governing permissions and
40050 limitations under the License.
40051*/
40052var P={1:"US AG AI AS BB BM BS CA DM DO GD GU JM KN KY LC MP MS PR SX TC TT VC VG VI".split(" "),7:["RU","KZ"],20:["EG"],27:["ZA"],30:["GR"],31:["NL"],32:["BE"],33:["FR"],34:["ES"],36:["HU"],39:["IT","VA"],40:["RO"],41:["CH"],43:["AT"],44:["GB","GG","IM","JE"],45:["DK"],46:["SE"],47:["NO","SJ"],48:["PL"],49:["DE"],51:["PE"],52:["MX"],53:["CU"],54:["AR"],55:["BR"],56:["CL"],57:["CO"],58:["VE"],60:["MY"],61:["AU","CC","CX"],62:["ID"],63:["PH"],64:["NZ"],65:["SG"],66:["TH"],81:["JP"],82:["KR"],84:["VN"],
4005386:["CN"],90:["TR"],91:["IN"],92:["PK"],93:["AF"],94:["LK"],95:["MM"],98:["IR"],211:["SS"],212:["MA","EH"],213:["DZ"],216:["TN"],218:["LY"],220:["GM"],221:["SN"],222:["MR"],223:["ML"],224:["GN"],225:["CI"],226:["BF"],227:["NE"],228:["TG"],229:["BJ"],230:["MU"],231:["LR"],232:["SL"],233:["GH"],234:["NG"],235:["TD"],236:["CF"],237:["CM"],238:["CV"],239:["ST"],240:["GQ"],241:["GA"],242:["CG"],243:["CD"],244:["AO"],245:["GW"],246:["IO"],247:["AC"],248:["SC"],249:["SD"],250:["RW"],251:["ET"],252:["SO"],
40054253:["DJ"],254:["KE"],255:["TZ"],256:["UG"],257:["BI"],258:["MZ"],260:["ZM"],261:["MG"],262:["RE","YT"],263:["ZW"],264:["NA"],265:["MW"],266:["LS"],267:["BW"],268:["SZ"],269:["KM"],290:["SH","TA"],291:["ER"],297:["AW"],298:["FO"],299:["GL"],350:["GI"],351:["PT"],352:["LU"],353:["IE"],354:["IS"],355:["AL"],356:["MT"],357:["CY"],358:["FI","AX"],359:["BG"],370:["LT"],371:["LV"],372:["EE"],373:["MD"],374:["AM"],375:["BY"],376:["AD"],377:["MC"],378:["SM"],380:["UA"],381:["RS"],382:["ME"],385:["HR"],386:["SI"],
40055387:["BA"],389:["MK"],420:["CZ"],421:["SK"],423:["LI"],500:["FK"],501:["BZ"],502:["GT"],503:["SV"],504:["HN"],505:["NI"],506:["CR"],507:["PA"],508:["PM"],509:["HT"],590:["GP","BL","MF"],591:["BO"],592:["GY"],593:["EC"],594:["GF"],595:["PY"],596:["MQ"],597:["SR"],598:["UY"],599:["CW","BQ"],670:["TL"],672:["NF"],673:["BN"],674:["NR"],675:["PG"],676:["TO"],677:["SB"],678:["VU"],679:["FJ"],680:["PW"],681:["WF"],682:["CK"],683:["NU"],685:["WS"],686:["KI"],687:["NC"],688:["TV"],689:["PF"],690:["TK"],691:["FM"],
40056692:["MH"],800:["001"],808:["001"],850:["KP"],852:["HK"],853:["MO"],855:["KH"],856:["LA"],870:["001"],878:["001"],880:["BD"],881:["001"],882:["001"],883:["001"],886:["TW"],888:["001"],960:["MV"],961:["LB"],962:["JO"],963:["SY"],964:["IQ"],965:["KW"],966:["SA"],967:["YE"],968:["OM"],970:["PS"],971:["AE"],972:["IL"],973:["BH"],974:["QA"],975:["BT"],976:["MN"],977:["NP"],979:["001"],992:["TJ"],993:["TM"],994:["AZ"],995:["GE"],996:["KG"],998:["UZ"]},xa={AC:[,[,,"[46]\\d{4}|[01589]\\d{5}",,,,,,,[5,6]],
40057[,,"6[2-467]\\d{3}",,,,"62889",,,[5]],[,,"4\\d{4}",,,,"40123",,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AC",247,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"[01589]\\d{5}",,,,"542011",,,[6]],,,[,,,,,,,,,[-1]]],AD:[,[,,"[16]\\d{5,8}|[37-9]\\d{5}",,,,,,,[6,8,9]],[,,"[78]\\d{5}",,,,"712345",,,[6]],[,,"(?:3\\d|6(?:[0-8]|90\\d{2}))\\d{4}",,,,"312345",,,[6,9]],[,,"180[02]\\d{4}",,,,"18001234",,,[8]],[,,"[19]\\d{5}",,,,"912345",,,[6]],[,,,,,,,,,[-1]],
40058[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AD",376,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1 $2",["[137-9]|6[0-8]"]],[,"(\\d{4})(\\d{4})","$1 $2",["180","180[02]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["690"]]],,[,,,,,,,,,[-1]],,,[,,"1800\\d{4}",,,,"18000000",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AE:[,[,,"[2-79]\\d{7,8}|800\\d{2,9}",,,,,,,[5,6,7,8,9,10,11,12]],[,,"[2-4679][2-8]\\d{6}",,,,"22345678",,,[8],[7]],[,,"5[024-68]\\d{7}",,,,"501234567",,,[9]],[,,"400\\d{6}|800\\d{2,9}",,,,"800123456"],[,,"900[02]\\d{5}",
40059,,,"900234567",,,[9]],[,,"700[05]\\d{5}",,,,"700012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AE",971,"00","0",,,"0",,,,[[,"([2-4679])(\\d{3})(\\d{4})","$1 $2 $3",["[2-4679][2-8]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{4})","$1 $2 $3",["5"],"0$1"],[,"([479]00)(\\d)(\\d{5})","$1 $2 $3",["[479]0"],"$1"],[,"([68]00)(\\d{2,9})","$1 $2",["60|8"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"600[25]\\d{5}",,,,"600212345",,,[9]],,,[,,,,,,,,,[-1]]],AF:[,[,,"[2-7]\\d{8}",,,,,,,[9],[7]],[,,"(?:[25][0-8]|[34][0-4]|6[0-5])[2-9]\\d{6}",
40060,,,"234567890",,,,[7]],[,,"7(?:[014-9]\\d|2[89]|30)\\d{6}",,,,"701234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AF",93,"00","0",,,"0",,,,[[,"([2-7]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2-7]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AG:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"268(?:4(?:6[0-38]|84)|56[0-2])\\d{4}",,,,"2684601234",,,,[7]],[,,"268(?:464|7(?:1[3-9]|2\\d|3[246]|64|7[0-689]|8[02-68]))\\d{4}",,,,"2684641234",,
40061,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"26848[01]\\d{4}",,,,"2684801234",,,,[7]],"AG",1,"011","1",,,"1",,,,,,[,,"26840[69]\\d{4}",,,,"2684061234",,,,[7]],,"268",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AI:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"2644(?:6[12]|9[78])\\d{4}",,,,"2644612345",,,,[7]],[,,"264(?:235|476|5(?:3[6-9]|8[1-4])|7(?:29|72))\\d{4}",
40062,,,"2642351234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"AI",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"264",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AL:[,[,,"[2-57]\\d{7}|6\\d{8}|8\\d{5,7}|9\\d{5}",,,,,,,[6,7,8,9],[5]],[,,"(?:2(?:1(?:0[2-9]|[1-9]\\d)|[247]\\d{2}|[35][2-9]\\d|[68](?:0[2-9]|[1-9]\\d)|9(?:[089][2-9]|[1-7]\\d))|3(?:1(?:[04-9][2-9]|[1-3]\\d)|[2-6]\\d{2}|[79](?:[09][2-9]|[1-8]\\d)|8(?:0[2-9]|[1-9]\\d))|4\\d{3}|5(?:1(?:[05-9][2-9]|[1-4]\\d)|[2-578]\\d{2}|6(?:[06-9][2-9]|[1-5]\\d)|9(?:[089][2-9]|[1-7]\\d))|8(?:[19](?:[06-9][2-9]|[1-5]\\d)|[2-6]\\d{2}|[78](?:[089][2-9]|[1-7]\\d)))\\d{4}",
40063,,,"22345678",,,[8],[5,6,7]],[,,"6(?:[689][2-9]|7[2-6])\\d{6}",,,,"662123456",,,[9]],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,"900[1-9]\\d{2}",,,,"900123",,,[6]],[,,"808[1-9]\\d{2}",,,,"808123",,,[6]],[,,"700[2-9]\\d{4}",,,,"70021234",,,[8]],[,,,,,,,,,[-1]],"AL",355,"00","0",,,"0",,,,[[,"(4)(\\d{3})(\\d{4})","$1 $2 $3",["4[0-6]"],"0$1"],[,"(6\\d)(\\d{3})(\\d{4})","$1 $2 $3",["6"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2358][2-5]|4[7-9]"],"0$1"],[,"(\\d{3})(\\d{3,5})","$1 $2",["[235][16-9]|8[016-9]|[79]"],
40064"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AM:[,[,,"[1-9]\\d{7}",,,,,,,[8],[5,6]],[,,"(?:1[0-2]\\d|2(?:2[2-46]|3[1-8]|4[2-69]|5[2-7]|6[1-9]|8[1-7])|3[12]2|47\\d)\\d{5}",,,,"10123456",,,,[5,6]],[,,"(?:4[1349]|55|77|88|9[1-9])\\d{6}",,,,"77123456"],[,,"800\\d{5}",,,,"80012345"],[,,"90[016]\\d{5}",,,,"90012345"],[,,"80[1-4]\\d{5}",,,,"80112345"],[,,,,,,,,,[-1]],[,,"60(?:2[078]|[3-7]\\d|8[0-5])\\d{4}",,,,"60271234"],"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",
40065["1|47"],"(0$1)"],[,"(\\d{2})(\\d{6})","$1 $2",["4[1349]|[5-7]|88|9[1-9]"],"0$1"],[,"(\\d{3})(\\d{5})","$1 $2",["[23]"],"(0$1)"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["8|90"],"0 $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AO:[,[,,"[29]\\d{8}",,,,,,,[9]],[,,"2\\d(?:[26-9]\\d|\\d[26-9])\\d{5}",,,,"222123456"],[,,"9[1-49]\\d{7}",,,,"923123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AO",244,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})",
40066"$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AR:[,[,,"11\\d{8}|[2368]\\d{9}|9\\d{10}",,,,,,,[10,11],[6,7,8]],[,,"11\\d{8}|(?:2(?:2(?:[013]\\d|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[067]\\d)|4(?:7[3-8]|9\\d)|6(?:[01346]\\d|2[24-6]|5[15-8])|80\\d|9(?:[0124789]\\d|3[1-6]|5[234]|6[2-46]))|3(?:3(?:2[79]|6\\d|8[2578])|4(?:[78]\\d|0[0124-9]|[1-35]\\d|4[24-7]|6[02-9]|9[123678])|5(?:[138]\\d|2[1245]|4[1-9]|6[2-4]|7[1-6])|6[24]\\d|7(?:[0469]\\d|1[1568]|2[013-9]|3[145]|5[14-8]|7[2-57]|8[0-24-9])|8(?:[013578]\\d|2[15-7]|4[13-6]|6[1-357-9]|9[124]))|670\\d)\\d{6}",
40067,,,"1123456789",,,[10],[6,7,8]],[,,"675\\d{7}|9(?:11[2-9]\\d{7}|(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[12358]|5[138]|6[24]|7[069]|8[013578]))[2-9]\\d{6}|\\d{4}[2-9]\\d{5})",,,,"91123456789",,,,[6,7,8]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"60[04579]\\d{7}",,,,"6001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AR",54,"00","0",,,"0?(?:(11|2(?:2(?:02?|[13]|2[13-79]|4[1-6]|5[2457]|6[124-8]|7[1-4]|8[13-6]|9[1267])|3(?:02?|1[467]|2[03-6]|3[13-8]|[49][2-6]|5[2-8]|[67])|4(?:7[3-578]|9)|6(?:[0136]|2[24-6]|4[6-8]?|5[15-8])|80|9(?:0[1-3]|[19]|2\\d|3[1-6]|4[02568]?|5[2-4]|6[2-46]|72?|8[23]?))|3(?:3(?:2[79]|6|8[2578])|4(?:0[0-24-9]|[12]|3[5-8]?|4[24-7]|5[4-68]?|6[02-9]|7[126]|8[2379]?|9[1-36-8])|5(?:1|2[1245]|3[237]?|4[1-46-9]|6[2-4]|7[1-6]|8[2-5]?)|6[24]|7(?:[069]|1[1568]|2[15]|3[145]|4[13]|5[14-8]|7[2-57]|8[126])|8(?:[01]|2[15-7]|3[2578]?|4[13-6]|5[4-8]?|6[1-357-9]|7[36-8]?|8[5-8]?|9[124])))?15)?",
40068"9$1",,,[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[68]"],"0$1"],[,"(\\d{2})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(\\d{3})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(\\d{4})(\\d{4})","$1-$2",["[2-9]"],"$1"],[,"(9)(11)(\\d{4})(\\d{4})","$2 15-$3-$4",["911"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{4})","$2 15-$3-$4",["9(?:2[234689]|3[3-8])","9(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578]))","9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))",
40069"9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))"],"0$1"],[,"(9)(\\d{4})(\\d{2})(\\d{4})","$2 15-$3-$4",["9[23]"],"0$1"],[,"(11)(\\d{4})(\\d{4})","$1 $2-$3",["1"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3",["2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578])","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))",
40070"2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))"],"0$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3",["[23]"],"0$1",,1],[,"(\\d{3})","$1",["1[012]|911"],"$1"]],[[,"([68]\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[68]"],"0$1"],[,"(9)(11)(\\d{4})(\\d{4})","$1 $2 $3-$4",["911"]],[,"(9)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3-$4",["9(?:2[234689]|3[3-8])","9(?:2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578]))",
40071"9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))","9(?:2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45])))"]],[,"(9)(\\d{4})(\\d{2})(\\d{4})","$1 $2 $3-$4",["9[23]"]],[,"(11)(\\d{4})(\\d{4})","$1 $2-$3",["1"],"0$1",
40072,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2-$3",["2(?:2[013]|3[067]|49|6[01346]|80|9[147-9])|3(?:36|4[1-358]|5[138]|6[24]|7[069]|8[013578])","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3[456]|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))","2(?:2(?:0[013-9]|[13])|3(?:0[013-9]|[67])|49|6(?:[0136]|4[0-59])|8|9(?:[19]|44|7[013-9]|8[14]))|3(?:36|4(?:[12]|3(?:4|5[014]|6[1239])|[58]4)|5(?:1|3[0-24-689]|8[46])|6|7[069]|8(?:[01]|34|[578][45]))"],
40073"0$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2-$3",["[23]"],"0$1",,1]],[,,,,,,,,,[-1]],,,[,,"810\\d{7}",,,,"8101234567",,,[10]],[,,"810\\d{7}",,,,"8101234567",,,[10]],,,[,,,,,,,,,[-1]]],AS:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"6846(?:22|33|44|55|77|88|9[19])\\d{4}",,,,"6846221234",,,,[7]],[,,"684(?:2(?:5[2468]|72)|7(?:3[13]|70))\\d{4}",,,,"6847331234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",
40074,,,"5002345678"],[,,,,,,,,,[-1]],"AS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"684",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AT:[,[,,"[1-9]\\d{3,12}",,,,,,,[4,5,6,7,8,9,10,11,12,13],[3]],[,,"1\\d{3,12}|(?:2(?:1[467]|2[13-8]|5[2357]|6[1-46-8]|7[1-8]|8[124-7]|9[1458])|3(?:1[1-8]|3[23568]|4[5-7]|5[1378]|6[1-38]|8[3-68])|4(?:2[1-8]|35|63|7[1368]|8[2457])|5(?:12|2[1-8]|3[357]|4[147]|5[12578]|6[37])|6(?:13|2[1-47]|4[1-35-8]|5[468]|62)|7(?:2[1-8]|3[25]|4[13478]|5[68]|6[16-8]|7[1-6]|9[45]))\\d{3,10}",
40075,,,"1234567890",,,,[3]],[,,"6(?:5[0-3579]|6[013-9]|[7-9]\\d)\\d{4,10}",,,,"664123456",,,[7,8,9,10,11,12,13]],[,,"800\\d{6,10}",,,,"800123456",,,[9,10,11,12,13]],[,,"9(?:0[01]|3[019])\\d{6,10}",,,,"900123456",,,[9,10,11,12,13]],[,,"8(?:10\\d|2(?:[01]\\d|8\\d?))\\d{5,9}",,,,"810123456",,,[8,9,10,11,12,13]],[,,,,,,,,,[-1]],[,,"780\\d{6,10}",,,,"780123456",,,[9,10,11,12,13]],"AT",43,"00","0",,,"0",,,,[[,"(116\\d{3})","$1",["116"],"$1"],[,"(1)(\\d{3,12})","$1 $2",["1"],"0$1"],[,"(5\\d)(\\d{3,5})","$1 $2",
40076["5[079]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["5[079]"],"0$1"],[,"(5\\d)(\\d{4})(\\d{4,7})","$1 $2 $3",["5[079]"],"0$1"],[,"(\\d{3})(\\d{3,10})","$1 $2",["316|46|51|732|6(?:5[0-3579]|[6-9])|7(?:[28]0)|[89]"],"0$1"],[,"(\\d{4})(\\d{3,9})","$1 $2",["2|3(?:1[1-578]|[3-8])|4[2378]|5[2-6]|6(?:[12]|4[1-9]|5[468])|7(?:2[1-8]|35|4[1-8]|[5-79])"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"5(?:(?:0[1-9]|17)\\d{2,10}|[79]\\d{3,11})|720\\d{6,10}",,,,"50123",,,[5,6,7,8,9,10,11,12,13]],,,[,,,,
40077,,,,,[-1]]],AU:[,[,,"1\\d{4,9}|[2-578]\\d{8}",,,,,,,[5,6,7,8,9,10]],[,,"[237]\\d{8}|8(?:[6-8]\\d{3}|9(?:[02-9]\\d{2}|1(?:[0-57-9]\\d|6[0135-9])))\\d{4}",,,,"212345678",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-3]\\d|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"19(?:0[0126]\\d|[679])\\d{5}",,,,"1900123456",,,[8,10]],[,,"13(?:00\\d{3}|45[0-4]|\\d)\\d{3}",,,,"1300123456",,,[6,8,10]],[,,"500\\d{6}",,,,"500123456",
40078,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"AU",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88)0011)|001[14-689]","0",,,"0",,"0011",,[[,"([2378])(\\d{4})(\\d{4})","$1 $2 $3",["[2378]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[45]|14"],"0$1"],[,"(16)(\\d{3,4})","$1 $2",["16"],"0$1"],[,"(16)(\\d{3})(\\d{2,4})","$1 $2 $3",["16"],"0$1"],[,"(1[389]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:[38]0|90)","1(?:[38]00|90)"],"$1"],[,"(180)(2\\d{3})","$1 $2",["180","1802"],"$1"],[,"(19\\d)(\\d{3})","$1 $2",
40079["19[13]"],"$1"],[,"(19\\d{2})(\\d{4})","$1 $2",["19[679]"],"$1"],[,"(13)(\\d{2})(\\d{2})","$1 $2 $3",["13[1-9]"],"$1"]],,[,,"16\\d{3,7}",,,,"1612345",,,[5,6,7,8,9]],1,,[,,"1(?:3(?:00\\d{3}|45[0-4]|\\d)\\d{3}|80(?:0\\d{6}|2\\d{3}))",,,,"1300123456",,,[6,7,8,10]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AW:[,[,,"[25-9]\\d{6}",,,,,,,[7]],[,,"5(?:2\\d|8[1-9])\\d{4}",,,,"5212345"],[,,"(?:5(?:6\\d|9[2-478])|6(?:[039]0|22|4[01]|6[0-2])|7[34]\\d|9(?:6[45]|9[4-8]))\\d{4}",,,,"5601234"],[,,"800\\d{4}",,,,"8001234"],
40080[,,"900\\d{4}",,,,"9001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"28\\d{5}|501\\d{4}",,,,"5011234"],"AW",297,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],AX:[,[,,"[15]\\d{6,9}|2\\d{4,9}|3\\d{5,9}|4\\d{7,10}|[67]\\d{7,9}|8\\d{7,8}",,,,,,,[5,6,7,8,9,10,11]],[,,"18[1-8]\\d{4,6}",,,,"181234567",,,[7,8,9]],[,,"4(?:[0-8]\\d{6,8}|9\\d{9})|50\\d{6,8}",,,,"412345678",,,[8,9,10,11]],[,,"800\\d{5,6}",,,,"800123456",,,[8,9]],[,,"[67]00\\d{5,6}",
40081,,,"600123456",,,[8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AX",358,"00|99(?:[02469]|5(?:11|33|5[59]|88|9[09]))","0",,,"0",,"00",,,,[,,,,,,,,,[-1]],,,[,,"100\\d{4,6}|20(?:0\\d{4,6}|2[023]\\d{4,5}|9[89]\\d{1,6})|300\\d{3,7}|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",,,,"1001234",,,[5,6,7,8,9,10]],[,,"10(?:0\\d{4,6}|[1-9]\\d{5,7})|2(?:0(?:0\\d{4,6}|[13-8]\\d{5,7}|2(?:[023]\\d{4,5}|[14-9]\\d{4,6})|9(?:[0-7]\\d{4,6}|[89]\\d{1,6}))|9\\d{5,8})|3(?:0(?:0\\d{3,7}|[1-57-9]\\d{5,7}|6(?:\\d{3}|\\d{5,7}))|93\\d{5,7})|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",
40082,,,"10112345",,,[5,6,7,8,9,10]],,,[,,,,,,,,,[-1]]],AZ:[,[,,"[1-9]\\d{8}",,,,,,,[9],[7]],[,,"(?:1[28]\\d{3}|2(?:02|1[24]|2[2-4]|33|[45]2|6[23])\\d{2}|365(?:[0-46-9]\\d|5[0-35-9]))\\d{4}",,,,"123123456",,,,[7]],[,,"(?:36554|(?:4[04]|5[015]|60|7[07])\\d{3})\\d{4}",,,,"401234567"],[,,"88\\d{7}",,,,"881234567"],[,,"900200\\d{3}",,,,"900200123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"AZ",994,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["(?:1[28]|2(?:[45]2|[0-36])|365)"],
40083"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[4-8]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BA:[,[,,"[3-9]\\d{7,8}",,,,,,,[8,9],[6]],[,,"(?:[35]\\d|49)\\d{6}",,,,"30123456",,,[8],[6]],[,,"6(?:0(?:3\\d|40)|[1-356]\\d|44[0-6]|71[137])\\d{5}",,,,"61123456"],[,,"8[08]\\d{6}",,,,"80123456",,,[8]],[,,"9[0246]\\d{6}",,,,"90123456",,,[8]],[,,"8[12]\\d{6}",,,,"82123456",,,[8]],[,,,,,,,,,
40084[-1]],[,,,,,,,,,[-1]],"BA",387,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2-$3",["[3-5]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["6[1-356]|[7-9]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["6[047]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"70[23]\\d{5}",,,,"70223456",,,[8]],,,[,,,,,,,,,[-1]]],BB:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"246(?:2(?:2[78]|7[0-4])|4(?:1[024-6]|2\\d|3[2-9])|5(?:20|[34]\\d|54|7[1-3])|6(?:2\\d|38)|7(?:37|57)|9(?:1[89]|63))\\d{4}",
40085,,,"2464123456",,,,[7]],[,,"246(?:2(?:[356]\\d|4[0-57-9]|8[0-79])|45\\d|8(?:[2-5]\\d|83))\\d{4}",,,,"2462501234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900\\d{7}|246976\\d{4}",,,,"9002123456",,,,[7]],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"24631\\d{5}",,,,"2463101234",,,,[7]],"BB",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"246",[,,,,,,,,,[-1]],[,,"246(?:292|367|4(?:1[7-9]|3[01]|44|67)|736)\\d{4}",,,,"2464301234",,,,[7]],,,[,,,,,
40086,,,,[-1]]],BD:[,[,,"[2-79]\\d{5,9}|1\\d{9}|8[0-7]\\d{4,8}",,,,,,,[6,7,8,9,10]],[,,"2(?:[45]\\d{3}|7(?:1[0-267]|2[0-289]|3[0-29]|4[01]|5[1-3]|6[013]|7[0178]|91)|8(?:0[125]|[139][1-6]|2[0157-9]|41|6[1-35]|7[1-5]|8[1-8]|90)|9(?:0[0-2]|1[0-4]|2[568]|3[3-6]|5[5-7]|6[0167]|7[15]|8[0146-9]))\\d{4}|3(?:12?[5-7]\\d{2}|0(?:2(?:[025-79]\\d|[348]\\d{1,2})|3(?:[2-4]\\d|[56]\\d?))|2(?:1\\d{2}|2(?:[12]\\d|[35]\\d{1,2}|4\\d?))|3(?:1\\d{2}|2(?:[2356]\\d|4\\d{1,2}))|4(?:1\\d{2}|2(?:2\\d{1,2}|[47]|5\\d{2}))|5(?:1\\d{2}|29)|[67]1\\d{2}|8(?:1\\d{2}|2(?:2\\d{2}|3|4\\d)))\\d{3}|4(?:0(?:2(?:[09]\\d|7)|33\\d{2})|1\\d{3}|2(?:1\\d{2}|2(?:[25]\\d?|[348]\\d|[67]\\d{1,2}))|3(?:1\\d{2}(?:\\d{2})?|2(?:[045]\\d|[236-9]\\d{1,2})|32\\d{2})|4(?:[18]\\d{2}|2(?:[2-46]\\d{2}|3)|5[25]\\d{2})|5(?:1\\d{2}|2(?:3\\d|5))|6(?:[18]\\d{2}|2(?:3(?:\\d{2})?|[46]\\d{1,2}|5\\d{2}|7\\d)|5(?:3\\d?|4\\d|[57]\\d{1,2}|6\\d{2}|8))|71\\d{2}|8(?:[18]\\d{2}|23\\d{2}|54\\d{2})|9(?:[18]\\d{2}|2[2-5]\\d{2}|53\\d{1,2}))\\d{3}|5(?:02[03489]\\d{2}|1\\d{2}|2(?:1\\d{2}|2(?:2(?:\\d{2})?|[457]\\d{2}))|3(?:1\\d{2}|2(?:[37](?:\\d{2})?|[569]\\d{2}))|4(?:1\\d{2}|2[46]\\d{2})|5(?:1\\d{2}|26\\d{1,2})|6(?:[18]\\d{2}|2|53\\d{2})|7(?:1|24)\\d{2}|8(?:1|26)\\d{2}|91\\d{2})\\d{3}|6(?:0(?:1\\d{2}|2(?:3\\d{2}|4\\d{1,2}))|2(?:2[2-5]\\d{2}|5(?:[3-5]\\d{2}|7)|8\\d{2})|3(?:1|2[3478])\\d{2}|4(?:1|2[34])\\d{2}|5(?:1|2[47])\\d{2}|6(?:[18]\\d{2}|6(?:2(?:2\\d|[34]\\d{2})|5(?:[24]\\d{2}|3\\d|5\\d{1,2})))|72[2-5]\\d{2}|8(?:1\\d{2}|2[2-5]\\d{2})|9(?:1\\d{2}|2[2-6]\\d{2}))\\d{3}|7(?:(?:02|[3-589]1|6[12]|72[24])\\d{2}|21\\d{3}|32)\\d{3}|8(?:(?:4[12]|[5-7]2|1\\d?)|(?:0|3[12]|[5-7]1|217)\\d)\\d{4}|9(?:[35]1|(?:[024]2|81)\\d|(?:1|[24]1)\\d{2})\\d{3}",
40087,,,"27111234",,,[6,7,8,9]],[,,"(?:1[13-9]\\d|(?:3[78]|44)[02-9]|6(?:44|6[02-9]))\\d{7}",,,,"1812345678",,,[10]],[,,"80[03]\\d{7}",,,,"8001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"96(?:0[49]|1[0-4]|6[69])\\d{6}",,,,"9604123456",,,[10]],"BD",880,"00","0",,,"0",,,,[[,"(2)(\\d{7,8})","$1-$2",["2"],"0$1"],[,"(\\d{2})(\\d{4,6})","$1-$2",["[3-79]1"],"0$1"],[,"(\\d{4})(\\d{3,6})","$1-$2",["1|3(?:0|[2-58]2)|4(?:0|[25]2|3[23]|[4689][25])|5(?:[02-578]2|6[25])|6(?:[0347-9]2|[26][25])|7[02-9]2|8(?:[023][23]|[4-7]2)|9(?:[02][23]|[458]2|6[016])"],
40088"0$1"],[,"(\\d{3})(\\d{3,7})","$1-$2",["[3-79][2-9]|8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BE:[,[,,"[1-9]\\d{7,8}",,,,,,,[8,9]],[,,"(?:1[0-69]|[23][2-8]|4[23]|5\\d|6[013-57-9]|71|8[1-79]|9[2-4])\\d{6}|80[2-8]\\d{5}",,,,"12345678",,,[8]],[,,"4(?:6[0135-8]|[79]\\d|8[3-9])\\d{6}",,,,"470123456",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"(?:70[2-467]|90[0-79])\\d{5}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BE",32,"00","0",,,
40089"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["4[6-9]"],"0$1"],[,"(\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|4[23]|9[2-4]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[156]|7[018]|8(?:0[1-9]|[1-79])"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["(?:80|9)0"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"78\\d{6}",,,,"78123456",,,[8]],,,[,,,,,,,,,[-1]]],BF:[,[,,"[25-7]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:49|5[23]|6[56]|9[016-9])|4(?:4[569]|5[4-6]|6[56]|7[0179])|5(?:[34]\\d|50|6[5-7]))\\d{4}",
40090,,,"20491234"],[,,"(?:5[15-8]|[67]\\d)\\d{6}",,,,"70123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BF",226,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BG:[,[,,"[23567]\\d{5,7}|[489]\\d{6,8}",,,,,,,[6,7,8,9],[4,5]],[,,"2\\d{5,7}|(?:[36]\\d|5[1-9]|8[1-6]|9[1-7])\\d{5,6}|(?:4(?:[124-7]\\d|3[1-6])|7(?:0[1-9]|[1-9]\\d))\\d{4,5}",,,,"2123456",,,[6,7,8],[4,5]],[,,"(?:8[7-9]\\d|9(?:8\\d|9[69]))\\d{6}|4(?:3[0789]|8\\d)\\d{5}",
40091,,,"48123456",,,[8,9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"90\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,"700\\d{5}",,,,"70012345",,,[8]],[,,,,,,,,,[-1]],"BG",359,"00","0",,,"0",,,,[[,"(2)(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4",["2"],"0$1"],[,"(2)(\\d{3})(\\d{3,4})","$1 $2 $3",["2"],"0$1"],[,"(\\d{3})(\\d{4})","$1 $2",["43[124-7]|70[1-9]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3",["43[124-7]|70[1-9]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["[78]00"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3})",
40092"$1 $2 $3",["99[69]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["[356]|4[124-7]|7[1-9]|8[1-6]|9[1-7]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["48|8[7-9]|9[08]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BH:[,[,,"[136-9]\\d{7}",,,,,,,[8]],[,,"(?:1(?:3[1356]|6[0156]|7\\d)\\d|6(?:1[16]\\d|500|6(?:0\\d|3[12]|44|7[7-9])|9[69][69])|7(?:1(?:11|78)|7\\d{2}))\\d{4}",,,,"17001234"],[,,"(?:3(?:[1-4679]\\d|5[013-69]|8[0-47-9])\\d|6(?:3(?:00|33|6[16])|6(?:[69]\\d|3[03-9]|7[0-6])))\\d{4}",
40093,,,"36001234"],[,,"80\\d{6}",,,,"80123456"],[,,"(?:87|9[014578])\\d{6}",,,,"90123456"],[,,"84\\d{6}",,,,"84123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BH",973,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BI:[,[,,"[267]\\d{7}",,,,,,,[8]],[,,"22\\d{6}",,,,"22201234"],[,,"(?:29|6[189]|7[124-9])\\d{6}",,,,"79561234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BI",257,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
40094"$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BJ:[,[,,"[2689]\\d{7}",,,,,,,[8]],[,,"2(?:02|1[037]|2[45]|3[68])\\d{5}",,,,"20211234"],[,,"(?:6[1-8]|9[03-9])\\d{6}",,,,"90011234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"857[58]\\d{4}",,,,"85751234"],"BJ",229,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2689]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"81\\d{6}",,,,"81123456"],,,[,,,,,,,,,[-1]]],BL:[,[,,"[56]\\d{8}",
40095,,,,,,[9]],[,,"590(?:2[7-9]|5[12]|87)\\d{4}",,,,"590271234"],[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BL",590,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BM:[,[,,"[4589]\\d{9}",,,,,,,[10],[7]],[,,"441(?:2(?:02|23|61|[3479]\\d)|[46]\\d{2}|5(?:4\\d|60|89)|824)\\d{4}",,,,"4412345678",,,,[7]],[,,"441(?:[37]\\d|5[0-39])\\d{5}",,,,"4413701234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
40096,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"BM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"441",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BN:[,[,,"[2-578]\\d{6}",,,,,,,[7]],[,,"2(?:[013-9]\\d|2[0-7])\\d{4}|[3-5]\\d{6}",,,,"2345678"],[,,"22[89]\\d{4}|[78]\\d{6}",,,,"7123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BN",673,"00",,,,,,,,[[,"([2-578]\\d{2})(\\d{4})",
40097"$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BO:[,[,,"[23467]\\d{7}|8\\d{8}",,,,,,,[8,9],[7]],[,,"(?:2(?:2\\d{2}|5(?:11|[258]\\d|9[67])|6(?:12|2\\d|9[34])|8(?:2[34]|39|62))|3(?:3\\d{2}|4(?:6\\d|8[24])|8(?:25|42|5[257]|86|9[25])|9(?:2\\d|3[234]|4[248]|5[24]|6[2-6]|7\\d))|4(?:4\\d{2}|6(?:11|[24689]\\d|72)))\\d{4}",,,,"22123456",,,[8],[7]],[,,"[67]\\d{7}",,,,"71234567",,,[8]],[,,"80017\\d{4}",,,,"800171234",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,
40098,,,,,,,[-1]],"BO",591,"00(1\\d)?","0",,,"0(1\\d)?",,,,[[,"([234])(\\d{7})","$1 $2",["[234]"],,"0$CC $1"],[,"([67]\\d{7})","$1",["[67]"],,"0$CC $1"],[,"(800)(\\d{2})(\\d{4})","$1 $2 $3",["800"],,"0$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BQ:[,[,,"[347]\\d{6}",,,,,,,[7]],[,,"(?:318[023]|41(?:6[023]|70)|7(?:1[578]|50)\\d)\\d{3}",,,,"7151234"],[,,"(?:31(?:8[14-8]|9[14578])|416[145-9]|7(?:0[01]|7[07]|8\\d|9[056])\\d)\\d{3}",,,,"3181234"],[,,,,,,,,,[-1]],[,,,,,,,,
40099,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BQ",599,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BR:[,[,,"[1-46-9]\\d{7,10}|5(?:[0-4]\\d{7,9}|5(?:[2-8]\\d{7}|9\\d{7,8}))",,,,,,,[8,9,10,11]],[,,"(?:[14689][1-9]|2[12478]|3[1-578]|5[13-5]|7[13-579])[2-5]\\d{7}",,,,"1123456789",,,[10],[8]],[,,"(?:[189][1-9]|2[12478])(?:7|9\\d)\\d{7}|(?:3[1-578]|[46][1-9]|5[13-5]|7[13-579])(?:[6-8]|9\\d?)\\d{7}",,,,"11961234567",,,[10,11],[8]],[,,"800\\d{6,7}",,,,"800123456",
40100,,[9,10]],[,,"(?:300|[59]00\\d?)\\d{6}",,,,"300123456",,,[9,10]],[,,"(?:300\\d(?:\\d{2})?|40(?:0\\d|20))\\d{4}",,,,"40041234",,,[8,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BR",55,"00(?:1[245]|2[1-35]|31|4[13]|[56]5|99)","0",,,"0(?:(1[245]|2[1-35]|31|4[13]|[56]5|99)(\\d{10,11}))?","$2",,,[[,"(\\d{4})(\\d{4})","$1-$2",["(?:300|40[02])","(?:300|40(?:0|20))"]],[,"([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3",["[3589]00"],"0$1"],[,"(\\d{3,5})","$1",["1[125689]"],"$1"],[,"(\\d{4})(\\d{4})","$1-$2",["[2-9](?:[1-9]|0[1-9])"],
40101"$1"],[,"(\\d{5})(\\d{4})","$1-$2",["9(?:[1-9]|0[1-9])"],"$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3",["[1-9][1-9]"],"($1)","0 $CC ($1)"],[,"(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3",["[1-9][1-9]9"],"($1)","0 $CC ($1)"]],[[,"(\\d{4})(\\d{4})","$1-$2",["(?:300|40[02])","(?:300|40(?:0|20))"]],[,"([3589]00)(\\d{2,3})(\\d{4})","$1 $2 $3",["[3589]00"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2-$3",["[1-9][1-9]"],"($1)","0 $CC ($1)"],[,"(\\d{2})(\\d{5})(\\d{4})","$1 $2-$3",["[1-9][1-9]9"],"($1)","0 $CC ($1)"]],
40102[,,,,,,,,,[-1]],,,[,,"(?:300\\d|40(?:0\\d|20))\\d{4}",,,,"40041234",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BS:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"242(?:3(?:02|[236][1-9]|4[0-24-9]|5[0-68]|7[3467]|8[0-4]|9[2-467])|461|502|6(?:0[1-3]|12|7[67]|8[78]|9[89])|7(?:02|88))\\d{4}",,,,"2423456789",,,,[7]],[,,"242(?:3(?:5[79]|[79]5)|4(?:[2-4][1-9]|5[1-8]|6[2-8]|7\\d|81)|5(?:2[45]|3[35]|44|5[1-9]|65|77)|6[34]6|7(?:27|38)|8(?:0[1-9]|1[02-9]|2\\d|99))\\d{4}",,,,"2423591234",,,,[7]],[,,"242300\\d{4}|8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
40103,,,"8002123456",,,,[7]],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"BS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"242",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BT:[,[,,"[1-8]\\d{6,7}",,,,,,,[7,8],[6]],[,,"(?:2[3-6]|[34][5-7]|5[236]|6[2-46]|7[246]|8[2-4])\\d{5}",,,,"2345678",,,[7],[6]],[,,"(?:1[67]|77)\\d{6}",,,,"17123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40104"BT",975,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1|77"]],[,"([2-8])(\\d{3})(\\d{3})","$1 $2 $3",["[2-68]|7[246]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BW:[,[,,"[2-79]\\d{6,7}",,,,,,,[7,8]],[,,"(?:2(?:4[0-48]|6[0-24]|9[0578])|3(?:1[0-35-9]|55|[69]\\d|7[01])|4(?:6[03]|7[1267]|9[0-5])|5(?:3[0389]|4[0489]|7[1-47]|88|9[0-49])|6(?:2[1-35]|5[149]|8[067]))\\d{4}",,,,"2401234",,,[7]],[,,"7(?:[1-6]\\d|7[014-8])\\d{5}",,,,"71123456",,,[8]],[,,,,,,
40105,,,[-1]],[,,"90\\d{5}",,,,"9012345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"79[12][01]\\d{4}",,,,"79101234",,,[8]],"BW",267,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-6]"]],[,"(7\\d)(\\d{3})(\\d{3})","$1 $2 $3",["7"]],[,"(90)(\\d{5})","$1 $2",["9"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BY:[,[,,"[1-4]\\d{8}|800\\d{3,7}|[89]\\d{9,10}",,,,,,,[6,7,8,9,10,11],[5]],[,,"(?:1(?:5(?:1[1-5]|[24]\\d|6[2-4]|9[1-7])|6(?:[235]\\d|4[1-7])|7\\d{2})|2(?:1(?:[246]\\d|3[0-35-9]|5[1-9])|2(?:[235]\\d|4[0-8])|3(?:[26]\\d|3[02-79]|4[024-7]|5[03-7])))\\d{5}",
40106,,,"152450911",,,[9],[5,6,7]],[,,"(?:2(?:5[5679]|9[1-9])|33\\d|44\\d)\\d{6}",,,,"294911911",,,[9]],[,,"8(?:0[13]|20\\d)\\d{7}|800\\d{3,7}",,,,"8011234567"],[,,"(?:810|902)\\d{7}",,,,"9021234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"249\\d{6}",,,,"249123456",,,[9]],"BY",375,"810","8",,,"8?0?",,"8~10",,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["17[0-3589]|2[4-9]|[34]","17(?:[02358]|1[0-2]|9[0189])|2[4-9]|[34]"],"8 0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4",["1(?:5[24]|6[235]|7[467])|2(?:1[246]|2[25]|3[26])",
40107"1(?:5[24]|6(?:2|3[04-9]|5[0346-9])|7(?:[46]|7[37-9]))|2(?:1[246]|2[25]|3[26])"],"8 0$1"],[,"(\\d{4})(\\d{2})(\\d{3})","$1 $2-$3",["1(?:5[169]|6[3-5]|7[179])|2(?:1[35]|2[34]|3[3-5])","1(?:5[169]|6(?:3[1-3]|4|5[125])|7(?:1[3-9]|7[0-24-6]|9[2-7]))|2(?:1[35]|2[34]|3[3-5])"],"8 0$1"],[,"([89]\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8[01]|9"],"8 $1"],[,"(82\\d)(\\d{4})(\\d{4})","$1 $2 $3",["82"],"8 $1"],[,"(800)(\\d{3})","$1 $2",["800"],"8 $1"],[,"(800)(\\d{2})(\\d{2,4})","$1 $2 $3",["800"],"8 $1"]],,[,,
40108,,,,,,,[-1]],,,[,,"8(?:0[13]|10|20\\d)\\d{7}|800\\d{3,7}|902\\d{7}",,,,"82012345678"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],BZ:[,[,,"[2-8]\\d{6}|0\\d{10}",,,,,,,[7,11]],[,,"(?:2(?:[02]\\d|36)|[3-58][02]\\d|7(?:[02]\\d|32))\\d{4}",,,,"2221234",,,[7]],[,,"6[0-35-7]\\d{5}",,,,"6221234",,,[7]],[,,"0800\\d{7}",,,,"08001234123",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"BZ",501,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[2-8]"]],[,"(0)(800)(\\d{4})(\\d{3})","$1-$2-$3-$4",["0"]]],
40109,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CA:[,[,,"[2-9]\\d{9}|3\\d{6}",,,,,,,[7,10]],[,,"(?:2(?:04|[23]6|[48]9|50)|3(?:06|43|65)|4(?:03|1[68]|3[178]|50)|5(?:06|1[49]|48|79|8[17])|6(?:0[04]|13|22|39|47)|7(?:0[59]|78|8[02])|8(?:[06]7|19|25|73)|90[25])[2-9]\\d{6}|310\\d{4}",,,,"2042345678",,,[10],[7]],[,,"(?:2(?:04|[23]6|[48]9|50)|3(?:06|43|65)|4(?:03|1[68]|3[178]|50)|5(?:06|1[49]|48|79|8[17])|6(?:0[04]|13|22|39|47)|7(?:0[59]|78|8[02])|8(?:[06]7|19|25|73)|90[25])[2-9]\\d{6}",
40110,,,"2042345678",,,[10],[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}|310\\d{4}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456",,,[10]],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678",,,[10]],[,,,,,,,,,[-1]],"CA",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CC:[,[,,"[1458]\\d{5,9}",,,,,,,[6,7,9,10],[8]],[,,"89162\\d{4}",,,,"891621234",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-2]\\d|3[0-57-9]|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",
40111,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"190[0126]\\d{6}",,,,"1900123456",,,[10]],[,,"13(?:00\\d{2})?\\d{4}",,,,"1300123456",,,[6,10]],[,,"500\\d{6}",,,,"500123456",,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"CC",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]","0",,,"0",,"0011",,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CD:[,[,,"[2-6]\\d{6}|[18]\\d{6,8}|9\\d{8}",,,,,,,[7,9]],[,,"1(?:2\\d{7}|\\d{6})|[2-6]\\d{6}",,,,"1234567"],
40112[,,"8(?:[0-2459]\\d{2}|8)\\d{5}|9[017-9]\\d{7}",,,,"991234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CD",243,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["12"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8[0-2459]|9"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["88"],"0$1"],[,"(\\d{2})(\\d{5})","$1 $2",["[1-6]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CF:[,[,,"[278]\\d{7}",,,,,,,[8]],[,,"2[12]\\d{6}",
40113,,,"21612345"],[,,"7[0257]\\d{6}",,,,"70012345"],[,,,,,,,,,[-1]],[,,"8776\\d{4}",,,,"87761234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CF",236,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CG:[,[,,"[028]\\d{8}",,,,,,,[9]],[,,"222[1-589]\\d{5}",,,,"222123456"],[,,"0[14-6]\\d{7}",,,,"061234567"],[,,,,,,,,,[-1]],[,,"80(?:0\\d{2}|11[01])\\d{4}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,
40114[-1]],"CG",242,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["801"]],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[02]"]],[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["800"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CH:[,[,,"[2-9]\\d{8}|860\\d{9}",,,,,,,[9,12]],[,,"(?:2[12467]|3[1-4]|4[134]|5[256]|6[12]|[7-9]1)\\d{7}",,,,"212345678",,,[9]],[,,"7[5-9]\\d{7}",,,,"781234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"90[016]\\d{6}",,,,"900123456",,,[9]],[,
40115,"84[0248]\\d{6}",,,,"840123456",,,[9]],[,,"878\\d{6}",,,,"878123456",,,[9]],[,,,,,,,,,[-1]],"CH",41,"00","0",,,"0",,,,[[,"([2-9]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-7]|[89]1"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8[047]|90"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["860"],"0$1"]],,[,,"74[0248]\\d{6}",,,,"740123456",,,[9]],,,[,,,,,,,,,[-1]],[,,"5[18]\\d{7}",,,,"581234567",,,[9]],,,[,,"860\\d{9}",,,,"860123456789",,,[12]]],CI:[,[,,"[02-8]\\d{7}",
40116,,,,,,[8]],[,,"(?:2(?:0[023]|1[02357]|[23][045]|4[03-5])|3(?:0[06]|1[069]|[2-4][07]|5[09]|6[08]))\\d{5}",,,,"21234567"],[,,"(?:0[1-9]|4\\d|5[14-9]|6[015-79]|[78][4-9])\\d{6}",,,,"01234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CI",225,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CK:[,[,,"[2-8]\\d{4}",,,,,,,[5]],[,,"(?:2\\d|3[13-7]|4[1-5])\\d{3}",,,,"21234"],[,,"[5-8]\\d{4}",
40117,,,"71234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CK",682,"00",,,,,,,,[[,"(\\d{2})(\\d{3})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CL:[,[,,"(?:[2-9]|600|123)\\d{7,8}",,,,,,,[9,10,11],[7,8]],[,,"2(?:1962\\d{4}|2\\d{7}|32[0-467]\\d{5})|(?:3[2-5]|[47][1-35]|5[1-3578]|6[13-57]|9[3-9])\\d{7}",,,,"221234567",,,[9],[7,8]],[,,"2(?:1962\\d{4}|2\\d{7}|32[0-467]\\d{5})|(?:3[2-5]|[47][1-35]|5[1-3578]|6[13-57]|9[3-9])\\d{7}",,
40118,,"961234567",,,[9],[8]],[,,"800\\d{6}|1230\\d{7}",,,,"800123456",,,[9,11]],[,,,,,,,,,[-1]],[,,"600\\d{7,8}",,,,"6001234567",,,[10,11]],[,,,,,,,,,[-1]],[,,"44\\d{7}",,,,"441234567",,,[9]],"CL",56,"(?:0|1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))0","0",,,"0|(1(?:1[0-69]|2[0-57]|5[13-58]|69|7[0167]|8[018]))",,,1,[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["2[23]"],"($1)","$CC ($1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[357]|4[1-35]|6[13-57]"],"($1)","$CC ($1)"],[,"(9)(\\d{4})(\\d{4})","$1 $2 $3",
40119["9"],"0$1"],[,"(44)(\\d{3})(\\d{4})","$1 $2 $3",["44"],"0$1"],[,"([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3",["60|8"],"$1"],[,"(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4",["60"],"$1"],[,"(1230)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"$1"],[,"(\\d{5})(\\d{4})","$1 $2",["219"],"($1)","$CC ($1)"],[,"(\\d{4,5})","$1",["[1-9]"],"$1"]],[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["2[23]"],"($1)","$CC ($1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[357]|4[1-35]|6[13-57]"],"($1)","$CC ($1)"],[,"(9)(\\d{4})(\\d{4})",
40120"$1 $2 $3",["9"],"0$1"],[,"(44)(\\d{3})(\\d{4})","$1 $2 $3",["44"],"0$1"],[,"([68]00)(\\d{3})(\\d{3,4})","$1 $2 $3",["60|8"],"$1"],[,"(600)(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3 $4",["60"],"$1"],[,"(1230)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"$1"],[,"(\\d{5})(\\d{4})","$1 $2",["219"],"($1)","$CC ($1)"]],[,,,,,,,,,[-1]],,,[,,"600\\d{7,8}",,,,"6001234567",,,[10,11]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CM:[,[,,"[2368]\\d{7,8}",,,,,,,[8,9]],[,,"2(?:22|33|4[23])\\d{6}",,,,"222123456",,,[9]],[,,"6[5-9]\\d{7}",
40121,,,"671234567",,,[9]],[,,"88\\d{6}",,,,"88012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CM",237,"00",,,,,,,,[[,"([26])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[26]"]],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|88"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CN:[,[,,"[1-7]\\d{6,11}|8[0-357-9]\\d{6,9}|9\\d{7,10}",,,,,,,[7,8,9,10,11,12],[5,6]],[,,"21(?:100\\d{2}|95\\d{3,4}|\\d{8,10})|(?:10|2[02-57-9]|3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1\\d|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98))(?:100\\d{2}|95\\d{3,4}|\\d{8})|(?:3(?:1[02-9]|35|49|5\\d|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|3[3-9]|5[2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[17]\\d|2[248]|3[04-9]|4[3-6]|5[0-4689]|6[2368]|9[02-9])|8(?:078|1[236-8]|2[5-7]|3\\d|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]\\d|4[13]|5[1-5]))(?:100\\d{2}|95\\d{3,4}|\\d{7})|80(?:29|6[03578]|7[018]|81)\\d{4}",
40122,,,"1012345678",,,,[5,6]],[,,"1(?:[38]\\d|4[57]|5[0-35-9]|7[0-35-8])\\d{8}",,,,"13123456789",,,[11]],[,,"(?:10)?800\\d{7}",,,,"8001234567",,,[10,12]],[,,"16[08]\\d{5}",,,,"16812345",,,[8]],[,,"400\\d{7}|950\\d{7,8}|(?:10|2[0-57-9]|3(?:[157]\\d|35|49|9[1-68])|4(?:[17]\\d|2[179]|[35][1-9]|6[4789]|8[23])|5(?:[1357]\\d|2[37]|4[36]|6[1-46]|80|9[1-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]\\d|2[248]|3[014-9]|4[3-6]|6[023689])|8(?:1[236-8]|2[5-7]|[37]\\d|5[14-9]|8[3678]|9[1-8])|9(?:0[1-3689]|1[1-79]|[379]\\d|4[13]|5[1-5]))96\\d{3,4}",
40123,,,"4001234567",,,[7,8,9,10,11],[5,6]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CN",86,"(1(?:[129]\\d{3}|79\\d{2}))?00","0",,,"(1(?:[129]\\d{3}|79\\d{2}))|0",,"00",,[[,"(80\\d{2})(\\d{4})","$1 $2",["80[2678]"],"0$1","$CC $1",1],[,"([48]00)(\\d{3})(\\d{4})","$1 $2 $3",["[48]00"]],[,"(\\d{5,6})","$1",["100|95"]],[,"(\\d{2})(\\d{5,6})","$1 $2",["(?:10|2\\d)[19]","(?:10|2\\d)(?:10|9[56])","(?:10|2\\d)(?:100|9[56])"],"0$1","$CC $1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["[3-9]","[3-9]\\d{2}[19]","[3-9]\\d{2}(?:10|9[56])"],
40124"0$1","$CC $1"],[,"(\\d{3,4})(\\d{4})","$1 $2",["[2-9]"]],[,"(21)(\\d{4})(\\d{4,6})","$1 $2 $3",["21"],"0$1","$CC $1",1],[,"([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["10[1-9]|2[02-9]","10[1-9]|2[02-9]","10(?:[1-79]|8(?:[1-9]|0[1-9]))|2[02-9]"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])"],
40125"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98)"],"0$1","$CC $1",1],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["807","8078"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["1[3-578]"],,"$CC $1"],[,"(10800)(\\d{3})(\\d{4})","$1 $2 $3",["108","1080","10800"]],[,"(\\d{3})(\\d{7,8})","$1 $2",["950"]]],[[,"(80\\d{2})(\\d{4})","$1 $2",["80[2678]"],"0$1","$CC $1",1],[,"([48]00)(\\d{3})(\\d{4})",
40126"$1 $2 $3",["[48]00"]],[,"(\\d{2})(\\d{5,6})","$1 $2",["(?:10|2\\d)[19]","(?:10|2\\d)(?:10|9[56])","(?:10|2\\d)(?:100|9[56])"],"0$1","$CC $1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["[3-9]","[3-9]\\d{2}[19]","[3-9]\\d{2}(?:10|9[56])"],"0$1","$CC $1"],[,"(21)(\\d{4})(\\d{4,6})","$1 $2 $3",["21"],"0$1","$CC $1",1],[,"([12]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["10[1-9]|2[02-9]","10[1-9]|2[02-9]","10(?:[1-79]|8(?:[1-9]|0[1-9]))|2[02-9]"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["3(?:1[02-9]|35|49|5|7[02-68]|9[1-68])|4(?:1[02-9]|2[179]|[35][2-9]|6[4789]|7\\d|8[23])|5(?:3[03-9]|4[36]|5[02-9]|6[1-46]|7[028]|80|9[2-46-9])|6(?:3[1-5]|6[0238]|9[12])|7(?:01|[1579]|2[248]|3[04-9]|4[3-6]|6[2368])|8(?:1[236-8]|2[5-7]|3|5[1-9]|7[02-9]|8[3678]|9[1-7])|9(?:0[1-3689]|1[1-79]|[379]|4[13]|5[1-5])"],
40127"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3(?:11|7[179])|4(?:[15]1|3[1-35])|5(?:1|2[37]|3[12]|51|7[13-79]|9[15])|7(?:31|5[457]|6[09]|91)|8(?:[57]1|98)"],"0$1","$CC $1",1],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["807","8078"],"0$1","$CC $1",1],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["1[3-578]"],,"$CC $1"],[,"(10800)(\\d{3})(\\d{4})","$1 $2 $3",["108","1080","10800"]],[,"(\\d{3})(\\d{7,8})","$1 $2",["950"]]],[,,,,,,,,,[-1]],,,[,,"(?:4|(?:10)?8)00\\d{7}|950\\d{7,8}",,,,"4001234567",
40128,,[10,11,12]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CO:[,[,,"(?:[13]\\d{0,3}|[24-8])\\d{7}",,,,,,,[8,10,11],[7]],[,,"[124-8][2-9]\\d{6}",,,,"12345678",,,[8],[7]],[,,"3(?:0[0-5]|1\\d|2[0-3]|5[01])\\d{7}",,,,"3211234567",,,[10]],[,,"1800\\d{7}",,,,"18001234567",,,[11]],[,,"19(?:0[01]|4[78])\\d{7}",,,,"19001234567",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CO",57,"00(?:4(?:[14]4|56)|[579])","0",,,"0([3579]|4(?:44|56))?",,,,[[,"(\\d)(\\d{7})","$1 $2",["1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","1(?:8[2-9]|9(?:09|[1-3])|[2-7])|[24-8]"],
40129"($1)","0$CC $1"],[,"(\\d{3})(\\d{7})","$1 $2",["3"],,"0$CC $1"],[,"(1)(\\d{3})(\\d{7})","$1-$2-$3",["1(?:80|9[04])","1(?:800|9(?:0[01]|4[78]))"],"0$1"]],[[,"(\\d)(\\d{7})","$1 $2",["1(?:8[2-9]|9[0-3]|[2-7])|[24-8]","1(?:8[2-9]|9(?:09|[1-3])|[2-7])|[24-8]"],"($1)","0$CC $1"],[,"(\\d{3})(\\d{7})","$1 $2",["3"],,"0$CC $1"],[,"(1)(\\d{3})(\\d{7})","$1 $2 $3",["1(?:80|9[04])","1(?:800|9(?:0[01]|4[78]))"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CR:[,[,,"[24-9]\\d{7,9}",,
40130,,,,,[8,10]],[,,"2[0-24-7]\\d{6}",,,,"22123456",,,[8]],[,,"5(?:0[01]|7[0-3])\\d{5}|6(?:[0-4]\\d{3}|500[01])\\d{3}|(?:7[0-3]|8[3-9])\\d{6}",,,,"83123456",,,[8]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"90[059]\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"210[0-6]\\d{4}|4\\d{7}|5100\\d{4}",,,,"40001234",,,[8]],"CR",506,"00",,,,"(19(?:0[012468]|1[09]|20|66|77|99))",,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[24-7]|8[3-9]"],,"$CC $1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["[89]0"],
40131,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CU:[,[,,"[2-57]\\d{5,7}",,,,,,,[6,7,8],[4,5]],[,,"2[1-4]\\d{5,6}|3(?:1\\d{6}|[23]\\d{4,6})|4(?:[125]\\d{5,6}|[36]\\d{6}|[78]\\d{4,6})|7\\d{6,7}",,,,"71234567",,,,[4,5]],[,,"5\\d{7}",,,,"51234567",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CU",53,"119","0",,,"0",,,,[[,"(\\d)(\\d{6,7})","$1 $2",["7"],"(0$1)"],[,"(\\d{2})(\\d{4,6})","$1 $2",["[2-4]"],"(0$1)"],[,"(\\d)(\\d{7})",
40132"$1 $2",["5"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CV:[,[,,"[259]\\d{6}",,,,,,,[7]],[,,"2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\\d|7[1-3]|8[1-5])\\d{4}",,,,"2211234"],[,,"(?:9\\d|59)\\d{5}",,,,"9911234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CV",238,"0",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CW:[,[,,"[169]\\d{6,7}",,,,,,,[7,8]],[,,"9(?:[48]\\d{2}|50\\d|7(?:2[0-24]|[34]\\d|6[35-7]|77|8[7-9]))\\d{4}",
40133,,,"94151234",,,[8]],[,,"9(?:5(?:[12467]\\d|3[01])|6(?:[15-9]\\d|3[01]))\\d{4}",,,,"95181234",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"60[0-2]\\d{4}",,,,"6001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"CW",599,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[13-7]"]],[,"(9)(\\d{3})(\\d{4})","$1 $2 $3",["9"]]],,[,,"955\\d{5}",,,,"95581234",,,[8]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CX:[,[,,"[1458]\\d{5,9}",,,,,,,[6,7,8,9,10]],[,,"89164\\d{4}",,,,"891641234",,,[9],[8]],[,,"14(?:5\\d|71)\\d{5}|4(?:[0-2]\\d|3[0-57-9]|4[47-9]|5[0-25-9]|6[6-9]|7[02-9]|8[147-9]|9[017-9])\\d{6}",
40134,,,"412345678",,,[9]],[,,"180(?:0\\d{3}|2)\\d{3}",,,,"1800123456",,,[7,10]],[,,"190[0126]\\d{6}",,,,"1900123456",,,[10]],[,,"13(?:00\\d{2})?\\d{4}",,,,"1300123456",,,[6,8,10]],[,,"500\\d{6}",,,,"500123456",,,[9]],[,,"550\\d{6}",,,,"550123456",,,[9]],"CX",61,"(?:14(?:1[14]|34|4[17]|[56]6|7[47]|88))?001[14-689]","0",,,"0",,"0011",,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],CY:[,[,,"[257-9]\\d{7}",,,,,,,[8]],[,,"2[2-6]\\d{6}",,,,"22345678"],[,,"9[4-79]\\d{6}",,,,"96123456"],
40135[,,"800\\d{5}",,,,"80001234"],[,,"90[09]\\d{5}",,,,"90012345"],[,,"80[1-9]\\d{5}",,,,"80112345"],[,,"700\\d{5}",,,,"70012345"],[,,,,,,,,,[-1]],"CY",357,"00",,,,,,,,[[,"(\\d{2})(\\d{6})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:50|77)\\d{6}",,,,"77123456"],,,[,,,,,,,,,[-1]]],CZ:[,[,,"[2-8]\\d{8}|9\\d{8,11}",,,,,,,[9,10,11,12]],[,,"2\\d{8}|(?:3[1257-9]|4[16-9]|5[13-9])\\d{7}",,,,"212345678",,,[9]],[,,"(?:60[1-8]|7(?:0[2-5]|[2379]\\d))\\d{6}",,,,"601123456",,,[9]],[,,"800\\d{6}",,,,"800123456",
40136,,[9]],[,,"9(?:0[05689]|76)\\d{6}",,,,"900123456",,,[9]],[,,"8[134]\\d{7}",,,,"811234567",,,[9]],[,,"70[01]\\d{6}",,,,"700123456",,,[9]],[,,"9[17]0\\d{6}",,,,"910123456",,,[9]],"CZ",420,"00",,,,,,,,[[,"([2-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8]|9[015-7]"]],[,"(96\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["96"]],[,"(9\\d)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["9[36]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"9(?:5\\d|7[234])\\d{6}",,,,"972123456",,,[9]],,,[,,"9(?:3\\d{9}|6\\d{7,10})",,,
40137,"93123456789"]],DE:[,[,,"[1-35-9]\\d{3,14}|4(?:[0-8]\\d{3,12}|9(?:[0-37]\\d|4(?:[1-35-8]|4\\d?)|5\\d{1,2}|6[1-8]\\d?)\\d{2,8})",,,,,,,[4,5,6,7,8,9,10,11,12,13,14,15],[3]],[,,"2\\d{5,13}|3(?:0\\d{3,13}|2\\d{9}|[3-9]\\d{4,13})|4(?:0\\d{3,12}|\\d{5,13})|5(?:0[2-8]|[1256]\\d|[38][0-8]|4\\d{0,2}|[79][0-7])\\d{3,11}|6(?:\\d{5,13}|9\\d{3,12})|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-8]\\d|9\\d?)\\d{3,10}|9(?:0[6-9]\\d{3,10}|1\\d{4,12}|[2-9]\\d{4,11})",,,,"30123456",,,[5,6,7,8,9,10,11,12,13,14,15],[3,
401384]],[,,"1(?:5[0-25-9]\\d{8}|6[023]\\d{7,8}|7\\d{8,9})",,,,"15123456789",,,[10,11]],[,,"800\\d{7,12}",,,,"8001234567890",,,[10,11,12,13,14,15]],[,,"137[7-9]\\d{6}|900(?:[135]\\d{6}|9\\d{7})",,,,"9001234567",,,[10,11]],[,,"1(?:3(?:7[1-6]\\d{6}|8\\d{4})|80\\d{5,11})",,,,"18012345",,,[7,8,9,10,11,12,13,14]],[,,"700\\d{8}",,,,"70012345678",,,[11]],[,,,,,,,,,[-1]],"DE",49,"00","0",,,"0",,,,[[,"(1\\d{2})(\\d{7,8})","$1 $2",["1[67]"],"0$1"],[,"(15\\d{3})(\\d{6})","$1 $2",["15[0568]"],"0$1"],[,"(1\\d{3})(\\d{7})",
40139"$1 $2",["15"],"0$1"],[,"(\\d{2})(\\d{3,11})","$1 $2",["3[02]|40|[68]9"],"0$1"],[,"(\\d{3})(\\d{3,11})","$1 $2",["2(?:\\d1|0[2389]|1[24]|28|34)|3(?:[3-9][15]|40)|[4-8][1-9]1|9(?:06|[1-9]1)"],"0$1"],[,"(\\d{4})(\\d{2,11})","$1 $2",["[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:[3569][02-46-9]|4[2-4679]|7[2-467]|8[2-46-8])","[24-6]|[7-9](?:\\d[1-9]|[1-9]\\d)|3(?:3(?:0[1-467]|2[127-9]|3[124578]|[46][1246]|7[1257-9]|8[1256]|9[145])|4(?:2[135]|3[1357]|4[13578]|6[1246]|7[1356]|9[1346])|5(?:0[14]|2[1-3589]|3[1357]|4[1246]|6[1-4]|7[1346]|8[13568]|9[1246])|6(?:0[356]|2[1-489]|3[124-6]|4[1347]|6[13]|7[12579]|8[1-356]|9[135])|7(?:2[1-7]|3[1357]|4[145]|6[1-5]|7[1-4])|8(?:21|3[1468]|4[1347]|6[0135-9]|7[1467]|8[136])|9(?:0[12479]|2[1358]|3[1357]|4[134679]|6[1-9]|7[136]|8[147]|9[1468]))"],
40140"0$1"],[,"(3\\d{4})(\\d{1,10})","$1 $2",["3"],"0$1"],[,"(800)(\\d{7,12})","$1 $2",["800"],"0$1"],[,"(\\d{3})(\\d)(\\d{4,10})","$1 $2 $3",["(?:18|90)0|137","1(?:37|80)|900[1359]"],"0$1"],[,"(1\\d{2})(\\d{5,11})","$1 $2",["181"],"0$1"],[,"(18\\d{3})(\\d{6})","$1 $2",["185","1850","18500"],"0$1"],[,"(18\\d{2})(\\d{7})","$1 $2",["18[68]"],"0$1"],[,"(18\\d)(\\d{8})","$1 $2",["18[2-579]"],"0$1"],[,"(700)(\\d{4})(\\d{4})","$1 $2 $3",["700"],"0$1"],[,"(138)(\\d{4})","$1 $2",["138"],"0$1"],[,"(15[013-68])(\\d{2})(\\d{8})",
40141"$1 $2 $3",["15[013-68]"],"0$1"],[,"(15[279]\\d)(\\d{2})(\\d{7})","$1 $2 $3",["15[279]"],"0$1"],[,"(1[67]\\d)(\\d{2})(\\d{7,8})","$1 $2 $3",["1(?:6[023]|7)"],"0$1"]],,[,,"16(?:4\\d{1,10}|[89]\\d{1,11})",,,,"16412345",,,[4,5,6,7,8,9,10,11,12,13,14]],,,[,,,,,,,,,[-1]],[,,"18(?:1\\d{5,11}|[2-9]\\d{8})",,,,"18500123456",,,[8,9,10,11,12,13,14]],,,[,,"1(?:5(?:(?:2\\d55|7\\d99|9\\d33)\\d{7}|(?:[034568]00|113)\\d{8})|6(?:013|255|399)\\d{7,8}|7(?:[015]13|[234]55|[69]33|[78]99)\\d{7,8})",,,,"177991234567",
40142,,[12,13]]],DJ:[,[,,"[27]\\d{7}",,,,,,,[8]],[,,"2(?:1[2-5]|7[45])\\d{5}",,,,"21360003"],[,,"77\\d{6}",,,,"77831001"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"DJ",253,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DK:[,[,,"[2-9]\\d{7}",,,,,,,[8]],[,,"(?:[2-7]\\d|8[126-9]|9[1-36-9])\\d{6}",,,,"32123456"],[,,"(?:[2-7]\\d|8[126-9]|9[1-36-9])\\d{6}",,,,"20123456"],[,,"80\\d{6}",
40143,,,"80123456"],[,,"90\\d{6}",,,,"90123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"DK",45,"00",,,,,,,1,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DM:[,[,,"[57-9]\\d{9}",,,,,,,[10],[7]],[,,"767(?:2(?:55|66)|4(?:2[01]|4[0-25-9])|50[0-4]|70[1-3])\\d{4}",,,,"7674201234",,,,[7]],[,,"767(?:2(?:[234689]5|7[5-7])|31[5-7]|61[1-7])\\d{4}",,,,"7672251234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],
40144[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"DM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"767",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DO:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"8(?:[04]9[2-9]\\d{6}|29(?:2(?:[0-59]\\d|6[04-9]|7[0-27]|8[0237-9])|3(?:[0-35-9]\\d|4[7-9])|[45]\\d{2}|6(?:[0-27-9]\\d|[3-5][1-9]|6[0135-8])|7(?:0[013-9]|[1-37]\\d|4[1-35689]|5[1-4689]|6[1-57-9]|8[1-79]|9[1-8])|8(?:0[146-9]|1[0-48]|[248]\\d|3[1-79]|5[01589]|6[013-68]|7[124-8]|9[0-8])|9(?:[0-24]\\d|3[02-46-9]|5[0-79]|60|7[0169]|8[57-9]|9[02-9]))\\d{4})",
40145,,,"8092345678",,,,[7]],[,,"8[024]9[2-9]\\d{6}",,,,"8092345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"DO",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"8[024]9",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],DZ:[,[,,"(?:[1-4]|[5-9]\\d)\\d{7}",,,,,,,[8,9]],[,,"(?:1\\d|2[013-79]|3[0-8]|4[0135689])\\d{6}|9619\\d{5}",,,,"12345678"],[,,"(?:5[4-6]|7[7-9])\\d{7}|6(?:[569]\\d|7[0-6])\\d{6}",
40146,,,"551234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"80[3-689]1\\d{5}",,,,"808123456",,,[9]],[,,"80[12]1\\d{5}",,,,"801123456",,,[9]],[,,,,,,,,,[-1]],[,,"98[23]\\d{6}",,,,"983123456",,,[9]],"DZ",213,"00","0",,,"0",,,,[[,"([1-4]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[1-4]"],"0$1"],[,"([5-8]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-8]"],"0$1"],[,"(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
40147EC:[,[,,"1\\d{9,10}|[2-8]\\d{7}|9\\d{8}",,,,,,,[8,9,10,11],[7]],[,,"[2-7][2-7]\\d{6}",,,,"22123456",,,[8],[7]],[,,"9(?:(?:39|[45][89]|7[7-9]|[89]\\d)\\d|6(?:[017-9]\\d|2[0-4]))\\d{5}",,,,"991234567",,,[9]],[,,"1800\\d{6,7}",,,,"18001234567",,,[10,11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"[2-7]890\\d{4}",,,,"28901234",,,[8]],"EC",593,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2-$3",["[247]|[356][2-8]"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["9"],"0$1"],[,"(1800)(\\d{3})(\\d{3,4})",
40148"$1 $2 $3",["1"],"$1"]],[[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[247]|[356][2-8]"]],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["9"],"0$1"],[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"],"$1"]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EE:[,[,,"[3-9]\\d{6,7}|800\\d{6,7}",,,,,,,[7,8,10]],[,,"(?:3[23589]|4[3-8]|6\\d|7[1-9]|88)\\d{5}",,,,"3212345",,,[7]],[,,"(?:5\\d|8[1-5])\\d{6}|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])\\d{3}",,,,"51234567",,,[7,8]],[,,"800(?:0\\d{3}|1\\d|[2-9])\\d{3}",
40149,,,"80012345"],[,,"(?:40\\d{2}|900)\\d{4}",,,,"9001234",,,[7,8]],[,,,,,,,,,[-1]],[,,"70[0-2]\\d{5}",,,,"70012345",,,[8]],[,,,,,,,,,[-1]],"EE",372,"00",,,,,,,,[[,"([3-79]\\d{2})(\\d{4})","$1 $2",["[369]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])|7[1-9]","[369]|4[3-8]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))|7[1-9]"]],[,"(70)(\\d{2})(\\d{4})","$1 $2 $3",["70"]],[,"(8000)(\\d{3})(\\d{3})","$1 $2 $3",["800","8000"]],[,"([458]\\d{3})(\\d{3,4})","$1 $2",["40|5|8(?:00|[1-5])","40|5|8(?:00[1-9]|[1-5])"]]],
40150,[,,,,,,,,,[-1]],,,[,,"800[2-9]\\d{3}",,,,"8002123",,,[7]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EG:[,[,,"1\\d{4,9}|[2456]\\d{8}|3\\d{7}|[89]\\d{8,9}",,,,,,,[8,9,10],[7]],[,,"(?:1(?:3[23]\\d|5(?:[23]|9\\d))|2[2-4]\\d{2}|3\\d{2}|4(?:0[2-5]|[578][23]|64)\\d|5(?:0[2-7]|[57][23])\\d|6[24-689]3\\d|8(?:2[2-57]|4[26]|6[237]|8[2-4])\\d|9(?:2[27]|3[24]|52|6[2356]|7[2-4])\\d)\\d{5}",,,,"234567890",,,[8,9],[7]],[,,"1(?:0[0-269]|1[0-245]|2[0-278]|55)\\d{7}",,,,"1001234567",,,[10]],[,,"800\\d{7}",,,,"8001234567",
40151,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"EG",20,"00","0",,,"0",,,,[[,"(\\d)(\\d{7,8})","$1 $2",["[23]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1[012]|[89]00"],"0$1"],[,"(\\d{2})(\\d{6,7})","$1 $2",["1[35]|[4-6]|[89][2-9]"],"0$1"],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["155"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],EH:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"528[89]\\d{5}",,,,"528812345"],[,,"(?:6(?:[0-79]\\d|8[0-247-9])|7(?:[07][07]|6[12]))\\d{6}",
40152,,,"650123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89\\d{7}",,,,"891234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5924[01]\\d{4}",,,,"592401234"],"EH",212,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,"528[89]",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ER:[,[,,"[178]\\d{6}",,,,,,,[7],[6]],[,,"1(?:1[12568]|20|40|55|6[146])\\d{4}|8\\d{6}",,,,"8370362",,,,[6]],[,,"17[1-3]\\d{4}|7\\d{6}",,,,"7123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ER",291,"00","0",,,"0",
40153,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ES:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"8(?:[1356]\\d|[28][0-8]|[47][1-9])\\d{6}|9(?:[135]\\d{7}|[28][0-8]\\d{6}|4[1-9]\\d{6}|6(?:[0-8]\\d{6}|9(?:0(?:[0-57-9]\\d{4}|6(?:0[0-8]|1[1-9]|[2-9]\\d)\\d{2})|[1-9]\\d{5}))|7(?:[124-9]\\d{2}|3(?:[0-8]\\d|9[1-9]))\\d{4})",,,,"810123456"],[,,"(?:6\\d{6}|7[1-48]\\d{5}|9(?:6906(?:09|10)|7390\\d{2}))\\d{2}",,,,"612345678"],[,,"[89]00\\d{6}",,,,"800123456"],
40154[,,"80[367]\\d{6}",,,,"803123456"],[,,"90[12]\\d{6}",,,,"901123456"],[,,"70\\d{7}",,,,"701234567"],[,,,,,,,,,[-1]],"ES",34,"00",,,,,,,,[[,"([89]00)(\\d{3})(\\d{3})","$1 $2 $3",["[89]00"]],[,"([5-9]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[568]|[79][0-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"51\\d{7}",,,,"511234567"],,,[,,,,,,,,,[-1]]],ET:[,[,,"[1-59]\\d{8}",,,,,,,[9],[7]],[,,"(?:11(?:1(?:1[124]|2[2-57]|3[1-5]|5[5-8]|8[6-8])|2(?:13|3[6-8]|5[89]|7[05-9]|8[2-6])|3(?:2[01]|3[0-289]|4[1289]|7[1-4]|87)|4(?:1[69]|3[2-49]|4[0-3]|6[5-8])|5(?:1[578]|44|5[0-4])|6(?:18|2[69]|39|4[5-7]|5[1-5]|6[0-59]|8[015-8]))|2(?:2(?:11[1-9]|22[0-7]|33\\d|44[1467]|66[1-68])|5(?:11[124-6]|33[2-8]|44[1467]|55[14]|66[1-3679]|77[124-79]|880))|3(?:3(?:11[0-46-8]|22[0-6]|33[0134689]|44[04]|55[0-6]|66[01467])|4(?:44[0-8]|55[0-69]|66[0-3]|77[1-5]))|4(?:6(?:22[0-24-7]|33[1-5]|44[13-69]|55[14-689]|660|88[1-4])|7(?:11[1-9]|22[1-9]|33[13-7]|44[13-6]|55[1-689]))|5(?:7(?:227|55[05]|(?:66|77)[14-8])|8(?:11[149]|22[013-79]|33[0-68]|44[013-8]|550|66[1-5]|77\\d)))\\d{4}",
40155,,,"111112345",,,,[7]],[,,"9(?:[1-46-8]\\d|5[89])\\d{6}",,,,"911234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ET",251,"00","0",,,"0",,,,[[,"([1-59]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FI:[,[,,"[16]\\d{6,9}|2\\d{4,9}|[35]\\d{5,9}|4\\d{7,10}|7\\d{7,9}|[89]\\d{6,8}",,,,,,,[5,6,7,8,9,10,11]],[,,"1[3-79][1-8]\\d{4,6}|[235689][1-8]\\d{5,7}",,,,"131234567",,,[7,8,9]],[,,"4(?:[0-8]\\d{6,8}|9\\d{9})|50\\d{4,8}",
40156,,,"412345678",,,[6,7,8,9,10,11]],[,,"800\\d{5,6}",,,,"800123456",,,[8,9]],[,,"[67]00\\d{5,6}",,,,"600123456",,,[8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FI",358,"00|99(?:[02469]|5(?:11|33|5[59]|88|9[09]))","0",,,"0",,"00",,[[,"(\\d{3})(\\d{3,7})","$1 $2",["(?:[1-3]00|[6-8]0)"],"0$1"],[,"(116\\d{3})","$1",["116"],"$1"],[,"(\\d{2})(\\d{3,9})","$1 $2",["1(?:0[1-9]|[3-9])|2(?:0[1-9]|9)|30[1-9]|4|50|7(?:[13]|5[03-9])"],"0$1"],[,"(75\\d{3})","$1",["75[12]"],"0$1"],[,"(\\d)(\\d{5,9})","$1 $2",
40157["[235689][1-8]"],"0$1"],[,"(39\\d)(\\d{3})(\\d{3})","$1 $2 $3",["39"],"0$1"]],[[,"(\\d{3})(\\d{3,7})","$1 $2",["(?:[1-3]00|[6-8]0)"],"0$1"],[,"(116\\d{3})","$1",["116"],"$1"],[,"(\\d{2})(\\d{3,9})","$1 $2",["1(?:0[1-9]|[3-9])|2(?:0[1-9]|9)|30[1-9]|4|50|7(?:[13]|5[03-9])"],"0$1"],[,"(\\d)(\\d{5,9})","$1 $2",["[235689][1-8]"],"0$1"],[,"(39\\d)(\\d{3})(\\d{3})","$1 $2 $3",["39"],"0$1"]],[,,,,,,,,,[-1]],1,,[,,"100\\d{4,6}|20(?:0\\d{4,6}|2[023]\\d{4,5}|9[89]\\d{1,6})|300\\d{3,7}|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",
40158,,,"1001234",,,[5,6,7,8,9,10]],[,,"10(?:0\\d{4,6}|[1-9]\\d{5,7})|2(?:0(?:0\\d{4,6}|[13-8]\\d{5,7}|2(?:[023]\\d{4,5}|[14-9]\\d{4,6})|9(?:[0-7]\\d{4,6}|[89]\\d{1,6}))|9\\d{5,8})|3(?:0(?:0\\d{3,7}|[1-57-9]\\d{5,7}|6(?:\\d{3}|\\d{5,7}))|93\\d{5,7})|60(?:[12]\\d{5,6}|6\\d{7})|7(?:1\\d{7}|3\\d{8}|5[03-9]\\d{5,6})",,,,"10112345",,,[5,6,7,8,9,10]],,,[,,,,,,,,,[-1]]],FJ:[,[,,"[35-9]\\d{6}|0\\d{10}",,,,,,,[7,11]],[,,"(?:3[0-5]|6[25-7]|8[58])\\d{5}",,,,"3212345",,,[7]],[,,"(?:5[018]|[79]\\d|8[034679])\\d{5}",
40159,,,"7012345",,,[7]],[,,"0800\\d{7}",,,,"08001234567",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FJ",679,"0(?:0|52)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[35-9]"]],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FK:[,[,,"[2-7]\\d{4}",,,,,,,[5]],[,,"[2-47]\\d{4}",,,,"31234"],[,,"[56]\\d{4}",,,,"51234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FK",500,"00",
40160,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FM:[,[,,"[39]\\d{6}",,,,,,,[7]],[,,"3[2357]0[1-9]\\d{3}|9[2-6]\\d{5}",,,,"3201234"],[,,"3[2357]0[1-9]\\d{3}|9[2-7]\\d{5}",,,,"3501234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"FM",691,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FO:[,[,,"[2-9]\\d{5}",,,,,,,[6]],[,,"(?:20|[3-4]\\d|8[19])\\d{4}",,,,"201234"],[,,"(?:[27][1-9]|5\\d)\\d{4}",
40161,,,"211234"],[,,"80[257-9]\\d{3}",,,,"802123"],[,,"90(?:[1345][15-7]|2[125-7]|99)\\d{2}",,,,"901123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:6[0-36]|88)\\d{4}",,,,"601234"],"FO",298,"00",,,,"(10(?:01|[12]0|88))",,,,[[,"(\\d{6})","$1",,,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],FR:[,[,,"[1-9]\\d{8}",,,,,,,[9]],[,,"[1-5]\\d{8}",,,,"123456789"],[,,"(?:6\\d|7[3-9])\\d{7}",,,,"612345678"],[,,"80[0-5]\\d{6}",,,,"801234567"],[,,"89[1-37-9]\\d{6}",,,,"891123456"],[,
40162,"8(?:1[0-29]|2[0156]|84|90)\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,"9\\d{8}",,,,"912345678"],"FR",33,"00","0",,,"0",,,,[[,"([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[1-79]"],"0$1"],[,"(1\\d{2})(\\d{3})","$1 $2",["11"],"$1"],[,"(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"],"0 $1"]],[[,"([1-79])(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["[1-79]"],"0$1"],[,"(8\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"],"0 $1"]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"80[6-9]\\d{6}",
40163,,,"806123456"],,,[,,,,,,,,,[-1]]],GA:[,[,,"0?\\d{7}",,,,,,,[7,8]],[,,"01\\d{6}",,,,"01441234",,,[8]],[,,"0?[2-7]\\d{6}",,,,"06031234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GA",241,"00",,,,,,,,[[,"(\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-7]"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GB:[,[,,"\\d{7,10}",,,,,,,[7,9,10],[4,5,6,8]],[,,"2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[0-2])\\d{7}|1(?:1(?:3[0-48]|[46][0-4]|5[0-26-9]|[78][0-49])|21[0-7]|31[0-8]|[4-69]1\\d)\\d{6}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-47-9]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1-35-79]|9[2-578])|4(?:0[03-9]|[28][02-57-9]|[37]\\d|4[02-69]|5[0-8]|[69][0-79])|5(?:0[1-35-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-57-9])|6(?:0[034689]|2[0-35689]|[38][013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|9[0124578])|7(?:0[0246-9]|2\\d|3[0236-8]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-57-9]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-57-9]|4[2-9]|5[0-579]|6[2-47-9]|7[0-24578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-47-9]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[0157-9]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[2-46-8]\\d{2}|16977[23]\\d{3}",
40164,,,"1212345678",,,[9,10],[4,5,6,7,8]],[,,"7(?:[1-3]\\d{3}|4(?:[0-46-9]\\d{2}|5(?:[0-689]\\d|7[0-57-9]))|5(?:0[0-8]|[13-9]\\d|2[0-35-9])\\d|7(?:0(?:0[01]|[1-9]\\d)|[1-7]\\d{2}|8[02-9]\\d|9[0-689]\\d)|8(?:[014-9]\\d|[23][0-8])\\d|9(?:[024-9]\\d{2}|1(?:[02-9]\\d|1[028])|3[0-689]\\d))\\d{5}",,,,"7400123456",,,[10]],[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}",,,,"8001234567"],[,,"(?:87[123]|9(?:[01]\\d|8[2349]))\\d{7}",,,,"9012345678",,,[10]],[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})",,,,"8431234567",
40165,,[7,10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],[,,"56\\d{8}",,,,"5612345678",,,[10]],"GB",44,"00","0"," x",,"0",,,,[[,"(7\\d{3})(\\d{6})","$1 $2",["7(?:[1-57-9]|62)","7(?:[1-57-9]|624)"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["2|5[56]|7[06]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1(?:1|\\d1)|3|9[018]"],"0$1"],[,"(\\d{5})(\\d{4,5})","$1 $2",["1(?:38|5[23]|69|76|94)","1(?:387|5(?:24|39)|697|768|946)","1(?:3873|5(?:242|39[456])|697[347]|768[347]|9467)"],"0$1"],[,"(1\\d{3})(\\d{5,6})",
40166"$1 $2",["1"],"0$1"],[,"(800)(\\d{4})","$1 $2",["800","8001","80011","800111","8001111"],"0$1"],[,"(845)(46)(4\\d)","$1 $2 $3",["845","8454","84546","845464"],"0$1"],[,"(8\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8(?:4[2-5]|7[0-3])"],"0$1"],[,"(80\\d)(\\d{3})(\\d{4})","$1 $2 $3",["80"],"0$1"],[,"([58]00)(\\d{6})","$1 $2",["[58]00"],"0$1"]],,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456",,,[10]],1,,[,,,,,,,,,[-1]],[,,"(?:3[0347]|55)\\d{8}",,,,"5512345678",,,[10]],,,[,
40167,,,,,,,,[-1]]],GD:[,[,,"[4589]\\d{9}",,,,,,,[10],[7]],[,,"473(?:2(?:3[0-2]|69)|3(?:2[89]|86)|4(?:[06]8|3[5-9]|4[0-49]|5[5-79]|68|73|90)|63[68]|7(?:58|84)|800|938)\\d{4}",,,,"4732691234",,,,[7]],[,,"473(?:4(?:0[2-79]|1[04-9]|2[0-5]|58)|5(?:2[01]|3[3-8])|901)\\d{4}",,,,"4734031234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"GD",1,"011","1",,,"1",,,
40168,,,[,,,,,,,,,[-1]],,"473",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GE:[,[,,"[34578]\\d{8}",,,,,,,[9],[6]],[,,"(?:3(?:[256]\\d|4[124-9]|7[0-4])|4(?:1\\d|2[2-7]|3[1-79]|4[2-8]|7[239]|9[1-7]))\\d{6}",,,,"322123456",,,,[6]],[,,"5(?:[14]4|5[0157-9]|68|7[0147-9]|9[0-35-9])\\d{6}",,,,"555123456"],[,,"800\\d{6}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"706\\d{6}",,,,"706123456"],"GE",995,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[348]"],"0$1"],
40169[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["7"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"706\\d{6}",,,,"706123456"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GF:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"594(?:10|2[012457-9]|3[0-57-9]|4[3-9]|5[7-9]|6[0-3]|9[014])\\d{4}",,,,"594101234"],[,,"694(?:[0249]\\d|1[2-9]|3[0-48])\\d{4}",,,,"694201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GF",594,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})",
40170"$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GG:[,[,,"[135789]\\d{6,9}",,,,,,,[7,9,10],[6]],[,,"1481[25-9]\\d{5}",,,,"1481256789",,,[10],[6]],[,,"7(?:781\\d|839\\d|911[17])\\d{5}",,,,"7781123456",,,[10]],[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}",,,,"8001234567"],[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}",,,,"9012345678",,,[10]],[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})",,,,"8431234567",,,[7,10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],[,,"56\\d{8}",
40171,,,"5612345678",,,[10]],"GG",44,"00","0",,,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456",,,[10]],,,[,,,,,,,,,[-1]],[,,"(?:3[0347]|55)\\d{8}",,,,"5512345678",,,[10]],,,[,,,,,,,,,[-1]]],GH:[,[,,"[235]\\d{8}|8\\d{7}",,,,,,,[8,9],[7]],[,,"3(?:0(?:[237]\\d|80)|[167](?:2[0-6]|7\\d|80)|2(?:2[0-5]|7\\d|80)|3(?:2[0-3]|7\\d|80)|4(?:2[013-9]|3[01]|7\\d|80)|5(?:2[0-7]|7\\d|80)|8(?:2[0-2]|7\\d|80)|9(?:[28]0|7\\d))\\d{5}",,,,"302345678",,,[9],[7]],[,,"(?:2[034678]\\d|5(?:[0457]\\d|6[01]))\\d{6}",
40172,,,"231234567",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GH",233,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[235]"],"0$1"],[,"(\\d{3})(\\d{5})","$1 $2",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"800\\d{5}",,,,"80012345",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GI:[,[,,"[256]\\d{7}",,,,,,,[8]],[,,"2(?:00\\d{2}|1(?:6[24-7]\\d|90[0-2])|2(?:2[2457]\\d|50[0-2]))\\d{3}",,,,"20012345"],[,,"(?:5[46-8]|62)\\d{6}",,,,"57123456"],
40173[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GI",350,"00",,,,,,,,[[,"(\\d{3})(\\d{5})","$1 $2",["2"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GL:[,[,,"[1-689]\\d{5}",,,,,,,[6]],[,,"(?:19|3[1-6]|6[14689]|8[14-79]|9\\d)\\d{4}",,,,"321000"],[,,"[245][2-9]\\d{4}",,,,"221234"],[,,"80\\d{4}",,,,"801234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3[89]\\d{4}",,,,"381234"],"GL",299,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3"]],
40174,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GM:[,[,,"[2-9]\\d{6}",,,,,,,[7]],[,,"(?:4(?:[23]\\d{2}|4(?:1[024679]|[6-9]\\d))|5(?:54[0-7]|6(?:[67]\\d)|7(?:1[04]|2[035]|3[58]|48))|8\\d{3})\\d{3}",,,,"5661234"],[,,"[23679]\\d{6}",,,,"3012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GM",220,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GN:[,[,,"[367]\\d{7,8}",,,,,,,[8,
401759]],[,,"30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\\d{4}",,,,"30241234",,,[8]],[,,"6[02356]\\d{7}",,,,"601123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"722\\d{6}",,,,"722123456",,,[9]],"GN",224,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["3"]],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[67]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GP:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"590(?:0[13468]|1[012]|2[0-68]|3[28]|4[0-8]|5[579]|6[0189]|70|8[0-689]|9\\d)\\d{4}",
40176,,,"590201234"],[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GP",590,"00","0",,,"0",,,,[[,"([56]90)(\\d{2})(\\d{4})","$1 $2-$3",,"0$1"]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GQ:[,[,,"[23589]\\d{8}",,,,,,,[9]],[,,"3(?:3(?:3\\d[7-9]|[0-24-9]\\d[46])|5\\d{2}[7-9])\\d{4}",,,,"333091234"],[,,"(?:222|55[15])\\d{6}",,,,"222123456"],[,,"80\\d[1-9]\\d{5}",,,,"800123456"],[,,"90\\d[1-9]\\d{5}",
40177,,,"900123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GQ",240,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[235]"]],[,"(\\d{3})(\\d{6})","$1 $2",["[89]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GR:[,[,,"[26-9]\\d{9}",,,,,,,[10]],[,,"2(?:1\\d{2}|2(?:2[1-46-9]|3[1-8]|4[1-7]|5[1-4]|6[1-8]|7[1-5]|[89][1-9])|3(?:1\\d|2[1-57]|[35][1-3]|4[13]|7[1-7]|8[124-6]|9[1-79])|4(?:1\\d|2[1-8]|3[1-4]|4[13-5]|6[1-578]|9[1-5])|5(?:1\\d|[29][1-4]|3[1-5]|4[124]|5[1-6])|6(?:1\\d|3[1245]|4[1-7]|5[13-9]|[269][1-6]|7[14]|8[1-5])|7(?:1\\d|2[1-5]|3[1-6]|4[1-7]|5[1-57]|6[135]|9[125-7])|8(?:1\\d|2[1-5]|[34][1-4]|9[1-57]))\\d{6}",
40178,,,"2123456789"],[,,"69\\d{8}",,,,"6912345678"],[,,"800\\d{7}",,,,"8001234567"],[,,"90[19]\\d{7}",,,,"9091234567"],[,,"8(?:0[16]|12|25)\\d{7}",,,,"8011234567"],[,,"70\\d{8}",,,,"7012345678"],[,,,,,,,,,[-1]],"GR",30,"00",,,,,,,,[[,"([27]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["21|7"]],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["2[2-9]1|[689]"]],[,"(2\\d{3})(\\d{6})","$1 $2",["2[2-9][02-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GT:[,[,,"[2-7]\\d{7}|1[89]\\d{9}",,,,,,,[8,11]],
40179[,,"[267][2-9]\\d{6}",,,,"22456789",,,[8]],[,,"[345]\\d{7}",,,,"51234567",,,[8]],[,,"18[01]\\d{8}",,,,"18001112222",,,[11]],[,,"19\\d{9}",,,,"19001112222",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GT",502,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[2-7]"]],[,"(\\d{4})(\\d{3})(\\d{4})","$1 $2 $3",["1"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GU:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"671(?:3(?:00|3[39]|4[349]|55|6[26])|4(?:56|7[1-9]|8[0236-9])|5(?:55|6[2-5]|88)|6(?:3[2-578]|4[24-9]|5[34]|78|8[5-9])|7(?:[079]7|2[0167]|3[45]|47|8[789])|8(?:[2-5789]8|6[48])|9(?:2[29]|6[79]|7[179]|8[789]|9[78]))\\d{4}",
40180,,,"6713001234",,,,[7]],[,,"671(?:3(?:00|3[39]|4[349]|55|6[26])|4(?:56|7[1-9]|8[0236-9])|5(?:55|6[2-5]|88)|6(?:3[2-578]|4[24-9]|5[34]|78|8[5-9])|7(?:[079]7|2[0167]|3[45]|47|8[789])|8(?:[2-5789]8|6[48])|9(?:2[29]|6[79]|7[179]|8[789]|9[78]))\\d{4}",,,,"6713001234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"GU",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],
40181,"671",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],GW:[,[,,"(?:4(?:0\\d{5}|4\\d{7})|9\\d{8})",,,,,,,[7,9]],[,,"443\\d{6}",,,,"443201234",,,[9]],[,,"9(?:5(?:5\\d|6[0-2])|6(?:5[0-2]|6\\d|9[012])|77\\d)\\d{5}",,,,"955012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"40\\d{5}",,,,"4012345",,,[7]],"GW",245,"00",,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["44|9[567]"]],[,"(\\d{3})(\\d{4})","$1 $2",["40"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,
40182,[,,,,,,,,,[-1]]],GY:[,[,,"[2-46-9]\\d{6}",,,,,,,[7]],[,,"(?:2(?:1[6-9]|2[0-35-9]|3[1-4]|5[3-9]|6\\d|7[0-24-79])|3(?:2[25-9]|3\\d)|4(?:4[0-24]|5[56])|77[1-57])\\d{4}",,,,"2201234"],[,,"6\\d{6}",,,,"6091234"],[,,"(?:289|862)\\d{4}",,,,"2891234"],[,,"9008\\d{3}",,,,"9008123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"GY",592,"001",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HK:[,[,,"[235-7]\\d{7}|8\\d{7,8}|9\\d{4,10}",,,,,,,[5,
401836,7,8,9,11]],[,,"(?:2(?:[13-8]\\d|2[013-9]|9[0-24-9])|3(?:[1569][0-24-9]|4[0-246-9]|7[0-24-69]|89)|58[01])\\d{5}",,,,"21234567",,,[8]],[,,"(?:5(?:[1-59][0-46-9]|6[0-4689]|7[0-469])|6(?:0[1-9]|[1459]\\d|[2368][0-57-9]|7[0-79])|9(?:0[1-9]|1[02-9]|[2358][0-8]|[467]\\d))\\d{5}",,,,"51234567",,,[8]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"900(?:[0-24-9]\\d{7}|3\\d{1,4})",,,,"90012345678",,,[5,6,7,8,11]],[,,,,,,,,,[-1]],[,,"8(?:1[1-4679]|2[0-367]|3[02-47])\\d{5}",,,,"81123456",,,[8]],[,,,,,,,,,[-1]],"HK",
40184852,"00(?:[126-9]|30|5[09])?",,,,,,"00",,[[,"(\\d{4})(\\d{4})","$1 $2",["[235-7]|[89](?:0[1-9]|[1-9])"]],[,"(800)(\\d{3})(\\d{3})","$1 $2 $3",["800"]],[,"(900)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4",["900"]],[,"(900)(\\d{2,5})","$1 $2",["900"]]],,[,,"7(?:1[0-369]|[23][0-37-9]|47|5[1578]|6[0235]|7[278]|8[236-9]|9[025-9])\\d{5}",,,,"71234567",,,[8]],,,[,,,,,,,,,[-1]],[,,"30(?:0[1-9]|[15-7]\\d|2[047]|89)\\d{4}",,,,"30161234",,,[8]],,,[,,,,,,,,,[-1]]],HN:[,[,,"[237-9]\\d{7}",,,,,,,[8]],[,,"2(?:2(?:0[019]|1[1-36]|[23]\\d|4[04-6]|5[57]|7[01389]|8[0146-9]|9[012])|4(?:07|2[3-59]|3[13-689]|4[0-68]|5[1-35])|5(?:16|4[03-5]|5\\d|6[4-6]|74)|6(?:[056]\\d|17|3[04]|4[0-378]|[78][0-8]|9[01])|7(?:6[46-9]|7[02-9]|8[034])|8(?:79|8[0-35789]|9[1-57-9]))\\d{4}",
40185,,,"22123456"],[,,"[37-9]\\d{7}",,,,"91234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"HN",504,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1-$2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HR:[,[,,"[1-7]\\d{5,8}|[89]\\d{6,8}",,,,,,,[6,7,8,9]],[,,"1\\d{7}|(?:2[0-3]|3[1-5]|4[02-47-9]|5[1-3])\\d{6,7}",,,,"12345678",,,[8,9],[6,7]],[,,"9(?:01\\d|[1259]\\d{2}|7(?:[0679]\\d|51)|8\\d{1,2})\\d{5}",,,,"921234567",,,[8,9]],[,,"80[01]\\d{4,6}",,,,
40186"800123456",,,[7,8,9]],[,,"6(?:[01]\\d{0,2}|[459]\\d{2})\\d{4}",,,,"611234",,,[6,7,8]],[,,,,,,,,,[-1]],[,,"7[45]\\d{6}",,,,"74123456",,,[8]],[,,,,,,,,,[-1]],"HR",385,"00","0",,,"0",,,,[[,"(1)(\\d{4})(\\d{3})","$1 $2 $3",["1"],"0$1"],[,"([2-5]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[2-5]"],"0$1"],[,"(9\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["9"],"0$1"],[,"(6[01])(\\d{2})(\\d{2,3})","$1 $2 $3",["6[01]"],"0$1"],[,"([67]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[67]"],"0$1"],[,"(80[01])(\\d{2})(\\d{2,3})","$1 $2 $3",
40187["8"],"0$1"],[,"(80[01])(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:62\\d?|72)\\d{6}",,,,"62123456",,,[8,9]],,,[,,,,,,,,,[-1]]],HT:[,[,,"[2-489]\\d{7}",,,,,,,[8]],[,,"2(?:2\\d|5[1-5]|81|9[149])\\d{5}",,,,"22453300"],[,,"[34]\\d{7}",,,,"34101234"],[,,"8\\d{7}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:9(?:[67][0-4]|8[0-3589]|9\\d))\\d{5}",,,,"98901234"],"HT",509,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3"]],,[,,,,,,,,,[-1]],
40188,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],HU:[,[,,"[1-9]\\d{7,8}",,,,,,,[8,9],[6]],[,,"(?:1\\d|2[2-9]|3[2-7]|4[24-9]|5[2-79]|6[23689]|7[2-9]|8[2-57-9]|9[2-69])\\d{6}",,,,"12345678",,,[8],[6]],[,,"(?:[257]0|3[01])\\d{7}",,,,"201234567",,,[9]],[,,"[48]0\\d{6}",,,,"80123456",,,[8]],[,,"9[01]\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"21\\d{7}",,,,"211234567",,,[9]],"HU",36,"00","06",,,"06",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"($1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})",
40189"$1 $2 $3",["[2-9]"],"($1)"]],,[,,,,,,,,,[-1]],,,[,,"[48]0\\d{6}",,,,"80123456",,,[8]],[,,"38\\d{7}",,,,"381234567",,,[9]],,,[,,,,,,,,,[-1]]],ID:[,[,,"(?:[1-79]\\d{6,10}|8\\d{7,11})",,,,,,,[7,8,9,10,11,12],[5,6]],[,,"2(?:1(?:14\\d{3}|[0-8]\\d{6,7}|500\\d{3}|9\\d{6})|2\\d{6,8}|4\\d{7,8})|(?:2(?:[35][1-4]|6[0-8]|7[1-6]|8\\d|9[1-8])|3(?:1|[25][1-8]|3[1-68]|4[1-3]|6[1-3568]|7[0-469]|8\\d)|4(?:0[1-589]|1[01347-9]|2[0-36-8]|3[0-24-68]|43|5[1-378]|6[1-5]|7[134]|8[1245])|5(?:1[1-35-9]|2[25-8]|3[124-9]|4[1-3589]|5[1-46]|6[1-8])|6(?:19?|[25]\\d|3[1-69]|4[1-6])|7(?:02|[125][1-9]|[36]\\d|4[1-8]|7[0-36-9])|9(?:0[12]|1[013-8]|2[0-479]|5[125-8]|6[23679]|7[159]|8[01346]))\\d{5,8}",
40190,,,"612345678",,,[7,8,9,10,11],[5,6]],[,,"(?:2(?:1(?:3[145]|4[01]|5[1-469]|60|8[0359]|9\\d)|2(?:88|9[1256])|3[1-4]9|4(?:36|91)|5(?:1[349]|[2-4]9)|6[0-7]9|7(?:[1-36]9|4[39])|8[1-5]9|9[1-48]9)|3(?:19[1-3]|2[12]9|3[13]9|4(?:1[69]|39)|5[14]9|6(?:1[69]|2[89])|709)|4[13]19|5(?:1(?:19|8[39])|4[129]9|6[12]9)|6(?:19[12]|2(?:[23]9|77))|7(?:1[13]9|2[15]9|419|5(?:1[89]|29)|6[15]9|7[178]9))\\d{5,6}|8[1-35-9]\\d{7,10}",,,,"812345678",,,[9,10,11,12]],[,,"177\\d{6,8}|800\\d{5,7}",,,,"8001234567",,,[8,9,10,11]],[,
40191,"809\\d{7}",,,,"8091234567",,,[10]],[,,"804\\d{7}",,,,"8041234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ID",62,"0(?:0[1789]|10(?:00|1[67]))","0",,,"0",,,,[[,"(\\d{2})(\\d{5,8})","$1 $2",["2[124]|[36]1"],"(0$1)"],[,"(\\d{3})(\\d{5,8})","$1 $2",["[4579]|2[035-9]|[36][02-9]"],"(0$1)"],[,"(8\\d{2})(\\d{3,4})(\\d{3})","$1-$2-$3",["8[1-35-9]"],"0$1"],[,"(8\\d{2})(\\d{4})(\\d{4,5})","$1-$2-$3",["8[1-35-9]"],"0$1"],[,"(1)(500)(\\d{3})","$1 $2 $3",["15"],"$1"],[,"(177)(\\d{6,8})","$1 $2",["17"],"0$1"],
40192[,"(800)(\\d{5,7})","$1 $2",["800"],"0$1"],[,"(804)(\\d{3})(\\d{4})","$1 $2 $3",["804"],"0$1"],[,"(80\\d)(\\d)(\\d{3})(\\d{3})","$1 $2 $3 $4",["80[79]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"8071\\d{6}",,,,"8071123456",,,[10]],[,,"1500\\d{3}|8071\\d{6}",,,,"8071123456",,,[7,10]],,,[,,,,,,,,,[-1]]],IE:[,[,,"[124-9]\\d{6,9}",,,,,,,[7,8,9,10],[5,6]],[,,"1\\d{7,8}|2(?:1\\d{6,7}|3\\d{7}|[24-9]\\d{5})|4(?:0[24]\\d{5}|[1-469]\\d{7}|5\\d{6}|7\\d{5}|8[0-46-9]\\d{7})|5(?:0[45]\\d{5}|1\\d{6}|[23679]\\d{7}|8\\d{5})|6(?:1\\d{6}|[237-9]\\d{5}|[4-6]\\d{7})|7[14]\\d{7}|9(?:1\\d{6}|[04]\\d{7}|[35-9]\\d{5})",
40193,,,"2212345",,,,[5,6]],[,,"8(?:22\\d{6}|[35-9]\\d{7})",,,,"850123456",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,"15(?:1[2-8]|[2-8]0|9[089])\\d{6}",,,,"1520123456",,,[10]],[,,"18[59]0\\d{6}",,,,"1850123456",,,[10]],[,,"700\\d{6}",,,,"700123456",,,[9]],[,,"76\\d{7}",,,,"761234567",,,[9]],"IE",353,"00","0",,,"0",,,,[[,"(1)(\\d{3,4})(\\d{4})","$1 $2 $3",["1"],"(0$1)"],[,"(\\d{2})(\\d{5})","$1 $2",["2[24-9]|47|58|6[237-9]|9[35-9]"],"(0$1)"],[,"(\\d{3})(\\d{5})","$1 $2",["40[24]|50[45]"],"(0$1)"],
40194[,"(48)(\\d{4})(\\d{4})","$1 $2 $3",["48"],"(0$1)"],[,"(818)(\\d{3})(\\d{3})","$1 $2 $3",["81"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[24-69]|7[14]"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["76|8[35-9]"],"0$1"],[,"(8\\d)(\\d)(\\d{3})(\\d{4})","$1 $2 $3 $4",["8[35-9]5"],"0$1"],[,"(700)(\\d{3})(\\d{3})","$1 $2 $3",["70"],"0$1"],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:8[059]|5)","1(?:8[059]0|5)"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"18[59]0\\d{6}",,,,"1850123456",,,[10]],[,,"818\\d{6}",
40195,,,"818123456",,,[9]],,,[,,"8[35-9]5\\d{7}",,,,"8551234567",,,[10]]],IL:[,[,,"1\\d{6,11}|[2-589]\\d{3}(?:\\d{3,6})?|6\\d{3}|7\\d{6,9}",,,,,,,[4,7,8,9,10,11,12]],[,,"(?:153\\d{1,2}|[2-489])\\d{7}",,,,"21234567",,,[8,11,12],[7]],[,,"5(?:[0-47-9]\\d{2}|5(?:01|2[23]|3[2-4]|4[45]|5[5689]|6[6-8]|7[0178]|8[6-9]|9[2-9])|6[2-9]\\d)\\d{5}",,,,"501234567",,,[9]],[,,"1(?:80[019]\\d{3}|255)\\d{3}",,,,"1800123456",,,[7,10]],[,,"1(?:212|(?:9(?:0[01]|19)|200)\\d{2})\\d{4}",,,,"1919123456",,,[8,9,10]],[,,"1700\\d{6}",
40196,,,"1700123456",,,[10]],[,,,,,,,,,[-1]],[,,"7(?:18\\d|2[23]\\d|3[237]\\d|47\\d|6[58]\\d|7\\d{2}|8(?:2\\d|33|55|77|81)|9[2579]\\d)\\d{5}",,,,"771234567",,,[9]],"IL",972,"0(?:0|1[2-9])","0",,,"0",,,,[[,"([2-489])(\\d{3})(\\d{4})","$1-$2-$3",["[2-489]"],"0$1"],[,"([57]\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[57]"],"0$1"],[,"(153)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["153"],"$1"],[,"(1)([7-9]\\d{2})(\\d{3})(\\d{3})","$1-$2-$3-$4",["1[7-9]"],"$1"],[,"(1255)(\\d{3})","$1-$2",["125"],"$1"],[,"(1200)(\\d{3})(\\d{3})",
40197"$1-$2-$3",["120"],"$1"],[,"(1212)(\\d{2})(\\d{2})","$1-$2-$3",["121"],"$1"],[,"(1599)(\\d{6})","$1-$2",["1599"],"$1"],[,"(151)(\\d{1,2})(\\d{3})(\\d{4})","$1-$2 $3-$4",["151"],"$1"],[,"(\\d{4})","*$1",["[2-689]"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"1700\\d{6}|[2-689]\\d{3}",,,,"1700123456",,,[4,10]],[,,"[2-689]\\d{3}|1599\\d{6}",,,,"1599123456",,,[4,10]],,,[,,"151\\d{8,9}",,,,"15112340000",,,[11,12]]],IM:[,[,,"[135789]\\d{6,9}",,,,,,,[10],[6]],[,,"1624[5-8]\\d{5}",,,,"1624756789",,,,[6]],[,,"7(?:4576|[59]24\\d|624[2-4])\\d{5}",
40198,,,"7924123456"],[,,"808162\\d{4}",,,,"8081624567"],[,,"(?:872299|90[0167]624)\\d{4}",,,,"9016247890"],[,,"8(?:4(?:40[49]06|5624\\d)|70624\\d)\\d{3}",,,,"8456247890"],[,,"70\\d{8}",,,,"7012345678"],[,,"56\\d{8}",,,,"5612345678"],"IM",44,"00","0",,,"0",,,,,,[,,"7624[01689]\\d{5}",,,,"7624012345"],,,[,,,,,,,,,[-1]],[,,"3(?:08162\\d|3\\d{5}|4(?:40[49]06|5624\\d)|7(?:0624\\d|2299\\d))\\d{3}|55\\d{8}",,,,"5512345678"],,,[,,,,,,,,,[-1]]],IN:[,[,,"008\\d{9}|1\\d{7,12}|[2-9]\\d{9,10}",,,,,,,[8,9,10,11,12,
4019913],[6,7]],[,,"(?:11|2[02]|33|4[04]|79)[2-7]\\d{7}|3880\\d{6}|80[2-467]\\d{7}|(?:1(?:2[0-249]|3[0-25]|4[145]|[59][14]|6[014]|7[1257]|8[01346])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[0-26-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[025]|[36][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2345]1|57|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91))[2-7]\\d{6}|(?:(?:1(?:2[35-8]|3[346-9]|4[236-9]|[59][0235-9]|6[235-9]|7[34689]|8[257-9])|2(?:1[134689]|3[24-8]|4[2-8]|5[25689]|6[2-4679]|7[13-79]|8[2-479]|9[235-9])|3(?:01|1[79]|2[1-5]|4[25-8]|5[125689]|6[235-7]|7[157-9]|8[2-467])|4(?:1[14578]|2[5689]|3[2-467]|5[4-7]|6[35]|73|8[2689]|9[2389])|5(?:[16][146-9]|2[14-8]|3[1346]|4[14-69]|5[46]|7[2-4]|8[2-8]|9[246])|6(?:1[1358]|2[2457]|3[2-4]|4[235-7]|[57][2-689]|6[24-578]|8[1-6])|8(?:1[1357-9]|2[235-8]|3[03-57-9]|4[0-24-9]|5\\d|6[2457-9]|7[1-6]|8[1256]|9[2-4]))\\d|7(?:(?:1[013-9]|2[0235-9]|3[2679]|4[1-35689]|5[2-46-9]|[67][02-9]|9\\d)\\d|8(?:2[0-6]|[013-8]\\d)))[2-7]\\d{5}",
40200,,,"1123456789",,,[10],[6,7,8]],[,,"(?:600[1-3]\\d|7(?:0\\d{3}|19[0-5]\\d|2(?:[0235679]\\d{2}|[14][017-9]\\d|8(?:[0-59]\\d|[678][089]))|3(?:[05-8]\\d{2}|1(?:[089]\\d|11|7[5-8])|2(?:[0-49][089]|[5-8]\\d)|3[017-9]\\d|4(?:[07-9]\\d|11)|9(?:[016-9]\\d|[2-5][089]))|4(?:0\\d{2}|1(?:[015-9]\\d|[23][089]|4[089])|2(?:0[089]|[1-7][089]|[89]\\d)|3(?:[0-8][089]|9\\d)|4(?:[089]\\d|11|7[02-8])|[56]\\d[089]|7(?:[089]\\d|11|7[02-8])|8(?:[0-24-7][089]|[389]\\d)|9(?:[0-6][089]|7[089]|[89]\\d))|5(?:[0346-8]\\d{2}|1(?:[07-9]\\d|11)|2(?:[04-9]\\d|[123][089])|5[017-9]\\d|9(?:[0-6][089]|[7-9]\\d))|6(?:0(?:[0-47]\\d|[5689][089])|(?:1[0-257-9]|[6-9]\\d)\\d|2(?:[0-4]\\d|[5-9][089])|3(?:[02-8][089]|[19]\\d)|4\\d[089]|5(?:[0-367][089]|[4589]\\d))|7(?:0(?:0[02-9]|[13-6][089]|[289]\\d|7[89])|[1-9]\\d{2})|8(?:[0-79]\\d{2}|8(?:[089]\\d|11|7[02-9]))|9(?:[089]\\d{2}|313|7(?:[02-8]\\d|9[07-9])))|8(?:0(?:[01589]\\d{2}|6[67]\\d|7(?:[02-8]\\d|9[05-9]))|1(?:[02-57-9]\\d{2}|1(?:[0-35-9]\\d|4[0-46-9])|6(?:[089]\\d|7[02-8]))|2(?:0(?:[089]\\d|7[02])|[14](?:[089]\\d|7[02-8])|[235-9]\\d{2})|3(?:[0357-9]\\d{2}|1(?:[089]\\d|7[02-6])|2(?:[09]\\d|77|8[0-689])|4(?:0[1-7]|[1-9]\\d)|6(?:[089]\\d|7[02-7]))|[45]\\d{3}|6(?:[02457-9]\\d{2}|1(?:[089]\\d|7[02-8])|3(?:[089]\\d|7[02-8])|6(?:[08]\\d|7[02-8]|9\\d))|7(?:0[07-9]\\d|[1-69]\\d{2}|[78](?:[089]\\d|7[02-8]))|8(?:[0-25-9]\\d{2}|3(?:[089]\\d|7[02-8])|4(?:[0489]\\d|7[02-68]))|9(?:[02-9]\\d{2}|1(?:[0289]\\d|7[2-6])))|9\\d{4})\\d{5}",
40201,,,"8123456789",,,[10]],[,,"00800\\d{7}|1(?:600\\d{6}|80(?:0\\d{4,9}|3\\d{9}))",,,,"1800123456"],[,,"186[12]\\d{9}",,,,"1861123456789",,,[13]],[,,"1860\\d{7}",,,,"18603451234",,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IN",91,"00","0",,,"0",,,,[[,"(\\d{8})","$1",["561","5616","56161"],"$1",,1],[,"(\\d{5})(\\d{5})","$1 $2",["600|7(?:[02-8]|19|9[037-9])|8(?:0[015-9]|[1-9])|9","600|7(?:[078]|19[0-5]|2(?:[02356-9]|[14][017-9]|9[389])|3(?:[025-9]|1[017-9]|[34][017-9])|4(?:[0-35689]|[47][017-9])|5(?:[02346-9]|1[017-9]|5[017-9])|6(?:[02-9]|1[0-257-9])|9(?:[089]|31|7[02-9]))|8(?:0(?:[01589]|6[67]|7[02-9])|1(?:[0-57-9]|6[07-9])|2(?:0[07-9]|[14][07-9]|[235-9])|3(?:[03-57-9]|[126][07-9])|[45]|6(?:[02457-9]|[136][07-9])|7(?:[078][07-9]|[1-69])|8(?:[0-25-9]|3[07-9]|4[047-9])|9(?:[02-9]|1[027-9]))|9",
40202"600|7(?:0|19[0-5]|2(?:[0235679]|[14][017-9]|8(?:[0-569]|[78][089])|9[389])|3(?:[05-8]|1(?:[0189]|7[5-9])|2(?:[5-8]|[0-49][089])|3[017-9]|4(?:[07-9]|11)|9(?:[01689]|[2345][089]|40|7[0189]))|4(?:[056]|1(?:[0135-9]|[23][089]|2[089]|4[089])|2(?:0[089]|[1-7][089]|[89])|3(?:[0-8][089]|9)|4(?:[089]|11|7[02-8])|7(?:[089]|11|7[02-8])|8(?:[0-24-7][089]|[389])|9(?:[0-7][089]|[89]))|5(?:[0346-9]|1[017-9]|2(?:[03-9]|[12][089])|5[017-9])|6(?:[0346-9]|1[0-257-9]|2(?:[0-4]\\d|[5-9][089])|5(?:[0-367][089]|[4589]))|7(?:0(?:[02-9]|1[089])|[1-9])|8(?:[0-79]|8(?:0[0189]|11|8[013-9]|9))|9(?:[089]|313|7(?:[02-8]|9[07-9])))|8(?:0(?:[01589]|6[67]|7(?:[02-8]|9[05-9]))|1(?:[02-57-9]|1(?:[0-35-9]|4[0-46-9])|6(?:[089]|7[02-8]))|2(?:0(?:[089]|7[02])|[14](?:[089]|7[02-8])|[235-9])|3(?:[0357-9]|1(?:[089]|7[02-6])|2(?:[09]|77|8[0-689])|4(?:0[1-7]|[1-9])|6(?:[089]|7[02-7]))|[45]|6(?:[02457-9]|1(?:[089]|7[02-8])|3(?:[089]|7[02-8])|6(?:[08]|7[02-8]|9\\d))|7(?:0[07-9]|[1-69]|7(?:[089]|7[02-8])|8(?:[089]|7[02-8]))|8(?:[0-25-9]|3(?:[089]|7[02-8])|4(?:[0489]|7[02-68]))|9(?:[02-9]|1(?:[0289]|7[2-6])))|9"],
40203"0$1",,1],[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["11|2[02]|33|4[04]|79[1-9]|80[2-46]"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1(?:2[0-249]|3[0-25]|4[145]|[59][14]|7[1257]|[68][1-9])|2(?:1[257]|3[013]|4[01]|5[0137]|6[0158]|78|8[1568]|9[14])|3(?:26|4[1-3]|5[34]|6[01489]|7[02-46]|8[159])|4(?:1[36]|2[1-47]|3[15]|5[12]|6[0-26-9]|7[0-24-9]|8[013-57]|9[014-7])|5(?:1[025]|[36][25]|22|4[28]|5[12]|[78]1|9[15])|6(?:12|[2-4]1|5[17]|6[13]|7[14]|80)|7(?:12|2[14]|3[134]|4[47]|5[15]|[67]1|88)|8(?:16|2[014]|3[126]|6[136]|7[078]|8[34]|91)"],
40204"0$1",,1],[,"(\\d{4})(\\d{3})(\\d{3})","$1 $2 $3",["1(?:[23579]|[468][1-9])|[2-8]"],"0$1",,1],[,"(\\d{2})(\\d{3})(\\d{4})(\\d{3})","$1 $2 $3 $4",["008"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["140"],"$1",,1],[,"(\\d{4})(\\d{2})(\\d{4})","$1 $2 $3",["160","1600"],"$1",,1],[,"(\\d{4})(\\d{4,5})","$1 $2",["180","1800"],"$1",,1],[,"(\\d{4})(\\d{2,4})(\\d{4})","$1 $2 $3",["180","1800"],"$1",,1],[,"(\\d{4})(\\d{3,4})(\\d{4})","$1 $2 $3",["186","1860"],"$1",,1],[,"(\\d{4})(\\d{3})(\\d{3})(\\d{3})",
40205"$1 $2 $3 $4",["18[06]"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,"00800\\d{7}|1(?:600\\d{6}|8(?:0(?:0\\d{4,9}|3\\d{9})|6(?:0\\d{7}|[12]\\d{9})))",,,,"1800123456"],[,,"140\\d{7}",,,,"1409305260",,,[10]],,,[,,,,,,,,,[-1]]],IO:[,[,,"3\\d{6}",,,,,,,[7]],[,,"37\\d{5}",,,,"3709100"],[,,"38\\d{5}",,,,"3801234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IO",246,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
40206IQ:[,[,,"[1-7]\\d{7,9}",,,,,,,[8,9,10],[6,7]],[,,"1\\d{7}|(?:2[13-5]|3[02367]|4[023]|5[03]|6[026])\\d{6,7}",,,,"12345678",,,[8,9],[6,7]],[,,"7[3-9]\\d{8}",,,,"7912345678",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"IQ",964,"00","0",,,"0",,,,[[,"(1)(\\d{3})(\\d{4})","$1 $2 $3",["1"],"0$1"],[,"([2-6]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[2-6]"],"0$1"],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40207,,[,,,,,,,,,[-1]]],IR:[,[,,"[1-8]\\d{5,9}|9(?:[0-4]\\d{8}|9\\d{8})",,,,,,,[6,7,10],[4,5,8]],[,,"(?:(?:1[137]|2[13-68]|3[1458]|4[145]|5[1468]|6[16]|7[1467]|8[13467])(?:\\d{8}|(?:[16]|[289]\\d?)\\d{3}))|94(?:000|11[1-7]|2\\d{2}|440)\\d{5}",,,,"2123456789",,,,[4,5,8]],[,,"9(?:0[1-3]\\d{2}|[1-3]\\d{3}|9(?:0\\d{2}|44\\d|810|9(?:00|11|9[89])))\\d{5}",,,,"9123456789",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:[2-6]0\\d|993)\\d{7}",,,,"9932123456",,,[10]],"IR",98,"00",
40208"0",,,"0",,,,[[,"(\\d{2})(\\d{4})(\\d{4})","$1 $2 $3",["[1-8]"],"0$1"],[,"(\\d{2})(\\d{4,5})","$1 $2",["[1-8]"],"0$1"],[,"(\\d{4,5})","$1",["96"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["9"],"0$1"]],,[,,"943\\d{7}",,,,"9432123456",,,[10]],,,[,,"(?:9411[1-7]|94440)\\d{5}",,,,"9411110000",,,[10]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],IS:[,[,,"[4-9]\\d{6}|38\\d{7}",,,,,,,[7,9]],[,,"(?:4(?:1[0-24-69]|2[0-7]|[37][0-8]|4[0-245]|5[0-68]|6\\d|8[0-36-8])|5(?:05|[156]\\d|2[02578]|3[0-79]|4[03-7]|7[0-2578]|8[0-35-9]|9[013-689])|87[23])\\d{4}",
40209,,,"4101234",,,[7]],[,,"38[589]\\d{6}|(?:6(?:1[1-8]|2[0-6]|3[027-9]|4[014679]|5[0159]|[67][0-69]|9\\d)|7(?:5[057]|[6-8]\\d)|8(?:2[0-59]|3[0-4]|[469]\\d|5[1-9]|88))\\d{4}",,,,"6111234"],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,"90\\d{5}",,,,"9011234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"49\\d{5}",,,,"4921234",,,[7]],"IS",354,"1(?:0(?:01|10|20)|100)|00",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[4-9]"]],[,"(3\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["3"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"809\\d{4}",
40210,,,"8091234",,,[7]],,,[,,"(?:6(?:2[78]|49|8\\d)|8(?:7[0189]|80)|95[48])\\d{4}",,,,"6271234",,,[7]]],IT:[,[,,"[01589]\\d{5,10}|3(?:[12457-9]\\d{8}|[36]\\d{7,9})",,,,,,,[6,7,8,9,10,11]],[,,"0(?:[26]\\d{4,9}|(?:1(?:[0159]\\d|[27][1-5]|31|4[1-4]|6[1356]|8[2-57])|3(?:[0159]\\d|2[1-4]|3[12]|[48][1-6]|6[2-59]|7[1-7])|4(?:[0159]\\d|[23][1-9]|4[245]|6[1-5]|7[1-4]|81)|5(?:[0159]\\d|2[1-5]|3[2-6]|4[1-79]|6[4-6]|7[1-578]|8[3-8])|7(?:[0159]\\d|2[12]|3[1-7]|4[2346]|6[13569]|7[13-6]|8[1-59])|8(?:[0159]\\d|2[34578]|3[1-356]|[6-8][1-5])|9(?:[0159]\\d|[238][1-5]|4[12]|6[1-8]|7[1-6]))\\d{2,7})",
40211,,,"0212345678"],[,,"3(?:[12457-9]\\d{8}|6\\d{7,8}|3\\d{7,9})",,,,"3123456789",,,[9,10,11]],[,,"80(?:0\\d{6}|3\\d{3})",,,,"800123456",,,[6,9]],[,,"0878\\d{5}|1(?:44|6[346])\\d{6}|89(?:2\\d{3}|4(?:[0-4]\\d{2}|[5-9]\\d{4})|5(?:[0-4]\\d{2}|[5-9]\\d{6})|9\\d{6})",,,,"899123456",,,[6,8,9,10]],[,,"84(?:[08]\\d{6}|[17]\\d{3})",,,,"848123456",,,[6,9]],[,,"1(?:78\\d|99)\\d{6}",,,,"1781234567",,,[9,10]],[,,"55\\d{8}",,,,"5512345678",,,[10]],"IT",39,"00",,,,,,,,[[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["0[26]|55"]],
40212[,"(0[26])(\\d{4})(\\d{5})","$1 $2 $3",["0[26]"]],[,"(0[26])(\\d{4,6})","$1 $2",["0[26]"]],[,"(0\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["0[13-57-9][0159]"]],[,"(\\d{3})(\\d{3,6})","$1 $2",["0[13-57-9][0159]|8(?:03|4[17]|9[245])","0[13-57-9][0159]|8(?:03|4[17]|9(?:2|[45][0-4]))"]],[,"(0\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["0[13-57-9][2-46-8]"]],[,"(0\\d{3})(\\d{2,6})","$1 $2",["0[13-57-9][2-46-8]"]],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["[13]|8(?:00|4[08]|9[59])","[13]|8(?:00|4[08]|9(?:5[5-9]|9))"]],
40213[,"(\\d{4})(\\d{4})","$1 $2",["894","894[5-9]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["3"]]],,[,,,,,,,,,[-1]],1,,[,,"848\\d{6}",,,,"848123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],JE:[,[,,"[135789]\\d{6,9}",,,,,,,[10],[6]],[,,"1534[0-24-8]\\d{5}",,,,"1534456789",,,,[6]],[,,"7(?:509\\d|7(?:00[378]|97[7-9])|829\\d|937\\d)\\d{5}",,,,"7797712345"],[,,"80(?:07(?:35|81)|8901)\\d{4}",,,,"8007354567"],[,,"(?:871206|90(?:066[59]|1810|71(?:07|55)))\\d{4}",,,,"9018105678"],[,,"8(?:4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|70002)\\d{4}",
40214,,,"8447034567"],[,,"701511\\d{4}",,,,"7015115678"],[,,"56\\d{8}",,,,"5612345678"],"JE",44,"00","0",,,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}",,,,"7640123456"],,,[,,,,,,,,,[-1]],[,,"3(?:0(?:07(?:35|81)|8901)|3\\d{4}|4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|7(?:0002|1206))\\d{4}|55\\d{8}",,,,"5512345678"],,,[,,,,,,,,,[-1]]],JM:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"876(?:5(?:0[12]|1[0-468]|2[35]|63)|6(?:0[1-3579]|1[027-9]|[23]\\d|40|5[06]|6[2-589]|7[05]|8[04]|9[4-9])|7(?:0[2-689]|[1-6]\\d|8[056]|9[45])|9(?:0[1-8]|1[02378]|[2-8]\\d|9[2-468]))\\d{4}",
40215,,,"8765123456",,,,[7]],[,,"876(?:2[14-9]\\d|[348]\\d{2}|5(?:0[3-9]|[2-57-9]\\d|6[0-24-9])|7(?:0[07]|7\\d|8[1-47-9]|9[0-36-9])|9(?:[01]9|9[0579]))\\d{4}",,,,"8762101234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"JM",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"876",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],JO:[,[,,"[235-9]\\d{7,8}",,,,,,,[8,
402169]],[,,"(?:2(?:6(?:2[0-35-9]|3[0-57-8]|4[24-7]|5[0-24-8]|[6-8][023]|9[0-3])|7(?:0[1-79]|10|2[014-7]|3[0-689]|4[019]|5[0-3578]))|32(?:0[1-69]|1[1-35-7]|2[024-7]|3\\d|4[0-3]|[57][023]|6[03])|53(?:0[0-3]|[13][023]|2[0-59]|49|5[0-35-9]|6[15]|7[45]|8[1-6]|9[0-36-9])|6(?:2[50]0|3(?:00|33)|4(?:0[0125]|1[2-7]|2[0569]|[38][07-9]|4[025689]|6[0-589]|7\\d|9[0-2])|5(?:[01][056]|2[034]|3[0-57-9]|4[17-8]|5[0-69]|6[0-35-9]|7[1-379]|8[0-68]|9[02-39]))|87(?:[02]0|7[08]|90))\\d{4}",,,,"62001234",,,[8]],[,,"7(?:55|7[025-9]|8[0-25-9]|9[0-25-9])\\d{6}",
40217,,,"790123456",,,[9]],[,,"80\\d{6}",,,,"80012345",,,[8]],[,,"900\\d{5}",,,,"90012345",,,[8]],[,,"85\\d{6}",,,,"85012345",,,[8]],[,,"70\\d{7}",,,,"700123456",,,[9]],[,,,,,,,,,[-1]],"JO",962,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2356]|87"],"(0$1)"],[,"(7)(\\d{4})(\\d{4})","$1 $2 $3",["7[457-9]"],"0$1"],[,"(\\d{2})(\\d{7})","$1 $2",["70"],"0$1"],[,"(\\d{3})(\\d{5,6})","$1 $2",["8[0158]|9"],"0$1"]],,[,,"74(?:66|77)\\d{5}",,,,"746612345",,,[9]],,,[,,,,,,,,,[-1]],[,,"8(?:10|8\\d)\\d{5}",
40218,,,"88101234",,,[8]],,,[,,,,,,,,,[-1]]],JP:[,[,,"[1-9]\\d{8,9}|00(?:[36]\\d{7,14}|7\\d{5,7}|8\\d{7})",,,,,,,[8,9,10,11,12,13,14,15,16,17]],[,,"(?:1(?:1[235-8]|2[3-6]|3[3-9]|4[2-6]|[58][2-8]|6[2-7]|7[2-9]|9[1-9])|2[2-9]\\d|[36][1-9]\\d|4(?:6[02-8]|[2-578]\\d|9[2-59])|5(?:6[1-9]|7[2-8]|[2-589]\\d)|7(?:3[4-9]|4[02-9]|[25-9]\\d)|8(?:3[2-9]|4[5-9]|5[1-9]|8[03-9]|[2679]\\d)|9(?:[679][1-9]|[2-58]\\d))\\d{6}",,,,"312345678",,,[9]],[,,"[7-9]0[1-9]\\d{7}",,,,"9012345678",,,[10]],[,,"120\\d{6}|800\\d{7}|00(?:37\\d{6,13}|66\\d{6,13}|777(?:[01]\\d{2}|5\\d{3}|8\\d{4})|882[1245]\\d{4})",
40219,,,"120123456"],[,,"990\\d{6}",,,,"990123456",,,[9]],[,,,,,,,,,[-1]],[,,"60\\d{7}",,,,"601234567",,,[9]],[,,"50[1-9]\\d{7}",,,,"5012345678",,,[10]],"JP",81,"010","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1-$2-$3",["(?:12|57|99)0"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["800"],"0$1"],[,"(\\d{4})(\\d{4})","$1-$2",["0077"],"$1"],[,"(\\d{4})(\\d{2})(\\d{3,4})","$1-$2-$3",["0077"],"$1"],[,"(\\d{4})(\\d{2})(\\d{4})","$1-$2-$3",["0088"],"$1"],[,"(\\d{4})(\\d{3})(\\d{3,4})","$1-$2-$3",["00(?:37|66)"],
40220"$1"],[,"(\\d{4})(\\d{4})(\\d{4,5})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{4})(\\d{5})(\\d{5,6})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{4})(\\d{6})(\\d{6,7})","$1-$2-$3",["00(?:37|66)"],"$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["[2579]0|80[1-9]"],"0$1"],[,"(\\d{4})(\\d)(\\d{4})","$1-$2-$3",["1(?:26|3[79]|4[56]|5[4-68]|6[3-5])|5(?:76|97)|499|746|8(?:3[89]|63|47|51)|9(?:49|80|9[16])","1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:76|97)9|499[2468]|7468|8(?:3(?:8[78]|96)|636|477|51[24])|9(?:496|802|9(?:1[23]|69))",
40221"1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:769|979[2-69])|499[2468]|7468|8(?:3(?:8[78]|96[2457-9])|636[2-57-9]|477|51[24])|9(?:496|802|9(?:1[23]|69))"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["1(?:2[3-6]|3[3-9]|4[2-6]|5[2-8]|[68][2-7]|7[2-689]|9[1-578])|2(?:2[03-689]|3[3-58]|4[0-468]|5[04-8]|6[013-8]|7[06-9]|8[02-57-9]|9[13])|4(?:2[28]|3[689]|6[035-7]|7[05689]|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-9])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[014-9])|8(?:2[49]|3[3-8]|4[5-8]|5[2-9]|6[35-9]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9[3-7])",
40222"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9[2-8])|3(?:7[2-6]|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5[4-7]|6[2-9]|8[2-8]|9[236-9])|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3[34]|[4-7]))",
40223"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6[56]))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))",
40224"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6(?:5[25]|60)))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))"],
40225"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["1|2(?:2[37]|5[5-9]|64|78|8[39]|91)|4(?:2[2689]|64|7[347])|5(?:[2-589]|39)|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93)","1|2(?:2[37]|5(?:[57]|[68]0|9[19])|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93[34])","1|2(?:2[37]|5(?:[57]|[68]0|9(?:17|99))|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93(?:31|4))"],
40226"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["2(?:9[14-79]|74|[34]7|[56]9)|82|993"],"0$1"],[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3",["3|4(?:2[09]|7[01])|6[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[2479][1-9]"],"0$1"]],[[,"(\\d{3})(\\d{3})(\\d{3})","$1-$2-$3",["(?:12|57|99)0"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["800"],"0$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["[2579]0|80[1-9]"],"0$1"],[,"(\\d{4})(\\d)(\\d{4})","$1-$2-$3",["1(?:26|3[79]|4[56]|5[4-68]|6[3-5])|5(?:76|97)|499|746|8(?:3[89]|63|47|51)|9(?:49|80|9[16])",
40227"1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:76|97)9|499[2468]|7468|8(?:3(?:8[78]|96)|636|477|51[24])|9(?:496|802|9(?:1[23]|69))","1(?:267|3(?:7[247]|9[278])|4(?:5[67]|66)|5(?:47|58|64|8[67])|6(?:3[245]|48|5[4-68]))|5(?:769|979[2-69])|499[2468]|7468|8(?:3(?:8[78]|96[2457-9])|636[2-57-9]|477|51[24])|9(?:496|802|9(?:1[23]|69))"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["1(?:2[3-6]|3[3-9]|4[2-6]|5[2-8]|[68][2-7]|7[2-689]|9[1-578])|2(?:2[03-689]|3[3-58]|4[0-468]|5[04-8]|6[013-8]|7[06-9]|8[02-57-9]|9[13])|4(?:2[28]|3[689]|6[035-7]|7[05689]|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9[4-9])|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9[014-9])|8(?:2[49]|3[3-8]|4[5-8]|5[2-9]|6[35-9]|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9[3-7])",
40228"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9[2-8])|3(?:7[2-6]|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5[4-7]|6[2-9]|8[2-8]|9[236-9])|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3[34]|[4-7]))",
40229"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6[56]))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))",
40230"1(?:2[3-6]|3[3-9]|4[2-6]|5(?:[236-8]|[45][2-69])|[68][2-7]|7[2-689]|9[1-578])|2(?:2(?:[04-689]|3[23])|3[3-58]|4[0-468]|5(?:5[78]|7[2-4]|[0468][2-9])|6(?:[0135-8]|4[2-5])|7(?:[0679]|8[2-7])|8(?:[024578]|3[25-9]|9[6-9])|9(?:11|3[2-4]))|4(?:2(?:2[2-9]|8[237-9])|3[689]|6[035-7]|7(?:[059][2-8]|[68])|80|9[3-5])|5(?:3[1-36-9]|4[4578]|5[013-8]|6[1-9]|7[2-8]|8[14-7]|9(?:[89][2-8]|[4-7]))|7(?:2[15]|3[5-9]|4[02-9]|6[135-8]|7[0-4689]|9(?:[017-9]|4[6-8]|5[2-478]|6[2-589]))|8(?:2(?:4[4-8]|9(?:[3578]|20|4[04-9]|6(?:5[25]|60)))|3(?:7(?:[2-5]|6[0-59])|[3-6][2-9]|8[2-5])|4[5-8]|5[2-9]|6(?:[37]|5(?:[467]|5[014-9])|6(?:[2-8]|9[02-69])|8[2-8]|9(?:[236-8]|9[23]))|7[579]|8[03-579]|9[2-8])|9(?:[23]0|4[02-46-9]|5[024-79]|6[4-9]|7[2-47-9]|8[02-7]|9(?:3(?:3[02-9]|4[0-24689])|4[2-69]|[5-7]))"],
40231"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["1|2(?:2[37]|5[5-9]|64|78|8[39]|91)|4(?:2[2689]|64|7[347])|5(?:[2-589]|39)|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93)","1|2(?:2[37]|5(?:[57]|[68]0|9[19])|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93[34])","1|2(?:2[37]|5(?:[57]|[68]0|9(?:17|99))|64|78|8[39]|917)|4(?:2(?:[68]|20|9[178])|64|7[347])|5(?:[2-589]|39[67])|60|8(?:[46-9]|3[279]|2[124589])|9(?:[235-8]|93(?:31|4))"],
40232"0$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["2(?:9[14-79]|74|[34]7|[56]9)|82|993"],"0$1"],[,"(\\d)(\\d{4})(\\d{4})","$1-$2-$3",["3|4(?:2[09]|7[01])|6[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3",["[2479][1-9]"],"0$1"]],[,,"20\\d{8}",,,,"2012345678",,,[10]],,,[,,"00(?:37\\d{6,13}|66\\d{6,13}|777(?:[01]\\d{2}|5\\d{3}|8\\d{4})|882[1245]\\d{4})",,,,"00777012"],[,,"570\\d{6}",,,,"570123456",,,[9]],,,[,,,,,,,,,[-1]]],KE:[,[,,"20\\d{6,7}|[4-9]\\d{6,9}",,,,,,,[7,8,9,10]],[,,"20\\d{6,7}|4(?:0\\d{6,7}|[136]\\d{7}|[245]\\d{5,7})|5(?:[08]\\d{7}|[1-79]\\d{5,7})|6(?:[01457-9]\\d{5,7}|2\\d{7}|6\\d{6,7})",
40233,,,"202012345",,,[7,8,9]],[,,"7(?:[0-3679]\\d|4[0-46-9]|5[0-6]|8[0-25-9])\\d{6}",,,,"712123456",,,[9]],[,,"800[24-8]\\d{5,6}",,,,"800223456",,,[9,10]],[,,"900[02-9]\\d{5}",,,,"900223456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KE",254,"000","0",,,"005|0",,,,[[,"(\\d{2})(\\d{5,7})","$1 $2",["[24-6]"],"0$1"],[,"(\\d{3})(\\d{6})","$1 $2",["7"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["[89]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KG:[,[,
40234,"[235-8]\\d{8,9}",,,,,,,[9,10],[5,6]],[,,"(?:3(?:1(?:[256]\\d|3[1-9]|47)|2(?:22|3[0-479]|6[0-7])|4(?:22|5[6-9]|6\\d)|5(?:22|3[4-7]|59|6\\d)|6(?:22|5[35-7]|6\\d)|7(?:22|3[468]|4[1-9]|59|[67]\\d)|9(?:22|4[1-8]|6\\d))|6(?:09|12|2[2-4])\\d)\\d{5}",,,,"312123456",,,[9],[5,6]],[,,"(?:20[0-35]|5[0-24-7]\\d|7[07]\\d)\\d{6}",,,,"700123456",,,[9]],[,,"800\\d{6,7}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KG",996,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",
40235["[25-7]|31[25]"],"0$1"],[,"(\\d{4})(\\d{5})","$1 $2",["3(?:1[36]|[2-9])"],"0$1"],[,"(\\d{3})(\\d{3})(\\d)(\\d{3})","$1 $2 $3 $4",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KH:[,[,,"[1-9]\\d{7,9}",,,,,,,[8,9,10],[6,7]],[,,"(?:2[3-6]|3[2-6]|4[2-4]|[5-7][2-5])(?:[237-9]|4[56]|5\\d|6\\d?)\\d{5}|23(?:4[234]|8\\d{2})\\d{4}",,,,"23756789",,,[8,9],[6,7]],[,,"(?:1(?:[013-79]\\d|[28]\\d{1,2})|2[3-6]48|3(?:[18]\\d{2}|[2-6]48)|4[2-4]48|5[2-5]48|6(?:[016-9]\\d|[2-5]48)|7(?:[07-9]\\d|[16]\\d{2}|[2-5]48)|8(?:[013-79]\\d|8\\d{2})|9(?:6\\d{2}|7\\d{1,2}|[0-589]\\d))\\d{5}",
40236,,,"91234567",,,[8,9]],[,,"1800(?:1\\d|2[019])\\d{4}",,,,"1800123456",,,[10]],[,,"1900(?:1\\d|2[09])\\d{4}",,,,"1900123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KH",855,"00[14-9]","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["1\\d[1-9]|[2-9]"],"0$1"],[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3",["1[89]0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KI:[,[,,"[2458]\\d{4}|3\\d{4,7}|7\\d{7}",,,,,,,[5,8]],[,,"(?:[24]\\d|3[1-9]|50|8[0-5])\\d{3}|7(?:27|31|5[0-4])\\d{5}",
40237,,,"31234"],[,,"7[23]0\\d{5}",,,,"72012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"30(?:0[01]\\d{2}|12(?:11|20))\\d{2}",,,,"30010000",,,[8]],"KI",686,"00",,,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KM:[,[,,"[3478]\\d{6}",,,,,,,[7]],[,,"7[4-7]\\d{5}",,,,"7712345"],[,,"[34]\\d{6}",,,,"3212345"],[,,,,,,,,,[-1]],[,,"(?:39[01]|8\\d{2})\\d{4}",,,,"8001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KM",269,"00",,,,,,,,[[,"(\\d{3})(\\d{2})(\\d{2})",
40238"$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KN:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"869(?:2(?:29|36)|302|4(?:6[015-9]|70))\\d{4}",,,,"8692361234",,,,[7]],[,,"869(?:5(?:5[6-8]|6[5-7])|66\\d|76[02-7])\\d{4}",,,,"8697652917",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"KN",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],
40239,"869",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KP:[,[,,"1\\d{9}|[28]\\d{7}",,,,,,,[8,10],[6,7]],[,,"2\\d{7}|85\\d{6}",,,,"21234567",,,[8],[6,7]],[,,"19[123]\\d{7}",,,,"1921234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KP",850,"00|99","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["1"],"0$1"],[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,"2(?:[0-24-9]\\d{2}|3(?:[0-79]\\d|8[02-9]))\\d{4}",
40240,,,"23821234",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KR:[,[,,"007\\d{9,11}|[1-7]\\d{3,9}|8\\d{8}",,,,,,,[4,5,6,8,9,10,12,13,14],[3,7]],[,,"(?:2|3[1-3]|[46][1-4]|5[1-5])(?:1\\d{2,3}|[1-9]\\d{6,7})",,,,"22123456",,,[4,5,6,8,9,10],[3,7]],[,,"1[0-26-9]\\d{7,8}",,,,"1000000000",,,[9,10]],[,,"(?:00798\\d{0,2}|80)\\d{7}",,,,"801234567",,,[9,12,13,14]],[,,"60[2-9]\\d{6}",,,,"602345678",,,[9]],[,,,,,,,,,[-1]],[,,"50\\d{8}",,,,"5012345678",,,[10]],[,,"70\\d{8}",,,,"7012345678",,,[10]],"KR",82,"00(?:[124-68]|3\\d{2}|7(?:[0-8]\\d|9[0-79]))",
40241"0",,,"0(8[1-46-8]|85\\d{2})?",,,,[[,"(\\d{5})(\\d{3,4})(\\d{4})","$1 $2 $3",["00798"],"$1","0$CC-$1"],[,"(\\d{5})(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["00798"],"$1","0$CC-$1"],[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["1(?:0|1[19]|[69]9|5[458])|[57]0","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3",["1(?:[01]|5[1-4]|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]","1(?:[01]|5(?:[1-3]|4[56])|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d)(\\d{4})",
40242"$1-$2-$3",["131","1312"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["131","131[13-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["13[2-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4",["30"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3",["2[1-9]"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})","$1-$2",["21[0-46-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})","$1-$2",["[3-6][1-9]1","[3-6][1-9]1(?:[0-46-9])"],"0$1","0$CC-$1"],[,"(\\d{4})(\\d{4})",
40243"$1-$2",["1(?:5[246-9]|6[04678]|8[03579])","1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))"],"$1","0$CC-$1"]],[[,"(\\d{2})(\\d{4})(\\d{4})","$1-$2-$3",["1(?:0|1[19]|[69]9|5[458])|[57]0","1(?:0|1[19]|[69]9|5(?:44|59|8))|[57]0"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1-$2-$3",["1(?:[01]|5[1-4]|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]","1(?:[01]|5(?:[1-3]|4[56])|6[2-8]|[7-9])|[68]0|[3-6][1-9][1-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d)(\\d{4})","$1-$2-$3",["131","1312"],"0$1",
40244"0$CC-$1"],[,"(\\d{3})(\\d{2})(\\d{4})","$1-$2-$3",["131","131[13-9]"],"0$1","0$CC-$1"],[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["13[2-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{2})(\\d{3})(\\d{4})","$1-$2-$3-$4",["30"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})(\\d{4})","$1-$2-$3",["2[1-9]"],"0$1","0$CC-$1"],[,"(\\d)(\\d{3,4})","$1-$2",["21[0-46-9]"],"0$1","0$CC-$1"],[,"(\\d{2})(\\d{3,4})","$1-$2",["[3-6][1-9]1","[3-6][1-9]1(?:[0-46-9])"],"0$1","0$CC-$1"],[,"(\\d{4})(\\d{4})","$1-$2",["1(?:5[246-9]|6[04678]|8[03579])",
40245"1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))"],"$1","0$CC-$1"]],[,,"15\\d{7,8}",,,,"1523456789",,,[9,10]],,,[,,"00798\\d{7,9}",,,,"007981234567",,,[12,13,14]],[,,"1(?:5(?:22|44|66|77|88|99)|6(?:00|44|6[16]|70|88)|8(?:00|33|55|77|99))\\d{4}",,,,"15441234",,,[8]],,,[,,,,,,,,,[-1]]],KW:[,[,,"[12569]\\d{6,7}",,,,,,,[7,8]],[,,"(?:18\\d|2(?:[23]\\d{2}|4(?:[1-35-9]\\d|44)|5(?:0[034]|[2-46]\\d|5[1-3]|7[1-7])))\\d{4}",,,,"22345678"],[,,"(?:5(?:[05]\\d{2}|1[0-7]\\d|2(?:22|5[25])|6[56]\\d)|6(?:0[034679]\\d|222|5[015-9]\\d|6\\d{2}|7(?:0[013-9]|[67]\\d)|9(?:[069]\\d|3[039]))|9(?:0[09]\\d|22\\d|4[01479]\\d|55\\d|6[0679]\\d|7(?:02|[1-9]\\d)|8[057-9]\\d|9\\d{2}))\\d{4}",
40246,,,"50012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"KW",965,"00",,,,,,,,[[,"(\\d{4})(\\d{3,4})","$1 $2",["[16]|2(?:[0-35-9]|4[0-35-9])|9[024-9]|52[25]"]],[,"(\\d{3})(\\d{5})","$1 $2",["244|5(?:[015]|6[56])"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KY:[,[,,"[3589]\\d{9}",,,,,,,[10],[7]],[,,"345(?:2(?:22|44)|444|6(?:23|38|40)|7(?:4[35-79]|6[6-9]|77)|8(?:00|1[45]|25|[48]8)|9(?:14|4[035-9]))\\d{4}",,,,"3452221234",,,,[7]],
40247[,,"345(?:32[1-9]|5(?:1[67]|2[5-79]|4[6-9]|50|76)|649|9(?:1[67]|2[2-9]|3[689]))\\d{4}",,,,"3453231234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}|345976\\d{4}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"KY",1,"011","1",,,"1",,,,,,[,,"345849\\d{4}",,,,"3458491234"],,"345",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],KZ:[,[,,"(?:33\\d|7\\d{2}|80[089])\\d{7}",,,,,,,[10]],[,,"33622\\d{5}|7(?:1(?:0(?:[23]\\d|4[0-3]|59|63)|1(?:[23]\\d|4[0-79]|59)|2(?:[23]\\d|59)|3(?:2\\d|3[0-79]|4[0-35-9]|59)|4(?:[24]\\d|3[013-9]|5[1-9])|5(?:2\\d|3[1-9]|4[0-7]|59)|6(?:[234]\\d|5[19]|61)|72\\d|8(?:[27]\\d|3[1-46-9]|4[0-5]))|2(?:1(?:[23]\\d|4[46-9]|5[3469])|2(?:2\\d|3[0679]|46|5[12679])|3(?:[234]\\d|5[139])|4(?:2\\d|3[1235-9]|59)|5(?:[23]\\d|4[01246-8]|59|61)|6(?:2\\d|3[1-9]|4[0-4]|59)|7(?:[2379]\\d|40|5[279])|8(?:[23]\\d|4[0-3]|59)|9(?:2\\d|3[124578]|59)))\\d{5}",
40248,,,"7123456789"],[,,"7(?:0[012578]|47|6[02-4]|7[15-8]|85)\\d{7}",,,,"7710009998"],[,,"800\\d{7}",,,,"8001234567"],[,,"809\\d{7}",,,,"8091234567"],[,,,,,,,,,[-1]],[,,"808\\d{7}",,,,"8081234567"],[,,"751\\d{7}",,,,"7511234567"],"KZ",7,"810","8",,,"8",,"8~10",,,,[,,,,,,,,,[-1]],,,[,,"751\\d{7}",,,,"7511234567"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LA:[,[,,"[2-8]\\d{7,9}",,,,,,,[8,9,10],[6]],[,,"(?:2[13]|3(?:0\\d|[14])|[5-7][14]|41|8[1468])\\d{6}",,,,"21212862",,,[8,9],[6]],[,,"20(?:2[2389]|5[24-689]|7[6-8]|9[125-9])\\d{6}",
40249,,,"2023123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LA",856,"00","0",,,"0",,,,[[,"(20)(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3 $4",["20"],"0$1"],[,"([2-8]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["2[13]|3[14]|[4-8]"],"0$1"],[,"(30)(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["30"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LB:[,[,,"[13-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:[14-6]\\d{2}|7(?:[2-57]\\d|62|8[0-7]|9[04-9])|8[02-9]\\d|9\\d{2})\\d{4}",
40250,,,"1123456",,,[7]],[,,"(?:3\\d|7(?:[01]\\d|6[013-9]|8[89]|9[1-3])|81\\d)\\d{5}",,,,"71123456"],[,,,,,,,,,[-1]],[,,"9[01]\\d{6}",,,,"90123456",,,[8]],[,,"80\\d{6}",,,,"80123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LB",961,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]|7(?:[2-57]|62|8[0-7]|9[04-9])|8[02-9]|9"],"0$1"],[,"([7-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[89][01]|7(?:[01]|6[013-9]|8[89]|9[1-3])"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LC:[,
40251[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"758(?:4(?:30|5[0-9]|6[2-9]|8[0-2])|57[0-2]|638)\\d{4}",,,,"7584305678",,,,[7]],[,,"758(?:28[4-7]|384|4(?:6[01]|8[4-9])|5(?:1[89]|20|84)|7(?:1[2-9]|2\\d|3[01]))\\d{4}",,,,"7582845678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"LC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"758",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,
40252[,,,,,,,,,[-1]]],LI:[,[,,"6\\d{8}|[23789]\\d{6}",,,,,,,[7,9]],[,,"(?:2(?:01|1[27]|3\\d|6[02-578]|96)|3(?:7[0135-7]|8[048]|9[0269]))\\d{4}",,,,"2345678",,,[7]],[,,"6(?:5(?:09|1\\d|20)|6(?:0[0-6]|10|2[06-9]|39))\\d{5}|7(?:[37-9]\\d|42|56)\\d{4}",,,,"660234567"],[,,"80(?:02[28]|9\\d{2})\\d{2}",,,,"8002222",,,[7]],[,,"90(?:02[258]|1(?:23|3[14])|66[136])\\d{2}",,,,"9002222",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LI",423,"00","0",,,"0|10(?:01|20|66)",,,,[[,"(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3",
40253["[23789]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["6[56]"]],[,"(69)(7\\d{2})(\\d{4})","$1 $2 $3",["697"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"870(?:28|87)\\d{2}",,,,"8702812",,,[7]],,,[,,"697(?:42|56|[78]\\d)\\d{4}",,,,"697861234",,,[9]]],LK:[,[,,"[1-9]\\d{8}",,,,,,,[9],[7]],[,,"1(?:1[2-57]\\d{6}|973\\d{5})|(?:2[13-7]|3[1-8]|4[157]|5[12457]|6[35-7]|[89]1)[2-57]\\d{6}",,,,"112345678",,,,[7]],[,,"7[0125-8]\\d{7}",,,,"712345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40254[,,,,,,,,,[-1]],"LK",94,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{1})(\\d{6})","$1 $2 $3",["[1-689]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LR:[,[,,"2\\d{7,8}|[378]\\d{8}|4\\d{6}|5\\d{6,8}",,,,,,,[7,8,9]],[,,"(?:2\\d{3}|33333)\\d{4}",,,,"21234567",,,[8,9]],[,,"(?:20\\d{2}|330\\d|4[67]|5(?:55)?\\d|77\\d{2}|88\\d{2})\\d{5}",,,,"770123456",,,[7,9]],[,,,,,,,,,[-1]],[,,"332(?:02|[2-5]\\d)\\d{4}",,,,"332021234",,,[9]],
40255[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LR",231,"00","0",,,"0",,,,[[,"(2\\d)(\\d{3})(\\d{3})","$1 $2 $3",["2"],"0$1"],[,"([4-5])(\\d{3})(\\d{3})","$1 $2 $3",["[45]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[23578]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LS:[,[,,"[2568]\\d{7}",,,,,,,[8]],[,,"2\\d{7}",,,,"22123456"],[,,"[56]\\d{7}",,,,"50123456"],[,,"800[256]\\d{4}",,,,"80021234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40256"LS",266,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LT:[,[,,"[3-9]\\d{7}",,,,,,,[8]],[,,"(?:3[1478]|4[124-6]|52)\\d{6}",,,,"31234567"],[,,"6\\d{7}",,,,"61234567"],[,,"800\\d{5}",,,,"80012345"],[,,"9(?:0[0239]|10)\\d{5}",,,,"90012345"],[,,"808\\d{5}",,,,"80812345"],[,,"700\\d{5}",,,,"70012345"],[,,,,,,,,,[-1]],"LT",370,"00","8",,,"[08]",,,,[[,"([34]\\d)(\\d{6})","$1 $2",["37|4(?:1|5[45]|6[2-4])"],"(8-$1)",,1],[,"([3-6]\\d{2})(\\d{5})",
40257"$1 $2",["3[148]|4(?:[24]|6[09])|528|6"],"(8-$1)",,1],[,"([7-9]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["[7-9]"],"8 $1",,1],[,"(5)(2\\d{2})(\\d{4})","$1 $2 $3",["52[0-79]"],"(8-$1)",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"70[67]\\d{5}",,,,"70712345"],,,[,,,,,,,,,[-1]]],LU:[,[,,"[24-9]\\d{3,10}|3(?:[0-46-9]\\d{2,9}|5[013-9]\\d{1,8})",,,,,,,[4,5,6,7,8,9,10,11]],[,,"(?:2[2-9]\\d{2,9}|(?:[3457]\\d{2}|8(?:0[2-9]|[13-9]\\d)|9(?:0[89]|[2-579]\\d))\\d{1,8})",,,,"27123456"],[,,"6[25-79][18]\\d{6}",,,,"628123456",
40258,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"90[015]\\d{5}",,,,"90012345",,,[8]],[,,"801\\d{5}",,,,"80112345",,,[8]],[,,"70\\d{6}",,,,"70123456",,,[8]],[,,"20(?:1\\d{5}|[2-689]\\d{1,7})",,,,"20201234",,,[4,5,6,7,8,9,10]],"LU",352,"00",,,,"(15(?:0[06]|1[12]|35|4[04]|55|6[26]|77|88|99)\\d)",,,,[[,"(\\d{2})(\\d{3})","$1 $2",["[2-5]|7[1-9]|[89](?:[1-9]|0[2-9])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["[2-5]|7[1-9]|[89](?:[1-9]|0[2-9])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",
40259["20"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{1,2})","$1 $2 $3 $4",["2(?:[0367]|4[3-8])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3 $4",["20"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{1,2})","$1 $2 $3 $4 $5",["2(?:[0367]|4[3-8])"],,"$CC $1"],[,"(\\d{2})(\\d{2})(\\d{2})(\\d{1,4})","$1 $2 $3 $4",["2(?:[12589]|4[12])|[3-5]|7[1-9]|8(?:[1-9]|0[2-9])|9(?:[1-9]|0[2-46-9])"],,"$CC $1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["70|80[01]|90[015]"],,"$CC $1"],[,"(\\d{3})(\\d{3})(\\d{3})",
40260"$1 $2 $3",["6"],,"$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LV:[,[,,"[2689]\\d{7}",,,,,,,[8]],[,,"6\\d{7}",,,,"63123456"],[,,"2\\d{7}",,,,"21234567"],[,,"80\\d{6}",,,,"80123456"],[,,"90\\d{6}",,,,"90123456"],[,,"81\\d{6}",,,,"81123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LV",371,"00",,,,,,,,[[,"([2689]\\d)(\\d{3})(\\d{3})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],LY:[,[,,"[25679]\\d{8}",,,,,,,[9],[7]],[,,"(?:2[1345]|5[1347]|6[123479]|71)\\d{7}",
40261,,,"212345678",,,,[7]],[,,"9[1-6]\\d{7}",,,,"912345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"LY",218,"00","0",,,"0",,,,[[,"([25679]\\d)(\\d{7})","$1-$2",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MA:[,[,,"[5-9]\\d{8}",,,,,,,[9]],[,,"5(?:2(?:[015-79]\\d|2[02-9]|3[2-57]|4[2-8]|8[235-7])\\d|3(?:[0-48]\\d|[57][2-9]|6[2-8]|9[3-9])\\d|4[067]\\d{2}|5[03]\\d{2})\\d{4}",,,,"520123456"],[,,"(?:6(?:[0-79]\\d|8[0-247-9])|7(?:[07][07]|6[12]))\\d{6}",
40262,,,"650123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89\\d{7}",,,,"891234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5924[01]\\d{4}",,,,"592401234"],"MA",212,"00","0",,,"0",,,,[[,"([5-7]\\d{2})(\\d{6})","$1-$2",["5(?:2[015-7]|3[0-4])|[67]"],"0$1"],[,"([58]\\d{3})(\\d{5})","$1-$2",["5(?:2[2-489]|3[5-9]|92)|892","5(?:2(?:[2-48]|9[0-7])|3(?:[5-79]|8[0-7])|924)|892"],"0$1"],[,"(5\\d{4})(\\d{4})","$1-$2",["5(?:29|38)","5(?:29|38)[89]"],"0$1"],[,"([5]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5(?:4[067]|5[03])"],
40263"0$1"],[,"(8[09])(\\d{7})","$1-$2",["8(?:0|9[013-9])"],"0$1"]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MC:[,[,,"[34689]\\d{7,8}",,,,,,,[8,9]],[,,"870\\d{5}|9[2-47-9]\\d{6}",,,,"99123456",,,[8]],[,,"3\\d{7}|4(?:4\\d|5[1-9])\\d{5}|6\\d{8}",,,,"612345678"],[,,"90\\d{6}",,,,"90123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MC",377,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[39]"],"$1"],[,"(\\d{2})(\\d{3})(\\d{3})",
40264"$1 $2 $3",["4"],"0$1"],[,"(6)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["6"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3",["8"],"$1"]],,[,,,,,,,,,[-1]],,,[,,"870\\d{5}",,,,"87012345",,,[8]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MD:[,[,,"[235-9]\\d{7}",,,,,,,[8]],[,,"(?:2[1-9]\\d|3[1-79]\\d|5(?:33|5[257]))\\d{5}",,,,"22212345"],[,,"(?:562|6\\d{2}|7(?:[189]\\d|6[07]|7[457-9]))\\d{5}",,,,"62112345"],[,,"800\\d{5}",,,,"80012345"],[,,"90[056]\\d{5}",,,,"90012345"],[,,"808\\d{5}",,,,"80812345"],
40265[,,,,,,,,,[-1]],[,,"3[08]\\d{6}",,,,"30123456"],"MD",373,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["22|3"],"0$1"],[,"([25-7]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["2[13-9]|[5-7]"],"0$1"],[,"([89]\\d{2})(\\d{5})","$1 $2",["[89]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"803\\d{5}",,,,"80312345"],,,[,,,,,,,,,[-1]]],ME:[,[,,"[2-9]\\d{7,8}",,,,,,,[8],[6]],[,,"(?:20[2-8]|3(?:0[2-7]|[12][235-7]|3[24-7])|4(?:0[2-467]|1[267])|5(?:0[2467]|1[267]|2[2367]))\\d{5}",,,,"30234567",,,,[6]],
40266[,,"6(?:00\\d|3[024]\\d|6[0-25]\\d|[7-9]\\d{2})\\d{4}",,,,"67622901"],[,,"80[0-258]\\d{5}",,,,"80080002"],[,,"(?:9(?:4[1568]|5[178]))\\d{5}",,,,"94515151"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"78[1-49]\\d{5}",,,,"78108780"],"ME",382,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[2-57-9]|6[036-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"77[1-9]\\d{5}",,,,"77273012"],,,[,,,,,,,,,[-1]]],MF:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"590(?:[02][79]|13|5[0-268]|[78]7)\\d{4}",,,,"590271234"],
40267[,,"690(?:0[05-9]|[1-9]\\d)\\d{4}",,,,"690001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MF",590,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MG:[,[,,"[23]\\d{8}",,,,,,,[9],[7]],[,,"20(?:2\\d{2}|4[47]\\d|5[3467]\\d|6[279]\\d|7(?:2[29]|[35]\\d)|8[268]\\d|9[245]\\d)\\d{4}",,,,"202123456",,,,[7]],[,,"3[2-49]\\d{7}",,,,"321234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"22\\d{7}",,,,"221234567"],
40268"MG",261,"00","0",,,"0",,,,[[,"([23]\\d)(\\d{2})(\\d{3})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MH:[,[,,"[2-6]\\d{6}",,,,,,,[7]],[,,"(?:247|528|625)\\d{4}",,,,"2471234"],[,,"(?:235|329|45[56]|545)\\d{4}",,,,"2351234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"635\\d{4}",,,,"6351234"],"MH",692,"011","1",,,"1",,,,[[,"(\\d{3})(\\d{4})","$1-$2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
40269MK:[,[,,"[2-578]\\d{7}",,,,,,,[8],[6,7]],[,,"(?:2(?:[23]\\d|5[124578]|6[01])|3(?:1[3-6]|[23][2-6]|4[2356])|4(?:[23][2-6]|4[3-6]|5[256]|6[25-8]|7[24-6]|8[4-6]))\\d{5}",,,,"22212345",,,,[6,7]],[,,"7(?:[0-25-8]\\d{2}|32\\d|421|9[23]\\d)\\d{4}",,,,"72345678"],[,,"800\\d{5}",,,,"80012345"],[,,"5[02-9]\\d{6}",,,,"50012345"],[,,"8(?:0[1-9]|[1-9]\\d)\\d{5}",,,,"80123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MK",389,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"([347]\\d)(\\d{3})(\\d{3})",
40270"$1 $2 $3",["[347]"],"0$1"],[,"([58]\\d{2})(\\d)(\\d{2})(\\d{2})","$1 $2 $3 $4",["[58]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ML:[,[,,"[246-9]\\d{7}",,,,,,,[8]],[,,"(?:2(?:0(?:2\\d|7[0-8])|1(?:2[5-7]|[3-689]\\d))|44[1239]\\d)\\d{4}",,,,"20212345"],[,,"(?:2(?:079|17\\d)|[679]\\d{3}|8[239]\\d{2})\\d{4}",,,,"65012345"],[,,"80\\d{6}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ML",223,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
40271"$1 $2 $3 $4",["[246-9]"]],[,"(\\d{4})","$1",["67|74"]]],[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[246-9]"]]],[,,,,,,,,,[-1]],,,[,,"80\\d{6}",,,,"80012345"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MM:[,[,,"[178]\\d{5,7}|[24-6]\\d{5,8}|9(?:[279]\\d{0,2}|5|[34]\\d{1,2}|6(?:\\d{1,2})?|8(?:\\d{2})?)\\d{6}",,,,,,,[6,7,8,9,10],[5]],[,,"1(?:2\\d{1,2}|[35]\\d|4(?:\\d|2[236]|39)|6\\d?|[89][0-6]\\d)\\d{4}|2(?:2(?:000\\d{3}|\\d{4})|3\\d{4}|4(?:0\\d{5}|26\\d{4}|39\\d{4}|\\d{4})|5(?:1\\d{3,6}|[02-9]\\d{3,5})|[6-9]\\d{4})|4(?:2[245-8]|3(?:2(?:02)?|[346]|56?)|[46][2-6]|5[3-5])\\d{4}|5(?:2(?:2(?:\\d{1,2})?|[3-8])|3[2-68]|4(?:21?|[4-8])|5[23]|6[2-4]|7[2-8]|8[24-7]|9[2-7])\\d{4}|6(?:0[23]|1(?:2(?:0|4\\d)?|[356])|2[2-6]|3[24-6]|4(?:2(?:4\\d)?|[3-6])|5[2-4]|6[2-8]|7(?:[2367]|4(?:\\d|39)|5\\d?|8[145]\\d)|8[245]|9(?:20?|4))\\d{4}|7(?:[04][24-8]|1(?:20?|[3-7])|22|3[2-4]|5[2-7])\\d{4}|8(?:1(?:2\\d{1,2}|[3-689]\\d)|2(?:2\\d|3(?:\\d|20)|[4-8]\\d)|3[24]\\d|4[24-7]\\d|5[245]\\d|6[23]\\d)\\d{3}",
40272,,,"1234567",,,[6,7,8,9],[5]],[,,"17[01]\\d{4}|9(?:2(?:[0-4]|5\\d{2}|6[0-5]\\d)|3(?:[0-36]|4[069])\\d|4(?:0[0-4]\\d|[1379]\\d|2\\d{2}|4[0-589]\\d|5\\d{2}|88)|5[0-6]|6(?:1\\d|9\\d{2}|\\d)|7(?:3\\d|[6-9]\\d{2})|8(?:\\d|9\\d{2})|9(?:1\\d|[5-7]\\d{2}|[089]))\\d{5}",,,,"92123456",,,[7,8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"1333\\d{4}",,,,"13331234",,,[8]],"MM",95,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["1|2[245]"],"0$1"],[,"(2)(\\d{4})(\\d{4})",
40273"$1 $2 $3",["251"],"0$1"],[,"(\\d)(\\d{2})(\\d{3})","$1 $2 $3",["16|2"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["432|67|81"],"0$1"],[,"(\\d{2})(\\d{2})(\\d{3,4})","$1 $2 $3",["[4-8]"],"0$1"],[,"(9)(\\d{3})(\\d{4,6})","$1 $2 $3",["9(?:2[0-4]|[35-9]|4[137-9])"],"0$1"],[,"(9)([34]\\d{4})(\\d{4})","$1 $2 $3",["9(?:3[0-36]|4[0-57-9])"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["92[56]"],"0$1"],[,"(9)(\\d{3})(\\d{3})(\\d{2})","$1 $2 $3 $4",["93"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,
40274,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MN:[,[,,"[12]\\d{7,9}|[57-9]\\d{7}",,,,,,,[8,9,10],[6,7]],[,,"[12](?:1\\d|2(?:[1-3]\\d?|7\\d)|3[2-8]\\d{1,2}|4[2-68]\\d{1,2}|5[1-4689]\\d{1,2})\\d{5}|5[0568]\\d{6}",,,,"50123456",,,,[6,7]],[,,"(?:8(?:[05689]\\d|3[01])|9[013-9]\\d)\\d{5}",,,,"88123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"7[05-8]\\d{6}",,,,"75123456",,,[8]],"MN",976,"001","0",,,"0",,,,[[,"([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1"],"0$1"],[,"([12]2\\d)(\\d{5,6})",
40275"$1 $2",["[12]2[1-3]"],"0$1"],[,"([12]\\d{3})(\\d{5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"],"0$1"],[,"(\\d{4})(\\d{4})","$1 $2",["[57-9]"],"$1"],[,"([12]\\d{4})(\\d{4,5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MO:[,[,,"[268]\\d{7}",,,,,,,[8]],[,,"(?:28[2-57-9]|8[2-57-9]\\d)\\d{5}",,,,"28212345"],[,,"6(?:[2356]\\d|8[158])\\d{5}",,,,"66123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40276[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MO",853,"00",,,,,,,,[[,"([268]\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MP:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"670(?:2(?:3[3-7]|56|8[5-8])|32[1238]|4(?:33|8[348])|5(?:32|55|88)|6(?:64|70|82)|78[3589]|8[3-9]8|989)\\d{4}",,,,"6702345678",,,,[7]],[,,"670(?:2(?:3[3-7]|56|8[5-8])|32[1238]|4(?:33|8[348])|5(?:32|55|88)|6(?:64|70|82)|78[3589]|8[3-9]8|989)\\d{4}",,,,"6702345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",
40277,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"MP",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"670",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MQ:[,[,,"[56]\\d{8}",,,,,,,[9]],[,,"596(?:0[2-5]|[12]0|3[05-9]|4[024-8]|[5-7]\\d|89|9[4-8])\\d{4}",,,,"596301234"],[,,"696(?:[0-47-9]\\d|5[0-6]|6[0-4])\\d{4}",,,,"696201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40278"MQ",596,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MR:[,[,,"[2-48]\\d{7}",,,,,,,[8]],[,,"25[08]\\d{5}|35\\d{6}|45[1-7]\\d{5}",,,,"35123456"],[,,"[234][0-46-9]\\d{6}",,,,"22123456"],[,,"800\\d{5}",,,,"80012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MR",222,"00",,,,,,,,[[,"([2-48]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,
40279,,,,[-1]],,,[,,,,,,,,,[-1]]],MS:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"664491\\d{4}",,,,"6644912345",,,,[7]],[,,"66449[2-6]\\d{4}",,,,"6644923456",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"MS",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"664",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MT:[,[,,"[2357-9]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:[169]\\d|3[1-4])|[1-357]\\d{2})\\d{4}",
40280,,,"21001234"],[,,"(?:7(?:210|[79]\\d{2})|9(?:2(?:1[01]|31)|69[67]|8(?:1[1-3]|89|97)|9\\d{2}))\\d{4}",,,,"96961234"],[,,"800[3467]\\d{4}",,,,"80071234"],[,,"5(?:0(?:0(?:37|43)|6\\d{2}|70\\d|9[0168]\\d)|[12]\\d0[1-5])\\d{3}",,,,"50037123"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3550\\d{4}",,,,"35501234"],"MT",356,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,"7117\\d{4}",,,,"71171234"],,,[,,,,,,,,,[-1]],[,,"501\\d{5}",,,,"50112345"],,,[,,,,,,,,,[-1]]],MU:[,[,,"[2-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:2(?:[03478]\\d|1[0-7]|6[1-69])|4(?:[013568]\\d|2[4-7])|5(?:44\\d|471)|6\\d{2}|8(?:14|3[129]))\\d{4}",
40281,,,"2012345"],[,,"5(?:2[59]\\d|4(?:2[1-389]|4\\d|7[1-9]|9\\d)|7\\d{2}|8(?:[0-25689]\\d|4[3479]|7[15-8])|9[0-8]\\d)\\d{4}",,,,"52512345",,,[8]],[,,"80[012]\\d{4}",,,,"8001234",,,[7]],[,,"30\\d{5}",,,,"3012345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3(?:20|9\\d)\\d{4}",,,,"3201234",,,[7]],"MU",230,"0(?:0|[2-7]0|33)",,,,,,"020",,[[,"([2-46-9]\\d{2})(\\d{4})","$1 $2",["[2-46-9]"]],[,"(5\\d{3})(\\d{4})","$1 $2",["5"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MV:[,[,,"[346-8]\\d{6,9}|9(?:00\\d{7}|\\d{6})",
40282,,,,,,[7,10]],[,,"(?:3(?:0[0-3]|3[0-59])|6(?:[57][02468]|6[024568]|8[024689]|90))\\d{4}",,,,"6701234",,,[7]],[,,"(?:46[46]|7[3-9]\\d|9[15-9]\\d)\\d{4}",,,,"7712345",,,[7]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MV",960,"0(?:0|19)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1-$2",["[3467]|9(?:[1-9]|0[1-9])"]],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[89]00"]]],,[,,"781\\d{4}",,,,"7812345",,,[7]],,,[,,,,,,,,,[-1]],[,,"4[05]0\\d{4}",
40283,,,"4001234",,,[7]],,,[,,,,,,,,,[-1]]],MW:[,[,,"(?:1(?:\\d{2})?|[2789]\\d{2})\\d{6}",,,,,,,[7,9]],[,,"(?:1[2-9]|21\\d{2})\\d{5}",,,,"1234567"],[,,"(?:111|77\\d|88\\d|99\\d)\\d{6}",,,,"991234567",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"MW",265,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"0$1"],[,"(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[1789]"],"0$1"]],,[,,,,,,,,,[-1]],
40284,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MX:[,[,,"[1-9]\\d{9,10}",,,,,,,[10,11],[7,8]],[,,"(?:33|55|81)\\d{8}|(?:2(?:0[01]|2[1-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-578]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[234][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7}",
40285,,,"2221234567",,,[10],[7,8]],[,,"1(?:(?:33|55|81)\\d{8}|(?:2(?:2[1-9]|3[1-35-8]|4[13-9]|7[1-689]|8[1-578]|9[467])|3(?:1[1-79]|[2458][1-9]|7[1-8]|9[1-5])|4(?:1[1-57-9]|[24-6][1-9]|[37][1-8]|8[1-35-9]|9[2-689])|5(?:88|9[1-79])|6(?:1[2-68]|[2-4][1-9]|5[1-3689]|6[12457-9]|7[1-7]|8[67]|9[4-8])|7(?:[13467][1-9]|2[1-8]|5[13-9]|8[1-69]|9[17])|8(?:2[13-689]|3[1-6]|4[124-6]|6[1246-9]|7[1-378]|9[12479])|9(?:1[346-9]|2[1-4]|3[2-46-8]|5[1348]|[69][1-9]|7[12]|8[1-8]))\\d{7})",,,,"12221234567",,,[11]],[,,"8(?:00|88)\\d{7}",
40286,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,"300\\d{7}",,,,"3001234567",,,[10]],[,,"500\\d{7}",,,,"5001234567",,,[10]],[,,,,,,,,,[-1]],"MX",52,"0[09]","01",,,"0[12]|04[45](\\d{10})","1$1",,,[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["33|55|81"],"01 $1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[2467]|3[0-2457-9]|5[089]|8[02-9]|9[0-35-9]"],"01 $1",,1],[,"(1)([358]\\d)(\\d{4})(\\d{4})","044 $2 $3 $4",["1(?:33|55|81)"],"$1",,1],[,"(1)(\\d{3})(\\d{3})(\\d{4})","044 $2 $3 $4",
40287["1(?:[2467]|3[0-2457-9]|5[089]|8[2-9]|9[1-35-9])"],"$1",,1]],[[,"([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3",["33|55|81"],"01 $1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["[2467]|3[0-2457-9]|5[089]|8[02-9]|9[0-35-9]"],"01 $1",,1],[,"(1)([358]\\d)(\\d{4})(\\d{4})","$1 $2 $3 $4",["1(?:33|55|81)"]],[,"(1)(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3 $4",["1(?:[2467]|3[0-2457-9]|5[089]|8[2-9]|9[1-35-9])"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MY:[,[,,"[13-9]\\d{7,9}",,,,,,,[8,9,
4028810],[6,7]],[,,"(?:3[2-9]\\d|[4-9][2-9])\\d{6}",,,,"323456789",,,[8,9],[6,7]],[,,"1(?:1[1-6]\\d{2}|[02-4679][2-9]\\d|59\\d{2}|8(?:1[23]|[2-9]\\d))\\d{5}",,,,"123456789",,,[9,10]],[,,"1[378]00\\d{6}",,,,"1300123456",,,[10]],[,,"1600\\d{6}",,,,"1600123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"154\\d{7}",,,,"1541234567",,,[10]],"MY",60,"00","0",,,"0",,,,[[,"([4-79])(\\d{3})(\\d{4})","$1-$2 $3",["[4-79]"],"0$1"],[,"(3)(\\d{4})(\\d{4})","$1-$2 $3",["3"],"0$1"],[,"([18]\\d)(\\d{3})(\\d{3,4})","$1-$2 $3",
40289["1[02-46-9][1-9]|8"],"0$1"],[,"(1)([36-8]00)(\\d{2})(\\d{4})","$1-$2-$3-$4",["1[36-8]0"]],[,"(11)(\\d{4})(\\d{4})","$1-$2 $3",["11"],"0$1"],[,"(15[49])(\\d{3})(\\d{4})","$1-$2 $3",["15"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],MZ:[,[,,"[28]\\d{7,8}",,,,,,,[8,9]],[,,"2(?:[1346]\\d|5[0-2]|[78][12]|93)\\d{5}",,,,"21123456",,,[8]],[,,"8[2-7]\\d{7}",,,,"821234567",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,
40290,,[-1]],"MZ",258,"00",,,,,,,,[[,"([28]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["2|8[2-7]"]],[,"(80\\d)(\\d{3})(\\d{3})","$1 $2 $3",["80"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NA:[,[,,"[68]\\d{7,8}",,,,,,,[8,9]],[,,"6(?:1(?:17|2(?:[0189]\\d|[2-6]|7\\d?)|3(?:[01378]|2\\d)|4(?:[024]|10?|3[15]?)|69|7[014])|2(?:17|5(?:[0-36-8]|4\\d?)|69|70)|3(?:17|2(?:[0237]\\d?|[14-689])|34|6[289]|7[01]|81)|4(?:17|2(?:[012]|7\\d?)|4(?:[06]|1\\d?)|5(?:[01357]|[25]\\d?)|69|7[01])|5(?:17|2(?:[0459]|[23678]\\d?)|69|7[01])|6(?:17|2(?:5|6\\d?)|38|42|69|7[01])|7(?:17|2(?:[569]|[234]\\d?)|3(?:0\\d?|[13])|6[89]|7[01]))\\d{4}",
40291,,,"61221234"],[,,"(?:60|8[125])\\d{7}",,,,"811234567",,,[9]],[,,,,,,,,,[-1]],[,,"8701\\d{5}",,,,"870123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"8(?:3\\d{2}|86)\\d{5}",,,,"88612345"],"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[1235]"],"0$1"],[,"(6\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["6"],"0$1"],[,"(88)(\\d{3})(\\d{3})","$1 $2 $3",["88"],"0$1"],[,"(870)(\\d{3})(\\d{3})","$1 $2 $3",["870"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
40292NC:[,[,,"[2-57-9]\\d{5}",,,,,,,[6]],[,,"(?:2[03-9]|3[0-5]|4[1-7]|88)\\d{4}",,,,"201234"],[,,"(?:5[0-4]|[79]\\d|8[0-79])\\d{4}",,,,"751234"],[,,,,,,,,,[-1]],[,,"36\\d{4}",,,,"366711"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NC",687,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1.$2.$3",["[2-46-9]|5[0-4]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NE:[,[,,"[0289]\\d{7}",,,,,,,[8]],[,,"2(?:0(?:20|3[1-7]|4[134]|5[14]|6[14578]|7[1-578])|1(?:4[145]|5[14]|6[14-68]|7[169]|88))\\d{4}",
40293,,,"20201234"],[,,"(?:8[089]|9\\d)\\d{6}",,,,"93123456"],[,,"08\\d{6}",,,,"08123456"],[,,"09\\d{6}",,,,"09123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NE",227,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[289]|09"]],[,"(08)(\\d{3})(\\d{3})","$1 $2 $3",["08"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NF:[,[,,"[13]\\d{5}",,,,,,,[6],[5]],[,,"(?:1(?:06|17|28|39)|3[012]\\d)\\d{3}",,,,"106609",,,,[5]],[,,"3[58]\\d{4}",,,,"381234",,,,[5]],[,
40294,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NF",672,"00",,,,,,,,[[,"(\\d{2})(\\d{4})","$1 $2",["1"]],[,"(\\d)(\\d{5})","$1 $2",["3"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NG:[,[,,"[1-6]\\d{5,8}|9\\d{5,9}|[78]\\d{5,13}",,,,,,,[7,8,10,11,12,13,14],[5,6]],[,,"[12]\\d{6,7}|9(?:0[3-9]|[1-9]\\d)\\d{5}|(?:3\\d|4[023568]|5[02368]|6[02-469]|7[4-69]|8[2-9])\\d{6}|(?:4[47]|5[14579]|6[1578]|7[0-357])\\d{5,6}|(?:78|41)\\d{5}",,,,"12345678",,
40295,[7,8],[5,6]],[,,"(?:1(?:7[34]\\d|8(?:04|[124579]\\d|8[0-3])|95\\d)|287[0-7]|3(?:18[1-8]|88[0-7]|9(?:8[5-9]|6[1-5]))|4(?:28[0-2]|6(?:7[1-9]|8[02-47])|88[0-2])|5(?:2(?:7[7-9]|8\\d)|38[1-79]|48[0-7]|68[4-7])|6(?:2(?:7[7-9]|8\\d)|4(?:3[7-9]|[68][129]|7[04-69]|9[1-8])|58[0-2]|98[7-9])|7(?:38[0-7]|69[1-8]|78[2-4])|8(?:28[3-9]|38[0-2]|4(?:2[12]|3[147-9]|5[346]|7[4-9]|8[014-689]|90)|58[1-8]|78[2-9]|88[5-7])|98[07]\\d)\\d{4}|(?:70(?:[1-689]\\d|7[0-3])|8(?:0(?:1[01]|[2-9]\\d)|1(?:[0-8]\\d|9[01]))|90[235-9]\\d)\\d{6}",
40296,,,"8021234567",,,[8,10]],[,,"800\\d{7,11}",,,,"80017591759",,,[10,11,12,13,14]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NG",234,"009","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[12]|9(?:0[3-9]|[1-9])"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["[3-6]|7(?:[1-79]|0[1-9])|8[2-9]"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["70|8[01]|90[235-9]"],"0$1"],[,"([78]00)(\\d{4})(\\d{4,5})","$1 $2 $3",["[78]00"],"0$1"],[,"([78]00)(\\d{5})(\\d{5,6})","$1 $2 $3",
40297["[78]00"],"0$1"],[,"(78)(\\d{2})(\\d{3})","$1 $2 $3",["78"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"700\\d{7,11}",,,,"7001234567",,,[10,11,12,13,14]],,,[,,,,,,,,,[-1]]],NI:[,[,,"[125-8]\\d{7}",,,,,,,[8]],[,,"2\\d{7}",,,,"21234567"],[,,"(?:5(?:5[0-7]|[78]\\d)|6(?:20|3[035]|4[045]|5[05]|77|8[1-9]|9[059])|7[5-8]\\d|8\\d{2})\\d{5}",,,,"81234567"],[,,"1800\\d{4}",,,,"18001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NI",505,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2"]],
40298,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NL:[,[,,"1\\d{4,8}|[2-7]\\d{8}|[89]\\d{6,9}",,,,,,,[5,6,7,8,9,10]],[,,"(?:1[0135-8]|2[02-69]|3[0-68]|4[0135-9]|[57]\\d|8[478])\\d{7}",,,,"101234567",,,[9]],[,,"6[1-58]\\d{7}",,,,"612345678",,,[9]],[,,"800\\d{4,7}",,,,"8001234",,,[7,8,9,10]],[,,"90[069]\\d{4,7}",,,,"9061234",,,[7,8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:6760|85\\d{2})\\d{5}",,,,"851234567",,,[9]],"NL",31,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})",
40299"$1 $2 $3",["1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7|8[4578]"],"0$1"],[,"([1-5]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["1[16-8]|2[259]|3[124]|4[17-9]|5[124679]"],"0$1"],[,"(6)(\\d{8})","$1 $2",["6[0-57-9]"],"0$1"],[,"(66)(\\d{7})","$1 $2",["66"],"0$1"],[,"(14)(\\d{3,4})","$1 $2",["14"],"$1"],[,"([89]0\\d)(\\d{4,7})","$1 $2",["80|9"],"0$1"]],,[,,"66\\d{7}",,,,"662345678",,,[9]],,,[,,"14\\d{3,4}",,,,"14123",,,[5,6]],[,,"140(?:1(?:[035]|[16-8]\\d)|2(?:[0346]|[259]\\d)|3(?:[03568]|[124]\\d)|4(?:[0356]|[17-9]\\d)|5(?:[0358]|[124679]\\d)|7\\d|8[458])",
40300,,,"14020",,,[5,6]],,,[,,,,,,,,,[-1]]],NO:[,[,,"0\\d{4}|[2-9]\\d{7}",,,,,,,[5,8]],[,,"(?:2[1-4]|3[1-3578]|5[1-35-7]|6[1-4679]|7[0-8])\\d{6}",,,,"21234567",,,[8]],[,,"(?:4[015-8]|5[89]|87|9\\d)\\d{6}",,,,"40612345",,,[8]],[,,"80[01]\\d{5}",,,,"80012345",,,[8]],[,,"82[09]\\d{5}",,,,"82012345",,,[8]],[,,"810(?:0[0-6]|[2-8]\\d)\\d{3}",,,,"81021234",,,[8]],[,,"880\\d{5}",,,,"88012345",,,[8]],[,,"85[0-5]\\d{5}",,,,"85012345",,,[8]],"NO",47,"00",,,,,,,,[[,"([489]\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",["[489]"]],
40301[,"([235-7]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[235-7]"]]],,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,"0\\d{4}|81(?:0(?:0[7-9]|1\\d)|5\\d{2})\\d{3}",,,,"01234"],,,[,,"81[23]\\d{5}",,,,"81212345",,,[8]]],NP:[,[,,"[1-8]\\d{7}|9(?:[1-69]\\d{6,8}|7[2-6]\\d{5,7}|8\\d{8})",,,,,,,[8,10],[6,7]],[,,"(?:1[0-6]\\d|2[13-79][2-6]|3[135-8][2-6]|4[146-9][2-6]|5[135-7][2-6]|6[13-9][2-6]|7[15-9][2-6]|8[1-46-9][2-6]|9[1-79][2-6])\\d{5}",,,,"14567890",,,[8],[6,7]],[,,"9(?:6[013]|7[245]|8[0-24-6])\\d{7}",,,,"9841234567",
40302,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NP",977,"00","0",,,"0",,,,[[,"(1)(\\d{7})","$1-$2",["1[2-6]"],"0$1"],[,"(\\d{2})(\\d{6})","$1-$2",["1[01]|[2-8]|9(?:[1-69]|7[15-9])"],"0$1"],[,"(9\\d{2})(\\d{7})","$1-$2",["9(?:6[013]|7[245]|8)"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NR:[,[,,"[458]\\d{6}",,,,,,,[7]],[,,"(?:444|888)\\d{4}",,,,"4441234"],[,,"55[5-9]\\d{4}",,,,"5551234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,
40303,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NR",674,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NU:[,[,,"[1-5]\\d{3}",,,,,,,[4]],[,,"[34]\\d{3}",,,,"4002"],[,,"[125]\\d{3}",,,,"1234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"NU",683,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],NZ:[,[,,"6[235-9]\\d{6}|[2-57-9]\\d{7,9}",,,,,,,[8,9,10],[7]],[,,"(?:3[2-79]|[49][2-9]|6[235-9]|7[2-57-9])\\d{6}|24099\\d{3}",
40304,,,"32345678",,,[8],[7]],[,,"2(?:[028]\\d{7,8}|1(?:[03]\\d{5,7}|[12457]\\d{5,6}|[689]\\d{5})|[79]\\d{7})",,,,"211234567"],[,,"508\\d{6,7}|80\\d{6,8}",,,,"800123456"],[,,"90\\d{6,7}",,,,"900123456",,,[8,9]],[,,,,,,,,,[-1]],[,,"70\\d{7}",,,,"701234567",,,[9]],[,,,,,,,,,[-1]],"NZ",64,"0(?:0|161)","0",,,"0",,"00",,[[,"(\\d)(\\d{3})(\\d{4})","$1-$2 $3",["240|[346]|7[2-57-9]|9[1-9]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["21"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{3,5})","$1 $2 $3",["2(?:1[1-9]|[69]|7[0-35-9])|70|86"],
40305"0$1"],[,"(2\\d)(\\d{3,4})(\\d{4})","$1 $2 $3",["2[028]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})","$1 $2 $3",["90"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["2(?:10|74)|5|[89]0"],"0$1"]],,[,,"[28]6\\d{6,7}",,,,"26123456",,,[8,9]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],OM:[,[,,"(?:5|[279]\\d)\\d{6}|800\\d{5,6}",,,,,,,[7,8,9]],[,,"2[2-6]\\d{6}",,,,"23123456",,,[8]],[,,"7[19]\\d{6}|9(?:0[1-9]|[1-9]\\d)\\d{5}",,,,"92123456",,,[8]],[,,"8007\\d{4,5}|500\\d{4}",,,,"80071234"],[,,"900\\d{5}",
40306,,,"90012345",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"OM",968,"00",,,,,,,,[[,"(2\\d)(\\d{6})","$1 $2",["2"]],[,"([79]\\d{3})(\\d{4})","$1 $2",["[79]"]],[,"([58]00)(\\d{4,6})","$1 $2",["[58]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PA:[,[,,"[1-9]\\d{6,7}",,,,,,,[7,8]],[,,"(?:1(?:0[0-8]|1[49]|2[37]|3[0137]|4[147]|5[05]|6[58]|7[0167]|8[58]|9[139])|2(?:[0235679]\\d|1[0-7]|4[04-9]|8[028])|3(?:[09]\\d|1[014-7]|2[0-3]|3[03]|4[03-57]|55|6[068]|7[06-8]|8[06-9])|4(?:3[013-69]|4\\d|7[0-589])|5(?:[01]\\d|2[0-7]|[56]0|79)|7(?:0[09]|2[0-267]|3[06]|[469]0|5[06-9]|7[0-24-79]|8[7-9])|8(?:09|[34]\\d|5[0134]|8[02])|9(?:0[6-9]|1[016-8]|2[036-8]|3[3679]|40|5[0489]|6[06-9]|7[046-9]|8[36-8]|9[1-9]))\\d{4}",
40307,,,"2001234",,,[7]],[,,"(?:1[16]1|21[89]|8(?:1[01]|7[23]))\\d{4}|6(?:[024-9]\\d|1[0-5]|3[0-24-9])\\d{5}",,,,"60012345"],[,,"80[09]\\d{4}",,,,"8001234",,,[7]],[,,"(?:779|8(?:55|60|7[78])|9(?:00|81))\\d{4}",,,,"8601234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PA",507,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[1-57-9]"]],[,"(\\d{4})(\\d{4})","$1-$2",["6"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PE:[,[,,"[14-9]\\d{7,8}",,,,,,,[8,9],[6,7]],[,,"(?:1\\d|4[1-4]|5[1-46]|6[1-7]|7[2-46]|8[2-4])\\d{6}",
40308,,,"11234567",,,[8],[6,7]],[,,"9\\d{8}",,,,"912345678",,,[9]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"805\\d{5}",,,,"80512345",,,[8]],[,,"801\\d{5}",,,,"80112345",,,[8]],[,,"80[24]\\d{5}",,,,"80212345",,,[8]],[,,,,,,,,,[-1]],"PE",51,"19(?:1[124]|77|90)00","0"," Anexo ",,"0",,,,[[,"(1)(\\d{7})","$1 $2",["1"],"(0$1)"],[,"([4-8]\\d)(\\d{6})","$1 $2",["[4-7]|8[2-4]"],"(0$1)"],[,"(\\d{3})(\\d{5})","$1 $2",["80"],"(0$1)"],[,"(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,
40309,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PF:[,[,,"4\\d{5,7}|8\\d{7}",,,,,,,[6,8]],[,,"4(?:[09][45689]\\d|4)\\d{4}",,,,"40412345"],[,,"8[79]\\d{6}",,,,"87123456",,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PF",689,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["4[09]|8[79]"]],[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["44"]]],,[,,,,,,,,,[-1]],,,[,,"44\\d{4}",,,,"441234",,,[6]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PG:[,[,,"[1-9]\\d{6,7}",,
40310,,,,,[7,8]],[,,"(?:3[0-2]\\d|4[257]\\d|5[34]\\d|64[1-9]|77(?:[0-24]\\d|30)|85[02-46-9]|9[78]\\d)\\d{4}",,,,"3123456",,,[7]],[,,"7(?:[0-689]\\d|75)\\d{5}",,,,"70123456",,,[8]],[,,"180\\d{4}",,,,"1801234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"2(?:0[0-47]|7[568])\\d{4}",,,,"2751234",,,[7]],"PG",675,"140[1-3]|00",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1 $2",["[13-689]|27"]],[,"(\\d{4})(\\d{4})","$1 $2",["20|7"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PH:[,
40311[,,"2\\d{5,7}|[3-9]\\d{7,9}|1800\\d{7,9}",,,,,,,[6,8,9,10,11,12,13],[5,7]],[,,"2\\d{5}(?:\\d{2})?|(?:3[2-68]|4[2-9]|5[2-6]|6[2-58]|7[24578]|8[2-8])\\d{7}|88(?:22\\d{6}|42\\d{4})",,,,"21234567",,,[6,8,9,10],[5,7]],[,,"(?:81[37]|9(?:0[5-9]|1[024-9]|2[0-35-9]|3[02-9]|4[235-9]|5[056]|6[5-7]|7[34-79]|89|9[4-9]))\\d{7}",,,,"9051234567",,,[10]],[,,"1800\\d{7,9}",,,,"180012345678",,,[11,12,13]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PH",63,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})",
40312"$1 $2 $3",["2"],"(0$1)"],[,"(2)(\\d{5})","$1 $2",["2"],"(0$1)"],[,"(\\d{4})(\\d{4,6})","$1 $2",["3(?:23|39|46)|4(?:2[3-6]|[35]9|4[26]|76)|5(?:22|44)|642|8(?:62|8[245])","3(?:230|397|461)|4(?:2(?:35|[46]4|51)|396|4(?:22|63)|59[347]|76[15])|5(?:221|446)|642[23]|8(?:622|8(?:[24]2|5[13]))"],"(0$1)"],[,"(\\d{5})(\\d{4})","$1 $2",["346|4(?:27|9[35])|883","3469|4(?:279|9(?:30|56))|8834"],"(0$1)"],[,"([3-8]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[3-8]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["81|9"],
40313"0$1"],[,"(1800)(\\d{3})(\\d{4})","$1 $2 $3",["1"]],[,"(1800)(\\d{1,2})(\\d{3})(\\d{4})","$1 $2 $3 $4",["1"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PK:[,[,,"1\\d{8}|[2-8]\\d{5,11}|9(?:[013-9]\\d{4,9}|2\\d(?:111\\d{6}|\\d{3,7}))",,,,,,,[8,9,10,11,12],[6,7]],[,,"(?:21|42)[2-9]\\d{7}|(?:2[25]|4[0146-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]\\d{6}|(?:2(?:3[2358]|4[2-4]|9[2-8])|45[3479]|54[2-467]|60[468]|72[236]|8(?:2[2-689]|3[23578]|4[3478]|5[2356])|9(?:2[2-8]|3[27-9]|4[2-6]|6[3569]|9[25-8]))[2-9]\\d{5,6}|58[126]\\d{7}",
40314,,,"2123456789",,,[9,10],[6,7,8]],[,,"3(?:[014]\\d|2[0-5]|3[0-7]|55|64)\\d{7}",,,,"3012345678",,,[10]],[,,"800\\d{5}",,,,"80012345",,,[8]],[,,"900\\d{5}",,,,"90012345",,,[8]],[,,,,,,,,,[-1]],[,,"122\\d{6}",,,,"122044444",,,[9]],[,,,,,,,,,[-1]],"PK",92,"00","0",,,"0",,,,[[,"(\\d{2})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4",["(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)1","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)11","(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)111"],"(0$1)"],
40315[,"(\\d{3})(111)(\\d{3})(\\d{3})","$1 $2 $3 $4",["2[349]|45|54|60|72|8[2-5]|9[2-9]","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d1","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d11","(?:2[349]|45|54|60|72|8[2-5]|9[2-9])\\d111"],"(0$1)"],[,"(\\d{2})(\\d{7,8})","$1 $2",["(?:2[125]|4[0-246-9]|5[1-35-7]|6[1-8]|7[14]|8[16]|91)[2-9]"],"(0$1)"],[,"(\\d{3})(\\d{6,7})","$1 $2",["2[349]|45|5(?:4|8[12])|60|72|8[2-5]|9[2-9]","(?:2[349]|45|5(?:4|8[12])|60|72|8[2-5]|9[2-9])\\d[2-9]"],"(0$1)"],[,"(3\\d{2})(\\d{7})","$1 $2",
40316["3"],"0$1"],[,"(1\\d{3})(\\d{5,6})","$1 $2",["1"],"$1"],[,"(586\\d{2})(\\d{5})","$1 $2",["586"],"(0$1)"],[,"([89]00)(\\d{3})(\\d{2})","$1 $2 $3",["[89]00"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"(?:2(?:[125]|3[2358]|4[2-4]|9[2-8])|4(?:[0-246-9]|5[3479])|5(?:[1-35-7]|4[2-467])|6(?:[1-8]|0[468])|7(?:[14]|2[236])|8(?:[16]|2[2-689]|3[23578]|4[3478]|5[2356])|9(?:1|22|3[27-9]|4[2-6]|6[3569]|9[2-7]))111\\d{6}",,,,"21111825888",,,[11,12]],,,[,,,,,,,,,[-1]]],PL:[,[,,"[1-57-9]\\d{6,8}|6\\d{5,8}",,
40317,,,,,[6,7,8,9]],[,,"(?:1[2-8]|2[2-69]|3[2-4]|4[1-468]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145])(?:\\d{7}|19\\d{3})",,,,"123456789",,,[7,9]],[,,"(?:45|5[0137]|6[069]|7[2389]|88)\\d{7}",,,,"512345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"70[01346-8]\\d{6}",,,,"701234567",,,[9]],[,,"801\\d{6}",,,,"801234567",,,[9]],[,,,,,,,,,[-1]],[,,"39\\d{7}",,,,"391234567",,,[9]],"PL",48,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1 $2",["11[68]|64"]],[,"(\\d{5})","$1",["19"]],[,"(\\d{2})(\\d{2})(\\d{3})","$1 $2 $3",
40318["1[2-8]|2[2-69]|3[2-4]|4[1-468]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]"]],[,"(\\d{3})(\\d{2})(\\d{2,3})","$1 $2 $3",["64"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["26|39|45|5[0137]|6[0469]|7[02389]|8[08]"]],[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[14]|2[0-57-9]|3[2-4]|5[24-689]|6[1-3578]|7[14-7]|8[1-79]|9[145]"]]],,[,,"64\\d{4,7}",,,,"641234567"],,,[,,,,,,,,,[-1]],[,,"804\\d{6}",,,,"804123456",,,[9]],,,[,,,,,,,,,[-1]]],PM:[,[,,"[45]\\d{5}",,,,,,,[6]],[,,"41\\d{4}",,,,"411234"],
40319[,,"(?:40|55)\\d{4}",,,,"551234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PM",508,"00","0",,,"0",,,,[[,"([45]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PR:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"(?:787|939)[2-9]\\d{6}",,,,"7872345678",,,,[7]],[,,"(?:787|939)[2-9]\\d{6}",,,,"7872345678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],
40320[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"PR",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"787|939",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PS:[,[,,"1\\d{9}|[24589]\\d{7,8}",,,,,,,[8,9,10],[7]],[,,"(?:22[234789]|42[45]|82[01458]|92[369])\\d{5}",,,,"22234567",,,[8],[7]],[,,"5[69]\\d{7}",,,,"599123456",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,,,,,,,,[-1]],[,,"1700\\d{6}",,,,"1700123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PS",970,
40321"00","0",,,"0",,,,[[,"([2489])(2\\d{2})(\\d{4})","$1 $2 $3",["[2489]"],"0$1"],[,"(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["5"],"0$1"],[,"(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PT:[,[,,"[2-46-9]\\d{8}",,,,,,,[9]],[,,"2(?:[12]\\d|[35][1-689]|4[1-59]|6[1-35689]|7[1-9]|8[1-69]|9[1256])\\d{6}",,,,"212345678"],[,,"9(?:[1236]\\d{2}|480)\\d{5}",,,,"912345678"],[,,"80[02]\\d{6}",,,,"800123456"],[,,"6(?:0[178]|4[68])\\d{6}|76(?:0[1-57]|1[2-47]|2[237])\\d{5}",
40322,,,"760123456"],[,,"80(?:8\\d|9[1579])\\d{5}",,,,"808123456"],[,,"884[0-4689]\\d{5}",,,,"884123456"],[,,"30\\d{7}",,,,"301234567"],"PT",351,"00",,,,,,,,[[,"(2\\d)(\\d{3})(\\d{4})","$1 $2 $3",["2[12]"]],[,"([2-46-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2[3-9]|[346-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7(?:0(?:7\\d|8[17]))\\d{5}",,,,"707123456"],,,[,,"600\\d{6}",,,,"600110000"]],PW:[,[,,"[2-8]\\d{6}",,,,,,,[7]],[,,"2552255|(?:277|345|488|5(?:35|44|87)|6(?:22|54|79)|7(?:33|47)|8(?:24|55|76))\\d{4}",
40323,,,"2771234"],[,,"(?:6[234689]0|77[45789])\\d{4}",,,,"6201234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"PW",680,"01[12]",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],PY:[,[,,"5[0-5]\\d{4,7}|[2-46-9]\\d{5,8}",,,,,,,[6,7,8,9],[5]],[,,"(?:[26]1|3[289]|4[124678]|7[123]|8[1236])\\d{5,7}|(?:2(?:2[4568]|7[15]|9[1-5])|3(?:18|3[167]|4[2357]|51)|4(?:18|2[45]|3[12]|5[13]|64|71|9[1-47])|5(?:[1-4]\\d|5[0234])|6(?:3[1-3]|44|7[1-4678])|7(?:17|4[0-4]|6[1-578]|75|8[0-8])|858)\\d{5,6}",
40324,,,"212345678",,,[7,8,9],[5,6]],[,,"9(?:6[12]|[78][1-6]|9[1-5])\\d{6}",,,,"961456789",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"8700[0-4]\\d{4}",,,,"870012345",,,[9]],"PY",595,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{5})","$1 $2",["(?:[26]1|3[289]|4[124678]|7[123]|8[1236])"],"(0$1)"],[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["(?:[26]1|3[289]|4[124678]|7[123]|8[1236])"],"(0$1)"],[,"(\\d{3})(\\d{3,6})","$1 $2",["[2-9]0"],"0$1"],[,"(\\d{3})(\\d{6})","$1 $2",["9[1-9]"],"0$1"],
40325[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["8700"]],[,"(\\d{3})(\\d{4,5})","$1 $2",["[2-8][1-9]"],"(0$1)"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[2-8][1-9]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"[2-9]0\\d{4,7}",,,,"201234567"],,,[,,,,,,,,,[-1]]],QA:[,[,,"[2-8]\\d{6,7}",,,,,,,[7,8]],[,,"4[04]\\d{6}",,,,"44123456",,,[8]],[,,"[3567]\\d{7}",,,,"33123456",,,[8]],[,,"800\\d{4}",,,,"8001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"QA",974,"00",,,,,,,,[[,"([28]\\d{2})(\\d{4})",
40326"$1 $2",["[28]"]],[,"([3-7]\\d{3})(\\d{4})","$1 $2",["[3-7]"]]],,[,,"2(?:[12]\\d|61)\\d{4}",,,,"2123456",,,[7]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RE:[,[,,"[268]\\d{8}",,,,,,,[9]],[,,"262\\d{6}",,,,"262161234"],[,,"69(?:2\\d{2}|3(?:0[0-46]|1[013]|2[0-2]|3[039]|4[0-7]|5[05]|6[06]|7[07]|8[0-38]|9[0-479]))\\d{4}",,,,"692123456"],[,,"80\\d{7}",,,,"801234567"],[,,"89[1-37-9]\\d{6}",,,,"891123456"],[,,"8(?:1[019]|2[0156]|84|90)\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RE",
40327262,"00","0",,,"0",,,,[[,"([268]\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"0$1"]],,[,,,,,,,,,[-1]],1,"262|69|8",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RO:[,[,,"[23]\\d{5,8}|[7-9]\\d{8}",,,,,,,[6,9]],[,,"2(?:1(?:\\d{7}|9\\d{3})|[3-6](?:\\d{7}|\\d9\\d{2}))|3(?:1\\d{4}(?:\\d{3})?|[3-6]\\d{7})",,,,"211234567"],[,,"7(?:[0-8]\\d{2}|99\\d)\\d{5}",,,,"712345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"90[036]\\d{6}",,,,"900123456",,,[9]],[,,"801\\d{6}",,,,"801123456",,,[9]],[,,,
40328,,,,,,[-1]],[,,,,,,,,,[-1]],"RO",40,"00","0"," int ",,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[23]1"],"0$1"],[,"(\\d{2})(\\d{4})","$1 $2",["[23]1"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["[23][3-7]|[7-9]"],"0$1"],[,"(2\\d{2})(\\d{3})","$1 $2",["2[3-6]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"37\\d{7}",,,,"372123456",,,[9]],,,[,,,,,,,,,[-1]]],RS:[,[,,"[126-9]\\d{4,11}|3(?:[0-79]\\d{3,10}|8[2-9]\\d{2,9})",,,,,,,[6,7,8,9,10,11,12],[5]],[,,"(?:1(?:[02-9][2-9]|1[1-9])\\d|2(?:[0-24-7][2-9]\\d|[389](?:0[2-9]|[2-9]\\d))|3(?:[0-8][2-9]\\d|9(?:[2-9]\\d|0[2-9])))\\d{3,8}",
40329,,,"10234567",,,[7,8,9,10,11,12],[5,6]],[,,"6(?:[0-689]|7\\d)\\d{6,7}",,,,"601234567",,,[8,9,10]],[,,"800\\d{3,9}",,,,"80012345"],[,,"(?:90[0169]|78\\d)\\d{3,7}",,,,"90012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RS",381,"00","0",,,"0",,,,[[,"([23]\\d{2})(\\d{4,9})","$1 $2",["(?:2[389]|39)0"],"0$1"],[,"([1-3]\\d)(\\d{5,10})","$1 $2",["1|2(?:[0-24-7]|[389][1-9])|3(?:[0-8]|9[1-9])"],"0$1"],[,"(6\\d)(\\d{6,8})","$1 $2",["6"],"0$1"],[,"([89]\\d{2})(\\d{3,9})","$1 $2",["[89]"],"0$1"],[,"(7[26])(\\d{4,9})",
40330"$1 $2",["7[26]"],"0$1"],[,"(7[08]\\d)(\\d{4,9})","$1 $2",["7[08]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7[06]\\d{4,10}",,,,"700123456"],,,[,,,,,,,,,[-1]]],RU:[,[,,"[3489]\\d{9}",,,,,,,[10]],[,,"(?:3(?:0[12]|4[1-35-79]|5[1-3]|65|8[1-58]|9[0145])|4(?:01|1[1356]|2[13467]|7[1-5]|8[1-7]|9[1-689])|8(?:1[1-8]|2[01]|3[13-6]|4[0-8]|5[15]|6[1-35-79]|7[1-37-9]))\\d{7}",,,,"3011234567"],[,,"9\\d{9}",,,,"9123456789"],[,,"80[04]\\d{7}",,,,"8001234567"],[,,"80[39]\\d{7}",,,,"8091234567"],[,,,,,,,,,[-1]],
40331[,,"808\\d{7}",,,,"8081234567"],[,,,,,,,,,[-1]],"RU",7,"810","8",,,"8",,"8~10",,[[,"(\\d{3})(\\d{2})(\\d{2})","$1-$2-$3",["[1-79]"],"$1",,1],[,"([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["[34689]"],"8 ($1)",,1],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"8 ($1)",,1]],[[,"([3489]\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2-$3-$4",["[34689]"],"8 ($1)",,1],[,"(7\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"],"8 ($1)",,1]],[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],RW:[,
40332[,,"[027-9]\\d{7,8}",,,,,,,[8,9]],[,,"2[258]\\d{7}|06\\d{6}",,,,"250123456"],[,,"7[238]\\d{7}",,,,"720123456",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"900\\d{6}",,,,"900123456",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"RW",250,"00","0",,,"0",,,,[[,"(2\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["2"],"$1"],[,"([7-9]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[7-9]"],"0$1"],[,"(0\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["0"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,
40333,[-1]]],SA:[,[,,"1\\d{7,8}|(?:[2-467]|92)\\d{7}|5\\d{8}|8\\d{9}",,,,,,,[8,9,10],[7]],[,,"11\\d{7}|1?(?:2[24-8]|3[35-8]|4[3-68]|6[2-5]|7[235-7])\\d{6}",,,,"112345678",,,[8,9],[7]],[,,"(?:5(?:[013-689]\\d|7[0-36-8])|811\\d)\\d{6}",,,,"512345678",,,[9,10]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,,,,,,,,[-1]],[,,"92[05]\\d{6}",,,,"920012345",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SA",966,"00","0",,,"0",,,,[[,"([1-467])(\\d{3})(\\d{4})","$1 $2 $3",["[1-467]"],"0$1"],[,"(1\\d)(\\d{3})(\\d{4})","$1 $2 $3",
40334["1[1-467]"],"0$1"],[,"(5\\d)(\\d{3})(\\d{4})","$1 $2 $3",["5"],"0$1"],[,"(92\\d{2})(\\d{5})","$1 $2",["92"],"$1"],[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"],"$1"],[,"(811)(\\d{3})(\\d{3,4})","$1 $2 $3",["81"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SB:[,[,,"[1-9]\\d{4,6}",,,,,,,[5,7]],[,,"(?:1[4-79]|[23]\\d|4[0-2]|5[03]|6[0-37])\\d{3}",,,,"40123",,,[5]],[,,"48\\d{3}|7(?:30|[46-8]\\d|5[025-9]|9[0-5])\\d{4}|8[4-9]\\d{5}|9(?:1[2-9]|2[013-9]|3[0-2]|[46]\\d|5[0-46-9]|7[0-689]|8[0-79]|9[0-8])\\d{4}",
40335,,,"7421234"],[,,"1[38]\\d{3}",,,,"18123",,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5[12]\\d{3}",,,,"51123",,,[5]],"SB",677,"0[01]",,,,,,,,[[,"(\\d{2})(\\d{5})","$1 $2",["[7-9]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SC:[,[,,"[24689]\\d{5,6}",,,,,,,[7]],[,,"4[2-46]\\d{5}",,,,"4217123"],[,,"2[5-8]\\d{5}",,,,"2510123"],[,,"8000\\d{3}",,,,"8000000"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:64\\d|971)\\d{4}",,,,"6412345"],"SC",248,"0(?:[02]|10?)",
40336,,,,,"00",,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[246]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SD:[,[,,"[19]\\d{8}",,,,,,,[9]],[,,"1(?:[125]\\d|8[3567])\\d{6}",,,,"121231234"],[,,"9[0-3569]\\d{7}",,,,"911231234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SD",249,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SE:[,[,,"[1-35-9]\\d{5,11}|4\\d{6,8}",
40337,,,,,,[6,7,8,9,10,12]],[,,"1(?:0[1-8]\\d{6}|[136]\\d{5,7}|(?:2[0-35]|4[0-4]|5[0-25-9]|7[13-6]|[89]\\d)\\d{5,6})|2(?:[136]\\d{5,7}|(?:2[0-7]|4[0136-8]|5[0138]|7[018]|8[01]|9[0-57])\\d{5,6})|3(?:[356]\\d{5,7}|(?:0[0-4]|1\\d|2[0-25]|4[056]|7[0-2]|8[0-3]|9[023])\\d{5,6})|4(?:[0246]\\d{5,7}|(?:1[013-8]|3[0135]|5[14-79]|7[0-246-9]|8[0156]|9[0-689])\\d{5,6})|5(?:0[0-6]|[15][0-5]|2[0-68]|3[0-4]|4\\d|6[03-5]|7[013]|8[0-79]|9[01])\\d{5,6}|6(?:[03]\\d{5,7}|(?:1[1-3]|2[0-4]|4[02-57]|5[0-37]|6[0-3]|7[0-2]|8[0247]|9[0-356])\\d{5,6})|8\\d{6,8}|9(?:0[1-9]\\d{4,6}|(?:1[0-68]|2\\d|3[02-5]|4[0-3]|5[0-4]|[68][01]|7[0135-8])\\d{5,6})",
40338,,,"8123456",,,[7,8,9]],[,,"7[02369]\\d{7}",,,,"701234567",,,[9]],[,,"20\\d{4,7}",,,,"20123456",,,[6,7,8,9]],[,,"649\\d{6}|9(?:00|39|44)[1-8]\\d{3,6}",,,,"9001234567",,,[7,8,9,10]],[,,"77(?:0\\d{3}(?:\\d{3})?|[1-7]\\d{6})",,,,"771234567",,,[6,9]],[,,"75[1-8]\\d{6}",,,,"751234567",,,[9]],[,,,,,,,,,[-1]],"SE",46,"00","0",,,"0",,,,[[,"(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1-$2 $3 $4",["8"],"0$1"],[,"([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1-$2 $3 $4",["1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90"],"0$1"],
40339[,"([1-469]\\d)(\\d{3})(\\d{2})","$1-$2 $3",["1[136]|2[136]|3[356]|4[0246]|6[03]|90"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1-$2 $3 $4",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"],"0$1"],[,"(\\d{3})(\\d{2,3})(\\d{2})","$1-$2 $3",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"],"0$1"],[,"(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4",["7"],"0$1"],[,"(77)(\\d{2})(\\d{2})",
40340"$1-$2$3",["7"],"0$1"],[,"(20)(\\d{2,3})(\\d{2})","$1-$2 $3",["20"],"0$1"],[,"(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})","$1-$2 $3 $4",["9[034]"],"0$1"],[,"(9[034]\\d)(\\d{4})","$1-$2",["9[034]"],"0$1"],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1-$2 $3 $4 $5",["25[245]|67[3-6]"],"0$1"]],[[,"(8)(\\d{2,3})(\\d{2,3})(\\d{2})","$1 $2 $3 $4",["8"]],[,"([1-69]\\d)(\\d{2,3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|90"]],[,"([1-469]\\d)(\\d{3})(\\d{2})","$1 $2 $3",["1[136]|2[136]|3[356]|4[0246]|6[03]|90"]],
40341[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"]],[,"(\\d{3})(\\d{2,3})(\\d{2})","$1 $2 $3",["1[2457]|2(?:[247-9]|5[0138])|3[0247-9]|4[1357-9]|5[0-35-9]|6(?:[124-689]|7[0-2])|9(?:[125-8]|3[0-5]|4[0-3])"]],[,"(7\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["7"]],[,"(77)(\\d{2})(\\d{2})","$1 $2 $3",["7"]],[,"(20)(\\d{2,3})(\\d{2})","$1 $2 $3",["20"]],[,"(9[034]\\d)(\\d{2})(\\d{2})(\\d{3})",
40342"$1 $2 $3 $4",["9[034]"]],[,"(9[034]\\d)(\\d{4})","$1 $2",["9[034]"]],[,"(\\d{3})(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["25[245]|67[3-6]"]]],[,,"74[02-9]\\d{6}",,,,"740123456",,,[9]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"(?:25[245]|67[3-6])\\d{9}",,,,"254123456789",,,[12]]],SG:[,[,,"[36]\\d{7}|[17-9]\\d{7,10}",,,,,,,[8,10,11]],[,,"6[1-9]\\d{6}",,,,"61234567",,,[8]],[,,"(?:8[1-8]|9[0-8])\\d{6}",,,,"81234567",,,[8]],[,,"1?800\\d{7}",,,,"18001234567",,,[10,11]],[,,"1900\\d{7}",,,,"19001234567",
40343,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"3[12]\\d{6}",,,,"31234567",,,[8]],"SG",65,"0[0-3]\\d",,,,,,,,[[,"([3689]\\d{3})(\\d{4})","$1 $2",["[369]|8[1-9]"]],[,"(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3",["1[89]"]],[,"(7000)(\\d{4})(\\d{3})","$1 $2 $3",["70"]],[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"7000\\d{7}",,,,"70001234567",,,[11]],,,[,,,,,,,,,[-1]]],SH:[,[,,"[256]\\d{4}",,,,,,,[4,5]],[,,"2(?:[0-57-9]\\d|6[4-9])\\d{2}",,,,"22158"],[,,"[56]\\d{4}",,,,"51234",
40344,,[5]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"262\\d{2}",,,,"26212",,,[5]],"SH",290,"00",,,,,,,,,,[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SI:[,[,,"[1-7]\\d{6,7}|[89]\\d{4,7}",,,,,,,[5,6,7,8]],[,,"(?:1\\d|[25][2-8]|3[24-8]|4[24-8]|7[3-8])\\d{6}",,,,"11234567",,,[8],[7]],[,,"(?:[37][01]\\d|4[0139]\\d|51\\d|6(?:[48]\\d|9[69]))\\d{5}",,,,"31234567",,,[8]],[,,"80\\d{4,6}",,,,"80123456",,,[6,7,8]],[,,"90\\d{4,6}|89[1-3]\\d{2,5}",,,,"90123456"],
40345[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"(?:59|8[1-3])\\d{6}",,,,"59012345",,,[8]],"SI",386,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[12]|3[24-8]|4[24-8]|5[2-8]|7[3-8]"],"(0$1)"],[,"([3-7]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[37][01]|4[0139]|51|6"],"0$1"],[,"([89][09])(\\d{3,6})","$1 $2",["[89][09]"],"0$1"],[,"([58]\\d{2})(\\d{5})","$1 $2",["59|8[1-3]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SJ:[,[,,"0\\d{4}|[45789]\\d{7}",,,,,,,[5,8]],[,
40346,"79\\d{6}",,,,"79123456",,,[8]],[,,"(?:4[015-8]|5[89]|9\\d)\\d{6}",,,,"41234567",,,[8]],[,,"80[01]\\d{5}",,,,"80012345",,,[8]],[,,"82[09]\\d{5}",,,,"82012345",,,[8]],[,,"810(?:0[0-6]|[2-8]\\d)\\d{3}",,,,"81021234",,,[8]],[,,"880\\d{5}",,,,"88012345",,,[8]],[,,"85[0-5]\\d{5}",,,,"85012345",,,[8]],"SJ",47,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"0\\d{4}|81(?:0(?:0[7-9]|1\\d)|5\\d{2})\\d{3}",,,,"01234"],,,[,,"81[23]\\d{5}",,,,"81212345",,,[8]]],SK:[,[,,"(?:[2-68]\\d{5,8}|9\\d{6,8})",,,,,
40347,,[6,7,9]],[,,"2(?:1(?:6\\d{3,4}|7\\d{3})|[2-9]\\d{7})|[3-5][1-8](?:1(?:6\\d{2,3}|7\\d{3})|\\d{7})",,,,"221234567"],[,,"9(?:0(?:[1-8]\\d|9[1-9])|(?:1[0-24-9]|[45]\\d)\\d)\\d{5}",,,,"912123456",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"9(?:[78]\\d{7}|00\\d{6})",,,,"900123456",,,[9]],[,,"8[5-9]\\d{7}",,,,"850123456",,,[9]],[,,,,,,,,,[-1]],[,,"6(?:02|5[0-4]|9[0-6])\\d{6}",,,,"690123456",,,[9]],"SK",421,"00","0",,,"0",,,,[[,"(2)(1[67])(\\d{3,4})","$1 $2 $3",["21[67]"],"0$1"],[,"([3-5]\\d)(1[67])(\\d{2,3})",
40348"$1 $2 $3",["[3-5]"],"0$1"],[,"(2)(\\d{3})(\\d{3})(\\d{2})","$1/$2 $3 $4",["2"],"0$1"],[,"([3-5]\\d)(\\d{3})(\\d{2})(\\d{2})","$1/$2 $3 $4",["[3-5]"],"0$1"],[,"([689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[689]"],"0$1"],[,"(9090)(\\d{3})","$1 $2",["9090"],"0$1"]],,[,,"9090\\d{3}",,,,"9090123",,,[7]],,,[,,"(?:602|8(?:00|[5-9]\\d)|9(?:00|[78]\\d))\\d{6}|9090\\d{3}",,,,"800123456",,,[7,9]],[,,"96\\d{7}",,,,"961234567",,,[9]],,,[,,,,,,,,,[-1]]],SL:[,[,,"[2-9]\\d{7}",,,,,,,[8],[6]],[,,"[235]2[2-4][2-9]\\d{4}",
40349,,,"22221234",,,,[6]],[,,"(?:2[15]|3[03-5]|4[04]|5[05]|66|7[6-9]|8[08]|99)\\d{6}",,,,"25123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SL",232,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",,"(0$1)"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SM:[,[,,"[05-7]\\d{7,9}",,,,,,,[8,10],[6]],[,,"0549(?:8[0157-9]|9\\d)\\d{4}",,,,"0549886377",,,[10],[6]],[,,"6[16]\\d{6}",,,,"66661212",,,[8]],[,,,,,,,,,[-1]],[,,"7[178]\\d{6}",,,,"71123456",
40350,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"5[158]\\d{6}",,,,"58001110",,,[8]],"SM",378,"00",,,,"(?:0549)?([89]\\d{5})","0549$1",,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-7]"]],[,"(0549)(\\d{6})","$1 $2",["0"]],[,"(\\d{6})","0549 $1",["[89]"]]],[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[5-7]"]],[,"(0549)(\\d{6})","($1) $2",["0"]],[,"(\\d{6})","(0549) $1",["[89]"]]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SN:[,[,,"[3789]\\d{8}",,,,,,,[9]],[,
40351,"3(?:0(?:1[0-2]|80)|282|3(?:8[1-9]|9[3-9])|611)\\d{5}",,,,"301012345"],[,,"7(?:[06-8]\\d|21|90)\\d{6}",,,,"701234567"],[,,"800\\d{6}",,,,"800123456"],[,,"88[4689]\\d{6}",,,,"884123456"],[,,"81[02468]\\d{6}",,,,"810123456"],[,,,,,,,,,[-1]],[,,"39[01]\\d{6}|3392\\d{5}|93330\\d{4}",,,,"933301234"],"SN",221,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[379]"]],[,"(\\d{3})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,
40352,,[-1]]],SO:[,[,,"[1-9]\\d{5,8}",,,,,,,[6,7,8,9]],[,,"(?:1\\d{1,2}|2[0-79]\\d|3[0-46-8]?\\d|4[0-7]?\\d|59\\d|8[125])\\d{4}",,,,"4012345",,,[6,7]],[,,"(?:15\\d|2(?:4\\d|8)|3[59]\\d{2}|4[89]\\d{2}|6[1-9]?\\d{2}|7(?:[1-8]\\d|9\\d{1,2})|8[08]\\d{2}|9(?:0[67]|[2-9])\\d)\\d{5}",,,,"71123456",,,[7,8,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SO",252,"00","0",,,"0",,,,[[,"(\\d{6})","$1",["[134]"]],[,"(\\d)(\\d{6})","$1 $2",["2[0-79]|[13-5]"]],[,"(\\d)(\\d{7})","$1 $2",
40353["24|[67]"]],[,"(\\d{2})(\\d{4})","$1 $2",["8[125]"]],[,"(\\d{2})(\\d{5,7})","$1 $2",["15|28|6[1-35-9]|799|9[2-9]"]],[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["3[59]|4[89]|6[24-6]|79|8[08]|90"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SR:[,[,,"[2-8]\\d{5,6}",,,,,,,[6,7]],[,,"(?:2[1-3]|3[0-7]|4\\d|5[2-58]|68\\d)\\d{4}",,,,"211234"],[,,"(?:7[124-7]|8[1-9])\\d{5}",,,,"7412345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"56\\d{4}",,,,"561234",
40354,,[6]],"SR",597,"00",,,,,,,,[[,"(\\d{3})(\\d{3})","$1-$2",["[2-4]|5[2-58]"]],[,"(\\d{2})(\\d{2})(\\d{2})","$1-$2-$3",["56"]],[,"(\\d{3})(\\d{4})","$1-$2",["[6-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SS:[,[,,"[19]\\d{8}",,,,,,,[9]],[,,"18\\d{7}",,,,"181234567"],[,,"(?:12|9[1257])\\d{7}",,,,"977123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SS",211,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",,"0$1"]],,[,,
40355,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ST:[,[,,"[29]\\d{6}",,,,,,,[7]],[,,"22\\d{5}",,,,"2221234"],[,,"9(?:0(?:0[5-9]|[1-9]\\d)|[89]\\d{2})\\d{3}",,,,"9812345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ST",239,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SV:[,[,,"[267]\\d{7}|[89]\\d{6}(?:\\d{4})?",,,,,,,[7,8,11]],[,,"2[1-6]\\d{6}",,,,"21234567",,,[8]],[,,"[67]\\d{7}",
40356,,,"70123456",,,[8]],[,,"800\\d{4}(?:\\d{4})?",,,,"8001234",,,[7,11]],[,,"900\\d{4}(?:\\d{4})?",,,,"9001234",,,[7,11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SV",503,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[267]"]],[,"(\\d{3})(\\d{4})","$1 $2",["[89]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["[89]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SX:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"7215(?:4[2-8]|8[239]|9[056])\\d{4}",,,,"7215425678",,,,[7]],[,,"7215(?:1[02]|2\\d|5[034679]|8[014-8])\\d{4}",
40357,,,"7215205678",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002123456"],[,,"900[2-9]\\d{6}",,,,"9002123456"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"SX",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"721",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SY:[,[,,"[1-59]\\d{7,8}",,,,,,,[8,9],[6,7]],[,,"(?:1(?:1\\d?|4\\d|[2356])|2(?:1\\d?|[235])|3(?:[13]\\d|4)|4[13]|5[1-3])\\d{6}",,,,"112345678",,,,[6,7]],[,,"9(?:22|[3-589]\\d|6[024-9])\\d{6}",
40358,,,"944567890",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"SY",963,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[1-5]"],"0$1",,1],[,"(9\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9"],"0$1",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],SZ:[,[,,"[027]\\d{7}",,,,,,,[8]],[,,"2[2-9]\\d{6}",,,,"22171234"],[,,"7[6-9]\\d{6}",,,,"76123456"],[,,"0800\\d{4}",,,,"08001234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,
40359,,,,,,,[-1]],"SZ",268,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["[027]"]]],,[,,,,,,,,,[-1]],,,[,,"0800\\d{4}",,,,"08001234"],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TA:[,[,,"8\\d{3}",,,,,,,[4]],[,,"8\\d{3}",,,,"8999"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TA",290,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TC:[,[,,"[5689]\\d{9}",,,,,,,[10],[7]],[,,"649(?:712|9(?:4\\d|50))\\d{4}",,,,"6497121234",,,,[7]],[,
40360,"649(?:2(?:3[129]|4[1-7])|3(?:3[1-389]|4[1-8])|4[34][1-3])\\d{4}",,,,"6492311234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,"64971[01]\\d{4}",,,,"6497101234",,,,[7]],"TC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"649",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TD:[,[,,"[2679]\\d{7}",,,,,,,[8]],[,,"22(?:[3789]0|5[0-5]|6[89])\\d{4}",,,,"22501234"],[,,"(?:6[023568]\\d|77\\d|9\\d{2})\\d{5}",
40361,,,"63012345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TD",235,"00|16",,,,,,"00",,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TG:[,[,,"[29]\\d{7}",,,,,,,[8]],[,,"2(?:2[2-7]|3[23]|44|55|66|77)\\d{5}",,,,"22212345"],[,,"9[0-36-9]\\d{6}",,,,"90112345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TG",228,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})",
40362"$1 $2 $3 $4",["[29]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TH:[,[,,"1\\d{8,9}|[2-9]\\d{7,8}",,,,,,,[8,9,10]],[,,"(?:2\\d|3[2-9]|4[2-5]|5[2-6]|7[3-7])\\d{6}",,,,"21234567",,,[8]],[,,"(?:14|6[1-6]|[89]\\d)\\d{7}",,,,"812345678",,,[9]],[,,"1800\\d{6}",,,,"1800123456",,,[10]],[,,"1900\\d{6}",,,,"1900123456",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"6[08]\\d{7}",,,,"601234567",,,[9]],"TH",66,"00","0",,,"0",,,,[[,"(2)(\\d{3})(\\d{4})","$1 $2 $3",["2"],"0$1"],[,"([13-9]\\d)(\\d{3})(\\d{3,4})",
40363"$1 $2 $3",["14|[3-9]"],"0$1"],[,"(1[89]00)(\\d{3})(\\d{3})","$1 $2 $3",["1"],"$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TJ:[,[,,"[3-57-9]\\d{8}",,,,,,,[9],[3,5,7]],[,,"(?:3(?:1[3-5]|2[245]|3[12]|4[24-7]|5[25]|72)|4(?:46|74|87))\\d{6}",,,,"372123456",,,,[3,5,7]],[,,"(?:41[18]|(?:5[05]|77|88|9[0-35-9])\\d)\\d{6}",,,,"917123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TJ",992,"810","8",,,"8",,"8~10",,[[,"([349]\\d{2})(\\d{2})(\\d{4})",
40364"$1 $2 $3",["[34]7|91[78]"],"$1",,1],[,"([457-9]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["4[148]|[578]|9(?:1[59]|[0235-9])"],"$1",,1],[,"(331700)(\\d)(\\d{2})","$1 $2 $3",["331","3317","33170","331700"],"$1",,1],[,"(\\d{4})(\\d)(\\d{4})","$1 $2 $3",["3[1-5]","3(?:[1245]|3(?:[02-9]|1[0-589]))"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TK:[,[,,"[2-47]\\d{3,6}",,,,,,,[4,5,6,7]],[,,"(?:2[2-4]|[34]\\d)\\d{2,5}",,,,"3101"],[,,"7[2-4]\\d{2,5}",,,,"7290"],[,,,,,,,,,[-1]],[,
40365,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TK",690,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TL:[,[,,"[2-489]\\d{6}|7\\d{6,7}",,,,,,,[7,8]],[,,"(?:2[1-5]|3[1-9]|4[1-4])\\d{5}",,,,"2112345",,,[7]],[,,"7[3-8]\\d{6}",,,,"77212345",,,[8]],[,,"80\\d{5}",,,,"8012345",,,[7]],[,,"90\\d{5}",,,,"9012345",,,[7]],[,,,,,,,,,[-1]],[,,"70\\d{5}",,,,"7012345",,,[7]],[,,,,,,,,,[-1]],"TL",670,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-489]|70"]],[,"(\\d{4})(\\d{4})",
40366"$1 $2",["7[3-8]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TM:[,[,,"[1-6]\\d{7}",,,,,,,[8]],[,,"(?:1(?:2\\d|3[1-9])|2(?:22|4[0-35-8])|3(?:22|4[03-9])|4(?:22|3[128]|4\\d|6[15])|5(?:22|5[7-9]|6[014-689]))\\d{5}",,,,"12345678"],[,,"6[1-9]\\d{6}",,,,"66123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TM",993,"810","8",,,"8",,"8~10",,[[,"(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2-$3-$4",["12"],"(8 $1)"],[,"(\\d{2})(\\d{6})","$1 $2",
40367["6"],"8 $1"],[,"(\\d{3})(\\d)(\\d{2})(\\d{2})","$1 $2-$3-$4",["13|[2-5]"],"(8 $1)"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TN:[,[,,"[2-57-9]\\d{7}",,,,,,,[8]],[,,"3(?:[012]\\d|6[0-4]|91)\\d{5}|7\\d{7}|81200\\d{3}",,,,"71234567"],[,,"(?:[259]\\d|4[0-6])\\d{6}",,,,"20123456"],[,,"8010\\d{4}",,,,"80101234"],[,,"88\\d{6}",,,,"88123456"],[,,"8[12]10\\d{4}",,,,"81101234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TN",216,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3"]],,[,
40368,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TO:[,[,,"[02-8]\\d{4,6}",,,,,,,[5,7]],[,,"(?:2\\d|3[1-8]|4[1-4]|[56]0|7[0149]|8[05])\\d{3}",,,,"20123",,,[5]],[,,"(?:7[578]|8[47-9])\\d{5}",,,,"7715123",,,[7]],[,,"0800\\d{3}",,,,"0800222",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TO",676,"00",,,,,,,,[[,"(\\d{2})(\\d{3})","$1-$2",["[1-6]|7[0-4]|8[05]"]],[,"(\\d{3})(\\d{4})","$1 $2",["7[5-9]|8[47-9]"]],[,"(\\d{4})(\\d{3})","$1 $2",["0"]]],,[,,,,,,,,,[-1]],
40369,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TR:[,[,,"[2-589]\\d{9}|444\\d{4}",,,,,,,[7,10]],[,,"(?:2(?:[13][26]|[28][2468]|[45][268]|[67][246])|3(?:[13][28]|[24-6][2468]|[78][02468]|92)|4(?:[16][246]|[23578][2468]|4[26]))\\d{7}",,,,"2123456789",,,[10]],[,,"5(?:(?:0[1-7]|22|[34]\\d|5[1-59]|9[246])\\d{2}|6161)\\d{5}",,,,"5012345678",,,[10]],[,,"800\\d{7}",,,,"8001234567",,,[10]],[,,"900\\d{7}",,,,"9001234567",,,[10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TR",90,"00","0",,,"0",,,
40370,[[,"(\\d{3})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[23]|4(?:[0-35-9]|4[0-35-9])"],"(0$1)",,1],[,"(\\d{3})(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["5[02-69]"],"0$1",,1],[,"(\\d{3})(\\d{3})(\\d{4})","$1 $2 $3",["51|[89]"],"0$1",,1],[,"(444)(\\d{1})(\\d{3})","$1 $2 $3",["444"]]],,[,,"512\\d{7}",,,,"5123456789",,,[10]],,,[,,"444\\d{4}",,,,"4441444",,,[7]],[,,"444\\d{4}|850\\d{7}",,,,"4441444"],,,[,,,,,,,,,[-1]]],TT:[,[,,"[589]\\d{9}",,,,,,,[10],[7]],[,,"868(?:2(?:01|[23]\\d)|6(?:0[79]|1[02-8]|2[1-9]|[3-69]\\d|7[0-79])|82[124])\\d{4}",
40371,,,"8682211234",,,,[7]],[,,"868(?:2(?:6[6-9]|[789]\\d)|3(?:0[1-9]|1[02-9]|[2-9]\\d)|4[6-9]\\d|6(?:20|78|8\\d)|7(?:0[1-9]|1[02-9]|[2-9]\\d))\\d{4}",,,,"8682911234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"TT",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"868",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"868619\\d{4}",,,,"8686191234",,,,[7]]],TV:[,[,,"[279]\\d{4,6}",
40372,,,,,,[5,6,7]],[,,"2[02-9]\\d{3}",,,,"20123",,,[5]],[,,"(?:70\\d|90)\\d{4}",,,,"901234",,,[6,7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"TV",688,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],TW:[,[,,"2\\d{6,8}|[3-689]\\d{7,8}|7\\d{7,9}",,,,,,,[7,8,9,10]],[,,"2(?:[235-8]\\d{7}|4\\d{6,7})|[3-8]\\d{7,8}",,,,"221234567",,,[8,9]],[,,"9\\d{8}",,,,"912345678",,,[9]],[,,"800\\d{6}",,,,"800123456",,,[9]],[,,"20(?:2|[013-9]\\d{2})\\d{4}",
40373,,,"203123456",,,[7,9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"70\\d{8}",,,,"7012345678",,,[10]],"TW",886,"0(?:0[25679]|19)","0","#",,"0",,,,[[,"(20)(\\d)(\\d{4})","$1 $2 $3",["202"],"0$1"],[,"(20)(\\d{3})(\\d{4})","$1 $2 $3",["20[013-9]"],"0$1"],[,"([2-8])(\\d{3,4})(\\d{4})","$1 $2 $3",["2[23-8]|[3-6]|[78][1-9]"],"0$1"],[,"([89]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["80|9"],"0$1"],[,"(70)(\\d{4})(\\d{4})","$1 $2 $3",["70"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],
40374TZ:[,[,,"\\d{9}",,,,,,,[7,9]],[,,"2[2-8]\\d{7}",,,,"222345678"],[,,"(?:6[2-9]|7[13-9])\\d{7}",,,,"621234567",,,[9]],[,,"80[08]\\d{6}",,,,"800123456",,,[9]],[,,"90\\d{7}",,,,"900123456",,,[9]],[,,"8(?:40|6[01])\\d{6}",,,,"840123456",,,[9]],[,,,,,,,,,[-1]],[,,"41\\d{7}",,,,"412345678",,,[9]],"TZ",255,"00[056]","0",,,"0",,,,[[,"([24]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[24]"],"0$1"],[,"([67]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[67]"],"0$1"],[,"([89]\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["[89]"],"0$1"]],
40375,[,,,,,,,,,[-1]],,,[,,"(?:8(?:[04]0|6[01])|90\\d)\\d{6}",,,,"800123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UA:[,[,,"[3-9]\\d{8}",,,,,,,[9],[5,6,7]],[,,"(?:3[1-8]|4[13-8]|5[1-7]|6[12459])\\d{7}",,,,"311234567",,,,[5,6,7]],[,,"(?:39|50|6[36-8]|7[1-3]|9[1-9])\\d{7}",,,,"391234567"],[,,"800\\d{6}",,,,"800123456"],[,,"900[2-49]\\d{5}",,,,"900212345"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"89\\d{7}",,,,"891234567"],"UA",380,"00","0",,,"0",,"0~0",,[[,"([3-9]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[38]9|4(?:[45][0-5]|87)|5(?:0|6[37]|7[37])|6[36-8]|7|9[1-9]",
40376"[38]9|4(?:[45][0-5]|87)|5(?:0|6(?:3[14-7]|7)|7[37])|6[36-8]|7|9[1-9]"],"0$1"],[,"([3-689]\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["3[1-8]2|4[13678]2|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90","3(?:[1-46-8]2[013-9]|52)|4(?:[1378]2|62[013-9])|5(?:[12457]2|6[24])|6(?:[49]2|[12][29]|5[24])|8[0-8]|90"],"0$1"],[,"([3-6]\\d{3})(\\d{5})","$1 $2",["3(?:5[013-9]|[1-46-8])|4(?:[137][013-9]|6|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6[0135-9]|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])","3(?:5[013-9]|[1-46-8](?:22|[013-9]))|4(?:[137][013-9]|6(?:[013-9]|22)|[45][6-9]|8[4-6])|5(?:[1245][013-9]|6(?:3[02389]|[015689])|3|7[4-6])|6(?:[49][013-9]|5[0135-9]|[12][13-8])"],
40377"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UG:[,[,,"\\d{9}",,,,,,,[9],[5,6,7]],[,,"20(?:[0147]\\d{2}|2(?:40|[5-9]\\d)|3(?:0[0-4]|[23]\\d)|5[0-4]\\d|6[035-9]\\d|8[0-2]\\d)\\d{4}|[34]\\d{8}",,,,"312345678",,,,[5,6,7]],[,,"7(?:(?:0[0-7]|[15789]\\d|30|4[0-4])\\d|2(?:[03]\\d|60))\\d{5}",,,,"712345678"],[,,"800[123]\\d{5}",,,,"800123456"],[,,"90[123]\\d{6}",,,,"901123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UG",256,"00[057]","0",,,"0",,,,[[,"(\\d{3})(\\d{6})",
40378"$1 $2",["[7-9]|20(?:[013-8]|2[5-9])|4(?:6[45]|[7-9])"],"0$1"],[,"(\\d{2})(\\d{7})","$1 $2",["3|4(?:[1-5]|6[0-36-9])"],"0$1"],[,"(2024)(\\d{5})","$1 $2",["2024"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],US:[,[,,"[2-9]\\d{9}",,,,,,,[10],[7]],[,,"(?:2(?:0[1-35-9]|1[02-9]|2[04589]|3[149]|4[08]|5[1-46]|6[0279]|7[026]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[0-24679]|4[67]|5[12]|6[014]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|58|6[39]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[19]|6[1-47]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[16]|5[017]|6[0-279]|78|8[012])|7(?:0[1-46-8]|1[02-9]|2[0457]|3[1247]|4[037]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[014678]|4[0179]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
40379,,,"2015550123",,,,[7]],[,,"(?:2(?:0[1-35-9]|1[02-9]|2[04589]|3[149]|4[08]|5[1-46]|6[0279]|7[026]|8[13])|3(?:0[1-57-9]|1[02-9]|2[0135]|3[0-24679]|4[67]|5[12]|6[014]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[0235]|58|6[39]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[19]|6[1-47]|7[013-5]|8[056])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[16]|5[017]|6[0-279]|78|8[012])|7(?:0[1-46-8]|1[02-9]|2[0457]|3[1247]|4[037]|5[47]|6[02359]|7[02-59]|8[156])|8(?:0[1-68]|1[02-8]|28|3[0-25]|4[3578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[014678]|4[0179]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
40380,,,"2015550123",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"US",1,"011","1",,,"1",,,1,[[,"(\\d{3})(\\d{4})","$1-$2",,,,1],[,"(\\d{3})(\\d{3})(\\d{4})","($1) $2-$3",,,,1]],[[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3"]],[,,,,,,,,,[-1]],1,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UY:[,[,,"[2489]\\d{6,7}",,,,,,,[7,8]],[,,"2\\d{7}|4[2-7]\\d{6}",,
40381,,"21231234",,,[8],[7]],[,,"9[1-9]\\d{6}",,,,"94231234",,,[8]],[,,"80[05]\\d{4}",,,,"8001234",,,[7]],[,,"90[0-8]\\d{4}",,,,"9001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UY",598,"0(?:1[3-9]\\d|0)","0"," int. ",,"0",,"00",,[[,"(\\d{4})(\\d{4})","$1 $2",["[24]"]],[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["9[1-9]"],"0$1"],[,"(\\d{3})(\\d{4})","$1 $2",["[89]0"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],UZ:[,[,,"[679]\\d{8}",,,,,,,[9],[7]],[,,"(?:6(?:1(?:22|3[124]|4[1-4]|5[123578]|64)|2(?:22|3[0-57-9]|41)|5(?:22|3[3-7]|5[024-8])|6\\d{2}|7(?:[23]\\d|7[69])|9(?:22|4[1-8]|6[135]))|7(?:0(?:5[4-9]|6[0146]|7[12456]|9[135-8])|1[12]\\d|2(?:22|3[1345789]|4[123579]|5[14])|3(?:2\\d|3[1578]|4[1-35-7]|5[1-57]|61)|4(?:2\\d|3[1-579]|7[1-79])|5(?:22|5[1-9]|6[1457])|6(?:22|3[12457]|4[13-8])|9(?:22|5[1-9])))\\d{5}",
40382,,,"662345678",,,,[7]],[,,"6(?:1(?:2(?:98|2[01])|35[0-4]|50\\d|61[23]|7(?:[01][017]|4\\d|55|9[5-9]))|2(?:11\\d|2(?:[12]1|9[01379])|5(?:[126]\\d|3[0-4])|7\\d{2})|5(?:19[01]|2(?:27|9[26])|30\\d|59\\d|7\\d{2})|6(?:2(?:1[5-9]|2[0367]|38|41|52|60)|3[79]\\d|4(?:56|83)|7(?:[07]\\d|1[017]|3[07]|4[047]|5[057]|67|8[0178]|9[79])|9[0-3]\\d)|7(?:2(?:24|3[237]|4[5-9]|7[15-8])|5(?:7[12]|8[0589])|7(?:0\\d|[39][07])|9(?:0\\d|7[079]))|9(?:2(?:1[1267]|5\\d|3[01]|7[0-4])|5[67]\\d|6(?:2[0-26]|8\\d)|7\\d{2}))\\d{4}|7(?:0\\d{3}|1(?:13[01]|6(?:0[47]|1[67]|66)|71[3-69]|98\\d)|2(?:2(?:2[79]|95)|3(?:2[5-9]|6[0-6])|57\\d|7(?:0\\d|1[17]|2[27]|3[37]|44|5[057]|66|88))|3(?:2(?:1[0-6]|21|3[469]|7[159])|33\\d|5(?:0[0-4]|5[579]|9\\d)|7(?:[0-3579]\\d|4[0467]|6[67]|8[078])|9[4-6]\\d)|4(?:2(?:29|5[0257]|6[0-7]|7[1-57])|5(?:1[0-4]|8\\d|9[5-9])|7(?:0\\d|1[024589]|2[0127]|3[0137]|[46][07]|5[01]|7[5-9]|9[079])|9(?:7[015-9]|[89]\\d))|5(?:112|2(?:0\\d|2[29]|[49]4)|3[1568]\\d|52[6-9]|7(?:0[01578]|1[017]|[23]7|4[047]|[5-7]\\d|8[78]|9[079]))|6(?:2(?:2[1245]|4[2-4])|39\\d|41[179]|5(?:[349]\\d|5[0-2])|7(?:0[017]|[13]\\d|22|44|55|67|88))|9(?:22[128]|3(?:2[0-4]|7\\d)|57[05629]|7(?:2[05-9]|3[37]|4\\d|60|7[2579]|87|9[07])))\\d{4}|9[0-57-9]\\d{7}",
40383,,,"912345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"UZ",998,"810","8",,,"8",,"8~10",,[[,"([679]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",,"8 $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VA:[,[,,"(?:0(?:878\\d{5}|6698\\d{5})|[1589]\\d{5,10}|3(?:[12457-9]\\d{8}|[36]\\d{7,9}))",,,,,,,[6,8,9,10,11]],[,,"06698\\d{5}",,,,"0669812345",,,[10]],[,,"3(?:[12457-9]\\d{8}|6\\d{7,8}|3\\d{7,9})",,,,"3123456789",,,[9,10,11]],[,,"80(?:0\\d{6}|3\\d{3})",
40384,,,"800123456",,,[6,9]],[,,"0878\\d{5}|1(?:44|6[346])\\d{6}|89(?:2\\d{3}|4(?:[0-4]\\d{2}|[5-9]\\d{4})|5(?:[0-4]\\d{2}|[5-9]\\d{6})|9\\d{6})",,,,"899123456",,,[6,8,9,10]],[,,"84(?:[08]\\d{6}|[17]\\d{3})",,,,"848123456",,,[6,9]],[,,"1(?:78\\d|99)\\d{6}",,,,"1781234567",,,[9,10]],[,,"55\\d{8}",,,,"5512345678",,,[10]],"VA",39,"00",,,,,,,,,,[,,,,,,,,,[-1]],,,[,,"848\\d{6}",,,,"848123456",,,[9]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VC:[,[,,"[5789]\\d{9}",,,,,,,[10],[7]],[,,"784(?:266|3(?:6[6-9]|7\\d|8[0-24-6])|4(?:38|5[0-36-8]|8[0-8])|5(?:55|7[0-2]|93)|638|784)\\d{4}",
40385,,,"7842661234",,,,[7]],[,,"784(?:4(?:3[0-5]|5[45]|89|9[0-58])|5(?:2[6-9]|3[0-4]))\\d{4}",,,,"7844301234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VC",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"784",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VE:[,[,,"[24589]\\d{9}",,,,,,,[10],[7]],[,,"(?:2(?:12|3[457-9]|[58][1-9]|[467]\\d|9[1-6])|50[01])\\d{7}",
40386,,,"2121234567",,,,[7]],[,,"4(?:1[24-8]|2[46])\\d{7}",,,,"4121234567"],[,,"800\\d{7}",,,,"8001234567"],[,,"900\\d{7}",,,,"9001234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VE",58,"00","0",,,"0",,,,[[,"(\\d{3})(\\d{7})","$1-$2",,"0$1","$CC $1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VG:[,[,,"[2589]\\d{9}",,,,,,,[10],[7]],[,,"284(?:(?:229|4(?:22|9[45])|774|8(?:52|6[459]))\\d{4}|496[0-5]\\d{3})",,,,"2842291234",,,,[7]],[,,"284(?:(?:3(?:0[0-3]|4[0-7]|68|9[34])|4(?:4[0-6]|68|99)|54[0-57])\\d{4}|496[6-9]\\d{3})",
40387,,,"2843001234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VG",1,"011","1",,,"1",,,,,,[,,,,,,,,,[-1]],,"284",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VI:[,[,,"[3589]\\d{9}",,,,,,,[10],[7]],[,,"340(?:2(?:01|2[0678]|44|77)|3(?:32|44)|4(?:22|7[34])|5(?:1[34]|55)|6(?:26|4[23]|77|9[023])|7(?:1[2-589]|27|7\\d)|884|998)\\d{4}",,,,"3406421234",
40388,,,[7]],[,,"340(?:2(?:01|2[0678]|44|77)|3(?:32|44)|4(?:22|7[34])|5(?:1[34]|55)|6(?:26|4[23]|77|9[023])|7(?:1[2-589]|27|7\\d)|884|998)\\d{4}",,,,"3406421234",,,,[7]],[,,"8(?:00|33|44|55|66|77|88)[2-9]\\d{6}",,,,"8002345678"],[,,"900[2-9]\\d{6}",,,,"9002345678"],[,,,,,,,,,[-1]],[,,"5(?:00|22|33|44|66|77|88)[2-9]\\d{6}",,,,"5002345678"],[,,,,,,,,,[-1]],"VI",1,"011","1",,,"1",,,1,,,[,,,,,,,,,[-1]],,"340",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],VN:[,[,,"[167]\\d{6,9}|[2-59]\\d{7,9}|8\\d{6,8}",
40389,,,,,,[7,8,9,10]],[,,"(?:2(?:0[3-9]|1[0-689]|2[0-25-9]|3[2-9]|[48][2-7]|5[124-9]|6[0-39]|7[0-7]|9[0-4679])|4\\d|5(?:0[01]|[5-9])|6(?:[0-46-8]|5[01])|7[0235])\\d{7}|8(?:[2-5]\\d|6[236]|7[13])\\d{6}",,,,"2101234567",,,[9,10]],[,,"(?:9\\d|1(?:2\\d|6[2-9]|8[68]|99))\\d{7}|8(?:6[89]|8\\d|9[89])\\d{6}",,,,"912345678",,,[9,10]],[,,"1800\\d{4,6}",,,,"1800123456",,,[8,9,10]],[,,"1900\\d{4,6}",,,,"1900123456",,,[8,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VN",84,"00","0",,,"0",,,,[[,"([17]99)(\\d{4})",
40390"$1 $2",["[17]99"],"0$1",,1],[,"([48])(\\d{4})(\\d{4})","$1 $2 $3",["4|8(?:[2-5]|6[236]|7[13])"],"0$1",,1],[,"(\\d{2})(\\d{4})(\\d{3,4})","$1 $2 $3",["2[48]|5[5-9]|6[0-46-8]|7[0235]"],"0$1",,1],[,"(80)(\\d{5})","$1 $2",["80"],"0$1",,1],[,"(69\\d)(\\d{4,5})","$1 $2",["69"],"0$1",,1],[,"(\\d{3})(\\d{4})(\\d{3})","$1 $2 $3",["2[0-35-79]|50|65"],"0$1",,1],[,"([89]\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["8(?:8|9[89])|9"],"0$1",,1],[,"(1[2689]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|8[68]|99)"],
40391"0$1",,1],[,"(86[89])(\\d{3})(\\d{3})","$1 $2 $3",["86[89]"],"0$1",,1],[,"(1[89]00)(\\d{4,6})","$1 $2",["1[89]0"],"$1",,1]],,[,,,,,,,,,[-1]],,,[,,"[17]99\\d{4}|69\\d{5,6}",,,,"1992000",,,[7,8]],[,,"[17]99\\d{4}|69\\d{5,6}|80\\d{5}",,,,"1992000",,,[7,8]],,,[,,,,,,,,,[-1]]],VU:[,[,,"[2-57-9]\\d{4,6}",,,,,,,[5,7]],[,,"(?:2[02-9]\\d|3(?:[5-7]\\d|8[0-8])|48[4-9]|88\\d)\\d{2}",,,,"22123",,,[5]],[,,"(?:5(?:7[2-5]|[0-689]\\d)|7[013-7]\\d)\\d{4}",,,,"5912345",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,
40392,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"VU",678,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[579]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"3[03]\\d{3}|900\\d{4}",,,,"30123"],,,[,,,,,,,,,[-1]]],WF:[,[,,"[4-8]\\d{5}",,,,,,,[6]],[,,"(?:50|68|72)\\d{4}",,,,"501234"],[,,"(?:50|68|72|8[23])\\d{4}",,,,"501234"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"WF",681,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40393,,[,,"[48]0\\d{4}",,,,"401234"]],WS:[,[,,"[2-8]\\d{4,6}",,,,,,,[5,6,7]],[,,"(?:[2-5]\\d|6[1-9]|84\\d{2})\\d{3}",,,,"22123",,,[5,7]],[,,"(?:60|7[25-7]\\d)\\d{4}",,,,"601234",,,[6,7]],[,,"800\\d{3}",,,,"800123",,,[6]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"WS",685,"0",,,,,,,,[[,"(8\\d{2})(\\d{3,4})","$1 $2",["8"]],[,"(7\\d)(\\d{5})","$1 $2",["7"]],[,"(\\d{5})","$1",["[2-6]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],YE:[,[,,"[1-7]\\d{6,8}",,,,
40394,,,[7,8,9],[6]],[,,"(?:1(?:7\\d|[2-68])|2[2-68]|3[2358]|4[2-58]|5[2-6]|6[3-58]|7[24-68])\\d{5}",,,,"1234567",,,[7,8],[6]],[,,"7[0137]\\d{7}",,,,"712345678",,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"YE",967,"00","0",,,"0",,,,[[,"([1-7])(\\d{3})(\\d{3,4})","$1 $2 $3",["[1-6]|7[24-68]"],"0$1"],[,"(7\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["7[0137]"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],YT:[,[,,"[268]\\d{8}",,,,,,,[9]],
40395[,,"269(?:6[0-4]|50)\\d{4}",,,,"269601234"],[,,"639(?:0[0-79]|1[019]|[26]\\d|3[09]|[45]0|7[06]|9[04-79])\\d{4}",,,,"639012345"],[,,"80\\d{7}",,,,"801234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"YT",262,"00","0",,,"0",,,,,,[,,,,,,,,,[-1]],,"269|63",[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ZA:[,[,,"[1-79]\\d{8}|8\\d{4,8}",,,,,,,[5,6,7,8,9]],[,,"(?:1[0-8]|2[1-378]|3[1-69]|4\\d|5[1346-8])\\d{7}",,,,"101234567",,,[9]],[,,"(?:6\\d|7[0-46-9])\\d{7}|8(?:[1-4]\\d{1,5}|5\\d{5})\\d{2}",
40396,,,"711234567"],[,,"80\\d{7}",,,,"801234567",,,[9]],[,,"86[2-9]\\d{6}|9[0-2]\\d{7}",,,,"862345678",,,[9]],[,,"860\\d{6}",,,,"860123456",,,[9]],[,,,,,,,,,[-1]],[,,"87\\d{7}",,,,"871234567",,,[9]],"ZA",27,"00","0",,,"0",,,,[[,"(860)(\\d{3})(\\d{3})","$1 $2 $3",["860"],"0$1"],[,"(\\d{2})(\\d{3,4})","$1 $2",["8[1-4]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{2,3})","$1 $2 $3",["8[1-4]"],"0$1"],[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[1-79]|8(?:[0-57]|6[1-9])"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,"861\\d{6}",
40397,,,"861123456",,,[9]],,,[,,,,,,,,,[-1]]],ZM:[,[,,"[289]\\d{8}",,,,,,,[9]],[,,"21[1-8]\\d{6}",,,,"211234567"],[,,"9(?:5[034589]|[67]\\d)\\d{6}",,,,"955123456"],[,,"800\\d{6}",,,,"800123456"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"ZM",260,"00","0",,,"0",,,,[[,"([29]\\d)(\\d{7})","$1 $2",["[29]"],"0$1"],[,"(800)(\\d{3})(\\d{3})","$1 $2 $3",["8"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],ZW:[,[,,"2(?:[0-2457-9]\\d{3,8}|6(?:[14]\\d{7}|\\d{4}))|[13-79]\\d{4,9}|8[06]\\d{5,8}",
40398,,,,,,[5,6,7,8,9,10],[3,4]],[,,"(?:2(?:0(?:4\\d|5\\d{2})|2[278]\\d|48\\d|7(?:[1-7]\\d|[089]\\d{2})|8(?:[2-57-9]|[146]\\d{2})|98)|3(?:08|17|3[78]|7(?:[19]|[56]\\d)|8[37]|98)|5[15][78]|6(?:28\\d{2}|37|6[78]|75\\d|98|8(?:7\\d|8)))\\d{3}|(?:2(?:1[39]|2[0157]|31|[56][14]|7[35]|84)|329)\\d{7}|(?:1(?:3\\d{2}|[4-8]|9\\d)|2(?:0\\d{2}|12|292|[569]\\d)|3(?:[26]|[013459]\\d)|5(?:0|1[2-4]|26|[37]2|5\\d{2}|[689]\\d)|6(?:[39]|[01246]\\d|[78]\\d{2}))\\d{3}|(?:29\\d|39|54)\\d{6}|(?:(?:25|54)83\\d|2582\\d{2}|65[2-8])\\d{2}|(?:4\\d{6,7}|9[2-9]\\d{4,5})",
40399,,,"1312345",,,,[3,4]],[,,"(?:7(?:1[2-8]|3[2-9]|7[1-9]|8[2-5])|8644)\\d{6}",,,,"712345678",,,[9,10]],[,,"80(?:[01]\\d|20|8[0-8])\\d{3}",,,,"8001234",,,[7]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"86(?:1[12]|30|55|77|8[368])\\d{6}",,,,"8686123456",,,[10]],"ZW",263,"00","0",,,"0",,,,[[,"([49])(\\d{3})(\\d{2,4})","$1 $2 $3",["4|9[2-9]"],"0$1"],[,"(7\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["7"],"0$1"],[,"(86\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["86[24]"],"0$1"],[,"([2356]\\d{2})(\\d{3,5})","$1 $2",
40400["2(?:0[45]|2[278]|[49]8|[78])|3(?:08|17|3[78]|7[1569]|8[37]|98)|5[15][78]|6(?:[29]8|[38]7|6[78]|75|[89]8)"],"0$1"],[,"(\\d{3})(\\d{3})(\\d{3,4})","$1 $2 $3",["2(?:1[39]|2[0157]|31|[56][14]|7[35]|84)|329"],"0$1"],[,"([1-356]\\d)(\\d{3,5})","$1 $2",["1[3-9]|2[02569]|3[0-69]|5[05689]|6\\d"],"0$1"],[,"([235]\\d)(\\d{3})(\\d{3,4})","$1 $2 $3",["[23]9|54"],"0$1"],[,"([25]\\d{3})(\\d{3,5})","$1 $2",["(?:25|54)8","258[23]|5483"],"0$1"],[,"(8\\d{3})(\\d{6})","$1 $2",["86"],"0$1"],[,"(80\\d)(\\d{4})","$1 $2",
40401["80"],"0$1"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],800:[,[,,"\\d{8}",,,,,,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{8}",,,,"12345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",800,,,,,,,,1,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],808:[,[,,"\\d{8}",,,,,,,[8]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{8}",,,,"12345678"],[,,,,,,,,,[-1]],[,,,,,,
40402,,,[-1]],"001",808,,,,,,,,1,[[,"(\\d{4})(\\d{4})","$1 $2"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],870:[,[,,"[35-7]\\d{8}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,"(?:[356]\\d|7[6-8])\\d{7}",,,,"301234567"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",870,,,,,,,,,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],878:[,[,,"1\\d{11}",,,,,,,[12]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],
40403[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"10\\d{10}",,,,"101234567890"],"001",878,,,,,,,,1,[[,"(\\d{2})(\\d{5})(\\d{5})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],881:[,[,,"[67]\\d{8}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,"[67]\\d{8}",,,,"612345678"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",881,,,,,,,,,[[,"(\\d)(\\d{3})(\\d{5})","$1 $2 $3",["[67]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,
40404,,[-1]],,,[,,,,,,,,,[-1]]],882:[,[,,"[13]\\d{6,11}",,,,,,,[7,8,9,10,11,12]],[,,,,,,,,,[-1]],[,,"3(?:2\\d{3}|37\\d{2}|4(?:2|7\\d{3}))\\d{4}",,,,"3421234",,,[7,9,10]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"1(?:3(?:0[0347]|[13][0139]|2[035]|4[013568]|6[0459]|7[06]|8[15678]|9[0689])\\d{4}|6\\d{5,10})|3(?:45|9\\d{3})\\d{7}",,,,"390123456789"],"001",882,,,,,,,,,[[,"(\\d{2})(\\d{4})(\\d{3})","$1 $2 $3",["3[23]"]],[,"(\\d{2})(\\d{5})","$1 $2",["16|342"]],[,"(\\d{2})(\\d{4})(\\d{4})",
40405"$1 $2 $3",["34[57]"]],[,"(\\d{3})(\\d{4})(\\d{4})","$1 $2 $3",["348"]],[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",["1"]],[,"(\\d{2})(\\d{3,4})(\\d{4})","$1 $2 $3",["16"]],[,"(\\d{2})(\\d{4,5})(\\d{5})","$1 $2 $3",["16|39"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,"348[57]\\d{7}",,,,"34851234567",,,[11]]],883:[,[,,"51\\d{7}(?:\\d{3})?",,,,,,,[9,12]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"51(?:00\\d{5}(?:\\d{3})?|[13]0\\d{8})",
40406,,,"510012345"],"001",883,,,,,,,,1,[[,"(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3",["510"]],[,"(\\d{3})(\\d{3})(\\d{3})(\\d{3})","$1 $2 $3 $4",["510"]],[,"(\\d{4})(\\d{4})(\\d{4})","$1 $2 $3",["51[13]"]]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]],888:[,[,,"\\d{11}",,,,,,,[11]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",888,,,,,,,,1,[[,"(\\d{3})(\\d{3})(\\d{5})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,
40407,[-1]],[,,"\\d{11}",,,,"12345678901"],,,[,,,,,,,,,[-1]]],979:[,[,,"\\d{9}",,,,,,,[9]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,"\\d{9}",,,,"123456789"],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],"001",979,,,,,,,,1,[[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3"]],,[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]],[,,,,,,,,,[-1]],,,[,,,,,,,,,[-1]]]};/*
40408
40409 Copyright (C) 2010 The Libphonenumber Authors.
40410
40411 Licensed under the Apache License, Version 2.0 (the "License");
40412 you may not use this file except in compliance with the License.
40413 You may obtain a copy of the License at
40414
40415 http://www.apache.org/licenses/LICENSE-2.0
40416
40417 Unless required by applicable law or agreed to in writing, software
40418 distributed under the License is distributed on an "AS IS" BASIS,
40419 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40420 See the License for the specific language governing permissions and
40421 limitations under the License.
40422*/
40423function Q(){this.a={}}Q.a=function(){return Q.b?Q.b:Q.b=new Q};
40424var ya={0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9","\uff10":"0","\uff11":"1","\uff12":"2","\uff13":"3","\uff14":"4","\uff15":"5","\uff16":"6","\uff17":"7","\uff18":"8","\uff19":"9","\u0660":"0","\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u06f0":"0","\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9"},Aa={0:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",
404257:"7",8:"8",9:"9","\uff10":"0","\uff11":"1","\uff12":"2","\uff13":"3","\uff14":"4","\uff15":"5","\uff16":"6","\uff17":"7","\uff18":"8","\uff19":"9","\u0660":"0","\u0661":"1","\u0662":"2","\u0663":"3","\u0664":"4","\u0665":"5","\u0666":"6","\u0667":"7","\u0668":"8","\u0669":"9","\u06f0":"0","\u06f1":"1","\u06f2":"2","\u06f3":"3","\u06f4":"4","\u06f5":"5","\u06f6":"6","\u06f7":"7","\u06f8":"8","\u06f9":"9",A:"2",B:"2",C:"2",D:"3",E:"3",F:"3",G:"4",H:"4",I:"4",J:"5",K:"5",L:"5",M:"6",N:"6",O:"6",P:"7",
40426Q:"7",R:"7",S:"7",T:"8",U:"8",V:"8",W:"9",X:"9",Y:"9",Z:"9"},R=RegExp("^[+\uff0b]+"),Ba=RegExp("([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9])"),Ca=RegExp("[+\uff0b0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]"),Da=/[\\\/] *x/,Ea=RegExp("[^0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9A-Za-z#]+$"),Fa=/(?:.*?[A-Za-z]){3}.*/,Ga=RegExp("(?:;ext=([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})|[ \u00a0\\t,]*(?:e?xt(?:ensi(?:o\u0301?|\u00f3))?n?|\uff45?\uff58\uff54\uff4e?|[;,x\uff58#\uff03~\uff5e]|int|anexo|\uff49\uff4e\uff54)[:\\.\uff0e]?[ \u00a0\\t,-]*([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})#?|[- ]+([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,5})#)$",
40427"i"),Ha=RegExp("^[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{2}$|^[+\uff0b]*(?:[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e*]*[0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]){3,}[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e*A-Za-z0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]*(?:;ext=([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})|[ \u00a0\\t,]*(?:e?xt(?:ensi(?:o\u0301?|\u00f3))?n?|\uff45?\uff58\uff54\uff4e?|[;,x\uff58#\uff03~\uff5e]|int|anexo|\uff49\uff4e\uff54)[:\\.\uff0e]?[ \u00a0\\t,-]*([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,7})#?|[- ]+([0-9\uff10-\uff19\u0660-\u0669\u06f0-\u06f9]{1,5})#)?$",
40428"i"),Ia=/(\$\d)/;function Ja(a){var b=a.search(Ca);0<=b?(a=a.substring(b),a=a.replace(Ea,""),b=a.search(Da),0<=b&&(a=a.substring(0,b))):a="";return a}function Ka(a){return 2>a.length?!1:S(Ha,a)}function La(a){return S(Fa,a)?Ma(a,Aa):Ma(a,ya)}function Na(a){var b=La(a.toString());a.b="";a.a(b)}function Oa(a){return!!a&&(1!=G(a,9)||-1!=D(a,9)[0])}function Ma(a,b){for(var c=new K,d,e=a.length,f=0;f<e;++f)d=a.charAt(f),d=b[d.toUpperCase()],null!=d&&c.a(d);return c.toString()}
40429function Pa(a){return null!=a&&isNaN(a)&&a.toUpperCase()in xa}
40430function Qa(a,b,c){if(0==B(b,2)&&null!=b.a[5]){var d=F(b,5);if(0<d.length)return d}var d=F(b,1),e=T(b);if(0==c)return Ra(d,0,e,"");if(!(d in P))return e;a=U(a,d,Sa(d));b=null!=b.a[3]&&B(b,3).length?3==c?";ext="+B(b,3):null!=a.a[13]?B(a,13)+F(b,3):" ext. "+F(b,3):"";a:{a=D(a,20).length&&2!=c?D(a,20):D(a,19);for(var f,g=a.length,h=0;h<g;++h){f=a[h];var k=G(f,3);if(!k||!e.search(B(f,3,k-1)))if(k=new RegExp(B(f,1)),S(k,e)){a=f;break a}}a=null}a&&(g=a,a=F(g,2),f=new RegExp(B(g,1)),F(g,5),g=F(g,4),e=2==
40431c&&null!=g&&0<g.length?e.replace(f,a.replace(Ia,g)):e.replace(f,a),3==c&&(e=e.replace(RegExp("^[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e]+"),""),e=e.replace(RegExp("[-x\u2010-\u2015\u2212\u30fc\uff0d-\uff0f \u00a0\u00ad\u200b\u2060\u3000()\uff08\uff09\uff3b\uff3d.\\[\\]/~\u2053\u223c\uff5e]+","g"),"-")));return Ra(d,c,e,b)}function U(a,b,c){return"001"==c?V(a,""+b):V(a,c)}
40432function T(a){if(null==a.a[2])return"";var b=""+B(a,2);return null!=a.a[4]&&B(a,4)&&0<F(a,8)?Array(F(a,8)+1).join("0")+b:b}function Ra(a,b,c,d){switch(b){case 0:return"+"+a+c+d;case 1:return"+"+a+" "+c+d;case 3:return"tel:+"+a+"-"+c+d;default:return c+d}}
40433function W(a,b){switch(b){case 4:return B(a,5);case 3:return B(a,4);case 1:return B(a,3);case 0:case 2:return B(a,2);case 5:return B(a,6);case 6:return B(a,8);case 7:return B(a,7);case 8:return B(a,21);case 9:return B(a,25);case 10:return B(a,28);default:return B(a,1)}}function Ta(a,b){return X(a,B(b,1))?X(a,B(b,5))?4:X(a,B(b,4))?3:X(a,B(b,6))?5:X(a,B(b,8))?6:X(a,B(b,7))?7:X(a,B(b,21))?8:X(a,B(b,25))?9:X(a,B(b,28))?10:X(a,B(b,2))?B(b,18)||X(a,B(b,3))?2:0:!B(b,18)&&X(a,B(b,3))?1:-1:-1}
40434function V(a,b){if(null==b)return null;b=b.toUpperCase();var c=a.a[b];if(!c){c=xa[b];if(!c)return null;c=(new ra).b(N.f(),c);a.a[b]=c}return c}function X(a,b){var c=a.length;return 0<G(b,9)&&-1==x(D(b,9),c)?!1:S(F(b,2),a)}function Ua(a,b){if(!b)return null;var c=F(b,1);if(c=P[c])if(1==c.length)c=c[0];else a:{for(var d=T(b),e,f=c.length,g=0;g<f;g++){e=c[g];var h=V(a,e);if(null!=h.a[23]){if(!d.search(B(h,23))){c=e;break a}}else if(-1!=Ta(d,h)){c=e;break a}}c=null}else c=null;return c}
40435function Sa(a){return(a=P[a])?a[0]:"ZZ"}function Y(a,b,c,d){var e=W(c,d),f=G(e,9)?D(e,9):D(B(c,1),9),e=D(e,10);if(2==d)if(Oa(W(c,0)))a=W(c,1),Oa(a)&&(f=f.concat(G(a,9)?D(a,9):D(B(c,1),9)),y(f),e.length?(e=e.concat(D(a,10)),y(e)):e=D(a,10));else return Y(a,b,c,1);if(-1==f[0])return 5;b=b.length;if(-1<x(e,b))return 4;c=f[0];return c==b?0:c>b?2:f[f.length-1]<b?3:-1<x(f,b,1)?0:5}
40436function Va(a,b,c,d,e,f){if(!b.length)return 0;b=new K(b);var g;c&&(g=B(c,11));null==g&&(g="NonMatch");var h=b.toString();if(h.length)if(R.test(h))h=h.replace(R,""),b.b="",b.a(La(h)),g=1;else{h=new RegExp(g);Na(b);g=b.toString();if(g.search(h))g=!1;else{var h=g.match(h)[0].length,k=g.substring(h).match(Ba);k&&null!=k[1]&&0<k[1].length&&"0"==Ma(k[1],ya)?g=!1:(b.b="",b.a(g.substring(h)),g=!0)}g=g?5:20}else g=20;e&&C(f,6,g);if(20!=g){if(2>=b.b.length)throw Error("Phone number too short after IDD");a:{a=
40437b.toString();if(a.length&&"0"!=a.charAt(0))for(e=a.length,b=1;3>=b&&b<=e;++b)if(c=parseInt(a.substring(0,b),10),c in P){d.a(a.substring(b));d=c;break a}d=0}if(d)return C(f,1,d),d;throw Error("Invalid country calling code");}if(c&&(g=F(c,10),h=""+g,k=b.toString(),!k.lastIndexOf(h,0)&&(h=new K(k.substring(h.length)),k=B(c,1),k=new RegExp(F(k,2)),Wa(h,c,null),h=h.toString(),!S(k,b.toString())&&S(k,h)||3==Y(a,b.toString(),c,-1))))return d.a(h),e&&C(f,6,10),C(f,1,g),g;C(f,1,0);return 0}
40438function Wa(a,b,c){var d=a.toString(),e=d.length,f=B(b,15);if(e&&null!=f&&f.length){var g=new RegExp("^(?:"+f+")");if(e=g.exec(d)){var f=new RegExp(F(B(b,1),2)),h=S(f,d),k=e.length-1;b=B(b,16);if(null!=b&&b.length&&null!=e[k]&&e[k].length){if(d=d.replace(g,b),!h||S(f,d))c&&0<k&&c.a(e[1]),a.set(d)}else if(!h||S(f,d.substring(e[0].length)))c&&0<k&&null!=e[k]&&c.a(e[1]),a.set(d.substring(e[0].length))}}}
40439function Z(a,b,c){if(!Pa(c)&&0<b.length&&"+"!=b.charAt(0))throw Error("Invalid country calling code");return Xa(a,b,c,!0)}
40440function Xa(a,b,c,d){if(null==b)throw Error("The string supplied did not seem to be a phone number");if(250<b.length)throw Error("The string supplied is too long to be a phone number");var e=new K,f=b.indexOf(";phone-context=");if(0<=f){var g=f+15;if("+"==b.charAt(g)){var h=b.indexOf(";",g);0<h?e.a(b.substring(g,h)):e.a(b.substring(g))}g=b.indexOf("tel:");e.a(b.substring(0<=g?g+4:0,f))}else e.a(Ja(b));f=e.toString();g=f.indexOf(";isub=");0<g&&(e.b="",e.a(f.substring(0,g)));if(!Ka(e.toString()))throw Error("The string supplied did not seem to be a phone number");
40441f=e.toString();if(!(Pa(c)||null!=f&&0<f.length&&R.test(f)))throw Error("Invalid country calling code");f=new O;d&&C(f,5,b);a:{b=e.toString();g=b.search(Ga);if(0<=g&&Ka(b.substring(0,g)))for(var h=b.match(Ga),k=h.length,q=1;q<k;++q)if(null!=h[q]&&0<h[q].length){e.b="";e.a(b.substring(0,g));b=h[q];break a}b=""}0<b.length&&C(f,3,b);g=V(a,c);b=new K;h=0;k=e.toString();try{h=Va(a,k,g,b,d,f)}catch(z){if("Invalid country calling code"==z.message&&R.test(k)){if(k=k.replace(R,""),h=Va(a,k,g,b,d,f),!h)throw z;
40442}else throw z;}h?(e=Sa(h),e!=c&&(g=U(a,h,e))):(Na(e),b.a(e.toString()),null!=c?(h=F(g,10),C(f,1,h)):d&&(delete f.a[6],f.b&&delete f.b[6]));if(2>b.b.length)throw Error("The string supplied is too short to be a phone number");g&&(c=new K,e=new K(b.toString()),Wa(e,g,c),a=Y(a,e.toString(),g,-1),2!=a&&4!=a&&5!=a&&(b=e,d&&0<c.toString().length&&C(f,7,c.toString())));d=b.toString();a=d.length;if(2>a)throw Error("The string supplied is too short to be a phone number");if(17<a)throw Error("The string supplied is too long to be a phone number");
40443if(1<d.length&&"0"==d.charAt(0)){C(f,4,!0);for(a=1;a<d.length-1&&"0"==d.charAt(a);)a++;1!=a&&C(f,8,a)}C(f,2,parseInt(d,10));return f}function S(a,b){var c="string"==typeof a?b.match("^(?:"+a+")$"):b.match(a);return c&&c[0].length==b.length?!0:!1};v("intlTelInputUtils",{});v("intlTelInputUtils.formatNumber",function(a,b,c){try{var d=Q.a(),e=Z(d,a,b);return Qa(d,e,"undefined"==typeof c?0:c)}catch(f){return a}});v("intlTelInputUtils.getExampleNumber",function(a,b,c){try{var d=Q.a(),e;a:{if(Pa(a)){var f=W(V(d,a),c);try{if(null!=f.a[6]){var g=B(f,6);e=Xa(d,g,a,!1);break a}}catch(h){}}e=null}return Qa(d,e,b?2:1)}catch(h){return""}});v("intlTelInputUtils.getExtension",function(a,b){try{return B(Z(Q.a(),a,b),3)}catch(c){return""}});
40444v("intlTelInputUtils.getNumberType",function(a,b){try{var c=Q.a(),d;var e=Z(c,a,b),f=Ua(c,e),g=U(c,F(e,1),f);if(g){var h=T(e);d=Ta(h,g)}else d=-1;return d}catch(k){return-99}});
40445v("intlTelInputUtils.getValidationError",function(a,b){try{var c=Q.a(),d;var e=Z(c,a,b),f=T(e),g=F(e,1);if(g in P){var h=U(c,g,Sa(g));d=Y(c,f,h,-1)}else d=1;return d}catch(k){return"Invalid country calling code"==k.message?1:"The string supplied did not seem to be a phone number"==k.message?4:"Phone number too short after IDD"==k.message||"The string supplied is too short to be a phone number"==k?2:"The string supplied is too long to be a phone number"==k.message?3:-99}});
40446v("intlTelInputUtils.isValidNumber",function(a,b){try{var c=Q.a(),d=Z(c,a,b),e;var f=Ua(c,d),g=F(d,1),h=U(c,g,f),k;if(!(k=!h)){var q;if(q="001"!=f){var z,za=V(c,f);if(!za)throw Error("Invalid region code: "+f);z=F(za,10);q=g!=z}k=q}if(k)e=!1;else{var Ya=T(d);e=-1!=Ta(Ya,h)}return e}catch(Za){return!1}});v("intlTelInputUtils.numberFormat",{E164:0,INTERNATIONAL:1,NATIONAL:2,RFC3966:3});
40447v("intlTelInputUtils.numberType",{FIXED_LINE:0,MOBILE:1,FIXED_LINE_OR_MOBILE:2,TOLL_FREE:3,PREMIUM_RATE:4,SHARED_COST:5,VOIP:6,PERSONAL_NUMBER:7,PAGER:8,UAN:9,VOICEMAIL:10,UNKNOWN:-1});v("intlTelInputUtils.validationError",{IS_POSSIBLE:0,INVALID_COUNTRY_CODE:1,TOO_SHORT:2,TOO_LONG:3,NOT_A_NUMBER:4});})();
40448
40449/**
40450 * WHMCS Telephone Country Code Dropdown
40451 *
40452 * Using https://github.com/jackocnr/intl-tel-input
40453 *
40454 * @copyright Copyright (c) WHMCS Limited 2005-2019
40455 * @license https://www.whmcs.com/license/ WHMCS Eula
40456 */
40457
40458jQuery(document).ready(function() {
40459 if (typeof customCountryData !== "undefined") {
40460 var teleCountryData = $.fn['intlTelInput'].getCountryData();
40461 for (var code in customCountryData) {
40462 if (customCountryData.hasOwnProperty(code)) {
40463 var countryDetails = customCountryData[code];
40464 codeLower = code.toLowerCase();
40465 if (countryDetails === false) {
40466 for (var i = 0; i < teleCountryData.length; i++) {
40467 if (codeLower === teleCountryData[i].iso2) {
40468 teleCountryData.splice(i, 1);
40469 break;
40470 }
40471 }
40472 } else {
40473 teleCountryData.push(
40474 {
40475 name: countryDetails.name,
40476 iso2: codeLower,
40477 dialCode: countryDetails.callingCode,
40478 priority: 0,
40479 areaCodes: null
40480 }
40481 );
40482 }
40483 }
40484 }
40485 }
40486
40487 if (jQuery('body').data('phone-cc-input')) {
40488 var phoneInput = jQuery('input[name^="phone"], input[name$="phone"], input[name="domaincontactphonenumber"]').not('input[type="hidden"]');
40489 if (phoneInput.length) {
40490 var countryInput = jQuery('[name^="country"], [name$="country"]'),
40491 initialCountry = 'us';
40492 if (countryInput.length) {
40493 initialCountry = countryInput.val().toLowerCase();
40494 if (initialCountry === 'um') {
40495 initialCountry = 'us';
40496 }
40497 }
40498
40499 phoneInput.each(function(){
40500 var thisInput = jQuery(this),
40501 inputName = thisInput.attr('name');
40502 if (inputName === 'domaincontactphonenumber') {
40503 initialCountry = jQuery('[name="domaincontactcountry"]').val().toLowerCase();
40504 }
40505 jQuery(this).before(
40506 '<input id="populatedCountryCode' + inputName + '" type="hidden" name="country-calling-code-' + inputName + '" value="" />'
40507 );
40508 thisInput.intlTelInput({
40509 preferredCountries: [initialCountry, "us", "gb"].filter(function(value, index, self) {
40510 return self.indexOf(value) === index;
40511 }),
40512 initialCountry: initialCountry,
40513 autoPlaceholder: 'polite', //always show the helper placeholder
40514 separateDialCode: true
40515 });
40516
40517 thisInput.on('countrychange', function (e, countryData) {
40518 jQuery('#populatedCountryCode' + inputName).val(countryData.dialCode);
40519 if (jQuery(this).val() === '+' + countryData.dialCode) {
40520 jQuery(this).val('');
40521 }
40522 });
40523 thisInput.on('blur keydown', function (e) {
40524 if (e.type === 'blur' || (e.type === 'keydown' && e.keyCode === 13)) {
40525 var number = jQuery(this).intlTelInput("getNumber"),
40526 countryData = jQuery(this).intlTelInput("getSelectedCountryData"),
40527 countryPrefix = '+' + countryData.dialCode;
40528
40529 if (number.indexOf(countryPrefix) === 0 && (number.match(/\+/g) || []).length > 1) {
40530 number = number.substr(countryPrefix.length);
40531 }
40532 jQuery(this).intlTelInput("setNumber", number);
40533 }
40534 });
40535 jQuery('#populatedCountryCode' + inputName).val(thisInput.intlTelInput('getSelectedCountryData').dialCode);
40536
40537 countryInput.on('change', function() {
40538 if (thisInput.val() === '') {
40539 var country = jQuery(this).val().toLowerCase();
40540 if (country === 'um') {
40541 country = 'us';
40542 }
40543 phoneInput.intlTelInput('setCountry', country);
40544 }
40545 });
40546
40547 // this must be .attr (not .data) in order for it to be found by [data-initial-value] selector
40548 thisInput.attr('data-initial-value', $(thisInput).val());
40549
40550 thisInput.parents('form').find('input[type=reset]').each(function() {
40551 var resetButton = this;
40552 var form = $(resetButton).parents('form');
40553
40554 if (!$(resetButton).data('phone-handler')) {
40555 $(resetButton).data('phone-handler', true);
40556
40557 $(resetButton).click(function(e) {
40558 e.stopPropagation();
40559
40560 $(form).trigger('reset');
40561
40562 $(form).find('input[data-initial-value]').each(function() {
40563 var inputToReset = this;
40564
40565 $(inputToReset).val(
40566 $(inputToReset).attr('data-initial-value')
40567 );
40568 });
40569
40570 return false;
40571 });
40572 }
40573 });
40574 });
40575
40576 /**
40577 * In places where a form icon is present, hide it.
40578 * Where the input has a class of field, remove that and add form-control in place.
40579 */
40580 phoneInput.parents('div.form-group').find('.field-icon').hide().end();
40581 phoneInput.removeClass('field').addClass('form-control');
40582 }
40583
40584 var registrarPhoneInput = jQuery('input[name$="][Phone Number]"], input[name$="][Phone]"]').not('input[type="hidden"]');
40585 if (registrarPhoneInput.length) {
40586 jQuery.each(registrarPhoneInput, function(index, input) {
40587 var thisInput = jQuery(this),
40588 inputName = thisInput.attr('name');
40589 inputName = inputName.replace('contactdetails[', '').replace('][Phone Number]', '').replace('][Phone]', '');
40590
40591 var countryInput = jQuery('[name$="' + inputName + '][Country]"]'),
40592 initialCountry = countryInput.val().toLowerCase();
40593 if (initialCountry === 'um') {
40594 initialCountry = 'us';
40595 }
40596
40597 thisInput.before('<input id="populated' + inputName + 'CountryCode" class="' + inputName + 'customwhois" type="hidden" name="contactdetails[' + inputName + '][Phone Country Code]" value="" />');
40598 thisInput.intlTelInput({
40599 preferredCountries: [initialCountry, "us", "gb"].filter(function(value, index, self) {
40600 return self.indexOf(value) === index;
40601 }),
40602 initialCountry: initialCountry,
40603 autoPlaceholder: 'polite', //always show the helper placeholder
40604 separateDialCode: true
40605 });
40606
40607 thisInput.on('countrychange', function (e, countryData) {
40608 jQuery('#populated' + inputName + 'CountryCode').val(countryData.dialCode);
40609 if (jQuery(this).val() === '+' + countryData.dialCode) {
40610 jQuery(this).val('');
40611 }
40612 });
40613 thisInput.on('blur keydown', function (e) {
40614 if (e.type === 'blur' || (e.type === 'keydown' && e.keyCode === 13)) {
40615 var number = jQuery(this).intlTelInput("getNumber"),
40616 countryData = jQuery(this).intlTelInput("getSelectedCountryData"),
40617 countryPrefix = '+' + countryData.dialCode;
40618
40619 if (number.indexOf(countryPrefix) === 0 && (number.match(/\+/g) || []).length > 1) {
40620 number = number.substr(countryPrefix.length);
40621 }
40622 jQuery(this).intlTelInput("setNumber", number);
40623 }
40624 });
40625 jQuery('#populated' + inputName + 'CountryCode').val(thisInput.intlTelInput('getSelectedCountryData').dialCode);
40626
40627 countryInput.on('blur', function() {
40628 if (thisInput.val() === '') {
40629 var country = jQuery(this).val().toLowerCase();
40630 if (country === 'um') {
40631 country = 'us';
40632 }
40633 thisInput.intlTelInput('setCountry', country);
40634 }
40635 });
40636
40637 });
40638 }
40639 }
40640});
40641
40642/*!
40643 * Lightbox v2.8.1
40644 * by Lokesh Dhakar
40645 *
40646 * More info:
40647 * http://lokeshdhakar.com/projects/lightbox2/
40648 *
40649 * Copyright 2007, 2015 Lokesh Dhakar
40650 * Released under the MIT license
40651 * https://github.com/lokesh/lightbox2/blob/master/LICENSE
40652 */
40653
40654// Uses Node, AMD or browser globals to create a module.
40655(function (root, factory) {
40656 if (typeof define === 'function' && define.amd) {
40657 // AMD. Register as an anonymous module.
40658 define(['jquery'], factory);
40659 } else if (typeof exports === 'object') {
40660 // Node. Does not work with strict CommonJS, but
40661 // only CommonJS-like environments that support module.exports,
40662 // like Node.
40663 module.exports = factory(require('jquery'));
40664 } else {
40665 // Browser globals (root is window)
40666 root.lightbox = factory(root.jQuery);
40667 }
40668}(this, function ($) {
40669
40670 function Lightbox(options) {
40671 this.album = [];
40672 this.currentImageIndex = void 0;
40673 this.init();
40674
40675 // options
40676 this.options = $.extend({}, this.constructor.defaults);
40677 this.option(options);
40678 }
40679
40680 // Descriptions of all options available on the demo site:
40681 // http://lokeshdhakar.com/projects/lightbox2/index.html#options
40682 Lightbox.defaults = {
40683 albumLabel: 'Image %1 of %2',
40684 alwaysShowNavOnTouchDevices: false,
40685 fadeDuration: 500,
40686 fitImagesInViewport: true,
40687 // maxWidth: 800,
40688 // maxHeight: 600,
40689 positionFromTop: 50,
40690 resizeDuration: 700,
40691 showImageNumberLabel: true,
40692 wrapAround: false
40693 };
40694
40695 Lightbox.prototype.option = function(options) {
40696 $.extend(this.options, options);
40697 };
40698
40699 Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
40700 return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
40701 };
40702
40703 Lightbox.prototype.init = function() {
40704 this.enable();
40705 this.build();
40706 };
40707
40708 // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
40709 // that contain 'lightbox'. When these are clicked, start lightbox.
40710 Lightbox.prototype.enable = function() {
40711 var self = this;
40712 $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
40713 self.start($(event.currentTarget));
40714 return false;
40715 });
40716 };
40717
40718 // Build html for the lightbox and the overlay.
40719 // Attach event handlers to the new DOM elements. click click click
40720 Lightbox.prototype.build = function() {
40721 var self = this;
40722 $('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body'));
40723
40724 // Cache jQuery objects
40725 this.$lightbox = $('#lightbox');
40726 this.$overlay = $('#lightboxOverlay');
40727 this.$outerContainer = this.$lightbox.find('.lb-outerContainer');
40728 this.$container = this.$lightbox.find('.lb-container');
40729
40730 // Store css values for future lookup
40731 this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10);
40732 this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10);
40733 this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10);
40734 this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10);
40735
40736 // Attach event handlers to the newly minted DOM elements
40737 this.$overlay.hide().on('click', function() {
40738 self.end();
40739 return false;
40740 });
40741
40742 this.$lightbox.hide().on('click', function(event) {
40743 if ($(event.target).attr('id') === 'lightbox') {
40744 self.end();
40745 }
40746 return false;
40747 });
40748
40749 this.$outerContainer.on('click', function(event) {
40750 if ($(event.target).attr('id') === 'lightbox') {
40751 self.end();
40752 }
40753 return false;
40754 });
40755
40756 this.$lightbox.find('.lb-prev').on('click', function() {
40757 if (self.currentImageIndex === 0) {
40758 self.changeImage(self.album.length - 1);
40759 } else {
40760 self.changeImage(self.currentImageIndex - 1);
40761 }
40762 return false;
40763 });
40764
40765 this.$lightbox.find('.lb-next').on('click', function() {
40766 if (self.currentImageIndex === self.album.length - 1) {
40767 self.changeImage(0);
40768 } else {
40769 self.changeImage(self.currentImageIndex + 1);
40770 }
40771 return false;
40772 });
40773
40774 this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
40775 self.end();
40776 return false;
40777 });
40778 };
40779
40780 // Show overlay and lightbox. If the image is part of a set, add siblings to album array.
40781 Lightbox.prototype.start = function($link) {
40782 var self = this;
40783 var $window = $(window);
40784
40785 $window.on('resize', $.proxy(this.sizeOverlay, this));
40786
40787 $('select, object, embed').css({
40788 visibility: 'hidden'
40789 });
40790
40791 this.sizeOverlay();
40792
40793 this.album = [];
40794 var imageNumber = 0;
40795
40796 function addToAlbum($link) {
40797 self.album.push({
40798 link: $link.attr('href'),
40799 title: $link.attr('data-title') || $link.attr('title')
40800 });
40801 }
40802
40803 // Support both data-lightbox attribute and rel attribute implementations
40804 var dataLightboxValue = $link.attr('data-lightbox');
40805 var $links;
40806
40807 if (dataLightboxValue) {
40808 $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');
40809 for (var i = 0; i < $links.length; i = ++i) {
40810 addToAlbum($($links[i]));
40811 if ($links[i] === $link[0]) {
40812 imageNumber = i;
40813 }
40814 }
40815 } else {
40816 if ($link.attr('rel') === 'lightbox') {
40817 // If image is not part of a set
40818 addToAlbum($link);
40819 } else {
40820 // If image is part of a set
40821 $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
40822 for (var j = 0; j < $links.length; j = ++j) {
40823 addToAlbum($($links[j]));
40824 if ($links[j] === $link[0]) {
40825 imageNumber = j;
40826 }
40827 }
40828 }
40829 }
40830
40831 // Position Lightbox
40832 var top = $window.scrollTop() + this.options.positionFromTop;
40833 var left = $window.scrollLeft();
40834 this.$lightbox.css({
40835 top: top + 'px',
40836 left: left + 'px'
40837 }).fadeIn(this.options.fadeDuration);
40838
40839 this.changeImage(imageNumber);
40840 };
40841
40842 // Hide most UI elements in preparation for the animated resizing of the lightbox.
40843 Lightbox.prototype.changeImage = function(imageNumber) {
40844 var self = this;
40845
40846 this.disableKeyboardNav();
40847 var $image = this.$lightbox.find('.lb-image');
40848
40849 this.$overlay.fadeIn(this.options.fadeDuration);
40850
40851 $('.lb-loader').fadeIn('slow');
40852 this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();
40853
40854 this.$outerContainer.addClass('animating');
40855
40856 // When image to show is preloaded, we send the width and height to sizeContainer()
40857 var preloader = new Image();
40858 preloader.onload = function() {
40859 var $preloader;
40860 var imageHeight;
40861 var imageWidth;
40862 var maxImageHeight;
40863 var maxImageWidth;
40864 var windowHeight;
40865 var windowWidth;
40866
40867 $image.attr('src', self.album[imageNumber].link);
40868
40869 $preloader = $(preloader);
40870
40871 $image.width(preloader.width);
40872 $image.height(preloader.height);
40873
40874 if (self.options.fitImagesInViewport) {
40875 // Fit image inside the viewport.
40876 // Take into account the border around the image and an additional 10px gutter on each side.
40877
40878 windowWidth = $(window).width();
40879 windowHeight = $(window).height();
40880 maxImageWidth = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20;
40881 maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120;
40882
40883 // Check if image size is larger then maxWidth|maxHeight in settings
40884 if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {
40885 maxImageWidth = self.options.maxWidth;
40886 }
40887 if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {
40888 maxImageHeight = self.options.maxHeight;
40889 }
40890
40891 // Is there a fitting issue?
40892 if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {
40893 if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {
40894 imageWidth = maxImageWidth;
40895 imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);
40896 $image.width(imageWidth);
40897 $image.height(imageHeight);
40898 } else {
40899 imageHeight = maxImageHeight;
40900 imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);
40901 $image.width(imageWidth);
40902 $image.height(imageHeight);
40903 }
40904 }
40905 }
40906 self.sizeContainer($image.width(), $image.height());
40907 };
40908
40909 preloader.src = this.album[imageNumber].link;
40910 this.currentImageIndex = imageNumber;
40911 };
40912
40913 // Stretch overlay to fit the viewport
40914 Lightbox.prototype.sizeOverlay = function() {
40915 this.$overlay
40916 .width($(window).width())
40917 .height($(document).height());
40918 };
40919
40920 // Animate the size of the lightbox to fit the image we are showing
40921 Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
40922 var self = this;
40923
40924 var oldWidth = this.$outerContainer.outerWidth();
40925 var oldHeight = this.$outerContainer.outerHeight();
40926 var newWidth = imageWidth + this.containerLeftPadding + this.containerRightPadding;
40927 var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding;
40928
40929 function postResize() {
40930 self.$lightbox.find('.lb-dataContainer').width(newWidth);
40931 self.$lightbox.find('.lb-prevLink').height(newHeight);
40932 self.$lightbox.find('.lb-nextLink').height(newHeight);
40933 self.showImage();
40934 }
40935
40936 if (oldWidth !== newWidth || oldHeight !== newHeight) {
40937 this.$outerContainer.animate({
40938 width: newWidth,
40939 height: newHeight
40940 }, this.options.resizeDuration, 'swing', function() {
40941 postResize();
40942 });
40943 } else {
40944 postResize();
40945 }
40946 };
40947
40948 // Display the image and its details and begin preload neighboring images.
40949 Lightbox.prototype.showImage = function() {
40950 this.$lightbox.find('.lb-loader').stop(true).hide();
40951 this.$lightbox.find('.lb-image').fadeIn('slow');
40952
40953 this.updateNav();
40954 this.updateDetails();
40955 this.preloadNeighboringImages();
40956 this.enableKeyboardNav();
40957 };
40958
40959 // Display previous and next navigation if appropriate.
40960 Lightbox.prototype.updateNav = function() {
40961 // Check to see if the browser supports touch events. If so, we take the conservative approach
40962 // and assume that mouse hover events are not supported and always show prev/next navigation
40963 // arrows in image sets.
40964 var alwaysShowNav = false;
40965 try {
40966 document.createEvent('TouchEvent');
40967 alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;
40968 } catch (e) {}
40969
40970 this.$lightbox.find('.lb-nav').show();
40971
40972 if (this.album.length > 1) {
40973 if (this.options.wrapAround) {
40974 if (alwaysShowNav) {
40975 this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
40976 }
40977 this.$lightbox.find('.lb-prev, .lb-next').show();
40978 } else {
40979 if (this.currentImageIndex > 0) {
40980 this.$lightbox.find('.lb-prev').show();
40981 if (alwaysShowNav) {
40982 this.$lightbox.find('.lb-prev').css('opacity', '1');
40983 }
40984 }
40985 if (this.currentImageIndex < this.album.length - 1) {
40986 this.$lightbox.find('.lb-next').show();
40987 if (alwaysShowNav) {
40988 this.$lightbox.find('.lb-next').css('opacity', '1');
40989 }
40990 }
40991 }
40992 }
40993 };
40994
40995 // Display caption, image number, and closing button.
40996 Lightbox.prototype.updateDetails = function() {
40997 var self = this;
40998
40999 // Enable anchor clicks in the injected caption html.
41000 // Thanks Nate Wright for the fix. @https://github.com/NateWr
41001 if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&
41002 this.album[this.currentImageIndex].title !== '') {
41003 this.$lightbox.find('.lb-caption')
41004 .html(this.album[this.currentImageIndex].title)
41005 .fadeIn('fast')
41006 .find('a').on('click', function(event) {
41007 if ($(this).attr('target') !== undefined) {
41008 window.open($(this).attr('href'), $(this).attr('target'));
41009 } else {
41010 location.href = $(this).attr('href');
41011 }
41012 });
41013 }
41014
41015 if (this.album.length > 1 && this.options.showImageNumberLabel) {
41016 var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
41017 this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
41018 } else {
41019 this.$lightbox.find('.lb-number').hide();
41020 }
41021
41022 this.$outerContainer.removeClass('animating');
41023
41024 this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
41025 return self.sizeOverlay();
41026 });
41027 };
41028
41029 // Preload previous and next images in set.
41030 Lightbox.prototype.preloadNeighboringImages = function() {
41031 if (this.album.length > this.currentImageIndex + 1) {
41032 var preloadNext = new Image();
41033 preloadNext.src = this.album[this.currentImageIndex + 1].link;
41034 }
41035 if (this.currentImageIndex > 0) {
41036 var preloadPrev = new Image();
41037 preloadPrev.src = this.album[this.currentImageIndex - 1].link;
41038 }
41039 };
41040
41041 Lightbox.prototype.enableKeyboardNav = function() {
41042 $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));
41043 };
41044
41045 Lightbox.prototype.disableKeyboardNav = function() {
41046 $(document).off('.keyboard');
41047 };
41048
41049 Lightbox.prototype.keyboardAction = function(event) {
41050 var KEYCODE_ESC = 27;
41051 var KEYCODE_LEFTARROW = 37;
41052 var KEYCODE_RIGHTARROW = 39;
41053
41054 var keycode = event.keyCode;
41055 var key = String.fromCharCode(keycode).toLowerCase();
41056 if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
41057 this.end();
41058 } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
41059 if (this.currentImageIndex !== 0) {
41060 this.changeImage(this.currentImageIndex - 1);
41061 } else if (this.options.wrapAround && this.album.length > 1) {
41062 this.changeImage(this.album.length - 1);
41063 }
41064 } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
41065 if (this.currentImageIndex !== this.album.length - 1) {
41066 this.changeImage(this.currentImageIndex + 1);
41067 } else if (this.options.wrapAround && this.album.length > 1) {
41068 this.changeImage(0);
41069 }
41070 }
41071 };
41072
41073 // Closing time. :-(
41074 Lightbox.prototype.end = function() {
41075 this.disableKeyboardNav();
41076 $(window).off('resize', this.sizeOverlay);
41077 this.$lightbox.fadeOut(this.options.fadeDuration);
41078 this.$overlay.fadeOut(this.options.fadeDuration);
41079 $('select, object, embed').css({
41080 visibility: 'visible'
41081 });
41082 };
41083
41084 return new Lightbox();
41085}));
41086
41087// TinyColor v1.4.2
41088// https://github.com/bgrins/TinyColor
41089// Brian Grinstead, MIT License
41090
41091(function(Math) {
41092
41093var trimLeft = /^\s+/,
41094 trimRight = /\s+$/,
41095 tinyCounter = 0,
41096 mathRound = Math.round,
41097 mathMin = Math.min,
41098 mathMax = Math.max,
41099 mathRandom = Math.random;
41100
41101function tinycolor (color, opts) {
41102
41103 color = (color) ? color : '';
41104 opts = opts || { };
41105
41106 // If input is already a tinycolor, return itself
41107 if (color instanceof tinycolor) {
41108 return color;
41109 }
41110 // If we are called as a function, call using new instead
41111 if (!(this instanceof tinycolor)) {
41112 return new tinycolor(color, opts);
41113 }
41114
41115 var rgb = inputToRGB(color);
41116 this._originalInput = color,
41117 this._r = rgb.r,
41118 this._g = rgb.g,
41119 this._b = rgb.b,
41120 this._a = rgb.a,
41121 this._roundA = mathRound(100*this._a) / 100,
41122 this._format = opts.format || rgb.format;
41123 this._gradientType = opts.gradientType;
41124
41125 // Don't let the range of [0,255] come back in [0,1].
41126 // Potentially lose a little bit of precision here, but will fix issues where
41127 // .5 gets interpreted as half of the total, instead of half of 1
41128 // If it was supposed to be 128, this was already taken care of by `inputToRgb`
41129 if (this._r < 1) { this._r = mathRound(this._r); }
41130 if (this._g < 1) { this._g = mathRound(this._g); }
41131 if (this._b < 1) { this._b = mathRound(this._b); }
41132
41133 this._ok = rgb.ok;
41134 this._tc_id = tinyCounter++;
41135}
41136
41137tinycolor.prototype = {
41138 isDark: function() {
41139 return this.getBrightness() < 128;
41140 },
41141 isLight: function() {
41142 return !this.isDark();
41143 },
41144 isValid: function() {
41145 return this._ok;
41146 },
41147 getOriginalInput: function() {
41148 return this._originalInput;
41149 },
41150 getFormat: function() {
41151 return this._format;
41152 },
41153 getAlpha: function() {
41154 return this._a;
41155 },
41156 getBrightness: function() {
41157 //http://www.w3.org/TR/AERT#color-contrast
41158 var rgb = this.toRgb();
41159 return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
41160 },
41161 getLuminance: function() {
41162 //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
41163 var rgb = this.toRgb();
41164 var RsRGB, GsRGB, BsRGB, R, G, B;
41165 RsRGB = rgb.r/255;
41166 GsRGB = rgb.g/255;
41167 BsRGB = rgb.b/255;
41168
41169 if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}
41170 if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}
41171 if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}
41172 return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
41173 },
41174 setAlpha: function(value) {
41175 this._a = boundAlpha(value);
41176 this._roundA = mathRound(100*this._a) / 100;
41177 return this;
41178 },
41179 toHsv: function() {
41180 var hsv = rgbToHsv(this._r, this._g, this._b);
41181 return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
41182 },
41183 toHsvString: function() {
41184 var hsv = rgbToHsv(this._r, this._g, this._b);
41185 var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
41186 return (this._a == 1) ?
41187 "hsv(" + h + ", " + s + "%, " + v + "%)" :
41188 "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
41189 },
41190 toHsl: function() {
41191 var hsl = rgbToHsl(this._r, this._g, this._b);
41192 return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
41193 },
41194 toHslString: function() {
41195 var hsl = rgbToHsl(this._r, this._g, this._b);
41196 var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
41197 return (this._a == 1) ?
41198 "hsl(" + h + ", " + s + "%, " + l + "%)" :
41199 "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
41200 },
41201 toHex: function(allow3Char) {
41202 return rgbToHex(this._r, this._g, this._b, allow3Char);
41203 },
41204 toHexString: function(allow3Char) {
41205 return '#' + this.toHex(allow3Char);
41206 },
41207 toHex8: function(allow4Char) {
41208 return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
41209 },
41210 toHex8String: function(allow4Char) {
41211 return '#' + this.toHex8(allow4Char);
41212 },
41213 toRgb: function() {
41214 return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
41215 },
41216 toRgbString: function() {
41217 return (this._a == 1) ?
41218 "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
41219 "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
41220 },
41221 toPercentageRgb: function() {
41222 return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
41223 },
41224 toPercentageRgbString: function() {
41225 return (this._a == 1) ?
41226 "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
41227 "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
41228 },
41229 toName: function() {
41230 if (this._a === 0) {
41231 return "transparent";
41232 }
41233
41234 if (this._a < 1) {
41235 return false;
41236 }
41237
41238 return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
41239 },
41240 toFilter: function(secondColor) {
41241 var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);
41242 var secondHex8String = hex8String;
41243 var gradientType = this._gradientType ? "GradientType = 1, " : "";
41244
41245 if (secondColor) {
41246 var s = tinycolor(secondColor);
41247 secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);
41248 }
41249
41250 return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
41251 },
41252 toString: function(format) {
41253 var formatSet = !!format;
41254 format = format || this._format;
41255
41256 var formattedString = false;
41257 var hasAlpha = this._a < 1 && this._a >= 0;
41258 var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name");
41259
41260 if (needsAlphaFormat) {
41261 // Special case for "transparent", all other non-alpha formats
41262 // will return rgba when there is transparency.
41263 if (format === "name" && this._a === 0) {
41264 return this.toName();
41265 }
41266 return this.toRgbString();
41267 }
41268 if (format === "rgb") {
41269 formattedString = this.toRgbString();
41270 }
41271 if (format === "prgb") {
41272 formattedString = this.toPercentageRgbString();
41273 }
41274 if (format === "hex" || format === "hex6") {
41275 formattedString = this.toHexString();
41276 }
41277 if (format === "hex3") {
41278 formattedString = this.toHexString(true);
41279 }
41280 if (format === "hex4") {
41281 formattedString = this.toHex8String(true);
41282 }
41283 if (format === "hex8") {
41284 formattedString = this.toHex8String();
41285 }
41286 if (format === "name") {
41287 formattedString = this.toName();
41288 }
41289 if (format === "hsl") {
41290 formattedString = this.toHslString();
41291 }
41292 if (format === "hsv") {
41293 formattedString = this.toHsvString();
41294 }
41295
41296 return formattedString || this.toHexString();
41297 },
41298 clone: function() {
41299 return tinycolor(this.toString());
41300 },
41301
41302 _applyModification: function(fn, args) {
41303 var color = fn.apply(null, [this].concat([].slice.call(args)));
41304 this._r = color._r;
41305 this._g = color._g;
41306 this._b = color._b;
41307 this.setAlpha(color._a);
41308 return this;
41309 },
41310 lighten: function() {
41311 return this._applyModification(lighten, arguments);
41312 },
41313 brighten: function() {
41314 return this._applyModification(brighten, arguments);
41315 },
41316 darken: function() {
41317 return this._applyModification(darken, arguments);
41318 },
41319 desaturate: function() {
41320 return this._applyModification(desaturate, arguments);
41321 },
41322 saturate: function() {
41323 return this._applyModification(saturate, arguments);
41324 },
41325 greyscale: function() {
41326 return this._applyModification(greyscale, arguments);
41327 },
41328 spin: function() {
41329 return this._applyModification(spin, arguments);
41330 },
41331
41332 _applyCombination: function(fn, args) {
41333 return fn.apply(null, [this].concat([].slice.call(args)));
41334 },
41335 analogous: function() {
41336 return this._applyCombination(analogous, arguments);
41337 },
41338 complement: function() {
41339 return this._applyCombination(complement, arguments);
41340 },
41341 monochromatic: function() {
41342 return this._applyCombination(monochromatic, arguments);
41343 },
41344 splitcomplement: function() {
41345 return this._applyCombination(splitcomplement, arguments);
41346 },
41347 triad: function() {
41348 return this._applyCombination(triad, arguments);
41349 },
41350 tetrad: function() {
41351 return this._applyCombination(tetrad, arguments);
41352 }
41353};
41354
41355// If input is an object, force 1 into "1.0" to handle ratios properly
41356// String input requires "1.0" as input, so 1 will be treated as 1
41357tinycolor.fromRatio = function(color, opts) {
41358 if (typeof color == "object") {
41359 var newColor = {};
41360 for (var i in color) {
41361 if (color.hasOwnProperty(i)) {
41362 if (i === "a") {
41363 newColor[i] = color[i];
41364 }
41365 else {
41366 newColor[i] = convertToPercentage(color[i]);
41367 }
41368 }
41369 }
41370 color = newColor;
41371 }
41372
41373 return tinycolor(color, opts);
41374};
41375
41376// Given a string or object, convert that input to RGB
41377// Possible string inputs:
41378//
41379// "red"
41380// "#f00" or "f00"
41381// "#ff0000" or "ff0000"
41382// "#ff000000" or "ff000000"
41383// "rgb 255 0 0" or "rgb (255, 0, 0)"
41384// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
41385// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
41386// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
41387// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
41388// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
41389// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
41390//
41391function inputToRGB(color) {
41392
41393 var rgb = { r: 0, g: 0, b: 0 };
41394 var a = 1;
41395 var s = null;
41396 var v = null;
41397 var l = null;
41398 var ok = false;
41399 var format = false;
41400
41401 if (typeof color == "string") {
41402 color = stringInputToObject(color);
41403 }
41404
41405 if (typeof color == "object") {
41406 if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
41407 rgb = rgbToRgb(color.r, color.g, color.b);
41408 ok = true;
41409 format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
41410 }
41411 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
41412 s = convertToPercentage(color.s);
41413 v = convertToPercentage(color.v);
41414 rgb = hsvToRgb(color.h, s, v);
41415 ok = true;
41416 format = "hsv";
41417 }
41418 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
41419 s = convertToPercentage(color.s);
41420 l = convertToPercentage(color.l);
41421 rgb = hslToRgb(color.h, s, l);
41422 ok = true;
41423 format = "hsl";
41424 }
41425
41426 if (color.hasOwnProperty("a")) {
41427 a = color.a;
41428 }
41429 }
41430
41431 a = boundAlpha(a);
41432
41433 return {
41434 ok: ok,
41435 format: color.format || format,
41436 r: mathMin(255, mathMax(rgb.r, 0)),
41437 g: mathMin(255, mathMax(rgb.g, 0)),
41438 b: mathMin(255, mathMax(rgb.b, 0)),
41439 a: a
41440 };
41441}
41442
41443
41444// Conversion Functions
41445// --------------------
41446
41447// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
41448// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
41449
41450// `rgbToRgb`
41451// Handle bounds / percentage checking to conform to CSS color spec
41452// <http://www.w3.org/TR/css3-color/>
41453// *Assumes:* r, g, b in [0, 255] or [0, 1]
41454// *Returns:* { r, g, b } in [0, 255]
41455function rgbToRgb(r, g, b){
41456 return {
41457 r: bound01(r, 255) * 255,
41458 g: bound01(g, 255) * 255,
41459 b: bound01(b, 255) * 255
41460 };
41461}
41462
41463// `rgbToHsl`
41464// Converts an RGB color value to HSL.
41465// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
41466// *Returns:* { h, s, l } in [0,1]
41467function rgbToHsl(r, g, b) {
41468
41469 r = bound01(r, 255);
41470 g = bound01(g, 255);
41471 b = bound01(b, 255);
41472
41473 var max = mathMax(r, g, b), min = mathMin(r, g, b);
41474 var h, s, l = (max + min) / 2;
41475
41476 if(max == min) {
41477 h = s = 0; // achromatic
41478 }
41479 else {
41480 var d = max - min;
41481 s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
41482 switch(max) {
41483 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
41484 case g: h = (b - r) / d + 2; break;
41485 case b: h = (r - g) / d + 4; break;
41486 }
41487
41488 h /= 6;
41489 }
41490
41491 return { h: h, s: s, l: l };
41492}
41493
41494// `hslToRgb`
41495// Converts an HSL color value to RGB.
41496// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
41497// *Returns:* { r, g, b } in the set [0, 255]
41498function hslToRgb(h, s, l) {
41499 var r, g, b;
41500
41501 h = bound01(h, 360);
41502 s = bound01(s, 100);
41503 l = bound01(l, 100);
41504
41505 function hue2rgb(p, q, t) {
41506 if(t < 0) t += 1;
41507 if(t > 1) t -= 1;
41508 if(t < 1/6) return p + (q - p) * 6 * t;
41509 if(t < 1/2) return q;
41510 if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
41511 return p;
41512 }
41513
41514 if(s === 0) {
41515 r = g = b = l; // achromatic
41516 }
41517 else {
41518 var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
41519 var p = 2 * l - q;
41520 r = hue2rgb(p, q, h + 1/3);
41521 g = hue2rgb(p, q, h);
41522 b = hue2rgb(p, q, h - 1/3);
41523 }
41524
41525 return { r: r * 255, g: g * 255, b: b * 255 };
41526}
41527
41528// `rgbToHsv`
41529// Converts an RGB color value to HSV
41530// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
41531// *Returns:* { h, s, v } in [0,1]
41532function rgbToHsv(r, g, b) {
41533
41534 r = bound01(r, 255);
41535 g = bound01(g, 255);
41536 b = bound01(b, 255);
41537
41538 var max = mathMax(r, g, b), min = mathMin(r, g, b);
41539 var h, s, v = max;
41540
41541 var d = max - min;
41542 s = max === 0 ? 0 : d / max;
41543
41544 if(max == min) {
41545 h = 0; // achromatic
41546 }
41547 else {
41548 switch(max) {
41549 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
41550 case g: h = (b - r) / d + 2; break;
41551 case b: h = (r - g) / d + 4; break;
41552 }
41553 h /= 6;
41554 }
41555 return { h: h, s: s, v: v };
41556}
41557
41558// `hsvToRgb`
41559// Converts an HSV color value to RGB.
41560// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
41561// *Returns:* { r, g, b } in the set [0, 255]
41562 function hsvToRgb(h, s, v) {
41563
41564 h = bound01(h, 360) * 6;
41565 s = bound01(s, 100);
41566 v = bound01(v, 100);
41567
41568 var i = Math.floor(h),
41569 f = h - i,
41570 p = v * (1 - s),
41571 q = v * (1 - f * s),
41572 t = v * (1 - (1 - f) * s),
41573 mod = i % 6,
41574 r = [v, q, p, p, t, v][mod],
41575 g = [t, v, v, q, p, p][mod],
41576 b = [p, p, t, v, v, q][mod];
41577
41578 return { r: r * 255, g: g * 255, b: b * 255 };
41579}
41580
41581// `rgbToHex`
41582// Converts an RGB color to hex
41583// Assumes r, g, and b are contained in the set [0, 255]
41584// Returns a 3 or 6 character hex
41585function rgbToHex(r, g, b, allow3Char) {
41586
41587 var hex = [
41588 pad2(mathRound(r).toString(16)),
41589 pad2(mathRound(g).toString(16)),
41590 pad2(mathRound(b).toString(16))
41591 ];
41592
41593 // Return a 3 character hex if possible
41594 if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
41595 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
41596 }
41597
41598 return hex.join("");
41599}
41600
41601// `rgbaToHex`
41602// Converts an RGBA color plus alpha transparency to hex
41603// Assumes r, g, b are contained in the set [0, 255] and
41604// a in [0, 1]. Returns a 4 or 8 character rgba hex
41605function rgbaToHex(r, g, b, a, allow4Char) {
41606
41607 var hex = [
41608 pad2(mathRound(r).toString(16)),
41609 pad2(mathRound(g).toString(16)),
41610 pad2(mathRound(b).toString(16)),
41611 pad2(convertDecimalToHex(a))
41612 ];
41613
41614 // Return a 4 character hex if possible
41615 if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {
41616 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
41617 }
41618
41619 return hex.join("");
41620}
41621
41622// `rgbaToArgbHex`
41623// Converts an RGBA color to an ARGB Hex8 string
41624// Rarely used, but required for "toFilter()"
41625function rgbaToArgbHex(r, g, b, a) {
41626
41627 var hex = [
41628 pad2(convertDecimalToHex(a)),
41629 pad2(mathRound(r).toString(16)),
41630 pad2(mathRound(g).toString(16)),
41631 pad2(mathRound(b).toString(16))
41632 ];
41633
41634 return hex.join("");
41635}
41636
41637// `equals`
41638// Can be called with any tinycolor input
41639tinycolor.equals = function (color1, color2) {
41640 if (!color1 || !color2) { return false; }
41641 return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
41642};
41643
41644tinycolor.random = function() {
41645 return tinycolor.fromRatio({
41646 r: mathRandom(),
41647 g: mathRandom(),
41648 b: mathRandom()
41649 });
41650};
41651
41652
41653// Modification Functions
41654// ----------------------
41655// Thanks to less.js for some of the basics here
41656// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
41657
41658function desaturate(color, amount) {
41659 amount = (amount === 0) ? 0 : (amount || 10);
41660 var hsl = tinycolor(color).toHsl();
41661 hsl.s -= amount / 100;
41662 hsl.s = clamp01(hsl.s);
41663 return tinycolor(hsl);
41664}
41665
41666function saturate(color, amount) {
41667 amount = (amount === 0) ? 0 : (amount || 10);
41668 var hsl = tinycolor(color).toHsl();
41669 hsl.s += amount / 100;
41670 hsl.s = clamp01(hsl.s);
41671 return tinycolor(hsl);
41672}
41673
41674function greyscale(color) {
41675 return tinycolor(color).desaturate(100);
41676}
41677
41678function lighten (color, amount) {
41679 amount = (amount === 0) ? 0 : (amount || 10);
41680 var hsl = tinycolor(color).toHsl();
41681 hsl.l += amount / 100;
41682 hsl.l = clamp01(hsl.l);
41683 return tinycolor(hsl);
41684}
41685
41686function brighten(color, amount) {
41687 amount = (amount === 0) ? 0 : (amount || 10);
41688 var rgb = tinycolor(color).toRgb();
41689 rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
41690 rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
41691 rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
41692 return tinycolor(rgb);
41693}
41694
41695function darken (color, amount) {
41696 amount = (amount === 0) ? 0 : (amount || 10);
41697 var hsl = tinycolor(color).toHsl();
41698 hsl.l -= amount / 100;
41699 hsl.l = clamp01(hsl.l);
41700 return tinycolor(hsl);
41701}
41702
41703// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
41704// Values outside of this range will be wrapped into this range.
41705function spin(color, amount) {
41706 var hsl = tinycolor(color).toHsl();
41707 var hue = (hsl.h + amount) % 360;
41708 hsl.h = hue < 0 ? 360 + hue : hue;
41709 return tinycolor(hsl);
41710}
41711
41712// Combination Functions
41713// ---------------------
41714// Thanks to jQuery xColor for some of the ideas behind these
41715// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
41716
41717function complement(color) {
41718 var hsl = tinycolor(color).toHsl();
41719 hsl.h = (hsl.h + 180) % 360;
41720 return tinycolor(hsl);
41721}
41722
41723function triad(color) {
41724 var hsl = tinycolor(color).toHsl();
41725 var h = hsl.h;
41726 return [
41727 tinycolor(color),
41728 tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
41729 tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
41730 ];
41731}
41732
41733function tetrad(color) {
41734 var hsl = tinycolor(color).toHsl();
41735 var h = hsl.h;
41736 return [
41737 tinycolor(color),
41738 tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
41739 tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
41740 tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
41741 ];
41742}
41743
41744function splitcomplement(color) {
41745 var hsl = tinycolor(color).toHsl();
41746 var h = hsl.h;
41747 return [
41748 tinycolor(color),
41749 tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
41750 tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
41751 ];
41752}
41753
41754function analogous(color, results, slices) {
41755 results = results || 6;
41756 slices = slices || 30;
41757
41758 var hsl = tinycolor(color).toHsl();
41759 var part = 360 / slices;
41760 var ret = [tinycolor(color)];
41761
41762 for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
41763 hsl.h = (hsl.h + part) % 360;
41764 ret.push(tinycolor(hsl));
41765 }
41766 return ret;
41767}
41768
41769function monochromatic(color, results) {
41770 results = results || 6;
41771 var hsv = tinycolor(color).toHsv();
41772 var h = hsv.h, s = hsv.s, v = hsv.v;
41773 var ret = [];
41774 var modification = 1 / results;
41775
41776 while (results--) {
41777 ret.push(tinycolor({ h: h, s: s, v: v}));
41778 v = (v + modification) % 1;
41779 }
41780
41781 return ret;
41782}
41783
41784// Utility Functions
41785// ---------------------
41786
41787tinycolor.mix = function(color1, color2, amount) {
41788 amount = (amount === 0) ? 0 : (amount || 50);
41789
41790 var rgb1 = tinycolor(color1).toRgb();
41791 var rgb2 = tinycolor(color2).toRgb();
41792
41793 var p = amount / 100;
41794
41795 var rgba = {
41796 r: ((rgb2.r - rgb1.r) * p) + rgb1.r,
41797 g: ((rgb2.g - rgb1.g) * p) + rgb1.g,
41798 b: ((rgb2.b - rgb1.b) * p) + rgb1.b,
41799 a: ((rgb2.a - rgb1.a) * p) + rgb1.a
41800 };
41801
41802 return tinycolor(rgba);
41803};
41804
41805
41806// Readability Functions
41807// ---------------------
41808// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
41809
41810// `contrast`
41811// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)
41812tinycolor.readability = function(color1, color2) {
41813 var c1 = tinycolor(color1);
41814 var c2 = tinycolor(color2);
41815 return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);
41816};
41817
41818// `isReadable`
41819// Ensure that foreground and background color combinations meet WCAG2 guidelines.
41820// The third argument is an optional Object.
41821// the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';
41822// the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.
41823// If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}.
41824
41825// *Example*
41826// tinycolor.isReadable("#000", "#111") => false
41827// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false
41828tinycolor.isReadable = function(color1, color2, wcag2) {
41829 var readability = tinycolor.readability(color1, color2);
41830 var wcag2Parms, out;
41831
41832 out = false;
41833
41834 wcag2Parms = validateWCAG2Parms(wcag2);
41835 switch (wcag2Parms.level + wcag2Parms.size) {
41836 case "AAsmall":
41837 case "AAAlarge":
41838 out = readability >= 4.5;
41839 break;
41840 case "AAlarge":
41841 out = readability >= 3;
41842 break;
41843 case "AAAsmall":
41844 out = readability >= 7;
41845 break;
41846 }
41847 return out;
41848
41849};
41850
41851// `mostReadable`
41852// Given a base color and a list of possible foreground or background
41853// colors for that base, returns the most readable color.
41854// Optionally returns Black or White if the most readable color is unreadable.
41855// *Example*
41856// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255"
41857// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff"
41858// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3"
41859// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff"
41860tinycolor.mostReadable = function(baseColor, colorList, args) {
41861 var bestColor = null;
41862 var bestScore = 0;
41863 var readability;
41864 var includeFallbackColors, level, size ;
41865 args = args || {};
41866 includeFallbackColors = args.includeFallbackColors ;
41867 level = args.level;
41868 size = args.size;
41869
41870 for (var i= 0; i < colorList.length ; i++) {
41871 readability = tinycolor.readability(baseColor, colorList[i]);
41872 if (readability > bestScore) {
41873 bestScore = readability;
41874 bestColor = tinycolor(colorList[i]);
41875 }
41876 }
41877
41878 if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
41879 return bestColor;
41880 }
41881 else {
41882 args.includeFallbackColors=false;
41883 return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
41884 }
41885};
41886
41887
41888// Big List of Colors
41889// ------------------
41890// <http://www.w3.org/TR/css3-color/#svg-color>
41891var names = tinycolor.names = {
41892 aliceblue: "f0f8ff",
41893 antiquewhite: "faebd7",
41894 aqua: "0ff",
41895 aquamarine: "7fffd4",
41896 azure: "f0ffff",
41897 beige: "f5f5dc",
41898 bisque: "ffe4c4",
41899 black: "000",
41900 blanchedalmond: "ffebcd",
41901 blue: "00f",
41902 blueviolet: "8a2be2",
41903 brown: "a52a2a",
41904 burlywood: "deb887",
41905 burntsienna: "ea7e5d",
41906 cadetblue: "5f9ea0",
41907 chartreuse: "7fff00",
41908 chocolate: "d2691e",
41909 coral: "ff7f50",
41910 cornflowerblue: "6495ed",
41911 cornsilk: "fff8dc",
41912 crimson: "dc143c",
41913 cyan: "0ff",
41914 darkblue: "00008b",
41915 darkcyan: "008b8b",
41916 darkgoldenrod: "b8860b",
41917 darkgray: "a9a9a9",
41918 darkgreen: "006400",
41919 darkgrey: "a9a9a9",
41920 darkkhaki: "bdb76b",
41921 darkmagenta: "8b008b",
41922 darkolivegreen: "556b2f",
41923 darkorange: "ff8c00",
41924 darkorchid: "9932cc",
41925 darkred: "8b0000",
41926 darksalmon: "e9967a",
41927 darkseagreen: "8fbc8f",
41928 darkslateblue: "483d8b",
41929 darkslategray: "2f4f4f",
41930 darkslategrey: "2f4f4f",
41931 darkturquoise: "00ced1",
41932 darkviolet: "9400d3",
41933 deeppink: "ff1493",
41934 deepskyblue: "00bfff",
41935 dimgray: "696969",
41936 dimgrey: "696969",
41937 dodgerblue: "1e90ff",
41938 firebrick: "b22222",
41939 floralwhite: "fffaf0",
41940 forestgreen: "228b22",
41941 fuchsia: "f0f",
41942 gainsboro: "dcdcdc",
41943 ghostwhite: "f8f8ff",
41944 gold: "ffd700",
41945 goldenrod: "daa520",
41946 gray: "808080",
41947 green: "008000",
41948 greenyellow: "adff2f",
41949 grey: "808080",
41950 honeydew: "f0fff0",
41951 hotpink: "ff69b4",
41952 indianred: "cd5c5c",
41953 indigo: "4b0082",
41954 ivory: "fffff0",
41955 khaki: "f0e68c",
41956 lavender: "e6e6fa",
41957 lavenderblush: "fff0f5",
41958 lawngreen: "7cfc00",
41959 lemonchiffon: "fffacd",
41960 lightblue: "add8e6",
41961 lightcoral: "f08080",
41962 lightcyan: "e0ffff",
41963 lightgoldenrodyellow: "fafad2",
41964 lightgray: "d3d3d3",
41965 lightgreen: "90ee90",
41966 lightgrey: "d3d3d3",
41967 lightpink: "ffb6c1",
41968 lightsalmon: "ffa07a",
41969 lightseagreen: "20b2aa",
41970 lightskyblue: "87cefa",
41971 lightslategray: "789",
41972 lightslategrey: "789",
41973 lightsteelblue: "b0c4de",
41974 lightyellow: "ffffe0",
41975 lime: "0f0",
41976 limegreen: "32cd32",
41977 linen: "faf0e6",
41978 magenta: "f0f",
41979 maroon: "800000",
41980 mediumaquamarine: "66cdaa",
41981 mediumblue: "0000cd",
41982 mediumorchid: "ba55d3",
41983 mediumpurple: "9370db",
41984 mediumseagreen: "3cb371",
41985 mediumslateblue: "7b68ee",
41986 mediumspringgreen: "00fa9a",
41987 mediumturquoise: "48d1cc",
41988 mediumvioletred: "c71585",
41989 midnightblue: "191970",
41990 mintcream: "f5fffa",
41991 mistyrose: "ffe4e1",
41992 moccasin: "ffe4b5",
41993 navajowhite: "ffdead",
41994 navy: "000080",
41995 oldlace: "fdf5e6",
41996 olive: "808000",
41997 olivedrab: "6b8e23",
41998 orange: "ffa500",
41999 orangered: "ff4500",
42000 orchid: "da70d6",
42001 palegoldenrod: "eee8aa",
42002 palegreen: "98fb98",
42003 paleturquoise: "afeeee",
42004 palevioletred: "db7093",
42005 papayawhip: "ffefd5",
42006 peachpuff: "ffdab9",
42007 peru: "cd853f",
42008 pink: "ffc0cb",
42009 plum: "dda0dd",
42010 powderblue: "b0e0e6",
42011 purple: "800080",
42012 rebeccapurple: "663399",
42013 red: "f00",
42014 rosybrown: "bc8f8f",
42015 royalblue: "4169e1",
42016 saddlebrown: "8b4513",
42017 salmon: "fa8072",
42018 sandybrown: "f4a460",
42019 seagreen: "2e8b57",
42020 seashell: "fff5ee",
42021 sienna: "a0522d",
42022 silver: "c0c0c0",
42023 skyblue: "87ceeb",
42024 slateblue: "6a5acd",
42025 slategray: "708090",
42026 slategrey: "708090",
42027 snow: "fffafa",
42028 springgreen: "00ff7f",
42029 steelblue: "4682b4",
42030 tan: "d2b48c",
42031 teal: "008080",
42032 thistle: "d8bfd8",
42033 tomato: "ff6347",
42034 turquoise: "40e0d0",
42035 violet: "ee82ee",
42036 wheat: "f5deb3",
42037 white: "fff",
42038 whitesmoke: "f5f5f5",
42039 yellow: "ff0",
42040 yellowgreen: "9acd32"
42041};
42042
42043// Make it easy to access colors via `hexNames[hex]`
42044var hexNames = tinycolor.hexNames = flip(names);
42045
42046
42047// Utilities
42048// ---------
42049
42050// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
42051function flip(o) {
42052 var flipped = { };
42053 for (var i in o) {
42054 if (o.hasOwnProperty(i)) {
42055 flipped[o[i]] = i;
42056 }
42057 }
42058 return flipped;
42059}
42060
42061// Return a valid alpha value [0,1] with all invalid values being set to 1
42062function boundAlpha(a) {
42063 a = parseFloat(a);
42064
42065 if (isNaN(a) || a < 0 || a > 1) {
42066 a = 1;
42067 }
42068
42069 return a;
42070}
42071
42072// Take input from [0, n] and return it as [0, 1]
42073function bound01(n, max) {
42074 if (isOnePointZero(n)) { n = "100%"; }
42075
42076 var processPercent = isPercentage(n);
42077 n = mathMin(max, mathMax(0, parseFloat(n)));
42078
42079 // Automatically convert percentage into number
42080 if (processPercent) {
42081 n = parseInt(n * max, 10) / 100;
42082 }
42083
42084 // Handle floating point rounding errors
42085 if ((Math.abs(n - max) < 0.000001)) {
42086 return 1;
42087 }
42088
42089 // Convert into [0, 1] range if it isn't already
42090 return (n % max) / parseFloat(max);
42091}
42092
42093// Force a number between 0 and 1
42094function clamp01(val) {
42095 return mathMin(1, mathMax(0, val));
42096}
42097
42098// Parse a base-16 hex value into a base-10 integer
42099function parseIntFromHex(val) {
42100 return parseInt(val, 16);
42101}
42102
42103// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
42104// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
42105function isOnePointZero(n) {
42106 return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
42107}
42108
42109// Check to see if string passed in is a percentage
42110function isPercentage(n) {
42111 return typeof n === "string" && n.indexOf('%') != -1;
42112}
42113
42114// Force a hex value to have 2 characters
42115function pad2(c) {
42116 return c.length == 1 ? '0' + c : '' + c;
42117}
42118
42119// Replace a decimal with it's percentage value
42120function convertToPercentage(n) {
42121 if (n <= 1) {
42122 n = (n * 100) + "%";
42123 }
42124
42125 return n;
42126}
42127
42128// Converts a decimal to a hex value
42129function convertDecimalToHex(d) {
42130 return Math.round(parseFloat(d) * 255).toString(16);
42131}
42132// Converts a hex value to a decimal
42133function convertHexToDecimal(h) {
42134 return (parseIntFromHex(h) / 255);
42135}
42136
42137var matchers = (function() {
42138
42139 // <http://www.w3.org/TR/css3-values/#integers>
42140 var CSS_INTEGER = "[-\\+]?\\d+%?";
42141
42142 // <http://www.w3.org/TR/css3-values/#number-value>
42143 var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
42144
42145 // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
42146 var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
42147
42148 // Actual matching.
42149 // Parentheses and commas are optional, but not required.
42150 // Whitespace can take the place of commas or opening paren
42151 var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
42152 var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
42153
42154 return {
42155 CSS_UNIT: new RegExp(CSS_UNIT),
42156 rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
42157 rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
42158 hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
42159 hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
42160 hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
42161 hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
42162 hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
42163 hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
42164 hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
42165 hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
42166 };
42167})();
42168
42169// `isValidCSSUnit`
42170// Take in a single string / number and check to see if it looks like a CSS unit
42171// (see `matchers` above for definition).
42172function isValidCSSUnit(color) {
42173 return !!matchers.CSS_UNIT.exec(color);
42174}
42175
42176// `stringInputToObject`
42177// Permissive string parsing. Take in a number of formats, and output an object
42178// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
42179function stringInputToObject(color) {
42180
42181 color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
42182 var named = false;
42183 if (names[color]) {
42184 color = names[color];
42185 named = true;
42186 }
42187 else if (color == 'transparent') {
42188 return { r: 0, g: 0, b: 0, a: 0, format: "name" };
42189 }
42190
42191 // Try to match string input using regular expressions.
42192 // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
42193 // Just return an object and let the conversion functions handle that.
42194 // This way the result will be the same whether the tinycolor is initialized with string or object.
42195 var match;
42196 if ((match = matchers.rgb.exec(color))) {
42197 return { r: match[1], g: match[2], b: match[3] };
42198 }
42199 if ((match = matchers.rgba.exec(color))) {
42200 return { r: match[1], g: match[2], b: match[3], a: match[4] };
42201 }
42202 if ((match = matchers.hsl.exec(color))) {
42203 return { h: match[1], s: match[2], l: match[3] };
42204 }
42205 if ((match = matchers.hsla.exec(color))) {
42206 return { h: match[1], s: match[2], l: match[3], a: match[4] };
42207 }
42208 if ((match = matchers.hsv.exec(color))) {
42209 return { h: match[1], s: match[2], v: match[3] };
42210 }
42211 if ((match = matchers.hsva.exec(color))) {
42212 return { h: match[1], s: match[2], v: match[3], a: match[4] };
42213 }
42214 if ((match = matchers.hex8.exec(color))) {
42215 return {
42216 r: parseIntFromHex(match[1]),
42217 g: parseIntFromHex(match[2]),
42218 b: parseIntFromHex(match[3]),
42219 a: convertHexToDecimal(match[4]),
42220 format: named ? "name" : "hex8"
42221 };
42222 }
42223 if ((match = matchers.hex6.exec(color))) {
42224 return {
42225 r: parseIntFromHex(match[1]),
42226 g: parseIntFromHex(match[2]),
42227 b: parseIntFromHex(match[3]),
42228 format: named ? "name" : "hex"
42229 };
42230 }
42231 if ((match = matchers.hex4.exec(color))) {
42232 return {
42233 r: parseIntFromHex(match[1] + '' + match[1]),
42234 g: parseIntFromHex(match[2] + '' + match[2]),
42235 b: parseIntFromHex(match[3] + '' + match[3]),
42236 a: convertHexToDecimal(match[4] + '' + match[4]),
42237 format: named ? "name" : "hex8"
42238 };
42239 }
42240 if ((match = matchers.hex3.exec(color))) {
42241 return {
42242 r: parseIntFromHex(match[1] + '' + match[1]),
42243 g: parseIntFromHex(match[2] + '' + match[2]),
42244 b: parseIntFromHex(match[3] + '' + match[3]),
42245 format: named ? "name" : "hex"
42246 };
42247 }
42248
42249 return false;
42250}
42251
42252function validateWCAG2Parms(parms) {
42253 // return valid WCAG2 parms for isReadable.
42254 // If input parms are invalid, return {"level":"AA", "size":"small"}
42255 var level, size;
42256 parms = parms || {"level":"AA", "size":"small"};
42257 level = (parms.level || "AA").toUpperCase();
42258 size = (parms.size || "small").toLowerCase();
42259 if (level !== "AA" && level !== "AAA") {
42260 level = "AA";
42261 }
42262 if (size !== "small" && size !== "large") {
42263 size = "small";
42264 }
42265 return {"level":level, "size":size};
42266}
42267
42268// Node: Export function
42269if (typeof module !== "undefined" && module.exports) {
42270 module.exports = tinycolor;
42271}
42272// AMD/requirejs: Define the module
42273else if (typeof define === 'function' && define.amd) {
42274 define(function () {return tinycolor;});
42275}
42276// Browser: Expose to window
42277else {
42278 window.tinycolor = tinycolor;
42279}
42280
42281})(Math);
42282