mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-05 03:44:37 -04:00
32858 lines
1.4 MiB
32858 lines
1.4 MiB
/*!
|
||
* jQuery JavaScript Library v1.11.1
|
||
* http://jquery.com/
|
||
*
|
||
* Includes Sizzle.js
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-05-01T17:42Z
|
||
*/
|
||
|
||
(function( global, factory ) {
|
||
|
||
if ( typeof module === "object" && typeof module.exports === "object" ) {
|
||
// For CommonJS and CommonJS-like environments where a proper window is present,
|
||
// execute the factory and get jQuery
|
||
// For environments that do not inherently posses a window with a document
|
||
// (such as Node.js), expose a jQuery-making factory as module.exports
|
||
// This accentuates the need for the creation of a real window
|
||
// e.g. var jQuery = require("jquery")(window);
|
||
// See ticket #14549 for more info
|
||
module.exports = global.document ?
|
||
factory( global, true ) :
|
||
function( w ) {
|
||
if ( !w.document ) {
|
||
throw new Error( "jQuery requires a window with a document" );
|
||
}
|
||
return factory( w );
|
||
};
|
||
} else {
|
||
factory( global );
|
||
}
|
||
|
||
// Pass this if window is not defined yet
|
||
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
||
|
||
// Can't do this because several apps including ASP.NET trace
|
||
// the stack via arguments.caller.callee and Firefox dies if
|
||
// you try to trace through "use strict" call chains. (#13335)
|
||
// Support: Firefox 18+
|
||
//
|
||
|
||
var deletedIds = [];
|
||
|
||
var slice = deletedIds.slice;
|
||
|
||
var concat = deletedIds.concat;
|
||
|
||
var push = deletedIds.push;
|
||
|
||
var indexOf = deletedIds.indexOf;
|
||
|
||
var class2type = {};
|
||
|
||
var toString = class2type.toString;
|
||
|
||
var hasOwn = class2type.hasOwnProperty;
|
||
|
||
var support = {};
|
||
|
||
|
||
|
||
var
|
||
version = "1.11.1",
|
||
|
||
// Define a local copy of jQuery
|
||
jQuery = function( selector, context ) {
|
||
// The jQuery object is actually just the init constructor 'enhanced'
|
||
// Need init if jQuery is called (just allow error to be thrown if not included)
|
||
return new jQuery.fn.init( selector, context );
|
||
},
|
||
|
||
// Support: Android<4.1, IE<9
|
||
// Make sure we trim BOM and NBSP
|
||
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
|
||
|
||
// Matches dashed string for camelizing
|
||
rmsPrefix = /^-ms-/,
|
||
rdashAlpha = /-([\da-z])/gi,
|
||
|
||
// Used by jQuery.camelCase as callback to replace()
|
||
fcamelCase = function( all, letter ) {
|
||
return letter.toUpperCase();
|
||
};
|
||
|
||
jQuery.fn = jQuery.prototype = {
|
||
// The current version of jQuery being used
|
||
jquery: version,
|
||
|
||
constructor: jQuery,
|
||
|
||
// Start with an empty selector
|
||
selector: "",
|
||
|
||
// The default length of a jQuery object is 0
|
||
length: 0,
|
||
|
||
toArray: function() {
|
||
return slice.call( this );
|
||
},
|
||
|
||
// Get the Nth element in the matched element set OR
|
||
// Get the whole matched element set as a clean array
|
||
get: function( num ) {
|
||
return num != null ?
|
||
|
||
// Return just the one element from the set
|
||
( num < 0 ? this[ num + this.length ] : this[ num ] ) :
|
||
|
||
// Return all the elements in a clean array
|
||
slice.call( this );
|
||
},
|
||
|
||
// Take an array of elements and push it onto the stack
|
||
// (returning the new matched element set)
|
||
pushStack: function( elems ) {
|
||
|
||
// Build a new jQuery matched element set
|
||
var ret = jQuery.merge( this.constructor(), elems );
|
||
|
||
// Add the old object onto the stack (as a reference)
|
||
ret.prevObject = this;
|
||
ret.context = this.context;
|
||
|
||
// Return the newly-formed element set
|
||
return ret;
|
||
},
|
||
|
||
// Execute a callback for every element in the matched set.
|
||
// (You can seed the arguments with an array of args, but this is
|
||
// only used internally.)
|
||
each: function( callback, args ) {
|
||
return jQuery.each( this, callback, args );
|
||
},
|
||
|
||
map: function( callback ) {
|
||
return this.pushStack( jQuery.map(this, function( elem, i ) {
|
||
return callback.call( elem, i, elem );
|
||
}));
|
||
},
|
||
|
||
slice: function() {
|
||
return this.pushStack( slice.apply( this, arguments ) );
|
||
},
|
||
|
||
first: function() {
|
||
return this.eq( 0 );
|
||
},
|
||
|
||
last: function() {
|
||
return this.eq( -1 );
|
||
},
|
||
|
||
eq: function( i ) {
|
||
var len = this.length,
|
||
j = +i + ( i < 0 ? len : 0 );
|
||
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
|
||
},
|
||
|
||
end: function() {
|
||
return this.prevObject || this.constructor(null);
|
||
},
|
||
|
||
// For internal use only.
|
||
// Behaves like an Array's method, not like a jQuery method.
|
||
push: push,
|
||
sort: deletedIds.sort,
|
||
splice: deletedIds.splice
|
||
};
|
||
|
||
jQuery.extend = jQuery.fn.extend = function() {
|
||
var src, copyIsArray, copy, name, options, clone,
|
||
target = arguments[0] || {},
|
||
i = 1,
|
||
length = arguments.length,
|
||
deep = false;
|
||
|
||
// Handle a deep copy situation
|
||
if ( typeof target === "boolean" ) {
|
||
deep = target;
|
||
|
||
// skip the boolean and the target
|
||
target = arguments[ i ] || {};
|
||
i++;
|
||
}
|
||
|
||
// Handle case when target is a string or something (possible in deep copy)
|
||
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
|
||
target = {};
|
||
}
|
||
|
||
// extend jQuery itself if only one argument is passed
|
||
if ( i === length ) {
|
||
target = this;
|
||
i--;
|
||
}
|
||
|
||
for ( ; i < length; i++ ) {
|
||
// Only deal with non-null/undefined values
|
||
if ( (options = arguments[ i ]) != null ) {
|
||
// Extend the base object
|
||
for ( name in options ) {
|
||
src = target[ name ];
|
||
copy = options[ name ];
|
||
|
||
// Prevent never-ending loop
|
||
if ( target === copy ) {
|
||
continue;
|
||
}
|
||
|
||
// Recurse if we're merging plain objects or arrays
|
||
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
|
||
if ( copyIsArray ) {
|
||
copyIsArray = false;
|
||
clone = src && jQuery.isArray(src) ? src : [];
|
||
|
||
} else {
|
||
clone = src && jQuery.isPlainObject(src) ? src : {};
|
||
}
|
||
|
||
// Never move original objects, clone them
|
||
target[ name ] = jQuery.extend( deep, clone, copy );
|
||
|
||
// Don't bring in undefined values
|
||
} else if ( copy !== undefined ) {
|
||
target[ name ] = copy;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Return the modified object
|
||
return target;
|
||
};
|
||
|
||
jQuery.extend({
|
||
// Unique for each copy of jQuery on the page
|
||
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
|
||
|
||
// Assume jQuery is ready without the ready module
|
||
isReady: true,
|
||
|
||
error: function( msg ) {
|
||
throw new Error( msg );
|
||
},
|
||
|
||
noop: function() {},
|
||
|
||
// See test/unit/core.js for details concerning isFunction.
|
||
// Since version 1.3, DOM methods and functions like alert
|
||
// aren't supported. They return false on IE (#2968).
|
||
isFunction: function( obj ) {
|
||
return jQuery.type(obj) === "function";
|
||
},
|
||
|
||
isArray: Array.isArray || function( obj ) {
|
||
return jQuery.type(obj) === "array";
|
||
},
|
||
|
||
isWindow: function( obj ) {
|
||
/* jshint eqeqeq: false */
|
||
return obj != null && obj == obj.window;
|
||
},
|
||
|
||
isNumeric: function( obj ) {
|
||
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
|
||
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
|
||
// subtraction forces infinities to NaN
|
||
return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
|
||
},
|
||
|
||
isEmptyObject: function( obj ) {
|
||
var name;
|
||
for ( name in obj ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
isPlainObject: function( obj ) {
|
||
var key;
|
||
|
||
// Must be an Object.
|
||
// Because of IE, we also have to check the presence of the constructor property.
|
||
// Make sure that DOM nodes and window objects don't pass through, as well
|
||
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
try {
|
||
// Not own constructor property must be Object
|
||
if ( obj.constructor &&
|
||
!hasOwn.call(obj, "constructor") &&
|
||
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
|
||
return false;
|
||
}
|
||
} catch ( e ) {
|
||
// IE8,9 Will throw exceptions on certain host objects #9897
|
||
return false;
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Handle iteration over inherited properties before own properties.
|
||
if ( support.ownLast ) {
|
||
for ( key in obj ) {
|
||
return hasOwn.call( obj, key );
|
||
}
|
||
}
|
||
|
||
// Own properties are enumerated firstly, so to speed up,
|
||
// if last one is own, then all properties are own.
|
||
for ( key in obj ) {}
|
||
|
||
return key === undefined || hasOwn.call( obj, key );
|
||
},
|
||
|
||
type: function( obj ) {
|
||
if ( obj == null ) {
|
||
return obj + "";
|
||
}
|
||
return typeof obj === "object" || typeof obj === "function" ?
|
||
class2type[ toString.call(obj) ] || "object" :
|
||
typeof obj;
|
||
},
|
||
|
||
// Evaluates a script in a global context
|
||
// Workarounds based on findings by Jim Driscoll
|
||
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
|
||
globalEval: function( data ) {
|
||
if ( data && jQuery.trim( data ) ) {
|
||
// We use execScript on Internet Explorer
|
||
// We use an anonymous function so that context is window
|
||
// rather than jQuery in Firefox
|
||
( window.execScript || function( data ) {
|
||
window[ "eval" ].call( window, data );
|
||
} )( data );
|
||
}
|
||
},
|
||
|
||
// Convert dashed to camelCase; used by the css and data modules
|
||
// Microsoft forgot to hump their vendor prefix (#9572)
|
||
camelCase: function( string ) {
|
||
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
||
},
|
||
|
||
nodeName: function( elem, name ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
|
||
},
|
||
|
||
// args is for internal usage only
|
||
each: function( obj, callback, args ) {
|
||
var value,
|
||
i = 0,
|
||
length = obj.length,
|
||
isArray = isArraylike( obj );
|
||
|
||
if ( args ) {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// A special, fast, case for the most common use of each
|
||
} else {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
},
|
||
|
||
// Support: Android<4.1, IE<9
|
||
trim: function( text ) {
|
||
return text == null ?
|
||
"" :
|
||
( text + "" ).replace( rtrim, "" );
|
||
},
|
||
|
||
// results is for internal usage only
|
||
makeArray: function( arr, results ) {
|
||
var ret = results || [];
|
||
|
||
if ( arr != null ) {
|
||
if ( isArraylike( Object(arr) ) ) {
|
||
jQuery.merge( ret,
|
||
typeof arr === "string" ?
|
||
[ arr ] : arr
|
||
);
|
||
} else {
|
||
push.call( ret, arr );
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
},
|
||
|
||
inArray: function( elem, arr, i ) {
|
||
var len;
|
||
|
||
if ( arr ) {
|
||
if ( indexOf ) {
|
||
return indexOf.call( arr, elem, i );
|
||
}
|
||
|
||
len = arr.length;
|
||
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
// Skip accessing in sparse arrays
|
||
if ( i in arr && arr[ i ] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
},
|
||
|
||
merge: function( first, second ) {
|
||
var len = +second.length,
|
||
j = 0,
|
||
i = first.length;
|
||
|
||
while ( j < len ) {
|
||
first[ i++ ] = second[ j++ ];
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
|
||
if ( len !== len ) {
|
||
while ( second[j] !== undefined ) {
|
||
first[ i++ ] = second[ j++ ];
|
||
}
|
||
}
|
||
|
||
first.length = i;
|
||
|
||
return first;
|
||
},
|
||
|
||
grep: function( elems, callback, invert ) {
|
||
var callbackInverse,
|
||
matches = [],
|
||
i = 0,
|
||
length = elems.length,
|
||
callbackExpect = !invert;
|
||
|
||
// Go through the array, only saving the items
|
||
// that pass the validator function
|
||
for ( ; i < length; i++ ) {
|
||
callbackInverse = !callback( elems[ i ], i );
|
||
if ( callbackInverse !== callbackExpect ) {
|
||
matches.push( elems[ i ] );
|
||
}
|
||
}
|
||
|
||
return matches;
|
||
},
|
||
|
||
// arg is for internal usage only
|
||
map: function( elems, callback, arg ) {
|
||
var value,
|
||
i = 0,
|
||
length = elems.length,
|
||
isArray = isArraylike( elems ),
|
||
ret = [];
|
||
|
||
// Go through the array, translating each of the items to their new values
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
|
||
// Go through every key on the object,
|
||
} else {
|
||
for ( i in elems ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Flatten any nested arrays
|
||
return concat.apply( [], ret );
|
||
},
|
||
|
||
// A global GUID counter for objects
|
||
guid: 1,
|
||
|
||
// Bind a function to a context, optionally partially applying any
|
||
// arguments.
|
||
proxy: function( fn, context ) {
|
||
var args, proxy, tmp;
|
||
|
||
if ( typeof context === "string" ) {
|
||
tmp = fn[ context ];
|
||
context = fn;
|
||
fn = tmp;
|
||
}
|
||
|
||
// Quick check to determine if target is callable, in the spec
|
||
// this throws a TypeError, but we will just return undefined.
|
||
if ( !jQuery.isFunction( fn ) ) {
|
||
return undefined;
|
||
}
|
||
|
||
// Simulated bind
|
||
args = slice.call( arguments, 2 );
|
||
proxy = function() {
|
||
return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
|
||
};
|
||
|
||
// Set the guid of unique handler to the same of original handler, so it can be removed
|
||
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
|
||
|
||
return proxy;
|
||
},
|
||
|
||
now: function() {
|
||
return +( new Date() );
|
||
},
|
||
|
||
// jQuery.support is not used in Core but other projects attach their
|
||
// properties to it so it needs to exist.
|
||
support: support
|
||
});
|
||
|
||
// Populate the class2type map
|
||
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
|
||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||
});
|
||
|
||
function isArraylike( obj ) {
|
||
var length = obj.length,
|
||
type = jQuery.type( obj );
|
||
|
||
if ( type === "function" || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
if ( obj.nodeType === 1 && length ) {
|
||
return true;
|
||
}
|
||
|
||
return type === "array" || length === 0 ||
|
||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
||
}
|
||
var Sizzle =
|
||
/*!
|
||
* Sizzle CSS Selector Engine v1.10.19
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2013 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-04-18
|
||
*/
|
||
(function( window ) {
|
||
|
||
var i,
|
||
support,
|
||
Expr,
|
||
getText,
|
||
isXML,
|
||
tokenize,
|
||
compile,
|
||
select,
|
||
outermostContext,
|
||
sortInput,
|
||
hasDuplicate,
|
||
|
||
// Local document vars
|
||
setDocument,
|
||
document,
|
||
docElem,
|
||
documentIsHTML,
|
||
rbuggyQSA,
|
||
rbuggyMatches,
|
||
matches,
|
||
contains,
|
||
|
||
// Instance-specific data
|
||
expando = "sizzle" + -(new Date()),
|
||
preferredDoc = window.document,
|
||
dirruns = 0,
|
||
done = 0,
|
||
classCache = createCache(),
|
||
tokenCache = createCache(),
|
||
compilerCache = createCache(),
|
||
sortOrder = function( a, b ) {
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
}
|
||
return 0;
|
||
},
|
||
|
||
// General-purpose constants
|
||
strundefined = typeof undefined,
|
||
MAX_NEGATIVE = 1 << 31,
|
||
|
||
// Instance methods
|
||
hasOwn = ({}).hasOwnProperty,
|
||
arr = [],
|
||
pop = arr.pop,
|
||
push_native = arr.push,
|
||
push = arr.push,
|
||
slice = arr.slice,
|
||
// Use a stripped-down indexOf if we can't use a native one
|
||
indexOf = arr.indexOf || function( elem ) {
|
||
var i = 0,
|
||
len = this.length;
|
||
for ( ; i < len; i++ ) {
|
||
if ( this[i] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
|
||
|
||
// Regular expressions
|
||
|
||
// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
|
||
whitespace = "[\\x20\\t\\r\\n\\f]",
|
||
// http://www.w3.org/TR/css3-syntax/#characters
|
||
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
|
||
|
||
// Loosely modeled on CSS identifier characters
|
||
// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
|
||
// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
|
||
identifier = characterEncoding.replace( "w", "w#" ),
|
||
|
||
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
|
||
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
|
||
// Operator (capture 2)
|
||
"*([*^$|!~]?=)" + whitespace +
|
||
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
|
||
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
|
||
"*\\]",
|
||
|
||
pseudos = ":(" + characterEncoding + ")(?:\\((" +
|
||
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
|
||
// 1. quoted (capture 3; capture 4 or capture 5)
|
||
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
|
||
// 2. simple (capture 6)
|
||
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
|
||
// 3. anything else (capture 2)
|
||
".*" +
|
||
")\\)|)",
|
||
|
||
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
|
||
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
|
||
|
||
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
|
||
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
|
||
|
||
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
|
||
|
||
rpseudo = new RegExp( pseudos ),
|
||
ridentifier = new RegExp( "^" + identifier + "$" ),
|
||
|
||
matchExpr = {
|
||
"ID": new RegExp( "^#(" + characterEncoding + ")" ),
|
||
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
|
||
"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
|
||
"ATTR": new RegExp( "^" + attributes ),
|
||
"PSEUDO": new RegExp( "^" + pseudos ),
|
||
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
|
||
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
|
||
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
|
||
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
|
||
// For use in libraries implementing .is()
|
||
// We use this for POS matching in `select`
|
||
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
|
||
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
|
||
},
|
||
|
||
rinputs = /^(?:input|select|textarea|button)$/i,
|
||
rheader = /^h\d$/i,
|
||
|
||
rnative = /^[^{]+\{\s*\[native \w/,
|
||
|
||
// Easily-parseable/retrievable ID or TAG or CLASS selectors
|
||
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
|
||
|
||
rsibling = /[+~]/,
|
||
rescape = /'|\\/g,
|
||
|
||
// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
|
||
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
|
||
funescape = function( _, escaped, escapedWhitespace ) {
|
||
var high = "0x" + escaped - 0x10000;
|
||
// NaN means non-codepoint
|
||
// Support: Firefox<24
|
||
// Workaround erroneous numeric interpretation of +"0x"
|
||
return high !== high || escapedWhitespace ?
|
||
escaped :
|
||
high < 0 ?
|
||
// BMP codepoint
|
||
String.fromCharCode( high + 0x10000 ) :
|
||
// Supplemental Plane codepoint (surrogate pair)
|
||
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
|
||
};
|
||
|
||
// Optimize for push.apply( _, NodeList )
|
||
try {
|
||
push.apply(
|
||
(arr = slice.call( preferredDoc.childNodes )),
|
||
preferredDoc.childNodes
|
||
);
|
||
// Support: Android<4.0
|
||
// Detect silently failing push.apply
|
||
arr[ preferredDoc.childNodes.length ].nodeType;
|
||
} catch ( e ) {
|
||
push = { apply: arr.length ?
|
||
|
||
// Leverage slice if possible
|
||
function( target, els ) {
|
||
push_native.apply( target, slice.call(els) );
|
||
} :
|
||
|
||
// Support: IE<9
|
||
// Otherwise append directly
|
||
function( target, els ) {
|
||
var j = target.length,
|
||
i = 0;
|
||
// Can't trust NodeList.length
|
||
while ( (target[j++] = els[i++]) ) {}
|
||
target.length = j - 1;
|
||
}
|
||
};
|
||
}
|
||
|
||
function Sizzle( selector, context, results, seed ) {
|
||
var match, elem, m, nodeType,
|
||
// QSA vars
|
||
i, groups, old, nid, newContext, newSelector;
|
||
|
||
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
|
||
context = context || document;
|
||
results = results || [];
|
||
|
||
if ( !selector || typeof selector !== "string" ) {
|
||
return results;
|
||
}
|
||
|
||
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
|
||
return [];
|
||
}
|
||
|
||
if ( documentIsHTML && !seed ) {
|
||
|
||
// Shortcuts
|
||
if ( (match = rquickExpr.exec( selector )) ) {
|
||
// Speed-up: Sizzle("#ID")
|
||
if ( (m = match[1]) ) {
|
||
if ( nodeType === 9 ) {
|
||
elem = context.getElementById( m );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document (jQuery #6963)
|
||
if ( elem && elem.parentNode ) {
|
||
// Handle the case where IE, Opera, and Webkit return items
|
||
// by name instead of ID
|
||
if ( elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
} else {
|
||
return results;
|
||
}
|
||
} else {
|
||
// Context is not a document
|
||
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
|
||
contains( context, elem ) && elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// Speed-up: Sizzle("TAG")
|
||
} else if ( match[2] ) {
|
||
push.apply( results, context.getElementsByTagName( selector ) );
|
||
return results;
|
||
|
||
// Speed-up: Sizzle(".CLASS")
|
||
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
|
||
push.apply( results, context.getElementsByClassName( m ) );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// QSA path
|
||
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
|
||
nid = old = expando;
|
||
newContext = context;
|
||
newSelector = nodeType === 9 && selector;
|
||
|
||
// qSA works strangely on Element-rooted queries
|
||
// We can work around this by specifying an extra ID on the root
|
||
// and working up from there (Thanks to Andrew Dupont for the technique)
|
||
// IE 8 doesn't work on object elements
|
||
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
|
||
groups = tokenize( selector );
|
||
|
||
if ( (old = context.getAttribute("id")) ) {
|
||
nid = old.replace( rescape, "\\$&" );
|
||
} else {
|
||
context.setAttribute( "id", nid );
|
||
}
|
||
nid = "[id='" + nid + "'] ";
|
||
|
||
i = groups.length;
|
||
while ( i-- ) {
|
||
groups[i] = nid + toSelector( groups[i] );
|
||
}
|
||
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
|
||
newSelector = groups.join(",");
|
||
}
|
||
|
||
if ( newSelector ) {
|
||
try {
|
||
push.apply( results,
|
||
newContext.querySelectorAll( newSelector )
|
||
);
|
||
return results;
|
||
} catch(qsaError) {
|
||
} finally {
|
||
if ( !old ) {
|
||
context.removeAttribute("id");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// All others
|
||
return select( selector.replace( rtrim, "$1" ), context, results, seed );
|
||
}
|
||
|
||
/**
|
||
* Create key-value caches of limited size
|
||
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
|
||
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
|
||
* deleting the oldest entry
|
||
*/
|
||
function createCache() {
|
||
var keys = [];
|
||
|
||
function cache( key, value ) {
|
||
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
|
||
if ( keys.push( key + " " ) > Expr.cacheLength ) {
|
||
// Only keep the most recent entries
|
||
delete cache[ keys.shift() ];
|
||
}
|
||
return (cache[ key + " " ] = value);
|
||
}
|
||
return cache;
|
||
}
|
||
|
||
/**
|
||
* Mark a function for special use by Sizzle
|
||
* @param {Function} fn The function to mark
|
||
*/
|
||
function markFunction( fn ) {
|
||
fn[ expando ] = true;
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Support testing using an element
|
||
* @param {Function} fn Passed the created div and expects a boolean result
|
||
*/
|
||
function assert( fn ) {
|
||
var div = document.createElement("div");
|
||
|
||
try {
|
||
return !!fn( div );
|
||
} catch (e) {
|
||
return false;
|
||
} finally {
|
||
// Remove from its parent by default
|
||
if ( div.parentNode ) {
|
||
div.parentNode.removeChild( div );
|
||
}
|
||
// release memory in IE
|
||
div = null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adds the same handler for all of the specified attrs
|
||
* @param {String} attrs Pipe-separated list of attributes
|
||
* @param {Function} handler The method that will be applied
|
||
*/
|
||
function addHandle( attrs, handler ) {
|
||
var arr = attrs.split("|"),
|
||
i = attrs.length;
|
||
|
||
while ( i-- ) {
|
||
Expr.attrHandle[ arr[i] ] = handler;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks document order of two siblings
|
||
* @param {Element} a
|
||
* @param {Element} b
|
||
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
|
||
*/
|
||
function siblingCheck( a, b ) {
|
||
var cur = b && a,
|
||
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
|
||
( ~b.sourceIndex || MAX_NEGATIVE ) -
|
||
( ~a.sourceIndex || MAX_NEGATIVE );
|
||
|
||
// Use IE sourceIndex if available on both nodes
|
||
if ( diff ) {
|
||
return diff;
|
||
}
|
||
|
||
// Check if b follows a
|
||
if ( cur ) {
|
||
while ( (cur = cur.nextSibling) ) {
|
||
if ( cur === b ) {
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return a ? 1 : -1;
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for input types
|
||
* @param {String} type
|
||
*/
|
||
function createInputPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for buttons
|
||
* @param {String} type
|
||
*/
|
||
function createButtonPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return (name === "input" || name === "button") && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for positionals
|
||
* @param {Function} fn
|
||
*/
|
||
function createPositionalPseudo( fn ) {
|
||
return markFunction(function( argument ) {
|
||
argument = +argument;
|
||
return markFunction(function( seed, matches ) {
|
||
var j,
|
||
matchIndexes = fn( [], seed.length, argument ),
|
||
i = matchIndexes.length;
|
||
|
||
// Match elements found at the specified indexes
|
||
while ( i-- ) {
|
||
if ( seed[ (j = matchIndexes[i]) ] ) {
|
||
seed[j] = !(matches[j] = seed[j]);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Checks a node for validity as a Sizzle context
|
||
* @param {Element|Object=} context
|
||
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
|
||
*/
|
||
function testContext( context ) {
|
||
return context && typeof context.getElementsByTagName !== strundefined && context;
|
||
}
|
||
|
||
// Expose support vars for convenience
|
||
support = Sizzle.support = {};
|
||
|
||
/**
|
||
* Detects XML nodes
|
||
* @param {Element|Object} elem An element or a document
|
||
* @returns {Boolean} True iff elem is a non-HTML XML node
|
||
*/
|
||
isXML = Sizzle.isXML = function( elem ) {
|
||
// documentElement is verified for cases where it doesn't yet exist
|
||
// (such as loading iframes in IE - #4833)
|
||
var documentElement = elem && (elem.ownerDocument || elem).documentElement;
|
||
return documentElement ? documentElement.nodeName !== "HTML" : false;
|
||
};
|
||
|
||
/**
|
||
* Sets document-related variables once based on the current document
|
||
* @param {Element|Object} [doc] An element or document object to use to set the document
|
||
* @returns {Object} Returns the current document
|
||
*/
|
||
setDocument = Sizzle.setDocument = function( node ) {
|
||
var hasCompare,
|
||
doc = node ? node.ownerDocument || node : preferredDoc,
|
||
parent = doc.defaultView;
|
||
|
||
// If no document and documentElement is available, return
|
||
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
|
||
return document;
|
||
}
|
||
|
||
// Set our document
|
||
document = doc;
|
||
docElem = doc.documentElement;
|
||
|
||
// Support tests
|
||
documentIsHTML = !isXML( doc );
|
||
|
||
// Support: IE>8
|
||
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
|
||
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
|
||
// IE6-8 do not support the defaultView property so parent will be undefined
|
||
if ( parent && parent !== parent.top ) {
|
||
// IE11 does not have attachEvent, so all must suffer
|
||
if ( parent.addEventListener ) {
|
||
parent.addEventListener( "unload", function() {
|
||
setDocument();
|
||
}, false );
|
||
} else if ( parent.attachEvent ) {
|
||
parent.attachEvent( "onunload", function() {
|
||
setDocument();
|
||
});
|
||
}
|
||
}
|
||
|
||
/* Attributes
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Support: IE<8
|
||
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
|
||
support.attributes = assert(function( div ) {
|
||
div.className = "i";
|
||
return !div.getAttribute("className");
|
||
});
|
||
|
||
/* getElement(s)By*
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Check if getElementsByTagName("*") returns only elements
|
||
support.getElementsByTagName = assert(function( div ) {
|
||
div.appendChild( doc.createComment("") );
|
||
return !div.getElementsByTagName("*").length;
|
||
});
|
||
|
||
// Check if getElementsByClassName can be trusted
|
||
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
|
||
div.innerHTML = "<div class='a'></div><div class='a i'></div>";
|
||
|
||
// Support: Safari<4
|
||
// Catch class over-caching
|
||
div.firstChild.className = "i";
|
||
// Support: Opera<10
|
||
// Catch gEBCN failure to find non-leading classes
|
||
return div.getElementsByClassName("i").length === 2;
|
||
});
|
||
|
||
// Support: IE<10
|
||
// Check if getElementById returns elements by name
|
||
// The broken getElementById methods don't pick up programatically-set names,
|
||
// so use a roundabout getElementsByName test
|
||
support.getById = assert(function( div ) {
|
||
docElem.appendChild( div ).id = expando;
|
||
return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
|
||
});
|
||
|
||
// ID find and filter
|
||
if ( support.getById ) {
|
||
Expr.find["ID"] = function( id, context ) {
|
||
if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
|
||
var m = context.getElementById( id );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document #6963
|
||
return m && m.parentNode ? [ m ] : [];
|
||
}
|
||
};
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
return elem.getAttribute("id") === attrId;
|
||
};
|
||
};
|
||
} else {
|
||
// Support: IE6/7
|
||
// getElementById is not reliable as a find shortcut
|
||
delete Expr.find["ID"];
|
||
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
|
||
return node && node.value === attrId;
|
||
};
|
||
};
|
||
}
|
||
|
||
// Tag
|
||
Expr.find["TAG"] = support.getElementsByTagName ?
|
||
function( tag, context ) {
|
||
if ( typeof context.getElementsByTagName !== strundefined ) {
|
||
return context.getElementsByTagName( tag );
|
||
}
|
||
} :
|
||
function( tag, context ) {
|
||
var elem,
|
||
tmp = [],
|
||
i = 0,
|
||
results = context.getElementsByTagName( tag );
|
||
|
||
// Filter out possible comments
|
||
if ( tag === "*" ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
tmp.push( elem );
|
||
}
|
||
}
|
||
|
||
return tmp;
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Class
|
||
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
|
||
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
|
||
return context.getElementsByClassName( className );
|
||
}
|
||
};
|
||
|
||
/* QSA/matchesSelector
|
||
---------------------------------------------------------------------- */
|
||
|
||
// QSA and matchesSelector support
|
||
|
||
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
|
||
rbuggyMatches = [];
|
||
|
||
// qSa(:focus) reports false when true (Chrome 21)
|
||
// We allow this because of a bug in IE8/9 that throws an error
|
||
// whenever `document.activeElement` is accessed on an iframe
|
||
// So, we allow :focus to pass through QSA all the time to avoid the IE error
|
||
// See http://bugs.jquery.com/ticket/13378
|
||
rbuggyQSA = [];
|
||
|
||
if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
|
||
// Build QSA regex
|
||
// Regex strategy adopted from Diego Perini
|
||
assert(function( div ) {
|
||
// Select is set to empty string on purpose
|
||
// This is to test IE's treatment of not explicitly
|
||
// setting a boolean content attribute,
|
||
// since its presence should be enough
|
||
// http://bugs.jquery.com/ticket/12359
|
||
div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
|
||
|
||
// Support: IE8, Opera 11-12.16
|
||
// Nothing should be selected when empty strings follow ^= or $= or *=
|
||
// The test attribute must be unknown in Opera but "safe" for WinRT
|
||
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
|
||
if ( div.querySelectorAll("[msallowclip^='']").length ) {
|
||
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
|
||
}
|
||
|
||
// Support: IE8
|
||
// Boolean attributes and "value" are not treated correctly
|
||
if ( !div.querySelectorAll("[selected]").length ) {
|
||
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
|
||
}
|
||
|
||
// Webkit/Opera - :checked should return selected option elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":checked").length ) {
|
||
rbuggyQSA.push(":checked");
|
||
}
|
||
});
|
||
|
||
assert(function( div ) {
|
||
// Support: Windows 8 Native Apps
|
||
// The type and name attributes are restricted during .innerHTML assignment
|
||
var input = doc.createElement("input");
|
||
input.setAttribute( "type", "hidden" );
|
||
div.appendChild( input ).setAttribute( "name", "D" );
|
||
|
||
// Support: IE8
|
||
// Enforce case-sensitivity of name attribute
|
||
if ( div.querySelectorAll("[name=d]").length ) {
|
||
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
|
||
}
|
||
|
||
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":enabled").length ) {
|
||
rbuggyQSA.push( ":enabled", ":disabled" );
|
||
}
|
||
|
||
// Opera 10-11 does not throw on post-comma invalid pseudos
|
||
div.querySelectorAll("*,:x");
|
||
rbuggyQSA.push(",.*:");
|
||
});
|
||
}
|
||
|
||
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
|
||
docElem.webkitMatchesSelector ||
|
||
docElem.mozMatchesSelector ||
|
||
docElem.oMatchesSelector ||
|
||
docElem.msMatchesSelector) )) ) {
|
||
|
||
assert(function( div ) {
|
||
// Check to see if it's possible to do matchesSelector
|
||
// on a disconnected node (IE 9)
|
||
support.disconnectedMatch = matches.call( div, "div" );
|
||
|
||
// This should fail with an exception
|
||
// Gecko does not error, returns false instead
|
||
matches.call( div, "[s!='']:x" );
|
||
rbuggyMatches.push( "!=", pseudos );
|
||
});
|
||
}
|
||
|
||
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
|
||
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
|
||
|
||
/* Contains
|
||
---------------------------------------------------------------------- */
|
||
hasCompare = rnative.test( docElem.compareDocumentPosition );
|
||
|
||
// Element contains another
|
||
// Purposefully does not implement inclusive descendent
|
||
// As in, an element does not contain itself
|
||
contains = hasCompare || rnative.test( docElem.contains ) ?
|
||
function( a, b ) {
|
||
var adown = a.nodeType === 9 ? a.documentElement : a,
|
||
bup = b && b.parentNode;
|
||
return a === bup || !!( bup && bup.nodeType === 1 && (
|
||
adown.contains ?
|
||
adown.contains( bup ) :
|
||
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
||
));
|
||
} :
|
||
function( a, b ) {
|
||
if ( b ) {
|
||
while ( (b = b.parentNode) ) {
|
||
if ( b === a ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/* Sorting
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Document order sorting
|
||
sortOrder = hasCompare ?
|
||
function( a, b ) {
|
||
|
||
// Flag for duplicate removal
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
// Sort on method existence if only one input has compareDocumentPosition
|
||
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
|
||
if ( compare ) {
|
||
return compare;
|
||
}
|
||
|
||
// Calculate position if both inputs belong to the same document
|
||
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
|
||
a.compareDocumentPosition( b ) :
|
||
|
||
// Otherwise we know they are disconnected
|
||
1;
|
||
|
||
// Disconnected nodes
|
||
if ( compare & 1 ||
|
||
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
|
||
|
||
// Choose the first element that is related to our preferred document
|
||
if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
|
||
return -1;
|
||
}
|
||
if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
|
||
return 1;
|
||
}
|
||
|
||
// Maintain original order
|
||
return sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
}
|
||
|
||
return compare & 4 ? -1 : 1;
|
||
} :
|
||
function( a, b ) {
|
||
// Exit early if the nodes are identical
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
var cur,
|
||
i = 0,
|
||
aup = a.parentNode,
|
||
bup = b.parentNode,
|
||
ap = [ a ],
|
||
bp = [ b ];
|
||
|
||
// Parentless nodes are either documents or disconnected
|
||
if ( !aup || !bup ) {
|
||
return a === doc ? -1 :
|
||
b === doc ? 1 :
|
||
aup ? -1 :
|
||
bup ? 1 :
|
||
sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
|
||
// If the nodes are siblings, we can do a quick check
|
||
} else if ( aup === bup ) {
|
||
return siblingCheck( a, b );
|
||
}
|
||
|
||
// Otherwise we need full lists of their ancestors for comparison
|
||
cur = a;
|
||
while ( (cur = cur.parentNode) ) {
|
||
ap.unshift( cur );
|
||
}
|
||
cur = b;
|
||
while ( (cur = cur.parentNode) ) {
|
||
bp.unshift( cur );
|
||
}
|
||
|
||
// Walk down the tree looking for a discrepancy
|
||
while ( ap[i] === bp[i] ) {
|
||
i++;
|
||
}
|
||
|
||
return i ?
|
||
// Do a sibling check if the nodes have a common ancestor
|
||
siblingCheck( ap[i], bp[i] ) :
|
||
|
||
// Otherwise nodes in our document sort first
|
||
ap[i] === preferredDoc ? -1 :
|
||
bp[i] === preferredDoc ? 1 :
|
||
0;
|
||
};
|
||
|
||
return doc;
|
||
};
|
||
|
||
Sizzle.matches = function( expr, elements ) {
|
||
return Sizzle( expr, null, null, elements );
|
||
};
|
||
|
||
Sizzle.matchesSelector = function( elem, expr ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
// Make sure that attribute selectors are quoted
|
||
expr = expr.replace( rattributeQuotes, "='$1']" );
|
||
|
||
if ( support.matchesSelector && documentIsHTML &&
|
||
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
|
||
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
|
||
|
||
try {
|
||
var ret = matches.call( elem, expr );
|
||
|
||
// IE 9's matchesSelector returns false on disconnected nodes
|
||
if ( ret || support.disconnectedMatch ||
|
||
// As well, disconnected nodes are said to be in a document
|
||
// fragment in IE 9
|
||
elem.document && elem.document.nodeType !== 11 ) {
|
||
return ret;
|
||
}
|
||
} catch(e) {}
|
||
}
|
||
|
||
return Sizzle( expr, document, null, [ elem ] ).length > 0;
|
||
};
|
||
|
||
Sizzle.contains = function( context, elem ) {
|
||
// Set document vars if needed
|
||
if ( ( context.ownerDocument || context ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
return contains( context, elem );
|
||
};
|
||
|
||
Sizzle.attr = function( elem, name ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
var fn = Expr.attrHandle[ name.toLowerCase() ],
|
||
// Don't get fooled by Object.prototype properties (jQuery #13807)
|
||
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
|
||
fn( elem, name, !documentIsHTML ) :
|
||
undefined;
|
||
|
||
return val !== undefined ?
|
||
val :
|
||
support.attributes || !documentIsHTML ?
|
||
elem.getAttribute( name ) :
|
||
(val = elem.getAttributeNode(name)) && val.specified ?
|
||
val.value :
|
||
null;
|
||
};
|
||
|
||
Sizzle.error = function( msg ) {
|
||
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
||
};
|
||
|
||
/**
|
||
* Document sorting and removing duplicates
|
||
* @param {ArrayLike} results
|
||
*/
|
||
Sizzle.uniqueSort = function( results ) {
|
||
var elem,
|
||
duplicates = [],
|
||
j = 0,
|
||
i = 0;
|
||
|
||
// Unless we *know* we can detect duplicates, assume their presence
|
||
hasDuplicate = !support.detectDuplicates;
|
||
sortInput = !support.sortStable && results.slice( 0 );
|
||
results.sort( sortOrder );
|
||
|
||
if ( hasDuplicate ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem === results[ i ] ) {
|
||
j = duplicates.push( i );
|
||
}
|
||
}
|
||
while ( j-- ) {
|
||
results.splice( duplicates[ j ], 1 );
|
||
}
|
||
}
|
||
|
||
// Clear input after sorting to release objects
|
||
// See https://github.com/jquery/sizzle/pull/225
|
||
sortInput = null;
|
||
|
||
return results;
|
||
};
|
||
|
||
/**
|
||
* Utility function for retrieving the text value of an array of DOM nodes
|
||
* @param {Array|Element} elem
|
||
*/
|
||
getText = Sizzle.getText = function( elem ) {
|
||
var node,
|
||
ret = "",
|
||
i = 0,
|
||
nodeType = elem.nodeType;
|
||
|
||
if ( !nodeType ) {
|
||
// If no nodeType, this is expected to be an array
|
||
while ( (node = elem[i++]) ) {
|
||
// Do not traverse comment nodes
|
||
ret += getText( node );
|
||
}
|
||
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||
// Use textContent for elements
|
||
// innerText usage removed for consistency of new lines (jQuery #11153)
|
||
if ( typeof elem.textContent === "string" ) {
|
||
return elem.textContent;
|
||
} else {
|
||
// Traverse its children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
ret += getText( elem );
|
||
}
|
||
}
|
||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||
return elem.nodeValue;
|
||
}
|
||
// Do not include comment or processing instruction nodes
|
||
|
||
return ret;
|
||
};
|
||
|
||
Expr = Sizzle.selectors = {
|
||
|
||
// Can be adjusted by the user
|
||
cacheLength: 50,
|
||
|
||
createPseudo: markFunction,
|
||
|
||
match: matchExpr,
|
||
|
||
attrHandle: {},
|
||
|
||
find: {},
|
||
|
||
relative: {
|
||
">": { dir: "parentNode", first: true },
|
||
" ": { dir: "parentNode" },
|
||
"+": { dir: "previousSibling", first: true },
|
||
"~": { dir: "previousSibling" }
|
||
},
|
||
|
||
preFilter: {
|
||
"ATTR": function( match ) {
|
||
match[1] = match[1].replace( runescape, funescape );
|
||
|
||
// Move the given value to match[3] whether quoted or unquoted
|
||
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
|
||
|
||
if ( match[2] === "~=" ) {
|
||
match[3] = " " + match[3] + " ";
|
||
}
|
||
|
||
return match.slice( 0, 4 );
|
||
},
|
||
|
||
"CHILD": function( match ) {
|
||
/* matches from matchExpr["CHILD"]
|
||
1 type (only|nth|...)
|
||
2 what (child|of-type)
|
||
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
|
||
4 xn-component of xn+y argument ([+-]?\d*n|)
|
||
5 sign of xn-component
|
||
6 x of xn-component
|
||
7 sign of y-component
|
||
8 y of y-component
|
||
*/
|
||
match[1] = match[1].toLowerCase();
|
||
|
||
if ( match[1].slice( 0, 3 ) === "nth" ) {
|
||
// nth-* requires argument
|
||
if ( !match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
// numeric x and y parameters for Expr.filter.CHILD
|
||
// remember that false/true cast respectively to 0/1
|
||
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
|
||
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
|
||
|
||
// other types prohibit arguments
|
||
} else if ( match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
return match;
|
||
},
|
||
|
||
"PSEUDO": function( match ) {
|
||
var excess,
|
||
unquoted = !match[6] && match[2];
|
||
|
||
if ( matchExpr["CHILD"].test( match[0] ) ) {
|
||
return null;
|
||
}
|
||
|
||
// Accept quoted arguments as-is
|
||
if ( match[3] ) {
|
||
match[2] = match[4] || match[5] || "";
|
||
|
||
// Strip excess characters from unquoted arguments
|
||
} else if ( unquoted && rpseudo.test( unquoted ) &&
|
||
// Get excess from tokenize (recursively)
|
||
(excess = tokenize( unquoted, true )) &&
|
||
// advance to the next closing parenthesis
|
||
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
|
||
|
||
// excess is a negative index
|
||
match[0] = match[0].slice( 0, excess );
|
||
match[2] = unquoted.slice( 0, excess );
|
||
}
|
||
|
||
// Return only captures needed by the pseudo filter method (type and argument)
|
||
return match.slice( 0, 3 );
|
||
}
|
||
},
|
||
|
||
filter: {
|
||
|
||
"TAG": function( nodeNameSelector ) {
|
||
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
|
||
return nodeNameSelector === "*" ?
|
||
function() { return true; } :
|
||
function( elem ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
||
};
|
||
},
|
||
|
||
"CLASS": function( className ) {
|
||
var pattern = classCache[ className + " " ];
|
||
|
||
return pattern ||
|
||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
|
||
classCache( className, function( elem ) {
|
||
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
|
||
});
|
||
},
|
||
|
||
"ATTR": function( name, operator, check ) {
|
||
return function( elem ) {
|
||
var result = Sizzle.attr( elem, name );
|
||
|
||
if ( result == null ) {
|
||
return operator === "!=";
|
||
}
|
||
if ( !operator ) {
|
||
return true;
|
||
}
|
||
|
||
result += "";
|
||
|
||
return operator === "=" ? result === check :
|
||
operator === "!=" ? result !== check :
|
||
operator === "^=" ? check && result.indexOf( check ) === 0 :
|
||
operator === "*=" ? check && result.indexOf( check ) > -1 :
|
||
operator === "$=" ? check && result.slice( -check.length ) === check :
|
||
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
|
||
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
|
||
false;
|
||
};
|
||
},
|
||
|
||
"CHILD": function( type, what, argument, first, last ) {
|
||
var simple = type.slice( 0, 3 ) !== "nth",
|
||
forward = type.slice( -4 ) !== "last",
|
||
ofType = what === "of-type";
|
||
|
||
return first === 1 && last === 0 ?
|
||
|
||
// Shortcut for :nth-*(n)
|
||
function( elem ) {
|
||
return !!elem.parentNode;
|
||
} :
|
||
|
||
function( elem, context, xml ) {
|
||
var cache, outerCache, node, diff, nodeIndex, start,
|
||
dir = simple !== forward ? "nextSibling" : "previousSibling",
|
||
parent = elem.parentNode,
|
||
name = ofType && elem.nodeName.toLowerCase(),
|
||
useCache = !xml && !ofType;
|
||
|
||
if ( parent ) {
|
||
|
||
// :(first|last|only)-(child|of-type)
|
||
if ( simple ) {
|
||
while ( dir ) {
|
||
node = elem;
|
||
while ( (node = node[ dir ]) ) {
|
||
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
|
||
return false;
|
||
}
|
||
}
|
||
// Reverse direction for :only-* (if we haven't yet done so)
|
||
start = dir = type === "only" && !start && "nextSibling";
|
||
}
|
||
return true;
|
||
}
|
||
|
||
start = [ forward ? parent.firstChild : parent.lastChild ];
|
||
|
||
// non-xml :nth-child(...) stores cache data on `parent`
|
||
if ( forward && useCache ) {
|
||
// Seek `elem` from a previously-cached index
|
||
outerCache = parent[ expando ] || (parent[ expando ] = {});
|
||
cache = outerCache[ type ] || [];
|
||
nodeIndex = cache[0] === dirruns && cache[1];
|
||
diff = cache[0] === dirruns && cache[2];
|
||
node = nodeIndex && parent.childNodes[ nodeIndex ];
|
||
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
|
||
// Fallback to seeking `elem` from the start
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
// When found, cache indexes on `parent` and break
|
||
if ( node.nodeType === 1 && ++diff && node === elem ) {
|
||
outerCache[ type ] = [ dirruns, nodeIndex, diff ];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Use previously-cached element index if available
|
||
} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
|
||
diff = cache[1];
|
||
|
||
// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
|
||
} else {
|
||
// Use the same loop as above to seek `elem` from the start
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
|
||
// Cache the index of each encountered element
|
||
if ( useCache ) {
|
||
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
|
||
}
|
||
|
||
if ( node === elem ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Incorporate the offset, then check against cycle size
|
||
diff -= last;
|
||
return diff === first || ( diff % first === 0 && diff / first >= 0 );
|
||
}
|
||
};
|
||
},
|
||
|
||
"PSEUDO": function( pseudo, argument ) {
|
||
// pseudo-class names are case-insensitive
|
||
// http://www.w3.org/TR/selectors/#pseudo-classes
|
||
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
|
||
// Remember that setFilters inherits from pseudos
|
||
var args,
|
||
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
|
||
Sizzle.error( "unsupported pseudo: " + pseudo );
|
||
|
||
// The user may use createPseudo to indicate that
|
||
// arguments are needed to create the filter function
|
||
// just as Sizzle does
|
||
if ( fn[ expando ] ) {
|
||
return fn( argument );
|
||
}
|
||
|
||
// But maintain support for old signatures
|
||
if ( fn.length > 1 ) {
|
||
args = [ pseudo, pseudo, "", argument ];
|
||
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
|
||
markFunction(function( seed, matches ) {
|
||
var idx,
|
||
matched = fn( seed, argument ),
|
||
i = matched.length;
|
||
while ( i-- ) {
|
||
idx = indexOf.call( seed, matched[i] );
|
||
seed[ idx ] = !( matches[ idx ] = matched[i] );
|
||
}
|
||
}) :
|
||
function( elem ) {
|
||
return fn( elem, 0, args );
|
||
};
|
||
}
|
||
|
||
return fn;
|
||
}
|
||
},
|
||
|
||
pseudos: {
|
||
// Potentially complex pseudos
|
||
"not": markFunction(function( selector ) {
|
||
// Trim the selector passed to compile
|
||
// to avoid treating leading and trailing
|
||
// spaces as combinators
|
||
var input = [],
|
||
results = [],
|
||
matcher = compile( selector.replace( rtrim, "$1" ) );
|
||
|
||
return matcher[ expando ] ?
|
||
markFunction(function( seed, matches, context, xml ) {
|
||
var elem,
|
||
unmatched = matcher( seed, null, xml, [] ),
|
||
i = seed.length;
|
||
|
||
// Match elements unmatched by `matcher`
|
||
while ( i-- ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
seed[i] = !(matches[i] = elem);
|
||
}
|
||
}
|
||
}) :
|
||
function( elem, context, xml ) {
|
||
input[0] = elem;
|
||
matcher( input, null, xml, results );
|
||
return !results.pop();
|
||
};
|
||
}),
|
||
|
||
"has": markFunction(function( selector ) {
|
||
return function( elem ) {
|
||
return Sizzle( selector, elem ).length > 0;
|
||
};
|
||
}),
|
||
|
||
"contains": markFunction(function( text ) {
|
||
return function( elem ) {
|
||
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
|
||
};
|
||
}),
|
||
|
||
// "Whether an element is represented by a :lang() selector
|
||
// is based solely on the element's language value
|
||
// being equal to the identifier C,
|
||
// or beginning with the identifier C immediately followed by "-".
|
||
// The matching of C against the element's language value is performed case-insensitively.
|
||
// The identifier C does not have to be a valid language name."
|
||
// http://www.w3.org/TR/selectors/#lang-pseudo
|
||
"lang": markFunction( function( lang ) {
|
||
// lang value must be a valid identifier
|
||
if ( !ridentifier.test(lang || "") ) {
|
||
Sizzle.error( "unsupported lang: " + lang );
|
||
}
|
||
lang = lang.replace( runescape, funescape ).toLowerCase();
|
||
return function( elem ) {
|
||
var elemLang;
|
||
do {
|
||
if ( (elemLang = documentIsHTML ?
|
||
elem.lang :
|
||
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
|
||
|
||
elemLang = elemLang.toLowerCase();
|
||
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
|
||
}
|
||
} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
|
||
return false;
|
||
};
|
||
}),
|
||
|
||
// Miscellaneous
|
||
"target": function( elem ) {
|
||
var hash = window.location && window.location.hash;
|
||
return hash && hash.slice( 1 ) === elem.id;
|
||
},
|
||
|
||
"root": function( elem ) {
|
||
return elem === docElem;
|
||
},
|
||
|
||
"focus": function( elem ) {
|
||
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
|
||
},
|
||
|
||
// Boolean properties
|
||
"enabled": function( elem ) {
|
||
return elem.disabled === false;
|
||
},
|
||
|
||
"disabled": function( elem ) {
|
||
return elem.disabled === true;
|
||
},
|
||
|
||
"checked": function( elem ) {
|
||
// In CSS3, :checked should return both checked and selected elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
var nodeName = elem.nodeName.toLowerCase();
|
||
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
|
||
},
|
||
|
||
"selected": function( elem ) {
|
||
// Accessing this property makes selected-by-default
|
||
// options in Safari work properly
|
||
if ( elem.parentNode ) {
|
||
elem.parentNode.selectedIndex;
|
||
}
|
||
|
||
return elem.selected === true;
|
||
},
|
||
|
||
// Contents
|
||
"empty": function( elem ) {
|
||
// http://www.w3.org/TR/selectors/#empty-pseudo
|
||
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
|
||
// but not by others (comment: 8; processing instruction: 7; etc.)
|
||
// nodeType < 6 works because attributes (2) do not appear as children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
if ( elem.nodeType < 6 ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
"parent": function( elem ) {
|
||
return !Expr.pseudos["empty"]( elem );
|
||
},
|
||
|
||
// Element/input types
|
||
"header": function( elem ) {
|
||
return rheader.test( elem.nodeName );
|
||
},
|
||
|
||
"input": function( elem ) {
|
||
return rinputs.test( elem.nodeName );
|
||
},
|
||
|
||
"button": function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === "button" || name === "button";
|
||
},
|
||
|
||
"text": function( elem ) {
|
||
var attr;
|
||
return elem.nodeName.toLowerCase() === "input" &&
|
||
elem.type === "text" &&
|
||
|
||
// Support: IE<8
|
||
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
|
||
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
|
||
},
|
||
|
||
// Position-in-collection
|
||
"first": createPositionalPseudo(function() {
|
||
return [ 0 ];
|
||
}),
|
||
|
||
"last": createPositionalPseudo(function( matchIndexes, length ) {
|
||
return [ length - 1 ];
|
||
}),
|
||
|
||
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
return [ argument < 0 ? argument + length : argument ];
|
||
}),
|
||
|
||
"even": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 0;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"odd": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 1;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; --i >= 0; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; ++i < length; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
})
|
||
}
|
||
};
|
||
|
||
Expr.pseudos["nth"] = Expr.pseudos["eq"];
|
||
|
||
// Add button/input type pseudos
|
||
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
|
||
Expr.pseudos[ i ] = createInputPseudo( i );
|
||
}
|
||
for ( i in { submit: true, reset: true } ) {
|
||
Expr.pseudos[ i ] = createButtonPseudo( i );
|
||
}
|
||
|
||
// Easy API for creating new setFilters
|
||
function setFilters() {}
|
||
setFilters.prototype = Expr.filters = Expr.pseudos;
|
||
Expr.setFilters = new setFilters();
|
||
|
||
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
|
||
var matched, match, tokens, type,
|
||
soFar, groups, preFilters,
|
||
cached = tokenCache[ selector + " " ];
|
||
|
||
if ( cached ) {
|
||
return parseOnly ? 0 : cached.slice( 0 );
|
||
}
|
||
|
||
soFar = selector;
|
||
groups = [];
|
||
preFilters = Expr.preFilter;
|
||
|
||
while ( soFar ) {
|
||
|
||
// Comma and first run
|
||
if ( !matched || (match = rcomma.exec( soFar )) ) {
|
||
if ( match ) {
|
||
// Don't consume trailing commas as valid
|
||
soFar = soFar.slice( match[0].length ) || soFar;
|
||
}
|
||
groups.push( (tokens = []) );
|
||
}
|
||
|
||
matched = false;
|
||
|
||
// Combinators
|
||
if ( (match = rcombinators.exec( soFar )) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
// Cast descendant combinators to space
|
||
type: match[0].replace( rtrim, " " )
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
|
||
// Filters
|
||
for ( type in Expr.filter ) {
|
||
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
|
||
(match = preFilters[ type ]( match ))) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
type: type,
|
||
matches: match
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
}
|
||
|
||
if ( !matched ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Return the length of the invalid excess
|
||
// if we're just parsing
|
||
// Otherwise, throw an error or return tokens
|
||
return parseOnly ?
|
||
soFar.length :
|
||
soFar ?
|
||
Sizzle.error( selector ) :
|
||
// Cache the tokens
|
||
tokenCache( selector, groups ).slice( 0 );
|
||
};
|
||
|
||
function toSelector( tokens ) {
|
||
var i = 0,
|
||
len = tokens.length,
|
||
selector = "";
|
||
for ( ; i < len; i++ ) {
|
||
selector += tokens[i].value;
|
||
}
|
||
return selector;
|
||
}
|
||
|
||
function addCombinator( matcher, combinator, base ) {
|
||
var dir = combinator.dir,
|
||
checkNonElements = base && dir === "parentNode",
|
||
doneName = done++;
|
||
|
||
return combinator.first ?
|
||
// Check against closest ancestor/preceding element
|
||
function( elem, context, xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
return matcher( elem, context, xml );
|
||
}
|
||
}
|
||
} :
|
||
|
||
// Check against all ancestor/preceding elements
|
||
function( elem, context, xml ) {
|
||
var oldCache, outerCache,
|
||
newCache = [ dirruns, doneName ];
|
||
|
||
// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
|
||
if ( xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
outerCache = elem[ expando ] || (elem[ expando ] = {});
|
||
if ( (oldCache = outerCache[ dir ]) &&
|
||
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
|
||
|
||
// Assign to newCache so results back-propagate to previous elements
|
||
return (newCache[ 2 ] = oldCache[ 2 ]);
|
||
} else {
|
||
// Reuse newcache so results back-propagate to previous elements
|
||
outerCache[ dir ] = newCache;
|
||
|
||
// A match means we're done; a fail means we have to keep checking
|
||
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
function elementMatcher( matchers ) {
|
||
return matchers.length > 1 ?
|
||
function( elem, context, xml ) {
|
||
var i = matchers.length;
|
||
while ( i-- ) {
|
||
if ( !matchers[i]( elem, context, xml ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
} :
|
||
matchers[0];
|
||
}
|
||
|
||
function multipleContexts( selector, contexts, results ) {
|
||
var i = 0,
|
||
len = contexts.length;
|
||
for ( ; i < len; i++ ) {
|
||
Sizzle( selector, contexts[i], results );
|
||
}
|
||
return results;
|
||
}
|
||
|
||
function condense( unmatched, map, filter, context, xml ) {
|
||
var elem,
|
||
newUnmatched = [],
|
||
i = 0,
|
||
len = unmatched.length,
|
||
mapped = map != null;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
if ( !filter || filter( elem, context, xml ) ) {
|
||
newUnmatched.push( elem );
|
||
if ( mapped ) {
|
||
map.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return newUnmatched;
|
||
}
|
||
|
||
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
|
||
if ( postFilter && !postFilter[ expando ] ) {
|
||
postFilter = setMatcher( postFilter );
|
||
}
|
||
if ( postFinder && !postFinder[ expando ] ) {
|
||
postFinder = setMatcher( postFinder, postSelector );
|
||
}
|
||
return markFunction(function( seed, results, context, xml ) {
|
||
var temp, i, elem,
|
||
preMap = [],
|
||
postMap = [],
|
||
preexisting = results.length,
|
||
|
||
// Get initial elements from seed or context
|
||
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
|
||
|
||
// Prefilter to get matcher input, preserving a map for seed-results synchronization
|
||
matcherIn = preFilter && ( seed || !selector ) ?
|
||
condense( elems, preMap, preFilter, context, xml ) :
|
||
elems,
|
||
|
||
matcherOut = matcher ?
|
||
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
|
||
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
|
||
|
||
// ...intermediate processing is necessary
|
||
[] :
|
||
|
||
// ...otherwise use results directly
|
||
results :
|
||
matcherIn;
|
||
|
||
// Find primary matches
|
||
if ( matcher ) {
|
||
matcher( matcherIn, matcherOut, context, xml );
|
||
}
|
||
|
||
// Apply postFilter
|
||
if ( postFilter ) {
|
||
temp = condense( matcherOut, postMap );
|
||
postFilter( temp, [], context, xml );
|
||
|
||
// Un-match failing elements by moving them back to matcherIn
|
||
i = temp.length;
|
||
while ( i-- ) {
|
||
if ( (elem = temp[i]) ) {
|
||
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( seed ) {
|
||
if ( postFinder || preFilter ) {
|
||
if ( postFinder ) {
|
||
// Get the final matcherOut by condensing this intermediate into postFinder contexts
|
||
temp = [];
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) ) {
|
||
// Restore matcherIn since elem is not yet a final match
|
||
temp.push( (matcherIn[i] = elem) );
|
||
}
|
||
}
|
||
postFinder( null, (matcherOut = []), temp, xml );
|
||
}
|
||
|
||
// Move matched elements from seed to results to keep them synchronized
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) &&
|
||
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
|
||
|
||
seed[temp] = !(results[temp] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add elements to results, through postFinder if defined
|
||
} else {
|
||
matcherOut = condense(
|
||
matcherOut === results ?
|
||
matcherOut.splice( preexisting, matcherOut.length ) :
|
||
matcherOut
|
||
);
|
||
if ( postFinder ) {
|
||
postFinder( null, results, matcherOut, xml );
|
||
} else {
|
||
push.apply( results, matcherOut );
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function matcherFromTokens( tokens ) {
|
||
var checkContext, matcher, j,
|
||
len = tokens.length,
|
||
leadingRelative = Expr.relative[ tokens[0].type ],
|
||
implicitRelative = leadingRelative || Expr.relative[" "],
|
||
i = leadingRelative ? 1 : 0,
|
||
|
||
// The foundational matcher ensures that elements are reachable from top-level context(s)
|
||
matchContext = addCombinator( function( elem ) {
|
||
return elem === checkContext;
|
||
}, implicitRelative, true ),
|
||
matchAnyContext = addCombinator( function( elem ) {
|
||
return indexOf.call( checkContext, elem ) > -1;
|
||
}, implicitRelative, true ),
|
||
matchers = [ function( elem, context, xml ) {
|
||
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
|
||
(checkContext = context).nodeType ?
|
||
matchContext( elem, context, xml ) :
|
||
matchAnyContext( elem, context, xml ) );
|
||
} ];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
|
||
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
|
||
} else {
|
||
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
|
||
|
||
// Return special upon seeing a positional matcher
|
||
if ( matcher[ expando ] ) {
|
||
// Find the next relative operator (if any) for proper handling
|
||
j = ++i;
|
||
for ( ; j < len; j++ ) {
|
||
if ( Expr.relative[ tokens[j].type ] ) {
|
||
break;
|
||
}
|
||
}
|
||
return setMatcher(
|
||
i > 1 && elementMatcher( matchers ),
|
||
i > 1 && toSelector(
|
||
// If the preceding token was a descendant combinator, insert an implicit any-element `*`
|
||
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
|
||
).replace( rtrim, "$1" ),
|
||
matcher,
|
||
i < j && matcherFromTokens( tokens.slice( i, j ) ),
|
||
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
|
||
j < len && toSelector( tokens )
|
||
);
|
||
}
|
||
matchers.push( matcher );
|
||
}
|
||
}
|
||
|
||
return elementMatcher( matchers );
|
||
}
|
||
|
||
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
|
||
var bySet = setMatchers.length > 0,
|
||
byElement = elementMatchers.length > 0,
|
||
superMatcher = function( seed, context, xml, results, outermost ) {
|
||
var elem, j, matcher,
|
||
matchedCount = 0,
|
||
i = "0",
|
||
unmatched = seed && [],
|
||
setMatched = [],
|
||
contextBackup = outermostContext,
|
||
// We must always have either seed elements or outermost context
|
||
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
|
||
// Use integer dirruns iff this is the outermost matcher
|
||
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
|
||
len = elems.length;
|
||
|
||
if ( outermost ) {
|
||
outermostContext = context !== document && context;
|
||
}
|
||
|
||
// Add elements passing elementMatchers directly to results
|
||
// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
|
||
// Support: IE<9, Safari
|
||
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
|
||
for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
|
||
if ( byElement && elem ) {
|
||
j = 0;
|
||
while ( (matcher = elementMatchers[j++]) ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
results.push( elem );
|
||
break;
|
||
}
|
||
}
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
}
|
||
}
|
||
|
||
// Track unmatched elements for set filters
|
||
if ( bySet ) {
|
||
// They will have gone through all possible matchers
|
||
if ( (elem = !matcher && elem) ) {
|
||
matchedCount--;
|
||
}
|
||
|
||
// Lengthen the array for every element, matched or not
|
||
if ( seed ) {
|
||
unmatched.push( elem );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply set filters to unmatched elements
|
||
matchedCount += i;
|
||
if ( bySet && i !== matchedCount ) {
|
||
j = 0;
|
||
while ( (matcher = setMatchers[j++]) ) {
|
||
matcher( unmatched, setMatched, context, xml );
|
||
}
|
||
|
||
if ( seed ) {
|
||
// Reintegrate element matches to eliminate the need for sorting
|
||
if ( matchedCount > 0 ) {
|
||
while ( i-- ) {
|
||
if ( !(unmatched[i] || setMatched[i]) ) {
|
||
setMatched[i] = pop.call( results );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Discard index placeholder values to get only actual matches
|
||
setMatched = condense( setMatched );
|
||
}
|
||
|
||
// Add matches to results
|
||
push.apply( results, setMatched );
|
||
|
||
// Seedless set matches succeeding multiple successful matchers stipulate sorting
|
||
if ( outermost && !seed && setMatched.length > 0 &&
|
||
( matchedCount + setMatchers.length ) > 1 ) {
|
||
|
||
Sizzle.uniqueSort( results );
|
||
}
|
||
}
|
||
|
||
// Override manipulation of globals by nested matchers
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
outermostContext = contextBackup;
|
||
}
|
||
|
||
return unmatched;
|
||
};
|
||
|
||
return bySet ?
|
||
markFunction( superMatcher ) :
|
||
superMatcher;
|
||
}
|
||
|
||
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
|
||
var i,
|
||
setMatchers = [],
|
||
elementMatchers = [],
|
||
cached = compilerCache[ selector + " " ];
|
||
|
||
if ( !cached ) {
|
||
// Generate a function of recursive functions that can be used to check each element
|
||
if ( !match ) {
|
||
match = tokenize( selector );
|
||
}
|
||
i = match.length;
|
||
while ( i-- ) {
|
||
cached = matcherFromTokens( match[i] );
|
||
if ( cached[ expando ] ) {
|
||
setMatchers.push( cached );
|
||
} else {
|
||
elementMatchers.push( cached );
|
||
}
|
||
}
|
||
|
||
// Cache the compiled function
|
||
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
|
||
|
||
// Save selector and tokenization
|
||
cached.selector = selector;
|
||
}
|
||
return cached;
|
||
};
|
||
|
||
/**
|
||
* A low-level selection function that works with Sizzle's compiled
|
||
* selector functions
|
||
* @param {String|Function} selector A selector or a pre-compiled
|
||
* selector function built with Sizzle.compile
|
||
* @param {Element} context
|
||
* @param {Array} [results]
|
||
* @param {Array} [seed] A set of elements to match against
|
||
*/
|
||
select = Sizzle.select = function( selector, context, results, seed ) {
|
||
var i, tokens, token, type, find,
|
||
compiled = typeof selector === "function" && selector,
|
||
match = !seed && tokenize( (selector = compiled.selector || selector) );
|
||
|
||
results = results || [];
|
||
|
||
// Try to minimize operations if there is no seed and only one group
|
||
if ( match.length === 1 ) {
|
||
|
||
// Take a shortcut and set the context if the root selector is an ID
|
||
tokens = match[0] = match[0].slice( 0 );
|
||
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
|
||
support.getById && context.nodeType === 9 && documentIsHTML &&
|
||
Expr.relative[ tokens[1].type ] ) {
|
||
|
||
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
|
||
if ( !context ) {
|
||
return results;
|
||
|
||
// Precompiled matchers will still verify ancestry, so step up a level
|
||
} else if ( compiled ) {
|
||
context = context.parentNode;
|
||
}
|
||
|
||
selector = selector.slice( tokens.shift().value.length );
|
||
}
|
||
|
||
// Fetch a seed set for right-to-left matching
|
||
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
|
||
while ( i-- ) {
|
||
token = tokens[i];
|
||
|
||
// Abort if we hit a combinator
|
||
if ( Expr.relative[ (type = token.type) ] ) {
|
||
break;
|
||
}
|
||
if ( (find = Expr.find[ type ]) ) {
|
||
// Search, expanding context for leading sibling combinators
|
||
if ( (seed = find(
|
||
token.matches[0].replace( runescape, funescape ),
|
||
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
|
||
)) ) {
|
||
|
||
// If seed is empty or no tokens remain, we can return early
|
||
tokens.splice( i, 1 );
|
||
selector = seed.length && toSelector( tokens );
|
||
if ( !selector ) {
|
||
push.apply( results, seed );
|
||
return results;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Compile and execute a filtering function if one is not provided
|
||
// Provide `match` to avoid retokenization if we modified the selector above
|
||
( compiled || compile( selector, match ) )(
|
||
seed,
|
||
context,
|
||
!documentIsHTML,
|
||
results,
|
||
rsibling.test( selector ) && testContext( context.parentNode ) || context
|
||
);
|
||
return results;
|
||
};
|
||
|
||
// One-time assignments
|
||
|
||
// Sort stability
|
||
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
|
||
|
||
// Support: Chrome<14
|
||
// Always assume duplicates if they aren't passed to the comparison function
|
||
support.detectDuplicates = !!hasDuplicate;
|
||
|
||
// Initialize against the default document
|
||
setDocument();
|
||
|
||
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
|
||
// Detached nodes confoundingly follow *each other*
|
||
support.sortDetached = assert(function( div1 ) {
|
||
// Should return 1, but returns 4 (following)
|
||
return div1.compareDocumentPosition( document.createElement("div") ) & 1;
|
||
});
|
||
|
||
// Support: IE<8
|
||
// Prevent attribute/property "interpolation"
|
||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !assert(function( div ) {
|
||
div.innerHTML = "<a href='#'></a>";
|
||
return div.firstChild.getAttribute("href") === "#" ;
|
||
}) ) {
|
||
addHandle( "type|href|height|width", function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use defaultValue in place of getAttribute("value")
|
||
if ( !support.attributes || !assert(function( div ) {
|
||
div.innerHTML = "<input/>";
|
||
div.firstChild.setAttribute( "value", "" );
|
||
return div.firstChild.getAttribute( "value" ) === "";
|
||
}) ) {
|
||
addHandle( "value", function( elem, name, isXML ) {
|
||
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
|
||
return elem.defaultValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use getAttributeNode to fetch booleans when getAttribute lies
|
||
if ( !assert(function( div ) {
|
||
return div.getAttribute("disabled") == null;
|
||
}) ) {
|
||
addHandle( booleans, function( elem, name, isXML ) {
|
||
var val;
|
||
if ( !isXML ) {
|
||
return elem[ name ] === true ? name.toLowerCase() :
|
||
(val = elem.getAttributeNode( name )) && val.specified ?
|
||
val.value :
|
||
null;
|
||
}
|
||
});
|
||
}
|
||
|
||
return Sizzle;
|
||
|
||
})( window );
|
||
|
||
|
||
|
||
jQuery.find = Sizzle;
|
||
jQuery.expr = Sizzle.selectors;
|
||
jQuery.expr[":"] = jQuery.expr.pseudos;
|
||
jQuery.unique = Sizzle.uniqueSort;
|
||
jQuery.text = Sizzle.getText;
|
||
jQuery.isXMLDoc = Sizzle.isXML;
|
||
jQuery.contains = Sizzle.contains;
|
||
|
||
|
||
|
||
var rneedsContext = jQuery.expr.match.needsContext;
|
||
|
||
var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
|
||
|
||
|
||
|
||
var risSimple = /^.[^:#\[\.,]*$/;
|
||
|
||
// Implement the identical functionality for filter and not
|
||
function winnow( elements, qualifier, not ) {
|
||
if ( jQuery.isFunction( qualifier ) ) {
|
||
return jQuery.grep( elements, function( elem, i ) {
|
||
/* jshint -W018 */
|
||
return !!qualifier.call( elem, i, elem ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( qualifier.nodeType ) {
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( elem === qualifier ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( typeof qualifier === "string" ) {
|
||
if ( risSimple.test( qualifier ) ) {
|
||
return jQuery.filter( qualifier, elements, not );
|
||
}
|
||
|
||
qualifier = jQuery.filter( qualifier, elements );
|
||
}
|
||
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
|
||
});
|
||
}
|
||
|
||
jQuery.filter = function( expr, elems, not ) {
|
||
var elem = elems[ 0 ];
|
||
|
||
if ( not ) {
|
||
expr = ":not(" + expr + ")";
|
||
}
|
||
|
||
return elems.length === 1 && elem.nodeType === 1 ?
|
||
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
|
||
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
|
||
return elem.nodeType === 1;
|
||
}));
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
find: function( selector ) {
|
||
var i,
|
||
ret = [],
|
||
self = this,
|
||
len = self.length;
|
||
|
||
if ( typeof selector !== "string" ) {
|
||
return this.pushStack( jQuery( selector ).filter(function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( self[ i ], this ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}) );
|
||
}
|
||
|
||
for ( i = 0; i < len; i++ ) {
|
||
jQuery.find( selector, self[ i ], ret );
|
||
}
|
||
|
||
// Needed because $( selector, context ) becomes $( context ).find( selector )
|
||
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
|
||
ret.selector = this.selector ? this.selector + " " + selector : selector;
|
||
return ret;
|
||
},
|
||
filter: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], false) );
|
||
},
|
||
not: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], true) );
|
||
},
|
||
is: function( selector ) {
|
||
return !!winnow(
|
||
this,
|
||
|
||
// If this is a positional/relative selector, check membership in the returned set
|
||
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
||
typeof selector === "string" && rneedsContext.test( selector ) ?
|
||
jQuery( selector ) :
|
||
selector || [],
|
||
false
|
||
).length;
|
||
}
|
||
});
|
||
|
||
|
||
// Initialize a jQuery object
|
||
|
||
|
||
// A central reference to the root jQuery(document)
|
||
var rootjQuery,
|
||
|
||
// Use the correct document accordingly with window argument (sandbox)
|
||
document = window.document,
|
||
|
||
// A simple way to check for HTML strings
|
||
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
||
// Strict HTML recognition (#11290: must start with <)
|
||
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
|
||
|
||
init = jQuery.fn.init = function( selector, context ) {
|
||
var match, elem;
|
||
|
||
// HANDLE: $(""), $(null), $(undefined), $(false)
|
||
if ( !selector ) {
|
||
return this;
|
||
}
|
||
|
||
// Handle HTML strings
|
||
if ( typeof selector === "string" ) {
|
||
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
|
||
// Assume that strings that start and end with <> are HTML and skip the regex check
|
||
match = [ null, selector, null ];
|
||
|
||
} else {
|
||
match = rquickExpr.exec( selector );
|
||
}
|
||
|
||
// Match html or make sure no context is specified for #id
|
||
if ( match && (match[1] || !context) ) {
|
||
|
||
// HANDLE: $(html) -> $(array)
|
||
if ( match[1] ) {
|
||
context = context instanceof jQuery ? context[0] : context;
|
||
|
||
// scripts is true for back-compat
|
||
// Intentionally let the error be thrown if parseHTML is not present
|
||
jQuery.merge( this, jQuery.parseHTML(
|
||
match[1],
|
||
context && context.nodeType ? context.ownerDocument || context : document,
|
||
true
|
||
) );
|
||
|
||
// HANDLE: $(html, props)
|
||
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
|
||
for ( match in context ) {
|
||
// Properties of context are called as methods if possible
|
||
if ( jQuery.isFunction( this[ match ] ) ) {
|
||
this[ match ]( context[ match ] );
|
||
|
||
// ...and otherwise set as attributes
|
||
} else {
|
||
this.attr( match, context[ match ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
|
||
// HANDLE: $(#id)
|
||
} else {
|
||
elem = document.getElementById( match[2] );
|
||
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document #6963
|
||
if ( elem && elem.parentNode ) {
|
||
// Handle the case where IE and Opera return items
|
||
// by name instead of ID
|
||
if ( elem.id !== match[2] ) {
|
||
return rootjQuery.find( selector );
|
||
}
|
||
|
||
// Otherwise, we inject the element directly into the jQuery object
|
||
this.length = 1;
|
||
this[0] = elem;
|
||
}
|
||
|
||
this.context = document;
|
||
this.selector = selector;
|
||
return this;
|
||
}
|
||
|
||
// HANDLE: $(expr, $(...))
|
||
} else if ( !context || context.jquery ) {
|
||
return ( context || rootjQuery ).find( selector );
|
||
|
||
// HANDLE: $(expr, context)
|
||
// (which is just equivalent to: $(context).find(expr)
|
||
} else {
|
||
return this.constructor( context ).find( selector );
|
||
}
|
||
|
||
// HANDLE: $(DOMElement)
|
||
} else if ( selector.nodeType ) {
|
||
this.context = this[0] = selector;
|
||
this.length = 1;
|
||
return this;
|
||
|
||
// HANDLE: $(function)
|
||
// Shortcut for document ready
|
||
} else if ( jQuery.isFunction( selector ) ) {
|
||
return typeof rootjQuery.ready !== "undefined" ?
|
||
rootjQuery.ready( selector ) :
|
||
// Execute immediately if ready is not present
|
||
selector( jQuery );
|
||
}
|
||
|
||
if ( selector.selector !== undefined ) {
|
||
this.selector = selector.selector;
|
||
this.context = selector.context;
|
||
}
|
||
|
||
return jQuery.makeArray( selector, this );
|
||
};
|
||
|
||
// Give the init function the jQuery prototype for later instantiation
|
||
init.prototype = jQuery.fn;
|
||
|
||
// Initialize central reference
|
||
rootjQuery = jQuery( document );
|
||
|
||
|
||
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
|
||
// methods guaranteed to produce a unique set when starting from a unique set
|
||
guaranteedUnique = {
|
||
children: true,
|
||
contents: true,
|
||
next: true,
|
||
prev: true
|
||
};
|
||
|
||
jQuery.extend({
|
||
dir: function( elem, dir, until ) {
|
||
var matched = [],
|
||
cur = elem[ dir ];
|
||
|
||
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
|
||
if ( cur.nodeType === 1 ) {
|
||
matched.push( cur );
|
||
}
|
||
cur = cur[dir];
|
||
}
|
||
return matched;
|
||
},
|
||
|
||
sibling: function( n, elem ) {
|
||
var r = [];
|
||
|
||
for ( ; n; n = n.nextSibling ) {
|
||
if ( n.nodeType === 1 && n !== elem ) {
|
||
r.push( n );
|
||
}
|
||
}
|
||
|
||
return r;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
has: function( target ) {
|
||
var i,
|
||
targets = jQuery( target, this ),
|
||
len = targets.length;
|
||
|
||
return this.filter(function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( this, targets[i] ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
closest: function( selectors, context ) {
|
||
var cur,
|
||
i = 0,
|
||
l = this.length,
|
||
matched = [],
|
||
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
|
||
jQuery( selectors, context || this.context ) :
|
||
0;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
|
||
// Always skip document fragments
|
||
if ( cur.nodeType < 11 && (pos ?
|
||
pos.index(cur) > -1 :
|
||
|
||
// Don't pass non-elements to Sizzle
|
||
cur.nodeType === 1 &&
|
||
jQuery.find.matchesSelector(cur, selectors)) ) {
|
||
|
||
matched.push( cur );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
|
||
},
|
||
|
||
// Determine the position of an element within
|
||
// the matched set of elements
|
||
index: function( elem ) {
|
||
|
||
// No argument, return index in parent
|
||
if ( !elem ) {
|
||
return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
|
||
}
|
||
|
||
// index in selector
|
||
if ( typeof elem === "string" ) {
|
||
return jQuery.inArray( this[0], jQuery( elem ) );
|
||
}
|
||
|
||
// Locate the position of the desired element
|
||
return jQuery.inArray(
|
||
// If it receives a jQuery object, the first element is used
|
||
elem.jquery ? elem[0] : elem, this );
|
||
},
|
||
|
||
add: function( selector, context ) {
|
||
return this.pushStack(
|
||
jQuery.unique(
|
||
jQuery.merge( this.get(), jQuery( selector, context ) )
|
||
)
|
||
);
|
||
},
|
||
|
||
addBack: function( selector ) {
|
||
return this.add( selector == null ?
|
||
this.prevObject : this.prevObject.filter(selector)
|
||
);
|
||
}
|
||
});
|
||
|
||
function sibling( cur, dir ) {
|
||
do {
|
||
cur = cur[ dir ];
|
||
} while ( cur && cur.nodeType !== 1 );
|
||
|
||
return cur;
|
||
}
|
||
|
||
jQuery.each({
|
||
parent: function( elem ) {
|
||
var parent = elem.parentNode;
|
||
return parent && parent.nodeType !== 11 ? parent : null;
|
||
},
|
||
parents: function( elem ) {
|
||
return jQuery.dir( elem, "parentNode" );
|
||
},
|
||
parentsUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "parentNode", until );
|
||
},
|
||
next: function( elem ) {
|
||
return sibling( elem, "nextSibling" );
|
||
},
|
||
prev: function( elem ) {
|
||
return sibling( elem, "previousSibling" );
|
||
},
|
||
nextAll: function( elem ) {
|
||
return jQuery.dir( elem, "nextSibling" );
|
||
},
|
||
prevAll: function( elem ) {
|
||
return jQuery.dir( elem, "previousSibling" );
|
||
},
|
||
nextUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "nextSibling", until );
|
||
},
|
||
prevUntil: function( elem, i, until ) {
|
||
return jQuery.dir( elem, "previousSibling", until );
|
||
},
|
||
siblings: function( elem ) {
|
||
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
|
||
},
|
||
children: function( elem ) {
|
||
return jQuery.sibling( elem.firstChild );
|
||
},
|
||
contents: function( elem ) {
|
||
return jQuery.nodeName( elem, "iframe" ) ?
|
||
elem.contentDocument || elem.contentWindow.document :
|
||
jQuery.merge( [], elem.childNodes );
|
||
}
|
||
}, function( name, fn ) {
|
||
jQuery.fn[ name ] = function( until, selector ) {
|
||
var ret = jQuery.map( this, fn, until );
|
||
|
||
if ( name.slice( -5 ) !== "Until" ) {
|
||
selector = until;
|
||
}
|
||
|
||
if ( selector && typeof selector === "string" ) {
|
||
ret = jQuery.filter( selector, ret );
|
||
}
|
||
|
||
if ( this.length > 1 ) {
|
||
// Remove duplicates
|
||
if ( !guaranteedUnique[ name ] ) {
|
||
ret = jQuery.unique( ret );
|
||
}
|
||
|
||
// Reverse order for parents* and prev-derivatives
|
||
if ( rparentsprev.test( name ) ) {
|
||
ret = ret.reverse();
|
||
}
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
});
|
||
var rnotwhite = (/\S+/g);
|
||
|
||
|
||
|
||
// String to Object options format cache
|
||
var optionsCache = {};
|
||
|
||
// Convert String-formatted options into Object-formatted ones and store in cache
|
||
function createOptions( options ) {
|
||
var object = optionsCache[ options ] = {};
|
||
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
|
||
object[ flag ] = true;
|
||
});
|
||
return object;
|
||
}
|
||
|
||
/*
|
||
* Create a callback list using the following parameters:
|
||
*
|
||
* options: an optional list of space-separated options that will change how
|
||
* the callback list behaves or a more traditional option object
|
||
*
|
||
* By default a callback list will act like an event callback list and can be
|
||
* "fired" multiple times.
|
||
*
|
||
* Possible options:
|
||
*
|
||
* once: will ensure the callback list can only be fired once (like a Deferred)
|
||
*
|
||
* memory: will keep track of previous values and will call any callback added
|
||
* after the list has been fired right away with the latest "memorized"
|
||
* values (like a Deferred)
|
||
*
|
||
* unique: will ensure a callback can only be added once (no duplicate in the list)
|
||
*
|
||
* stopOnFalse: interrupt callings when a callback returns false
|
||
*
|
||
*/
|
||
jQuery.Callbacks = function( options ) {
|
||
|
||
// Convert options from String-formatted to Object-formatted if needed
|
||
// (we check in cache first)
|
||
options = typeof options === "string" ?
|
||
( optionsCache[ options ] || createOptions( options ) ) :
|
||
jQuery.extend( {}, options );
|
||
|
||
var // Flag to know if list is currently firing
|
||
firing,
|
||
// Last fire value (for non-forgettable lists)
|
||
memory,
|
||
// Flag to know if list was already fired
|
||
fired,
|
||
// End of the loop when firing
|
||
firingLength,
|
||
// Index of currently firing callback (modified by remove if needed)
|
||
firingIndex,
|
||
// First callback to fire (used internally by add and fireWith)
|
||
firingStart,
|
||
// Actual callback list
|
||
list = [],
|
||
// Stack of fire calls for repeatable lists
|
||
stack = !options.once && [],
|
||
// Fire callbacks
|
||
fire = function( data ) {
|
||
memory = options.memory && data;
|
||
fired = true;
|
||
firingIndex = firingStart || 0;
|
||
firingStart = 0;
|
||
firingLength = list.length;
|
||
firing = true;
|
||
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
|
||
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
|
||
memory = false; // To prevent further calls using add
|
||
break;
|
||
}
|
||
}
|
||
firing = false;
|
||
if ( list ) {
|
||
if ( stack ) {
|
||
if ( stack.length ) {
|
||
fire( stack.shift() );
|
||
}
|
||
} else if ( memory ) {
|
||
list = [];
|
||
} else {
|
||
self.disable();
|
||
}
|
||
}
|
||
},
|
||
// Actual Callbacks object
|
||
self = {
|
||
// Add a callback or a collection of callbacks to the list
|
||
add: function() {
|
||
if ( list ) {
|
||
// First, we save the current length
|
||
var start = list.length;
|
||
(function add( args ) {
|
||
jQuery.each( args, function( _, arg ) {
|
||
var type = jQuery.type( arg );
|
||
if ( type === "function" ) {
|
||
if ( !options.unique || !self.has( arg ) ) {
|
||
list.push( arg );
|
||
}
|
||
} else if ( arg && arg.length && type !== "string" ) {
|
||
// Inspect recursively
|
||
add( arg );
|
||
}
|
||
});
|
||
})( arguments );
|
||
// Do we need to add the callbacks to the
|
||
// current firing batch?
|
||
if ( firing ) {
|
||
firingLength = list.length;
|
||
// With memory, if we're not firing then
|
||
// we should call right away
|
||
} else if ( memory ) {
|
||
firingStart = start;
|
||
fire( memory );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Remove a callback from the list
|
||
remove: function() {
|
||
if ( list ) {
|
||
jQuery.each( arguments, function( _, arg ) {
|
||
var index;
|
||
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
||
list.splice( index, 1 );
|
||
// Handle firing indexes
|
||
if ( firing ) {
|
||
if ( index <= firingLength ) {
|
||
firingLength--;
|
||
}
|
||
if ( index <= firingIndex ) {
|
||
firingIndex--;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return this;
|
||
},
|
||
// Check if a given callback is in the list.
|
||
// If no argument is given, return whether or not list has callbacks attached.
|
||
has: function( fn ) {
|
||
return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
|
||
},
|
||
// Remove all callbacks from the list
|
||
empty: function() {
|
||
list = [];
|
||
firingLength = 0;
|
||
return this;
|
||
},
|
||
// Have the list do nothing anymore
|
||
disable: function() {
|
||
list = stack = memory = undefined;
|
||
return this;
|
||
},
|
||
// Is it disabled?
|
||
disabled: function() {
|
||
return !list;
|
||
},
|
||
// Lock the list in its current state
|
||
lock: function() {
|
||
stack = undefined;
|
||
if ( !memory ) {
|
||
self.disable();
|
||
}
|
||
return this;
|
||
},
|
||
// Is it locked?
|
||
locked: function() {
|
||
return !stack;
|
||
},
|
||
// Call all callbacks with the given context and arguments
|
||
fireWith: function( context, args ) {
|
||
if ( list && ( !fired || stack ) ) {
|
||
args = args || [];
|
||
args = [ context, args.slice ? args.slice() : args ];
|
||
if ( firing ) {
|
||
stack.push( args );
|
||
} else {
|
||
fire( args );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Call all the callbacks with the given arguments
|
||
fire: function() {
|
||
self.fireWith( this, arguments );
|
||
return this;
|
||
},
|
||
// To know if the callbacks have already been called at least once
|
||
fired: function() {
|
||
return !!fired;
|
||
}
|
||
};
|
||
|
||
return self;
|
||
};
|
||
|
||
|
||
jQuery.extend({
|
||
|
||
Deferred: function( func ) {
|
||
var tuples = [
|
||
// action, add listener, listener list, final state
|
||
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
|
||
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
|
||
[ "notify", "progress", jQuery.Callbacks("memory") ]
|
||
],
|
||
state = "pending",
|
||
promise = {
|
||
state: function() {
|
||
return state;
|
||
},
|
||
always: function() {
|
||
deferred.done( arguments ).fail( arguments );
|
||
return this;
|
||
},
|
||
then: function( /* fnDone, fnFail, fnProgress */ ) {
|
||
var fns = arguments;
|
||
return jQuery.Deferred(function( newDefer ) {
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
|
||
// deferred[ done | fail | progress ] for forwarding actions to newDefer
|
||
deferred[ tuple[1] ](function() {
|
||
var returned = fn && fn.apply( this, arguments );
|
||
if ( returned && jQuery.isFunction( returned.promise ) ) {
|
||
returned.promise()
|
||
.done( newDefer.resolve )
|
||
.fail( newDefer.reject )
|
||
.progress( newDefer.notify );
|
||
} else {
|
||
newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
|
||
}
|
||
});
|
||
});
|
||
fns = null;
|
||
}).promise();
|
||
},
|
||
// Get a promise for this deferred
|
||
// If obj is provided, the promise aspect is added to the object
|
||
promise: function( obj ) {
|
||
return obj != null ? jQuery.extend( obj, promise ) : promise;
|
||
}
|
||
},
|
||
deferred = {};
|
||
|
||
// Keep pipe for back-compat
|
||
promise.pipe = promise.then;
|
||
|
||
// Add list-specific methods
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var list = tuple[ 2 ],
|
||
stateString = tuple[ 3 ];
|
||
|
||
// promise[ done | fail | progress ] = list.add
|
||
promise[ tuple[1] ] = list.add;
|
||
|
||
// Handle state
|
||
if ( stateString ) {
|
||
list.add(function() {
|
||
// state = [ resolved | rejected ]
|
||
state = stateString;
|
||
|
||
// [ reject_list | resolve_list ].disable; progress_list.lock
|
||
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
|
||
}
|
||
|
||
// deferred[ resolve | reject | notify ]
|
||
deferred[ tuple[0] ] = function() {
|
||
deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
|
||
return this;
|
||
};
|
||
deferred[ tuple[0] + "With" ] = list.fireWith;
|
||
});
|
||
|
||
// Make the deferred a promise
|
||
promise.promise( deferred );
|
||
|
||
// Call given func if any
|
||
if ( func ) {
|
||
func.call( deferred, deferred );
|
||
}
|
||
|
||
// All done!
|
||
return deferred;
|
||
},
|
||
|
||
// Deferred helper
|
||
when: function( subordinate /* , ..., subordinateN */ ) {
|
||
var i = 0,
|
||
resolveValues = slice.call( arguments ),
|
||
length = resolveValues.length,
|
||
|
||
// the count of uncompleted subordinates
|
||
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
|
||
|
||
// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
|
||
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
|
||
|
||
// Update function for both resolve and progress values
|
||
updateFunc = function( i, contexts, values ) {
|
||
return function( value ) {
|
||
contexts[ i ] = this;
|
||
values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
|
||
if ( values === progressValues ) {
|
||
deferred.notifyWith( contexts, values );
|
||
|
||
} else if ( !(--remaining) ) {
|
||
deferred.resolveWith( contexts, values );
|
||
}
|
||
};
|
||
},
|
||
|
||
progressValues, progressContexts, resolveContexts;
|
||
|
||
// add listeners to Deferred subordinates; treat others as resolved
|
||
if ( length > 1 ) {
|
||
progressValues = new Array( length );
|
||
progressContexts = new Array( length );
|
||
resolveContexts = new Array( length );
|
||
for ( ; i < length; i++ ) {
|
||
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
|
||
resolveValues[ i ].promise()
|
||
.done( updateFunc( i, resolveContexts, resolveValues ) )
|
||
.fail( deferred.reject )
|
||
.progress( updateFunc( i, progressContexts, progressValues ) );
|
||
} else {
|
||
--remaining;
|
||
}
|
||
}
|
||
}
|
||
|
||
// if we're not waiting on anything, resolve the master
|
||
if ( !remaining ) {
|
||
deferred.resolveWith( resolveContexts, resolveValues );
|
||
}
|
||
|
||
return deferred.promise();
|
||
}
|
||
});
|
||
|
||
|
||
// The deferred used on DOM ready
|
||
var readyList;
|
||
|
||
jQuery.fn.ready = function( fn ) {
|
||
// Add the callback
|
||
jQuery.ready.promise().done( fn );
|
||
|
||
return this;
|
||
};
|
||
|
||
jQuery.extend({
|
||
// Is the DOM ready to be used? Set to true once it occurs.
|
||
isReady: false,
|
||
|
||
// A counter to track how many items to wait for before
|
||
// the ready event fires. See #6781
|
||
readyWait: 1,
|
||
|
||
// Hold (or release) the ready event
|
||
holdReady: function( hold ) {
|
||
if ( hold ) {
|
||
jQuery.readyWait++;
|
||
} else {
|
||
jQuery.ready( true );
|
||
}
|
||
},
|
||
|
||
// Handle when the DOM is ready
|
||
ready: function( wait ) {
|
||
|
||
// Abort if there are pending holds or we're already ready
|
||
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
||
if ( !document.body ) {
|
||
return setTimeout( jQuery.ready );
|
||
}
|
||
|
||
// Remember that the DOM is ready
|
||
jQuery.isReady = true;
|
||
|
||
// If a normal DOM Ready event fired, decrement, and wait if need be
|
||
if ( wait !== true && --jQuery.readyWait > 0 ) {
|
||
return;
|
||
}
|
||
|
||
// If there are functions bound, to execute
|
||
readyList.resolveWith( document, [ jQuery ] );
|
||
|
||
// Trigger any bound ready events
|
||
if ( jQuery.fn.triggerHandler ) {
|
||
jQuery( document ).triggerHandler( "ready" );
|
||
jQuery( document ).off( "ready" );
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Clean-up method for dom ready events
|
||
*/
|
||
function detach() {
|
||
if ( document.addEventListener ) {
|
||
document.removeEventListener( "DOMContentLoaded", completed, false );
|
||
window.removeEventListener( "load", completed, false );
|
||
|
||
} else {
|
||
document.detachEvent( "onreadystatechange", completed );
|
||
window.detachEvent( "onload", completed );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The ready event handler and self cleanup method
|
||
*/
|
||
function completed() {
|
||
// readyState === "complete" is good enough for us to call the dom ready in oldIE
|
||
if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
|
||
detach();
|
||
jQuery.ready();
|
||
}
|
||
}
|
||
|
||
jQuery.ready.promise = function( obj ) {
|
||
if ( !readyList ) {
|
||
|
||
readyList = jQuery.Deferred();
|
||
|
||
// Catch cases where $(document).ready() is called after the browser event has already occurred.
|
||
// we once tried to use readyState "interactive" here, but it caused issues like the one
|
||
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
|
||
if ( document.readyState === "complete" ) {
|
||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||
setTimeout( jQuery.ready );
|
||
|
||
// Standards-based browsers support DOMContentLoaded
|
||
} else if ( document.addEventListener ) {
|
||
// Use the handy event callback
|
||
document.addEventListener( "DOMContentLoaded", completed, false );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.addEventListener( "load", completed, false );
|
||
|
||
// If IE event model is used
|
||
} else {
|
||
// Ensure firing before onload, maybe late but safe also for iframes
|
||
document.attachEvent( "onreadystatechange", completed );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.attachEvent( "onload", completed );
|
||
|
||
// If IE and not a frame
|
||
// continually check to see if the document is ready
|
||
var top = false;
|
||
|
||
try {
|
||
top = window.frameElement == null && document.documentElement;
|
||
} catch(e) {}
|
||
|
||
if ( top && top.doScroll ) {
|
||
(function doScrollCheck() {
|
||
if ( !jQuery.isReady ) {
|
||
|
||
try {
|
||
// Use the trick by Diego Perini
|
||
// http://javascript.nwbox.com/IEContentLoaded/
|
||
top.doScroll("left");
|
||
} catch(e) {
|
||
return setTimeout( doScrollCheck, 50 );
|
||
}
|
||
|
||
// detach all dom ready events
|
||
detach();
|
||
|
||
// and execute any waiting functions
|
||
jQuery.ready();
|
||
}
|
||
})();
|
||
}
|
||
}
|
||
}
|
||
return readyList.promise( obj );
|
||
};
|
||
|
||
|
||
var strundefined = typeof undefined;
|
||
|
||
|
||
|
||
// Support: IE<9
|
||
// Iteration over object's inherited properties before its own
|
||
var i;
|
||
for ( i in jQuery( support ) ) {
|
||
break;
|
||
}
|
||
support.ownLast = i !== "0";
|
||
|
||
// Note: most support tests are defined in their respective modules.
|
||
// false until the test is run
|
||
support.inlineBlockNeedsLayout = false;
|
||
|
||
// Execute ASAP in case we need to set body.style.zoom
|
||
jQuery(function() {
|
||
// Minified: var a,b,c,d
|
||
var val, div, body, container;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Return for frameset docs that don't have a body
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
if ( typeof div.style.zoom !== strundefined ) {
|
||
// Support: IE<8
|
||
// Check if natively block-level elements act like inline-block
|
||
// elements when setting their display to 'inline' and giving
|
||
// them layout
|
||
div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
|
||
|
||
support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
|
||
if ( val ) {
|
||
// Prevent IE 6 from affecting layout for positioned elements #11048
|
||
// Prevent IE from shrinking the body in IE 7 mode #12869
|
||
// Support: IE<8
|
||
body.style.zoom = 1;
|
||
}
|
||
}
|
||
|
||
body.removeChild( container );
|
||
});
|
||
|
||
|
||
|
||
|
||
(function() {
|
||
var div = document.createElement( "div" );
|
||
|
||
// Execute the test only if not already executed in another module.
|
||
if (support.deleteExpando == null) {
|
||
// Support: IE<9
|
||
support.deleteExpando = true;
|
||
try {
|
||
delete div.test;
|
||
} catch( e ) {
|
||
support.deleteExpando = false;
|
||
}
|
||
}
|
||
|
||
// Null elements to avoid leaks in IE.
|
||
div = null;
|
||
})();
|
||
|
||
|
||
/**
|
||
* Determines whether an object can have data
|
||
*/
|
||
jQuery.acceptData = function( elem ) {
|
||
var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
|
||
nodeType = +elem.nodeType || 1;
|
||
|
||
// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
|
||
return nodeType !== 1 && nodeType !== 9 ?
|
||
false :
|
||
|
||
// Nodes accept data unless otherwise specified; rejection can be conditional
|
||
!noData || noData !== true && elem.getAttribute("classid") === noData;
|
||
};
|
||
|
||
|
||
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
|
||
rmultiDash = /([A-Z])/g;
|
||
|
||
function dataAttr( elem, key, data ) {
|
||
// If nothing was found internally, try to fetch any
|
||
// data from the HTML5 data-* attribute
|
||
if ( data === undefined && elem.nodeType === 1 ) {
|
||
|
||
var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
|
||
|
||
data = elem.getAttribute( name );
|
||
|
||
if ( typeof data === "string" ) {
|
||
try {
|
||
data = data === "true" ? true :
|
||
data === "false" ? false :
|
||
data === "null" ? null :
|
||
// Only convert to a number if it doesn't change the string
|
||
+data + "" === data ? +data :
|
||
rbrace.test( data ) ? jQuery.parseJSON( data ) :
|
||
data;
|
||
} catch( e ) {}
|
||
|
||
// Make sure we set the data so it isn't changed later
|
||
jQuery.data( elem, key, data );
|
||
|
||
} else {
|
||
data = undefined;
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// checks a cache object for emptiness
|
||
function isEmptyDataObject( obj ) {
|
||
var name;
|
||
for ( name in obj ) {
|
||
|
||
// if the public data object is empty, the private is still empty
|
||
if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
|
||
continue;
|
||
}
|
||
if ( name !== "toJSON" ) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
|
||
if ( !jQuery.acceptData( elem ) ) {
|
||
return;
|
||
}
|
||
|
||
var ret, thisCache,
|
||
internalKey = jQuery.expando,
|
||
|
||
// We have to handle DOM nodes and JS objects differently because IE6-7
|
||
// can't GC object references properly across the DOM-JS boundary
|
||
isNode = elem.nodeType,
|
||
|
||
// Only DOM nodes need the global jQuery cache; JS object data is
|
||
// attached directly to the object so GC can occur automatically
|
||
cache = isNode ? jQuery.cache : elem,
|
||
|
||
// Only defining an ID for JS objects if its cache already exists allows
|
||
// the code to shortcut on the same path as a DOM node with no cache
|
||
id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
|
||
|
||
// Avoid doing any more work than we need to when trying to get data on an
|
||
// object that has no data at all
|
||
if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
|
||
return;
|
||
}
|
||
|
||
if ( !id ) {
|
||
// Only DOM nodes need a new unique ID for each element since their data
|
||
// ends up in the global cache
|
||
if ( isNode ) {
|
||
id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
|
||
} else {
|
||
id = internalKey;
|
||
}
|
||
}
|
||
|
||
if ( !cache[ id ] ) {
|
||
// Avoid exposing jQuery metadata on plain JS objects when the object
|
||
// is serialized using JSON.stringify
|
||
cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
|
||
}
|
||
|
||
// An object can be passed to jQuery.data instead of a key/value pair; this gets
|
||
// shallow copied over onto the existing cache
|
||
if ( typeof name === "object" || typeof name === "function" ) {
|
||
if ( pvt ) {
|
||
cache[ id ] = jQuery.extend( cache[ id ], name );
|
||
} else {
|
||
cache[ id ].data = jQuery.extend( cache[ id ].data, name );
|
||
}
|
||
}
|
||
|
||
thisCache = cache[ id ];
|
||
|
||
// jQuery data() is stored in a separate object inside the object's internal data
|
||
// cache in order to avoid key collisions between internal data and user-defined
|
||
// data.
|
||
if ( !pvt ) {
|
||
if ( !thisCache.data ) {
|
||
thisCache.data = {};
|
||
}
|
||
|
||
thisCache = thisCache.data;
|
||
}
|
||
|
||
if ( data !== undefined ) {
|
||
thisCache[ jQuery.camelCase( name ) ] = data;
|
||
}
|
||
|
||
// Check for both converted-to-camel and non-converted data property names
|
||
// If a data property was specified
|
||
if ( typeof name === "string" ) {
|
||
|
||
// First Try to find as-is property data
|
||
ret = thisCache[ name ];
|
||
|
||
// Test for null|undefined property data
|
||
if ( ret == null ) {
|
||
|
||
// Try to find the camelCased property
|
||
ret = thisCache[ jQuery.camelCase( name ) ];
|
||
}
|
||
} else {
|
||
ret = thisCache;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
function internalRemoveData( elem, name, pvt ) {
|
||
if ( !jQuery.acceptData( elem ) ) {
|
||
return;
|
||
}
|
||
|
||
var thisCache, i,
|
||
isNode = elem.nodeType,
|
||
|
||
// See jQuery.data for more information
|
||
cache = isNode ? jQuery.cache : elem,
|
||
id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
|
||
|
||
// If there is already no cache entry for this object, there is no
|
||
// purpose in continuing
|
||
if ( !cache[ id ] ) {
|
||
return;
|
||
}
|
||
|
||
if ( name ) {
|
||
|
||
thisCache = pvt ? cache[ id ] : cache[ id ].data;
|
||
|
||
if ( thisCache ) {
|
||
|
||
// Support array or space separated string names for data keys
|
||
if ( !jQuery.isArray( name ) ) {
|
||
|
||
// try the string as a key before any manipulation
|
||
if ( name in thisCache ) {
|
||
name = [ name ];
|
||
} else {
|
||
|
||
// split the camel cased version by spaces unless a key with the spaces exists
|
||
name = jQuery.camelCase( name );
|
||
if ( name in thisCache ) {
|
||
name = [ name ];
|
||
} else {
|
||
name = name.split(" ");
|
||
}
|
||
}
|
||
} else {
|
||
// If "name" is an array of keys...
|
||
// When data is initially created, via ("key", "val") signature,
|
||
// keys will be converted to camelCase.
|
||
// Since there is no way to tell _how_ a key was added, remove
|
||
// both plain key and camelCase key. #12786
|
||
// This will only penalize the array argument path.
|
||
name = name.concat( jQuery.map( name, jQuery.camelCase ) );
|
||
}
|
||
|
||
i = name.length;
|
||
while ( i-- ) {
|
||
delete thisCache[ name[i] ];
|
||
}
|
||
|
||
// If there is no data left in the cache, we want to continue
|
||
// and let the cache object itself get destroyed
|
||
if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// See jQuery.data for more information
|
||
if ( !pvt ) {
|
||
delete cache[ id ].data;
|
||
|
||
// Don't destroy the parent cache unless the internal data object
|
||
// had been the only thing left in it
|
||
if ( !isEmptyDataObject( cache[ id ] ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Destroy the cache
|
||
if ( isNode ) {
|
||
jQuery.cleanData( [ elem ], true );
|
||
|
||
// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
|
||
/* jshint eqeqeq: false */
|
||
} else if ( support.deleteExpando || cache != cache.window ) {
|
||
/* jshint eqeqeq: true */
|
||
delete cache[ id ];
|
||
|
||
// When all else fails, null
|
||
} else {
|
||
cache[ id ] = null;
|
||
}
|
||
}
|
||
|
||
jQuery.extend({
|
||
cache: {},
|
||
|
||
// The following elements (space-suffixed to avoid Object.prototype collisions)
|
||
// throw uncatchable exceptions if you attempt to set expando properties
|
||
noData: {
|
||
"applet ": true,
|
||
"embed ": true,
|
||
// ...but Flash objects (which have this classid) *can* handle expandos
|
||
"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
|
||
},
|
||
|
||
hasData: function( elem ) {
|
||
elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
|
||
return !!elem && !isEmptyDataObject( elem );
|
||
},
|
||
|
||
data: function( elem, name, data ) {
|
||
return internalData( elem, name, data );
|
||
},
|
||
|
||
removeData: function( elem, name ) {
|
||
return internalRemoveData( elem, name );
|
||
},
|
||
|
||
// For internal use only.
|
||
_data: function( elem, name, data ) {
|
||
return internalData( elem, name, data, true );
|
||
},
|
||
|
||
_removeData: function( elem, name ) {
|
||
return internalRemoveData( elem, name, true );
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
data: function( key, value ) {
|
||
var i, name, data,
|
||
elem = this[0],
|
||
attrs = elem && elem.attributes;
|
||
|
||
// Special expections of .data basically thwart jQuery.access,
|
||
// so implement the relevant behavior ourselves
|
||
|
||
// Gets all values
|
||
if ( key === undefined ) {
|
||
if ( this.length ) {
|
||
data = jQuery.data( elem );
|
||
|
||
if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
|
||
i = attrs.length;
|
||
while ( i-- ) {
|
||
|
||
// Support: IE11+
|
||
// The attrs elements can be null (#14894)
|
||
if ( attrs[ i ] ) {
|
||
name = attrs[ i ].name;
|
||
if ( name.indexOf( "data-" ) === 0 ) {
|
||
name = jQuery.camelCase( name.slice(5) );
|
||
dataAttr( elem, name, data[ name ] );
|
||
}
|
||
}
|
||
}
|
||
jQuery._data( elem, "parsedAttrs", true );
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// Sets multiple values
|
||
if ( typeof key === "object" ) {
|
||
return this.each(function() {
|
||
jQuery.data( this, key );
|
||
});
|
||
}
|
||
|
||
return arguments.length > 1 ?
|
||
|
||
// Sets one value
|
||
this.each(function() {
|
||
jQuery.data( this, key, value );
|
||
}) :
|
||
|
||
// Gets one value
|
||
// Try to fetch any internally stored data first
|
||
elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
|
||
},
|
||
|
||
removeData: function( key ) {
|
||
return this.each(function() {
|
||
jQuery.removeData( this, key );
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.extend({
|
||
queue: function( elem, type, data ) {
|
||
var queue;
|
||
|
||
if ( elem ) {
|
||
type = ( type || "fx" ) + "queue";
|
||
queue = jQuery._data( elem, type );
|
||
|
||
// Speed up dequeue by getting out quickly if this is just a lookup
|
||
if ( data ) {
|
||
if ( !queue || jQuery.isArray(data) ) {
|
||
queue = jQuery._data( elem, type, jQuery.makeArray(data) );
|
||
} else {
|
||
queue.push( data );
|
||
}
|
||
}
|
||
return queue || [];
|
||
}
|
||
},
|
||
|
||
dequeue: function( elem, type ) {
|
||
type = type || "fx";
|
||
|
||
var queue = jQuery.queue( elem, type ),
|
||
startLength = queue.length,
|
||
fn = queue.shift(),
|
||
hooks = jQuery._queueHooks( elem, type ),
|
||
next = function() {
|
||
jQuery.dequeue( elem, type );
|
||
};
|
||
|
||
// If the fx queue is dequeued, always remove the progress sentinel
|
||
if ( fn === "inprogress" ) {
|
||
fn = queue.shift();
|
||
startLength--;
|
||
}
|
||
|
||
if ( fn ) {
|
||
|
||
// Add a progress sentinel to prevent the fx queue from being
|
||
// automatically dequeued
|
||
if ( type === "fx" ) {
|
||
queue.unshift( "inprogress" );
|
||
}
|
||
|
||
// clear up the last queue stop function
|
||
delete hooks.stop;
|
||
fn.call( elem, next, hooks );
|
||
}
|
||
|
||
if ( !startLength && hooks ) {
|
||
hooks.empty.fire();
|
||
}
|
||
},
|
||
|
||
// not intended for public consumption - generates a queueHooks object, or returns the current one
|
||
_queueHooks: function( elem, type ) {
|
||
var key = type + "queueHooks";
|
||
return jQuery._data( elem, key ) || jQuery._data( elem, key, {
|
||
empty: jQuery.Callbacks("once memory").add(function() {
|
||
jQuery._removeData( elem, type + "queue" );
|
||
jQuery._removeData( elem, key );
|
||
})
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
queue: function( type, data ) {
|
||
var setter = 2;
|
||
|
||
if ( typeof type !== "string" ) {
|
||
data = type;
|
||
type = "fx";
|
||
setter--;
|
||
}
|
||
|
||
if ( arguments.length < setter ) {
|
||
return jQuery.queue( this[0], type );
|
||
}
|
||
|
||
return data === undefined ?
|
||
this :
|
||
this.each(function() {
|
||
var queue = jQuery.queue( this, type, data );
|
||
|
||
// ensure a hooks for this queue
|
||
jQuery._queueHooks( this, type );
|
||
|
||
if ( type === "fx" && queue[0] !== "inprogress" ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
dequeue: function( type ) {
|
||
return this.each(function() {
|
||
jQuery.dequeue( this, type );
|
||
});
|
||
},
|
||
clearQueue: function( type ) {
|
||
return this.queue( type || "fx", [] );
|
||
},
|
||
// Get a promise resolved when queues of a certain type
|
||
// are emptied (fx is the type by default)
|
||
promise: function( type, obj ) {
|
||
var tmp,
|
||
count = 1,
|
||
defer = jQuery.Deferred(),
|
||
elements = this,
|
||
i = this.length,
|
||
resolve = function() {
|
||
if ( !( --count ) ) {
|
||
defer.resolveWith( elements, [ elements ] );
|
||
}
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
obj = type;
|
||
type = undefined;
|
||
}
|
||
type = type || "fx";
|
||
|
||
while ( i-- ) {
|
||
tmp = jQuery._data( elements[ i ], type + "queueHooks" );
|
||
if ( tmp && tmp.empty ) {
|
||
count++;
|
||
tmp.empty.add( resolve );
|
||
}
|
||
}
|
||
resolve();
|
||
return defer.promise( obj );
|
||
}
|
||
});
|
||
var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
|
||
|
||
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
|
||
|
||
var isHidden = function( elem, el ) {
|
||
// isHidden might be called from jQuery#filter function;
|
||
// in that case, element will be second argument
|
||
elem = el || elem;
|
||
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
|
||
};
|
||
|
||
|
||
|
||
// Multifunctional method to get and set values of a collection
|
||
// The value/s can optionally be executed if it's a function
|
||
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
|
||
var i = 0,
|
||
length = elems.length,
|
||
bulk = key == null;
|
||
|
||
// Sets many values
|
||
if ( jQuery.type( key ) === "object" ) {
|
||
chainable = true;
|
||
for ( i in key ) {
|
||
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
|
||
}
|
||
|
||
// Sets one value
|
||
} else if ( value !== undefined ) {
|
||
chainable = true;
|
||
|
||
if ( !jQuery.isFunction( value ) ) {
|
||
raw = true;
|
||
}
|
||
|
||
if ( bulk ) {
|
||
// Bulk operations run against the entire set
|
||
if ( raw ) {
|
||
fn.call( elems, value );
|
||
fn = null;
|
||
|
||
// ...except when executing function values
|
||
} else {
|
||
bulk = fn;
|
||
fn = function( elem, key, value ) {
|
||
return bulk.call( jQuery( elem ), value );
|
||
};
|
||
}
|
||
}
|
||
|
||
if ( fn ) {
|
||
for ( ; i < length; i++ ) {
|
||
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
return chainable ?
|
||
elems :
|
||
|
||
// Gets
|
||
bulk ?
|
||
fn.call( elems ) :
|
||
length ? fn( elems[0], key ) : emptyGet;
|
||
};
|
||
var rcheckableType = (/^(?:checkbox|radio)$/i);
|
||
|
||
|
||
|
||
(function() {
|
||
// Minified: var a,b,c
|
||
var input = document.createElement( "input" ),
|
||
div = document.createElement( "div" ),
|
||
fragment = document.createDocumentFragment();
|
||
|
||
// Setup
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
|
||
// IE strips leading whitespace when .innerHTML is used
|
||
support.leadingWhitespace = div.firstChild.nodeType === 3;
|
||
|
||
// Make sure that tbody elements aren't automatically inserted
|
||
// IE will insert them into empty tables
|
||
support.tbody = !div.getElementsByTagName( "tbody" ).length;
|
||
|
||
// Make sure that link elements get serialized correctly by innerHTML
|
||
// This requires a wrapper element in IE
|
||
support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
|
||
|
||
// Makes sure cloning an html5 element does not cause problems
|
||
// Where outerHTML is undefined, this still works
|
||
support.html5Clone =
|
||
document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
|
||
|
||
// Check if a disconnected checkbox will retain its checked
|
||
// value of true after appended to the DOM (IE6/7)
|
||
input.type = "checkbox";
|
||
input.checked = true;
|
||
fragment.appendChild( input );
|
||
support.appendChecked = input.checked;
|
||
|
||
// Make sure textarea (and checkbox) defaultValue is properly cloned
|
||
// Support: IE6-IE11+
|
||
div.innerHTML = "<textarea>x</textarea>";
|
||
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
|
||
|
||
// #11217 - WebKit loses check when the name is after the checked attribute
|
||
fragment.appendChild( div );
|
||
div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
|
||
|
||
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
|
||
// old WebKit doesn't clone checked state correctly in fragments
|
||
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
||
|
||
// Support: IE<9
|
||
// Opera does not clone events (and typeof div.attachEvent === undefined).
|
||
// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
|
||
support.noCloneEvent = true;
|
||
if ( div.attachEvent ) {
|
||
div.attachEvent( "onclick", function() {
|
||
support.noCloneEvent = false;
|
||
});
|
||
|
||
div.cloneNode( true ).click();
|
||
}
|
||
|
||
// Execute the test only if not already executed in another module.
|
||
if (support.deleteExpando == null) {
|
||
// Support: IE<9
|
||
support.deleteExpando = true;
|
||
try {
|
||
delete div.test;
|
||
} catch( e ) {
|
||
support.deleteExpando = false;
|
||
}
|
||
}
|
||
})();
|
||
|
||
|
||
(function() {
|
||
var i, eventName,
|
||
div = document.createElement( "div" );
|
||
|
||
// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
|
||
for ( i in { submit: true, change: true, focusin: true }) {
|
||
eventName = "on" + i;
|
||
|
||
if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
|
||
// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
|
||
div.setAttribute( eventName, "t" );
|
||
support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
|
||
}
|
||
}
|
||
|
||
// Null elements to avoid leaks in IE.
|
||
div = null;
|
||
})();
|
||
|
||
|
||
var rformElems = /^(?:input|select|textarea)$/i,
|
||
rkeyEvent = /^key/,
|
||
rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
|
||
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
|
||
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
|
||
|
||
function returnTrue() {
|
||
return true;
|
||
}
|
||
|
||
function returnFalse() {
|
||
return false;
|
||
}
|
||
|
||
function safeActiveElement() {
|
||
try {
|
||
return document.activeElement;
|
||
} catch ( err ) { }
|
||
}
|
||
|
||
/*
|
||
* Helper functions for managing events -- not part of the public interface.
|
||
* Props to Dean Edwards' addEvent library for many of the ideas.
|
||
*/
|
||
jQuery.event = {
|
||
|
||
global: {},
|
||
|
||
add: function( elem, types, handler, data, selector ) {
|
||
var tmp, events, t, handleObjIn,
|
||
special, eventHandle, handleObj,
|
||
handlers, type, namespaces, origType,
|
||
elemData = jQuery._data( elem );
|
||
|
||
// Don't attach events to noData or text/comment nodes (but allow plain objects)
|
||
if ( !elemData ) {
|
||
return;
|
||
}
|
||
|
||
// Caller can pass in an object of custom data in lieu of the handler
|
||
if ( handler.handler ) {
|
||
handleObjIn = handler;
|
||
handler = handleObjIn.handler;
|
||
selector = handleObjIn.selector;
|
||
}
|
||
|
||
// Make sure that the handler has a unique ID, used to find/remove it later
|
||
if ( !handler.guid ) {
|
||
handler.guid = jQuery.guid++;
|
||
}
|
||
|
||
// Init the element's event structure and main handler, if this is the first
|
||
if ( !(events = elemData.events) ) {
|
||
events = elemData.events = {};
|
||
}
|
||
if ( !(eventHandle = elemData.handle) ) {
|
||
eventHandle = elemData.handle = function( e ) {
|
||
// Discard the second event of a jQuery.event.trigger() and
|
||
// when an event is called after a page has unloaded
|
||
return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
|
||
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
|
||
undefined;
|
||
};
|
||
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
|
||
eventHandle.elem = elem;
|
||
}
|
||
|
||
// Handle multiple events separated by a space
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// There *must* be a type, no attaching namespace-only handlers
|
||
if ( !type ) {
|
||
continue;
|
||
}
|
||
|
||
// If event changes its type, use the special event handlers for the changed type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// If selector defined, determine special event api type, otherwise given type
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
|
||
// Update special based on newly reset type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// handleObj is passed to all event handlers
|
||
handleObj = jQuery.extend({
|
||
type: type,
|
||
origType: origType,
|
||
data: data,
|
||
handler: handler,
|
||
guid: handler.guid,
|
||
selector: selector,
|
||
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
||
namespace: namespaces.join(".")
|
||
}, handleObjIn );
|
||
|
||
// Init the event handler queue if we're the first
|
||
if ( !(handlers = events[ type ]) ) {
|
||
handlers = events[ type ] = [];
|
||
handlers.delegateCount = 0;
|
||
|
||
// Only use addEventListener/attachEvent if the special events handler returns false
|
||
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
|
||
// Bind the global event handler to the element
|
||
if ( elem.addEventListener ) {
|
||
elem.addEventListener( type, eventHandle, false );
|
||
|
||
} else if ( elem.attachEvent ) {
|
||
elem.attachEvent( "on" + type, eventHandle );
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( special.add ) {
|
||
special.add.call( elem, handleObj );
|
||
|
||
if ( !handleObj.handler.guid ) {
|
||
handleObj.handler.guid = handler.guid;
|
||
}
|
||
}
|
||
|
||
// Add to the element's handler list, delegates in front
|
||
if ( selector ) {
|
||
handlers.splice( handlers.delegateCount++, 0, handleObj );
|
||
} else {
|
||
handlers.push( handleObj );
|
||
}
|
||
|
||
// Keep track of which events have ever been used, for event optimization
|
||
jQuery.event.global[ type ] = true;
|
||
}
|
||
|
||
// Nullify elem to prevent memory leaks in IE
|
||
elem = null;
|
||
},
|
||
|
||
// Detach an event or set of events from an element
|
||
remove: function( elem, types, handler, selector, mappedTypes ) {
|
||
var j, handleObj, tmp,
|
||
origCount, t, events,
|
||
special, handlers, type,
|
||
namespaces, origType,
|
||
elemData = jQuery.hasData( elem ) && jQuery._data( elem );
|
||
|
||
if ( !elemData || !(events = elemData.events) ) {
|
||
return;
|
||
}
|
||
|
||
// Once for each type.namespace in types; type may be omitted
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// Unbind all events (on this namespace, if provided) for the element
|
||
if ( !type ) {
|
||
for ( type in events ) {
|
||
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
special = jQuery.event.special[ type ] || {};
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
handlers = events[ type ] || [];
|
||
tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
|
||
|
||
// Remove matching events
|
||
origCount = j = handlers.length;
|
||
while ( j-- ) {
|
||
handleObj = handlers[ j ];
|
||
|
||
if ( ( mappedTypes || origType === handleObj.origType ) &&
|
||
( !handler || handler.guid === handleObj.guid ) &&
|
||
( !tmp || tmp.test( handleObj.namespace ) ) &&
|
||
( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
|
||
handlers.splice( j, 1 );
|
||
|
||
if ( handleObj.selector ) {
|
||
handlers.delegateCount--;
|
||
}
|
||
if ( special.remove ) {
|
||
special.remove.call( elem, handleObj );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove generic event handler if we removed something and no more handlers exist
|
||
// (avoids potential for endless recursion during removal of special event handlers)
|
||
if ( origCount && !handlers.length ) {
|
||
if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
||
jQuery.removeEvent( elem, type, elemData.handle );
|
||
}
|
||
|
||
delete events[ type ];
|
||
}
|
||
}
|
||
|
||
// Remove the expando if it's no longer used
|
||
if ( jQuery.isEmptyObject( events ) ) {
|
||
delete elemData.handle;
|
||
|
||
// removeData also checks for emptiness and clears the expando if empty
|
||
// so use it instead of delete
|
||
jQuery._removeData( elem, "events" );
|
||
}
|
||
},
|
||
|
||
trigger: function( event, data, elem, onlyHandlers ) {
|
||
var handle, ontype, cur,
|
||
bubbleType, special, tmp, i,
|
||
eventPath = [ elem || document ],
|
||
type = hasOwn.call( event, "type" ) ? event.type : event,
|
||
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
|
||
|
||
cur = tmp = elem = elem || document;
|
||
|
||
// Don't do events on text and comment nodes
|
||
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
||
return;
|
||
}
|
||
|
||
// focus/blur morphs to focusin/out; ensure we're not firing them right now
|
||
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( type.indexOf(".") >= 0 ) {
|
||
// Namespaced trigger; create a regexp to match event type in handle()
|
||
namespaces = type.split(".");
|
||
type = namespaces.shift();
|
||
namespaces.sort();
|
||
}
|
||
ontype = type.indexOf(":") < 0 && "on" + type;
|
||
|
||
// Caller can pass in a jQuery.Event object, Object, or just an event type string
|
||
event = event[ jQuery.expando ] ?
|
||
event :
|
||
new jQuery.Event( type, typeof event === "object" && event );
|
||
|
||
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
|
||
event.isTrigger = onlyHandlers ? 2 : 3;
|
||
event.namespace = namespaces.join(".");
|
||
event.namespace_re = event.namespace ?
|
||
new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
|
||
null;
|
||
|
||
// Clean up the event in case it is being reused
|
||
event.result = undefined;
|
||
if ( !event.target ) {
|
||
event.target = elem;
|
||
}
|
||
|
||
// Clone any incoming data and prepend the event, creating the handler arg list
|
||
data = data == null ?
|
||
[ event ] :
|
||
jQuery.makeArray( data, [ event ] );
|
||
|
||
// Allow special events to draw outside the lines
|
||
special = jQuery.event.special[ type ] || {};
|
||
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine event propagation path in advance, per W3C events spec (#9951)
|
||
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
||
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
|
||
|
||
bubbleType = special.delegateType || type;
|
||
if ( !rfocusMorph.test( bubbleType + type ) ) {
|
||
cur = cur.parentNode;
|
||
}
|
||
for ( ; cur; cur = cur.parentNode ) {
|
||
eventPath.push( cur );
|
||
tmp = cur;
|
||
}
|
||
|
||
// Only add window if we got to document (e.g., not plain obj or detached DOM)
|
||
if ( tmp === (elem.ownerDocument || document) ) {
|
||
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
|
||
}
|
||
}
|
||
|
||
// Fire handlers on the event path
|
||
i = 0;
|
||
while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
|
||
|
||
event.type = i > 1 ?
|
||
bubbleType :
|
||
special.bindType || type;
|
||
|
||
// jQuery handler
|
||
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
|
||
if ( handle ) {
|
||
handle.apply( cur, data );
|
||
}
|
||
|
||
// Native handler
|
||
handle = ontype && cur[ ontype ];
|
||
if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
|
||
event.result = handle.apply( cur, data );
|
||
if ( event.result === false ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
}
|
||
event.type = type;
|
||
|
||
// If nobody prevented the default action, do it now
|
||
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
|
||
|
||
if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
|
||
jQuery.acceptData( elem ) ) {
|
||
|
||
// Call a native DOM method on the target with the same name name as the event.
|
||
// Can't use an .isFunction() check here because IE6/7 fails that test.
|
||
// Don't do default actions on window, that's where global variables be (#6170)
|
||
if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
|
||
|
||
// Don't re-trigger an onFOO event when we call its FOO() method
|
||
tmp = elem[ ontype ];
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = null;
|
||
}
|
||
|
||
// Prevent re-triggering of the same event, since we already bubbled it above
|
||
jQuery.event.triggered = type;
|
||
try {
|
||
elem[ type ]();
|
||
} catch ( e ) {
|
||
// IE<9 dies on focus/blur to hidden element (#1486,#12518)
|
||
// only reproducible on winXP IE8 native, not IE9 in IE8 mode
|
||
}
|
||
jQuery.event.triggered = undefined;
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = tmp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
dispatch: function( event ) {
|
||
|
||
// Make a writable jQuery.Event from the native event object
|
||
event = jQuery.event.fix( event );
|
||
|
||
var i, ret, handleObj, matched, j,
|
||
handlerQueue = [],
|
||
args = slice.call( arguments ),
|
||
handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
|
||
special = jQuery.event.special[ event.type ] || {};
|
||
|
||
// Use the fix-ed jQuery.Event rather than the (read-only) native event
|
||
args[0] = event;
|
||
event.delegateTarget = this;
|
||
|
||
// Call the preDispatch hook for the mapped type, and let it bail if desired
|
||
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine handlers
|
||
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
||
|
||
// Run delegates first; they may want to stop propagation beneath us
|
||
i = 0;
|
||
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
|
||
event.currentTarget = matched.elem;
|
||
|
||
j = 0;
|
||
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
|
||
|
||
// Triggered event must either 1) have no namespace, or
|
||
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
|
||
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
|
||
|
||
event.handleObj = handleObj;
|
||
event.data = handleObj.data;
|
||
|
||
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
|
||
.apply( matched.elem, args );
|
||
|
||
if ( ret !== undefined ) {
|
||
if ( (event.result = ret) === false ) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call the postDispatch hook for the mapped type
|
||
if ( special.postDispatch ) {
|
||
special.postDispatch.call( this, event );
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
handlers: function( event, handlers ) {
|
||
var sel, handleObj, matches, i,
|
||
handlerQueue = [],
|
||
delegateCount = handlers.delegateCount,
|
||
cur = event.target;
|
||
|
||
// Find delegate handlers
|
||
// Black-hole SVG <use> instance trees (#13180)
|
||
// Avoid non-left-click bubbling in Firefox (#3861)
|
||
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
|
||
|
||
/* jshint eqeqeq: false */
|
||
for ( ; cur != this; cur = cur.parentNode || this ) {
|
||
/* jshint eqeqeq: true */
|
||
|
||
// Don't check non-elements (#13208)
|
||
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
||
if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
|
||
matches = [];
|
||
for ( i = 0; i < delegateCount; i++ ) {
|
||
handleObj = handlers[ i ];
|
||
|
||
// Don't conflict with Object.prototype properties (#13203)
|
||
sel = handleObj.selector + " ";
|
||
|
||
if ( matches[ sel ] === undefined ) {
|
||
matches[ sel ] = handleObj.needsContext ?
|
||
jQuery( sel, this ).index( cur ) >= 0 :
|
||
jQuery.find( sel, this, null, [ cur ] ).length;
|
||
}
|
||
if ( matches[ sel ] ) {
|
||
matches.push( handleObj );
|
||
}
|
||
}
|
||
if ( matches.length ) {
|
||
handlerQueue.push({ elem: cur, handlers: matches });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the remaining (directly-bound) handlers
|
||
if ( delegateCount < handlers.length ) {
|
||
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
|
||
}
|
||
|
||
return handlerQueue;
|
||
},
|
||
|
||
fix: function( event ) {
|
||
if ( event[ jQuery.expando ] ) {
|
||
return event;
|
||
}
|
||
|
||
// Create a writable copy of the event object and normalize some properties
|
||
var i, prop, copy,
|
||
type = event.type,
|
||
originalEvent = event,
|
||
fixHook = this.fixHooks[ type ];
|
||
|
||
if ( !fixHook ) {
|
||
this.fixHooks[ type ] = fixHook =
|
||
rmouseEvent.test( type ) ? this.mouseHooks :
|
||
rkeyEvent.test( type ) ? this.keyHooks :
|
||
{};
|
||
}
|
||
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
|
||
|
||
event = new jQuery.Event( originalEvent );
|
||
|
||
i = copy.length;
|
||
while ( i-- ) {
|
||
prop = copy[ i ];
|
||
event[ prop ] = originalEvent[ prop ];
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Fix target property (#1925)
|
||
if ( !event.target ) {
|
||
event.target = originalEvent.srcElement || document;
|
||
}
|
||
|
||
// Support: Chrome 23+, Safari?
|
||
// Target should not be a text node (#504, #13143)
|
||
if ( event.target.nodeType === 3 ) {
|
||
event.target = event.target.parentNode;
|
||
}
|
||
|
||
// Support: IE<9
|
||
// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
|
||
event.metaKey = !!event.metaKey;
|
||
|
||
return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
|
||
},
|
||
|
||
// Includes some event props shared by KeyEvent and MouseEvent
|
||
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
|
||
|
||
fixHooks: {},
|
||
|
||
keyHooks: {
|
||
props: "char charCode key keyCode".split(" "),
|
||
filter: function( event, original ) {
|
||
|
||
// Add which for key events
|
||
if ( event.which == null ) {
|
||
event.which = original.charCode != null ? original.charCode : original.keyCode;
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
mouseHooks: {
|
||
props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
|
||
filter: function( event, original ) {
|
||
var body, eventDoc, doc,
|
||
button = original.button,
|
||
fromElement = original.fromElement;
|
||
|
||
// Calculate pageX/Y if missing and clientX/Y available
|
||
if ( event.pageX == null && original.clientX != null ) {
|
||
eventDoc = event.target.ownerDocument || document;
|
||
doc = eventDoc.documentElement;
|
||
body = eventDoc.body;
|
||
|
||
event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
|
||
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
|
||
}
|
||
|
||
// Add relatedTarget, if necessary
|
||
if ( !event.relatedTarget && fromElement ) {
|
||
event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
|
||
}
|
||
|
||
// Add which for click: 1 === left; 2 === middle; 3 === right
|
||
// Note: button is not normalized, so don't use it
|
||
if ( !event.which && button !== undefined ) {
|
||
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
special: {
|
||
load: {
|
||
// Prevent triggered image.load events from bubbling to window.load
|
||
noBubble: true
|
||
},
|
||
focus: {
|
||
// Fire native event if possible so blur/focus sequence is correct
|
||
trigger: function() {
|
||
if ( this !== safeActiveElement() && this.focus ) {
|
||
try {
|
||
this.focus();
|
||
return false;
|
||
} catch ( e ) {
|
||
// Support: IE<9
|
||
// If we error on focus to hidden element (#1486, #12518),
|
||
// let .trigger() run the handlers
|
||
}
|
||
}
|
||
},
|
||
delegateType: "focusin"
|
||
},
|
||
blur: {
|
||
trigger: function() {
|
||
if ( this === safeActiveElement() && this.blur ) {
|
||
this.blur();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusout"
|
||
},
|
||
click: {
|
||
// For checkbox, fire native event so checked state will be right
|
||
trigger: function() {
|
||
if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
|
||
this.click();
|
||
return false;
|
||
}
|
||
},
|
||
|
||
// For cross-browser consistency, don't fire native .click() on links
|
||
_default: function( event ) {
|
||
return jQuery.nodeName( event.target, "a" );
|
||
}
|
||
},
|
||
|
||
beforeunload: {
|
||
postDispatch: function( event ) {
|
||
|
||
// Support: Firefox 20+
|
||
// Firefox doesn't alert if the returnValue field is not set.
|
||
if ( event.result !== undefined && event.originalEvent ) {
|
||
event.originalEvent.returnValue = event.result;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
simulate: function( type, elem, event, bubble ) {
|
||
// Piggyback on a donor event to simulate a different one.
|
||
// Fake originalEvent to avoid donor's stopPropagation, but if the
|
||
// simulated event prevents default then we do the same on the donor.
|
||
var e = jQuery.extend(
|
||
new jQuery.Event(),
|
||
event,
|
||
{
|
||
type: type,
|
||
isSimulated: true,
|
||
originalEvent: {}
|
||
}
|
||
);
|
||
if ( bubble ) {
|
||
jQuery.event.trigger( e, null, elem );
|
||
} else {
|
||
jQuery.event.dispatch.call( elem, e );
|
||
}
|
||
if ( e.isDefaultPrevented() ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.removeEvent = document.removeEventListener ?
|
||
function( elem, type, handle ) {
|
||
if ( elem.removeEventListener ) {
|
||
elem.removeEventListener( type, handle, false );
|
||
}
|
||
} :
|
||
function( elem, type, handle ) {
|
||
var name = "on" + type;
|
||
|
||
if ( elem.detachEvent ) {
|
||
|
||
// #8545, #7054, preventing memory leaks for custom events in IE6-8
|
||
// detachEvent needed property on element, by name of that event, to properly expose it to GC
|
||
if ( typeof elem[ name ] === strundefined ) {
|
||
elem[ name ] = null;
|
||
}
|
||
|
||
elem.detachEvent( name, handle );
|
||
}
|
||
};
|
||
|
||
jQuery.Event = function( src, props ) {
|
||
// Allow instantiation without the 'new' keyword
|
||
if ( !(this instanceof jQuery.Event) ) {
|
||
return new jQuery.Event( src, props );
|
||
}
|
||
|
||
// Event object
|
||
if ( src && src.type ) {
|
||
this.originalEvent = src;
|
||
this.type = src.type;
|
||
|
||
// Events bubbling up the document may have been marked as prevented
|
||
// by a handler lower down the tree; reflect the correct value.
|
||
this.isDefaultPrevented = src.defaultPrevented ||
|
||
src.defaultPrevented === undefined &&
|
||
// Support: IE < 9, Android < 4.0
|
||
src.returnValue === false ?
|
||
returnTrue :
|
||
returnFalse;
|
||
|
||
// Event type
|
||
} else {
|
||
this.type = src;
|
||
}
|
||
|
||
// Put explicitly provided properties onto the event object
|
||
if ( props ) {
|
||
jQuery.extend( this, props );
|
||
}
|
||
|
||
// Create a timestamp if incoming event doesn't have one
|
||
this.timeStamp = src && src.timeStamp || jQuery.now();
|
||
|
||
// Mark it as fixed
|
||
this[ jQuery.expando ] = true;
|
||
};
|
||
|
||
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
|
||
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
|
||
jQuery.Event.prototype = {
|
||
isDefaultPrevented: returnFalse,
|
||
isPropagationStopped: returnFalse,
|
||
isImmediatePropagationStopped: returnFalse,
|
||
|
||
preventDefault: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isDefaultPrevented = returnTrue;
|
||
if ( !e ) {
|
||
return;
|
||
}
|
||
|
||
// If preventDefault exists, run it on the original event
|
||
if ( e.preventDefault ) {
|
||
e.preventDefault();
|
||
|
||
// Support: IE
|
||
// Otherwise set the returnValue property of the original event to false
|
||
} else {
|
||
e.returnValue = false;
|
||
}
|
||
},
|
||
stopPropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isPropagationStopped = returnTrue;
|
||
if ( !e ) {
|
||
return;
|
||
}
|
||
// If stopPropagation exists, run it on the original event
|
||
if ( e.stopPropagation ) {
|
||
e.stopPropagation();
|
||
}
|
||
|
||
// Support: IE
|
||
// Set the cancelBubble property of the original event to true
|
||
e.cancelBubble = true;
|
||
},
|
||
stopImmediatePropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isImmediatePropagationStopped = returnTrue;
|
||
|
||
if ( e && e.stopImmediatePropagation ) {
|
||
e.stopImmediatePropagation();
|
||
}
|
||
|
||
this.stopPropagation();
|
||
}
|
||
};
|
||
|
||
// Create mouseenter/leave events using mouseover/out and event-time checks
|
||
jQuery.each({
|
||
mouseenter: "mouseover",
|
||
mouseleave: "mouseout",
|
||
pointerenter: "pointerover",
|
||
pointerleave: "pointerout"
|
||
}, function( orig, fix ) {
|
||
jQuery.event.special[ orig ] = {
|
||
delegateType: fix,
|
||
bindType: fix,
|
||
|
||
handle: function( event ) {
|
||
var ret,
|
||
target = this,
|
||
related = event.relatedTarget,
|
||
handleObj = event.handleObj;
|
||
|
||
// For mousenter/leave call the handler if related is outside the target.
|
||
// NB: No relatedTarget if the mouse left/entered the browser window
|
||
if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
|
||
event.type = handleObj.origType;
|
||
ret = handleObj.handler.apply( this, arguments );
|
||
event.type = fix;
|
||
}
|
||
return ret;
|
||
}
|
||
};
|
||
});
|
||
|
||
// IE submit delegation
|
||
if ( !support.submitBubbles ) {
|
||
|
||
jQuery.event.special.submit = {
|
||
setup: function() {
|
||
// Only need this for delegated form submit events
|
||
if ( jQuery.nodeName( this, "form" ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Lazy-add a submit handler when a descendant form may potentially be submitted
|
||
jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
|
||
// Node name check avoids a VML-related crash in IE (#9807)
|
||
var elem = e.target,
|
||
form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
|
||
if ( form && !jQuery._data( form, "submitBubbles" ) ) {
|
||
jQuery.event.add( form, "submit._submit", function( event ) {
|
||
event._submit_bubble = true;
|
||
});
|
||
jQuery._data( form, "submitBubbles", true );
|
||
}
|
||
});
|
||
// return undefined since we don't need an event listener
|
||
},
|
||
|
||
postDispatch: function( event ) {
|
||
// If form was submitted by the user, bubble the event up the tree
|
||
if ( event._submit_bubble ) {
|
||
delete event._submit_bubble;
|
||
if ( this.parentNode && !event.isTrigger ) {
|
||
jQuery.event.simulate( "submit", this.parentNode, event, true );
|
||
}
|
||
}
|
||
},
|
||
|
||
teardown: function() {
|
||
// Only need this for delegated form submit events
|
||
if ( jQuery.nodeName( this, "form" ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
|
||
jQuery.event.remove( this, "._submit" );
|
||
}
|
||
};
|
||
}
|
||
|
||
// IE change delegation and checkbox/radio fix
|
||
if ( !support.changeBubbles ) {
|
||
|
||
jQuery.event.special.change = {
|
||
|
||
setup: function() {
|
||
|
||
if ( rformElems.test( this.nodeName ) ) {
|
||
// IE doesn't fire change on a check/radio until blur; trigger it on click
|
||
// after a propertychange. Eat the blur-change in special.change.handle.
|
||
// This still fires onchange a second time for check/radio after blur.
|
||
if ( this.type === "checkbox" || this.type === "radio" ) {
|
||
jQuery.event.add( this, "propertychange._change", function( event ) {
|
||
if ( event.originalEvent.propertyName === "checked" ) {
|
||
this._just_changed = true;
|
||
}
|
||
});
|
||
jQuery.event.add( this, "click._change", function( event ) {
|
||
if ( this._just_changed && !event.isTrigger ) {
|
||
this._just_changed = false;
|
||
}
|
||
// Allow triggered, simulated change events (#11500)
|
||
jQuery.event.simulate( "change", this, event, true );
|
||
});
|
||
}
|
||
return false;
|
||
}
|
||
// Delegated event; lazy-add a change handler on descendant inputs
|
||
jQuery.event.add( this, "beforeactivate._change", function( e ) {
|
||
var elem = e.target;
|
||
|
||
if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
|
||
jQuery.event.add( elem, "change._change", function( event ) {
|
||
if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
|
||
jQuery.event.simulate( "change", this.parentNode, event, true );
|
||
}
|
||
});
|
||
jQuery._data( elem, "changeBubbles", true );
|
||
}
|
||
});
|
||
},
|
||
|
||
handle: function( event ) {
|
||
var elem = event.target;
|
||
|
||
// Swallow native change events from checkbox/radio, we already triggered them above
|
||
if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
|
||
return event.handleObj.handler.apply( this, arguments );
|
||
}
|
||
},
|
||
|
||
teardown: function() {
|
||
jQuery.event.remove( this, "._change" );
|
||
|
||
return !rformElems.test( this.nodeName );
|
||
}
|
||
};
|
||
}
|
||
|
||
// Create "bubbling" focus and blur events
|
||
if ( !support.focusinBubbles ) {
|
||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||
|
||
// Attach a single capturing handler on the document while someone wants focusin/focusout
|
||
var handler = function( event ) {
|
||
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
|
||
};
|
||
|
||
jQuery.event.special[ fix ] = {
|
||
setup: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = jQuery._data( doc, fix );
|
||
|
||
if ( !attaches ) {
|
||
doc.addEventListener( orig, handler, true );
|
||
}
|
||
jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
|
||
},
|
||
teardown: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = jQuery._data( doc, fix ) - 1;
|
||
|
||
if ( !attaches ) {
|
||
doc.removeEventListener( orig, handler, true );
|
||
jQuery._removeData( doc, fix );
|
||
} else {
|
||
jQuery._data( doc, fix, attaches );
|
||
}
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
jQuery.fn.extend({
|
||
|
||
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
|
||
var type, origFn;
|
||
|
||
// Types can be a map of types/handlers
|
||
if ( typeof types === "object" ) {
|
||
// ( types-Object, selector, data )
|
||
if ( typeof selector !== "string" ) {
|
||
// ( types-Object, data )
|
||
data = data || selector;
|
||
selector = undefined;
|
||
}
|
||
for ( type in types ) {
|
||
this.on( type, selector, data, types[ type ], one );
|
||
}
|
||
return this;
|
||
}
|
||
|
||
if ( data == null && fn == null ) {
|
||
// ( types, fn )
|
||
fn = selector;
|
||
data = selector = undefined;
|
||
} else if ( fn == null ) {
|
||
if ( typeof selector === "string" ) {
|
||
// ( types, selector, fn )
|
||
fn = data;
|
||
data = undefined;
|
||
} else {
|
||
// ( types, data, fn )
|
||
fn = data;
|
||
data = selector;
|
||
selector = undefined;
|
||
}
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
} else if ( !fn ) {
|
||
return this;
|
||
}
|
||
|
||
if ( one === 1 ) {
|
||
origFn = fn;
|
||
fn = function( event ) {
|
||
// Can use an empty set, since event contains the info
|
||
jQuery().off( event );
|
||
return origFn.apply( this, arguments );
|
||
};
|
||
// Use same guid so caller can remove using origFn
|
||
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
||
}
|
||
return this.each( function() {
|
||
jQuery.event.add( this, types, fn, data, selector );
|
||
});
|
||
},
|
||
one: function( types, selector, data, fn ) {
|
||
return this.on( types, selector, data, fn, 1 );
|
||
},
|
||
off: function( types, selector, fn ) {
|
||
var handleObj, type;
|
||
if ( types && types.preventDefault && types.handleObj ) {
|
||
// ( event ) dispatched jQuery.Event
|
||
handleObj = types.handleObj;
|
||
jQuery( types.delegateTarget ).off(
|
||
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
|
||
handleObj.selector,
|
||
handleObj.handler
|
||
);
|
||
return this;
|
||
}
|
||
if ( typeof types === "object" ) {
|
||
// ( types-object [, selector] )
|
||
for ( type in types ) {
|
||
this.off( type, selector, types[ type ] );
|
||
}
|
||
return this;
|
||
}
|
||
if ( selector === false || typeof selector === "function" ) {
|
||
// ( types [, fn] )
|
||
fn = selector;
|
||
selector = undefined;
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
}
|
||
return this.each(function() {
|
||
jQuery.event.remove( this, types, fn, selector );
|
||
});
|
||
},
|
||
|
||
trigger: function( type, data ) {
|
||
return this.each(function() {
|
||
jQuery.event.trigger( type, data, this );
|
||
});
|
||
},
|
||
triggerHandler: function( type, data ) {
|
||
var elem = this[0];
|
||
if ( elem ) {
|
||
return jQuery.event.trigger( type, data, elem, true );
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
function createSafeFragment( document ) {
|
||
var list = nodeNames.split( "|" ),
|
||
safeFrag = document.createDocumentFragment();
|
||
|
||
if ( safeFrag.createElement ) {
|
||
while ( list.length ) {
|
||
safeFrag.createElement(
|
||
list.pop()
|
||
);
|
||
}
|
||
}
|
||
return safeFrag;
|
||
}
|
||
|
||
var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
|
||
"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
|
||
rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
|
||
rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
|
||
rleadingWhitespace = /^\s+/,
|
||
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
|
||
rtagName = /<([\w:]+)/,
|
||
rtbody = /<tbody/i,
|
||
rhtml = /<|&#?\w+;/,
|
||
rnoInnerhtml = /<(?:script|style|link)/i,
|
||
// checked="checked" or checked
|
||
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
||
rscriptType = /^$|\/(?:java|ecma)script/i,
|
||
rscriptTypeMasked = /^true\/(.*)/,
|
||
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
|
||
|
||
// We have to close these tags to support XHTML (#13200)
|
||
wrapMap = {
|
||
option: [ 1, "<select multiple='multiple'>", "</select>" ],
|
||
legend: [ 1, "<fieldset>", "</fieldset>" ],
|
||
area: [ 1, "<map>", "</map>" ],
|
||
param: [ 1, "<object>", "</object>" ],
|
||
thead: [ 1, "<table>", "</table>" ],
|
||
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
|
||
col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
|
||
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
|
||
|
||
// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
|
||
// unless wrapped in a div with non-breaking characters in front of it.
|
||
_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
|
||
},
|
||
safeFragment = createSafeFragment( document ),
|
||
fragmentDiv = safeFragment.appendChild( document.createElement("div") );
|
||
|
||
wrapMap.optgroup = wrapMap.option;
|
||
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
|
||
wrapMap.th = wrapMap.td;
|
||
|
||
function getAll( context, tag ) {
|
||
var elems, elem,
|
||
i = 0,
|
||
found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
|
||
typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
|
||
undefined;
|
||
|
||
if ( !found ) {
|
||
for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
|
||
if ( !tag || jQuery.nodeName( elem, tag ) ) {
|
||
found.push( elem );
|
||
} else {
|
||
jQuery.merge( found, getAll( elem, tag ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
|
||
jQuery.merge( [ context ], found ) :
|
||
found;
|
||
}
|
||
|
||
// Used in buildFragment, fixes the defaultChecked property
|
||
function fixDefaultChecked( elem ) {
|
||
if ( rcheckableType.test( elem.type ) ) {
|
||
elem.defaultChecked = elem.checked;
|
||
}
|
||
}
|
||
|
||
// Support: IE<8
|
||
// Manipulating tables requires a tbody
|
||
function manipulationTarget( elem, content ) {
|
||
return jQuery.nodeName( elem, "table" ) &&
|
||
jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
|
||
|
||
elem.getElementsByTagName("tbody")[0] ||
|
||
elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
|
||
elem;
|
||
}
|
||
|
||
// Replace/restore the type attribute of script elements for safe DOM manipulation
|
||
function disableScript( elem ) {
|
||
elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
|
||
return elem;
|
||
}
|
||
function restoreScript( elem ) {
|
||
var match = rscriptTypeMasked.exec( elem.type );
|
||
if ( match ) {
|
||
elem.type = match[1];
|
||
} else {
|
||
elem.removeAttribute("type");
|
||
}
|
||
return elem;
|
||
}
|
||
|
||
// Mark scripts as having already been evaluated
|
||
function setGlobalEval( elems, refElements ) {
|
||
var elem,
|
||
i = 0;
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
|
||
}
|
||
}
|
||
|
||
function cloneCopyEvent( src, dest ) {
|
||
|
||
if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
|
||
return;
|
||
}
|
||
|
||
var type, i, l,
|
||
oldData = jQuery._data( src ),
|
||
curData = jQuery._data( dest, oldData ),
|
||
events = oldData.events;
|
||
|
||
if ( events ) {
|
||
delete curData.handle;
|
||
curData.events = {};
|
||
|
||
for ( type in events ) {
|
||
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
|
||
jQuery.event.add( dest, type, events[ type ][ i ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
// make the cloned public data object a copy from the original
|
||
if ( curData.data ) {
|
||
curData.data = jQuery.extend( {}, curData.data );
|
||
}
|
||
}
|
||
|
||
function fixCloneNodeIssues( src, dest ) {
|
||
var nodeName, e, data;
|
||
|
||
// We do not need to do anything for non-Elements
|
||
if ( dest.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
nodeName = dest.nodeName.toLowerCase();
|
||
|
||
// IE6-8 copies events bound via attachEvent when using cloneNode.
|
||
if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
|
||
data = jQuery._data( dest );
|
||
|
||
for ( e in data.events ) {
|
||
jQuery.removeEvent( dest, e, data.handle );
|
||
}
|
||
|
||
// Event data gets referenced instead of copied if the expando gets copied too
|
||
dest.removeAttribute( jQuery.expando );
|
||
}
|
||
|
||
// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
|
||
if ( nodeName === "script" && dest.text !== src.text ) {
|
||
disableScript( dest ).text = src.text;
|
||
restoreScript( dest );
|
||
|
||
// IE6-10 improperly clones children of object elements using classid.
|
||
// IE10 throws NoModificationAllowedError if parent is null, #12132.
|
||
} else if ( nodeName === "object" ) {
|
||
if ( dest.parentNode ) {
|
||
dest.outerHTML = src.outerHTML;
|
||
}
|
||
|
||
// This path appears unavoidable for IE9. When cloning an object
|
||
// element in IE9, the outerHTML strategy above is not sufficient.
|
||
// If the src has innerHTML and the destination does not,
|
||
// copy the src.innerHTML into the dest.innerHTML. #10324
|
||
if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
|
||
dest.innerHTML = src.innerHTML;
|
||
}
|
||
|
||
} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
|
||
// IE6-8 fails to persist the checked state of a cloned checkbox
|
||
// or radio button. Worse, IE6-7 fail to give the cloned element
|
||
// a checked appearance if the defaultChecked value isn't also set
|
||
|
||
dest.defaultChecked = dest.checked = src.checked;
|
||
|
||
// IE6-7 get confused and end up setting the value of a cloned
|
||
// checkbox/radio button to an empty string instead of "on"
|
||
if ( dest.value !== src.value ) {
|
||
dest.value = src.value;
|
||
}
|
||
|
||
// IE6-8 fails to return the selected option to the default selected
|
||
// state when cloning options
|
||
} else if ( nodeName === "option" ) {
|
||
dest.defaultSelected = dest.selected = src.defaultSelected;
|
||
|
||
// IE6-8 fails to set the defaultValue to the correct value when
|
||
// cloning other types of input fields
|
||
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
||
dest.defaultValue = src.defaultValue;
|
||
}
|
||
}
|
||
|
||
jQuery.extend({
|
||
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
||
var destElements, node, clone, i, srcElements,
|
||
inPage = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
|
||
clone = elem.cloneNode( true );
|
||
|
||
// IE<=8 does not properly clone detached, unknown element nodes
|
||
} else {
|
||
fragmentDiv.innerHTML = elem.outerHTML;
|
||
fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
|
||
}
|
||
|
||
if ( (!support.noCloneEvent || !support.noCloneChecked) &&
|
||
(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
|
||
|
||
// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
|
||
destElements = getAll( clone );
|
||
srcElements = getAll( elem );
|
||
|
||
// Fix all IE cloning issues
|
||
for ( i = 0; (node = srcElements[i]) != null; ++i ) {
|
||
// Ensure that the destination node is not null; Fixes #9587
|
||
if ( destElements[i] ) {
|
||
fixCloneNodeIssues( node, destElements[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Copy the events from the original to the clone
|
||
if ( dataAndEvents ) {
|
||
if ( deepDataAndEvents ) {
|
||
srcElements = srcElements || getAll( elem );
|
||
destElements = destElements || getAll( clone );
|
||
|
||
for ( i = 0; (node = srcElements[i]) != null; i++ ) {
|
||
cloneCopyEvent( node, destElements[i] );
|
||
}
|
||
} else {
|
||
cloneCopyEvent( elem, clone );
|
||
}
|
||
}
|
||
|
||
// Preserve script evaluation history
|
||
destElements = getAll( clone, "script" );
|
||
if ( destElements.length > 0 ) {
|
||
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
|
||
}
|
||
|
||
destElements = srcElements = node = null;
|
||
|
||
// Return the cloned set
|
||
return clone;
|
||
},
|
||
|
||
buildFragment: function( elems, context, scripts, selection ) {
|
||
var j, elem, contains,
|
||
tmp, tag, tbody, wrap,
|
||
l = elems.length,
|
||
|
||
// Ensure a safe fragment
|
||
safe = createSafeFragment( context ),
|
||
|
||
nodes = [],
|
||
i = 0;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
elem = elems[ i ];
|
||
|
||
if ( elem || elem === 0 ) {
|
||
|
||
// Add nodes directly
|
||
if ( jQuery.type( elem ) === "object" ) {
|
||
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
|
||
|
||
// Convert non-html into a text node
|
||
} else if ( !rhtml.test( elem ) ) {
|
||
nodes.push( context.createTextNode( elem ) );
|
||
|
||
// Convert html into DOM nodes
|
||
} else {
|
||
tmp = tmp || safe.appendChild( context.createElement("div") );
|
||
|
||
// Deserialize a standard representation
|
||
tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
|
||
wrap = wrapMap[ tag ] || wrapMap._default;
|
||
|
||
tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
|
||
|
||
// Descend through wrappers to the right content
|
||
j = wrap[0];
|
||
while ( j-- ) {
|
||
tmp = tmp.lastChild;
|
||
}
|
||
|
||
// Manually add leading whitespace removed by IE
|
||
if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
|
||
nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
|
||
}
|
||
|
||
// Remove IE's autoinserted <tbody> from table fragments
|
||
if ( !support.tbody ) {
|
||
|
||
// String was a <table>, *may* have spurious <tbody>
|
||
elem = tag === "table" && !rtbody.test( elem ) ?
|
||
tmp.firstChild :
|
||
|
||
// String was a bare <thead> or <tfoot>
|
||
wrap[1] === "<table>" && !rtbody.test( elem ) ?
|
||
tmp :
|
||
0;
|
||
|
||
j = elem && elem.childNodes.length;
|
||
while ( j-- ) {
|
||
if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
|
||
elem.removeChild( tbody );
|
||
}
|
||
}
|
||
}
|
||
|
||
jQuery.merge( nodes, tmp.childNodes );
|
||
|
||
// Fix #12392 for WebKit and IE > 9
|
||
tmp.textContent = "";
|
||
|
||
// Fix #12392 for oldIE
|
||
while ( tmp.firstChild ) {
|
||
tmp.removeChild( tmp.firstChild );
|
||
}
|
||
|
||
// Remember the top-level container for proper cleanup
|
||
tmp = safe.lastChild;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fix #11356: Clear elements from fragment
|
||
if ( tmp ) {
|
||
safe.removeChild( tmp );
|
||
}
|
||
|
||
// Reset defaultChecked for any radios and checkboxes
|
||
// about to be appended to the DOM in IE 6/7 (#8060)
|
||
if ( !support.appendChecked ) {
|
||
jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
|
||
}
|
||
|
||
i = 0;
|
||
while ( (elem = nodes[ i++ ]) ) {
|
||
|
||
// #4087 - If origin and destination elements are the same, and this is
|
||
// that element, do not do anything
|
||
if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
|
||
continue;
|
||
}
|
||
|
||
contains = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Append to fragment
|
||
tmp = getAll( safe.appendChild( elem ), "script" );
|
||
|
||
// Preserve script evaluation history
|
||
if ( contains ) {
|
||
setGlobalEval( tmp );
|
||
}
|
||
|
||
// Capture executables
|
||
if ( scripts ) {
|
||
j = 0;
|
||
while ( (elem = tmp[ j++ ]) ) {
|
||
if ( rscriptType.test( elem.type || "" ) ) {
|
||
scripts.push( elem );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
tmp = null;
|
||
|
||
return safe;
|
||
},
|
||
|
||
cleanData: function( elems, /* internal */ acceptData ) {
|
||
var elem, type, id, data,
|
||
i = 0,
|
||
internalKey = jQuery.expando,
|
||
cache = jQuery.cache,
|
||
deleteExpando = support.deleteExpando,
|
||
special = jQuery.event.special;
|
||
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
if ( acceptData || jQuery.acceptData( elem ) ) {
|
||
|
||
id = elem[ internalKey ];
|
||
data = id && cache[ id ];
|
||
|
||
if ( data ) {
|
||
if ( data.events ) {
|
||
for ( type in data.events ) {
|
||
if ( special[ type ] ) {
|
||
jQuery.event.remove( elem, type );
|
||
|
||
// This is a shortcut to avoid jQuery.event.remove's overhead
|
||
} else {
|
||
jQuery.removeEvent( elem, type, data.handle );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove cache only if it was not already removed by jQuery.event.remove
|
||
if ( cache[ id ] ) {
|
||
|
||
delete cache[ id ];
|
||
|
||
// IE does not allow us to delete expando properties from nodes,
|
||
// nor does it have a removeAttribute function on Document nodes;
|
||
// we must handle all of these cases
|
||
if ( deleteExpando ) {
|
||
delete elem[ internalKey ];
|
||
|
||
} else if ( typeof elem.removeAttribute !== strundefined ) {
|
||
elem.removeAttribute( internalKey );
|
||
|
||
} else {
|
||
elem[ internalKey ] = null;
|
||
}
|
||
|
||
deletedIds.push( id );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
text: function( value ) {
|
||
return access( this, function( value ) {
|
||
return value === undefined ?
|
||
jQuery.text( this ) :
|
||
this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
append: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.appendChild( elem );
|
||
}
|
||
});
|
||
},
|
||
|
||
prepend: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.insertBefore( elem, target.firstChild );
|
||
}
|
||
});
|
||
},
|
||
|
||
before: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this );
|
||
}
|
||
});
|
||
},
|
||
|
||
after: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this.nextSibling );
|
||
}
|
||
});
|
||
},
|
||
|
||
remove: function( selector, keepData /* Internal Use Only */ ) {
|
||
var elem,
|
||
elems = selector ? jQuery.filter( selector, this ) : this,
|
||
i = 0;
|
||
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
|
||
if ( !keepData && elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem ) );
|
||
}
|
||
|
||
if ( elem.parentNode ) {
|
||
if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
setGlobalEval( getAll( elem, "script" ) );
|
||
}
|
||
elem.parentNode.removeChild( elem );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
empty: function() {
|
||
var elem,
|
||
i = 0;
|
||
|
||
for ( ; (elem = this[i]) != null; i++ ) {
|
||
// Remove element nodes and prevent memory leaks
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
}
|
||
|
||
// Remove any remaining nodes
|
||
while ( elem.firstChild ) {
|
||
elem.removeChild( elem.firstChild );
|
||
}
|
||
|
||
// If this is a select, ensure that it displays empty (#12336)
|
||
// Support: IE<9
|
||
if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
|
||
elem.options.length = 0;
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
clone: function( dataAndEvents, deepDataAndEvents ) {
|
||
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
|
||
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
|
||
|
||
return this.map(function() {
|
||
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
|
||
});
|
||
},
|
||
|
||
html: function( value ) {
|
||
return access( this, function( value ) {
|
||
var elem = this[ 0 ] || {},
|
||
i = 0,
|
||
l = this.length;
|
||
|
||
if ( value === undefined ) {
|
||
return elem.nodeType === 1 ?
|
||
elem.innerHTML.replace( rinlinejQuery, "" ) :
|
||
undefined;
|
||
}
|
||
|
||
// See if we can take a shortcut and just use innerHTML
|
||
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
|
||
( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
|
||
( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
|
||
!wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
|
||
|
||
value = value.replace( rxhtmlTag, "<$1></$2>" );
|
||
|
||
try {
|
||
for (; i < l; i++ ) {
|
||
// Remove element nodes and prevent memory leaks
|
||
elem = this[i] || {};
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
elem.innerHTML = value;
|
||
}
|
||
}
|
||
|
||
elem = 0;
|
||
|
||
// If using innerHTML throws an exception, use the fallback method
|
||
} catch(e) {}
|
||
}
|
||
|
||
if ( elem ) {
|
||
this.empty().append( value );
|
||
}
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
replaceWith: function() {
|
||
var arg = arguments[ 0 ];
|
||
|
||
// Make the changes, replacing each context element with the new content
|
||
this.domManip( arguments, function( elem ) {
|
||
arg = this.parentNode;
|
||
|
||
jQuery.cleanData( getAll( this ) );
|
||
|
||
if ( arg ) {
|
||
arg.replaceChild( elem, this );
|
||
}
|
||
});
|
||
|
||
// Force removal if there was no new content (e.g., from empty arguments)
|
||
return arg && (arg.length || arg.nodeType) ? this : this.remove();
|
||
},
|
||
|
||
detach: function( selector ) {
|
||
return this.remove( selector, true );
|
||
},
|
||
|
||
domManip: function( args, callback ) {
|
||
|
||
// Flatten any nested arrays
|
||
args = concat.apply( [], args );
|
||
|
||
var first, node, hasScripts,
|
||
scripts, doc, fragment,
|
||
i = 0,
|
||
l = this.length,
|
||
set = this,
|
||
iNoClone = l - 1,
|
||
value = args[0],
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
// We can't cloneNode fragments that contain checked, in WebKit
|
||
if ( isFunction ||
|
||
( l > 1 && typeof value === "string" &&
|
||
!support.checkClone && rchecked.test( value ) ) ) {
|
||
return this.each(function( index ) {
|
||
var self = set.eq( index );
|
||
if ( isFunction ) {
|
||
args[0] = value.call( this, index, self.html() );
|
||
}
|
||
self.domManip( args, callback );
|
||
});
|
||
}
|
||
|
||
if ( l ) {
|
||
fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
|
||
first = fragment.firstChild;
|
||
|
||
if ( fragment.childNodes.length === 1 ) {
|
||
fragment = first;
|
||
}
|
||
|
||
if ( first ) {
|
||
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
|
||
hasScripts = scripts.length;
|
||
|
||
// Use the original fragment for the last item instead of the first because it can end up
|
||
// being emptied incorrectly in certain situations (#8070).
|
||
for ( ; i < l; i++ ) {
|
||
node = fragment;
|
||
|
||
if ( i !== iNoClone ) {
|
||
node = jQuery.clone( node, true, true );
|
||
|
||
// Keep references to cloned scripts for later restoration
|
||
if ( hasScripts ) {
|
||
jQuery.merge( scripts, getAll( node, "script" ) );
|
||
}
|
||
}
|
||
|
||
callback.call( this[i], node, i );
|
||
}
|
||
|
||
if ( hasScripts ) {
|
||
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
||
|
||
// Reenable scripts
|
||
jQuery.map( scripts, restoreScript );
|
||
|
||
// Evaluate executable scripts on first document insertion
|
||
for ( i = 0; i < hasScripts; i++ ) {
|
||
node = scripts[ i ];
|
||
if ( rscriptType.test( node.type || "" ) &&
|
||
!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
|
||
|
||
if ( node.src ) {
|
||
// Optional AJAX dependency, but won't run scripts if not present
|
||
if ( jQuery._evalUrl ) {
|
||
jQuery._evalUrl( node.src );
|
||
}
|
||
} else {
|
||
jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fix #11809: Avoid leaking memory
|
||
fragment = first = null;
|
||
}
|
||
}
|
||
|
||
return this;
|
||
}
|
||
});
|
||
|
||
jQuery.each({
|
||
appendTo: "append",
|
||
prependTo: "prepend",
|
||
insertBefore: "before",
|
||
insertAfter: "after",
|
||
replaceAll: "replaceWith"
|
||
}, function( name, original ) {
|
||
jQuery.fn[ name ] = function( selector ) {
|
||
var elems,
|
||
i = 0,
|
||
ret = [],
|
||
insert = jQuery( selector ),
|
||
last = insert.length - 1;
|
||
|
||
for ( ; i <= last; i++ ) {
|
||
elems = i === last ? this : this.clone(true);
|
||
jQuery( insert[i] )[ original ]( elems );
|
||
|
||
// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
|
||
push.apply( ret, elems.get() );
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
});
|
||
|
||
|
||
var iframe,
|
||
elemdisplay = {};
|
||
|
||
/**
|
||
* Retrieve the actual display of a element
|
||
* @param {String} name nodeName of the element
|
||
* @param {Object} doc Document object
|
||
*/
|
||
// Called only from within defaultDisplay
|
||
function actualDisplay( name, doc ) {
|
||
var style,
|
||
elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
|
||
|
||
// getDefaultComputedStyle might be reliably used only on attached element
|
||
display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
|
||
|
||
// Use of this method is a temporary fix (more like optmization) until something better comes along,
|
||
// since it was removed from specification and supported only in FF
|
||
style.display : jQuery.css( elem[ 0 ], "display" );
|
||
|
||
// We don't have any data stored on the element,
|
||
// so use "detach" method as fast way to get rid of the element
|
||
elem.detach();
|
||
|
||
return display;
|
||
}
|
||
|
||
/**
|
||
* Try to determine the default display value of an element
|
||
* @param {String} nodeName
|
||
*/
|
||
function defaultDisplay( nodeName ) {
|
||
var doc = document,
|
||
display = elemdisplay[ nodeName ];
|
||
|
||
if ( !display ) {
|
||
display = actualDisplay( nodeName, doc );
|
||
|
||
// If the simple way fails, read from inside an iframe
|
||
if ( display === "none" || !display ) {
|
||
|
||
// Use the already-created iframe if possible
|
||
iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
|
||
|
||
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
|
||
doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
|
||
|
||
// Support: IE
|
||
doc.write();
|
||
doc.close();
|
||
|
||
display = actualDisplay( nodeName, doc );
|
||
iframe.detach();
|
||
}
|
||
|
||
// Store the correct default display
|
||
elemdisplay[ nodeName ] = display;
|
||
}
|
||
|
||
return display;
|
||
}
|
||
|
||
|
||
(function() {
|
||
var shrinkWrapBlocksVal;
|
||
|
||
support.shrinkWrapBlocks = function() {
|
||
if ( shrinkWrapBlocksVal != null ) {
|
||
return shrinkWrapBlocksVal;
|
||
}
|
||
|
||
// Will be changed later if needed.
|
||
shrinkWrapBlocksVal = false;
|
||
|
||
// Minified: var b,c,d
|
||
var div, body, container;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Test fired too early or in an unsupported environment, exit.
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
// Support: IE6
|
||
// Check if elements with layout shrink-wrap their children
|
||
if ( typeof div.style.zoom !== strundefined ) {
|
||
// Reset CSS: box-sizing; display; margin; border
|
||
div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
|
||
"box-sizing:content-box;display:block;margin:0;border:0;" +
|
||
"padding:1px;width:1px;zoom:1";
|
||
div.appendChild( document.createElement( "div" ) ).style.width = "5px";
|
||
shrinkWrapBlocksVal = div.offsetWidth !== 3;
|
||
}
|
||
|
||
body.removeChild( container );
|
||
|
||
return shrinkWrapBlocksVal;
|
||
};
|
||
|
||
})();
|
||
var rmargin = (/^margin/);
|
||
|
||
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
||
|
||
|
||
|
||
var getStyles, curCSS,
|
||
rposition = /^(top|right|bottom|left)$/;
|
||
|
||
if ( window.getComputedStyle ) {
|
||
getStyles = function( elem ) {
|
||
return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
|
||
};
|
||
|
||
curCSS = function( elem, name, computed ) {
|
||
var width, minWidth, maxWidth, ret,
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
|
||
// getPropertyValue is only needed for .css('filter') in IE9, see #12537
|
||
ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
|
||
|
||
if ( computed ) {
|
||
|
||
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
ret = jQuery.style( elem, name );
|
||
}
|
||
|
||
// A tribute to the "awesome hack by Dean Edwards"
|
||
// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
|
||
// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
|
||
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
|
||
if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
width = style.width;
|
||
minWidth = style.minWidth;
|
||
maxWidth = style.maxWidth;
|
||
|
||
// Put in the new values to get a computed value out
|
||
style.minWidth = style.maxWidth = style.width = ret;
|
||
ret = computed.width;
|
||
|
||
// Revert the changed values
|
||
style.width = width;
|
||
style.minWidth = minWidth;
|
||
style.maxWidth = maxWidth;
|
||
}
|
||
}
|
||
|
||
// Support: IE
|
||
// IE returns zIndex value as an integer.
|
||
return ret === undefined ?
|
||
ret :
|
||
ret + "";
|
||
};
|
||
} else if ( document.documentElement.currentStyle ) {
|
||
getStyles = function( elem ) {
|
||
return elem.currentStyle;
|
||
};
|
||
|
||
curCSS = function( elem, name, computed ) {
|
||
var left, rs, rsLeft, ret,
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
ret = computed ? computed[ name ] : undefined;
|
||
|
||
// Avoid setting ret to empty string here
|
||
// so we don't default to auto
|
||
if ( ret == null && style && style[ name ] ) {
|
||
ret = style[ name ];
|
||
}
|
||
|
||
// From the awesome hack by Dean Edwards
|
||
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
|
||
|
||
// If we're not dealing with a regular pixel number
|
||
// but a number that has a weird ending, we need to convert it to pixels
|
||
// but not position css attributes, as those are proportional to the parent element instead
|
||
// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
|
||
if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
left = style.left;
|
||
rs = elem.runtimeStyle;
|
||
rsLeft = rs && rs.left;
|
||
|
||
// Put in the new values to get a computed value out
|
||
if ( rsLeft ) {
|
||
rs.left = elem.currentStyle.left;
|
||
}
|
||
style.left = name === "fontSize" ? "1em" : ret;
|
||
ret = style.pixelLeft + "px";
|
||
|
||
// Revert the changed values
|
||
style.left = left;
|
||
if ( rsLeft ) {
|
||
rs.left = rsLeft;
|
||
}
|
||
}
|
||
|
||
// Support: IE
|
||
// IE returns zIndex value as an integer.
|
||
return ret === undefined ?
|
||
ret :
|
||
ret + "" || "auto";
|
||
};
|
||
}
|
||
|
||
|
||
|
||
|
||
function addGetHookIf( conditionFn, hookFn ) {
|
||
// Define the hook, we'll check on the first run if it's really needed.
|
||
return {
|
||
get: function() {
|
||
var condition = conditionFn();
|
||
|
||
if ( condition == null ) {
|
||
// The test was not ready at this point; screw the hook this time
|
||
// but check again when needed next time.
|
||
return;
|
||
}
|
||
|
||
if ( condition ) {
|
||
// Hook not needed (or it's not possible to use it due to missing dependency),
|
||
// remove it.
|
||
// Since there are no other hooks for marginRight, remove the whole object.
|
||
delete this.get;
|
||
return;
|
||
}
|
||
|
||
// Hook needed; redefine it so that the support test is not executed again.
|
||
|
||
return (this.get = hookFn).apply( this, arguments );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
(function() {
|
||
// Minified: var b,c,d,e,f,g, h,i
|
||
var div, style, a, pixelPositionVal, boxSizingReliableVal,
|
||
reliableHiddenOffsetsVal, reliableMarginRightVal;
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
a = div.getElementsByTagName( "a" )[ 0 ];
|
||
style = a && a.style;
|
||
|
||
// Finish early in limited (non-browser) environments
|
||
if ( !style ) {
|
||
return;
|
||
}
|
||
|
||
style.cssText = "float:left;opacity:.5";
|
||
|
||
// Support: IE<9
|
||
// Make sure that element opacity exists (as opposed to filter)
|
||
support.opacity = style.opacity === "0.5";
|
||
|
||
// Verify style float existence
|
||
// (IE uses styleFloat instead of cssFloat)
|
||
support.cssFloat = !!style.cssFloat;
|
||
|
||
div.style.backgroundClip = "content-box";
|
||
div.cloneNode( true ).style.backgroundClip = "";
|
||
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
||
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
|
||
style.WebkitBoxSizing === "";
|
||
|
||
jQuery.extend(support, {
|
||
reliableHiddenOffsets: function() {
|
||
if ( reliableHiddenOffsetsVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return reliableHiddenOffsetsVal;
|
||
},
|
||
|
||
boxSizingReliable: function() {
|
||
if ( boxSizingReliableVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return boxSizingReliableVal;
|
||
},
|
||
|
||
pixelPosition: function() {
|
||
if ( pixelPositionVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return pixelPositionVal;
|
||
},
|
||
|
||
// Support: Android 2.3
|
||
reliableMarginRight: function() {
|
||
if ( reliableMarginRightVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return reliableMarginRightVal;
|
||
}
|
||
});
|
||
|
||
function computeStyleTests() {
|
||
// Minified: var b,c,d,j
|
||
var div, body, container, contents;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Test fired too early or in an unsupported environment, exit.
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
|
||
"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
|
||
"border:1px;padding:1px;width:4px;position:absolute";
|
||
|
||
// Support: IE<9
|
||
// Assume reasonable values in the absence of getComputedStyle
|
||
pixelPositionVal = boxSizingReliableVal = false;
|
||
reliableMarginRightVal = true;
|
||
|
||
// Check for getComputedStyle so that this code is not run in IE<9.
|
||
if ( window.getComputedStyle ) {
|
||
pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
|
||
boxSizingReliableVal =
|
||
( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
|
||
|
||
// Support: Android 2.3
|
||
// Div with explicit width and no margin-right incorrectly
|
||
// gets computed margin-right based on width of container (#3333)
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
contents = div.appendChild( document.createElement( "div" ) );
|
||
|
||
// Reset CSS: box-sizing; display; margin; border; padding
|
||
contents.style.cssText = div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
|
||
"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
|
||
contents.style.marginRight = contents.style.width = "0";
|
||
div.style.width = "1px";
|
||
|
||
reliableMarginRightVal =
|
||
!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
|
||
}
|
||
|
||
// Support: IE8
|
||
// Check if table cells still have offsetWidth/Height when they are set
|
||
// to display:none and there are still other visible table cells in a
|
||
// table row; if so, offsetWidth/Height are not reliable for use when
|
||
// determining if an element has been hidden directly using
|
||
// display:none (it is still safe to use offsets if a parent element is
|
||
// hidden; don safety goggles and see bug #4512 for more information).
|
||
div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
|
||
contents = div.getElementsByTagName( "td" );
|
||
contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
|
||
reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
|
||
if ( reliableHiddenOffsetsVal ) {
|
||
contents[ 0 ].style.display = "";
|
||
contents[ 1 ].style.display = "none";
|
||
reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
|
||
}
|
||
|
||
body.removeChild( container );
|
||
}
|
||
|
||
})();
|
||
|
||
|
||
// A method for quickly swapping in/out CSS properties to get correct calculations.
|
||
jQuery.swap = function( elem, options, callback, args ) {
|
||
var ret, name,
|
||
old = {};
|
||
|
||
// Remember the old values, and insert the new ones
|
||
for ( name in options ) {
|
||
old[ name ] = elem.style[ name ];
|
||
elem.style[ name ] = options[ name ];
|
||
}
|
||
|
||
ret = callback.apply( elem, args || [] );
|
||
|
||
// Revert the old values
|
||
for ( name in options ) {
|
||
elem.style[ name ] = old[ name ];
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
var
|
||
ralpha = /alpha\([^)]*\)/i,
|
||
ropacity = /opacity\s*=\s*([^)]*)/,
|
||
|
||
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
|
||
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
|
||
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
|
||
|
||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||
cssNormalTransform = {
|
||
letterSpacing: "0",
|
||
fontWeight: "400"
|
||
},
|
||
|
||
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
|
||
|
||
|
||
// return a css property mapped to a potentially vendor prefixed property
|
||
function vendorPropName( style, name ) {
|
||
|
||
// shortcut for names that are not vendor prefixed
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
|
||
// check for vendor prefixed names
|
||
var capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||
origName = name,
|
||
i = cssPrefixes.length;
|
||
|
||
while ( i-- ) {
|
||
name = cssPrefixes[ i ] + capName;
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
}
|
||
|
||
return origName;
|
||
}
|
||
|
||
function showHide( elements, show ) {
|
||
var display, elem, hidden,
|
||
values = [],
|
||
index = 0,
|
||
length = elements.length;
|
||
|
||
for ( ; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
|
||
values[ index ] = jQuery._data( elem, "olddisplay" );
|
||
display = elem.style.display;
|
||
if ( show ) {
|
||
// Reset the inline display of this element to learn if it is
|
||
// being hidden by cascaded rules or not
|
||
if ( !values[ index ] && display === "none" ) {
|
||
elem.style.display = "";
|
||
}
|
||
|
||
// Set elements which have been overridden with display: none
|
||
// in a stylesheet to whatever the default browser style is
|
||
// for such an element
|
||
if ( elem.style.display === "" && isHidden( elem ) ) {
|
||
values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
|
||
}
|
||
} else {
|
||
hidden = isHidden( elem );
|
||
|
||
if ( display && display !== "none" || !hidden ) {
|
||
jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set the display of most of the elements in a second loop
|
||
// to avoid the constant reflow
|
||
for ( index = 0; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
|
||
elem.style.display = show ? values[ index ] || "" : "none";
|
||
}
|
||
}
|
||
|
||
return elements;
|
||
}
|
||
|
||
function setPositiveNumber( elem, value, subtract ) {
|
||
var matches = rnumsplit.exec( value );
|
||
return matches ?
|
||
// Guard against undefined "subtract", e.g., when used as in cssHooks
|
||
Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
|
||
value;
|
||
}
|
||
|
||
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
|
||
var i = extra === ( isBorderBox ? "border" : "content" ) ?
|
||
// If we already have the right measurement, avoid augmentation
|
||
4 :
|
||
// Otherwise initialize for horizontal or vertical properties
|
||
name === "width" ? 1 : 0,
|
||
|
||
val = 0;
|
||
|
||
for ( ; i < 4; i += 2 ) {
|
||
// both box models exclude margin, so add it if we want it
|
||
if ( extra === "margin" ) {
|
||
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
if ( isBorderBox ) {
|
||
// border-box includes padding, so remove it if we want content
|
||
if ( extra === "content" ) {
|
||
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
// at this point, extra isn't border nor margin, so remove border
|
||
if ( extra !== "margin" ) {
|
||
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
} else {
|
||
// at this point, extra isn't content, so add padding
|
||
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
|
||
// at this point, extra isn't content nor padding, so add border
|
||
if ( extra !== "padding" ) {
|
||
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
}
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
function getWidthOrHeight( elem, name, extra ) {
|
||
|
||
// Start with offset property, which is equivalent to the border-box value
|
||
var valueIsBorderBox = true,
|
||
val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
|
||
styles = getStyles( elem ),
|
||
isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
|
||
|
||
// some non-html elements return undefined for offsetWidth, so check for null/undefined
|
||
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
|
||
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
|
||
if ( val <= 0 || val == null ) {
|
||
// Fall back to computed then uncomputed css if necessary
|
||
val = curCSS( elem, name, styles );
|
||
if ( val < 0 || val == null ) {
|
||
val = elem.style[ name ];
|
||
}
|
||
|
||
// Computed unit is not pixels. Stop here and return.
|
||
if ( rnumnonpx.test(val) ) {
|
||
return val;
|
||
}
|
||
|
||
// we need the check for style in case a browser which returns unreliable values
|
||
// for getComputedStyle silently falls back to the reliable elem.style
|
||
valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
|
||
|
||
// Normalize "", auto, and prepare for extra
|
||
val = parseFloat( val ) || 0;
|
||
}
|
||
|
||
// use the active box-sizing model to add/subtract irrelevant styles
|
||
return ( val +
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra || ( isBorderBox ? "border" : "content" ),
|
||
valueIsBorderBox,
|
||
styles
|
||
)
|
||
) + "px";
|
||
}
|
||
|
||
jQuery.extend({
|
||
// Add in style property hooks for overriding the default
|
||
// behavior of getting and setting a style property
|
||
cssHooks: {
|
||
opacity: {
|
||
get: function( elem, computed ) {
|
||
if ( computed ) {
|
||
// We should always get a number back from opacity
|
||
var ret = curCSS( elem, "opacity" );
|
||
return ret === "" ? "1" : ret;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
// Don't automatically add "px" to these possibly-unitless properties
|
||
cssNumber: {
|
||
"columnCount": true,
|
||
"fillOpacity": true,
|
||
"flexGrow": true,
|
||
"flexShrink": true,
|
||
"fontWeight": true,
|
||
"lineHeight": true,
|
||
"opacity": true,
|
||
"order": true,
|
||
"orphans": true,
|
||
"widows": true,
|
||
"zIndex": true,
|
||
"zoom": true
|
||
},
|
||
|
||
// Add in properties whose names you wish to fix before
|
||
// setting or getting the value
|
||
cssProps: {
|
||
// normalize float css property
|
||
"float": support.cssFloat ? "cssFloat" : "styleFloat"
|
||
},
|
||
|
||
// Get and set the style property on a DOM Node
|
||
style: function( elem, name, value, extra ) {
|
||
// Don't set styles on text and comment nodes
|
||
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure that we're working with the right name
|
||
var ret, type, hooks,
|
||
origName = jQuery.camelCase( name ),
|
||
style = elem.style;
|
||
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// Check if we're setting a value
|
||
if ( value !== undefined ) {
|
||
type = typeof value;
|
||
|
||
// convert relative number strings (+= or -=) to relative numbers. #7345
|
||
if ( type === "string" && (ret = rrelNum.exec( value )) ) {
|
||
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
|
||
// Fixes bug #9237
|
||
type = "number";
|
||
}
|
||
|
||
// Make sure that null and NaN values aren't set. See: #7116
|
||
if ( value == null || value !== value ) {
|
||
return;
|
||
}
|
||
|
||
// If a number was passed in, add 'px' to the (except for certain CSS properties)
|
||
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
|
||
value += "px";
|
||
}
|
||
|
||
// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
|
||
// but it would mean to define eight (for every problematic property) identical functions
|
||
if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
|
||
style[ name ] = "inherit";
|
||
}
|
||
|
||
// If a hook was provided, use that value, otherwise just set the specified value
|
||
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
|
||
|
||
// Support: IE
|
||
// Swallow errors from 'invalid' CSS values (#5509)
|
||
try {
|
||
style[ name ] = value;
|
||
} catch(e) {}
|
||
}
|
||
|
||
} else {
|
||
// If a hook was provided get the non-computed value from there
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
// Otherwise just get the value from the style object
|
||
return style[ name ];
|
||
}
|
||
},
|
||
|
||
css: function( elem, name, extra, styles ) {
|
||
var num, val, hooks,
|
||
origName = jQuery.camelCase( name );
|
||
|
||
// Make sure that we're working with the right name
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// If a hook was provided get the computed value from there
|
||
if ( hooks && "get" in hooks ) {
|
||
val = hooks.get( elem, true, extra );
|
||
}
|
||
|
||
// Otherwise, if a way to get the computed value exists, use that
|
||
if ( val === undefined ) {
|
||
val = curCSS( elem, name, styles );
|
||
}
|
||
|
||
//convert "normal" to computed value
|
||
if ( val === "normal" && name in cssNormalTransform ) {
|
||
val = cssNormalTransform[ name ];
|
||
}
|
||
|
||
// Return, converting to number if forced or a qualifier was provided and val looks numeric
|
||
if ( extra === "" || extra ) {
|
||
num = parseFloat( val );
|
||
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
|
||
}
|
||
return val;
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "height", "width" ], function( i, name ) {
|
||
jQuery.cssHooks[ name ] = {
|
||
get: function( elem, computed, extra ) {
|
||
if ( computed ) {
|
||
// certain elements can have dimension info if we invisibly show them
|
||
// however, it must have a current display style that would benefit from this
|
||
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
|
||
jQuery.swap( elem, cssShow, function() {
|
||
return getWidthOrHeight( elem, name, extra );
|
||
}) :
|
||
getWidthOrHeight( elem, name, extra );
|
||
}
|
||
},
|
||
|
||
set: function( elem, value, extra ) {
|
||
var styles = extra && getStyles( elem );
|
||
return setPositiveNumber( elem, value, extra ?
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra,
|
||
support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
||
styles
|
||
) : 0
|
||
);
|
||
}
|
||
};
|
||
});
|
||
|
||
if ( !support.opacity ) {
|
||
jQuery.cssHooks.opacity = {
|
||
get: function( elem, computed ) {
|
||
// IE uses filters for opacity
|
||
return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
|
||
( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
|
||
computed ? "1" : "";
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var style = elem.style,
|
||
currentStyle = elem.currentStyle,
|
||
opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
|
||
filter = currentStyle && currentStyle.filter || style.filter || "";
|
||
|
||
// IE has trouble with opacity if it does not have layout
|
||
// Force it by setting the zoom level
|
||
style.zoom = 1;
|
||
|
||
// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
|
||
// if value === "", then remove inline opacity #12685
|
||
if ( ( value >= 1 || value === "" ) &&
|
||
jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
|
||
style.removeAttribute ) {
|
||
|
||
// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
|
||
// if "filter:" is present at all, clearType is disabled, we want to avoid this
|
||
// style.removeAttribute is IE Only, but so apparently is this code path...
|
||
style.removeAttribute( "filter" );
|
||
|
||
// if there is no filter style applied in a css rule or unset inline opacity, we are done
|
||
if ( value === "" || currentStyle && !currentStyle.filter ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// otherwise, set new filter values
|
||
style.filter = ralpha.test( filter ) ?
|
||
filter.replace( ralpha, opacity ) :
|
||
filter + " " + opacity;
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
// Work around by temporarily setting element display to inline-block
|
||
return jQuery.swap( elem, { "display": "inline-block" },
|
||
curCSS, [ elem, "marginRight" ] );
|
||
}
|
||
}
|
||
);
|
||
|
||
// These hooks are used by animate to expand properties
|
||
jQuery.each({
|
||
margin: "",
|
||
padding: "",
|
||
border: "Width"
|
||
}, function( prefix, suffix ) {
|
||
jQuery.cssHooks[ prefix + suffix ] = {
|
||
expand: function( value ) {
|
||
var i = 0,
|
||
expanded = {},
|
||
|
||
// assumes a single number if not a string
|
||
parts = typeof value === "string" ? value.split(" ") : [ value ];
|
||
|
||
for ( ; i < 4; i++ ) {
|
||
expanded[ prefix + cssExpand[ i ] + suffix ] =
|
||
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
|
||
}
|
||
|
||
return expanded;
|
||
}
|
||
};
|
||
|
||
if ( !rmargin.test( prefix ) ) {
|
||
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
css: function( name, value ) {
|
||
return access( this, function( elem, name, value ) {
|
||
var styles, len,
|
||
map = {},
|
||
i = 0;
|
||
|
||
if ( jQuery.isArray( name ) ) {
|
||
styles = getStyles( elem );
|
||
len = name.length;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
|
||
}
|
||
|
||
return map;
|
||
}
|
||
|
||
return value !== undefined ?
|
||
jQuery.style( elem, name, value ) :
|
||
jQuery.css( elem, name );
|
||
}, name, value, arguments.length > 1 );
|
||
},
|
||
show: function() {
|
||
return showHide( this, true );
|
||
},
|
||
hide: function() {
|
||
return showHide( this );
|
||
},
|
||
toggle: function( state ) {
|
||
if ( typeof state === "boolean" ) {
|
||
return state ? this.show() : this.hide();
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( isHidden( this ) ) {
|
||
jQuery( this ).show();
|
||
} else {
|
||
jQuery( this ).hide();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
function Tween( elem, options, prop, end, easing ) {
|
||
return new Tween.prototype.init( elem, options, prop, end, easing );
|
||
}
|
||
jQuery.Tween = Tween;
|
||
|
||
Tween.prototype = {
|
||
constructor: Tween,
|
||
init: function( elem, options, prop, end, easing, unit ) {
|
||
this.elem = elem;
|
||
this.prop = prop;
|
||
this.easing = easing || "swing";
|
||
this.options = options;
|
||
this.start = this.now = this.cur();
|
||
this.end = end;
|
||
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
||
},
|
||
cur: function() {
|
||
var hooks = Tween.propHooks[ this.prop ];
|
||
|
||
return hooks && hooks.get ?
|
||
hooks.get( this ) :
|
||
Tween.propHooks._default.get( this );
|
||
},
|
||
run: function( percent ) {
|
||
var eased,
|
||
hooks = Tween.propHooks[ this.prop ];
|
||
|
||
if ( this.options.duration ) {
|
||
this.pos = eased = jQuery.easing[ this.easing ](
|
||
percent, this.options.duration * percent, 0, 1, this.options.duration
|
||
);
|
||
} else {
|
||
this.pos = eased = percent;
|
||
}
|
||
this.now = ( this.end - this.start ) * eased + this.start;
|
||
|
||
if ( this.options.step ) {
|
||
this.options.step.call( this.elem, this.now, this );
|
||
}
|
||
|
||
if ( hooks && hooks.set ) {
|
||
hooks.set( this );
|
||
} else {
|
||
Tween.propHooks._default.set( this );
|
||
}
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Tween.prototype.init.prototype = Tween.prototype;
|
||
|
||
Tween.propHooks = {
|
||
_default: {
|
||
get: function( tween ) {
|
||
var result;
|
||
|
||
if ( tween.elem[ tween.prop ] != null &&
|
||
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
|
||
return tween.elem[ tween.prop ];
|
||
}
|
||
|
||
// passing an empty string as a 3rd parameter to .css will automatically
|
||
// attempt a parseFloat and fallback to a string if the parse fails
|
||
// so, simple values such as "10px" are parsed to Float.
|
||
// complex values such as "rotate(1rad)" are returned as is.
|
||
result = jQuery.css( tween.elem, tween.prop, "" );
|
||
// Empty strings, null, undefined and "auto" are converted to 0.
|
||
return !result || result === "auto" ? 0 : result;
|
||
},
|
||
set: function( tween ) {
|
||
// use step hook for back compat - use cssHook if its there - use .style if its
|
||
// available and use plain properties where available
|
||
if ( jQuery.fx.step[ tween.prop ] ) {
|
||
jQuery.fx.step[ tween.prop ]( tween );
|
||
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
|
||
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
||
} else {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Support: IE <=9
|
||
// Panic based approach to setting things on disconnected nodes
|
||
|
||
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
|
||
set: function( tween ) {
|
||
if ( tween.elem.nodeType && tween.elem.parentNode ) {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.easing = {
|
||
linear: function( p ) {
|
||
return p;
|
||
},
|
||
swing: function( p ) {
|
||
return 0.5 - Math.cos( p * Math.PI ) / 2;
|
||
}
|
||
};
|
||
|
||
jQuery.fx = Tween.prototype.init;
|
||
|
||
// Back Compat <1.8 extension point
|
||
jQuery.fx.step = {};
|
||
|
||
|
||
|
||
|
||
var
|
||
fxNow, timerId,
|
||
rfxtypes = /^(?:toggle|show|hide)$/,
|
||
rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
|
||
rrun = /queueHooks$/,
|
||
animationPrefilters = [ defaultPrefilter ],
|
||
tweeners = {
|
||
"*": [ function( prop, value ) {
|
||
var tween = this.createTween( prop, value ),
|
||
target = tween.cur(),
|
||
parts = rfxnum.exec( value ),
|
||
unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||
|
||
// Starting value computation is required for potential unit mismatches
|
||
start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
|
||
rfxnum.exec( jQuery.css( tween.elem, prop ) ),
|
||
scale = 1,
|
||
maxIterations = 20;
|
||
|
||
if ( start && start[ 3 ] !== unit ) {
|
||
// Trust units reported by jQuery.css
|
||
unit = unit || start[ 3 ];
|
||
|
||
// Make sure we update the tween properties later on
|
||
parts = parts || [];
|
||
|
||
// Iteratively approximate from a nonzero starting point
|
||
start = +target || 1;
|
||
|
||
do {
|
||
// If previous iteration zeroed out, double until we get *something*
|
||
// Use a string for doubling factor so we don't accidentally see scale as unchanged below
|
||
scale = scale || ".5";
|
||
|
||
// Adjust and apply
|
||
start = start / scale;
|
||
jQuery.style( tween.elem, prop, start + unit );
|
||
|
||
// Update scale, tolerating zero or NaN from tween.cur()
|
||
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
|
||
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
|
||
}
|
||
|
||
// Update tween properties
|
||
if ( parts ) {
|
||
start = tween.start = +start || +target || 0;
|
||
tween.unit = unit;
|
||
// If a +=/-= token was provided, we're doing a relative animation
|
||
tween.end = parts[ 1 ] ?
|
||
start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
|
||
+parts[ 2 ];
|
||
}
|
||
|
||
return tween;
|
||
} ]
|
||
};
|
||
|
||
// Animations created synchronously will run synchronously
|
||
function createFxNow() {
|
||
setTimeout(function() {
|
||
fxNow = undefined;
|
||
});
|
||
return ( fxNow = jQuery.now() );
|
||
}
|
||
|
||
// Generate parameters to create a standard animation
|
||
function genFx( type, includeWidth ) {
|
||
var which,
|
||
attrs = { height: type },
|
||
i = 0;
|
||
|
||
// if we include width, step value is 1 to do all cssExpand values,
|
||
// if we don't include width, step value is 2 to skip over Left and Right
|
||
includeWidth = includeWidth ? 1 : 0;
|
||
for ( ; i < 4 ; i += 2 - includeWidth ) {
|
||
which = cssExpand[ i ];
|
||
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
||
}
|
||
|
||
if ( includeWidth ) {
|
||
attrs.opacity = attrs.width = type;
|
||
}
|
||
|
||
return attrs;
|
||
}
|
||
|
||
function createTween( value, prop, animation ) {
|
||
var tween,
|
||
collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
|
||
index = 0,
|
||
length = collection.length;
|
||
for ( ; index < length; index++ ) {
|
||
if ( (tween = collection[ index ].call( animation, prop, value )) ) {
|
||
|
||
// we're done with this property
|
||
return tween;
|
||
}
|
||
}
|
||
}
|
||
|
||
function defaultPrefilter( elem, props, opts ) {
|
||
/* jshint validthis: true */
|
||
var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
|
||
anim = this,
|
||
orig = {},
|
||
style = elem.style,
|
||
hidden = elem.nodeType && isHidden( elem ),
|
||
dataShow = jQuery._data( elem, "fxshow" );
|
||
|
||
// handle queue: false promises
|
||
if ( !opts.queue ) {
|
||
hooks = jQuery._queueHooks( elem, "fx" );
|
||
if ( hooks.unqueued == null ) {
|
||
hooks.unqueued = 0;
|
||
oldfire = hooks.empty.fire;
|
||
hooks.empty.fire = function() {
|
||
if ( !hooks.unqueued ) {
|
||
oldfire();
|
||
}
|
||
};
|
||
}
|
||
hooks.unqueued++;
|
||
|
||
anim.always(function() {
|
||
// doing this makes sure that the complete handler will be called
|
||
// before this completes
|
||
anim.always(function() {
|
||
hooks.unqueued--;
|
||
if ( !jQuery.queue( elem, "fx" ).length ) {
|
||
hooks.empty.fire();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// height/width overflow pass
|
||
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
|
||
// Make sure that nothing sneaks out
|
||
// Record all 3 overflow attributes because IE does not
|
||
// change the overflow attribute when overflowX and
|
||
// overflowY are set to the same value
|
||
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
||
|
||
// Set display property to inline-block for height/width
|
||
// animations on inline elements that are having width/height animated
|
||
display = jQuery.css( elem, "display" );
|
||
|
||
// Test default display if display is currently "none"
|
||
checkDisplay = display === "none" ?
|
||
jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
|
||
|
||
if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
|
||
|
||
// inline-level elements accept inline-block;
|
||
// block-level elements need to be inline with layout
|
||
if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
|
||
style.display = "inline-block";
|
||
} else {
|
||
style.zoom = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( opts.overflow ) {
|
||
style.overflow = "hidden";
|
||
if ( !support.shrinkWrapBlocks() ) {
|
||
anim.always(function() {
|
||
style.overflow = opts.overflow[ 0 ];
|
||
style.overflowX = opts.overflow[ 1 ];
|
||
style.overflowY = opts.overflow[ 2 ];
|
||
});
|
||
}
|
||
}
|
||
|
||
// show/hide pass
|
||
for ( prop in props ) {
|
||
value = props[ prop ];
|
||
if ( rfxtypes.exec( value ) ) {
|
||
delete props[ prop ];
|
||
toggle = toggle || value === "toggle";
|
||
if ( value === ( hidden ? "hide" : "show" ) ) {
|
||
|
||
// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
|
||
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
|
||
hidden = true;
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
|
||
|
||
// Any non-fx value stops us from restoring the original display value
|
||
} else {
|
||
display = undefined;
|
||
}
|
||
}
|
||
|
||
if ( !jQuery.isEmptyObject( orig ) ) {
|
||
if ( dataShow ) {
|
||
if ( "hidden" in dataShow ) {
|
||
hidden = dataShow.hidden;
|
||
}
|
||
} else {
|
||
dataShow = jQuery._data( elem, "fxshow", {} );
|
||
}
|
||
|
||
// store state if its toggle - enables .stop().toggle() to "reverse"
|
||
if ( toggle ) {
|
||
dataShow.hidden = !hidden;
|
||
}
|
||
if ( hidden ) {
|
||
jQuery( elem ).show();
|
||
} else {
|
||
anim.done(function() {
|
||
jQuery( elem ).hide();
|
||
});
|
||
}
|
||
anim.done(function() {
|
||
var prop;
|
||
jQuery._removeData( elem, "fxshow" );
|
||
for ( prop in orig ) {
|
||
jQuery.style( elem, prop, orig[ prop ] );
|
||
}
|
||
});
|
||
for ( prop in orig ) {
|
||
tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
|
||
|
||
if ( !( prop in dataShow ) ) {
|
||
dataShow[ prop ] = tween.start;
|
||
if ( hidden ) {
|
||
tween.end = tween.start;
|
||
tween.start = prop === "width" || prop === "height" ? 1 : 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If this is a noop like .hide().hide(), restore an overwritten display value
|
||
} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
|
||
style.display = display;
|
||
}
|
||
}
|
||
|
||
function propFilter( props, specialEasing ) {
|
||
var index, name, easing, value, hooks;
|
||
|
||
// camelCase, specialEasing and expand cssHook pass
|
||
for ( index in props ) {
|
||
name = jQuery.camelCase( index );
|
||
easing = specialEasing[ name ];
|
||
value = props[ index ];
|
||
if ( jQuery.isArray( value ) ) {
|
||
easing = value[ 1 ];
|
||
value = props[ index ] = value[ 0 ];
|
||
}
|
||
|
||
if ( index !== name ) {
|
||
props[ name ] = value;
|
||
delete props[ index ];
|
||
}
|
||
|
||
hooks = jQuery.cssHooks[ name ];
|
||
if ( hooks && "expand" in hooks ) {
|
||
value = hooks.expand( value );
|
||
delete props[ name ];
|
||
|
||
// not quite $.extend, this wont overwrite keys already present.
|
||
// also - reusing 'index' from above because we have the correct "name"
|
||
for ( index in value ) {
|
||
if ( !( index in props ) ) {
|
||
props[ index ] = value[ index ];
|
||
specialEasing[ index ] = easing;
|
||
}
|
||
}
|
||
} else {
|
||
specialEasing[ name ] = easing;
|
||
}
|
||
}
|
||
}
|
||
|
||
function Animation( elem, properties, options ) {
|
||
var result,
|
||
stopped,
|
||
index = 0,
|
||
length = animationPrefilters.length,
|
||
deferred = jQuery.Deferred().always( function() {
|
||
// don't match elem in the :animated selector
|
||
delete tick.elem;
|
||
}),
|
||
tick = function() {
|
||
if ( stopped ) {
|
||
return false;
|
||
}
|
||
var currentTime = fxNow || createFxNow(),
|
||
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
||
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
|
||
temp = remaining / animation.duration || 0,
|
||
percent = 1 - temp,
|
||
index = 0,
|
||
length = animation.tweens.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( percent );
|
||
}
|
||
|
||
deferred.notifyWith( elem, [ animation, percent, remaining ]);
|
||
|
||
if ( percent < 1 && length ) {
|
||
return remaining;
|
||
} else {
|
||
deferred.resolveWith( elem, [ animation ] );
|
||
return false;
|
||
}
|
||
},
|
||
animation = deferred.promise({
|
||
elem: elem,
|
||
props: jQuery.extend( {}, properties ),
|
||
opts: jQuery.extend( true, { specialEasing: {} }, options ),
|
||
originalProperties: properties,
|
||
originalOptions: options,
|
||
startTime: fxNow || createFxNow(),
|
||
duration: options.duration,
|
||
tweens: [],
|
||
createTween: function( prop, end ) {
|
||
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
||
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
||
animation.tweens.push( tween );
|
||
return tween;
|
||
},
|
||
stop: function( gotoEnd ) {
|
||
var index = 0,
|
||
// if we are going to the end, we want to run all the tweens
|
||
// otherwise we skip this part
|
||
length = gotoEnd ? animation.tweens.length : 0;
|
||
if ( stopped ) {
|
||
return this;
|
||
}
|
||
stopped = true;
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( 1 );
|
||
}
|
||
|
||
// resolve when we played the last frame
|
||
// otherwise, reject
|
||
if ( gotoEnd ) {
|
||
deferred.resolveWith( elem, [ animation, gotoEnd ] );
|
||
} else {
|
||
deferred.rejectWith( elem, [ animation, gotoEnd ] );
|
||
}
|
||
return this;
|
||
}
|
||
}),
|
||
props = animation.props;
|
||
|
||
propFilter( props, animation.opts.specialEasing );
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
|
||
if ( result ) {
|
||
return result;
|
||
}
|
||
}
|
||
|
||
jQuery.map( props, createTween, animation );
|
||
|
||
if ( jQuery.isFunction( animation.opts.start ) ) {
|
||
animation.opts.start.call( elem, animation );
|
||
}
|
||
|
||
jQuery.fx.timer(
|
||
jQuery.extend( tick, {
|
||
elem: elem,
|
||
anim: animation,
|
||
queue: animation.opts.queue
|
||
})
|
||
);
|
||
|
||
// attach callbacks from options
|
||
return animation.progress( animation.opts.progress )
|
||
.done( animation.opts.done, animation.opts.complete )
|
||
.fail( animation.opts.fail )
|
||
.always( animation.opts.always );
|
||
}
|
||
|
||
jQuery.Animation = jQuery.extend( Animation, {
|
||
tweener: function( props, callback ) {
|
||
if ( jQuery.isFunction( props ) ) {
|
||
callback = props;
|
||
props = [ "*" ];
|
||
} else {
|
||
props = props.split(" ");
|
||
}
|
||
|
||
var prop,
|
||
index = 0,
|
||
length = props.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
prop = props[ index ];
|
||
tweeners[ prop ] = tweeners[ prop ] || [];
|
||
tweeners[ prop ].unshift( callback );
|
||
}
|
||
},
|
||
|
||
prefilter: function( callback, prepend ) {
|
||
if ( prepend ) {
|
||
animationPrefilters.unshift( callback );
|
||
} else {
|
||
animationPrefilters.push( callback );
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.speed = function( speed, easing, fn ) {
|
||
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
||
complete: fn || !fn && easing ||
|
||
jQuery.isFunction( speed ) && speed,
|
||
duration: speed,
|
||
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
|
||
};
|
||
|
||
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
|
||
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
|
||
|
||
// normalize opt.queue - true/undefined/null -> "fx"
|
||
if ( opt.queue == null || opt.queue === true ) {
|
||
opt.queue = "fx";
|
||
}
|
||
|
||
// Queueing
|
||
opt.old = opt.complete;
|
||
|
||
opt.complete = function() {
|
||
if ( jQuery.isFunction( opt.old ) ) {
|
||
opt.old.call( this );
|
||
}
|
||
|
||
if ( opt.queue ) {
|
||
jQuery.dequeue( this, opt.queue );
|
||
}
|
||
};
|
||
|
||
return opt;
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
fadeTo: function( speed, to, easing, callback ) {
|
||
|
||
// show any hidden elements after setting opacity to 0
|
||
return this.filter( isHidden ).css( "opacity", 0 ).show()
|
||
|
||
// animate to the value specified
|
||
.end().animate({ opacity: to }, speed, easing, callback );
|
||
},
|
||
animate: function( prop, speed, easing, callback ) {
|
||
var empty = jQuery.isEmptyObject( prop ),
|
||
optall = jQuery.speed( speed, easing, callback ),
|
||
doAnimation = function() {
|
||
// Operate on a copy of prop so per-property easing won't be lost
|
||
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
|
||
|
||
// Empty animations, or finishing resolves immediately
|
||
if ( empty || jQuery._data( this, "finish" ) ) {
|
||
anim.stop( true );
|
||
}
|
||
};
|
||
doAnimation.finish = doAnimation;
|
||
|
||
return empty || optall.queue === false ?
|
||
this.each( doAnimation ) :
|
||
this.queue( optall.queue, doAnimation );
|
||
},
|
||
stop: function( type, clearQueue, gotoEnd ) {
|
||
var stopQueue = function( hooks ) {
|
||
var stop = hooks.stop;
|
||
delete hooks.stop;
|
||
stop( gotoEnd );
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
gotoEnd = clearQueue;
|
||
clearQueue = type;
|
||
type = undefined;
|
||
}
|
||
if ( clearQueue && type !== false ) {
|
||
this.queue( type || "fx", [] );
|
||
}
|
||
|
||
return this.each(function() {
|
||
var dequeue = true,
|
||
index = type != null && type + "queueHooks",
|
||
timers = jQuery.timers,
|
||
data = jQuery._data( this );
|
||
|
||
if ( index ) {
|
||
if ( data[ index ] && data[ index ].stop ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
} else {
|
||
for ( index in data ) {
|
||
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
|
||
timers[ index ].anim.stop( gotoEnd );
|
||
dequeue = false;
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// start the next in the queue if the last step wasn't forced
|
||
// timers currently will call their complete callbacks, which will dequeue
|
||
// but only if they were gotoEnd
|
||
if ( dequeue || !gotoEnd ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
finish: function( type ) {
|
||
if ( type !== false ) {
|
||
type = type || "fx";
|
||
}
|
||
return this.each(function() {
|
||
var index,
|
||
data = jQuery._data( this ),
|
||
queue = data[ type + "queue" ],
|
||
hooks = data[ type + "queueHooks" ],
|
||
timers = jQuery.timers,
|
||
length = queue ? queue.length : 0;
|
||
|
||
// enable finishing flag on private data
|
||
data.finish = true;
|
||
|
||
// empty the queue first
|
||
jQuery.queue( this, type, [] );
|
||
|
||
if ( hooks && hooks.stop ) {
|
||
hooks.stop.call( this, true );
|
||
}
|
||
|
||
// look for any active animations, and finish them
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
|
||
timers[ index ].anim.stop( true );
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// look for any animations in the old queue and finish them
|
||
for ( index = 0; index < length; index++ ) {
|
||
if ( queue[ index ] && queue[ index ].finish ) {
|
||
queue[ index ].finish.call( this );
|
||
}
|
||
}
|
||
|
||
// turn off finishing flag
|
||
delete data.finish;
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
|
||
var cssFn = jQuery.fn[ name ];
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return speed == null || typeof speed === "boolean" ?
|
||
cssFn.apply( this, arguments ) :
|
||
this.animate( genFx( name, true ), speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
// Generate shortcuts for custom animations
|
||
jQuery.each({
|
||
slideDown: genFx("show"),
|
||
slideUp: genFx("hide"),
|
||
slideToggle: genFx("toggle"),
|
||
fadeIn: { opacity: "show" },
|
||
fadeOut: { opacity: "hide" },
|
||
fadeToggle: { opacity: "toggle" }
|
||
}, function( name, props ) {
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return this.animate( props, speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
jQuery.timers = [];
|
||
jQuery.fx.tick = function() {
|
||
var timer,
|
||
timers = jQuery.timers,
|
||
i = 0;
|
||
|
||
fxNow = jQuery.now();
|
||
|
||
for ( ; i < timers.length; i++ ) {
|
||
timer = timers[ i ];
|
||
// Checks the timer has not already been removed
|
||
if ( !timer() && timers[ i ] === timer ) {
|
||
timers.splice( i--, 1 );
|
||
}
|
||
}
|
||
|
||
if ( !timers.length ) {
|
||
jQuery.fx.stop();
|
||
}
|
||
fxNow = undefined;
|
||
};
|
||
|
||
jQuery.fx.timer = function( timer ) {
|
||
jQuery.timers.push( timer );
|
||
if ( timer() ) {
|
||
jQuery.fx.start();
|
||
} else {
|
||
jQuery.timers.pop();
|
||
}
|
||
};
|
||
|
||
jQuery.fx.interval = 13;
|
||
|
||
jQuery.fx.start = function() {
|
||
if ( !timerId ) {
|
||
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
|
||
}
|
||
};
|
||
|
||
jQuery.fx.stop = function() {
|
||
clearInterval( timerId );
|
||
timerId = null;
|
||
};
|
||
|
||
jQuery.fx.speeds = {
|
||
slow: 600,
|
||
fast: 200,
|
||
// Default speed
|
||
_default: 400
|
||
};
|
||
|
||
|
||
// Based off of the plugin by Clint Helfers, with permission.
|
||
// http://blindsignals.com/index.php/2009/07/jquery-delay/
|
||
jQuery.fn.delay = function( time, type ) {
|
||
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
||
type = type || "fx";
|
||
|
||
return this.queue( type, function( next, hooks ) {
|
||
var timeout = setTimeout( next, time );
|
||
hooks.stop = function() {
|
||
clearTimeout( timeout );
|
||
};
|
||
});
|
||
};
|
||
|
||
|
||
(function() {
|
||
// Minified: var a,b,c,d,e
|
||
var input, div, select, a, opt;
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
div.setAttribute( "className", "t" );
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
a = div.getElementsByTagName("a")[ 0 ];
|
||
|
||
// First batch of tests.
|
||
select = document.createElement("select");
|
||
opt = select.appendChild( document.createElement("option") );
|
||
input = div.getElementsByTagName("input")[ 0 ];
|
||
|
||
a.style.cssText = "top:1px";
|
||
|
||
// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
|
||
support.getSetAttribute = div.className !== "t";
|
||
|
||
// Get the style information from getAttribute
|
||
// (IE uses .cssText instead)
|
||
support.style = /top/.test( a.getAttribute("style") );
|
||
|
||
// Make sure that URLs aren't manipulated
|
||
// (IE normalizes it by default)
|
||
support.hrefNormalized = a.getAttribute("href") === "/a";
|
||
|
||
// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
|
||
support.checkOn = !!input.value;
|
||
|
||
// Make sure that a selected-by-default option has a working selected property.
|
||
// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
|
||
support.optSelected = opt.selected;
|
||
|
||
// Tests for enctype support on a form (#6743)
|
||
support.enctype = !!document.createElement("form").enctype;
|
||
|
||
// Make sure that the options inside disabled selects aren't marked as disabled
|
||
// (WebKit marks them as disabled)
|
||
select.disabled = true;
|
||
support.optDisabled = !opt.disabled;
|
||
|
||
// Support: IE8 only
|
||
// Check if we can trust getAttribute("value")
|
||
input = document.createElement( "input" );
|
||
input.setAttribute( "value", "" );
|
||
support.input = input.getAttribute( "value" ) === "";
|
||
|
||
// Check if an input maintains its value after becoming a radio
|
||
input.value = "t";
|
||
input.setAttribute( "type", "radio" );
|
||
support.radioValue = input.value === "t";
|
||
})();
|
||
|
||
|
||
var rreturn = /\r/g;
|
||
|
||
jQuery.fn.extend({
|
||
val: function( value ) {
|
||
var hooks, ret, isFunction,
|
||
elem = this[0];
|
||
|
||
if ( !arguments.length ) {
|
||
if ( elem ) {
|
||
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
|
||
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
ret = elem.value;
|
||
|
||
return typeof ret === "string" ?
|
||
// handle most common string cases
|
||
ret.replace(rreturn, "") :
|
||
// handle cases where value is null/undef or number
|
||
ret == null ? "" : ret;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
return this.each(function( i ) {
|
||
var val;
|
||
|
||
if ( this.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
if ( isFunction ) {
|
||
val = value.call( this, i, jQuery( this ).val() );
|
||
} else {
|
||
val = value;
|
||
}
|
||
|
||
// Treat null/undefined as ""; convert numbers to string
|
||
if ( val == null ) {
|
||
val = "";
|
||
} else if ( typeof val === "number" ) {
|
||
val += "";
|
||
} else if ( jQuery.isArray( val ) ) {
|
||
val = jQuery.map( val, function( value ) {
|
||
return value == null ? "" : value + "";
|
||
});
|
||
}
|
||
|
||
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
|
||
|
||
// If set returns undefined, fall back to normal setting
|
||
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
|
||
this.value = val;
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
valHooks: {
|
||
option: {
|
||
get: function( elem ) {
|
||
var val = jQuery.find.attr( elem, "value" );
|
||
return val != null ?
|
||
val :
|
||
// Support: IE10-11+
|
||
// option.text throws exceptions (#14686, #14858)
|
||
jQuery.trim( jQuery.text( elem ) );
|
||
}
|
||
},
|
||
select: {
|
||
get: function( elem ) {
|
||
var value, option,
|
||
options = elem.options,
|
||
index = elem.selectedIndex,
|
||
one = elem.type === "select-one" || index < 0,
|
||
values = one ? null : [],
|
||
max = one ? index + 1 : options.length,
|
||
i = index < 0 ?
|
||
max :
|
||
one ? index : 0;
|
||
|
||
// Loop through all the selected options
|
||
for ( ; i < max; i++ ) {
|
||
option = options[ i ];
|
||
|
||
// oldIE doesn't update selected after form reset (#2551)
|
||
if ( ( option.selected || i === index ) &&
|
||
// Don't return options that are disabled or in a disabled optgroup
|
||
( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
|
||
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
|
||
|
||
// Get the specific value for the option
|
||
value = jQuery( option ).val();
|
||
|
||
// We don't need an array for one selects
|
||
if ( one ) {
|
||
return value;
|
||
}
|
||
|
||
// Multi-Selects return an array
|
||
values.push( value );
|
||
}
|
||
}
|
||
|
||
return values;
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var optionSet, option,
|
||
options = elem.options,
|
||
values = jQuery.makeArray( value ),
|
||
i = options.length;
|
||
|
||
while ( i-- ) {
|
||
option = options[ i ];
|
||
|
||
if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
|
||
|
||
// Support: IE6
|
||
// When new option element is added to select box we need to
|
||
// force reflow of newly added node in order to workaround delay
|
||
// of initialization properties
|
||
try {
|
||
option.selected = optionSet = true;
|
||
|
||
} catch ( _ ) {
|
||
|
||
// Will be executed only in IE6
|
||
option.scrollHeight;
|
||
}
|
||
|
||
} else {
|
||
option.selected = false;
|
||
}
|
||
}
|
||
|
||
// Force browsers to behave consistently when non-matching value is set
|
||
if ( !optionSet ) {
|
||
elem.selectedIndex = -1;
|
||
}
|
||
|
||
return options;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Radios and checkboxes getter/setter
|
||
jQuery.each([ "radio", "checkbox" ], function() {
|
||
jQuery.valHooks[ this ] = {
|
||
set: function( elem, value ) {
|
||
if ( jQuery.isArray( value ) ) {
|
||
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
|
||
}
|
||
}
|
||
};
|
||
if ( !support.checkOn ) {
|
||
jQuery.valHooks[ this ].get = function( elem ) {
|
||
// Support: Webkit
|
||
// "" is returned instead of "on" if a value isn't specified
|
||
return elem.getAttribute("value") === null ? "on" : elem.value;
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var nodeHook, boolHook,
|
||
attrHandle = jQuery.expr.attrHandle,
|
||
ruseDefault = /^(?:checked|selected)$/i,
|
||
getSetAttribute = support.getSetAttribute,
|
||
getSetInput = support.input;
|
||
|
||
jQuery.fn.extend({
|
||
attr: function( name, value ) {
|
||
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeAttr: function( name ) {
|
||
return this.each(function() {
|
||
jQuery.removeAttr( this, name );
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
attr: function( elem, name, value ) {
|
||
var hooks, ret,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set attributes on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// Fallback to prop when attributes are not supported
|
||
if ( typeof elem.getAttribute === strundefined ) {
|
||
return jQuery.prop( elem, name, value );
|
||
}
|
||
|
||
// All attributes are lowercase
|
||
// Grab necessary hook if one is defined
|
||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||
name = name.toLowerCase();
|
||
hooks = jQuery.attrHooks[ name ] ||
|
||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
|
||
if ( value === null ) {
|
||
jQuery.removeAttr( elem, name );
|
||
|
||
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
||
return ret;
|
||
|
||
} else {
|
||
elem.setAttribute( name, value + "" );
|
||
return value;
|
||
}
|
||
|
||
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
||
return ret;
|
||
|
||
} else {
|
||
ret = jQuery.find.attr( elem, name );
|
||
|
||
// Non-existent attributes return null, we normalize to undefined
|
||
return ret == null ?
|
||
undefined :
|
||
ret;
|
||
}
|
||
},
|
||
|
||
removeAttr: function( elem, value ) {
|
||
var name, propName,
|
||
i = 0,
|
||
attrNames = value && value.match( rnotwhite );
|
||
|
||
if ( attrNames && elem.nodeType === 1 ) {
|
||
while ( (name = attrNames[i++]) ) {
|
||
propName = jQuery.propFix[ name ] || name;
|
||
|
||
// Boolean attributes get special treatment (#10870)
|
||
if ( jQuery.expr.match.bool.test( name ) ) {
|
||
// Set corresponding property to false
|
||
if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
||
elem[ propName ] = false;
|
||
// Support: IE<9
|
||
// Also clear defaultChecked/defaultSelected (if appropriate)
|
||
} else {
|
||
elem[ jQuery.camelCase( "default-" + name ) ] =
|
||
elem[ propName ] = false;
|
||
}
|
||
|
||
// See #9699 for explanation of this approach (setting first, then removal)
|
||
} else {
|
||
jQuery.attr( elem, name, "" );
|
||
}
|
||
|
||
elem.removeAttribute( getSetAttribute ? name : propName );
|
||
}
|
||
}
|
||
},
|
||
|
||
attrHooks: {
|
||
type: {
|
||
set: function( elem, value ) {
|
||
if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
|
||
// Setting the type on a radio button after the value resets the value in IE6-9
|
||
// Reset value to default in case type is set after value during creation
|
||
var val = elem.value;
|
||
elem.setAttribute( "type", value );
|
||
if ( val ) {
|
||
elem.value = val;
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Hook for boolean attributes
|
||
boolHook = {
|
||
set: function( elem, value, name ) {
|
||
if ( value === false ) {
|
||
// Remove boolean attributes when set to false
|
||
jQuery.removeAttr( elem, name );
|
||
} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
||
// IE<8 needs the *property* name
|
||
elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
|
||
|
||
// Use defaultChecked and defaultSelected for oldIE
|
||
} else {
|
||
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
|
||
}
|
||
|
||
return name;
|
||
}
|
||
};
|
||
|
||
// Retrieve booleans specially
|
||
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
|
||
|
||
var getter = attrHandle[ name ] || jQuery.find.attr;
|
||
|
||
attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
|
||
function( elem, name, isXML ) {
|
||
var ret, handle;
|
||
if ( !isXML ) {
|
||
// Avoid an infinite loop by temporarily removing this function from the getter
|
||
handle = attrHandle[ name ];
|
||
attrHandle[ name ] = ret;
|
||
ret = getter( elem, name, isXML ) != null ?
|
||
name.toLowerCase() :
|
||
null;
|
||
attrHandle[ name ] = handle;
|
||
}
|
||
return ret;
|
||
} :
|
||
function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem[ jQuery.camelCase( "default-" + name ) ] ?
|
||
name.toLowerCase() :
|
||
null;
|
||
}
|
||
};
|
||
});
|
||
|
||
// fix oldIE attroperties
|
||
if ( !getSetInput || !getSetAttribute ) {
|
||
jQuery.attrHooks.value = {
|
||
set: function( elem, value, name ) {
|
||
if ( jQuery.nodeName( elem, "input" ) ) {
|
||
// Does not return so that setAttribute is also used
|
||
elem.defaultValue = value;
|
||
} else {
|
||
// Use nodeHook if defined (#1954); otherwise setAttribute is fine
|
||
return nodeHook && nodeHook.set( elem, value, name );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// IE6/7 do not support getting/setting some attributes with get/setAttribute
|
||
if ( !getSetAttribute ) {
|
||
|
||
// Use this for any attribute in IE6/7
|
||
// This fixes almost every IE6/7 issue
|
||
nodeHook = {
|
||
set: function( elem, value, name ) {
|
||
// Set the existing or create a new attribute node
|
||
var ret = elem.getAttributeNode( name );
|
||
if ( !ret ) {
|
||
elem.setAttributeNode(
|
||
(ret = elem.ownerDocument.createAttribute( name ))
|
||
);
|
||
}
|
||
|
||
ret.value = value += "";
|
||
|
||
// Break association with cloned elements by also using setAttribute (#9646)
|
||
if ( name === "value" || value === elem.getAttribute( name ) ) {
|
||
return value;
|
||
}
|
||
}
|
||
};
|
||
|
||
// Some attributes are constructed with empty-string values when not defined
|
||
attrHandle.id = attrHandle.name = attrHandle.coords =
|
||
function( elem, name, isXML ) {
|
||
var ret;
|
||
if ( !isXML ) {
|
||
return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
|
||
ret.value :
|
||
null;
|
||
}
|
||
};
|
||
|
||
// Fixing value retrieval on a button requires this module
|
||
jQuery.valHooks.button = {
|
||
get: function( elem, name ) {
|
||
var ret = elem.getAttributeNode( name );
|
||
if ( ret && ret.specified ) {
|
||
return ret.value;
|
||
}
|
||
},
|
||
set: nodeHook.set
|
||
};
|
||
|
||
// Set contenteditable to false on removals(#10429)
|
||
// Setting to empty string throws an error as an invalid value
|
||
jQuery.attrHooks.contenteditable = {
|
||
set: function( elem, value, name ) {
|
||
nodeHook.set( elem, value === "" ? false : value, name );
|
||
}
|
||
};
|
||
|
||
// Set width and height to auto instead of 0 on empty string( Bug #8150 )
|
||
// This is for removals
|
||
jQuery.each([ "width", "height" ], function( i, name ) {
|
||
jQuery.attrHooks[ name ] = {
|
||
set: function( elem, value ) {
|
||
if ( value === "" ) {
|
||
elem.setAttribute( name, "auto" );
|
||
return value;
|
||
}
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
if ( !support.style ) {
|
||
jQuery.attrHooks.style = {
|
||
get: function( elem ) {
|
||
// Return undefined in the case of empty string
|
||
// Note: IE uppercases css property names, but if we were to .toLowerCase()
|
||
// .cssText, that would destroy case senstitivity in URL's, like in "background"
|
||
return elem.style.cssText || undefined;
|
||
},
|
||
set: function( elem, value ) {
|
||
return ( elem.style.cssText = value + "" );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
|
||
|
||
var rfocusable = /^(?:input|select|textarea|button|object)$/i,
|
||
rclickable = /^(?:a|area)$/i;
|
||
|
||
jQuery.fn.extend({
|
||
prop: function( name, value ) {
|
||
return access( this, jQuery.prop, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeProp: function( name ) {
|
||
name = jQuery.propFix[ name ] || name;
|
||
return this.each(function() {
|
||
// try/catch handles cases where IE balks (such as removing a property on window)
|
||
try {
|
||
this[ name ] = undefined;
|
||
delete this[ name ];
|
||
} catch( e ) {}
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
propFix: {
|
||
"for": "htmlFor",
|
||
"class": "className"
|
||
},
|
||
|
||
prop: function( elem, name, value ) {
|
||
var ret, hooks, notxml,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set properties on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
||
|
||
if ( notxml ) {
|
||
// Fix name and attach hooks
|
||
name = jQuery.propFix[ name ] || name;
|
||
hooks = jQuery.propHooks[ name ];
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
|
||
ret :
|
||
( elem[ name ] = value );
|
||
|
||
} else {
|
||
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
|
||
ret :
|
||
elem[ name ];
|
||
}
|
||
},
|
||
|
||
propHooks: {
|
||
tabIndex: {
|
||
get: function( elem ) {
|
||
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
|
||
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
|
||
// Use proper attribute retrieval(#12072)
|
||
var tabindex = jQuery.find.attr( elem, "tabindex" );
|
||
|
||
return tabindex ?
|
||
parseInt( tabindex, 10 ) :
|
||
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
||
0 :
|
||
-1;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Some attributes require a special call on IE
|
||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !support.hrefNormalized ) {
|
||
// href/src property should get the full normalized URL (#10299/#12915)
|
||
jQuery.each([ "href", "src" ], function( i, name ) {
|
||
jQuery.propHooks[ name ] = {
|
||
get: function( elem ) {
|
||
return elem.getAttribute( name, 4 );
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
// Support: Safari, IE9+
|
||
// mis-reports the default selected property of an option
|
||
// Accessing the parent's selectedIndex property fixes it
|
||
if ( !support.optSelected ) {
|
||
jQuery.propHooks.selected = {
|
||
get: function( elem ) {
|
||
var parent = elem.parentNode;
|
||
|
||
if ( parent ) {
|
||
parent.selectedIndex;
|
||
|
||
// Make sure that it also works with optgroups, see #5701
|
||
if ( parent.parentNode ) {
|
||
parent.parentNode.selectedIndex;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.each([
|
||
"tabIndex",
|
||
"readOnly",
|
||
"maxLength",
|
||
"cellSpacing",
|
||
"cellPadding",
|
||
"rowSpan",
|
||
"colSpan",
|
||
"useMap",
|
||
"frameBorder",
|
||
"contentEditable"
|
||
], function() {
|
||
jQuery.propFix[ this.toLowerCase() ] = this;
|
||
});
|
||
|
||
// IE6/7 call enctype encoding
|
||
if ( !support.enctype ) {
|
||
jQuery.propFix.enctype = "encoding";
|
||
}
|
||
|
||
|
||
|
||
|
||
var rclass = /[\t\r\n\f]/g;
|
||
|
||
jQuery.fn.extend({
|
||
addClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
i = 0,
|
||
len = this.length,
|
||
proceed = typeof value === "string" && value;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).addClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
|
||
if ( proceed ) {
|
||
// The disjunction here is for better compressibility (see removeClass)
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
" "
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||
cur += clazz + " ";
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = jQuery.trim( cur );
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
removeClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
i = 0,
|
||
len = this.length,
|
||
proceed = arguments.length === 0 || typeof value === "string" && value;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).removeClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
if ( proceed ) {
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
// This expression is here for better compressibility (see addClass)
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
""
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
// Remove *all* instances
|
||
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
|
||
cur = cur.replace( " " + clazz + " ", " " );
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = value ? jQuery.trim( cur ) : "";
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
toggleClass: function( value, stateVal ) {
|
||
var type = typeof value;
|
||
|
||
if ( typeof stateVal === "boolean" && type === "string" ) {
|
||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||
}
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( i ) {
|
||
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( type === "string" ) {
|
||
// toggle individual class names
|
||
var className,
|
||
i = 0,
|
||
self = jQuery( this ),
|
||
classNames = value.match( rnotwhite ) || [];
|
||
|
||
while ( (className = classNames[ i++ ]) ) {
|
||
// check each className given, space separated list
|
||
if ( self.hasClass( className ) ) {
|
||
self.removeClass( className );
|
||
} else {
|
||
self.addClass( className );
|
||
}
|
||
}
|
||
|
||
// Toggle whole class name
|
||
} else if ( type === strundefined || type === "boolean" ) {
|
||
if ( this.className ) {
|
||
// store className if set
|
||
jQuery._data( this, "__className__", this.className );
|
||
}
|
||
|
||
// If the element has a class name or if we're passed "false",
|
||
// then remove the whole classname (if there was one, the above saved it).
|
||
// Otherwise bring back whatever was previously saved (if anything),
|
||
// falling back to the empty string if nothing was stored.
|
||
this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
|
||
}
|
||
});
|
||
},
|
||
|
||
hasClass: function( selector ) {
|
||
var className = " " + selector + " ",
|
||
i = 0,
|
||
l = this.length;
|
||
for ( ; i < l; i++ ) {
|
||
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// Return jQuery for attributes-only inclusion
|
||
|
||
|
||
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
|
||
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
|
||
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
|
||
|
||
// Handle event binding
|
||
jQuery.fn[ name ] = function( data, fn ) {
|
||
return arguments.length > 0 ?
|
||
this.on( name, null, data, fn ) :
|
||
this.trigger( name );
|
||
};
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
hover: function( fnOver, fnOut ) {
|
||
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
||
},
|
||
|
||
bind: function( types, data, fn ) {
|
||
return this.on( types, null, data, fn );
|
||
},
|
||
unbind: function( types, fn ) {
|
||
return this.off( types, null, fn );
|
||
},
|
||
|
||
delegate: function( selector, types, data, fn ) {
|
||
return this.on( types, selector, data, fn );
|
||
},
|
||
undelegate: function( selector, types, fn ) {
|
||
// ( namespace ) or ( selector, types [, fn] )
|
||
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
|
||
}
|
||
});
|
||
|
||
|
||
var nonce = jQuery.now();
|
||
|
||
var rquery = (/\?/);
|
||
|
||
|
||
|
||
var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
|
||
|
||
jQuery.parseJSON = function( data ) {
|
||
// Attempt to parse using the native JSON parser first
|
||
if ( window.JSON && window.JSON.parse ) {
|
||
// Support: Android 2.3
|
||
// Workaround failure to string-cast null input
|
||
return window.JSON.parse( data + "" );
|
||
}
|
||
|
||
var requireNonComma,
|
||
depth = null,
|
||
str = jQuery.trim( data + "" );
|
||
|
||
// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
|
||
// after removing valid tokens
|
||
return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
|
||
|
||
// Force termination if we see a misplaced comma
|
||
if ( requireNonComma && comma ) {
|
||
depth = 0;
|
||
}
|
||
|
||
// Perform no more replacements after returning to outermost depth
|
||
if ( depth === 0 ) {
|
||
return token;
|
||
}
|
||
|
||
// Commas must not follow "[", "{", or ","
|
||
requireNonComma = open || comma;
|
||
|
||
// Determine new depth
|
||
// array/object open ("[" or "{"): depth += true - false (increment)
|
||
// array/object close ("]" or "}"): depth += false - true (decrement)
|
||
// other cases ("," or primitive): depth += true - true (numeric cast)
|
||
depth += !close - !open;
|
||
|
||
// Remove this token
|
||
return "";
|
||
}) ) ?
|
||
( Function( "return " + str ) )() :
|
||
jQuery.error( "Invalid JSON: " + data );
|
||
};
|
||
|
||
|
||
// Cross-browser xml parsing
|
||
jQuery.parseXML = function( data ) {
|
||
var xml, tmp;
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
try {
|
||
if ( window.DOMParser ) { // Standard
|
||
tmp = new DOMParser();
|
||
xml = tmp.parseFromString( data, "text/xml" );
|
||
} else { // IE
|
||
xml = new ActiveXObject( "Microsoft.XMLDOM" );
|
||
xml.async = "false";
|
||
xml.loadXML( data );
|
||
}
|
||
} catch( e ) {
|
||
xml = undefined;
|
||
}
|
||
if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
|
||
jQuery.error( "Invalid XML: " + data );
|
||
}
|
||
return xml;
|
||
};
|
||
|
||
|
||
var
|
||
// Document location
|
||
ajaxLocParts,
|
||
ajaxLocation,
|
||
|
||
rhash = /#.*$/,
|
||
rts = /([?&])_=[^&]*/,
|
||
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
|
||
// #7653, #8125, #8152: local protocol detection
|
||
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
||
rnoContent = /^(?:GET|HEAD)$/,
|
||
rprotocol = /^\/\//,
|
||
rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
|
||
|
||
/* Prefilters
|
||
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
|
||
* 2) These are called:
|
||
* - BEFORE asking for a transport
|
||
* - AFTER param serialization (s.data is a string if s.processData is true)
|
||
* 3) key is the dataType
|
||
* 4) the catchall symbol "*" can be used
|
||
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
||
*/
|
||
prefilters = {},
|
||
|
||
/* Transports bindings
|
||
* 1) key is the dataType
|
||
* 2) the catchall symbol "*" can be used
|
||
* 3) selection will start with transport dataType and THEN go to "*" if needed
|
||
*/
|
||
transports = {},
|
||
|
||
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
||
allTypes = "*/".concat("*");
|
||
|
||
// #8138, IE may throw an exception when accessing
|
||
// a field from window.location if document.domain has been set
|
||
try {
|
||
ajaxLocation = location.href;
|
||
} catch( e ) {
|
||
// Use the href attribute of an A element
|
||
// since IE will modify it given document.location
|
||
ajaxLocation = document.createElement( "a" );
|
||
ajaxLocation.href = "";
|
||
ajaxLocation = ajaxLocation.href;
|
||
}
|
||
|
||
// Segment location into parts
|
||
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
|
||
|
||
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
|
||
function addToPrefiltersOrTransports( structure ) {
|
||
|
||
// dataTypeExpression is optional and defaults to "*"
|
||
return function( dataTypeExpression, func ) {
|
||
|
||
if ( typeof dataTypeExpression !== "string" ) {
|
||
func = dataTypeExpression;
|
||
dataTypeExpression = "*";
|
||
}
|
||
|
||
var dataType,
|
||
i = 0,
|
||
dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
|
||
|
||
if ( jQuery.isFunction( func ) ) {
|
||
// For each dataType in the dataTypeExpression
|
||
while ( (dataType = dataTypes[i++]) ) {
|
||
// Prepend if requested
|
||
if ( dataType.charAt( 0 ) === "+" ) {
|
||
dataType = dataType.slice( 1 ) || "*";
|
||
(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
|
||
|
||
// Otherwise append
|
||
} else {
|
||
(structure[ dataType ] = structure[ dataType ] || []).push( func );
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// Base inspection function for prefilters and transports
|
||
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
|
||
|
||
var inspected = {},
|
||
seekingTransport = ( structure === transports );
|
||
|
||
function inspect( dataType ) {
|
||
var selected;
|
||
inspected[ dataType ] = true;
|
||
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
|
||
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
|
||
if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
|
||
options.dataTypes.unshift( dataTypeOrTransport );
|
||
inspect( dataTypeOrTransport );
|
||
return false;
|
||
} else if ( seekingTransport ) {
|
||
return !( selected = dataTypeOrTransport );
|
||
}
|
||
});
|
||
return selected;
|
||
}
|
||
|
||
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
|
||
}
|
||
|
||
// A special extend for ajax options
|
||
// that takes "flat" options (not to be deep extended)
|
||
// Fixes #9887
|
||
function ajaxExtend( target, src ) {
|
||
var deep, key,
|
||
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
||
|
||
for ( key in src ) {
|
||
if ( src[ key ] !== undefined ) {
|
||
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
|
||
}
|
||
}
|
||
if ( deep ) {
|
||
jQuery.extend( true, target, deep );
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
/* Handles responses to an ajax request:
|
||
* - finds the right dataType (mediates between content-type and expected dataType)
|
||
* - returns the corresponding response
|
||
*/
|
||
function ajaxHandleResponses( s, jqXHR, responses ) {
|
||
var firstDataType, ct, finalDataType, type,
|
||
contents = s.contents,
|
||
dataTypes = s.dataTypes;
|
||
|
||
// Remove auto dataType and get content-type in the process
|
||
while ( dataTypes[ 0 ] === "*" ) {
|
||
dataTypes.shift();
|
||
if ( ct === undefined ) {
|
||
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
|
||
}
|
||
}
|
||
|
||
// Check if we're dealing with a known content-type
|
||
if ( ct ) {
|
||
for ( type in contents ) {
|
||
if ( contents[ type ] && contents[ type ].test( ct ) ) {
|
||
dataTypes.unshift( type );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check to see if we have a response for the expected dataType
|
||
if ( dataTypes[ 0 ] in responses ) {
|
||
finalDataType = dataTypes[ 0 ];
|
||
} else {
|
||
// Try convertible dataTypes
|
||
for ( type in responses ) {
|
||
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
|
||
finalDataType = type;
|
||
break;
|
||
}
|
||
if ( !firstDataType ) {
|
||
firstDataType = type;
|
||
}
|
||
}
|
||
// Or just use first one
|
||
finalDataType = finalDataType || firstDataType;
|
||
}
|
||
|
||
// If we found a dataType
|
||
// We add the dataType to the list if needed
|
||
// and return the corresponding response
|
||
if ( finalDataType ) {
|
||
if ( finalDataType !== dataTypes[ 0 ] ) {
|
||
dataTypes.unshift( finalDataType );
|
||
}
|
||
return responses[ finalDataType ];
|
||
}
|
||
}
|
||
|
||
/* Chain conversions given the request and the original response
|
||
* Also sets the responseXXX fields on the jqXHR instance
|
||
*/
|
||
function ajaxConvert( s, response, jqXHR, isSuccess ) {
|
||
var conv2, current, conv, tmp, prev,
|
||
converters = {},
|
||
// Work with a copy of dataTypes in case we need to modify it for conversion
|
||
dataTypes = s.dataTypes.slice();
|
||
|
||
// Create converters map with lowercased keys
|
||
if ( dataTypes[ 1 ] ) {
|
||
for ( conv in s.converters ) {
|
||
converters[ conv.toLowerCase() ] = s.converters[ conv ];
|
||
}
|
||
}
|
||
|
||
current = dataTypes.shift();
|
||
|
||
// Convert to each sequential dataType
|
||
while ( current ) {
|
||
|
||
if ( s.responseFields[ current ] ) {
|
||
jqXHR[ s.responseFields[ current ] ] = response;
|
||
}
|
||
|
||
// Apply the dataFilter if provided
|
||
if ( !prev && isSuccess && s.dataFilter ) {
|
||
response = s.dataFilter( response, s.dataType );
|
||
}
|
||
|
||
prev = current;
|
||
current = dataTypes.shift();
|
||
|
||
if ( current ) {
|
||
|
||
// There's only work to do if current dataType is non-auto
|
||
if ( current === "*" ) {
|
||
|
||
current = prev;
|
||
|
||
// Convert response if prev dataType is non-auto and differs from current
|
||
} else if ( prev !== "*" && prev !== current ) {
|
||
|
||
// Seek a direct converter
|
||
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
|
||
|
||
// If none found, seek a pair
|
||
if ( !conv ) {
|
||
for ( conv2 in converters ) {
|
||
|
||
// If conv2 outputs current
|
||
tmp = conv2.split( " " );
|
||
if ( tmp[ 1 ] === current ) {
|
||
|
||
// If prev can be converted to accepted input
|
||
conv = converters[ prev + " " + tmp[ 0 ] ] ||
|
||
converters[ "* " + tmp[ 0 ] ];
|
||
if ( conv ) {
|
||
// Condense equivalence converters
|
||
if ( conv === true ) {
|
||
conv = converters[ conv2 ];
|
||
|
||
// Otherwise, insert the intermediate dataType
|
||
} else if ( converters[ conv2 ] !== true ) {
|
||
current = tmp[ 0 ];
|
||
dataTypes.unshift( tmp[ 1 ] );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply converter (if not an equivalence)
|
||
if ( conv !== true ) {
|
||
|
||
// Unless errors are allowed to bubble, catch and return them
|
||
if ( conv && s[ "throws" ] ) {
|
||
response = conv( response );
|
||
} else {
|
||
try {
|
||
response = conv( response );
|
||
} catch ( e ) {
|
||
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return { state: "success", data: response };
|
||
}
|
||
|
||
jQuery.extend({
|
||
|
||
// Counter for holding the number of active queries
|
||
active: 0,
|
||
|
||
// Last-Modified header cache for next request
|
||
lastModified: {},
|
||
etag: {},
|
||
|
||
ajaxSettings: {
|
||
url: ajaxLocation,
|
||
type: "GET",
|
||
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
|
||
global: true,
|
||
processData: true,
|
||
async: true,
|
||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||
/*
|
||
timeout: 0,
|
||
data: null,
|
||
dataType: null,
|
||
username: null,
|
||
password: null,
|
||
cache: null,
|
||
throws: false,
|
||
traditional: false,
|
||
headers: {},
|
||
*/
|
||
|
||
accepts: {
|
||
"*": allTypes,
|
||
text: "text/plain",
|
||
html: "text/html",
|
||
xml: "application/xml, text/xml",
|
||
json: "application/json, text/javascript"
|
||
},
|
||
|
||
contents: {
|
||
xml: /xml/,
|
||
html: /html/,
|
||
json: /json/
|
||
},
|
||
|
||
responseFields: {
|
||
xml: "responseXML",
|
||
text: "responseText",
|
||
json: "responseJSON"
|
||
},
|
||
|
||
// Data converters
|
||
// Keys separate source (or catchall "*") and destination types with a single space
|
||
converters: {
|
||
|
||
// Convert anything to text
|
||
"* text": String,
|
||
|
||
// Text to html (true = no transformation)
|
||
"text html": true,
|
||
|
||
// Evaluate text as a json expression
|
||
"text json": jQuery.parseJSON,
|
||
|
||
// Parse text as xml
|
||
"text xml": jQuery.parseXML
|
||
},
|
||
|
||
// For options that shouldn't be deep extended:
|
||
// you can add your own custom options here if
|
||
// and when you create one that shouldn't be
|
||
// deep extended (see ajaxExtend)
|
||
flatOptions: {
|
||
url: true,
|
||
context: true
|
||
}
|
||
},
|
||
|
||
// Creates a full fledged settings object into target
|
||
// with both ajaxSettings and settings fields.
|
||
// If target is omitted, writes into ajaxSettings.
|
||
ajaxSetup: function( target, settings ) {
|
||
return settings ?
|
||
|
||
// Building a settings object
|
||
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
|
||
|
||
// Extending ajaxSettings
|
||
ajaxExtend( jQuery.ajaxSettings, target );
|
||
},
|
||
|
||
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
|
||
ajaxTransport: addToPrefiltersOrTransports( transports ),
|
||
|
||
// Main method
|
||
ajax: function( url, options ) {
|
||
|
||
// If url is an object, simulate pre-1.5 signature
|
||
if ( typeof url === "object" ) {
|
||
options = url;
|
||
url = undefined;
|
||
}
|
||
|
||
// Force options to be an object
|
||
options = options || {};
|
||
|
||
var // Cross-domain detection vars
|
||
parts,
|
||
// Loop variable
|
||
i,
|
||
// URL without anti-cache param
|
||
cacheURL,
|
||
// Response headers as string
|
||
responseHeadersString,
|
||
// timeout handle
|
||
timeoutTimer,
|
||
|
||
// To know if global events are to be dispatched
|
||
fireGlobals,
|
||
|
||
transport,
|
||
// Response headers
|
||
responseHeaders,
|
||
// Create the final options object
|
||
s = jQuery.ajaxSetup( {}, options ),
|
||
// Callbacks context
|
||
callbackContext = s.context || s,
|
||
// Context for global events is callbackContext if it is a DOM node or jQuery collection
|
||
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
|
||
jQuery( callbackContext ) :
|
||
jQuery.event,
|
||
// Deferreds
|
||
deferred = jQuery.Deferred(),
|
||
completeDeferred = jQuery.Callbacks("once memory"),
|
||
// Status-dependent callbacks
|
||
statusCode = s.statusCode || {},
|
||
// Headers (they are sent all at once)
|
||
requestHeaders = {},
|
||
requestHeadersNames = {},
|
||
// The jqXHR state
|
||
state = 0,
|
||
// Default abort message
|
||
strAbort = "canceled",
|
||
// Fake xhr
|
||
jqXHR = {
|
||
readyState: 0,
|
||
|
||
// Builds headers hashtable if needed
|
||
getResponseHeader: function( key ) {
|
||
var match;
|
||
if ( state === 2 ) {
|
||
if ( !responseHeaders ) {
|
||
responseHeaders = {};
|
||
while ( (match = rheaders.exec( responseHeadersString )) ) {
|
||
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
|
||
}
|
||
}
|
||
match = responseHeaders[ key.toLowerCase() ];
|
||
}
|
||
return match == null ? null : match;
|
||
},
|
||
|
||
// Raw string
|
||
getAllResponseHeaders: function() {
|
||
return state === 2 ? responseHeadersString : null;
|
||
},
|
||
|
||
// Caches the header
|
||
setRequestHeader: function( name, value ) {
|
||
var lname = name.toLowerCase();
|
||
if ( !state ) {
|
||
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
|
||
requestHeaders[ name ] = value;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Overrides response content-type header
|
||
overrideMimeType: function( type ) {
|
||
if ( !state ) {
|
||
s.mimeType = type;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Status-dependent callbacks
|
||
statusCode: function( map ) {
|
||
var code;
|
||
if ( map ) {
|
||
if ( state < 2 ) {
|
||
for ( code in map ) {
|
||
// Lazy-add the new callback in a way that preserves old ones
|
||
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
|
||
}
|
||
} else {
|
||
// Execute the appropriate callbacks
|
||
jqXHR.always( map[ jqXHR.status ] );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Cancel the request
|
||
abort: function( statusText ) {
|
||
var finalText = statusText || strAbort;
|
||
if ( transport ) {
|
||
transport.abort( finalText );
|
||
}
|
||
done( 0, finalText );
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// Attach deferreds
|
||
deferred.promise( jqXHR ).complete = completeDeferred.add;
|
||
jqXHR.success = jqXHR.done;
|
||
jqXHR.error = jqXHR.fail;
|
||
|
||
// Remove hash character (#7531: and string promotion)
|
||
// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
|
||
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
||
// We also use the url parameter if available
|
||
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
|
||
|
||
// Alias method option to type as per ticket #12004
|
||
s.type = options.method || options.type || s.method || s.type;
|
||
|
||
// Extract dataTypes list
|
||
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
|
||
|
||
// A cross-domain request is in order when we have a protocol:host:port mismatch
|
||
if ( s.crossDomain == null ) {
|
||
parts = rurl.exec( s.url.toLowerCase() );
|
||
s.crossDomain = !!( parts &&
|
||
( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
|
||
( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
|
||
( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
|
||
);
|
||
}
|
||
|
||
// Convert data if not already a string
|
||
if ( s.data && s.processData && typeof s.data !== "string" ) {
|
||
s.data = jQuery.param( s.data, s.traditional );
|
||
}
|
||
|
||
// Apply prefilters
|
||
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
|
||
|
||
// If request was aborted inside a prefilter, stop there
|
||
if ( state === 2 ) {
|
||
return jqXHR;
|
||
}
|
||
|
||
// We can fire global events as of now if asked to
|
||
fireGlobals = s.global;
|
||
|
||
// Watch for a new set of requests
|
||
if ( fireGlobals && jQuery.active++ === 0 ) {
|
||
jQuery.event.trigger("ajaxStart");
|
||
}
|
||
|
||
// Uppercase the type
|
||
s.type = s.type.toUpperCase();
|
||
|
||
// Determine if request has content
|
||
s.hasContent = !rnoContent.test( s.type );
|
||
|
||
// Save the URL in case we're toying with the If-Modified-Since
|
||
// and/or If-None-Match header later on
|
||
cacheURL = s.url;
|
||
|
||
// More options handling for requests with no content
|
||
if ( !s.hasContent ) {
|
||
|
||
// If data is available, append data to url
|
||
if ( s.data ) {
|
||
cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
|
||
// #9682: remove data so that it's not used in an eventual retry
|
||
delete s.data;
|
||
}
|
||
|
||
// Add anti-cache in url if needed
|
||
if ( s.cache === false ) {
|
||
s.url = rts.test( cacheURL ) ?
|
||
|
||
// If there is already a '_' parameter, set its value
|
||
cacheURL.replace( rts, "$1_=" + nonce++ ) :
|
||
|
||
// Otherwise add one to the end
|
||
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
|
||
}
|
||
}
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
if ( jQuery.lastModified[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
|
||
}
|
||
if ( jQuery.etag[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
|
||
}
|
||
}
|
||
|
||
// Set the correct header, if data is being sent
|
||
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
|
||
jqXHR.setRequestHeader( "Content-Type", s.contentType );
|
||
}
|
||
|
||
// Set the Accepts header for the server, depending on the dataType
|
||
jqXHR.setRequestHeader(
|
||
"Accept",
|
||
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
|
||
s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
|
||
s.accepts[ "*" ]
|
||
);
|
||
|
||
// Check for headers option
|
||
for ( i in s.headers ) {
|
||
jqXHR.setRequestHeader( i, s.headers[ i ] );
|
||
}
|
||
|
||
// Allow custom headers/mimetypes and early abort
|
||
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
|
||
// Abort if not done already and return
|
||
return jqXHR.abort();
|
||
}
|
||
|
||
// aborting is no longer a cancellation
|
||
strAbort = "abort";
|
||
|
||
// Install callbacks on deferreds
|
||
for ( i in { success: 1, error: 1, complete: 1 } ) {
|
||
jqXHR[ i ]( s[ i ] );
|
||
}
|
||
|
||
// Get transport
|
||
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
|
||
|
||
// If no transport, we auto-abort
|
||
if ( !transport ) {
|
||
done( -1, "No Transport" );
|
||
} else {
|
||
jqXHR.readyState = 1;
|
||
|
||
// Send global event
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
|
||
}
|
||
// Timeout
|
||
if ( s.async && s.timeout > 0 ) {
|
||
timeoutTimer = setTimeout(function() {
|
||
jqXHR.abort("timeout");
|
||
}, s.timeout );
|
||
}
|
||
|
||
try {
|
||
state = 1;
|
||
transport.send( requestHeaders, done );
|
||
} catch ( e ) {
|
||
// Propagate exception as error if not done
|
||
if ( state < 2 ) {
|
||
done( -1, e );
|
||
// Simply rethrow otherwise
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Callback for when everything is done
|
||
function done( status, nativeStatusText, responses, headers ) {
|
||
var isSuccess, success, error, response, modified,
|
||
statusText = nativeStatusText;
|
||
|
||
// Called once
|
||
if ( state === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// State is "done" now
|
||
state = 2;
|
||
|
||
// Clear timeout if it exists
|
||
if ( timeoutTimer ) {
|
||
clearTimeout( timeoutTimer );
|
||
}
|
||
|
||
// Dereference transport for early garbage collection
|
||
// (no matter how long the jqXHR object will be used)
|
||
transport = undefined;
|
||
|
||
// Cache response headers
|
||
responseHeadersString = headers || "";
|
||
|
||
// Set readyState
|
||
jqXHR.readyState = status > 0 ? 4 : 0;
|
||
|
||
// Determine if successful
|
||
isSuccess = status >= 200 && status < 300 || status === 304;
|
||
|
||
// Get response data
|
||
if ( responses ) {
|
||
response = ajaxHandleResponses( s, jqXHR, responses );
|
||
}
|
||
|
||
// Convert no matter what (that way responseXXX fields are always set)
|
||
response = ajaxConvert( s, response, jqXHR, isSuccess );
|
||
|
||
// If successful, handle type chaining
|
||
if ( isSuccess ) {
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
modified = jqXHR.getResponseHeader("Last-Modified");
|
||
if ( modified ) {
|
||
jQuery.lastModified[ cacheURL ] = modified;
|
||
}
|
||
modified = jqXHR.getResponseHeader("etag");
|
||
if ( modified ) {
|
||
jQuery.etag[ cacheURL ] = modified;
|
||
}
|
||
}
|
||
|
||
// if no content
|
||
if ( status === 204 || s.type === "HEAD" ) {
|
||
statusText = "nocontent";
|
||
|
||
// if not modified
|
||
} else if ( status === 304 ) {
|
||
statusText = "notmodified";
|
||
|
||
// If we have data, let's convert it
|
||
} else {
|
||
statusText = response.state;
|
||
success = response.data;
|
||
error = response.error;
|
||
isSuccess = !error;
|
||
}
|
||
} else {
|
||
// We extract error from statusText
|
||
// then normalize statusText and status for non-aborts
|
||
error = statusText;
|
||
if ( status || !statusText ) {
|
||
statusText = "error";
|
||
if ( status < 0 ) {
|
||
status = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set data for the fake xhr object
|
||
jqXHR.status = status;
|
||
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
|
||
|
||
// Success/Error
|
||
if ( isSuccess ) {
|
||
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
|
||
} else {
|
||
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
|
||
}
|
||
|
||
// Status-dependent callbacks
|
||
jqXHR.statusCode( statusCode );
|
||
statusCode = undefined;
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
|
||
[ jqXHR, s, isSuccess ? success : error ] );
|
||
}
|
||
|
||
// Complete
|
||
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
|
||
// Handle the global AJAX counter
|
||
if ( !( --jQuery.active ) ) {
|
||
jQuery.event.trigger("ajaxStop");
|
||
}
|
||
}
|
||
}
|
||
|
||
return jqXHR;
|
||
},
|
||
|
||
getJSON: function( url, data, callback ) {
|
||
return jQuery.get( url, data, callback, "json" );
|
||
},
|
||
|
||
getScript: function( url, callback ) {
|
||
return jQuery.get( url, undefined, callback, "script" );
|
||
}
|
||
});
|
||
|
||
jQuery.each( [ "get", "post" ], function( i, method ) {
|
||
jQuery[ method ] = function( url, data, callback, type ) {
|
||
// shift arguments if data argument was omitted
|
||
if ( jQuery.isFunction( data ) ) {
|
||
type = type || callback;
|
||
callback = data;
|
||
data = undefined;
|
||
}
|
||
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: method,
|
||
dataType: type,
|
||
data: data,
|
||
success: callback
|
||
});
|
||
};
|
||
});
|
||
|
||
// Attach a bunch of functions for handling common AJAX events
|
||
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
|
||
jQuery.fn[ type ] = function( fn ) {
|
||
return this.on( type, fn );
|
||
};
|
||
});
|
||
|
||
|
||
jQuery._evalUrl = function( url ) {
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: "GET",
|
||
dataType: "script",
|
||
async: false,
|
||
global: false,
|
||
"throws": true
|
||
});
|
||
};
|
||
|
||
|
||
jQuery.fn.extend({
|
||
wrapAll: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function(i) {
|
||
jQuery(this).wrapAll( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
if ( this[0] ) {
|
||
// The elements to wrap the target around
|
||
var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
|
||
|
||
if ( this[0].parentNode ) {
|
||
wrap.insertBefore( this[0] );
|
||
}
|
||
|
||
wrap.map(function() {
|
||
var elem = this;
|
||
|
||
while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
|
||
elem = elem.firstChild;
|
||
}
|
||
|
||
return elem;
|
||
}).append( this );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
wrapInner: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function(i) {
|
||
jQuery(this).wrapInner( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
var self = jQuery( this ),
|
||
contents = self.contents();
|
||
|
||
if ( contents.length ) {
|
||
contents.wrapAll( html );
|
||
|
||
} else {
|
||
self.append( html );
|
||
}
|
||
});
|
||
},
|
||
|
||
wrap: function( html ) {
|
||
var isFunction = jQuery.isFunction( html );
|
||
|
||
return this.each(function(i) {
|
||
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
|
||
});
|
||
},
|
||
|
||
unwrap: function() {
|
||
return this.parent().each(function() {
|
||
if ( !jQuery.nodeName( this, "body" ) ) {
|
||
jQuery( this ).replaceWith( this.childNodes );
|
||
}
|
||
}).end();
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.expr.filters.hidden = function( elem ) {
|
||
// Support: Opera <= 12.12
|
||
// Opera reports offsetWidths and offsetHeights less than zero on some elements
|
||
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
|
||
(!support.reliableHiddenOffsets() &&
|
||
((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
|
||
};
|
||
|
||
jQuery.expr.filters.visible = function( elem ) {
|
||
return !jQuery.expr.filters.hidden( elem );
|
||
};
|
||
|
||
|
||
|
||
|
||
var r20 = /%20/g,
|
||
rbracket = /\[\]$/,
|
||
rCRLF = /\r?\n/g,
|
||
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
|
||
rsubmittable = /^(?:input|select|textarea|keygen)/i;
|
||
|
||
function buildParams( prefix, obj, traditional, add ) {
|
||
var name;
|
||
|
||
if ( jQuery.isArray( obj ) ) {
|
||
// Serialize array item.
|
||
jQuery.each( obj, function( i, v ) {
|
||
if ( traditional || rbracket.test( prefix ) ) {
|
||
// Treat each array item as a scalar.
|
||
add( prefix, v );
|
||
|
||
} else {
|
||
// Item is non-scalar (array or object), encode its numeric index.
|
||
buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
|
||
}
|
||
});
|
||
|
||
} else if ( !traditional && jQuery.type( obj ) === "object" ) {
|
||
// Serialize object item.
|
||
for ( name in obj ) {
|
||
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
|
||
}
|
||
|
||
} else {
|
||
// Serialize scalar item.
|
||
add( prefix, obj );
|
||
}
|
||
}
|
||
|
||
// Serialize an array of form elements or a set of
|
||
// key/values into a query string
|
||
jQuery.param = function( a, traditional ) {
|
||
var prefix,
|
||
s = [],
|
||
add = function( key, value ) {
|
||
// If value is a function, invoke it and return its value
|
||
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
|
||
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
|
||
};
|
||
|
||
// Set traditional to true for jQuery <= 1.3.2 behavior.
|
||
if ( traditional === undefined ) {
|
||
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
|
||
}
|
||
|
||
// If an array was passed in, assume that it is an array of form elements.
|
||
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
|
||
// Serialize the form elements
|
||
jQuery.each( a, function() {
|
||
add( this.name, this.value );
|
||
});
|
||
|
||
} else {
|
||
// If traditional, encode the "old" way (the way 1.3.2 or older
|
||
// did it), otherwise encode params recursively.
|
||
for ( prefix in a ) {
|
||
buildParams( prefix, a[ prefix ], traditional, add );
|
||
}
|
||
}
|
||
|
||
// Return the resulting serialization
|
||
return s.join( "&" ).replace( r20, "+" );
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
serialize: function() {
|
||
return jQuery.param( this.serializeArray() );
|
||
},
|
||
serializeArray: function() {
|
||
return this.map(function() {
|
||
// Can add propHook for "elements" to filter or add form elements
|
||
var elements = jQuery.prop( this, "elements" );
|
||
return elements ? jQuery.makeArray( elements ) : this;
|
||
})
|
||
.filter(function() {
|
||
var type = this.type;
|
||
// Use .is(":disabled") so that fieldset[disabled] works
|
||
return this.name && !jQuery( this ).is( ":disabled" ) &&
|
||
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
|
||
( this.checked || !rcheckableType.test( type ) );
|
||
})
|
||
.map(function( i, elem ) {
|
||
var val = jQuery( this ).val();
|
||
|
||
return val == null ?
|
||
null :
|
||
jQuery.isArray( val ) ?
|
||
jQuery.map( val, function( val ) {
|
||
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}) :
|
||
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}).get();
|
||
}
|
||
});
|
||
|
||
|
||
// Create the request object
|
||
// (This is still attached to ajaxSettings for backward compatibility)
|
||
jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
|
||
// Support: IE6+
|
||
function() {
|
||
|
||
// XHR cannot access local files, always use ActiveX for that case
|
||
return !this.isLocal &&
|
||
|
||
// Support: IE7-8
|
||
// oldIE XHR does not support non-RFC2616 methods (#13240)
|
||
// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
|
||
// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
|
||
// Although this check for six methods instead of eight
|
||
// since IE also does not support "trace" and "connect"
|
||
/^(get|post|head|put|delete|options)$/i.test( this.type ) &&
|
||
|
||
createStandardXHR() || createActiveXHR();
|
||
} :
|
||
// For all other browsers, use the standard XMLHttpRequest object
|
||
createStandardXHR;
|
||
|
||
var xhrId = 0,
|
||
xhrCallbacks = {},
|
||
xhrSupported = jQuery.ajaxSettings.xhr();
|
||
|
||
// Support: IE<10
|
||
// Open requests must be manually aborted on unload (#5280)
|
||
if ( window.ActiveXObject ) {
|
||
jQuery( window ).on( "unload", function() {
|
||
for ( var key in xhrCallbacks ) {
|
||
xhrCallbacks[ key ]( undefined, true );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Determine support properties
|
||
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
|
||
xhrSupported = support.ajax = !!xhrSupported;
|
||
|
||
// Create transport if the browser can provide an xhr
|
||
if ( xhrSupported ) {
|
||
|
||
jQuery.ajaxTransport(function( options ) {
|
||
// Cross domain only allowed if supported through XMLHttpRequest
|
||
if ( !options.crossDomain || support.cors ) {
|
||
|
||
var callback;
|
||
|
||
return {
|
||
send: function( headers, complete ) {
|
||
var i,
|
||
xhr = options.xhr(),
|
||
id = ++xhrId;
|
||
|
||
// Open the socket
|
||
xhr.open( options.type, options.url, options.async, options.username, options.password );
|
||
|
||
// Apply custom fields if provided
|
||
if ( options.xhrFields ) {
|
||
for ( i in options.xhrFields ) {
|
||
xhr[ i ] = options.xhrFields[ i ];
|
||
}
|
||
}
|
||
|
||
// Override mime type if needed
|
||
if ( options.mimeType && xhr.overrideMimeType ) {
|
||
xhr.overrideMimeType( options.mimeType );
|
||
}
|
||
|
||
// X-Requested-With header
|
||
// For cross-domain requests, seeing as conditions for a preflight are
|
||
// akin to a jigsaw puzzle, we simply never set it to be sure.
|
||
// (it can always be set on a per-request basis or even using ajaxSetup)
|
||
// For same-domain requests, won't change header if already provided.
|
||
if ( !options.crossDomain && !headers["X-Requested-With"] ) {
|
||
headers["X-Requested-With"] = "XMLHttpRequest";
|
||
}
|
||
|
||
// Set headers
|
||
for ( i in headers ) {
|
||
// Support: IE<9
|
||
// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
|
||
// request header to a null-value.
|
||
//
|
||
// To keep consistent with other XHR implementations, cast the value
|
||
// to string and ignore `undefined`.
|
||
if ( headers[ i ] !== undefined ) {
|
||
xhr.setRequestHeader( i, headers[ i ] + "" );
|
||
}
|
||
}
|
||
|
||
// Do send the request
|
||
// This may raise an exception which is actually
|
||
// handled in jQuery.ajax (so no try/catch here)
|
||
xhr.send( ( options.hasContent && options.data ) || null );
|
||
|
||
// Listener
|
||
callback = function( _, isAbort ) {
|
||
var status, statusText, responses;
|
||
|
||
// Was never called and is aborted or complete
|
||
if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
|
||
// Clean up
|
||
delete xhrCallbacks[ id ];
|
||
callback = undefined;
|
||
xhr.onreadystatechange = jQuery.noop;
|
||
|
||
// Abort manually if needed
|
||
if ( isAbort ) {
|
||
if ( xhr.readyState !== 4 ) {
|
||
xhr.abort();
|
||
}
|
||
} else {
|
||
responses = {};
|
||
status = xhr.status;
|
||
|
||
// Support: IE<10
|
||
// Accessing binary-data responseText throws an exception
|
||
// (#11426)
|
||
if ( typeof xhr.responseText === "string" ) {
|
||
responses.text = xhr.responseText;
|
||
}
|
||
|
||
// Firefox throws an exception when accessing
|
||
// statusText for faulty cross-domain requests
|
||
try {
|
||
statusText = xhr.statusText;
|
||
} catch( e ) {
|
||
// We normalize with Webkit giving an empty statusText
|
||
statusText = "";
|
||
}
|
||
|
||
// Filter status for non standard behaviors
|
||
|
||
// If the request is local and we have data: assume a success
|
||
// (success with no data won't get notified, that's the best we
|
||
// can do given current implementations)
|
||
if ( !status && options.isLocal && !options.crossDomain ) {
|
||
status = responses.text ? 200 : 404;
|
||
// IE - #1450: sometimes returns 1223 when it should be 204
|
||
} else if ( status === 1223 ) {
|
||
status = 204;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call complete if needed
|
||
if ( responses ) {
|
||
complete( status, statusText, responses, xhr.getAllResponseHeaders() );
|
||
}
|
||
};
|
||
|
||
if ( !options.async ) {
|
||
// if we're in sync mode we fire the callback
|
||
callback();
|
||
} else if ( xhr.readyState === 4 ) {
|
||
// (IE6 & IE7) if it's in cache and has been
|
||
// retrieved directly we need to fire the callback
|
||
setTimeout( callback );
|
||
} else {
|
||
// Add to the list of active xhr callbacks
|
||
xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
|
||
}
|
||
},
|
||
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback( undefined, true );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
}
|
||
|
||
// Functions to create xhrs
|
||
function createStandardXHR() {
|
||
try {
|
||
return new window.XMLHttpRequest();
|
||
} catch( e ) {}
|
||
}
|
||
|
||
function createActiveXHR() {
|
||
try {
|
||
return new window.ActiveXObject( "Microsoft.XMLHTTP" );
|
||
} catch( e ) {}
|
||
}
|
||
|
||
|
||
|
||
|
||
// Install script dataType
|
||
jQuery.ajaxSetup({
|
||
accepts: {
|
||
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
|
||
},
|
||
contents: {
|
||
script: /(?:java|ecma)script/
|
||
},
|
||
converters: {
|
||
"text script": function( text ) {
|
||
jQuery.globalEval( text );
|
||
return text;
|
||
}
|
||
}
|
||
});
|
||
|
||
// Handle cache's special case and global
|
||
jQuery.ajaxPrefilter( "script", function( s ) {
|
||
if ( s.cache === undefined ) {
|
||
s.cache = false;
|
||
}
|
||
if ( s.crossDomain ) {
|
||
s.type = "GET";
|
||
s.global = false;
|
||
}
|
||
});
|
||
|
||
// Bind script tag hack transport
|
||
jQuery.ajaxTransport( "script", function(s) {
|
||
|
||
// This transport only deals with cross domain requests
|
||
if ( s.crossDomain ) {
|
||
|
||
var script,
|
||
head = document.head || jQuery("head")[0] || document.documentElement;
|
||
|
||
return {
|
||
|
||
send: function( _, callback ) {
|
||
|
||
script = document.createElement("script");
|
||
|
||
script.async = true;
|
||
|
||
if ( s.scriptCharset ) {
|
||
script.charset = s.scriptCharset;
|
||
}
|
||
|
||
script.src = s.url;
|
||
|
||
// Attach handlers for all browsers
|
||
script.onload = script.onreadystatechange = function( _, isAbort ) {
|
||
|
||
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
||
|
||
// Handle memory leak in IE
|
||
script.onload = script.onreadystatechange = null;
|
||
|
||
// Remove the script
|
||
if ( script.parentNode ) {
|
||
script.parentNode.removeChild( script );
|
||
}
|
||
|
||
// Dereference the script
|
||
script = null;
|
||
|
||
// Callback if not abort
|
||
if ( !isAbort ) {
|
||
callback( 200, "success" );
|
||
}
|
||
}
|
||
};
|
||
|
||
// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
|
||
// Use native DOM manipulation to avoid our domManip AJAX trickery
|
||
head.insertBefore( script, head.firstChild );
|
||
},
|
||
|
||
abort: function() {
|
||
if ( script ) {
|
||
script.onload( undefined, true );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var oldCallbacks = [],
|
||
rjsonp = /(=)\?(?=&|$)|\?\?/;
|
||
|
||
// Default jsonp settings
|
||
jQuery.ajaxSetup({
|
||
jsonp: "callback",
|
||
jsonpCallback: function() {
|
||
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
|
||
this[ callback ] = true;
|
||
return callback;
|
||
}
|
||
});
|
||
|
||
// Detect, normalize options and install callbacks for jsonp requests
|
||
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
|
||
|
||
var callbackName, overwritten, responseContainer,
|
||
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
|
||
"url" :
|
||
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
|
||
);
|
||
|
||
// Handle iff the expected data type is "jsonp" or we have a parameter to set
|
||
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
|
||
|
||
// Get callback name, remembering preexisting value associated with it
|
||
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
|
||
s.jsonpCallback() :
|
||
s.jsonpCallback;
|
||
|
||
// Insert callback into url or form data
|
||
if ( jsonProp ) {
|
||
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
|
||
} else if ( s.jsonp !== false ) {
|
||
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
|
||
}
|
||
|
||
// Use data converter to retrieve json after script execution
|
||
s.converters["script json"] = function() {
|
||
if ( !responseContainer ) {
|
||
jQuery.error( callbackName + " was not called" );
|
||
}
|
||
return responseContainer[ 0 ];
|
||
};
|
||
|
||
// force json dataType
|
||
s.dataTypes[ 0 ] = "json";
|
||
|
||
// Install callback
|
||
overwritten = window[ callbackName ];
|
||
window[ callbackName ] = function() {
|
||
responseContainer = arguments;
|
||
};
|
||
|
||
// Clean-up function (fires after converters)
|
||
jqXHR.always(function() {
|
||
// Restore preexisting value
|
||
window[ callbackName ] = overwritten;
|
||
|
||
// Save back as free
|
||
if ( s[ callbackName ] ) {
|
||
// make sure that re-using the options doesn't screw things around
|
||
s.jsonpCallback = originalSettings.jsonpCallback;
|
||
|
||
// save the callback name for future use
|
||
oldCallbacks.push( callbackName );
|
||
}
|
||
|
||
// Call if it was a function and we have a response
|
||
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
|
||
overwritten( responseContainer[ 0 ] );
|
||
}
|
||
|
||
responseContainer = overwritten = undefined;
|
||
});
|
||
|
||
// Delegate to script
|
||
return "script";
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// data: string of html
|
||
// context (optional): If specified, the fragment will be created in this context, defaults to document
|
||
// keepScripts (optional): If true, will include scripts passed in the html string
|
||
jQuery.parseHTML = function( data, context, keepScripts ) {
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
if ( typeof context === "boolean" ) {
|
||
keepScripts = context;
|
||
context = false;
|
||
}
|
||
context = context || document;
|
||
|
||
var parsed = rsingleTag.exec( data ),
|
||
scripts = !keepScripts && [];
|
||
|
||
// Single tag
|
||
if ( parsed ) {
|
||
return [ context.createElement( parsed[1] ) ];
|
||
}
|
||
|
||
parsed = jQuery.buildFragment( [ data ], context, scripts );
|
||
|
||
if ( scripts && scripts.length ) {
|
||
jQuery( scripts ).remove();
|
||
}
|
||
|
||
return jQuery.merge( [], parsed.childNodes );
|
||
};
|
||
|
||
|
||
// Keep a copy of the old load method
|
||
var _load = jQuery.fn.load;
|
||
|
||
/**
|
||
* Load a url into a page
|
||
*/
|
||
jQuery.fn.load = function( url, params, callback ) {
|
||
if ( typeof url !== "string" && _load ) {
|
||
return _load.apply( this, arguments );
|
||
}
|
||
|
||
var selector, response, type,
|
||
self = this,
|
||
off = url.indexOf(" ");
|
||
|
||
if ( off >= 0 ) {
|
||
selector = jQuery.trim( url.slice( off, url.length ) );
|
||
url = url.slice( 0, off );
|
||
}
|
||
|
||
// If it's a function
|
||
if ( jQuery.isFunction( params ) ) {
|
||
|
||
// We assume that it's the callback
|
||
callback = params;
|
||
params = undefined;
|
||
|
||
// Otherwise, build a param string
|
||
} else if ( params && typeof params === "object" ) {
|
||
type = "POST";
|
||
}
|
||
|
||
// If we have elements to modify, make the request
|
||
if ( self.length > 0 ) {
|
||
jQuery.ajax({
|
||
url: url,
|
||
|
||
// if "type" variable is undefined, then "GET" method will be used
|
||
type: type,
|
||
dataType: "html",
|
||
data: params
|
||
}).done(function( responseText ) {
|
||
|
||
// Save response for use in complete callback
|
||
response = arguments;
|
||
|
||
self.html( selector ?
|
||
|
||
// If a selector was specified, locate the right elements in a dummy div
|
||
// Exclude scripts to avoid IE 'Permission Denied' errors
|
||
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
|
||
|
||
// Otherwise use the full result
|
||
responseText );
|
||
|
||
}).complete( callback && function( jqXHR, status ) {
|
||
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
|
||
});
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.expr.filters.animated = function( elem ) {
|
||
return jQuery.grep(jQuery.timers, function( fn ) {
|
||
return elem === fn.elem;
|
||
}).length;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
var docElem = window.document.documentElement;
|
||
|
||
/**
|
||
* Gets a window from an element
|
||
*/
|
||
function getWindow( elem ) {
|
||
return jQuery.isWindow( elem ) ?
|
||
elem :
|
||
elem.nodeType === 9 ?
|
||
elem.defaultView || elem.parentWindow :
|
||
false;
|
||
}
|
||
|
||
jQuery.offset = {
|
||
setOffset: function( elem, options, i ) {
|
||
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
|
||
position = jQuery.css( elem, "position" ),
|
||
curElem = jQuery( elem ),
|
||
props = {};
|
||
|
||
// set position first, in-case top/left are set even on static elem
|
||
if ( position === "static" ) {
|
||
elem.style.position = "relative";
|
||
}
|
||
|
||
curOffset = curElem.offset();
|
||
curCSSTop = jQuery.css( elem, "top" );
|
||
curCSSLeft = jQuery.css( elem, "left" );
|
||
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
|
||
jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
|
||
|
||
// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
|
||
if ( calculatePosition ) {
|
||
curPosition = curElem.position();
|
||
curTop = curPosition.top;
|
||
curLeft = curPosition.left;
|
||
} else {
|
||
curTop = parseFloat( curCSSTop ) || 0;
|
||
curLeft = parseFloat( curCSSLeft ) || 0;
|
||
}
|
||
|
||
if ( jQuery.isFunction( options ) ) {
|
||
options = options.call( elem, i, curOffset );
|
||
}
|
||
|
||
if ( options.top != null ) {
|
||
props.top = ( options.top - curOffset.top ) + curTop;
|
||
}
|
||
if ( options.left != null ) {
|
||
props.left = ( options.left - curOffset.left ) + curLeft;
|
||
}
|
||
|
||
if ( "using" in options ) {
|
||
options.using.call( elem, props );
|
||
} else {
|
||
curElem.css( props );
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
offset: function( options ) {
|
||
if ( arguments.length ) {
|
||
return options === undefined ?
|
||
this :
|
||
this.each(function( i ) {
|
||
jQuery.offset.setOffset( this, options, i );
|
||
});
|
||
}
|
||
|
||
var docElem, win,
|
||
box = { top: 0, left: 0 },
|
||
elem = this[ 0 ],
|
||
doc = elem && elem.ownerDocument;
|
||
|
||
if ( !doc ) {
|
||
return;
|
||
}
|
||
|
||
docElem = doc.documentElement;
|
||
|
||
// Make sure it's not a disconnected DOM node
|
||
if ( !jQuery.contains( docElem, elem ) ) {
|
||
return box;
|
||
}
|
||
|
||
// If we don't have gBCR, just use 0,0 rather than error
|
||
// BlackBerry 5, iOS 3 (original iPhone)
|
||
if ( typeof elem.getBoundingClientRect !== strundefined ) {
|
||
box = elem.getBoundingClientRect();
|
||
}
|
||
win = getWindow( doc );
|
||
return {
|
||
top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
|
||
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
|
||
};
|
||
},
|
||
|
||
position: function() {
|
||
if ( !this[ 0 ] ) {
|
||
return;
|
||
}
|
||
|
||
var offsetParent, offset,
|
||
parentOffset = { top: 0, left: 0 },
|
||
elem = this[ 0 ];
|
||
|
||
// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
|
||
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
||
// we assume that getBoundingClientRect is available when computed position is fixed
|
||
offset = elem.getBoundingClientRect();
|
||
} else {
|
||
// Get *real* offsetParent
|
||
offsetParent = this.offsetParent();
|
||
|
||
// Get correct offsets
|
||
offset = this.offset();
|
||
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
|
||
parentOffset = offsetParent.offset();
|
||
}
|
||
|
||
// Add offsetParent borders
|
||
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
|
||
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
|
||
}
|
||
|
||
// Subtract parent offsets and element margins
|
||
// note: when an element has margin: auto the offsetLeft and marginLeft
|
||
// are the same in Safari causing offset.left to incorrectly be 0
|
||
return {
|
||
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
||
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
|
||
};
|
||
},
|
||
|
||
offsetParent: function() {
|
||
return this.map(function() {
|
||
var offsetParent = this.offsetParent || docElem;
|
||
|
||
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
|
||
offsetParent = offsetParent.offsetParent;
|
||
}
|
||
return offsetParent || docElem;
|
||
});
|
||
}
|
||
});
|
||
|
||
// Create scrollLeft and scrollTop methods
|
||
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
|
||
var top = /Y/.test( prop );
|
||
|
||
jQuery.fn[ method ] = function( val ) {
|
||
return access( this, function( elem, method, val ) {
|
||
var win = getWindow( elem );
|
||
|
||
if ( val === undefined ) {
|
||
return win ? (prop in win) ? win[ prop ] :
|
||
win.document.documentElement[ method ] :
|
||
elem[ method ];
|
||
}
|
||
|
||
if ( win ) {
|
||
win.scrollTo(
|
||
!top ? val : jQuery( win ).scrollLeft(),
|
||
top ? val : jQuery( win ).scrollTop()
|
||
);
|
||
|
||
} else {
|
||
elem[ method ] = val;
|
||
}
|
||
}, method, val, arguments.length, null );
|
||
};
|
||
});
|
||
|
||
// Add the top/left cssHooks using jQuery.fn.position
|
||
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
|
||
// getComputedStyle returns percent when specified for top/left/bottom/right
|
||
// rather than make the css module depend on the offset module, we just check for it here
|
||
jQuery.each( [ "top", "left" ], function( i, prop ) {
|
||
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
computed = curCSS( elem, prop );
|
||
// if curCSS returns percentage, fallback to offset
|
||
return rnumnonpx.test( computed ) ?
|
||
jQuery( elem ).position()[ prop ] + "px" :
|
||
computed;
|
||
}
|
||
}
|
||
);
|
||
});
|
||
|
||
|
||
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
|
||
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
|
||
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
|
||
// margin is only for outerHeight, outerWidth
|
||
jQuery.fn[ funcName ] = function( margin, value ) {
|
||
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
|
||
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
|
||
|
||
return access( this, function( elem, type, value ) {
|
||
var doc;
|
||
|
||
if ( jQuery.isWindow( elem ) ) {
|
||
// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
|
||
// isn't a whole lot we can do. See pull request at this URL for discussion:
|
||
// https://github.com/jquery/jquery/pull/764
|
||
return elem.document.documentElement[ "client" + name ];
|
||
}
|
||
|
||
// Get document width or height
|
||
if ( elem.nodeType === 9 ) {
|
||
doc = elem.documentElement;
|
||
|
||
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
|
||
// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
|
||
return Math.max(
|
||
elem.body[ "scroll" + name ], doc[ "scroll" + name ],
|
||
elem.body[ "offset" + name ], doc[ "offset" + name ],
|
||
doc[ "client" + name ]
|
||
);
|
||
}
|
||
|
||
return value === undefined ?
|
||
// Get width or height on the element, requesting but not forcing parseFloat
|
||
jQuery.css( elem, type, extra ) :
|
||
|
||
// Set width or height on the element
|
||
jQuery.style( elem, type, value, extra );
|
||
}, type, chainable ? margin : undefined, chainable, null );
|
||
};
|
||
});
|
||
});
|
||
|
||
|
||
// The number of elements contained in the matched element set
|
||
jQuery.fn.size = function() {
|
||
return this.length;
|
||
};
|
||
|
||
jQuery.fn.andSelf = jQuery.fn.addBack;
|
||
|
||
|
||
|
||
|
||
// Register as a named AMD module, since jQuery can be concatenated with other
|
||
// files that may use define, but not via a proper concatenation script that
|
||
// understands anonymous AMD modules. A named AMD is safest and most robust
|
||
// way to register. Lowercase jquery is used because AMD module names are
|
||
// derived from file names, and jQuery is normally delivered in a lowercase
|
||
// file name. Do this after creating the global so that if an AMD module wants
|
||
// to call noConflict to hide this version of jQuery, it will work.
|
||
|
||
// Note that for maximum portability, libraries that are not jQuery should
|
||
// declare themselves as anonymous modules, and avoid setting a global if an
|
||
// AMD loader is present. jQuery is a special case. For more information, see
|
||
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
||
|
||
if ( typeof define === "function" && define.amd ) {
|
||
define( "jquery", [], function() {
|
||
return jQuery;
|
||
});
|
||
}
|
||
|
||
|
||
|
||
|
||
var
|
||
// Map over jQuery in case of overwrite
|
||
_jQuery = window.jQuery,
|
||
|
||
// Map over the $ in case of overwrite
|
||
_$ = window.$;
|
||
|
||
jQuery.noConflict = function( deep ) {
|
||
if ( window.$ === jQuery ) {
|
||
window.$ = _$;
|
||
}
|
||
|
||
if ( deep && window.jQuery === jQuery ) {
|
||
window.jQuery = _jQuery;
|
||
}
|
||
|
||
return jQuery;
|
||
};
|
||
|
||
// Expose jQuery and $ identifiers, even in
|
||
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||
// and CommonJS for browser emulators (#13566)
|
||
if ( typeof noGlobal === strundefined ) {
|
||
window.jQuery = window.$ = jQuery;
|
||
}
|
||
|
||
|
||
|
||
|
||
return jQuery;
|
||
|
||
}));
|
||
|
||
/*! jQuery UI - v1.11.0 - 2014-06-26
|
||
* http://jqueryui.com
|
||
* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
|
||
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
|
||
|
||
(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&i(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}function s(e){for(var t,i;e.length&&e[0]!==document;){if(t=e.css("position"),("absolute"===t||"relative"===t||"fixed"===t)&&(i=parseInt(e.css("zIndex"),10),!isNaN(i)&&0!==i))return i;e=e.parent()}return 0}function a(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.regional.en=e.extend(!0,{},this.regional[""]),this.regional["en-US"]=e.extend(!0,{},this.regional.en),this.dpDiv=n(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function n(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){e.datepicker._isDisabledDatepicker(g.inline?t.parent()[0]:g.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))})}function r(t,i){e.extend(t,i);for(var s in i)null==i[s]&&(t[s]=i[s]);return t}function o(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.0",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(){var t=this.css("position"),i="absolute"===t,s=this.parents().filter(function(){var t=e(this);return i&&"static"===t.css("position")?!1:/(auto|scroll)/.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==t&&s.length?s:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),a=isNaN(s);return(a||s>=0)&&t(i,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,n){return e.each(a,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),n&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var a="Width"===i?["Left","Right"]:["Top","Bottom"],n=i.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?r["inner"+i].call(this):this.each(function(){e(this).css(n,s(this,t)+"px")})},e.fn["outer"+i]=function(t,a){return"number"!=typeof t?r["outer"+i].call(this,t):this.each(function(){e(this).css(n,s(this,t,!0,a)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,a=e(this[0]);a.length&&a[0]!==document;){if(i=a.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(a.css("zIndex"),10),!isNaN(s)&&0!==s))return s;a=a.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i,s){var a,n=e.plugins[t];if(n&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(a=0;n.length>a;a++)e.options[n[a][0]]&&n[a][1].apply(e.element,i)}};var h=0,l=Array.prototype.slice;e.cleanData=function(t){return function(i){for(var s,a=0;null!=(s=i[a]);a++)try{e(s).triggerHandler("remove")}catch(n){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var a,n,r,o,h={},l=t.split(".")[0];return t=t.split(".")[1],a=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][a.toLowerCase()]=function(t){return!!e.data(t,a)},e[l]=e[l]||{},n=e[l][t],r=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new r(e,t)},e.extend(r,n,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),o=new i,o.options=e.widget.extend({},o.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},a=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,n=this._superApply;return this._super=e,this._superApply=a,t=s.apply(this,arguments),this._super=i,this._superApply=n,t}}(),void 0):(h[t]=s,void 0)}),r.prototype=e.widget.extend(o,{widgetEventPrefix:n?o.widgetEventPrefix||t:t},h,{constructor:r,namespace:l,widgetName:t,widgetFullName:a}),n?(e.each(n._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete n._childConstructors):i._childConstructors.push(r),e.widget.bridge(t,r),r},e.widget.extend=function(t){for(var i,s,a=l.call(arguments,1),n=0,r=a.length;r>n;n++)for(i in a[n])s=a[n][i],a[n].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var n="string"==typeof a,r=l.call(arguments,1),o=this;return a=!n&&r.length?e.widget.extend.apply(null,[a].concat(r)):a,n?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(o=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(o=i&&i.jquery?o.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))}),o}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,a,n,r=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(r={},s=t.split("."),t=s.shift(),s.length){for(a=r[t]=e.widget.extend({},this.options[t]),n=0;s.length-1>n;n++)a[s[n]]=a[s[n]]||{},a=a[s[n]];if(t=s.pop(),1===arguments.length)return void 0===a[t]?null:a[t];a[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];r[t]=i}return this._setOptions(r),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var a,n=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=a=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,a=this.widget()),e.each(s,function(s,r){function o(){return t||n.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof r?n[r]:r).apply(n,arguments):void 0}"string"!=typeof r&&(o.guid=r.guid=r.guid||o.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+n.eventNamespace,u=h[2];u?a.delegate(u,l,o):i.bind(l,o)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var a,n,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(a in n)a in i||(i[a]=n[a]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,a,n){"string"==typeof a&&(a={effect:a});var r,o=a?a===!0||"number"==typeof a?i:a.effect||i:t;a=a||{},"number"==typeof a&&(a={duration:a}),r=!e.isEmptyObject(a),a.complete=n,a.delay&&s.delay(a.delay),r&&e.effects&&e.effects.effect[o]?s[t](a):o!==t&&s[o]?s[o](a.duration,a.easing,n):s.queue(function(i){e(this)[t](),n&&n.call(s[0]),i()})}}),e.widget;var u=!1;e(document).mouseup(function(){u=!1}),e.widget("ui.mouse",{version:"1.11.0",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!u){this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,a="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!a&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),u=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):t.which?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),u=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var a,n,r=Math.max,o=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==a)return a;var t,i,s=e("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),n=s.children()[0];return e("body").append(s),t=n.offsetWidth,s.css("overflow","scroll"),i=n.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),a=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),a="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,n="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:n?e.position.scrollbarWidth():0,height:a?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]),a=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:a,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},e.fn.position=function(a){if(!a||!a.of)return f.apply(this,arguments);a=e.extend({},a);var p,m,g,v,y,b,_=e(a.of),x=e.position.getWithinInfo(a.within),k=e.position.getScrollInfo(x),w=(a.collision||"flip").split(" "),D={};return b=s(_),_[0].preventDefault&&(a.at="left top"),m=b.width,g=b.height,v=b.offset,y=e.extend({},v),e.each(["my","at"],function(){var e,t,i=(a[this]||"").split(" ");1===i.length&&(i=l.test(i[0])?i.concat(["center"]):u.test(i[0])?["center"].concat(i):["center","center"]),i[0]=l.test(i[0])?i[0]:"center",i[1]=u.test(i[1])?i[1]:"center",e=d.exec(i[0]),t=d.exec(i[1]),D[this]=[e?e[0]:0,t?t[0]:0],a[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===a.at[0]?y.left+=m:"center"===a.at[0]&&(y.left+=m/2),"bottom"===a.at[1]?y.top+=g:"center"===a.at[1]&&(y.top+=g/2),p=t(D.at,m,g),y.left+=p[0],y.top+=p[1],this.each(function(){var s,l,u=e(this),d=u.outerWidth(),c=u.outerHeight(),f=i(this,"marginLeft"),b=i(this,"marginTop"),T=d+f+i(this,"marginRight")+k.width,S=c+b+i(this,"marginBottom")+k.height,M=e.extend({},y),N=t(D.my,u.outerWidth(),u.outerHeight());"right"===a.my[0]?M.left-=d:"center"===a.my[0]&&(M.left-=d/2),"bottom"===a.my[1]?M.top-=c:"center"===a.my[1]&&(M.top-=c/2),M.left+=N[0],M.top+=N[1],n||(M.left=h(M.left),M.top=h(M.top)),s={marginLeft:f,marginTop:b},e.each(["left","top"],function(t,i){e.ui.position[w[t]]&&e.ui.position[w[t]][i](M,{targetWidth:m,targetHeight:g,elemWidth:d,elemHeight:c,collisionPosition:s,collisionWidth:T,collisionHeight:S,offset:[p[0]+N[0],p[1]+N[1]],my:a.my,at:a.at,within:x,elem:u})}),a.using&&(l=function(e){var t=v.left-M.left,i=t+m-d,s=v.top-M.top,n=s+g-c,h={target:{element:_,left:v.left,top:v.top,width:m,height:g},element:{element:u,left:M.left,top:M.top,width:d,height:c},horizontal:0>i?"left":t>0?"right":"center",vertical:0>n?"top":s>0?"bottom":"middle"};d>m&&m>o(t+i)&&(h.horizontal="center"),c>g&&g>o(s+n)&&(h.vertical="middle"),h.important=r(o(t),o(i))>r(o(s),o(n))?"horizontal":"vertical",a.using.call(this,e,h)}),u.offset(e.extend(M,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollLeft:s.offset.left,n=s.width,o=e.left-t.collisionPosition.marginLeft,h=a-o,l=o+t.collisionWidth-n-a;t.collisionWidth>n?h>0&&0>=l?(i=e.left+h+t.collisionWidth-n-a,e.left+=h-i):e.left=l>0&&0>=h?a:h>l?a+n-t.collisionWidth:a:h>0?e.left+=h:l>0?e.left-=l:e.left=r(e.left-o,e.left)},top:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollTop:s.offset.top,n=t.within.height,o=e.top-t.collisionPosition.marginTop,h=a-o,l=o+t.collisionHeight-n-a;t.collisionHeight>n?h>0&&0>=l?(i=e.top+h+t.collisionHeight-n-a,e.top+=h-i):e.top=l>0&&0>=h?a:h>l?a+n-t.collisionHeight:a:h>0?e.top+=h:l>0?e.top-=l:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var i,s,a=t.within,n=a.offset.left+a.scrollLeft,r=a.width,h=a.isWindow?a.scrollLeft:a.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-r-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-r-n,(0>i||o(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>o(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,a=t.within,n=a.offset.top+a.scrollTop,r=a.height,h=a.isWindow?a.scrollTop:a.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-r-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-r-n,e.top+p+f+m>u&&(0>s||o(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,e.top+p+f+m>d&&(i>0||d>o(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,a,r,o=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(o?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(r in s)t.style[r]=s[r];t.appendChild(h),i=o||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",a=e(h).offset().left,n=a>10&&11>a,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.draggable",e.ui.mouse,{version:"1.11.0",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(t){var i=this.document[0],s=this.options;try{i.activeElement&&"body"!==i.activeElement.nodeName.toLowerCase()&&e(i.activeElement).blur()}catch(a){}return this.helper||s.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(s.iframeFix===!0?"iframe":s.iframeFix).each(function(){e("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this._removeHandleClassName(),e(this.options.handle||this.element).addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.element.find(".ui-draggable-handle").addBack().removeClass("ui-draggable-handle")},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,a=this.options,n=this.document[0];return this.relative_container=null,a.containment?"window"===a.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===a.containment?(this.containment=[0,0,e(n).width()-this.helperProportions.width-this.margins.left,(e(n).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):a.containment.constructor===Array?(this.containment=a.containment,void 0):("parent"===a.containment&&(a.containment=this.helper[0].parentNode),i=e(a.containment),s=i[0],s&&(t="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(e,t){t||(t=this.position);var i="absolute"===e?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:t.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(e,t){var i,s,a,n,r=this.options,o=this._isRootNode(this.scrollParent[0]),h=e.pageX,l=e.pageY;return o&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),r.grid&&(a=r.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/r.grid[1])*r.grid[1]:this.originalPageY,l=i?a-this.offset.click.top>=i[1]||a-this.offset.click.top>i[3]?a:a-this.offset.click.top>=i[1]?a-r.grid[1]:a+r.grid[1]:a,n=r.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/r.grid[0])*r.grid[0]:this.originalPageX,h=i?n-this.offset.click.left>=i[0]||n-this.offset.click.left>i[2]?n:n-this.offset.click.left>=i[0]?n-r.grid[0]:n+r.grid[0]:n),"y"===r.axis&&(h=this.originalPageX),"x"===r.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:o?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:o?0:this.offset.scroll.left)}
|
||
},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s,this],!0),"drag"===t&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i,s){var a=s.options,n=e.extend({},i,{item:s.element});s.sortables=[],e(a.connectToSortable).each(function(){var i=e(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i,s){var a=e.extend({},i,{item:s.element});e.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,a))})},drag:function(t,i,s){var a=this;e.each(s.sortables,function(){var n=!1,r=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(n=!0,e.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==r&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(r.instance.element[0],this.instance.element[0])&&(n=!1),n})),n?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(a).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",t),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",t),s.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,i,s){var a=e("body"),n=s.options;a.css("cursor")&&(n._cursor=a.css("cursor")),a.css("cursor",n.cursor)},stop:function(t,i,s){var a=s.options;a._cursor&&e("body").css("cursor",a._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i,s){var a=e(i.helper),n=s.options;a.css("opacity")&&(n._opacity=a.css("opacity")),a.css("opacity",n.opacity)},stop:function(t,i,s){var a=s.options;a._opacity&&e(i.helper).css("opacity",a._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,i){i.scrollParent[0]!==i.document[0]&&"HTML"!==i.scrollParent[0].tagName&&(i.overflowOffset=i.scrollParent.offset())},drag:function(t,i,s){var a=s.options,n=!1,r=s.document[0];s.scrollParent[0]!==r&&"HTML"!==s.scrollParent[0].tagName?(a.axis&&"x"===a.axis||(s.overflowOffset.top+s.scrollParent[0].offsetHeight-t.pageY<a.scrollSensitivity?s.scrollParent[0].scrollTop=n=s.scrollParent[0].scrollTop+a.scrollSpeed:t.pageY-s.overflowOffset.top<a.scrollSensitivity&&(s.scrollParent[0].scrollTop=n=s.scrollParent[0].scrollTop-a.scrollSpeed)),a.axis&&"y"===a.axis||(s.overflowOffset.left+s.scrollParent[0].offsetWidth-t.pageX<a.scrollSensitivity?s.scrollParent[0].scrollLeft=n=s.scrollParent[0].scrollLeft+a.scrollSpeed:t.pageX-s.overflowOffset.left<a.scrollSensitivity&&(s.scrollParent[0].scrollLeft=n=s.scrollParent[0].scrollLeft-a.scrollSpeed))):(a.axis&&"x"===a.axis||(t.pageY-e(r).scrollTop()<a.scrollSensitivity?n=e(r).scrollTop(e(r).scrollTop()-a.scrollSpeed):e(window).height()-(t.pageY-e(r).scrollTop())<a.scrollSensitivity&&(n=e(r).scrollTop(e(r).scrollTop()+a.scrollSpeed))),a.axis&&"y"===a.axis||(t.pageX-e(r).scrollLeft()<a.scrollSensitivity?n=e(r).scrollLeft(e(r).scrollLeft()-a.scrollSpeed):e(window).width()-(t.pageX-e(r).scrollLeft())<a.scrollSensitivity&&(n=e(r).scrollLeft(e(r).scrollLeft()+a.scrollSpeed)))),n!==!1&&e.ui.ddmanager&&!a.dropBehaviour&&e.ui.ddmanager.prepareOffsets(s,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,i,s){var a=s.options;s.snapElements=[],e(a.snap.constructor!==String?a.snap.items||":data(ui-draggable)":a.snap).each(function(){var t=e(this),i=t.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:i.top,left:i.left})})},drag:function(t,i,s){var a,n,r,o,h,l,u,d,c,p,f=s.options,m=f.snapTolerance,g=i.offset.left,v=g+s.helperProportions.width,y=i.offset.top,b=y+s.helperProportions.height;for(c=s.snapElements.length-1;c>=0;c--)h=s.snapElements[c].left,l=h+s.snapElements[c].width,u=s.snapElements[c].top,d=u+s.snapElements[c].height,h-m>v||g>l+m||u-m>b||y>d+m||!e.contains(s.snapElements[c].item.ownerDocument,s.snapElements[c].item)?(s.snapElements[c].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(a=m>=Math.abs(u-b),n=m>=Math.abs(d-y),r=m>=Math.abs(h-v),o=m>=Math.abs(l-g),a&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top-s.margins.top),n&&(i.position.top=s._convertPositionTo("relative",{top:d,left:0}).top-s.margins.top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left-s.margins.left),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left-s.margins.left)),p=a||n||r||o,"outer"!==f.snapMode&&(a=m>=Math.abs(u-y),n=m>=Math.abs(d-b),r=m>=Math.abs(h-g),o=m>=Math.abs(l-v),a&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top-s.margins.top),n&&(i.position.top=s._convertPositionTo("relative",{top:d-s.helperProportions.height,left:0}).top-s.margins.top),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left-s.margins.left),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left-s.margins.left)),!s.snapElements[c].snapping&&(a||n||r||o||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=a||n||r||o||p)}}),e.ui.plugin.add("draggable","stack",{start:function(t,i,s){var a,n=s.options,r=e.makeArray(e(n.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});r.length&&(a=parseInt(e(r[0]).css("zIndex"),10)||0,e(r).each(function(t){e(this).css("zIndex",a+t)}),this.css("zIndex",a+r.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i,s){var a=e(i.helper),n=s.options;a.css("zIndex")&&(n._zIndex=a.css("zIndex")),a.css("zIndex",n.zIndex)},stop:function(t,i,s){var a=s.options;a._zIndex&&e(i.helper).css("zIndex",a._zIndex)}}),e.ui.draggable,e.widget("ui.droppable",{version:"1.11.0",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(s)?s:function(e){return e.is(s)},this.proportions=function(){return arguments.length?(t=arguments[0],void 0):t?t:t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(t){e.ui.ddmanager.droppables[t]=e.ui.ddmanager.droppables[t]||[],e.ui.ddmanager.droppables[t].push(this)},_splice:function(e){for(var t=0;e.length>t;t++)e[t]===this&&e.splice(t,1)},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];this._splice(t),this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){if("accept"===t)this.accept=e.isFunction(i)?i:function(e){return e.is(i)};else if("scope"===t){var s=e.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(t,i)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,a=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=e(this).droppable("instance");return t.options.greedy&&!t.options.disabled&&t.options.scope===s.options.scope&&t.accept.call(t.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(t,{offset:t.element.offset()}),t.options.tolerance)?(a=!0,!1):void 0}),a?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(){function e(e,t,i){return e>=t&&t+i>e}return function(t,i,s){if(!i.offset)return!1;var a,n,r=(t.positionAbs||t.position.absolute).left,o=(t.positionAbs||t.position.absolute).top,h=r+t.helperProportions.width,l=o+t.helperProportions.height,u=i.offset.left,d=i.offset.top,c=u+i.proportions().width,p=d+i.proportions().height;switch(s){case"fit":return r>=u&&c>=h&&o>=d&&p>=l;case"intersect":return r+t.helperProportions.width/2>u&&c>h-t.helperProportions.width/2&&o+t.helperProportions.height/2>d&&p>l-t.helperProportions.height/2;case"pointer":return a=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,n=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,e(n,d,i.proportions().height)&&e(a,u,i.proportions().width);case"touch":return(o>=d&&p>=o||l>=d&&p>=l||d>o&&l>p)&&(r>=u&&c>=r||h>=u&&c>=h||u>r&&h>c);default:return!1}}}(),e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,a,n=e.ui.ddmanager.droppables[t.options.scope]||[],r=i?i.type:null,o=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;n.length>s;s++)if(!(n[s].options.disabled||t&&!n[s].accept.call(n[s].element[0],t.currentItem||t.element))){for(a=0;o.length>a;a++)if(o[a]===n[s].element[0]){n[s].proportions().height=0;continue e}n[s].visible="none"!==n[s].element.css("display"),n[s].visible&&("mousedown"===r&&n[s]._activate.call(n[s],i),n[s].offset=n[s].element.offset(),n[s].proportions({width:n[s].element[0].offsetWidth,height:n[s].element[0].offsetHeight}))}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,a,n,r=e.ui.intersect(t,this,this.options.tolerance),o=!r&&this.isover?"isout":r&&!this.isover?"isover":null;o&&(this.options.greedy&&(a=this.options.scope,n=this.element.parents(":data(ui-droppable)").filter(function(){return e(this).droppable("instance").options.scope===a}),n.length&&(s=e(n[0]).droppable("instance"),s.greedyChild="isover"===o)),s&&"isover"===o&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[o]=!0,this["isout"===o?"isover":"isout"]=!1,this["isover"===o?"_over":"_out"].call(this,i),s&&"isout"===o&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}},e.ui.droppable,e.widget("ui.resizable",e.ui.mouse,{version:"1.11.0",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(e){return parseInt(e,10)||0},_isNumber:function(e){return!isNaN(parseInt(e,10))},_hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)},_create:function(){var t,i,s,a,n,r=this,o=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!o.aspectRatio,aspectRatio:o.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:o.helper||o.ghost||o.animate?o.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=o.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),n="ui-resizable-"+s,a=e("<div class='ui-resizable-handle "+n+"'></div>"),a.css({zIndex:o.zIndex}),"se"===s&&a.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(a);this._renderAxis=function(t){var i,s,a,n;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=this.element.children(this.handles[i]).first().show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=e(this.handles[i],this.element),n=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),a=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(a,n),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){r.resizing||(this.className&&(a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=a&&a[1]?a[1]:"se")}),o.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){o.disabled||(e(this).removeClass("ui-resizable-autohide"),r._handles.show())}).mouseleave(function(){o.disabled||r.resizing||(e(this).addClass("ui-resizable-autohide"),r._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,a=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(a=!0);return!this.options.disabled&&a},_mouseStart:function(t){var i,s,a,n=this.options,r=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),n.containment&&(i+=e(n.containment).scrollLeft()||0,s+=e(n.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:r.width(),height:r.height()},this.originalSize=this._helper?{width:r.outerWidth(),height:r.outerHeight()}:{width:r.width(),height:r.height()},this.originalPosition={left:i,top:s},this.sizeDiff={width:r.outerWidth()-r.width(),height:r.outerHeight()-r.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof n.aspectRatio?n.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===a?this.axis+"-resize":a),r.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var i,s=this.helper,a={},n=this.originalMousePosition,r=this.axis,o=t.pageX-n.left||0,h=t.pageY-n.top||0,l=this._change[r];return this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height},l?(i=l.apply(this,[t,o,h]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),this.position.top!==this.prevPosition.top&&(a.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(a.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(a.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(a.height=this.size.height+"px"),s.css(a),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(a)||this._trigger("resize",t,this.ui()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,a,n,r,o,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),a=s&&this._hasScroll(i[0],"left")?0:u.sizeDiff.height,n=s?0:u.sizeDiff.width,r={width:u.helper.width()-n,height:u.helper.height()-a},o=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(r,{top:h,left:o})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,i,s,a,n,r=this.options;n={minWidth:this._isNumber(r.minWidth)?r.minWidth:0,maxWidth:this._isNumber(r.maxWidth)?r.maxWidth:1/0,minHeight:this._isNumber(r.minHeight)?r.minHeight:0,maxHeight:this._isNumber(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||e)&&(t=n.minHeight*this.aspectRatio,s=n.minWidth/this.aspectRatio,i=n.maxHeight*this.aspectRatio,a=n.maxWidth/this.aspectRatio,t>n.minWidth&&(n.minWidth=t),s>n.minHeight&&(n.minHeight=s),n.maxWidth>i&&(n.maxWidth=i),n.maxHeight>a&&(n.maxHeight=a)),this._vBoundaries=n},_updateCache:function(e){this.offset=this.helper.offset(),this._isNumber(e.left)&&(this.position.left=e.left),this._isNumber(e.top)&&(this.position.top=e.top),this._isNumber(e.height)&&(this.size.height=e.height),this._isNumber(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,i=this.size,s=this.axis;return this._isNumber(e.height)?e.width=e.height*this.aspectRatio:this._isNumber(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===s&&(e.left=t.left+(i.width-e.width),e.top=null),"nw"===s&&(e.top=t.top+(i.height-e.height),e.left=t.left+(i.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,i=this.axis,s=this._isNumber(e.width)&&t.maxWidth&&t.maxWidth<e.width,a=this._isNumber(e.height)&&t.maxHeight&&t.maxHeight<e.height,n=this._isNumber(e.width)&&t.minWidth&&t.minWidth>e.width,r=this._isNumber(e.height)&&t.minHeight&&t.minHeight>e.height,o=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,l=/sw|nw|w/.test(i),u=/nw|ne|n/.test(i);return n&&(e.width=t.minWidth),r&&(e.height=t.minHeight),s&&(e.width=t.maxWidth),a&&(e.height=t.maxHeight),n&&l&&(e.left=o-t.minWidth),s&&l&&(e.left=o-t.maxWidth),r&&u&&(e.top=h-t.minHeight),a&&u&&(e.top=h-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var e,t,i,s,a,n=this.helper||this.element;for(e=0;this._proportionallyResizeElements.length>e;e++){if(a=this._proportionallyResizeElements[e],!this.borderDif)for(this.borderDif=[],i=[a.css("borderTopWidth"),a.css("borderRightWidth"),a.css("borderBottomWidth"),a.css("borderLeftWidth")],s=[a.css("paddingTop"),a.css("paddingRight"),a.css("paddingBottom"),a.css("paddingLeft")],t=0;i.length>t;t++)this.borderDif[t]=(parseInt(i[t],10)||0)+(parseInt(s[t],10)||0);a.css({height:n.height()-this.borderDif[0]-this.borderDif[2]||0,width:n.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,a=this.originalPosition;return{top:a.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition,prevSize:this.prevSize,prevPosition:this.prevPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).resizable("instance"),s=i.options,a=i._proportionallyResizeElements,n=a.length&&/textarea/i.test(a[0].nodeName),r=n&&i._hasScroll(a[0],"left")?0:i.sizeDiff.height,o=n?0:i.sizeDiff.width,h={width:i.size.width-o,height:i.size.height-r},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};a&&a.length&&e(a[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,i,s,a,n,r,o,h=e(this).resizable("instance"),l=h.options,u=h.element,d=l.containment,c=d instanceof e?d.get(0):/parent/.test(d)?u.parent().get(0):d;c&&(h.containerElement=e(c),/document/.test(d)||d===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(c),i=[],e(["Top","Right","Left","Bottom"]).each(function(e,s){i[e]=h._num(t.css("padding"+s))}),h.containerOffset=t.offset(),h.containerPosition=t.position(),h.containerSize={height:t.innerHeight()-i[3],width:t.innerWidth()-i[1]},s=h.containerOffset,a=h.containerSize.height,n=h.containerSize.width,r=h._hasScroll(c,"left")?c.scrollWidth:n,o=h._hasScroll(c)?c.scrollHeight:a,h.parentData={element:c,left:s.left,top:s.top,width:r,height:o}))},resize:function(t,i){var s,a,n,r,o=e(this).resizable("instance"),h=o.options,l=o.containerOffset,u=o.position,d=o._aspectRatio||t.shiftKey,c={top:0,left:0},p=o.containerElement,f=!0;p[0]!==document&&/static/.test(p.css("position"))&&(c=l),u.left<(o._helper?l.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-l.left:o.position.left-c.left),d&&(o.size.height=o.size.width/o.aspectRatio,f=!1),o.position.left=h.helper?l.left:0),u.top<(o._helper?l.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-l.top:o.position.top),d&&(o.size.width=o.size.height*o.aspectRatio,f=!1),o.position.top=o._helper?l.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,s=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-l.left)+o.sizeDiff.width),a=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-l.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),r=/relative|absolute/.test(o.containerElement.css("position")),n&&r&&(s-=Math.abs(o.parentData.left)),s+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-s,d&&(o.size.height=o.size.width/o.aspectRatio,f=!1)),a+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-a,d&&(o.size.width=o.size.height*o.aspectRatio,f=!1)),f||(o.position.left=i.prevPosition.left,o.position.top=i.prevPosition.top,o.size.width=i.prevSize.width,o.size.height=i.prevSize.height)},stop:function(){var t=e(this).resizable("instance"),i=t.options,s=t.containerOffset,a=t.containerPosition,n=t.containerElement,r=e(t.helper),o=r.offset(),h=r.outerWidth()-t.sizeDiff.width,l=r.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(n.css("position"))&&e(this).css({left:o.left-a.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(n.css("position"))&&e(this).css({left:o.left-a.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).resizable("instance"),a=s.options,n=s.originalSize,r=s.originalPosition,o={height:s.size.height-n.height||0,width:s.size.width-n.width||0,top:s.position.top-r.top||0,left:s.position.left-r.left||0},h=function(t,s){e(t).each(function(){var t=e(this),a=e(this).data("ui-resizable-alsoresize"),n={},r=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(e,t){var i=(a[t]||0)+(o[t]||0);i&&i>=0&&(n[t]=i||null)}),t.css(n)})};"object"!=typeof a.alsoResize||a.alsoResize.nodeType?h(a.alsoResize):e.each(a.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).resizable("instance"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).resizable("instance"),i=t.options,s=t.size,a=t.originalSize,n=t.originalPosition,r=t.axis,o="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=o[0]||1,l=o[1]||1,u=Math.round((s.width-a.width)/h)*h,d=Math.round((s.height-a.height)/l)*l,c=a.width+u,p=a.height+d,f=i.maxWidth&&c>i.maxWidth,m=i.maxHeight&&p>i.maxHeight,g=i.minWidth&&i.minWidth>c,v=i.minHeight&&i.minHeight>p;i.grid=o,g&&(c+=h),v&&(p+=l),f&&(c-=h),m&&(p-=l),/^(se|s|e)$/.test(r)?(t.size.width=c,t.size.height=p):/^(ne)$/.test(r)?(t.size.width=c,t.size.height=p,t.position.top=n.top-d):/^(sw)$/.test(r)?(t.size.width=c,t.size.height=p,t.position.left=n.left-u):(p-l>0?(t.size.height=p,t.position.top=n.top-d):(t.size.height=l,t.position.top=n.top+a.height-l),c-h>0?(t.size.width=c,t.position.left=n.left-u):(t.size.width=h,t.position.left=n.left+a.width-h))}}),e.ui.resizable,e.widget("ui.selectable",e.ui.mouse,{version:"1.11.0",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;
|
||
this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,a=e.data(this,"selectable-item");return a?(s=!t.metaKey&&!t.ctrlKey||!a.$element.hasClass("ui-selected"),a.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),a.unselecting=!s,a.selecting=s,a.selected=s,s?i._trigger("selecting",t,{selecting:a.element}):i._trigger("unselecting",t,{unselecting:a.element}),!1):void 0}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,a=this.options,n=this.opos[0],r=this.opos[1],o=t.pageX,h=t.pageY;return n>o&&(i=o,o=n,n=i),r>h&&(i=h,h=r,r=i),this.helper.css({left:n,top:r,width:o-n,height:h-r}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===a.tolerance?l=!(i.left>o||n>i.right||i.top>h||r>i.bottom):"fit"===a.tolerance&&(l=i.left>n&&o>i.right&&i.top>r&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}}),e.widget("ui.sortable",e.ui.mouse,{version:"1.11.0",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(e,t,i){return e>=t&&t+i>e},_isFloating:function(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===e.axis||this._isFloating(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(e,t){this._super(e,t),"handle"===e&&this._setHandleClassName()},_setHandleClassName:function(){this.element.find(".ui-sortable-handle").removeClass("ui-sortable-handle"),e.each(this.items,function(){(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item).addClass("ui-sortable-handle")})},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").find(".ui-sortable-handle").removeClass("ui-sortable-handle"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,i){var s=null,a=!1,n=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,n.widgetName+"-item")===n?(s=e(this),!1):void 0}),e.data(t.target,n.widgetName+"-item")===n&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(a=!0)}),a)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var a,n,r=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,r.cursorAt&&this._adjustOffsetFromHelper(r.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),r.containment&&this._setContainment(),r.cursor&&"auto"!==r.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",r.cursor),this.storedStylesheet=e("<style>*{ cursor: "+r.cursor+" !important; }</style>").appendTo(n)),r.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",r.opacity)),r.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",r.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(a=this.containers.length-1;a>=0;a--)this.containers[a]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,a,n,r=this.options,o=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<r.scrollSensitivity?this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop+r.scrollSpeed:t.pageY-this.overflowOffset.top<r.scrollSensitivity&&(this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop-r.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<r.scrollSensitivity?this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft+r.scrollSpeed:t.pageX-this.overflowOffset.left<r.scrollSensitivity&&(this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft-r.scrollSpeed)):(t.pageY-e(document).scrollTop()<r.scrollSensitivity?o=e(document).scrollTop(e(document).scrollTop()-r.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<r.scrollSensitivity&&(o=e(document).scrollTop(e(document).scrollTop()+r.scrollSpeed)),t.pageX-e(document).scrollLeft()<r.scrollSensitivity?o=e(document).scrollLeft(e(document).scrollLeft()-r.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<r.scrollSensitivity&&(o=e(document).scrollLeft(e(document).scrollLeft()+r.scrollSpeed))),o!==!1&&e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],a=s.item[0],n=this._intersectsWithPointer(s),n&&s.instance===this.currentContainer&&a!==this.currentItem[0]&&this.placeholder[1===n?"next":"prev"]()[0]!==a&&!e.contains(this.placeholder[0],a)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],a):!0)){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,a=this.placeholder.offset(),n=this.options.axis,r={};n&&"x"!==n||(r.left=a.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(r.top=a.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(r,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,a=s+this.helperProportions.height,n=e.left,r=n+e.width,o=e.top,h=o+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>o&&h>s+l,c="y"===this.options.axis||t+u>n&&r>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>n&&r>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>o&&h>a-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),i="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),s=t&&i,a=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return s?this.floating?n&&"right"===n||"down"===a?2:1:a&&("down"===a?2:1):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return this.floating&&a?"right"===a&&i||"left"===a&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){o.push(this)}var s,a,n,r,o=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(n=e(l[s]),a=n.length-1;a>=0;a--)r=e.data(n[a],this.widgetFullName),r&&r!==this&&!r.options.disabled&&h.push([e.isFunction(r.options.items)?r.options.items.call(r.element):e(r.options.items,r.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),r]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(o)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,a,n,r,o,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(a=e(c[i]),s=a.length-1;s>=0;s--)n=e.data(a[s],this.widgetFullName),n&&n!==this&&!n.options.disabled&&(d.push([e.isFunction(n.options.items)?n.options.items.call(n.element[0],t,{item:this.currentItem}):e(n.options.items,n.element),n]),this.containers.push(n));for(i=d.length-1;i>=0;i--)for(r=d[i][1],o=d[i][0],s=0,l=o.length;l>s;s++)h=e(o[s]),h.data(this.widgetName+"-item",r),u.push({item:h,instance:r,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,a,n;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(a=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=a.outerWidth(),s.height=a.outerHeight()),n=a.offset(),s.left=n.left,s.top=n.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)n=this.containers[i].element.offset(),this.containers[i].containerCache.left=n.left,this.containers[i].containerCache.top=n.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),a=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?t.currentItem.children().each(function(){e("<td> </td>",t.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(a)}):"img"===s&&a.attr("src",t.currentItem.attr("src")),i||a.css("visibility","hidden"),a},update:function(e,a){(!i||s.forcePlaceholderSize)&&(a.height()||a.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),a.width()||a.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var i,s,a,n,r,o,h,l,u,d,c=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(c&&e.contains(this.containers[i].element[0],c.element[0]))continue;c=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(a=1e4,n=null,u=c.floating||this._isFloating(this.currentItem),r=u?"left":"top",o=u?"width":"height",d=u?"clientX":"clientY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[r],l=!1,t[d]-h>this.items[s][o]/2&&(l=!0),a>Math.abs(t[d]-h)&&(a=Math.abs(t[d]-h),n=this.items[s],this.direction=l?"up":"down"));if(!n&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return;n?this._rearrange(t,n,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,a=this.options;"parent"===a.containment&&(a.containment=this.helper[0].parentNode),("document"===a.containment||"window"===a.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e("document"===a.containment?document:window).width()-this.helperProportions.width-this.margins.left,(e("document"===a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(a.containment)||(t=e(a.containment)[0],i=e(a.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,a="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,n=/(html|body)/i.test(a[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:a.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:a.scrollLeft())*s}},_generatePosition:function(t){var i,s,a=this.options,n=t.pageX,r=t.pageY,o="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(o[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(n=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(r=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(n=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(r=this.containment[3]+this.offset.click.top)),a.grid&&(i=this.originalPageY+Math.round((r-this.originalPageY)/a.grid[1])*a.grid[1],r=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-a.grid[1]:i+a.grid[1]:i,s=this.originalPageX+Math.round((n-this.originalPageX)/a.grid[0])*a.grid[0],n=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-a.grid[0]:s+a.grid[0]:s)),{top:r-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:o.scrollTop()),left:n-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:o.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var a=this.counter;this._delay(function(){a===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,a=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&a.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||a.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(a.push(function(e){this._trigger("remove",e,this._uiHash())}),a.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),a.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||a.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(a.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!t){for(this._trigger("beforeStop",e,this._uiHash()),s=0;a.length>s;s++)a[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!1}if(t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!t){for(s=0;a.length>s;s++)a[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}}),e.widget("ui.accordion",{version:"1.11.0",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").removeUniqueId(),this._destroyIcons(),e=this.headers.next().removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&(this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)),void 0)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,s=this.headers.length,a=this.headers.index(t.target),n=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:n=this.headers[(a+1)%s];break;case i.LEFT:case i.UP:n=this.headers[(a-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:n=this.headers[0];break;case i.END:n=this.headers[s-1]}n&&(e(t.target).attr("tabIndex",-1),e(n).attr("tabIndex",0),n.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var t,i=this.options,s=i.heightStyle,a=this.element.parent();this.active=this._findActive(i.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(){var t=e(this),i=t.uniqueId().attr("id"),s=t.next(),a=s.uniqueId().attr("id");
|
||
t.attr("aria-controls",a),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(t=a.height(),this.element.siblings(":visible").each(function(){var i=e(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(t-=i.outerHeight(!0))}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,s=this.active,a=e(t.currentTarget),n=a[0]===s[0],r=n&&i.collapsible,o=r?e():a.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:r?e():a,newPanel:o};t.preventDefault(),n&&!i.collapsible||this._trigger("beforeActivate",t,l)===!1||(i.active=r?!1:this.headers.index(a),this.active=n?e():a,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),n||(a.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&a.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),a.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,s=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,t):(s.hide(),i.show(),this._toggleComplete(t)),s.attr({"aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true",tabIndex:0,"aria-expanded":"true"})},_animate:function(e,t,i){var s,a,n,r=this,o=0,h=e.length&&(!t.length||e.index()<t.index()),l=this.options.animate||{},u=h&&l.down||l,d=function(){r._toggleComplete(i)};return"number"==typeof u&&(n=u),"string"==typeof u&&(a=u),a=a||u.easing||l.easing,n=n||u.duration||l.duration,t.length?e.length?(s=e.show().outerHeight(),t.animate(this.hideProps,{duration:n,easing:a,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(this.showProps,{duration:n,easing:a,complete:d,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?o+=i.now:"content"!==r.options.heightStyle&&(i.now=Math.round(s-t.outerHeight()-o),o=0)}}),void 0):t.animate(this.hideProps,n,a,d):e.animate(this.showProps,n,a,d)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.widget("ui.menu",{version:"1.11.0",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},items:"> *",menus:"ul",position:{my:"left-1 top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item":function(e){e.preventDefault()},"click .ui-menu-item":function(t){var i=e(t.target);!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&e(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var i=e(t.currentTarget);i.siblings(".ui-state-active").removeClass("ui-state-active"),this.focus(t,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.find(this.options.items).eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){this._closeOnDocumentClick(e)&&this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").removeUniqueId().removeClass("ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function i(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,a,n,r,o,h=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:h=!1,a=this.previousFilter||"",n=String.fromCharCode(t.keyCode),r=!1,clearTimeout(this.filterTimer),n===a?r=!0:n=a+n,o=RegExp("^"+i(n),"i"),s=this.activeMenu.find(this.options.items).filter(function(){return o.test(e(this).text())}),s=r&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(n=String.fromCharCode(t.keyCode),o=RegExp("^"+i(n),"i"),s=this.activeMenu.find(this.options.items).filter(function(){return o.test(e(this).text())})),s.length?(this.focus(t,s),s.length>1?(this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.is("[aria-haspopup='true']")?this.expand(e):this.select(e))},refresh:function(){var t,i,s=this,a=this.options.icons.submenu,n=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),n.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-front").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),i=t.parent(),s=e("<span>").addClass("ui-menu-icon ui-icon "+a).data("ui-menu-submenu-carat",!0);i.attr("aria-haspopup","true").prepend(s),t.attr("aria-labelledby",i.attr("id"))}),t=n.add(this.element),i=t.find(this.options.items),i.not(".ui-menu-item").each(function(){var t=e(this);s._isDivider(t)&&t.addClass("ui-widget-content ui-menu-divider")}),i.not(".ui-menu-item, .ui-menu-divider").addClass("ui-menu-item").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){"icons"===e&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},focus:function(e,t){var i,s;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.addClass("ui-state-focus").removeClass("ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").addClass("ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&e&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,a,n,r,o;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,a=t.offset().top-this.activeMenu.offset().top-i-s,n=this.activeMenu.scrollTop(),r=this.activeMenu.height(),o=t.outerHeight(),0>a?this.activeMenu.scrollTop(n+a):a+o>r&&this.activeMenu.scrollTop(n+a-r+o))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this.active.removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active}))},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find(".ui-state-active").not(".ui-state-focus").removeClass("ui-state-active")},_closeOnDocumentClick:function(t){return!e(t.target).closest(".ui-menu").length},_isDivider:function(e){return!/[^\-\u2014\u2013\s]/.test(e.text())},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[t]()),this.focus(i,s)},nextPage:function(t){var i,s,a;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,a=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-a}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(t),void 0)},previousPage:function(t){var i,s,a;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,a=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+a>0}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items).first())),void 0):(this.next(t),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,i)}}),e.widget("ui.autocomplete",{version:"1.11.0",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,a=this.element[0].nodeName.toLowerCase(),n="textarea"===a,r="input"===a;this.isMultiLine=n?!0:r?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[n||r?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(a){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,void 0;t=!1,s=!1,i=!1;var n=e.ui.keyCode;switch(a.keyCode){case n.PAGE_UP:t=!0,this._move("previousPage",a);break;case n.PAGE_DOWN:t=!0,this._move("nextPage",a);break;case n.UP:t=!0,this._keyEvent("previous",a);break;case n.DOWN:t=!0,this._keyEvent("next",a);break;case n.ENTER:this.menu.active&&(t=!0,a.preventDefault(),this.menu.select(a));break;case n.TAB:this.menu.active&&this.menu.select(a);break;case n.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(a),a.preventDefault());break;default:i=!0,this._searchTimeout(a)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var a=e.ui.keyCode;switch(s.keyCode){case a.PAGE_UP:this._move("previousPage",s);break;case a.PAGE_DOWN:this._move("nextPage",s);break;case a.UP:this._keyEvent("previous",s);break;case a.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),void 0):(this._searchTimeout(e),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(e),this._change(e),void 0)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){var s,a;return this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),void 0):(a=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:a})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(a.value),s=i.item.attr("aria-label")||a.value,s&&jQuery.trim(s).length&&(this.liveRegion.children().hide(),e("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,a){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){a(e)},error:function(){a([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),i=this.menu.element.is(":visible"),s=e.altKey||e.ctrlKey||e.metaKey||e.shiftKey;(!t||t&&!i&&!s)&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):void 0},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var t=++this.requestIndex;return e.proxy(function(e){t===this.requestIndex&&this.__response(e),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").text(i.label).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[e](t),void 0):(this.search(null,t),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.children().hide(),e("<div>").text(i).appendTo(this.liveRegion))}}),e.ui.autocomplete;var d,c="ui-button ui-widget ui-state-default ui-corner-all",p="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",f=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},m=function(t){var i=t.name,s=t.form,a=e([]);return i&&(i=i.replace(/'/g,"\\'"),a=s?e(s).find("[name='"+i+"'][type=radio]"):e("[name='"+i+"'][type=radio]",t.ownerDocument).filter(function(){return!this.form})),a};e.widget("ui.button",{version:"1.11.0",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,f),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,i=this.options,s="checkbox"===this.type||"radio"===this.type,a=s?"":"ui-state-active";null===i.label&&(i.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(c).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){i.disabled||this===d&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){i.disabled||e(this).removeClass(a)}).bind("click"+this.eventNamespace,function(e){i.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),s&&this.element.bind("change"+this.eventNamespace,function(){t.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return i.disabled?!1:void 0}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(i.disabled)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var s=t.element[0];m(s).not(s).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return i.disabled?!1:(e(this).addClass("ui-state-active"),d=this,t.document.one("mouseup",function(){d=null}),void 0)}).bind("mouseup"+this.eventNamespace,function(){return i.disabled?!1:(e(this).removeClass("ui-state-active"),void 0)}).bind("keydown"+this.eventNamespace,function(t){return i.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),void 0)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",i.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(c+" ui-state-active "+p).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),t&&("checkbox"===this.type||"radio"===this.type?this.buttonElement.removeClass("ui-state-focus"):this.buttonElement.removeClass("ui-state-focus ui-state-active")),void 0):(this._resetButton(),void 0)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?m(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),void 0;var t=this.buttonElement.removeClass(p),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),s=this.options.icons,a=s.primary&&s.secondary,n=[];s.primary||s.secondary?(this.options.text&&n.push("ui-button-text-icon"+(a?"s":s.primary?"-primary":"-secondary")),s.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(n.push(a?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):n.push("ui-button-text-only"),t.addClass(n.join(" "))}}),e.widget("ui.buttonset",{version:"1.11.0",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction"),i=this.element.find(this.options.items),s=i.filter(":ui-button");i.not(":ui-button").button(),s.button("refresh"),this.buttons=i.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}}),e.ui.button,e.extend(e.ui,{datepicker:{version:"1.11.0"}});var g;e.extend(a.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return r(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var s,a,n;s=t.nodeName.toLowerCase(),a="div"===s||"span"===s,t.id||(this.uuid+=1,t.id="dp"+this.uuid),n=this._newInst(e(t),a),n.settings=e.extend({},i||{}),"input"===s?this._connectDatepicker(t,n):a&&this._inlineDatepicker(t,n)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?n(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var s=e(t);i.append=e([]),i.trigger=e([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,"datepicker",i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var s,a,n,r=this._get(i,"appendText"),o=this._get(i,"isRTL");i.append&&i.append.remove(),r&&(i.append=e("<span class='"+this._appendClass+"'>"+r+"</span>"),t[o?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&t.focus(this._showDatepicker),("button"===s||"both"===s)&&(a=this._get(i,"buttonText"),n=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:n,alt:a,title:a}):e("<button type='button'></button>").addClass(this._triggerClass).html(n?e("<img/>").attr({src:n,alt:a,title:a}):a)),t[o?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,s,a,n=new Date(2009,11,20),r=this._get(e,"dateFormat");r.match(/[DM]/)&&(t=function(e){for(i=0,s=0,a=0;e.length>a;a++)e[a].length>i&&(i=e[a].length,s=a);return s},n.setMonth(t(this._get(e,r.match(/MM/)?"monthNames":"monthNamesShort"))),n.setDate(t(this._get(e,r.match(/DD/)?"dayNames":"dayNamesShort"))+20-n.getDay())),e.input.attr("size",this._formatDate(e,n).length)}},_inlineDatepicker:function(t,i){var s=e(t);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),e.data(t,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,s,a,n){var o,h,l,u,d,c=this._dialogInst;return c||(this.uuid+=1,o="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+o+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),c=this._dialogInst=this._newInst(this._dialogInput,!1),c.settings={},e.data(this._dialogInput[0],"datepicker",c)),r(c.settings,a||{}),i=i&&i.constructor===Date?this._formatDate(c,i):i,this._dialogInput.val(i),this._pos=n?n.length?n:[n.pageX,n.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+u,l/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),c.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],"datepicker",c),this},_destroyDatepicker:function(t){var i,s=e(t),a=e.data(t,"datepicker");s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,"datepicker"),"input"===i?(a.append.remove(),a.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())
|
||
},_enableDatepicker:function(t){var i,s,a=e(t),n=e.data(t,"datepicker");a.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=a.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,s,a=e(t),n=e.data(t,"datepicker");a.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=a.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(t,i,s){var a,n,o,h,l=this._getInst(t);return 2===arguments.length&&"string"==typeof i?"defaults"===i?e.extend({},e.datepicker._defaults):l?"all"===i?e.extend({},l.settings):this._get(l,i):null:(a=i||{},"string"==typeof i&&(a={},a[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),n=this._getDateDatepicker(t,!0),o=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),r(l.settings,a),null!==o&&void 0!==a.dateFormat&&void 0===a.minDate&&(l.settings.minDate=this._formatDate(l,o)),null!==h&&void 0!==a.dateFormat&&void 0===a.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in a&&(a.disabled?this._disableDatepicker(t):this._enableDatepicker(t)),this._attachments(e(t),l),this._autoSize(l),this._setDate(l,n),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,s,a,n=e.datepicker._getInst(t.target),r=!0,o=n.dpDiv.is(".ui-datepicker-rtl");if(n._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),r=!1;break;case 13:return a=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",n.dpDiv),a[0]&&e.datepicker._selectDay(t.target,n.selectedMonth,n.selectedYear,a[0]),i=e.datepicker._get(n,"onSelect"),i?(s=e.datepicker._formatDate(n),i.apply(n.input?n.input[0]:null,[s,n])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),r=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),r=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?1:-1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),r=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?-1:1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),r=t.ctrlKey||t.metaKey;break;default:r=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):r=!1;r&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(t){var i,s,a=e.datepicker._getInst(t.target);return e.datepicker._get(a,"constrainInput")?(i=e.datepicker._possibleChars(e.datepicker._get(a,"dateFormat")),s=String.fromCharCode(null==t.charCode?t.keyCode:t.charCode),t.ctrlKey||t.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(t){var i,s=e.datepicker._getInst(t.target);if(s.input.val()!==s.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,e.datepicker._getFormatConfig(s)),i&&(e.datepicker._setDateFromField(s),e.datepicker._updateAlternate(s),e.datepicker._updateDatepicker(s))}catch(a){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,a,n,o,h,l,u;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),a=e.datepicker._get(i,"beforeShow"),n=a?a.apply(t,[t,i]):{},n!==!1&&(r(i.settings,n),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),o=!1,e(t).parents().each(function(){return o|="fixed"===e(this).css("position"),!o}),h={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),h=e.datepicker._checkOffset(i,h,o),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":o?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),i.inline||(l=e.datepicker._get(i,"showAnim"),u=e.datepicker._get(i,"duration"),i.dpDiv.css("z-index",s(e(t))+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[l]?i.dpDiv.show(l,e.datepicker._get(i,"showOptions"),u):i.dpDiv[l||"show"](l?u:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,g=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t),t.dpDiv.find("."+this._dayOverClass+" a");var i,s=this._getNumberOfMonths(t),a=s[1],n=17;t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),a>1&&t.dpDiv.addClass("ui-datepicker-multi-"+a).css("width",n*a+"em"),t.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,s){var a=t.dpDiv.outerWidth(),n=t.dpDiv.outerHeight(),r=t.input?t.input.outerWidth():0,o=t.input?t.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:e(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?a-r:0,i.left-=s&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=s&&i.top===t.input.offset().top+o?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+a>h&&h>a?Math.abs(i.left+a-h):0),i.top-=Math.min(i.top,i.top+n>l&&l>n?Math.abs(n+o):0),i},_findPos:function(t){for(var i,s=this._getInst(t),a=this._get(s,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[a?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,s,a,n,r=this._curInst;!r||t&&r!==e.data(t,"datepicker")||this._datepickerShowing&&(i=this._get(r,"showAnim"),s=this._get(r,"duration"),a=function(){e.datepicker._tidyDialog(r)},e.effects&&(e.effects.effect[i]||e.effects[i])?r.dpDiv.hide(i,e.datepicker._get(r,"showOptions"),s,a):r.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,a),i||a(),this._datepickerShowing=!1,n=this._get(r,"onClose"),n&&n.apply(r.input?r.input[0]:null,[r.input?r.input.val():"",r]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),s=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==s)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,s){var a=e(t),n=this._getInst(a[0]);this._isDisabledDatepicker(a[0])||(this._adjustInstDate(n,i+("M"===s?this._get(n,"showCurrentAtPos"):0),s),this._updateDatepicker(n))},_gotoToday:function(t){var i,s=e(t),a=this._getInst(s[0]);this._get(a,"gotoCurrent")&&a.currentDay?(a.selectedDay=a.currentDay,a.drawMonth=a.selectedMonth=a.currentMonth,a.drawYear=a.selectedYear=a.currentYear):(i=new Date,a.selectedDay=i.getDate(),a.drawMonth=a.selectedMonth=i.getMonth(),a.drawYear=a.selectedYear=i.getFullYear()),this._notifyChange(a),this._adjustDate(s)},_selectMonthYear:function(t,i,s){var a=e(t),n=this._getInst(a[0]);n["selected"+("M"===s?"Month":"Year")]=n["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(n),this._adjustDate(a)},_selectDay:function(t,i,s,a){var n,r=e(t);e(a).hasClass(this._unselectableClass)||this._isDisabledDatepicker(r[0])||(n=this._getInst(r[0]),n.selectedDay=n.currentDay=e("a",a).html(),n.selectedMonth=n.currentMonth=i,n.selectedYear=n.currentYear=s,this._selectDate(t,this._formatDate(n,n.currentDay,n.currentMonth,n.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var s,a=e(t),n=this._getInst(a[0]);i=null!=i?i:this._formatDate(n),n.input&&n.input.val(i),this._updateAlternate(n),s=this._get(n,"onSelect"),s?s.apply(n.input?n.input[0]:null,[i,n]):n.input&&n.input.trigger("change"),n.inline?this._updateDatepicker(n):(this._hideDatepicker(),this._lastInput=n.input[0],"object"!=typeof n.input[0]&&n.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,s,a,n=this._get(t,"altField");n&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),s=this._getDate(t),a=this.formatDate(i,s,this._getFormatConfig(t)),e(n).each(function(){e(this).val(a)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(t,i,s){if(null==t||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var a,n,r,o,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),d=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,c=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,m=-1,g=-1,v=-1,y=-1,b=!1,_=function(e){var i=t.length>a+1&&t.charAt(a+1)===e;return i&&a++,i},x=function(e){var t=_(e),s="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,a=RegExp("^\\d{1,"+s+"}"),n=i.substring(h).match(a);if(!n)throw"Missing number at position "+h;return h+=n[0].length,parseInt(n[0],10)},k=function(t,s,a){var n=-1,r=e.map(_(t)?a:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(r,function(e,t){var s=t[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(n=t[0],h+=s.length,!1):void 0}),-1!==n)return n+1;throw"Unknown name at position "+h},w=function(){if(i.charAt(h)!==t.charAt(a))throw"Unexpected literal at position "+h;h++};for(a=0;t.length>a;a++)if(b)"'"!==t.charAt(a)||_("'")?w():b=!1;else switch(t.charAt(a)){case"d":v=x("d");break;case"D":k("D",d,c);break;case"o":y=x("o");break;case"m":g=x("m");break;case"M":g=k("M",p,f);break;case"y":m=x("y");break;case"@":o=new Date(x("@")),m=o.getFullYear(),g=o.getMonth()+1,v=o.getDate();break;case"!":o=new Date((x("!")-this._ticksTo1970)/1e4),m=o.getFullYear(),g=o.getMonth()+1,v=o.getDate();break;case"'":_("'")?w():b=!0;break;default:w()}if(i.length>h&&(r=i.substr(h),!/^\s+/.test(r)))throw"Extra/unparsed characters found in date: "+r;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),y>-1)for(g=1,v=y;;){if(n=this._getDaysInMonth(m,g-1),n>=v)break;g++,v-=n}if(o=this._daylightSavingAdjust(new Date(m,g-1,v)),o.getFullYear()!==m||o.getMonth()+1!==g||o.getDate()!==v)throw"Invalid date";return o},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var s,a=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,n=(i?i.dayNames:null)||this._defaults.dayNames,r=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,o=(i?i.monthNames:null)||this._defaults.monthNames,h=function(t){var i=e.length>s+1&&e.charAt(s+1)===t;return i&&s++,i},l=function(e,t,i){var s=""+t;if(h(e))for(;i>s.length;)s="0"+s;return s},u=function(e,t,i,s){return h(e)?s[t]:i[t]},d="",c=!1;if(t)for(s=0;e.length>s;s++)if(c)"'"!==e.charAt(s)||h("'")?d+=e.charAt(s):c=!1;else switch(e.charAt(s)){case"d":d+=l("d",t.getDate(),2);break;case"D":d+=u("D",t.getDay(),a,n);break;case"o":d+=l("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":d+=l("m",t.getMonth()+1,2);break;case"M":d+=u("M",t.getMonth(),r,o);break;case"y":d+=h("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":d+=t.getTime();break;case"!":d+=1e4*t.getTime()+this._ticksTo1970;break;case"'":h("'")?d+="'":c=!0;break;default:d+=e.charAt(s)}return d},_possibleChars:function(e){var t,i="",s=!1,a=function(i){var s=e.length>t+1&&e.charAt(t+1)===i;return s&&t++,s};for(t=0;e.length>t;t++)if(s)"'"!==e.charAt(t)||a("'")?i+=e.charAt(t):s=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":a("'")?i+="'":s=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,t){return void 0!==e.settings[t]?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),s=e.lastVal=e.input?e.input.val():null,a=this._getDefaultDate(e),n=a,r=this._getFormatConfig(e);try{n=this.parseDate(i,s,r)||a}catch(o){s=t?"":s}e.selectedDay=n.getDate(),e.drawMonth=e.selectedMonth=n.getMonth(),e.drawYear=e.selectedYear=n.getFullYear(),e.currentDay=s?n.getDate():0,e.currentMonth=s?n.getMonth():0,e.currentYear=s?n.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,s){var a=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},n=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(s){}for(var a=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,n=a.getFullYear(),r=a.getMonth(),o=a.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":o+=parseInt(l[1],10);break;case"w":case"W":o+=7*parseInt(l[1],10);break;case"m":case"M":r+=parseInt(l[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r));break;case"y":case"Y":n+=parseInt(l[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r))}l=h.exec(i)}return new Date(n,r,o)},r=null==i||""===i?s:"string"==typeof i?n(i):"number"==typeof i?isNaN(i)?s:a(i):new Date(i.getTime());return r=r&&"Invalid Date"==""+r?s:r,r&&(r.setHours(0),r.setMinutes(0),r.setSeconds(0),r.setMilliseconds(0)),this._daylightSavingAdjust(r)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var s=!t,a=e.selectedMonth,n=e.selectedYear,r=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=r.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=r.getMonth(),e.drawYear=e.selectedYear=e.currentYear=r.getFullYear(),a===e.selectedMonth&&n===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(s?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),s="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(s,-i,"M")},next:function(){e.datepicker._adjustDate(s,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(s)},selectDay:function(){return e.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(s,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,s,a,n,r,o,h,l,u,d,c,p,f,m,g,v,y,b,_,x,k,w,D,T,S,M,N,C,A,I,P,F,H,z,j,E,O,L,W=new Date,R=this._daylightSavingAdjust(new Date(W.getFullYear(),W.getMonth(),W.getDate())),Y=this._get(e,"isRTL"),J=this._get(e,"showButtonPanel"),B=this._get(e,"hideIfNoPrevNext"),K=this._get(e,"navigationAsDateFormat"),V=this._getNumberOfMonths(e),q=this._get(e,"showCurrentAtPos"),U=this._get(e,"stepMonths"),G=1!==V[0]||1!==V[1],Q=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),X=this._getMinMaxDate(e,"min"),$=this._getMinMaxDate(e,"max"),Z=e.drawMonth-q,et=e.drawYear;if(0>Z&&(Z+=12,et--),$)for(t=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-V[0]*V[1]+1,$.getDate())),t=X&&X>t?X:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-U,1)),this._getFormatConfig(e)):i,s=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":B?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",a=this._get(e,"nextText"),a=K?this.formatDate(a,this._daylightSavingAdjust(new Date(et,Z+U,1)),this._getFormatConfig(e)):a,n=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+a+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+a+"</span></a>":B?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+a+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+a+"</span></a>",r=this._get(e,"currentText"),o=this._get(e,"gotoCurrent")&&e.currentDay?Q:R,r=K?this.formatDate(r,o,this._getFormatConfig(e)):r,h=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",l=J?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(e,o)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+r+"</button>":"")+(Y?"":h)+"</div>":"",u=parseInt(this._get(e,"firstDay"),10),u=isNaN(u)?0:u,d=this._get(e,"showWeek"),c=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),f=this._get(e,"monthNames"),m=this._get(e,"monthNamesShort"),g=this._get(e,"beforeShowDay"),v=this._get(e,"showOtherMonths"),y=this._get(e,"selectOtherMonths"),b=this._getDefaultDate(e),_="",k=0;V[0]>k;k++){for(w="",this.maxRows=4,D=0;V[1]>D;D++){if(T=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),S=" ui-corner-all",M="",G){if(M+="<div class='ui-datepicker-group",V[1]>1)switch(D){case 0:M+=" ui-datepicker-group-first",S=" ui-corner-"+(Y?"right":"left");break;case V[1]-1:M+=" ui-datepicker-group-last",S=" ui-corner-"+(Y?"left":"right");break;default:M+=" ui-datepicker-group-middle",S=""}M+="'>"}for(M+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+S+"'>"+(/all|left/.test(S)&&0===k?Y?n:s:"")+(/all|right/.test(S)&&0===k?Y?s:n:"")+this._generateMonthYearHeader(e,Z,et,X,$,k>0||D>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",N=d?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",x=0;7>x;x++)C=(x+u)%7,N+="<th scope='col'"+((x+u+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+c[C]+"'>"+p[C]+"</span></th>";for(M+=N+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),I=(this._getFirstDayOfMonth(et,Z)-u+7)%7,P=Math.ceil((I+A)/7),F=G?this.maxRows>P?this.maxRows:P:P,this.maxRows=F,H=this._daylightSavingAdjust(new Date(et,Z,1-I)),z=0;F>z;z++){for(M+="<tr>",j=d?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(H)+"</td>":"",x=0;7>x;x++)E=g?g.apply(e.input?e.input[0]:null,[H]):[!0,""],O=H.getMonth()!==Z,L=O&&!y||!E[0]||X&&X>H||$&&H>$,j+="<td class='"+((x+u+6)%7>=5?" ui-datepicker-week-end":"")+(O?" ui-datepicker-other-month":"")+(H.getTime()===T.getTime()&&Z===e.selectedMonth&&e._keyEvent||b.getTime()===H.getTime()&&b.getTime()===T.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(O&&!v?"":" "+E[1]+(H.getTime()===Q.getTime()?" "+this._currentClass:"")+(H.getTime()===R.getTime()?" ui-datepicker-today":""))+"'"+(O&&!v||!E[2]?"":" title='"+E[2].replace(/'/g,"'")+"'")+(L?"":" data-handler='selectDay' data-event='click' data-month='"+H.getMonth()+"' data-year='"+H.getFullYear()+"'")+">"+(O&&!v?" ":L?"<span class='ui-state-default'>"+H.getDate()+"</span>":"<a class='ui-state-default"+(H.getTime()===R.getTime()?" ui-state-highlight":"")+(H.getTime()===Q.getTime()?" ui-state-active":"")+(O?" ui-priority-secondary":"")+"' href='#'>"+H.getDate()+"</a>")+"</td>",H.setDate(H.getDate()+1),H=this._daylightSavingAdjust(H);M+=j+"</tr>"}Z++,Z>11&&(Z=0,et++),M+="</tbody></table>"+(G?"</div>"+(V[0]>0&&D===V[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),w+=M}_+=w}return _+=l,e._keyEvent=!1,_},_generateMonthYearHeader:function(e,t,i,s,a,n,r,o){var h,l,u,d,c,p,f,m,g=this._get(e,"changeMonth"),v=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",_="";if(n||!g)_+="<span class='ui-datepicker-month'>"+r[t]+"</span>";else{for(h=s&&s.getFullYear()===i,l=a&&a.getFullYear()===i,_+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",u=0;12>u;u++)(!h||u>=s.getMonth())&&(!l||a.getMonth()>=u)&&(_+="<option value='"+u+"'"+(u===t?" selected='selected'":"")+">"+o[u]+"</option>");_+="</select>"}if(y||(b+=_+(!n&&g&&v?"":" ")),!e.yearshtml)if(e.yearshtml="",n||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(d=this._get(e,"yearRange").split(":"),c=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?c+parseInt(e,10):parseInt(e,10);return isNaN(t)?c:t},f=p(d[0]),m=Math.max(f,p(d[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=a?Math.min(m,a.getFullYear()):m,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)e.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";e.yearshtml+="</select>",b+=e.yearshtml,e.yearshtml=null}return b+=this._get(e,"yearSuffix"),y&&(b+=(!n&&g&&v?"":" ")+_),b+="</div>"},_adjustInstDate:function(e,t,i){var s=e.drawYear+("Y"===i?t:0),a=e.drawMonth+("M"===i?t:0),n=Math.min(e.selectedDay,this._getDaysInMonth(s,a))+("D"===i?t:0),r=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(s,a,n)));e.selectedDay=r.getDate(),e.drawMonth=e.selectedMonth=r.getMonth(),e.drawYear=e.selectedYear=r.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),s=this._getMinMaxDate(e,"max"),a=i&&i>t?i:t;return s&&a>s?s:a},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,s){var a=this._getNumberOfMonths(e),n=this._daylightSavingAdjust(new Date(i,s+(0>t?t:a[0]*a[1]),1));return 0>t&&n.setDate(this._getDaysInMonth(n.getFullYear(),n.getMonth())),this._isInRange(e,n)},_isInRange:function(e,t){var i,s,a=this._getMinMaxDate(e,"min"),n=this._getMinMaxDate(e,"max"),r=null,o=null,h=this._get(e,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),r=parseInt(i[0],10),o=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(r+=s),i[1].match(/[+\-].*/)&&(o+=s)),(!a||t.getTime()>=a.getTime())&&(!n||t.getTime()<=n.getTime())&&(!r||t.getFullYear()>=r)&&(!o||o>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,s){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var a=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(s,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),a,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new a,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.11.0",e.datepicker,e.widget("ui.dialog",{version:"1.11.0",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"Close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i,s=this;if(this._isOpen&&this._trigger("beforeClose",t)!==!1){if(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&e(i).blur()}catch(a){}this._hide(this.uiDialog,this.options.hide,function(){s._trigger("close",t)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,i){var s=!1,a=this.uiDialog.siblings(".ui-front:visible").map(function(){return+e(this).css("z-index")}).get(),n=Math.max.apply(null,a);return n>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",n+1),s=!0),s&&!i&&this._trigger("focus",t),s},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._trigger("open"),void 0)},_focusTabbable:function(){var e=this._focusedElement;e||(e=this.element.find("[autofocus]")),e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()
|
||
},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),void 0;if(t.keyCode===e.ui.keyCode.TAB&&!t.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),a=i.filter(":last");t.target!==a[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==s[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){a.focus()}),t.preventDefault()):(this._delay(function(){s.focus()}),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html(" "),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),void 0):(e.each(i,function(i,s){var a,n;s=e.isFunction(s)?{click:s,text:i}:s,s=e.extend({type:"button"},s),a=s.click,s.click=function(){a.apply(t.element[0],arguments)},n={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,e("<button></button>",s).button(n).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,a){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,t(a))},drag:function(e,s){i._trigger("drag",e,t(s))},stop:function(a,n){var r=n.offset.left-i.document.scrollLeft(),o=n.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(o>=0?"+":"")+o,of:i.window},e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",a,t(n))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,s=this.options,a=s.resizable,n=this.uiDialog.css("position"),r="string"==typeof a?a:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:r,start:function(s,a){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,t(a))},resize:function(e,s){i._trigger("resize",e,t(s))},stop:function(a,n){var r=i.uiDialog.offset(),o=r.left-i.document.scrollLeft(),h=r.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(o>=0?"+":"")+o+" "+"top"+(h>=0?"+":"")+h,of:i.window},e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",a,t(n))}}).css("position",n)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._untrackInstance(),this._trackingInstances().unshift(this),this._focusedElement=e(t.target)}})},_untrackInstance:function(){var t=this._trackingInstances(),i=e.inArray(this,t);-1!==i&&t.splice(i,1)},_trackingInstances:function(){var e=this.document.data("ui-dialog-instances");return e||(e=[],this.document.data("ui-dialog-instances",e)),e},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,a={};e.each(t,function(e,t){i._setOption(e,t),e in i.sizeRelatedOptions&&(s=!0),e in i.resizableRelatedOptions&&(a[e]=t)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",a)},_setOption:function(e,t){var i,s,a=this.uiDialog;"dialogClass"===e&&a.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=a.is(":data(ui-draggable)"),i&&!t&&a.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(s=a.is(":data(ui-resizable)"),s&&!t&&a.resizable("destroy"),s&&"string"==typeof t&&a.resizable("option","handles",t),s||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),e=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),t=Math.max(0,s.minHeight-e),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-e):"none","auto"===s.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=!0;this._delay(function(){t=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(e){t||this._allowInteraction(e)||(e.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var e=this.document.data("ui-dialog-overlays")-1;e?this.document.data("ui-dialog-overlays",e):this.document.unbind("focusin").removeData("ui-dialog-overlays"),this.overlay.remove(),this.overlay=null}}}),e.widget("ui.progressbar",{version:"1.11.0",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return void 0===e?this.options.value:(this.options.value=this._constrainedValue(e),this._refreshValue(),void 0)},_constrainedValue:function(e){return void 0===e&&(e=this.options.value),this.indeterminate=e===!1,"number"!=typeof e&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){"max"===e&&(t=Math.max(this.min,t)),"disabled"===e&&this.element.toggleClass("ui-state-disabled",!!t).attr("aria-disabled",t),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),e.widget("ui.selectmenu",{version:"1.11.0",defaultElement:"<select>",options:{appendTo:null,disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:null,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this.options.disabled&&this.disable()},_drawButton:function(){var t=this,i=this.element.attr("tabindex");this.label=e("label[for='"+this.ids.element+"']").attr("for",this.ids.button),this._on(this.label,{click:function(e){this.button.focus(),e.preventDefault()}}),this.element.hide(),this.button=e("<span>",{"class":"ui-selectmenu-button ui-widget ui-state-default ui-corner-all",tabindex:i||this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true"}).insertAfter(this.element),e("<span>",{"class":"ui-icon "+this.options.icons.button}).prependTo(this.button),this.buttonText=e("<span>",{"class":"ui-selectmenu-text"}).appendTo(this.button),this._setText(this.buttonText,this.element.find("option:selected").text()),this._setOption("width",this.options.width),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){t.menuItems||t._refreshMenu()}),this._hoverable(this.button),this._focusable(this.button)},_drawMenu:function(){var t=this;this.menu=e("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=e("<div>",{"class":"ui-selectmenu-menu ui-front"}).append(this.menu).appendTo(this._appendTo()),this.menuInstance=this.menu.menu({role:"listbox",select:function(e,i){e.preventDefault(),t._select(i.item.data("ui-selectmenu-item"),e)},focus:function(e,i){var s=i.item.data("ui-selectmenu-item");null!=t.focusIndex&&s.index!==t.focusIndex&&(t._trigger("focus",e,{item:s}),t.isOpen||t._select(s,e)),t.focusIndex=s.index,t.button.attr("aria-activedescendant",t.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menu.addClass("ui-corner-bottom").removeClass("ui-corner-all"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this._setText(this.buttonText,this._getSelectedItem().text()),this._setOption("width",this.options.width)},_refreshMenu:function(){this.menu.empty();var e,t=this.element.find("option");t.length&&(this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup"),e=this._getSelectedItem(),this.menuInstance.focus(null,e),this._setAria(e.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(e){this.options.disabled||(this.menuItems?(this.menu.find(".ui-state-focus").removeClass("ui-state-focus"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",e))},_position:function(){this.menuWrap.position(e.extend({of:this.button},this.options.position))},close:function(e){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this._off(this.document),this._trigger("close",e))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderMenu:function(t,i){var s=this,a="";e.each(i,function(i,n){n.optgroup!==a&&(e("<li>",{"class":"ui-selectmenu-optgroup ui-menu-divider"+(n.element.parent("optgroup").prop("disabled")?" ui-state-disabled":""),text:n.optgroup}).appendTo(t),a=n.optgroup),s._renderItemData(t,n)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-selectmenu-item",t)},_renderItem:function(t,i){var s=e("<li>");return i.disabled&&s.addClass("ui-state-disabled"),this._setText(s,i.label),s.appendTo(t)},_setText:function(e,t){t?e.text(t):e.html(" ")},_move:function(e,t){var i,s,a=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex):(i=this.menuItems.eq(this.element[0].selectedIndex),a+=":not(.ui-state-disabled)"),s="first"===e||"last"===e?i["first"===e?"prevAll":"nextAll"](a).eq(-1):i[e+"All"](a).eq(0),s.length&&this.menuInstance.focus(t,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex)},_toggle:function(e){this[this.isOpen?"close":"open"](e)},_documentClick:{mousedown:function(t){this.isOpen&&(e(t.target).closest(".ui-selectmenu-menu, #"+this.ids.button).length||this.close(t))}},_buttonEvents:{click:"_toggle",keydown:function(t){var i=!0;switch(t.keyCode){case e.ui.keyCode.TAB:case e.ui.keyCode.ESCAPE:this.close(t),i=!1;break;case e.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case e.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case e.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case e.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case e.ui.keyCode.LEFT:this._move("prev",t);break;case e.ui.keyCode.RIGHT:this._move("next",t);break;case e.ui.keyCode.HOME:case e.ui.keyCode.PAGE_UP:this._move("first",t);break;case e.ui.keyCode.END:case e.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),i=!1}i&&t.preventDefault()}},_selectFocusedItem:function(e){var t=this.menuItems.eq(this.focusIndex);t.hasClass("ui-state-disabled")||this._select(t.data("ui-selectmenu-item"),e)},_select:function(e,t){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=e.index,this._setText(this.buttonText,e.label),this._setAria(e),this._trigger("select",t,{item:e}),e.index!==i&&this._trigger("change",t,{item:e}),this.close(t)},_setAria:function(e){var t=this.menuItems.eq(e.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(e,t){"icons"===e&&this.button.find("span.ui-icon").removeClass(this.options.icons.button).addClass(t.button),this._super(e,t),"appendTo"===e&&this.menuWrap.appendTo(this._appendTo()),"disabled"===e&&(this.menuInstance.option("disabled",t),this.button.toggleClass("ui-state-disabled",t).attr("aria-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)),"width"===e&&(t||(t=this.element.outerWidth()),this.button.outerWidth(t))},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t&&t[0]||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_toggleAttr:function(){this.button.toggleClass("ui-corner-top",this.isOpen).toggleClass("ui-corner-all",!this.isOpen).attr("aria-expanded",this.isOpen),this.menuWrap.toggleClass("ui-selectmenu-open",this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){return{disabled:this.element.prop("disabled")}},_parseOptions:function(t){var i=[];t.each(function(t,s){var a=e(s),n=a.parent("optgroup");i.push({element:a,index:t,value:a.attr("value"),label:a.text(),optgroup:n.attr("label")||"",disabled:n.prop("disabled")||a.prop("disabled")})}),this.items=i},_destroy:function(){this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.label.attr("for",this.ids.element)}}),e.widget("ui.slider",e.ui.mouse,{version:"1.11.0",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,i,s=this.options,a=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),n="<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",r=[];for(i=s.values&&s.values.length||1,a.length>i&&(a.slice(i).remove(),a=a.slice(0,i)),t=a.length;i>t;t++)r.push(n);this.handles=a.add(e(r.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)})},_createRange:function(){var t=this.options,i="";t.range?(t.range===!0&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:e.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=e("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===t.range||"max"===t.range?" ui-slider-range-"+t.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var i,s,a,n,r,o,h,l,u=this,d=this.options;return d.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:t.pageX,y:t.pageY},s=this._normValueFromMouse(i),a=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var i=Math.abs(s-u.values(t));(a>i||a===i&&(t===u._lastChangedValue||u.values(t)===d.min))&&(a=i,n=e(this),r=t)}),o=this._start(t,r),o===!1?!1:(this._mouseSliding=!0,this._handleIndex=r,n.addClass("ui-state-active").focus(),h=n.offset(),l=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:t.pageX-h.left-n.width()/2,top:t.pageY-h.top-n.height()/2-(parseInt(n.css("borderTopWidth"),10)||0)-(parseInt(n.css("borderBottomWidth"),10)||0)+(parseInt(n.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,r,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},i=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,i),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,i,s,a,n;return"horizontal"===this.orientation?(t=this.elementSize.width,i=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,i=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/t,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),a=this._valueMax()-this._valueMin(),n=this._valueMin()+s*a,this._trimAlignValue(n)},_start:function(e,t){var i={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("start",e,i)},_slide:function(e,t,i){var s,a,n;this.options.values&&this.options.values.length?(s=this.values(t?0:1),2===this.options.values.length&&this.options.range===!0&&(0===t&&i>s||1===t&&s>i)&&(i=s),i!==this.values(t)&&(a=this.values(),a[t]=i,n=this._trigger("slide",e,{handle:this.handles[t],value:i,values:a}),s=this.values(t?0:1),n!==!1&&this.values(t,i))):i!==this.value()&&(n=this._trigger("slide",e,{handle:this.handles[t],value:i}),n!==!1&&this.value(i))},_stop:function(e,t){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._trigger("stop",e,i)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(t),i.values=this.values()),this._lastChangedValue=t,this._trigger("change",e,i)}},value:function(e){return arguments.length?(this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(t,i){var s,a,n;if(arguments.length>1)return this.options.values[t]=this._trimAlignValue(i),this._refreshValue(),this._change(null,t),void 0;if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();for(s=this.options.values,a=arguments[0],n=0;s.length>n;n+=1)s[n]=this._trimAlignValue(a[n]),this._change(null,n);this._refreshValue()},_setOption:function(t,i){var s,a=0;switch("range"===t&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),e.isArray(this.options.values)&&(a=this.options.values.length),"disabled"===t&&this.element.toggleClass("ui-state-disabled",!!i),this._super(t,i),t){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;a>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e)},_values:function(e){var t,i,s;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(e){if(this._valueMin()>=e)return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,i=(e-this._valueMin())%t,s=e-i;return 2*Math.abs(i)>=t&&(s+=i>0?t:-t),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,i,s,a,n,r=this.options.range,o=this.options,h=this,l=this._animateOff?!1:o.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",e(this).stop(1,1)[l?"animate":"css"](u,o.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},o.animate),1===s&&h.range[l?"animate":"css"]({width:i-t+"%"},{queue:!1,duration:o.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},o.animate),1===s&&h.range[l?"animate":"css"]({height:i-t+"%"},{queue:!1,duration:o.animate}))),t=i}):(s=this.value(),a=this._valueMin(),n=this._valueMax(),i=n!==a?100*((s-a)/(n-a)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,o.animate),"min"===r&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},o.animate),"max"===r&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:o.animate}),"min"===r&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},o.animate),"max"===r&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:o.animate}))},_handleEvents:{keydown:function(t){var i,s,a,n,r=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,e(t.target).addClass("ui-state-active"),i=this._start(t,r),i===!1))return}switch(n=this.options.step,s=a=this.options.values&&this.options.values.length?this.values(r):this.value(),t.keyCode){case e.ui.keyCode.HOME:a=this._valueMin();break;case e.ui.keyCode.END:a=this._valueMax();break;case e.ui.keyCode.PAGE_UP:a=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.PAGE_DOWN:a=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(s===this._valueMax())return;a=this._trimAlignValue(s+n);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(s===this._valueMin())return;a=this._trimAlignValue(s-n)}this._slide(t,r,a)},keyup:function(t){var i=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,i),this._change(t,i),e(t.target).removeClass("ui-state-active"))}}}),e.widget("ui.spinner",{version:"1.11.0",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},i=this.element;return e.each(["min","max","step"],function(e,s){var a=i.attr(s);void 0!==a&&a.length&&(t[s]=a)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e),void 0)},mousewheel:function(e,t){if(t){if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()}},"mousedown .ui-spinner-button":function(t){function i(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(t)!==!1&&this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){return e(t.currentTarget).hasClass("ui-state-active")?this._start(t)===!1?!1:(this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*e.height())&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var i=this.options,s=e.ui.keyCode;switch(t.keyCode){case s.UP:return this._repeat(null,1,t),!0;case s.DOWN:return this._repeat(null,-1,t),!0;case s.PAGE_UP:return this._repeat(null,i.page,t),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>▲</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>▼</span>"+"</a>"},_start:function(e){return this.spinning||this._trigger("start",e)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(e,t,i){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,i)},e),this._spin(t*this.options.step,i)},_spin:function(e,t){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+e*this._increment(this.counter)),this.spinning&&this._trigger("spin",t,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(t){var i=this.options.incremental;return i?e.isFunction(i)?i(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return null!==this.options.min&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=""+e,i=t.indexOf(".");return-1===i?0:t.length-i-1},_adjustValue:function(e){var t,i,s=this.options;return t=null!==s.min?s.min:0,i=e-t,i=Math.round(i/s.step)*s.step,e=t+i,e=parseFloat(e.toFixed(this._precision())),null!==s.max&&e>s.max?s.max:null!==s.min&&s.min>e?s.min:e
|
||
},_stop:function(e){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e))},_setOption:function(e,t){if("culture"===e||"numberFormat"===e){var i=this._parse(this.element.val());return this.options[e]=t,this.element.val(this._format(i)),void 0}("max"===e||"min"===e||"step"===e)&&"string"==typeof t&&(t=this._parse(t)),"icons"===e&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(t.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(t.down)),this._super(e,t),"disabled"===e&&(this.widget().toggleClass("ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable"))},_setOptions:o(function(e){this._super(e)}),_parse:function(e){return"string"==typeof e&&""!==e&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),""===e||isNaN(e)?null:e},_format:function(e){return""===e?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var e=this.value();return null===e?!1:e===this._adjustValue(e)},_value:function(e,t){var i;""!==e&&(i=this._parse(e),null!==i&&(t||(i=this._adjustValue(i)),e=this._format(i))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:o(function(e){this._stepUp(e)}),_stepUp:function(e){this._start()&&(this._spin((e||1)*this.options.step),this._stop())},stepDown:o(function(e){this._stepDown(e)}),_stepDown:function(e){this._start()&&(this._spin((e||1)*-this.options.step),this._stop())},pageUp:o(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:o(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){return arguments.length?(o(this._value).call(this,e),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),e.widget("ui.tabs",{version:"1.11.0",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var e=/#.*$/;return function(t){var i,s;t=t.cloneNode(!1),i=t.href.replace(e,""),s=location.href.replace(e,"");try{i=decodeURIComponent(i)}catch(a){}try{s=decodeURIComponent(s)}catch(a){}return t.hash.length>1&&i===s}}(),_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var t=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===t&&(s&&this.tabs.each(function(i,a){return e(a).attr("aria-controls")===s?(t=i,!1):void 0}),null===t&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===t||-1===t)&&(t=this.tabs.length?0:!1)),t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),-1===t&&(t=i?!1:0)),!i&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var i=e(this.document[0].activeElement).closest("li"),s=this.tabs.index(i),a=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:s++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:a=!1,s--;break;case e.ui.keyCode.END:s=this.anchors.length-1;break;case e.ui.keyCode.HOME:s=0;break;case e.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case e.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}t.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,a),t.ctrlKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){return t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,i){function s(){return t>a&&(t=0),0>t&&(t=a),t}for(var a=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):"disabled"===e?(this._setupDisabled(t),void 0):(this._super(e,t),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",t),t||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(t),"heightStyle"===e&&this._setupHeightStyle(t),void 0)},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,s){var a,n,r,o=e(s).uniqueId().attr("id"),h=e(s).closest("li"),l=h.attr("aria-controls");t._isLocal(s)?(a=s.hash,r=a.substring(1),n=t.element.find(t._sanitizeSelector(a))):(r=h.attr("aria-controls")||e({}).uniqueId()[0].id,a="#"+r,n=t.element.find(a),n.length||(n=t._createPanel(r),n.insertAfter(t.panels[i-1]||t.tablist)),n.attr("aria-live","polite")),n.length&&(t.panels=t.panels.add(n)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":r,"aria-labelledby":o}),n.attr("aria-labelledby",o)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(e){e.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,a=e(t.currentTarget),n=a.closest("li"),r=n[0]===s[0],o=r&&i.collapsible,h=o?e():this._getPanelForTab(n),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:o?e():n,newPanel:h};t.preventDefault(),n.hasClass("ui-state-disabled")||n.hasClass("ui-tabs-loading")||this.running||r&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=o?!1:this.tabs.index(n),this.active=r?e():n,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(n),t),this._toggle(t,u))},_toggle:function(t,i){function s(){n.running=!1,n._trigger("activate",t,i)}function a(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&n.options.show?n._show(r,n.options.show,s):(r.show(),s())}var n=this,r=i.newPanel,o=i.oldPanel;this.running=!0,o.length&&this.options.hide?this._hide(o,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),a()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),o.hide(),a()),o.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),r.length&&o.length?i.oldTab.attr("tabIndex",-1):r.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),r.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(t){var i=this.options.disabled;i!==!1&&(void 0===t?i=!1:(t=this._getIndex(t),i=e.isArray(i)?e.map(i,function(e){return e!==t?e:null}):e.map(this.tabs,function(e,i){return i!==t?i:null})),this._setupDisabled(i))},disable:function(t){var i=this.options.disabled;if(i!==!0){if(void 0===t)i=!0;else{if(t=this._getIndex(t),-1!==e.inArray(t,i))return;i=e.isArray(i)?e.merge([t],i).sort():[t]}this._setupDisabled(i)}},load:function(t,i){t=this._getIndex(t);var s=this,a=this.tabs.eq(t),n=a.find(".ui-tabs-anchor"),r=this._getPanelForTab(a),o={tab:a,panel:r};this._isLocal(n[0])||(this.xhr=e.ajax(this._ajaxSettings(n,i,o)),this.xhr&&"canceled"!==this.xhr.statusText&&(a.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){r.html(e),s._trigger("load",i,o)},1)}).complete(function(e,t){setTimeout(function(){"abort"===t&&s.panels.stop(!1,!0),a.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),e===s.xhr&&delete s.xhr},1)})))},_ajaxSettings:function(t,i,s){var a=this;return{url:t.attr("href"),beforeSend:function(t,n){return a._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:n},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),e.widget("ui.tooltip",{version:"1.11.0",options:{content:function(){var t=e(this).attr("title")||"";return e("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_addDescribedBy:function(t,i){var s=(t.attr("aria-describedby")||"").split(/\s+/);s.push(i),t.data("ui-tooltip-id",i).attr("aria-describedby",e.trim(s.join(" ")))},_removeDescribedBy:function(t){var i=t.data("ui-tooltip-id"),s=(t.attr("aria-describedby")||"").split(/\s+/),a=e.inArray(i,s);-1!==a&&s.splice(a,1),t.removeData("ui-tooltip-id"),s=e.trim(s.join(" ")),s?t.attr("aria-describedby",s):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable(),this.liveRegion=e("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).addClass("ui-helper-hidden-accessible").appendTo(this.document[0].body)},_setOption:function(t,i){var s=this;return"disabled"===t?(this[i?"_disable":"_enable"](),this.options[t]=i,void 0):(this._super(t,i),"content"===t&&e.each(this.tooltips,function(e,t){s._updateContent(t)}),void 0)},_disable:function(){var t=this;e.each(this.tooltips,function(i,s){var a=e.Event("blur");a.target=a.currentTarget=s[0],t.close(a,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var i=this,s=e(t?t.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&s.parents().each(function(){var t,s=e(this);s.data("ui-tooltip-open")&&(t=e.Event("blur"),t.target=t.currentTarget=this,i.close(t,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,t))},_updateContent:function(e,t){var i,s=this.options.content,a=this,n=t?t.type:null;return"string"==typeof s?this._open(t,e,s):(i=s.call(e[0],function(i){e.data("ui-tooltip-open")&&a._delay(function(){t&&(t.type=n),this._open(t,e,i)})}),i&&this._open(t,e,i),void 0)},_open:function(t,i,s){function a(e){l.of=e,n.is(":hidden")||n.position(l)}var n,r,o,h,l=e.extend({},this.options.position);if(s){if(n=this._find(i),n.length)return n.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(t&&"mouseover"===t.type?i.attr("title",""):i.removeAttr("title")),n=this._tooltip(i),this._addDescribedBy(i,n.attr("id")),n.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),s.clone?(h=s.clone(),h.removeAttr("id").find("[id]").removeAttr("id")):h=s,e("<div>").html(h).appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:a}),a(t)):n.position(e.extend({of:i},this.options.position)),n.hide(),this._show(n,this.options.show),this.options.show&&this.options.show.delay&&(o=this.delayedShow=setInterval(function(){n.is(":visible")&&(a(l.of),clearInterval(o))},e.fx.interval)),this._trigger("open",t,{tooltip:n}),r={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var s=e.Event(t);s.currentTarget=i[0],this.close(s,!0)}}},i[0]!==this.element[0]&&(r.remove=function(){this._removeTooltip(n)}),t&&"mouseover"!==t.type||(r.mouseleave="close"),t&&"focusin"!==t.type||(r.focusout="close"),this._on(!0,i,r)}},close:function(t){var i=this,s=e(t?t.currentTarget:this.element),a=this._find(s);this.closing||(clearInterval(this.delayedShow),s.data("ui-tooltip-title")&&!s.attr("title")&&s.attr("title",s.data("ui-tooltip-title")),this._removeDescribedBy(s),a.stop(!0),this._hide(a,this.options.hide,function(){i._removeTooltip(e(this))}),s.removeData("ui-tooltip-open"),this._off(s,"mouseleave focusout keyup"),s[0]!==this.element[0]&&this._off(s,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&e.each(this.parents,function(t,s){e(s.element).attr("title",s.title),delete i.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:a}),this.closing=!1)},_tooltip:function(t){var i=e("<div>").attr("role","tooltip").addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||"")),s=i.uniqueId().attr("id");return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),this.tooltips[s]=t,i},_find:function(t){var i=t.data("ui-tooltip-id");return i?e("#"+i):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(i,s){var a=e.Event("blur");a.target=a.currentTarget=s[0],t.close(a,!0),e("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title")||s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}});var v="ui-effects-";e.effects={effect:{}},function(e,t){function i(e,t,i){var s=d[t.type]||{};return null==e?i||!t.def?null:t.def:(e=s.floor?~~e:parseFloat(e),isNaN(e)?t.def:s.mod?(e+s.mod)%s.mod:0>e?0:e>s.max?s.max:e)}function s(i){var s=l(),a=s._rgba=[];return i=i.toLowerCase(),f(h,function(e,n){var r,o=n.re.exec(i),h=o&&n.parse(o),l=n.space||"rgba";return h?(r=s[l](h),s[u[l].cache]=r[u[l].cache],a=s._rgba=r._rgba,!1):t}),a.length?("0,0,0,0"===a.join()&&e.extend(a,n.transparent),s):n[i]}function a(e,t,i){return i=(i+1)%1,1>6*i?e+6*(t-e)*i:1>2*i?t:2>3*i?e+6*(t-e)*(2/3-i):e}var n,r="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",o=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(e){return[2.55*e[1],2.55*e[2],2.55*e[3],e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],l=e.Color=function(t,i,s,a){return new e.Color.fn.parse(t,i,s,a)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},d={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},c=l.support={},p=e("<p>")[0],f=e.each;p.style.cssText="background-color:rgba(1,1,1,.5)",c.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),l.fn=e.extend(l.prototype,{parse:function(a,r,o,h){if(a===t)return this._rgba=[null,null,null,null],this;(a.jquery||a.nodeType)&&(a=e(a).css(r),r=t);var d=this,c=e.type(a),p=this._rgba=[];return r!==t&&(a=[a,r,o,h],c="array"),"string"===c?this.parse(s(a)||n._default):"array"===c?(f(u.rgba.props,function(e,t){p[t.idx]=i(a[t.idx],t)}),this):"object"===c?(a instanceof l?f(u,function(e,t){a[t.cache]&&(d[t.cache]=a[t.cache].slice())}):f(u,function(t,s){var n=s.cache;f(s.props,function(e,t){if(!d[n]&&s.to){if("alpha"===e||null==a[e])return;d[n]=s.to(d._rgba)}d[n][t.idx]=i(a[e],t,!0)}),d[n]&&0>e.inArray(null,d[n].slice(0,3))&&(d[n][3]=1,s.from&&(d._rgba=s.from(d[n])))}),this):t},is:function(e){var i=l(e),s=!0,a=this;return f(u,function(e,n){var r,o=i[n.cache];return o&&(r=a[n.cache]||n.to&&n.to(a._rgba)||[],f(n.props,function(e,i){return null!=o[i.idx]?s=o[i.idx]===r[i.idx]:t})),s}),s},_space:function(){var e=[],t=this;return f(u,function(i,s){t[s.cache]&&e.push(i)}),e.pop()},transition:function(e,t){var s=l(e),a=s._space(),n=u[a],r=0===this.alpha()?l("transparent"):this,o=r[n.cache]||n.to(r._rgba),h=o.slice();return s=s[n.cache],f(n.props,function(e,a){var n=a.idx,r=o[n],l=s[n],u=d[a.type]||{};null!==l&&(null===r?h[n]=l:(u.mod&&(l-r>u.mod/2?r+=u.mod:r-l>u.mod/2&&(r-=u.mod)),h[n]=i((l-r)*t+r,a)))}),this[a](h)},blend:function(t){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),a=l(t)._rgba;return l(e.map(i,function(e,t){return(1-s)*a[t]+s*e}))},toRgbaString:function(){var t="rgba(",i=e.map(this._rgba,function(e,t){return null==e?t>2?1:0:e});return 1===i[3]&&(i.pop(),t="rgb("),t+i.join()+")"},toHslaString:function(){var t="hsla(",i=e.map(this.hsla(),function(e,t){return null==e&&(e=t>2?1:0),t&&3>t&&(e=Math.round(100*e)+"%"),e});return 1===i[3]&&(i.pop(),t="hsl("),t+i.join()+")"},toHexString:function(t){var i=this._rgba.slice(),s=i.pop();return t&&i.push(~~(255*s)),"#"+e.map(i,function(e){return e=(e||0).toString(16),1===e.length?"0"+e:e}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,u.hsla.to=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t,i,s=e[0]/255,a=e[1]/255,n=e[2]/255,r=e[3],o=Math.max(s,a,n),h=Math.min(s,a,n),l=o-h,u=o+h,d=.5*u;return t=h===o?0:s===o?60*(a-n)/l+360:a===o?60*(n-s)/l+120:60*(s-a)/l+240,i=0===l?0:.5>=d?l/u:l/(2-u),[Math.round(t)%360,i,d,null==r?1:r]},u.hsla.from=function(e){if(null==e[0]||null==e[1]||null==e[2])return[null,null,null,e[3]];var t=e[0]/360,i=e[1],s=e[2],n=e[3],r=.5>=s?s*(1+i):s+i-s*i,o=2*s-r;return[Math.round(255*a(o,r,t+1/3)),Math.round(255*a(o,r,t)),Math.round(255*a(o,r,t-1/3)),n]},f(u,function(s,a){var n=a.props,r=a.cache,h=a.to,u=a.from;l.fn[s]=function(s){if(h&&!this[r]&&(this[r]=h(this._rgba)),s===t)return this[r].slice();var a,o=e.type(s),d="array"===o||"object"===o?s:arguments,c=this[r].slice();return f(n,function(e,t){var s=d["object"===o?e:t.idx];null==s&&(s=c[t.idx]),c[t.idx]=i(s,t)}),u?(a=l(u(c)),a[r]=c,a):l(c)},f(n,function(t,i){l.fn[t]||(l.fn[t]=function(a){var n,r=e.type(a),h="alpha"===t?this._hsla?"hsla":"rgba":s,l=this[h](),u=l[i.idx];return"undefined"===r?u:("function"===r&&(a=a.call(this,u),r=e.type(a)),null==a&&i.empty?this:("string"===r&&(n=o.exec(a),n&&(a=u+parseFloat(n[2])*("+"===n[1]?1:-1))),l[i.idx]=a,this[h](l)))})})}),l.hook=function(t){var i=t.split(" ");f(i,function(t,i){e.cssHooks[i]={set:function(t,a){var n,r,o="";if("transparent"!==a&&("string"!==e.type(a)||(n=s(a)))){if(a=l(n||a),!c.rgba&&1!==a._rgba[3]){for(r="backgroundColor"===i?t.parentNode:t;(""===o||"transparent"===o)&&r&&r.style;)try{o=e.css(r,"backgroundColor"),r=r.parentNode}catch(h){}a=a.blend(o&&"transparent"!==o?o:"_default")}a=a.toRgbaString()}try{t.style[i]=a}catch(h){}}},e.fx.step[i]=function(t){t.colorInit||(t.start=l(t.elem,i),t.end=l(t.end),t.colorInit=!0),e.cssHooks[i].set(t.elem,t.start.transition(t.end,t.pos))}})},l.hook(r),e.cssHooks.borderColor={expand:function(e){var t={};return f(["Top","Right","Bottom","Left"],function(i,s){t["border"+s+"Color"]=e}),t}},n=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function t(t){var i,s,a=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,n={};if(a&&a.length&&a[0]&&a[a[0]])for(s=a.length;s--;)i=a[s],"string"==typeof a[i]&&(n[e.camelCase(i)]=a[i]);else for(i in a)"string"==typeof a[i]&&(n[i]=a[i]);return n}function i(t,i){var s,n,r={};for(s in i)n=i[s],t[s]!==n&&(a[s]||(e.fx.step[s]||!isNaN(parseFloat(n)))&&(r[s]=n));return r}var s=["add","remove","toggle"],a={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,i){e.fx.step[i]=function(e){("none"!==e.end&&!e.setAttr||1===e.pos&&!e.setAttr)&&(jQuery.style(e.elem,i,e.end),e.setAttr=!0)}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(a,n,r,o){var h=e.speed(n,r,o);return this.queue(function(){var n,r=e(this),o=r.attr("class")||"",l=h.children?r.find("*").addBack():r;l=l.map(function(){var i=e(this);return{el:i,start:t(this)}}),n=function(){e.each(s,function(e,t){a[t]&&r[t+"Class"](a[t])})},n(),l=l.map(function(){return this.end=t(this.el[0]),this.diff=i(this.start,this.end),this}),r.attr("class",o),l=l.map(function(){var t=this,i=e.Deferred(),s=e.extend({},h,{queue:!1,complete:function(){i.resolve(t)}});return this.el.animate(this.diff,s),i.promise()}),e.when.apply(e,l.get()).done(function(){n(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),h.complete.call(r[0])})})},e.fn.extend({addClass:function(t){return function(i,s,a,n){return s?e.effects.animateClass.call(this,{add:i},s,a,n):t.apply(this,arguments)}}(e.fn.addClass),removeClass:function(t){return function(i,s,a,n){return arguments.length>1?e.effects.animateClass.call(this,{remove:i},s,a,n):t.apply(this,arguments)}}(e.fn.removeClass),toggleClass:function(t){return function(i,s,a,n,r){return"boolean"==typeof s||void 0===s?a?e.effects.animateClass.call(this,s?{add:i}:{remove:i},a,n,r):t.apply(this,arguments):e.effects.animateClass.call(this,{toggle:i},s,a,n)}}(e.fn.toggleClass),switchClass:function(t,i,s,a,n){return e.effects.animateClass.call(this,{add:i,remove:t},s,a,n)}})}(),function(){function t(t,i,s,a){return e.isPlainObject(t)&&(i=t,t=t.effect),t={effect:t},null==i&&(i={}),e.isFunction(i)&&(a=i,s=null,i={}),("number"==typeof i||e.fx.speeds[i])&&(a=s,s=i,i={}),e.isFunction(s)&&(a=s,s=null),i&&e.extend(t,i),s=s||i.duration,t.duration=e.fx.off?0:"number"==typeof s?s:s in e.fx.speeds?e.fx.speeds[s]:e.fx.speeds._default,t.complete=a||i.complete,t}function i(t){return!t||"number"==typeof t||e.fx.speeds[t]?!0:"string"!=typeof t||e.effects.effect[t]?e.isFunction(t)?!0:"object"!=typeof t||t.effect?!1:!0:!0}e.extend(e.effects,{version:"1.11.0",save:function(e,t){for(var i=0;t.length>i;i++)null!==t[i]&&e.data(v+t[i],e[0].style[t[i]])},restore:function(e,t){var i,s;for(s=0;t.length>s;s++)null!==t[s]&&(i=e.data(v+t[s]),void 0===i&&(i=""),e.css(t[s],i))},setMode:function(e,t){return"toggle"===t&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var i,s;switch(e[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=e[0]/t.height}switch(e[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=e[1]/t.width}return{x:s,y:i}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var i={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},s=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),a={width:t.width(),height:t.height()},n=document.activeElement;try{n.id}catch(r){n=document.body}return t.wrap(s),(t[0]===n||e.contains(t[0],n))&&e(n).focus(),s=t.parent(),"static"===t.css("position")?(s.css({position:"relative"}),t.css({position:"relative"})):(e.extend(i,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,s){i[s]=t.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(a),s.css(i).show()},removeWrapper:function(t){var i=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===i||e.contains(t[0],i))&&e(i).focus()),t},setTransition:function(t,i,s,a){return a=a||{},e.each(i,function(e,i){var n=t.cssUnit(i);n[0]>0&&(a[i]=n[0]*s+n[1])}),a}}),e.fn.extend({effect:function(){function i(t){function i(){e.isFunction(n)&&n.call(a[0]),e.isFunction(t)&&t()}var a=e(this),n=s.complete,o=s.mode;(a.is(":hidden")?"hide"===o:"show"===o)?(a[o](),i()):r.call(a[0],s,i)}var s=t.apply(this,arguments),a=s.mode,n=s.queue,r=e.effects.effect[s.effect];return e.fx.off||!r?a?this[a](s.duration,s.complete):this.each(function(){s.complete&&s.complete.call(this)}):n===!1?this.each(i):this.queue(n||"fx",i)},show:function(e){return function(s){if(i(s))return e.apply(this,arguments);var a=t.apply(this,arguments);return a.mode="show",this.effect.call(this,a)}}(e.fn.show),hide:function(e){return function(s){if(i(s))return e.apply(this,arguments);var a=t.apply(this,arguments);return a.mode="hide",this.effect.call(this,a)}}(e.fn.hide),toggle:function(e){return function(s){if(i(s)||"boolean"==typeof s)return e.apply(this,arguments);var a=t.apply(this,arguments);return a.mode="toggle",this.effect.call(this,a)}}(e.fn.toggle),cssUnit:function(t){var i=this.css(t),s=[];return e.each(["em","px","%","pt"],function(e,t){i.indexOf(t)>0&&(s=[parseFloat(i),t])}),s}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,i){t[i]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return 0===e||1===e?e:-Math.pow(2,8*(e-1))*Math.sin((80*(e-1)-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){for(var t,i=4;((t=Math.pow(2,--i))-1)/11>e;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*t-2)/22-e,2)}}),e.each(t,function(t,i){e.easing["easeIn"+t]=i,e.easing["easeOut"+t]=function(e){return 1-i(1-e)},e.easing["easeInOut"+t]=function(e){return.5>e?i(2*e)/2:1-i(-2*e+2)/2}})}(),e.effects,e.effects.effect.blind=function(t,i){var s,a,n,r=e(this),o=/up|down|vertical/,h=/up|left|vertical|horizontal/,l=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(r,t.mode||"hide"),d=t.direction||"up",c=o.test(d),p=c?"height":"width",f=c?"top":"left",m=h.test(d),g={},v="show"===u;
|
||
r.parent().is(".ui-effects-wrapper")?e.effects.save(r.parent(),l):e.effects.save(r,l),r.show(),s=e.effects.createWrapper(r).css({overflow:"hidden"}),a=s[p](),n=parseFloat(s.css(f))||0,g[p]=v?a:0,m||(r.css(c?"bottom":"right",0).css(c?"top":"left","auto").css({position:"absolute"}),g[f]=v?n:a+n),v&&(s.css(p,0),m||s.css(f,n+a)),s.animate(g,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){"hide"===u&&r.hide(),e.effects.restore(r,l),e.effects.removeWrapper(r),i()}})},e.effects.effect.bounce=function(t,i){var s,a,n,r=e(this),o=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(r,t.mode||"effect"),l="hide"===h,u="show"===h,d=t.direction||"up",c=t.distance,p=t.times||5,f=2*p+(u||l?1:0),m=t.duration/f,g=t.easing,v="up"===d||"down"===d?"top":"left",y="up"===d||"left"===d,b=r.queue(),_=b.length;for((u||l)&&o.push("opacity"),e.effects.save(r,o),r.show(),e.effects.createWrapper(r),c||(c=r["top"===v?"outerHeight":"outerWidth"]()/3),u&&(n={opacity:1},n[v]=0,r.css("opacity",0).css(v,y?2*-c:2*c).animate(n,m,g)),l&&(c/=Math.pow(2,p-1)),n={},n[v]=0,s=0;p>s;s++)a={},a[v]=(y?"-=":"+=")+c,r.animate(a,m,g).animate(n,m,g),c=l?2*c:c/2;l&&(a={opacity:0},a[v]=(y?"-=":"+=")+c,r.animate(a,m,g)),r.queue(function(){l&&r.hide(),e.effects.restore(r,o),e.effects.removeWrapper(r),i()}),_>1&&b.splice.apply(b,[1,0].concat(b.splice(_,f+1))),r.dequeue()},e.effects.effect.clip=function(t,i){var s,a,n,r=e(this),o=["position","top","bottom","left","right","height","width"],h=e.effects.setMode(r,t.mode||"hide"),l="show"===h,u=t.direction||"vertical",d="vertical"===u,c=d?"height":"width",p=d?"top":"left",f={};e.effects.save(r,o),r.show(),s=e.effects.createWrapper(r).css({overflow:"hidden"}),a="IMG"===r[0].tagName?s:r,n=a[c](),l&&(a.css(c,0),a.css(p,n/2)),f[c]=l?n:0,f[p]=l?0:n/2,a.animate(f,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){l||r.hide(),e.effects.restore(r,o),e.effects.removeWrapper(r),i()}})},e.effects.effect.drop=function(t,i){var s,a=e(this),n=["position","top","bottom","left","right","opacity","height","width"],r=e.effects.setMode(a,t.mode||"hide"),o="show"===r,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h?"pos":"neg",d={opacity:o?1:0};e.effects.save(a,n),a.show(),e.effects.createWrapper(a),s=t.distance||a["top"===l?"outerHeight":"outerWidth"](!0)/2,o&&a.css("opacity",0).css(l,"pos"===u?-s:s),d[l]=(o?"pos"===u?"+=":"-=":"pos"===u?"-=":"+=")+s,a.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===r&&a.hide(),e.effects.restore(a,n),e.effects.removeWrapper(a),i()}})},e.effects.effect.explode=function(t,i){function s(){b.push(this),b.length===d*c&&a()}function a(){p.css({visibility:"visible"}),e(b).remove(),m||p.hide(),i()}var n,r,o,h,l,u,d=t.pieces?Math.round(Math.sqrt(t.pieces)):3,c=d,p=e(this),f=e.effects.setMode(p,t.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/c),y=Math.ceil(p.outerHeight()/d),b=[];for(n=0;d>n;n++)for(h=g.top+n*y,u=n-(d-1)/2,r=0;c>r;r++)o=g.left+r*v,l=r-(c-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-r*v,top:-n*y}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:y,left:o+(m?l*v:0),top:h+(m?u*y:0),opacity:m?0:1}).animate({left:o+(m?0:l*v),top:h+(m?0:u*y),opacity:m?1:0},t.duration||500,t.easing,s)},e.effects.effect.fade=function(t,i){var s=e(this),a=e.effects.setMode(s,t.mode||"toggle");s.animate({opacity:a},{queue:!1,duration:t.duration,easing:t.easing,complete:i})},e.effects.effect.fold=function(t,i){var s,a,n=e(this),r=["position","top","bottom","left","right","height","width"],o=e.effects.setMode(n,t.mode||"hide"),h="show"===o,l="hide"===o,u=t.size||15,d=/([0-9]+)%/.exec(u),c=!!t.horizFirst,p=h!==c,f=p?["width","height"]:["height","width"],m=t.duration/2,g={},v={};e.effects.save(n,r),n.show(),s=e.effects.createWrapper(n).css({overflow:"hidden"}),a=p?[s.width(),s.height()]:[s.height(),s.width()],d&&(u=parseInt(d[1],10)/100*a[l?0:1]),h&&s.css(c?{height:0,width:u}:{height:u,width:0}),g[f[0]]=h?a[0]:u,v[f[1]]=h?a[1]:0,s.animate(g,m,t.easing).animate(v,m,t.easing,function(){l&&n.hide(),e.effects.restore(n,r),e.effects.removeWrapper(n),i()})},e.effects.effect.highlight=function(t,i){var s=e(this),a=["backgroundImage","backgroundColor","opacity"],n=e.effects.setMode(s,t.mode||"show"),r={backgroundColor:s.css("backgroundColor")};"hide"===n&&(r.opacity=0),e.effects.save(s,a),s.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(r,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===n&&s.hide(),e.effects.restore(s,a),i()}})},e.effects.effect.size=function(t,i){var s,a,n,r=e(this),o=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],u=["fontSize"],d=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],c=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(r,t.mode||"effect"),f=t.restore||"effect"!==p,m=t.scale||"both",g=t.origin||["middle","center"],v=r.css("position"),y=f?o:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&r.show(),s={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},"toggle"===t.mode&&"show"===p?(r.from=t.to||b,r.to=t.from||s):(r.from=t.from||("show"===p?b:s),r.to=t.to||("hide"===p?b:s)),n={from:{y:r.from.height/s.height,x:r.from.width/s.width},to:{y:r.to.height/s.height,x:r.to.width/s.width}},("box"===m||"both"===m)&&(n.from.y!==n.to.y&&(y=y.concat(d),r.from=e.effects.setTransition(r,d,n.from.y,r.from),r.to=e.effects.setTransition(r,d,n.to.y,r.to)),n.from.x!==n.to.x&&(y=y.concat(c),r.from=e.effects.setTransition(r,c,n.from.x,r.from),r.to=e.effects.setTransition(r,c,n.to.x,r.to))),("content"===m||"both"===m)&&n.from.y!==n.to.y&&(y=y.concat(u).concat(l),r.from=e.effects.setTransition(r,u,n.from.y,r.from),r.to=e.effects.setTransition(r,u,n.to.y,r.to)),e.effects.save(r,y),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),g&&(a=e.effects.getBaseline(g,s),r.from.top=(s.outerHeight-r.outerHeight())*a.y,r.from.left=(s.outerWidth-r.outerWidth())*a.x,r.to.top=(s.outerHeight-r.to.outerHeight)*a.y,r.to.left=(s.outerWidth-r.to.outerWidth)*a.x),r.css(r.from),("content"===m||"both"===m)&&(d=d.concat(["marginTop","marginBottom"]).concat(u),c=c.concat(["marginLeft","marginRight"]),l=o.concat(d).concat(c),r.find("*[width]").each(function(){var i=e(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&e.effects.save(i,l),i.from={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},i.to={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x},n.from.y!==n.to.y&&(i.from=e.effects.setTransition(i,d,n.from.y,i.from),i.to=e.effects.setTransition(i,d,n.to.y,i.to)),n.from.x!==n.to.x&&(i.from=e.effects.setTransition(i,c,n.from.x,i.from),i.to=e.effects.setTransition(i,c,n.to.x,i.to)),i.css(i.from),i.animate(i.to,t.duration,t.easing,function(){f&&e.effects.restore(i,l)})})),r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){0===r.to.opacity&&r.css("opacity",r.from.opacity),"hide"===p&&r.hide(),e.effects.restore(r,y),f||("static"===v?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,i){var s=parseInt(i,10),a=e?r.to.left:r.to.top;return"auto"===i?a+"px":s+a+"px"})})),e.effects.removeWrapper(r),i()}})},e.effects.effect.scale=function(t,i){var s=e(this),a=e.extend(!0,{},t),n=e.effects.setMode(s,t.mode||"effect"),r=parseInt(t.percent,10)||(0===parseInt(t.percent,10)?0:"hide"===n?0:100),o=t.direction||"both",h=t.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},u={y:"horizontal"!==o?r/100:1,x:"vertical"!==o?r/100:1};a.effect="size",a.queue=!1,a.complete=i,"effect"!==n&&(a.origin=h||["middle","center"],a.restore=!0),a.from=t.from||("show"===n?{height:0,width:0,outerHeight:0,outerWidth:0}:l),a.to={height:l.height*u.y,width:l.width*u.x,outerHeight:l.outerHeight*u.y,outerWidth:l.outerWidth*u.x},a.fade&&("show"===n&&(a.from.opacity=0,a.to.opacity=1),"hide"===n&&(a.from.opacity=1,a.to.opacity=0)),s.effect(a)},e.effects.effect.puff=function(t,i){var s=e(this),a=e.effects.setMode(s,t.mode||"hide"),n="hide"===a,r=parseInt(t.percent,10)||150,o=r/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:a,complete:i,percent:n?r:100,from:n?h:{height:h.height*o,width:h.width*o,outerHeight:h.outerHeight*o,outerWidth:h.outerWidth*o}}),s.effect(t)},e.effects.effect.pulsate=function(t,i){var s,a=e(this),n=e.effects.setMode(a,t.mode||"show"),r="show"===n,o="hide"===n,h=r||"hide"===n,l=2*(t.times||5)+(h?1:0),u=t.duration/l,d=0,c=a.queue(),p=c.length;for((r||!a.is(":visible"))&&(a.css("opacity",0).show(),d=1),s=1;l>s;s++)a.animate({opacity:d},u,t.easing),d=1-d;a.animate({opacity:d},u,t.easing),a.queue(function(){o&&a.hide(),i()}),p>1&&c.splice.apply(c,[1,0].concat(c.splice(p,l+1))),a.dequeue()},e.effects.effect.shake=function(t,i){var s,a=e(this),n=["position","top","bottom","left","right","height","width"],r=e.effects.setMode(a,t.mode||"effect"),o=t.direction||"left",h=t.distance||20,l=t.times||3,u=2*l+1,d=Math.round(t.duration/u),c="up"===o||"down"===o?"top":"left",p="up"===o||"left"===o,f={},m={},g={},v=a.queue(),y=v.length;for(e.effects.save(a,n),a.show(),e.effects.createWrapper(a),f[c]=(p?"-=":"+=")+h,m[c]=(p?"+=":"-=")+2*h,g[c]=(p?"-=":"+=")+2*h,a.animate(f,d,t.easing),s=1;l>s;s++)a.animate(m,d,t.easing).animate(g,d,t.easing);a.animate(m,d,t.easing).animate(f,d/2,t.easing).queue(function(){"hide"===r&&a.hide(),e.effects.restore(a,n),e.effects.removeWrapper(a),i()}),y>1&&v.splice.apply(v,[1,0].concat(v.splice(y,u+1))),a.dequeue()},e.effects.effect.slide=function(t,i){var s,a=e(this),n=["position","top","bottom","left","right","width","height"],r=e.effects.setMode(a,t.mode||"show"),o="show"===r,h=t.direction||"left",l="up"===h||"down"===h?"top":"left",u="up"===h||"left"===h,d={};e.effects.save(a,n),a.show(),s=t.distance||a["top"===l?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(a).css({overflow:"hidden"}),o&&a.css(l,u?isNaN(s)?"-"+s:-s:s),d[l]=(o?u?"+=":"-=":u?"-=":"+=")+s,a.animate(d,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){"hide"===r&&a.hide(),e.effects.restore(a,n),e.effects.removeWrapper(a),i()}})},e.effects.effect.transfer=function(t,i){var s=e(this),a=e(t.to),n="fixed"===a.css("position"),r=e("body"),o=n?r.scrollTop():0,h=n?r.scrollLeft():0,l=a.offset(),u={top:l.top-o,left:l.left-h,height:a.innerHeight(),width:a.innerWidth()},d=s.offset(),c=e("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(t.className).css({top:d.top-o,left:d.left-h,height:s.innerHeight(),width:s.innerWidth(),position:n?"fixed":"absolute"}).animate(u,t.duration,t.easing,function(){c.remove(),i()})}});
|
||
/*!
|
||
* Bootstrap v3.2.0 (http://getbootstrap.com)
|
||
* Copyright 2011-2014 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
*/
|
||
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.2.0",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.2.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b).on("keydown.bs.carousel",a.proxy(this.keydown,this)),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.2.0",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.to=function(b){var c=this,d=this.getItemIndex(this.$active=this.$element.find(".item.active"));return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,f&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(e)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one("bsTransitionEnd",function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(m)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.2.0",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(){this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.one("bsTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.2.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f+', [role="menu"], [role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.2.0",c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.$body.addClass("modal-open"),this.setScrollbar(),this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(c.$body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one("bsTransitionEnd",function(){c.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(300):c.$element.trigger("focus").trigger(e)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.$body.removeClass("modal-open"),this.resetScrollbar(),this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;if(this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;e?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(150):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var f=function(){c.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",f).emulateTransitionEnd(150):f()}else b&&b()},c.prototype.checkScrollbar=function(){document.body.clientWidth>=window.innerWidth||(this.scrollbarWidth=this.scrollbarWidth||this.measureScrollbar())},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.scrollbarWidth&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.2.0",c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var c=a.contains(document.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!c)return;var d=this,e=this.tip(),f=this.getUID(this.type);this.setContent(),e.attr("id",f),this.$element.attr("aria-describedby",f),this.options.animation&&e.addClass("fade");var g="function"==typeof this.options.placement?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,h=/\s?auto?\s?/i,i=h.test(g);i&&(g=g.replace(h,"")||"top"),e.detach().css({top:0,left:0,display:"block"}).addClass(g).data("bs."+this.type,this),this.options.container?e.appendTo(this.options.container):e.insertAfter(this.$element);var j=this.getPosition(),k=e[0].offsetWidth,l=e[0].offsetHeight;if(i){var m=g,n=this.$element.parent(),o=this.getPosition(n);g="bottom"==g&&j.top+j.height+l-o.scroll>o.height?"top":"top"==g&&j.top-o.scroll-l<0?"bottom":"right"==g&&j.right+k>o.width?"left":"left"==g&&j.left-k<o.left?"right":g,e.removeClass(m).addClass(g)}var p=this.getCalculatedOffset(g,j,k,l);this.applyPlacement(p,g);var q=function(){d.$element.trigger("shown.bs."+d.type),d.hoverState=null};a.support.transition&&this.$tip.hasClass("fade")?e.one("bsTransitionEnd",q).emulateTransitionEnd(150):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=k.left?2*k.left-e+i:2*k.top-f+j,m=k.left?"left":"top",n=k.left?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(l,d[0][n],m)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.removeAttr("aria-describedby"),this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one("bsTransitionEnd",b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName;return a.extend({},"function"==typeof c.getBoundingClientRect?c.getBoundingClientRect():null,{scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop(),width:d?a(window).width():b.outerWidth(),height:d?a(window).height():b.outerHeight()},d?{top:0,left:0}:b.offset())},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||"destroy"!=b)&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.2.0",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").empty()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.2.0",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.2.0",c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.closest("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},c.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one("bsTransitionEnd",e).emulateTransitionEnd(150):e(),f.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(c){c.preventDefault(),b.call(a(this),"show")})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.2.0",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=a(document).height(),d=this.$target.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=b-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){null!=this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:b-this.$element.height()-h}))}}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},d.offsetBottom&&(d.offset.bottom=d.offsetBottom),d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
|
||
/*! DataTables 1.10.0
|
||
* ©2008-2014 SpryMedia Ltd - datatables.net/license
|
||
*/
|
||
|
||
/**
|
||
* @summary DataTables
|
||
* @description Paginate, search and order HTML tables
|
||
* @version 1.10.0
|
||
* @file jquery.dataTables.js
|
||
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
||
* @contact www.sprymedia.co.uk/contact
|
||
* @copyright Copyright 2008-2014 SpryMedia Ltd.
|
||
*
|
||
* This source file is free software, available under the following license:
|
||
* MIT license - http://datatables.net/license
|
||
*
|
||
* This source file is distributed in the hope that it will be useful, but
|
||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
||
*
|
||
* For details please refer to: http://www.datatables.net
|
||
*/
|
||
|
||
/*jslint evil: true, undef: true, browser: true */
|
||
/*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,_fnInvalidateRow,_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,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
|
||
|
||
(/** @lends <global> */function( window, document, undefined ) {
|
||
|
||
(function( factory ) {
|
||
"use strict";
|
||
|
||
if ( typeof define === 'function' && define.amd ) {
|
||
// Define as an AMD module if possible
|
||
define( 'datatables', ['jquery'], factory );
|
||
}
|
||
else if ( typeof exports === 'object' ) {
|
||
// Node/CommonJS
|
||
factory( require( 'jquery' ) );
|
||
}
|
||
else if ( jQuery && !jQuery.fn.dataTable ) {
|
||
// Define using browser globals otherwise
|
||
// Prevent multiple instantiations if the script is loaded twice
|
||
factory( jQuery );
|
||
}
|
||
}
|
||
(/** @lends <global> */function( $ ) {
|
||
"use strict";
|
||
|
||
/**
|
||
* DataTables is a plug-in for the jQuery Javascript library. It is a highly
|
||
* flexible tool, based upon the foundations of progressive enhancement,
|
||
* which will add advanced interaction controls to any HTML table. For a
|
||
* full list of features please refer to
|
||
* [DataTables.net](href="http://datatables.net).
|
||
*
|
||
* Note that the `DataTable` object is not a global variable but is aliased
|
||
* to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
|
||
* be accessed.
|
||
*
|
||
* @class
|
||
* @param {object} [init={}] Configuration object for DataTables. Options
|
||
* are defined by {@link DataTable.defaults}
|
||
* @requires jQuery 1.7+
|
||
*
|
||
* @example
|
||
* // Basic initialisation
|
||
* $(document).ready( function {
|
||
* $('#example').dataTable();
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Initialisation with configuration options - in this case, disable
|
||
* // pagination and sorting.
|
||
* $(document).ready( function {
|
||
* $('#example').dataTable( {
|
||
* "paginate": false,
|
||
* "sort": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
var DataTable;
|
||
|
||
|
||
/*
|
||
* It is useful to have variables which are scoped locally so only the
|
||
* DataTables functions can access them and they don't leak into global space.
|
||
* At the same time these functions are often useful over multiple files in the
|
||
* core and API, so we list, or at least document, all variables which are used
|
||
* by DataTables as private variables here. This also ensures that there is no
|
||
* clashing of variable names and that they can easily referenced for reuse.
|
||
*/
|
||
|
||
|
||
// Defined else where
|
||
// _selector_run
|
||
// _selector_opts
|
||
// _selector_first
|
||
// _selector_row_indexes
|
||
|
||
var _ext; // DataTable.ext
|
||
var _Api; // DataTable.Api
|
||
var _api_register; // DataTable.Api.register
|
||
var _api_registerPlural; // DataTable.Api.registerPlural
|
||
|
||
var _re_dic = {};
|
||
var _re_new_lines = /[\r\n]/g;
|
||
var _re_html = /<.*?>/g;
|
||
var _re_date_start = /^[\d\+\-a-zA-Z]/;
|
||
|
||
// Escape regular expression special characters
|
||
var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
|
||
|
||
// U+2009 is thin space and U+202F is narrow no-break space, both used in many
|
||
// standards as thousands separators
|
||
var _re_formatted_numeric = /[',$£€¥%\u2009\u202F]/g;
|
||
|
||
|
||
var _empty = function ( d ) {
|
||
return !d || d === '-' ? true : false;
|
||
};
|
||
|
||
|
||
var _intVal = function ( s ) {
|
||
var integer = parseInt( s, 10 );
|
||
return !isNaN(integer) && isFinite(s) ? integer : null;
|
||
};
|
||
|
||
// Convert from a formatted number with characters other than `.` as the
|
||
// decimal place, to a Javascript number
|
||
var _numToDecimal = function ( num, decimalPoint ) {
|
||
// Cache created regular expressions for speed as this function is called often
|
||
if ( ! _re_dic[ decimalPoint ] ) {
|
||
_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
|
||
}
|
||
return typeof num === 'string' ?
|
||
num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
|
||
num;
|
||
};
|
||
|
||
|
||
var _isNumber = function ( d, decimalPoint, formatted ) {
|
||
var strType = typeof d === 'string';
|
||
|
||
if ( decimalPoint && strType ) {
|
||
d = _numToDecimal( d, decimalPoint );
|
||
}
|
||
|
||
if ( formatted && strType ) {
|
||
d = d.replace( _re_formatted_numeric, '' );
|
||
}
|
||
|
||
return !d || d==='-' || (!isNaN( parseFloat(d) ) && isFinite( d ));
|
||
};
|
||
|
||
|
||
// A string without HTML in it can be considered to be HTML still
|
||
var _isHtml = function ( d ) {
|
||
return !d || typeof d === 'string';
|
||
};
|
||
|
||
|
||
var _htmlNumeric = function ( d, decimalPoint, formatted ) {
|
||
if ( _empty( d ) ) {
|
||
return true;
|
||
}
|
||
|
||
var html = _isHtml( d );
|
||
return ! html ?
|
||
null :
|
||
_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
|
||
true :
|
||
null;
|
||
};
|
||
|
||
|
||
var _pluck = function ( a, prop, prop2 ) {
|
||
var out = [];
|
||
var i=0, ien=a.length;
|
||
|
||
// Could have the test in the loop for slightly smaller code, but speed
|
||
// is essential here
|
||
if ( prop2 !== undefined ) {
|
||
for ( ; i<ien ; i++ ) {
|
||
if ( a[i] && a[i][ prop ] ) {
|
||
out.push( a[i][ prop ][ prop2 ] );
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
for ( ; i<ien ; i++ ) {
|
||
if ( a[i] ) {
|
||
out.push( a[i][ prop ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
// Basically the same as _pluck, but rather than looping over `a` we use `order`
|
||
// as the indexes to pick from `a`
|
||
var _pluck_order = function ( a, order, prop, prop2 )
|
||
{
|
||
var out = [];
|
||
var i=0, ien=order.length;
|
||
|
||
// Could have the test in the loop for slightly smaller code, but speed
|
||
// is essential here
|
||
if ( prop2 !== undefined ) {
|
||
for ( ; i<ien ; i++ ) {
|
||
out.push( a[ order[i] ][ prop ][ prop2 ] );
|
||
}
|
||
}
|
||
else {
|
||
for ( ; i<ien ; i++ ) {
|
||
out.push( a[ order[i] ][ prop ] );
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _range = function ( len, start )
|
||
{
|
||
var out = [];
|
||
var end;
|
||
|
||
if ( start === undefined ) {
|
||
start = 0;
|
||
end = len;
|
||
}
|
||
else {
|
||
end = start;
|
||
start = len;
|
||
}
|
||
|
||
for ( var i=start ; i<end ; i++ ) {
|
||
out.push( i );
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _stripHtml = function ( d ) {
|
||
return d.replace( _re_html, '' );
|
||
};
|
||
|
||
|
||
/**
|
||
* Find the unique elements in a source array.
|
||
*
|
||
* @param {array} src Source array
|
||
* @return {array} Array of unique items
|
||
* @ignore
|
||
*/
|
||
var _unique = function ( src )
|
||
{
|
||
// A faster unique method is to use object keys to identify used values,
|
||
// but this doesn't work with arrays or objects, which we must also
|
||
// consider. See jsperf.com/compare-array-unique-versions/4 for more
|
||
// information.
|
||
var
|
||
out = [],
|
||
val,
|
||
i, ien=src.length,
|
||
j, k=0;
|
||
|
||
again: for ( i=0 ; i<ien ; i++ ) {
|
||
val = src[i];
|
||
|
||
for ( j=0 ; j<k ; j++ ) {
|
||
if ( out[j] === val ) {
|
||
continue again;
|
||
}
|
||
}
|
||
|
||
out.push( val );
|
||
k++;
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Create a mapping object that allows camel case parameters to be looked up
|
||
* for their Hungarian counterparts. The mapping is stored in a private
|
||
* parameter called `_hungarianMap` which can be accessed on the source object.
|
||
* @param {object} o
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnHungarianMap ( o )
|
||
{
|
||
var
|
||
hungarian = 'a aa ai ao as b fn i m o s ',
|
||
match,
|
||
newKey,
|
||
map = {};
|
||
|
||
$.each( o, function (key, val) {
|
||
match = key.match(/^([^A-Z]+?)([A-Z])/);
|
||
|
||
if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
|
||
{
|
||
newKey = key.replace( match[0], match[2].toLowerCase() );
|
||
map[ newKey ] = key;
|
||
|
||
//console.log( key, match );
|
||
if ( match[1] === 'o' )
|
||
{
|
||
_fnHungarianMap( o[key] );
|
||
}
|
||
}
|
||
} );
|
||
|
||
o._hungarianMap = map;
|
||
}
|
||
|
||
|
||
/**
|
||
* Convert from camel case parameters to Hungarian, based on a Hungarian map
|
||
* created by _fnHungarianMap.
|
||
* @param {object} src The model object which holds all parameters that can be
|
||
* mapped.
|
||
* @param {object} user The object to convert from camel case to Hungarian.
|
||
* @param {boolean} force When set to `true`, properties which already have a
|
||
* Hungarian value in the `user` object will be overwritten. Otherwise they
|
||
* won't be.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCamelToHungarian ( src, user, force )
|
||
{
|
||
if ( ! src._hungarianMap ) {
|
||
_fnHungarianMap( src );
|
||
}
|
||
|
||
var hungarianKey;
|
||
|
||
$.each( user, function (key, val) {
|
||
hungarianKey = src._hungarianMap[ key ];
|
||
|
||
if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
|
||
{
|
||
// For objects, we need to buzz down into the object to copy parameters
|
||
if ( hungarianKey.charAt(0) === 'o' )
|
||
{
|
||
// Copy the camelCase options over to the hungarian
|
||
if ( ! user[ hungarianKey ] ) {
|
||
user[ hungarianKey ] = {};
|
||
}
|
||
$.extend( true, user[hungarianKey], user[key] );
|
||
|
||
_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
|
||
}
|
||
else {
|
||
user[hungarianKey] = user[ key ];
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Language compatibility - when certain options are given, and others aren't, we
|
||
* need to duplicate the values over, in order to provide backwards compatibility
|
||
* with older language files.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLanguageCompat( lang )
|
||
{
|
||
var defaults = DataTable.defaults.oLanguage;
|
||
var zeroRecords = lang.sZeroRecords;
|
||
|
||
/* Backwards compatibility - if there is no sEmptyTable given, then use the same as
|
||
* sZeroRecords - assuming that is given.
|
||
*/
|
||
if ( ! lang.sEmptyTable && zeroRecords &&
|
||
defaults.sEmptyTable === "No data available in table" )
|
||
{
|
||
_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
|
||
}
|
||
|
||
/* Likewise with loading records */
|
||
if ( ! lang.sLoadingRecords && zeroRecords &&
|
||
defaults.sLoadingRecords === "Loading..." )
|
||
{
|
||
_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
|
||
}
|
||
|
||
// Old parameter name of the thousands separator mapped onto the new
|
||
if ( lang.sInfoThousands ) {
|
||
lang.sThousands = lang.sInfoThousands;
|
||
}
|
||
|
||
var decimal = lang.sDecimal;
|
||
if ( decimal ) {
|
||
_addNumericSort( decimal );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Map one parameter onto another
|
||
* @param {object} o Object to map
|
||
* @param {*} knew The new parameter name
|
||
* @param {*} old The old parameter name
|
||
*/
|
||
var _fnCompatMap = function ( o, knew, old ) {
|
||
if ( o[ knew ] !== undefined ) {
|
||
o[ old ] = o[ knew ];
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Provide backwards compatibility for the main DT options. Note that the new
|
||
* options are mapped onto the old parameters, so this is an external interface
|
||
* change only.
|
||
* @param {object} init Object to map
|
||
*/
|
||
function _fnCompatOpts ( init )
|
||
{
|
||
_fnCompatMap( init, 'ordering', 'bSort' );
|
||
_fnCompatMap( init, 'orderMulti', 'bSortMulti' );
|
||
_fnCompatMap( init, 'orderClasses', 'bSortClasses' );
|
||
_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
|
||
_fnCompatMap( init, 'order', 'aaSorting' );
|
||
_fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
|
||
_fnCompatMap( init, 'paging', 'bPaginate' );
|
||
_fnCompatMap( init, 'pagingType', 'sPaginationType' );
|
||
_fnCompatMap( init, 'pageLength', 'iDisplayLength' );
|
||
_fnCompatMap( init, 'searching', 'bFilter' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Provide backwards compatibility for column options. Note that the new options
|
||
* are mapped onto the old parameters, so this is an external interface change
|
||
* only.
|
||
* @param {object} init Object to map
|
||
*/
|
||
function _fnCompatCols ( init )
|
||
{
|
||
_fnCompatMap( init, 'orderable', 'bSortable' );
|
||
_fnCompatMap( init, 'orderData', 'aDataSort' );
|
||
_fnCompatMap( init, 'orderSequence', 'asSorting' );
|
||
_fnCompatMap( init, 'orderDataType', 'sortDataType' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Browser feature detection for capabilities, quirks
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBrowserDetect( settings )
|
||
{
|
||
var browser = settings.oBrowser;
|
||
|
||
// Scrolling feature / quirks detection
|
||
var n = $('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
height: 1,
|
||
width: 1,
|
||
overflow: 'hidden'
|
||
} )
|
||
.append(
|
||
$('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 1,
|
||
left: 1,
|
||
width: 100,
|
||
overflow: 'scroll'
|
||
} )
|
||
.append(
|
||
$('<div class="test"/>')
|
||
.css( {
|
||
width: '100%',
|
||
height: 10
|
||
} )
|
||
)
|
||
)
|
||
.appendTo( 'body' );
|
||
|
||
var test = n.find('.test');
|
||
|
||
// IE6/7 will oversize a width 100% element inside a scrolling element, to
|
||
// include the width of the scrollbar, while other browsers ensure the inner
|
||
// element is contained without forcing scrolling
|
||
browser.bScrollOversize = test[0].offsetWidth === 100;
|
||
|
||
// In rtl text layout, some browsers (most, but not all) will place the
|
||
// scrollbar on the left, rather than the right.
|
||
browser.bScrollbarLeft = test.offset().left !== 1;
|
||
|
||
n.remove();
|
||
}
|
||
|
||
|
||
/**
|
||
* Array.prototype reduce[Right] method, used for browsers which don't support
|
||
* JS 1.6. Done this way to reduce code size, since we iterate either way
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnReduce ( that, fn, init, start, end, inc )
|
||
{
|
||
var
|
||
i = start,
|
||
value,
|
||
isSet = false;
|
||
|
||
if ( init !== undefined ) {
|
||
value = init;
|
||
isSet = true;
|
||
}
|
||
|
||
while ( i !== end ) {
|
||
if ( ! that.hasOwnProperty(i) ) {
|
||
continue;
|
||
}
|
||
|
||
value = isSet ?
|
||
fn( value, that[i], i, that ) :
|
||
that[i];
|
||
|
||
isSet = true;
|
||
i += inc;
|
||
}
|
||
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* Add a column to the list used for the table with default values
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} nTh The th element for this column
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddColumn( oSettings, nTh )
|
||
{
|
||
// Add column to aoColumns array
|
||
var oDefaults = DataTable.defaults.column;
|
||
var iCol = oSettings.aoColumns.length;
|
||
var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
|
||
"nTh": nTh ? nTh : document.createElement('th'),
|
||
"sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
|
||
"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
|
||
"mData": oDefaults.mData ? oDefaults.mData : iCol,
|
||
idx: iCol
|
||
} );
|
||
oSettings.aoColumns.push( oCol );
|
||
|
||
// Add search object for column specific search. Note that the `searchCols[ iCol ]`
|
||
// passed into extend can be undefined. This allows the user to give a default
|
||
// with only some of the parameters defined, and also not give a default
|
||
var searchCols = oSettings.aoPreSearchCols;
|
||
searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
|
||
|
||
// Use the default column options function to initialise classes etc
|
||
_fnColumnOptions( oSettings, iCol, null );
|
||
}
|
||
|
||
|
||
/**
|
||
* Apply options for a column
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iCol column index to consider
|
||
* @param {object} oOptions object with sType, bVisible and bSearchable etc
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnOptions( oSettings, iCol, oOptions )
|
||
{
|
||
var oCol = oSettings.aoColumns[ iCol ];
|
||
var oClasses = oSettings.oClasses;
|
||
var th = $(oCol.nTh);
|
||
|
||
// Try to get width information from the DOM. We can't get it from CSS
|
||
// as we'd need to parse the CSS stylesheet. `width` option can override
|
||
if ( ! oCol.sWidthOrig ) {
|
||
// Width attribute
|
||
oCol.sWidthOrig = th.attr('width') || null;
|
||
|
||
// Style attribute
|
||
var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%])/);
|
||
if ( t ) {
|
||
oCol.sWidthOrig = t[1];
|
||
}
|
||
}
|
||
|
||
/* User specified column options */
|
||
if ( oOptions !== undefined && oOptions !== null )
|
||
{
|
||
// Backwards compatibility
|
||
_fnCompatCols( oOptions );
|
||
|
||
// Map camel case parameters to their Hungarian counterparts
|
||
_fnCamelToHungarian( DataTable.defaults.column, oOptions );
|
||
|
||
/* Backwards compatibility for mDataProp */
|
||
if ( oOptions.mDataProp !== undefined && !oOptions.mData )
|
||
{
|
||
oOptions.mData = oOptions.mDataProp;
|
||
}
|
||
|
||
if ( oOptions.sType )
|
||
{
|
||
oCol._sManualType = oOptions.sType;
|
||
}
|
||
|
||
// `class` is a reserved word in Javascript, so we need to provide
|
||
// the ability to use a valid name for the camel case input
|
||
if ( oOptions.className && ! oOptions.sClass )
|
||
{
|
||
oOptions.sClass = oOptions.className;
|
||
}
|
||
|
||
$.extend( oCol, oOptions );
|
||
_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
|
||
|
||
/* iDataSort to be applied (backwards compatibility), but aDataSort will take
|
||
* priority if defined
|
||
*/
|
||
if ( typeof oOptions.iDataSort === 'number' )
|
||
{
|
||
oCol.aDataSort = [ oOptions.iDataSort ];
|
||
}
|
||
_fnMap( oCol, oOptions, "aDataSort" );
|
||
}
|
||
|
||
/* Cache the data get and set functions for speed */
|
||
var mDataSrc = oCol.mData;
|
||
var mData = _fnGetObjectDataFn( mDataSrc );
|
||
var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
|
||
|
||
var attrTest = function( src ) {
|
||
return typeof src === 'string' && src.indexOf('@') !== -1;
|
||
};
|
||
oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
|
||
attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
|
||
);
|
||
|
||
oCol.fnGetData = function (oData, sSpecific) {
|
||
var innerData = mData( oData, sSpecific );
|
||
|
||
if ( oCol.mRender && (sSpecific && sSpecific !== '') )
|
||
{
|
||
return mRender( innerData, sSpecific, oData );
|
||
}
|
||
return innerData;
|
||
};
|
||
oCol.fnSetData = _fnSetObjectDataFn( mDataSrc );
|
||
|
||
/* Feature sorting overrides column specific when off */
|
||
if ( !oSettings.oFeatures.bSort )
|
||
{
|
||
oCol.bSortable = false;
|
||
th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
|
||
}
|
||
|
||
/* Check that the class assignment is correct for sorting */
|
||
var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
|
||
var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
|
||
if ( !oCol.bSortable || (!bAsc && !bDesc) )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableNone;
|
||
oCol.sSortingClassJUI = "";
|
||
}
|
||
else if ( bAsc && !bDesc )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableAsc;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
|
||
}
|
||
else if ( !bAsc && bDesc )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableDesc;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
|
||
}
|
||
else
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortable;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUI;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Adjust the table column widths for new data. Note: you would probably want to
|
||
* do a redraw after calling this function!
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAdjustColumnSizing ( settings )
|
||
{
|
||
/* Not interested in doing column width calculation if auto-width is disabled */
|
||
if ( settings.oFeatures.bAutoWidth !== false )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
|
||
_fnCalculateColumnWidths( settings );
|
||
for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
columns[i].nTh.style.width = columns[i].sWidth;
|
||
}
|
||
}
|
||
|
||
var scroll = settings.oScroll;
|
||
if ( scroll.sY !== '' || scroll.sX !== '')
|
||
{
|
||
_fnScrollDraw( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'column-sizing', [settings] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Covert the index of a visible column to the index in the data array (take account
|
||
* of hidden columns)
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iMatch Visible column index to lookup
|
||
* @returns {int} i the data index
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnVisibleToColumnIndex( oSettings, iMatch )
|
||
{
|
||
var aiVis = _fnGetColumns( oSettings, 'bVisible' );
|
||
|
||
return typeof aiVis[iMatch] === 'number' ?
|
||
aiVis[iMatch] :
|
||
null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Covert the index of an index in the data array and convert it to the visible
|
||
* column index (take account of hidden columns)
|
||
* @param {int} iMatch Column index to lookup
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {int} i the data index
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnIndexToVisible( oSettings, iMatch )
|
||
{
|
||
var aiVis = _fnGetColumns( oSettings, 'bVisible' );
|
||
var iPos = $.inArray( iMatch, aiVis );
|
||
|
||
return iPos !== -1 ? iPos : null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the number of visible columns
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {int} i the number of visible columns
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnVisbleColumns( oSettings )
|
||
{
|
||
return _fnGetColumns( oSettings, 'bVisible' ).length;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get an array of column indexes that match a given property
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sParam Parameter in aoColumns to look for - typically
|
||
* bVisible or bSearchable
|
||
* @returns {array} Array of indexes with matched properties
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetColumns( oSettings, sParam )
|
||
{
|
||
var a = [];
|
||
|
||
$.map( oSettings.aoColumns, function(val, i) {
|
||
if ( val[sParam] ) {
|
||
a.push( i );
|
||
}
|
||
} );
|
||
|
||
return a;
|
||
}
|
||
|
||
|
||
/**
|
||
* Calculate the 'type' of a column
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnTypes ( settings )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
var data = settings.aoData;
|
||
var types = DataTable.ext.type.detect;
|
||
var i, ien, j, jen, k, ken;
|
||
var col, cell, detectedType, cache;
|
||
|
||
// For each column, spin over the
|
||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||
col = columns[i];
|
||
cache = [];
|
||
|
||
if ( ! col.sType && col._sManualType ) {
|
||
col.sType = col._sManualType;
|
||
}
|
||
else if ( ! col.sType ) {
|
||
for ( j=0, jen=types.length ; j<jen ; j++ ) {
|
||
for ( k=0, ken=data.length ; k<ken ; k++ ) {
|
||
// Use a cache array so we only need to get the type data
|
||
// from the formatter once (when using multiple detectors)
|
||
if ( cache[k] === undefined ) {
|
||
cache[k] = _fnGetCellData( settings, k, i, 'type' );
|
||
}
|
||
|
||
detectedType = types[j]( cache[k], settings );
|
||
|
||
// Doesn't match, so break early, since this type can't
|
||
// apply to this column. Also, HTML is a special case since
|
||
// it is so similar to `string`. Just a single match is
|
||
// needed for a column to be html type
|
||
if ( ! detectedType || detectedType === 'html' ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Type is valid for all data points in the column - use this
|
||
// type
|
||
if ( detectedType ) {
|
||
col.sType = detectedType;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Fall back - if no type was detected, always use string
|
||
if ( ! col.sType ) {
|
||
col.sType = 'string';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Take the column definitions and static columns arrays and calculate how
|
||
* they relate to column indexes. The callback function will then apply the
|
||
* definition found for a column to a suitable configuration object.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} aoColDefs The aoColumnDefs array that is to be applied
|
||
* @param {array} aoCols The aoColumns array that defines columns individually
|
||
* @param {function} fn Callback function - takes two parameters, the calculated
|
||
* column index and the definition for that column.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
|
||
{
|
||
var i, iLen, j, jLen, k, kLen, def;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
// Column definitions with aTargets
|
||
if ( aoColDefs )
|
||
{
|
||
/* Loop over the definitions array - loop in reverse so first instance has priority */
|
||
for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
|
||
{
|
||
def = aoColDefs[i];
|
||
|
||
/* Each definition can target multiple columns, as it is an array */
|
||
var aTargets = def.targets !== undefined ?
|
||
def.targets :
|
||
def.aTargets;
|
||
|
||
if ( ! $.isArray( aTargets ) )
|
||
{
|
||
aTargets = [ aTargets ];
|
||
}
|
||
|
||
for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
|
||
{
|
||
if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
|
||
{
|
||
/* Add columns that we don't yet know about */
|
||
while( columns.length <= aTargets[j] )
|
||
{
|
||
_fnAddColumn( oSettings );
|
||
}
|
||
|
||
/* Integer, basic index */
|
||
fn( aTargets[j], def );
|
||
}
|
||
else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
|
||
{
|
||
/* Negative integer, right to left column counting */
|
||
fn( columns.length+aTargets[j], def );
|
||
}
|
||
else if ( typeof aTargets[j] === 'string' )
|
||
{
|
||
/* Class name matching on TH element */
|
||
for ( k=0, kLen=columns.length ; k<kLen ; k++ )
|
||
{
|
||
if ( aTargets[j] == "_all" ||
|
||
$(columns[k].nTh).hasClass( aTargets[j] ) )
|
||
{
|
||
fn( k, def );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Statically defined columns array
|
||
if ( aoCols )
|
||
{
|
||
for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
|
||
{
|
||
fn( i, aoCols[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add a data array to the table, creating DOM node etc. This is the parallel to
|
||
* _fnGatherData, but for adding rows from a Javascript source, rather than a
|
||
* DOM source.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} aData data array to be added
|
||
* @param {node} [nTr] TR element to add to the table - optional. If not given,
|
||
* DataTables will create a row automatically
|
||
* @param {array} [anTds] Array of TD|TH elements for the row - must be given
|
||
* if nTr is.
|
||
* @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddData ( oSettings, aDataIn, nTr, anTds )
|
||
{
|
||
/* Create the object for storing information about this new row */
|
||
var iRow = oSettings.aoData.length;
|
||
var oData = $.extend( true, {}, DataTable.models.oRow, {
|
||
src: nTr ? 'dom' : 'data'
|
||
} );
|
||
|
||
oData._aData = aDataIn;
|
||
oSettings.aoData.push( oData );
|
||
|
||
/* Create the cells */
|
||
var nTd, sThisType;
|
||
var columns = oSettings.aoColumns;
|
||
for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
// When working with a row, the data source object must be populated. In
|
||
// all other cases, the data source object is already populated, so we
|
||
// don't overwrite it, which might break bindings etc
|
||
if ( nTr ) {
|
||
_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
|
||
}
|
||
columns[i].sType = null;
|
||
}
|
||
|
||
/* Add to the display array */
|
||
oSettings.aiDisplayMaster.push( iRow );
|
||
|
||
/* Create the DOM information */
|
||
if ( !oSettings.oFeatures.bDeferRender )
|
||
{
|
||
_fnCreateTr( oSettings, iRow, nTr, anTds );
|
||
}
|
||
|
||
return iRow;
|
||
}
|
||
|
||
|
||
/**
|
||
* Add one or more TR elements to the table. Generally we'd expect to
|
||
* use this for reading data from a DOM sourced table, but it could be
|
||
* used for an TR element. Note that if a TR is given, it is used (i.e.
|
||
* it is not cloned).
|
||
* @param {object} settings dataTables settings object
|
||
* @param {array|node|jQuery} trs The TR element(s) to add to the table
|
||
* @returns {array} Array of indexes for the added rows
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddTr( settings, trs )
|
||
{
|
||
var row;
|
||
|
||
// Allow an individual node to be passed in
|
||
if ( ! (trs instanceof $) ) {
|
||
trs = $(trs);
|
||
}
|
||
|
||
return trs.map( function (i, el) {
|
||
row = _fnGetRowElements( settings, el );
|
||
return _fnAddData( settings, row.data, el, row.cells );
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Take a TR element and convert it to an index in aoData
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} n the TR element to find
|
||
* @returns {int} index if the node is found, null if not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnNodeToDataIndex( oSettings, n )
|
||
{
|
||
return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Take a TD element and convert it into a column data index (not the visible index)
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow The row number the TD/TH can be found in
|
||
* @param {node} n The TD/TH element to find
|
||
* @returns {int} index if the node is found, -1 if not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnNodeToColumnIndex( oSettings, iRow, n )
|
||
{
|
||
return $.inArray( n, oSettings.aoData[ iRow ].anCells );
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the data for a given cell from the internal cache, taking into account data mapping
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow aoData row id
|
||
* @param {int} iCol Column index
|
||
* @param {string} sSpecific data get type ('display', 'type' 'filter' 'sort')
|
||
* @returns {*} Cell data
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
|
||
{
|
||
var oCol = oSettings.aoColumns[iCol];
|
||
var oData = oSettings.aoData[iRow]._aData;
|
||
var sData = oCol.fnGetData( oData, sSpecific );
|
||
|
||
if ( sData === undefined )
|
||
{
|
||
if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null )
|
||
{
|
||
_fnLog( oSettings, 0, "Requested unknown parameter "+
|
||
(typeof oCol.mData=='function' ? '{function}' : "'"+oCol.mData+"'")+
|
||
" for row "+iRow, 4 );
|
||
oSettings.iDrawError = oSettings.iDraw;
|
||
}
|
||
return oCol.sDefaultContent;
|
||
}
|
||
|
||
/* When the data source is null, we can use default column data */
|
||
if ( (sData === oData || sData === null) && oCol.sDefaultContent !== null )
|
||
{
|
||
sData = oCol.sDefaultContent;
|
||
}
|
||
else if ( typeof sData === 'function' )
|
||
{
|
||
// If the data source is a function, then we run it and use the return
|
||
return sData();
|
||
}
|
||
|
||
if ( sData === null && sSpecific == 'display' )
|
||
{
|
||
return '';
|
||
}
|
||
return sData;
|
||
}
|
||
|
||
|
||
/**
|
||
* Set the value for a specific cell, into the internal data cache
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow aoData row id
|
||
* @param {int} iCol Column index
|
||
* @param {*} val Value to set
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSetCellData( oSettings, iRow, iCol, val )
|
||
{
|
||
var oCol = oSettings.aoColumns[iCol];
|
||
var oData = oSettings.aoData[iRow]._aData;
|
||
|
||
oCol.fnSetData( oData, val );
|
||
}
|
||
|
||
|
||
// Private variable that is used to match action syntax in the data property object
|
||
var __reArray = /\[.*?\]$/;
|
||
var __reFn = /\(\)$/;
|
||
|
||
/**
|
||
* Split string on periods, taking into account escaped periods
|
||
* @param {string} str String to split
|
||
* @return {array} Split string
|
||
*/
|
||
function _fnSplitObjNotation( str )
|
||
{
|
||
return $.map( str.match(/(\\.|[^\.])+/g), function ( s ) {
|
||
return s.replace('\\.', '.');
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Return a function that can be used to get data from a source object, taking
|
||
* into account the ability to use nested objects as a source
|
||
* @param {string|int|function} mSource The data source for the object
|
||
* @returns {function} Data get function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetObjectDataFn( mSource )
|
||
{
|
||
if ( $.isPlainObject( mSource ) )
|
||
{
|
||
/* Build an object of get functions, and wrap them in a single call */
|
||
var o = {};
|
||
$.each( mSource, function (key, val) {
|
||
if ( val ) {
|
||
o[key] = _fnGetObjectDataFn( val );
|
||
}
|
||
} );
|
||
|
||
return function (data, type, extra) {
|
||
var t = o[type] || o._;
|
||
return t !== undefined ?
|
||
t(data, type, extra) :
|
||
data;
|
||
};
|
||
}
|
||
else if ( mSource === null )
|
||
{
|
||
/* Give an empty string for rendering / sorting etc */
|
||
return function (data, type) {
|
||
return data;
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'function' )
|
||
{
|
||
return function (data, type, extra) {
|
||
return mSource( data, type, extra );
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||
{
|
||
/* If there is a . in the source string then the data source is in a
|
||
* nested object so we loop over the data for each level to get the next
|
||
* level down. On each loop we test for undefined, and if found immediately
|
||
* return. This allows entire objects to be missing and sDefaultContent to
|
||
* be used if defined, rather than throwing an error
|
||
*/
|
||
var fetchData = function (data, type, src) {
|
||
var arrayNotation, funcNotation, out, innerSrc;
|
||
|
||
if ( src !== "" )
|
||
{
|
||
var a = _fnSplitObjNotation( src );
|
||
|
||
for ( var i=0, iLen=a.length ; i<iLen ; i++ )
|
||
{
|
||
// Check if we are dealing with special notation
|
||
arrayNotation = a[i].match(__reArray);
|
||
funcNotation = a[i].match(__reFn);
|
||
|
||
if ( arrayNotation )
|
||
{
|
||
// Array notation
|
||
a[i] = a[i].replace(__reArray, '');
|
||
|
||
// Condition allows simply [] to be passed in
|
||
if ( a[i] !== "" ) {
|
||
data = data[ a[i] ];
|
||
}
|
||
out = [];
|
||
|
||
// Get the remainder of the nested object to get
|
||
a.splice( 0, i+1 );
|
||
innerSrc = a.join('.');
|
||
|
||
// Traverse each entry in the array getting the properties requested
|
||
for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
|
||
out.push( fetchData( data[j], type, innerSrc ) );
|
||
}
|
||
|
||
// If a string is given in between the array notation indicators, that
|
||
// is used to join the strings together, otherwise an array is returned
|
||
var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
|
||
data = (join==="") ? out : out.join(join);
|
||
|
||
// The inner call to fetchData has already traversed through the remainder
|
||
// of the source requested, so we exit from the loop
|
||
break;
|
||
}
|
||
else if ( funcNotation )
|
||
{
|
||
// Function call
|
||
a[i] = a[i].replace(__reFn, '');
|
||
data = data[ a[i] ]();
|
||
continue;
|
||
}
|
||
|
||
if ( data === null || data[ a[i] ] === undefined )
|
||
{
|
||
return undefined;
|
||
}
|
||
data = data[ a[i] ];
|
||
}
|
||
}
|
||
|
||
return data;
|
||
};
|
||
|
||
return function (data, type) {
|
||
return fetchData( data, type, mSource );
|
||
};
|
||
}
|
||
else
|
||
{
|
||
/* Array or flat object mapping */
|
||
return function (data, type) {
|
||
return data[mSource];
|
||
};
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Return a function that can be used to set data from a source object, taking
|
||
* into account the ability to use nested objects as a source
|
||
* @param {string|int|function} mSource The data source for the object
|
||
* @returns {function} Data set function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSetObjectDataFn( mSource )
|
||
{
|
||
if ( $.isPlainObject( mSource ) )
|
||
{
|
||
/* Unlike get, only the underscore (global) option is used for for
|
||
* setting data since we don't know the type here. This is why an object
|
||
* option is not documented for `mData` (which is read/write), but it is
|
||
* for `mRender` which is read only.
|
||
*/
|
||
return _fnSetObjectDataFn( mSource._ );
|
||
}
|
||
else if ( mSource === null )
|
||
{
|
||
/* Nothing to do when the data source is null */
|
||
return function (data, val) {};
|
||
}
|
||
else if ( typeof mSource === 'function' )
|
||
{
|
||
return function (data, val) {
|
||
mSource( data, 'set', val );
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||
{
|
||
/* Like the get, we need to get data from a nested object */
|
||
var setData = function (data, val, src) {
|
||
var a = _fnSplitObjNotation( src ), b;
|
||
var aLast = a[a.length-1];
|
||
var arrayNotation, funcNotation, o, innerSrc;
|
||
|
||
for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
|
||
{
|
||
// Check if we are dealing with an array notation request
|
||
arrayNotation = a[i].match(__reArray);
|
||
funcNotation = a[i].match(__reFn);
|
||
|
||
if ( arrayNotation )
|
||
{
|
||
a[i] = a[i].replace(__reArray, '');
|
||
data[ a[i] ] = [];
|
||
|
||
// Get the remainder of the nested object to set so we can recurse
|
||
b = a.slice();
|
||
b.splice( 0, i+1 );
|
||
innerSrc = b.join('.');
|
||
|
||
// Traverse each entry in the array setting the properties requested
|
||
for ( var j=0, jLen=val.length ; j<jLen ; j++ )
|
||
{
|
||
o = {};
|
||
setData( o, val[j], innerSrc );
|
||
data[ a[i] ].push( o );
|
||
}
|
||
|
||
// The inner call to setData has already traversed through the remainder
|
||
// of the source and has set the data, thus we can exit here
|
||
return;
|
||
}
|
||
else if ( funcNotation )
|
||
{
|
||
// Function call
|
||
a[i] = a[i].replace(__reFn, '');
|
||
data = data[ a[i] ]( val );
|
||
}
|
||
|
||
// If the nested object doesn't currently exist - since we are
|
||
// trying to set the value - create it
|
||
if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
|
||
{
|
||
data[ a[i] ] = {};
|
||
}
|
||
data = data[ a[i] ];
|
||
}
|
||
|
||
// Last item in the input - i.e, the actual set
|
||
if ( aLast.match(__reFn ) )
|
||
{
|
||
// Function call
|
||
data = data[ aLast.replace(__reFn, '') ]( val );
|
||
}
|
||
else
|
||
{
|
||
// If array notation is used, we just want to strip it and use the property name
|
||
// and assign the value. If it isn't used, then we get the result we want anyway
|
||
data[ aLast.replace(__reArray, '') ] = val;
|
||
}
|
||
};
|
||
|
||
return function (data, val) {
|
||
return setData( data, val, mSource );
|
||
};
|
||
}
|
||
else
|
||
{
|
||
/* Array or flat object mapping */
|
||
return function (data, val) {
|
||
data[mSource] = val;
|
||
};
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Return an array with the full table data
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns array {array} aData Master data array
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetDataMaster ( settings )
|
||
{
|
||
return _pluck( settings.aoData, '_aData' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Nuke the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnClearTable( settings )
|
||
{
|
||
settings.aoData.length = 0;
|
||
settings.aiDisplayMaster.length = 0;
|
||
settings.aiDisplay.length = 0;
|
||
}
|
||
|
||
|
||
/**
|
||
* Take an array of integers (index array) and remove a target integer (value - not
|
||
* the key!)
|
||
* @param {array} a Index array to target
|
||
* @param {int} iTarget value to find
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDeleteIndex( a, iTarget, splice )
|
||
{
|
||
var iTargetIndex = -1;
|
||
|
||
for ( var i=0, iLen=a.length ; i<iLen ; i++ )
|
||
{
|
||
if ( a[i] == iTarget )
|
||
{
|
||
iTargetIndex = i;
|
||
}
|
||
else if ( a[i] > iTarget )
|
||
{
|
||
a[i]--;
|
||
}
|
||
}
|
||
|
||
if ( iTargetIndex != -1 && splice === undefined )
|
||
{
|
||
a.splice( iTargetIndex, 1 );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Mark cached data as invalid such that a re-read of the data will occur when
|
||
* the cached data is next requested. Also update from the data source object.
|
||
*
|
||
* @param {object} settings DataTables settings object
|
||
* @param {int} rowIdx Row index to invalidate
|
||
* @memberof DataTable#oApi
|
||
*
|
||
* @todo For the modularisation of v1.11 this will need to become a callback, so
|
||
* the sort and filter methods can subscribe to it. That will required
|
||
* initialisation options for sorting, which is why it is not already baked in
|
||
*/
|
||
function _fnInvalidateRow( settings, rowIdx, src, column )
|
||
{
|
||
var row = settings.aoData[ rowIdx ];
|
||
var i, ien;
|
||
|
||
// Are we reading last data from DOM or the data object?
|
||
if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
|
||
// Read the data from the DOM
|
||
row._aData = _fnGetRowElements( settings, row ).data;
|
||
}
|
||
else {
|
||
// Reading from data object, update the DOM
|
||
var cells = row.anCells;
|
||
|
||
if ( cells ) {
|
||
for ( i=0, ien=cells.length ; i<ien ; i++ ) {
|
||
cells[i].innerHTML = _fnGetCellData( settings, rowIdx, i, 'display' );
|
||
}
|
||
}
|
||
}
|
||
|
||
row._aSortData = null;
|
||
row._aFilterData = null;
|
||
|
||
// Invalidate the type for a specific column (if given) or all columns since
|
||
// the data might have changed
|
||
var cols = settings.aoColumns;
|
||
if ( column !== undefined ) {
|
||
cols[ column ].sType = null;
|
||
}
|
||
else {
|
||
for ( i=0, ien=cols.length ; i<ien ; i++ ) {
|
||
cols[i].sType = null;
|
||
}
|
||
}
|
||
|
||
// Update DataTables special `DT_*` attributes for the row
|
||
_fnRowAttributes( row );
|
||
}
|
||
|
||
|
||
/**
|
||
* Build a data source object from an HTML row, reading the contents of the
|
||
* cells that are in the row.
|
||
*
|
||
* @param {object} settings DataTables settings object
|
||
* @param {node|object} TR element from which to read data or existing row
|
||
* object from which to re-read the data from the cells
|
||
* @returns {object} Object with two parameters: `data` the data read, in
|
||
* document order, and `cells` and array of nodes (they can be useful to the
|
||
* caller, so rather than needing a second traversal to get them, just return
|
||
* them from here).
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetRowElements( settings, row )
|
||
{
|
||
var
|
||
d = [],
|
||
tds = [],
|
||
td = row.firstChild,
|
||
name, col, o, i=0, contents,
|
||
columns = settings.aoColumns;
|
||
|
||
var attr = function ( str, data, td ) {
|
||
if ( typeof str === 'string' ) {
|
||
var idx = str.indexOf('@');
|
||
|
||
if ( idx !== -1 ) {
|
||
var src = str.substring( idx+1 );
|
||
o[ '@'+src ] = td.getAttribute( src );
|
||
}
|
||
}
|
||
};
|
||
|
||
var cellProcess = function ( cell ) {
|
||
col = columns[i];
|
||
contents = $.trim(cell.innerHTML);
|
||
|
||
if ( col && col._bAttrSrc ) {
|
||
o = {
|
||
display: contents
|
||
};
|
||
|
||
attr( col.mData.sort, o, cell );
|
||
attr( col.mData.type, o, cell );
|
||
attr( col.mData.filter, o, cell );
|
||
|
||
d.push( o );
|
||
}
|
||
else {
|
||
d.push( contents );
|
||
}
|
||
|
||
tds.push( cell );
|
||
i++;
|
||
};
|
||
|
||
if ( td ) {
|
||
// `tr` element passed in
|
||
while ( td ) {
|
||
name = td.nodeName.toUpperCase();
|
||
|
||
if ( name == "TD" || name == "TH" ) {
|
||
cellProcess( td );
|
||
}
|
||
|
||
td = td.nextSibling;
|
||
}
|
||
}
|
||
else {
|
||
// Existing row object passed in
|
||
tds = row.anCells;
|
||
|
||
for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
|
||
cellProcess( tds[j] );
|
||
}
|
||
}
|
||
|
||
return {
|
||
data: d,
|
||
cells: tds
|
||
};
|
||
}
|
||
/**
|
||
* Create a new TR element (and it's TD children) for a row
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow Row to consider
|
||
* @param {node} [nTrIn] TR element to add to the table - optional. If not given,
|
||
* DataTables will create a row automatically
|
||
* @param {array} [anTds] Array of TD|TH elements for the row - must be given
|
||
* if nTr is.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
|
||
{
|
||
var
|
||
row = oSettings.aoData[iRow],
|
||
rowData = row._aData,
|
||
cells = [],
|
||
nTr, nTd, oCol,
|
||
i, iLen;
|
||
|
||
if ( row.nTr === null )
|
||
{
|
||
nTr = nTrIn || document.createElement('tr');
|
||
|
||
row.nTr = nTr;
|
||
row.anCells = cells;
|
||
|
||
/* Use a private property on the node to allow reserve mapping from the node
|
||
* to the aoData array for fast look up
|
||
*/
|
||
nTr._DT_RowIndex = iRow;
|
||
|
||
/* Special parameters can be given by the data source to be used on the row */
|
||
_fnRowAttributes( row );
|
||
|
||
/* Process each column */
|
||
for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
|
||
{
|
||
oCol = oSettings.aoColumns[i];
|
||
|
||
nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
|
||
cells.push( nTd );
|
||
|
||
// Need to create the HTML if new, or if a rendering function is defined
|
||
if ( !nTrIn || oCol.mRender || oCol.mData !== i )
|
||
{
|
||
nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
|
||
}
|
||
|
||
/* Add user defined class */
|
||
if ( oCol.sClass )
|
||
{
|
||
nTd.className += ' '+oCol.sClass;
|
||
}
|
||
|
||
// Visibility - add or remove as required
|
||
if ( oCol.bVisible && ! nTrIn )
|
||
{
|
||
nTr.appendChild( nTd );
|
||
}
|
||
else if ( ! oCol.bVisible && nTrIn )
|
||
{
|
||
nTd.parentNode.removeChild( nTd );
|
||
}
|
||
|
||
if ( oCol.fnCreatedCell )
|
||
{
|
||
oCol.fnCreatedCell.call( oSettings.oInstance,
|
||
nTd, _fnGetCellData( oSettings, iRow, i, 'display' ), rowData, iRow, i
|
||
);
|
||
}
|
||
}
|
||
|
||
_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
|
||
}
|
||
|
||
// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
|
||
// and deployed
|
||
row.nTr.setAttribute( 'role', 'row' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Add attributes to a row based on the special `DT_*` parameters in a data
|
||
* source object.
|
||
* @param {object} DataTables row object for the row to be modified
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnRowAttributes( row )
|
||
{
|
||
var tr = row.nTr;
|
||
var data = row._aData;
|
||
|
||
if ( tr ) {
|
||
if ( data.DT_RowId ) {
|
||
tr.id = data.DT_RowId;
|
||
}
|
||
|
||
if ( data.DT_RowClass ) {
|
||
// Remove any classes added by DT_RowClass before
|
||
var a = data.DT_RowClass.split(' ');
|
||
row.__rowc = row.__rowc ?
|
||
_unique( row.__rowc.concat( a ) ) :
|
||
a;
|
||
|
||
$(tr)
|
||
.removeClass( row.__rowc.join(' ') )
|
||
.addClass( data.DT_RowClass );
|
||
}
|
||
|
||
if ( data.DT_RowData ) {
|
||
$(tr).data( data.DT_RowData );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Create the HTML header for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBuildHead( oSettings )
|
||
{
|
||
var i, ien, cell, row, column;
|
||
var thead = oSettings.nTHead;
|
||
var tfoot = oSettings.nTFoot;
|
||
var createHeader = $('th, td', thead).length === 0;
|
||
var classes = oSettings.oClasses;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
if ( createHeader ) {
|
||
row = $('<tr/>').appendTo( thead );
|
||
}
|
||
|
||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||
column = columns[i];
|
||
cell = $( column.nTh ).addClass( column.sClass );
|
||
|
||
if ( createHeader ) {
|
||
cell.appendTo( row );
|
||
}
|
||
|
||
// 1.11 move into sorting
|
||
if ( oSettings.oFeatures.bSort ) {
|
||
cell.addClass( column.sSortingClass );
|
||
|
||
if ( column.bSortable !== false ) {
|
||
cell
|
||
.attr( 'tabindex', oSettings.iTabIndex )
|
||
.attr( 'aria-controls', oSettings.sTableId );
|
||
|
||
_fnSortAttachListener( oSettings, column.nTh, i );
|
||
}
|
||
}
|
||
|
||
if ( column.sTitle != cell.html() ) {
|
||
cell.html( column.sTitle );
|
||
}
|
||
|
||
_fnRenderer( oSettings, 'header' )(
|
||
oSettings, cell, column, classes
|
||
);
|
||
}
|
||
|
||
if ( createHeader ) {
|
||
_fnDetectHeader( oSettings.aoHeader, thead );
|
||
}
|
||
|
||
/* ARIA role for the rows */
|
||
$(thead).find('>tr').attr('role', 'row');
|
||
|
||
/* Deal with the footer - add classes if required */
|
||
$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
|
||
$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
|
||
|
||
// Cache the footer cells. Note that we only take the cells from the first
|
||
// row in the footer. If there is more than one row the user wants to
|
||
// interact with, they need to use the table().foot() method. Note also this
|
||
// allows cells to be used for multiple columns using colspan
|
||
if ( tfoot !== null ) {
|
||
var cells = oSettings.aoFooter[0];
|
||
|
||
for ( i=0, ien=cells.length ; i<ien ; i++ ) {
|
||
column = columns[i];
|
||
column.nTf = cells[i].cell;
|
||
|
||
if ( column.sClass ) {
|
||
$(column.nTf).addClass( column.sClass );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Draw the header (or footer) element based on the column visibility states. The
|
||
* methodology here is to use the layout array from _fnDetectHeader, modified for
|
||
* the instantaneous column visibility, to construct the new layout. The grid is
|
||
* traversed over cell at a time in a rows x columns grid fashion, although each
|
||
* cell insert can cover multiple elements in the grid - which is tracks using the
|
||
* aApplied array. Cell inserts in the grid will only occur where there isn't
|
||
* already a cell in that position.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param array {objects} aoSource Layout array from _fnDetectHeader
|
||
* @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
|
||
{
|
||
var i, iLen, j, jLen, k, kLen, n, nLocalTr;
|
||
var aoLocal = [];
|
||
var aApplied = [];
|
||
var iColumns = oSettings.aoColumns.length;
|
||
var iRowspan, iColspan;
|
||
|
||
if ( ! aoSource )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( bIncludeHidden === undefined )
|
||
{
|
||
bIncludeHidden = false;
|
||
}
|
||
|
||
/* Make a copy of the master layout array, but without the visible columns in it */
|
||
for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
|
||
{
|
||
aoLocal[i] = aoSource[i].slice();
|
||
aoLocal[i].nTr = aoSource[i].nTr;
|
||
|
||
/* Remove any columns which are currently hidden */
|
||
for ( j=iColumns-1 ; j>=0 ; j-- )
|
||
{
|
||
if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
|
||
{
|
||
aoLocal[i].splice( j, 1 );
|
||
}
|
||
}
|
||
|
||
/* Prep the applied array - it needs an element for each row */
|
||
aApplied.push( [] );
|
||
}
|
||
|
||
for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
|
||
{
|
||
nLocalTr = aoLocal[i].nTr;
|
||
|
||
/* All cells are going to be replaced, so empty out the row */
|
||
if ( nLocalTr )
|
||
{
|
||
while( (n = nLocalTr.firstChild) )
|
||
{
|
||
nLocalTr.removeChild( n );
|
||
}
|
||
}
|
||
|
||
for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
|
||
{
|
||
iRowspan = 1;
|
||
iColspan = 1;
|
||
|
||
/* Check to see if there is already a cell (row/colspan) covering our target
|
||
* insert point. If there is, then there is nothing to do.
|
||
*/
|
||
if ( aApplied[i][j] === undefined )
|
||
{
|
||
nLocalTr.appendChild( aoLocal[i][j].cell );
|
||
aApplied[i][j] = 1;
|
||
|
||
/* Expand the cell to cover as many rows as needed */
|
||
while ( aoLocal[i+iRowspan] !== undefined &&
|
||
aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
|
||
{
|
||
aApplied[i+iRowspan][j] = 1;
|
||
iRowspan++;
|
||
}
|
||
|
||
/* Expand the cell to cover as many columns as needed */
|
||
while ( aoLocal[i][j+iColspan] !== undefined &&
|
||
aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
|
||
{
|
||
/* Must update the applied array over the rows for the columns */
|
||
for ( k=0 ; k<iRowspan ; k++ )
|
||
{
|
||
aApplied[i+k][j+iColspan] = 1;
|
||
}
|
||
iColspan++;
|
||
}
|
||
|
||
/* Do the actual expansion in the DOM */
|
||
$(aoLocal[i][j].cell)
|
||
.attr('rowspan', iRowspan)
|
||
.attr('colspan', iColspan);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Insert the required TR nodes into the table for display
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDraw( oSettings )
|
||
{
|
||
/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
|
||
var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
|
||
if ( $.inArray( false, aPreDraw ) !== -1 )
|
||
{
|
||
_fnProcessingDisplay( oSettings, false );
|
||
return;
|
||
}
|
||
|
||
var i, iLen, n;
|
||
var anRows = [];
|
||
var iRowCount = 0;
|
||
var asStripeClasses = oSettings.asStripeClasses;
|
||
var iStripes = asStripeClasses.length;
|
||
var iOpenRows = oSettings.aoOpenRows.length;
|
||
var oLang = oSettings.oLanguage;
|
||
var iInitDisplayStart = oSettings.iInitDisplayStart;
|
||
var bServerSide = _fnDataSource( oSettings ) == 'ssp';
|
||
var aiDisplay = oSettings.aiDisplay;
|
||
|
||
oSettings.bDrawing = true;
|
||
|
||
/* Check and see if we have an initial draw position from state saving */
|
||
if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
|
||
{
|
||
oSettings._iDisplayStart = bServerSide ?
|
||
iInitDisplayStart :
|
||
iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
|
||
0 :
|
||
iInitDisplayStart;
|
||
|
||
oSettings.iInitDisplayStart = -1;
|
||
}
|
||
|
||
var iDisplayStart = oSettings._iDisplayStart;
|
||
var iDisplayEnd = oSettings.fnDisplayEnd();
|
||
|
||
/* Server-side processing draw intercept */
|
||
if ( oSettings.bDeferLoading )
|
||
{
|
||
oSettings.bDeferLoading = false;
|
||
oSettings.iDraw++;
|
||
_fnProcessingDisplay( oSettings, false );
|
||
}
|
||
else if ( !bServerSide )
|
||
{
|
||
oSettings.iDraw++;
|
||
}
|
||
else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( aiDisplay.length !== 0 )
|
||
{
|
||
var iStart = bServerSide ? 0 : iDisplayStart;
|
||
var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
|
||
|
||
for ( var j=iStart ; j<iEnd ; j++ )
|
||
{
|
||
var iDataIndex = aiDisplay[j];
|
||
var aoData = oSettings.aoData[ iDataIndex ];
|
||
if ( aoData.nTr === null )
|
||
{
|
||
_fnCreateTr( oSettings, iDataIndex );
|
||
}
|
||
|
||
var nRow = aoData.nTr;
|
||
|
||
/* Remove the old striping classes and then add the new one */
|
||
if ( iStripes !== 0 )
|
||
{
|
||
var sStripe = asStripeClasses[ iRowCount % iStripes ];
|
||
if ( aoData._sRowStripe != sStripe )
|
||
{
|
||
$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
|
||
aoData._sRowStripe = sStripe;
|
||
}
|
||
}
|
||
|
||
/* Row callback functions - might want to manipulate the row */
|
||
_fnCallbackFire( oSettings, 'aoRowCallback', null,
|
||
[nRow, aoData._aData, iRowCount, j] );
|
||
|
||
anRows.push( nRow );
|
||
iRowCount++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Table is empty - create a row with an empty message in it */
|
||
var sZero = oLang.sZeroRecords;
|
||
if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
|
||
{
|
||
sZero = oLang.sLoadingRecords;
|
||
}
|
||
else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
|
||
{
|
||
sZero = oLang.sEmptyTable;
|
||
}
|
||
|
||
anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
|
||
.append( $('<td />', {
|
||
'valign': 'top',
|
||
'colSpan': _fnVisbleColumns( oSettings ),
|
||
'class': oSettings.oClasses.sRowEmpty
|
||
} ).html( sZero ) )[0];
|
||
}
|
||
|
||
/* Header and footer callbacks */
|
||
_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
|
||
_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
|
||
|
||
_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
|
||
_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
|
||
|
||
var body = $(oSettings.nTBody);
|
||
|
||
body.children().detach();
|
||
body.append( $(anRows) );
|
||
|
||
/* Call all required callback functions for the end of a draw */
|
||
_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
|
||
|
||
/* Draw is complete, sorting and filtering must be as well */
|
||
oSettings.bSorted = false;
|
||
oSettings.bFiltered = false;
|
||
oSettings.bDrawing = false;
|
||
}
|
||
|
||
|
||
/**
|
||
* Redraw the table - taking account of the various features which are enabled
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {boolean} [holdPosition] Keep the current paging position. By default
|
||
* the paging is reset to the first page
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnReDraw( settings, holdPosition )
|
||
{
|
||
var
|
||
features = settings.oFeatures,
|
||
sort = features.bSort,
|
||
filter = features.bFilter;
|
||
|
||
if ( sort ) {
|
||
_fnSort( settings );
|
||
}
|
||
|
||
if ( filter ) {
|
||
_fnFilterComplete( settings, settings.oPreviousSearch );
|
||
}
|
||
else {
|
||
// No filtering, so we want to just use the display master
|
||
settings.aiDisplay = settings.aiDisplayMaster.slice();
|
||
}
|
||
|
||
if ( holdPosition !== true ) {
|
||
settings._iDisplayStart = 0;
|
||
}
|
||
|
||
_fnDraw( settings );
|
||
}
|
||
|
||
|
||
/**
|
||
* Add the options to the page HTML for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddOptionsHtml ( oSettings )
|
||
{
|
||
var classes = oSettings.oClasses;
|
||
var table = $(oSettings.nTable);
|
||
var holding = $('<div/>').insertBefore( table ); // Holding element for speed
|
||
var features = oSettings.oFeatures;
|
||
|
||
// All DataTables are wrapped in a div
|
||
var insert = $('<div/>', {
|
||
id: oSettings.sTableId+'_wrapper',
|
||
'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
|
||
} );
|
||
|
||
oSettings.nHolding = holding[0];
|
||
oSettings.nTableWrapper = insert[0];
|
||
oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
|
||
|
||
/* Loop over the user set positioning and place the elements as needed */
|
||
var aDom = oSettings.sDom.split('');
|
||
var featureNode, cOption, nNewNode, cNext, sAttr, j;
|
||
for ( var i=0 ; i<aDom.length ; i++ )
|
||
{
|
||
featureNode = null;
|
||
cOption = aDom[i];
|
||
|
||
if ( cOption == '<' )
|
||
{
|
||
/* New container div */
|
||
nNewNode = $('<div/>')[0];
|
||
|
||
/* Check to see if we should append an id and/or a class name to the container */
|
||
cNext = aDom[i+1];
|
||
if ( cNext == "'" || cNext == '"' )
|
||
{
|
||
sAttr = "";
|
||
j = 2;
|
||
while ( aDom[i+j] != cNext )
|
||
{
|
||
sAttr += aDom[i+j];
|
||
j++;
|
||
}
|
||
|
||
/* Replace jQuery UI constants @todo depreciated */
|
||
if ( sAttr == "H" )
|
||
{
|
||
sAttr = classes.sJUIHeader;
|
||
}
|
||
else if ( sAttr == "F" )
|
||
{
|
||
sAttr = classes.sJUIFooter;
|
||
}
|
||
|
||
/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
|
||
* breaks the string into parts and applies them as needed
|
||
*/
|
||
if ( sAttr.indexOf('.') != -1 )
|
||
{
|
||
var aSplit = sAttr.split('.');
|
||
nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
|
||
nNewNode.className = aSplit[1];
|
||
}
|
||
else if ( sAttr.charAt(0) == "#" )
|
||
{
|
||
nNewNode.id = sAttr.substr(1, sAttr.length-1);
|
||
}
|
||
else
|
||
{
|
||
nNewNode.className = sAttr;
|
||
}
|
||
|
||
i += j; /* Move along the position array */
|
||
}
|
||
|
||
insert.append( nNewNode );
|
||
insert = $(nNewNode);
|
||
}
|
||
else if ( cOption == '>' )
|
||
{
|
||
/* End container div */
|
||
insert = insert.parent();
|
||
}
|
||
// @todo Move options into their own plugins?
|
||
else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
|
||
{
|
||
/* Length */
|
||
featureNode = _fnFeatureHtmlLength( oSettings );
|
||
}
|
||
else if ( cOption == 'f' && features.bFilter )
|
||
{
|
||
/* Filter */
|
||
featureNode = _fnFeatureHtmlFilter( oSettings );
|
||
}
|
||
else if ( cOption == 'r' && features.bProcessing )
|
||
{
|
||
/* pRocessing */
|
||
featureNode = _fnFeatureHtmlProcessing( oSettings );
|
||
}
|
||
else if ( cOption == 't' )
|
||
{
|
||
/* Table */
|
||
featureNode = _fnFeatureHtmlTable( oSettings );
|
||
}
|
||
else if ( cOption == 'i' && features.bInfo )
|
||
{
|
||
/* Info */
|
||
featureNode = _fnFeatureHtmlInfo( oSettings );
|
||
}
|
||
else if ( cOption == 'p' && features.bPaginate )
|
||
{
|
||
/* Pagination */
|
||
featureNode = _fnFeatureHtmlPaginate( oSettings );
|
||
}
|
||
else if ( DataTable.ext.feature.length !== 0 )
|
||
{
|
||
/* Plug-in features */
|
||
var aoFeatures = DataTable.ext.feature;
|
||
for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
|
||
{
|
||
if ( cOption == aoFeatures[k].cFeature )
|
||
{
|
||
featureNode = aoFeatures[k].fnInit( oSettings );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Add to the 2D features array */
|
||
if ( featureNode )
|
||
{
|
||
var aanFeatures = oSettings.aanFeatures;
|
||
|
||
if ( ! aanFeatures[cOption] )
|
||
{
|
||
aanFeatures[cOption] = [];
|
||
}
|
||
|
||
aanFeatures[cOption].push( featureNode );
|
||
insert.append( featureNode );
|
||
}
|
||
}
|
||
|
||
/* Built our DOM structure - replace the holding div with what we want */
|
||
holding.replaceWith( insert );
|
||
}
|
||
|
||
|
||
/**
|
||
* Use the DOM source to create up an array of header cells. The idea here is to
|
||
* create a layout grid (array) of rows x columns, which contains a reference
|
||
* to the cell that that point in the grid (regardless of col/rowspan), such that
|
||
* any column / row could be removed and the new grid constructed
|
||
* @param array {object} aLayout Array to store the calculated layout in
|
||
* @param {node} nThead The header/footer element for the table
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDetectHeader ( aLayout, nThead )
|
||
{
|
||
var nTrs = $(nThead).children('tr');
|
||
var nTr, nCell;
|
||
var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
|
||
var bUnique;
|
||
var fnShiftCol = function ( a, i, j ) {
|
||
var k = a[i];
|
||
while ( k[j] ) {
|
||
j++;
|
||
}
|
||
return j;
|
||
};
|
||
|
||
aLayout.splice( 0, aLayout.length );
|
||
|
||
/* We know how many rows there are in the layout - so prep it */
|
||
for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
|
||
{
|
||
aLayout.push( [] );
|
||
}
|
||
|
||
/* Calculate a layout array */
|
||
for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
|
||
{
|
||
nTr = nTrs[i];
|
||
iColumn = 0;
|
||
|
||
/* For every cell in the row... */
|
||
nCell = nTr.firstChild;
|
||
while ( nCell ) {
|
||
if ( nCell.nodeName.toUpperCase() == "TD" ||
|
||
nCell.nodeName.toUpperCase() == "TH" )
|
||
{
|
||
/* Get the col and rowspan attributes from the DOM and sanitise them */
|
||
iColspan = nCell.getAttribute('colspan') * 1;
|
||
iRowspan = nCell.getAttribute('rowspan') * 1;
|
||
iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
|
||
iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
|
||
|
||
/* There might be colspan cells already in this row, so shift our target
|
||
* accordingly
|
||
*/
|
||
iColShifted = fnShiftCol( aLayout, i, iColumn );
|
||
|
||
/* Cache calculation for unique columns */
|
||
bUnique = iColspan === 1 ? true : false;
|
||
|
||
/* If there is col / rowspan, copy the information into the layout grid */
|
||
for ( l=0 ; l<iColspan ; l++ )
|
||
{
|
||
for ( k=0 ; k<iRowspan ; k++ )
|
||
{
|
||
aLayout[i+k][iColShifted+l] = {
|
||
"cell": nCell,
|
||
"unique": bUnique
|
||
};
|
||
aLayout[i+k].nTr = nTr;
|
||
}
|
||
}
|
||
}
|
||
nCell = nCell.nextSibling;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Get an array of unique th elements, one for each column
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} nHeader automatically detect the layout from this node - optional
|
||
* @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
|
||
* @returns array {node} aReturn list of unique th's
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
|
||
{
|
||
var aReturn = [];
|
||
if ( !aLayout )
|
||
{
|
||
aLayout = oSettings.aoHeader;
|
||
if ( nHeader )
|
||
{
|
||
aLayout = [];
|
||
_fnDetectHeader( aLayout, nHeader );
|
||
}
|
||
}
|
||
|
||
for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
|
||
{
|
||
for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
|
||
{
|
||
if ( aLayout[i][j].unique &&
|
||
(!aReturn[j] || !oSettings.bSortCellsTop) )
|
||
{
|
||
aReturn[j] = aLayout[i][j].cell;
|
||
}
|
||
}
|
||
}
|
||
|
||
return aReturn;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Create an Ajax call based on the table's settings, taking into account that
|
||
* parameters can have multiple forms, and backwards compatibility.
|
||
*
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} data Data to send to the server, required by
|
||
* DataTables - may be augmented by developer callbacks
|
||
* @param {function} fn Callback function to run when data is obtained
|
||
*/
|
||
function _fnBuildAjax( oSettings, data, fn )
|
||
{
|
||
// Compatibility with 1.9-, allow fnServerData and event to manipulate
|
||
_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
|
||
|
||
// Convert to object based for 1.10+ if using the old array scheme which can
|
||
// come from server-side processing or serverParams
|
||
if ( data && $.isArray(data) ) {
|
||
var tmp = {};
|
||
var rbracket = /(.*?)\[\]$/;
|
||
|
||
$.each( data, function (key, val) {
|
||
var match = val.name.match(rbracket);
|
||
|
||
if ( match ) {
|
||
// Support for arrays
|
||
var name = match[0];
|
||
|
||
if ( ! tmp[ name ] ) {
|
||
tmp[ name ] = [];
|
||
}
|
||
tmp[ name ].push( val.value );
|
||
}
|
||
else {
|
||
tmp[val.name] = val.value;
|
||
}
|
||
} );
|
||
data = tmp;
|
||
}
|
||
|
||
var ajaxData;
|
||
var ajax = oSettings.ajax;
|
||
var instance = oSettings.oInstance;
|
||
|
||
if ( $.isPlainObject( ajax ) && ajax.data )
|
||
{
|
||
ajaxData = ajax.data;
|
||
|
||
var newData = $.isFunction( ajaxData ) ?
|
||
ajaxData( data ) : // fn can manipulate data or return an object
|
||
ajaxData; // object or array to merge
|
||
|
||
// If the function returned an object, use that alone
|
||
data = $.isFunction( ajaxData ) && newData ?
|
||
newData :
|
||
$.extend( true, data, newData );
|
||
|
||
// Remove the data property as we've resolved it already and don't want
|
||
// jQuery to do it again (it is restored at the end of the function)
|
||
delete ajax.data;
|
||
}
|
||
|
||
var baseAjax = {
|
||
"data": data,
|
||
"success": function (json) {
|
||
var error = json.error || json.sError;
|
||
if ( error ) {
|
||
oSettings.oApi._fnLog( oSettings, 0, error );
|
||
}
|
||
|
||
oSettings.json = json;
|
||
_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json] );
|
||
fn( json );
|
||
},
|
||
"dataType": "json",
|
||
"cache": false,
|
||
"type": oSettings.sServerMethod,
|
||
"error": function (xhr, error, thrown) {
|
||
var log = oSettings.oApi._fnLog;
|
||
|
||
if ( error == "parsererror" ) {
|
||
log( oSettings, 0, 'Invalid JSON response', 1 );
|
||
}
|
||
else if ( xhr.readyState === 4 ) {
|
||
log( oSettings, 0, 'Ajax error', 7 );
|
||
}
|
||
|
||
_fnProcessingDisplay( oSettings, false );
|
||
}
|
||
};
|
||
|
||
// Store the data submitted for the API
|
||
oSettings.oAjaxData = data;
|
||
|
||
// Allow plug-ins and external processes to modify the data
|
||
_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
|
||
|
||
if ( oSettings.fnServerData )
|
||
{
|
||
// DataTables 1.9- compatibility
|
||
oSettings.fnServerData.call( instance,
|
||
oSettings.sAjaxSource,
|
||
$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
|
||
return { name: key, value: val };
|
||
} ),
|
||
fn,
|
||
oSettings
|
||
);
|
||
}
|
||
else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
|
||
{
|
||
// DataTables 1.9- compatibility
|
||
oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
|
||
url: ajax || oSettings.sAjaxSource
|
||
} ) );
|
||
}
|
||
else if ( $.isFunction( ajax ) )
|
||
{
|
||
// Is a function - let the caller define what needs to be done
|
||
oSettings.jqXHR = ajax.call( instance, data, fn, oSettings );
|
||
}
|
||
else
|
||
{
|
||
// Object to extend the base settings
|
||
oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
|
||
|
||
// Restore for next time around
|
||
ajax.data = ajaxData;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Update the table using an Ajax call
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {boolean} Block the table drawing or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxUpdate( oSettings )
|
||
{
|
||
if ( oSettings.bAjaxDataGet )
|
||
{
|
||
oSettings.iDraw++;
|
||
_fnProcessingDisplay( oSettings, true );
|
||
var iColumns = oSettings.aoColumns.length;
|
||
var aoData = _fnAjaxParameters( oSettings );
|
||
|
||
_fnBuildAjax( oSettings, aoData, function(json) {
|
||
_fnAjaxUpdateDraw( oSettings, json );
|
||
}, oSettings );
|
||
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* Build up the parameters in an object needed for a server-side processing
|
||
* request. Note that this is basically done twice, is different ways - a modern
|
||
* method which is used by default in DataTables 1.10 which uses objects and
|
||
* arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
|
||
* the sAjaxSource option is used in the initialisation, or the legacyAjax
|
||
* option is set.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {bool} block the table drawing or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxParameters( settings )
|
||
{
|
||
var
|
||
columns = settings.aoColumns,
|
||
columnCount = columns.length,
|
||
features = settings.oFeatures,
|
||
preSearch = settings.oPreviousSearch,
|
||
preColSearch = settings.aoPreSearchCols,
|
||
i, data = [], dataProp, column, columnSearch,
|
||
sort = _fnSortFlatten( settings ),
|
||
displayStart = settings._iDisplayStart,
|
||
displayLength = features.bPaginate !== false ?
|
||
settings._iDisplayLength :
|
||
-1;
|
||
|
||
var param = function ( name, value ) {
|
||
data.push( { 'name': name, 'value': value } );
|
||
};
|
||
|
||
// DataTables 1.9- compatible method
|
||
param( 'sEcho', settings.iDraw );
|
||
param( 'iColumns', columnCount );
|
||
param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
|
||
param( 'iDisplayStart', displayStart );
|
||
param( 'iDisplayLength', displayLength );
|
||
|
||
// DataTables 1.10+ method
|
||
var d = {
|
||
draw: settings.iDraw,
|
||
columns: [],
|
||
order: [],
|
||
start: displayStart,
|
||
length: displayLength,
|
||
search: {
|
||
value: preSearch.sSearch,
|
||
regex: preSearch.bRegex
|
||
}
|
||
};
|
||
|
||
for ( i=0 ; i<columnCount ; i++ ) {
|
||
column = columns[i];
|
||
columnSearch = preColSearch[i];
|
||
dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
|
||
|
||
d.columns.push( {
|
||
data: dataProp,
|
||
name: column.sName,
|
||
searchable: column.bSearchable,
|
||
orderable: column.bSortable,
|
||
search: {
|
||
value: columnSearch.sSearch,
|
||
regex: columnSearch.bRegex
|
||
}
|
||
} );
|
||
|
||
param( "mDataProp_"+i, dataProp );
|
||
|
||
if ( features.bFilter ) {
|
||
param( 'sSearch_'+i, columnSearch.sSearch );
|
||
param( 'bRegex_'+i, columnSearch.bRegex );
|
||
param( 'bSearchable_'+i, column.bSearchable );
|
||
}
|
||
|
||
if ( features.bSort ) {
|
||
param( 'bSortable_'+i, column.bSortable );
|
||
}
|
||
}
|
||
|
||
if ( features.bFilter ) {
|
||
param( 'sSearch', preSearch.sSearch );
|
||
param( 'bRegex', preSearch.bRegex );
|
||
}
|
||
|
||
if ( features.bSort ) {
|
||
$.each( sort, function ( i, val ) {
|
||
d.order.push( { column: val.col, dir: val.dir } );
|
||
|
||
param( 'iSortCol_'+i, val.col );
|
||
param( 'sSortDir_'+i, val.dir );
|
||
} );
|
||
|
||
param( 'iSortingCols', sort.length );
|
||
}
|
||
|
||
// If the legacy.ajax parameter is null, then we automatically decide which
|
||
// form to use, based on sAjaxSource
|
||
var legacy = DataTable.ext.legacy.ajax;
|
||
if ( legacy === null ) {
|
||
return settings.sAjaxSource ? data : d;
|
||
}
|
||
|
||
// Otherwise, if legacy has been specified then we use that to decide on the
|
||
// form
|
||
return legacy ? data : d;
|
||
}
|
||
|
||
|
||
/**
|
||
* Data the data from the server (nuking the old) and redraw the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} json json data return from the server.
|
||
* @param {string} json.sEcho Tracking flag for DataTables to match requests
|
||
* @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
|
||
* @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
|
||
* @param {array} json.aaData The data to display on this page
|
||
* @param {string} [json.sColumns] Column ordering (sName, comma separated)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxUpdateDraw ( settings, json )
|
||
{
|
||
// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
|
||
// Support both
|
||
var compat = function ( old, modern ) {
|
||
return json[old] !== undefined ? json[old] : json[modern];
|
||
};
|
||
|
||
var draw = compat( 'sEcho', 'draw' );
|
||
var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
|
||
var rocordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
|
||
|
||
if ( draw ) {
|
||
// Protect against out of sequence returns
|
||
if ( draw*1 < settings.iDraw ) {
|
||
return;
|
||
}
|
||
settings.iDraw = draw * 1;
|
||
}
|
||
|
||
_fnClearTable( settings );
|
||
settings._iRecordsTotal = parseInt(recordsTotal, 10);
|
||
settings._iRecordsDisplay = parseInt(rocordsFiltered, 10);
|
||
|
||
var data = _fnAjaxDataSrc( settings, json );
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
_fnAddData( settings, data[i] );
|
||
}
|
||
settings.aiDisplay = settings.aiDisplayMaster.slice();
|
||
|
||
settings.bAjaxDataGet = false;
|
||
_fnDraw( settings );
|
||
|
||
if ( ! settings._bInitComplete ) {
|
||
_fnInitComplete( settings, json );
|
||
}
|
||
|
||
settings.bAjaxDataGet = true;
|
||
_fnProcessingDisplay( settings, false );
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the data from the JSON data source to use for drawing a table. Using
|
||
* `_fnGetObjectDataFn` allows the data to be sourced from a property of the
|
||
* source object, or from a processing function.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} json Data source object / array from the server
|
||
* @return {array} Array of data to use
|
||
*/
|
||
function _fnAjaxDataSrc ( oSettings, json )
|
||
{
|
||
var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
|
||
oSettings.ajax.dataSrc :
|
||
oSettings.sAjaxDataProp; // Compatibility with 1.9-.
|
||
|
||
// Compatibility with 1.9-. In order to read from aaData, check if the
|
||
// default has been changed, if not, check for aaData
|
||
if ( dataSrc === 'data' ) {
|
||
return json.aaData || json[dataSrc];
|
||
}
|
||
|
||
return dataSrc !== "" ?
|
||
_fnGetObjectDataFn( dataSrc )( json ) :
|
||
json;
|
||
}
|
||
|
||
|
||
/**
|
||
* Generate the node required for filtering text
|
||
* @returns {node} Filter control element
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlFilter ( settings )
|
||
{
|
||
var classes = settings.oClasses;
|
||
var tableId = settings.sTableId;
|
||
var previousSearch = settings.oPreviousSearch;
|
||
var features = settings.aanFeatures;
|
||
var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
|
||
|
||
var str = settings.oLanguage.sSearch;
|
||
str = str.match(/_INPUT_/) ?
|
||
str.replace('_INPUT_', input) :
|
||
str+input;
|
||
|
||
var filter = $('<div/>', {
|
||
'id': ! features.f ? tableId+'_filter' : null,
|
||
'class': classes.sFilter
|
||
} )
|
||
.append( $('<label/>' ).append( str ) );
|
||
|
||
var searchFn = function() {
|
||
/* Update all other filter input elements for the new display */
|
||
var n = features.f;
|
||
var val = !this.value ? "" : this.value; // mental IE8 fix :-(
|
||
|
||
/* Now do the filter */
|
||
if ( val != previousSearch.sSearch ) {
|
||
_fnFilterComplete( settings, {
|
||
"sSearch": val,
|
||
"bRegex": previousSearch.bRegex,
|
||
"bSmart": previousSearch.bSmart ,
|
||
"bCaseInsensitive": previousSearch.bCaseInsensitive
|
||
} );
|
||
|
||
// Need to redraw, without resorting
|
||
settings._iDisplayStart = 0;
|
||
_fnDraw( settings );
|
||
}
|
||
};
|
||
var jqFilter = $('input', filter)
|
||
.val( previousSearch.sSearch.replace('"','"') )
|
||
.bind(
|
||
'keyup.DT search.DT input.DT paste.DT cut.DT',
|
||
_fnDataSource( settings ) === 'ssp' ?
|
||
_fnThrottle( searchFn, 400 ):
|
||
searchFn
|
||
)
|
||
.bind( 'keypress.DT', function(e) {
|
||
/* Prevent form submission */
|
||
if ( e.keyCode == 13 ) {
|
||
return false;
|
||
}
|
||
} )
|
||
.attr('aria-controls', tableId);
|
||
|
||
// Update the input elements whenever the table is filtered
|
||
$(settings.nTable).on( 'filter.DT', function () {
|
||
// IE9 throws an 'unknown error' if document.activeElement is used
|
||
// inside an iframe or frame...
|
||
try {
|
||
if ( jqFilter[0] !== document.activeElement ) {
|
||
jqFilter.val( previousSearch.sSearch );
|
||
}
|
||
}
|
||
catch ( e ) {}
|
||
} );
|
||
|
||
return filter[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the table using both the global filter and column based filtering
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} oSearch search information
|
||
* @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterComplete ( oSettings, oInput, iForce )
|
||
{
|
||
var oPrevSearch = oSettings.oPreviousSearch;
|
||
var aoPrevSearch = oSettings.aoPreSearchCols;
|
||
var fnSaveFilter = function ( oFilter ) {
|
||
/* Save the filtering values */
|
||
oPrevSearch.sSearch = oFilter.sSearch;
|
||
oPrevSearch.bRegex = oFilter.bRegex;
|
||
oPrevSearch.bSmart = oFilter.bSmart;
|
||
oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
|
||
};
|
||
var fnRegex = function ( o ) {
|
||
// Backwards compatibility with the bEscapeRegex option
|
||
return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
|
||
};
|
||
|
||
// Resolve any column types that are unknown due to addition or invalidation
|
||
// @todo As per sort - can this be moved into an event handler?
|
||
_fnColumnTypes( oSettings );
|
||
|
||
/* In server-side processing all filtering is done by the server, so no point hanging around here */
|
||
if ( _fnDataSource( oSettings ) != 'ssp' )
|
||
{
|
||
/* Global filter */
|
||
_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
|
||
fnSaveFilter( oInput );
|
||
|
||
/* Now do the individual column filter */
|
||
for ( var i=0 ; i<aoPrevSearch.length ; i++ )
|
||
{
|
||
_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
|
||
aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
|
||
}
|
||
|
||
/* Custom filtering */
|
||
_fnFilterCustom( oSettings );
|
||
}
|
||
else
|
||
{
|
||
fnSaveFilter( oInput );
|
||
}
|
||
|
||
/* Tell the draw function we have been filtering */
|
||
oSettings.bFiltered = true;
|
||
_fnCallbackFire( oSettings, null, 'search', [oSettings] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Apply custom filtering functions
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterCustom( settings )
|
||
{
|
||
var filters = DataTable.ext.search;
|
||
var displayRows = settings.aiDisplay;
|
||
var row, rowIdx;
|
||
|
||
for ( var i=0, iLen=filters.length ; i<iLen ; i++ ) {
|
||
for ( var j=displayRows.length-1 ; j>=0 ; j-- ) {
|
||
rowIdx = displayRows[ j ];
|
||
row = settings.aoData[ rowIdx ];
|
||
|
||
if ( ! filters[i]( settings, row._aFilterData, rowIdx, row._aData ) ) {
|
||
displayRows.splice( j, 1 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the table on a per-column basis
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sInput string to filter on
|
||
* @param {int} iColumn column to filter
|
||
* @param {bool} bRegex treat search string as a regular expression or not
|
||
* @param {bool} bSmart use smart filtering or not
|
||
* @param {bool} bCaseInsensitive Do case insenstive matching or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
|
||
{
|
||
if ( searchStr === '' ) {
|
||
return;
|
||
}
|
||
|
||
var data;
|
||
var display = settings.aiDisplay;
|
||
var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
|
||
|
||
for ( var i=display.length-1 ; i>=0 ; i-- ) {
|
||
data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
|
||
|
||
if ( ! rpSearch.test( data ) ) {
|
||
display.splice( i, 1 );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the data table based on user input and draw the table
|
||
* @param {object} settings dataTables settings object
|
||
* @param {string} input string to filter on
|
||
* @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
|
||
* @param {bool} regex treat as a regular expression or not
|
||
* @param {bool} smart perform smart filtering or not
|
||
* @param {bool} caseInsensitive Do case insenstive matching or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
|
||
{
|
||
var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
|
||
var prevSearch = settings.oPreviousSearch.sSearch;
|
||
var displayMaster = settings.aiDisplayMaster;
|
||
var display, invalidated, i;
|
||
|
||
// Need to take account of custom filtering functions - always filter
|
||
if ( DataTable.ext.search.length !== 0 ) {
|
||
force = true;
|
||
}
|
||
|
||
// Check if any of the rows were invalidated
|
||
invalidated = _fnFilterData( settings );
|
||
|
||
// If the input is blank - we just want the full data set
|
||
if ( input.length <= 0 ) {
|
||
settings.aiDisplay = displayMaster.slice();
|
||
}
|
||
else {
|
||
// New search - start from the master array
|
||
if ( invalidated ||
|
||
force ||
|
||
prevSearch.length > input.length ||
|
||
input.indexOf(prevSearch) !== 0 ||
|
||
settings.bSorted // On resort, the display master needs to be
|
||
// re-filtered since indexes will have changed
|
||
) {
|
||
settings.aiDisplay = displayMaster.slice();
|
||
}
|
||
|
||
// Search the display array
|
||
display = settings.aiDisplay;
|
||
|
||
for ( i=display.length-1 ; i>=0 ; i-- ) {
|
||
if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
|
||
display.splice( i, 1 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Build a regular expression object suitable for searching a table
|
||
* @param {string} sSearch string to search for
|
||
* @param {bool} bRegex treat as a regular expression or not
|
||
* @param {bool} bSmart perform smart filtering or not
|
||
* @param {bool} bCaseInsensitive Do case insensitive matching or not
|
||
* @returns {RegExp} constructed object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
|
||
{
|
||
search = regex ?
|
||
search :
|
||
_fnEscapeRegex( search );
|
||
|
||
if ( smart ) {
|
||
/* For smart filtering we want to allow the search to work regardless of
|
||
* word order. We also want double quoted text to be preserved, so word
|
||
* order is important - a la google. So this is what we want to
|
||
* generate:
|
||
*
|
||
* ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
|
||
*/
|
||
var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || '', function ( word ) {
|
||
return word.charAt(0) === '"' ?
|
||
word.match( /^"(.*)"$/ )[1] :
|
||
word;
|
||
} );
|
||
|
||
search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
|
||
}
|
||
|
||
return new RegExp( search, caseInsensitive ? 'i' : '' );
|
||
}
|
||
|
||
|
||
/**
|
||
* scape a string such that it can be used in a regular expression
|
||
* @param {string} sVal string to escape
|
||
* @returns {string} escaped string
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnEscapeRegex ( sVal )
|
||
{
|
||
return sVal.replace( _re_escape_regex, '\\$1' );
|
||
}
|
||
|
||
|
||
|
||
var __filter_div = $('<div>')[0];
|
||
var __filter_div_textContent = __filter_div.textContent !== undefined;
|
||
|
||
// Update the filtering data for each row if needed (by invalidation or first run)
|
||
function _fnFilterData ( settings )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
var column;
|
||
var i, j, ien, jen, filterData, cellData, row;
|
||
var fomatters = DataTable.ext.type.search;
|
||
var wasInvalidated = false;
|
||
|
||
for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( ! row._aFilterData ) {
|
||
filterData = [];
|
||
|
||
for ( j=0, jen=columns.length ; j<jen ; j++ ) {
|
||
column = columns[j];
|
||
|
||
if ( column.bSearchable ) {
|
||
cellData = _fnGetCellData( settings, i, j, 'filter' );
|
||
|
||
cellData = fomatters[ column.sType ] ?
|
||
fomatters[ column.sType ]( cellData ) :
|
||
cellData !== null ?
|
||
cellData :
|
||
'';
|
||
}
|
||
else {
|
||
cellData = '';
|
||
}
|
||
|
||
// If it looks like there is an HTML entity in the string,
|
||
// attempt to decode it so sorting works as expected. Note that
|
||
// we could use a single line of jQuery to do this, but the DOM
|
||
// method used here is much faster http://jsperf.com/html-decode
|
||
if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
|
||
__filter_div.innerHTML = cellData;
|
||
cellData = __filter_div_textContent ?
|
||
__filter_div.textContent :
|
||
__filter_div.innerText;
|
||
}
|
||
|
||
if ( cellData.replace ) {
|
||
cellData = cellData.replace(/[\r\n]/g, '');
|
||
}
|
||
|
||
filterData.push( cellData );
|
||
}
|
||
|
||
row._aFilterData = filterData;
|
||
row._sFilterRow = filterData.join(' ');
|
||
wasInvalidated = true;
|
||
}
|
||
}
|
||
|
||
return wasInvalidated;
|
||
}
|
||
|
||
/**
|
||
* Generate the node required for the info display
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {node} Information element
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlInfo ( settings )
|
||
{
|
||
var
|
||
tid = settings.sTableId,
|
||
nodes = settings.aanFeatures.i,
|
||
n = $('<div/>', {
|
||
'class': settings.oClasses.sInfo,
|
||
'id': ! nodes ? tid+'_info' : null
|
||
} );
|
||
|
||
if ( ! nodes ) {
|
||
// Update display on each draw
|
||
settings.aoDrawCallback.push( {
|
||
"fn": _fnUpdateInfo,
|
||
"sName": "information"
|
||
} );
|
||
|
||
n
|
||
.attr( 'role', 'status' )
|
||
.attr( 'aria-live', 'polite' );
|
||
|
||
// Table is described by our info div
|
||
$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
|
||
}
|
||
|
||
return n[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Update the information elements in the display
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnUpdateInfo ( settings )
|
||
{
|
||
/* Show information about the table */
|
||
var nodes = settings.aanFeatures.i;
|
||
if ( nodes.length === 0 ) {
|
||
return;
|
||
}
|
||
|
||
var
|
||
lang = settings.oLanguage,
|
||
start = settings._iDisplayStart+1,
|
||
end = settings.fnDisplayEnd(),
|
||
max = settings.fnRecordsTotal(),
|
||
total = settings.fnRecordsDisplay(),
|
||
out = total ?
|
||
lang.sInfo :
|
||
lang.sInfoEmpty;
|
||
|
||
if ( total !== max ) {
|
||
/* Record set after filtering */
|
||
out += ' ' + lang.sInfoFiltered;
|
||
}
|
||
|
||
// Convert the macros
|
||
out += lang.sInfoPostFix;
|
||
out = _fnInfoMacros( settings, out );
|
||
|
||
var callback = lang.fnInfoCallback;
|
||
if ( callback !== null ) {
|
||
out = callback.call( settings.oInstance,
|
||
settings, start, end, max, total, out
|
||
);
|
||
}
|
||
|
||
$(nodes).html( out );
|
||
}
|
||
|
||
|
||
function _fnInfoMacros ( settings, str )
|
||
{
|
||
// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
|
||
// internally
|
||
var
|
||
formatter = settings.fnFormatNumber,
|
||
start = settings._iDisplayStart+1,
|
||
len = settings._iDisplayLength,
|
||
vis = settings.fnRecordsDisplay(),
|
||
all = len === -1;
|
||
|
||
return str.
|
||
replace(/_START_/g, formatter.call( settings, start ) ).
|
||
replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
|
||
replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
|
||
replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
|
||
replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
|
||
replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Draw the table for the first time, adding all required features
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnInitialise ( settings )
|
||
{
|
||
var i, iLen, iAjaxStart=settings.iInitDisplayStart;
|
||
var columns = settings.aoColumns, column;
|
||
var features = settings.oFeatures;
|
||
|
||
/* Ensure that the table data is fully initialised */
|
||
if ( ! settings.bInitialised ) {
|
||
setTimeout( function(){ _fnInitialise( settings ); }, 200 );
|
||
return;
|
||
}
|
||
|
||
/* Show the display HTML options */
|
||
_fnAddOptionsHtml( settings );
|
||
|
||
/* Build and draw the header / footer for the table */
|
||
_fnBuildHead( settings );
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
/* Okay to show that something is going on now */
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
/* Calculate sizes for columns */
|
||
if ( features.bAutoWidth ) {
|
||
_fnCalculateColumnWidths( settings );
|
||
}
|
||
|
||
for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
|
||
column = columns[i];
|
||
|
||
if ( column.sWidth ) {
|
||
column.nTh.style.width = _fnStringToCss( column.sWidth );
|
||
}
|
||
}
|
||
|
||
// If there is default sorting required - let's do it. The sort function
|
||
// will do the drawing for us. Otherwise we draw the table regardless of the
|
||
// Ajax source - this allows the table to look initialised for Ajax sourcing
|
||
// data (show 'loading' message possibly)
|
||
_fnReDraw( settings );
|
||
|
||
// Server-side processing init complete is done by _fnAjaxUpdateDraw
|
||
var dataSrc = _fnDataSource( settings );
|
||
if ( dataSrc != 'ssp' ) {
|
||
// if there is an ajax source load the data
|
||
if ( dataSrc == 'ajax' ) {
|
||
_fnBuildAjax( settings, [], function(json) {
|
||
var aData = _fnAjaxDataSrc( settings, json );
|
||
|
||
// Got the data - add it to the table
|
||
for ( i=0 ; i<aData.length ; i++ ) {
|
||
_fnAddData( settings, aData[i] );
|
||
}
|
||
|
||
// Reset the init display for cookie saving. We've already done
|
||
// a filter, and therefore cleared it before. So we need to make
|
||
// it appear 'fresh'
|
||
settings.iInitDisplayStart = iAjaxStart;
|
||
|
||
_fnReDraw( settings );
|
||
|
||
_fnProcessingDisplay( settings, false );
|
||
_fnInitComplete( settings, json );
|
||
}, settings );
|
||
}
|
||
else {
|
||
_fnProcessingDisplay( settings, false );
|
||
_fnInitComplete( settings );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Draw the table for the first time, adding all required features
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} [json] JSON from the server that completed the table, if using Ajax source
|
||
* with client-side processing (optional)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnInitComplete ( settings, json )
|
||
{
|
||
settings._bInitComplete = true;
|
||
|
||
// On an Ajax load we now have data and therefore want to apply the column
|
||
// sizing
|
||
if ( json ) {
|
||
_fnAdjustColumnSizing( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
|
||
}
|
||
|
||
|
||
function _fnLengthChange ( settings, val )
|
||
{
|
||
var len = parseInt( val, 10 );
|
||
settings._iDisplayLength = len;
|
||
|
||
_fnLengthOverflow( settings );
|
||
|
||
// Fire length change event
|
||
_fnCallbackFire( settings, null, 'length', [settings, len] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Generate the node required for user display length changing
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Display length feature node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlLength ( settings )
|
||
{
|
||
var
|
||
classes = settings.oClasses,
|
||
tableId = settings.sTableId,
|
||
menu = settings.aLengthMenu,
|
||
d2 = $.isArray( menu[0] ),
|
||
lengths = d2 ? menu[0] : menu,
|
||
language = d2 ? menu[1] : menu;
|
||
|
||
var select = $('<select/>', {
|
||
'name': tableId+'_length',
|
||
'aria-controls': tableId,
|
||
'class': classes.sLengthSelect
|
||
} );
|
||
|
||
for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
|
||
select[0][ i ] = new Option( language[i], lengths[i] );
|
||
}
|
||
|
||
var div = $('<div><label/></div>').addClass( classes.sLength );
|
||
if ( ! settings.aanFeatures.l ) {
|
||
div[0].id = tableId+'_length';
|
||
}
|
||
|
||
var a = settings.oLanguage.sLengthMenu.split(/(_MENU_)/);
|
||
div.children().append( a.length > 1 ?
|
||
[ a[0], select, a[2] ] :
|
||
a[0]
|
||
);
|
||
|
||
// Can't use `select` variable, as user might provide their own select menu
|
||
$('select', div)
|
||
.val( settings._iDisplayLength )
|
||
.bind( 'change.DT', function(e) {
|
||
_fnLengthChange( settings, $(this).val() );
|
||
_fnDraw( settings );
|
||
} );
|
||
|
||
// Update node value whenever anything changes the table's length
|
||
$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
|
||
$('select', div).val( len );
|
||
} );
|
||
|
||
return div[0];
|
||
}
|
||
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Note that most of the paging logic is done in
|
||
* DataTable.ext.pager
|
||
*/
|
||
|
||
/**
|
||
* Generate the node required for default pagination
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {node} Pagination feature node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlPaginate ( settings )
|
||
{
|
||
var
|
||
type = settings.sPaginationType,
|
||
plugin = DataTable.ext.pager[ type ],
|
||
modern = typeof plugin === 'function',
|
||
redraw = function( settings ) {
|
||
_fnDraw( settings );
|
||
},
|
||
node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
|
||
features = settings.aanFeatures;
|
||
|
||
if ( ! modern ) {
|
||
plugin.fnInit( settings, node, redraw );
|
||
}
|
||
|
||
/* Add a draw callback for the pagination on first instance, to update the paging display */
|
||
if ( ! features.p )
|
||
{
|
||
node.id = settings.sTableId+'_paginate';
|
||
|
||
settings.aoDrawCallback.push( {
|
||
"fn": function( settings ) {
|
||
if ( modern ) {
|
||
var
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
visRecords = settings.fnRecordsDisplay(),
|
||
all = len === -1,
|
||
page = all ? 0 : Math.ceil( start / len ),
|
||
pages = all ? 1 : Math.ceil( visRecords / len ),
|
||
buttons = plugin(page, pages),
|
||
i, ien;
|
||
|
||
for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
|
||
_fnRenderer( settings, 'pageButton' )(
|
||
settings, features.p[i], i, buttons, page, pages
|
||
);
|
||
}
|
||
}
|
||
else {
|
||
plugin.fnUpdate( settings, redraw );
|
||
}
|
||
},
|
||
"sName": "pagination"
|
||
} );
|
||
}
|
||
|
||
return node;
|
||
}
|
||
|
||
|
||
/**
|
||
* Alter the display settings to change the page
|
||
* @param {object} settings DataTables settings object
|
||
* @param {string|int} action Paging action to take: "first", "previous",
|
||
* "next" or "last" or page number to jump to (integer)
|
||
* @param [bool] redraw Automatically draw the update or not
|
||
* @returns {bool} true page has changed, false - no change
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnPageChange ( settings, action, redraw )
|
||
{
|
||
var
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
records = settings.fnRecordsDisplay();
|
||
|
||
if ( records === 0 || len === -1 )
|
||
{
|
||
start = 0;
|
||
}
|
||
else if ( typeof action === "number" )
|
||
{
|
||
start = action * len;
|
||
|
||
if ( start > records )
|
||
{
|
||
start = 0;
|
||
}
|
||
}
|
||
else if ( action == "first" )
|
||
{
|
||
start = 0;
|
||
}
|
||
else if ( action == "previous" )
|
||
{
|
||
start = len >= 0 ?
|
||
start - len :
|
||
0;
|
||
|
||
if ( start < 0 )
|
||
{
|
||
start = 0;
|
||
}
|
||
}
|
||
else if ( action == "next" )
|
||
{
|
||
if ( start + len < records )
|
||
{
|
||
start += len;
|
||
}
|
||
}
|
||
else if ( action == "last" )
|
||
{
|
||
start = Math.floor( (records-1) / len) * len;
|
||
}
|
||
else
|
||
{
|
||
_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
|
||
}
|
||
|
||
var changed = settings._iDisplayStart !== start;
|
||
settings._iDisplayStart = start;
|
||
|
||
if ( changed ) {
|
||
_fnCallbackFire( settings, null, 'page', [settings] );
|
||
|
||
if ( redraw ) {
|
||
_fnDraw( settings );
|
||
}
|
||
}
|
||
|
||
return changed;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Generate the node required for the processing node
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Processing element
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlProcessing ( settings )
|
||
{
|
||
return $('<div/>', {
|
||
'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
|
||
'class': settings.oClasses.sProcessing
|
||
} )
|
||
.html( settings.oLanguage.sProcessing )
|
||
.insertBefore( settings.nTable )[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Display or hide the processing indicator
|
||
* @param {object} settings dataTables settings object
|
||
* @param {bool} show Show the processing indicator (true) or not (false)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnProcessingDisplay ( settings, show )
|
||
{
|
||
if ( settings.oFeatures.bProcessing ) {
|
||
$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'processing', [settings, show] );
|
||
}
|
||
|
||
/**
|
||
* Add any control elements for the table - specifically scrolling
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Node to add to the DOM
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlTable ( settings )
|
||
{
|
||
var table = $(settings.nTable);
|
||
|
||
// Add the ARIA grid role to the table
|
||
table.attr( 'role', 'grid' );
|
||
|
||
// Scrolling from here on in
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( scroll.sX === '' && scroll.sY === '' ) {
|
||
return settings.nTable;
|
||
}
|
||
|
||
var scrollX = scroll.sX;
|
||
var scrollY = scroll.sY;
|
||
var classes = settings.oClasses;
|
||
var caption = table.children('caption');
|
||
var captionSide = caption.length ? caption[0]._captionSide : null;
|
||
var headerClone = $( table[0].cloneNode(false) );
|
||
var footerClone = $( table[0].cloneNode(false) );
|
||
var footer = table.children('tfoot');
|
||
var _div = '<div/>';
|
||
var size = function ( s ) {
|
||
return !s ? null : _fnStringToCss( s );
|
||
};
|
||
|
||
// This is fairly messy, but with x scrolling enabled, if the table has a
|
||
// width attribute, regardless of any width applied using the column width
|
||
// options, the browser will shrink or grow the table as needed to fit into
|
||
// that 100%. That would make the width options useless. So we remove it.
|
||
// This is okay, under the assumption that width:100% is applied to the
|
||
// table in CSS (it is in the default stylesheet) which will set the table
|
||
// width as appropriate (the attribute and css behave differently...)
|
||
if ( scroll.sX && table.attr('width') === '100%' ) {
|
||
table.removeAttr('width');
|
||
}
|
||
|
||
if ( ! footer.length ) {
|
||
footer = null;
|
||
}
|
||
|
||
/*
|
||
* The HTML structure that we want to generate in this function is:
|
||
* div - scroller
|
||
* div - scroll head
|
||
* div - scroll head inner
|
||
* table - scroll head table
|
||
* thead - thead
|
||
* div - scroll body
|
||
* table - table (master table)
|
||
* thead - thead clone for sizing
|
||
* tbody - tbody
|
||
* div - scroll foot
|
||
* div - scroll foot inner
|
||
* table - scroll foot table
|
||
* tfoot - tfoot
|
||
*/
|
||
var scroller = $( _div, { 'class': classes.sScrollWrapper } )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollHead } )
|
||
.css( {
|
||
overflow: 'hidden',
|
||
position: 'relative',
|
||
border: 0,
|
||
width: scrollX ? size(scrollX) : '100%'
|
||
} )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollHeadInner } )
|
||
.css( {
|
||
'box-sizing': 'content-box',
|
||
width: scroll.sXInner || '100%'
|
||
} )
|
||
.append(
|
||
headerClone
|
||
.removeAttr('id')
|
||
.css( 'margin-left', 0 )
|
||
.append(
|
||
table.children('thead')
|
||
)
|
||
)
|
||
)
|
||
.append( captionSide === 'top' ? caption : null )
|
||
)
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollBody } )
|
||
.css( {
|
||
overflow: 'auto',
|
||
height: size( scrollY ),
|
||
width: size( scrollX )
|
||
} )
|
||
.append( table )
|
||
);
|
||
|
||
if ( footer ) {
|
||
scroller.append(
|
||
$(_div, { 'class': classes.sScrollFoot } )
|
||
.css( {
|
||
overflow: 'hidden',
|
||
border: 0,
|
||
width: scrollX ? size(scrollX) : '100%'
|
||
} )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollFootInner } )
|
||
.append(
|
||
footerClone
|
||
.removeAttr('id')
|
||
.css( 'margin-left', 0 )
|
||
.append(
|
||
table.children('tfoot')
|
||
)
|
||
)
|
||
)
|
||
.append( captionSide === 'bottom' ? caption : null )
|
||
);
|
||
}
|
||
|
||
var children = scroller.children();
|
||
var scrollHead = children[0];
|
||
var scrollBody = children[1];
|
||
var scrollFoot = footer ? children[2] : null;
|
||
|
||
// When the body is scrolled, then we also want to scroll the headers
|
||
if ( scrollX ) {
|
||
$(scrollBody).scroll( function (e) {
|
||
var scrollLeft = this.scrollLeft;
|
||
|
||
scrollHead.scrollLeft = scrollLeft;
|
||
|
||
if ( footer ) {
|
||
scrollFoot.scrollLeft = scrollLeft;
|
||
}
|
||
} );
|
||
}
|
||
|
||
settings.nScrollHead = scrollHead;
|
||
settings.nScrollBody = scrollBody;
|
||
settings.nScrollFoot = scrollFoot;
|
||
|
||
// On redraw - align columns
|
||
settings.aoDrawCallback.push( {
|
||
"fn": _fnScrollDraw,
|
||
"sName": "scrolling"
|
||
} );
|
||
|
||
return scroller[0];
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Update the header, footer and body tables for resizing - i.e. column
|
||
* alignment.
|
||
*
|
||
* Welcome to the most horrible function DataTables. The process that this
|
||
* function follows is basically:
|
||
* 1. Re-create the table inside the scrolling div
|
||
* 2. Take live measurements from the DOM
|
||
* 3. Apply the measurements to align the columns
|
||
* 4. Clean up
|
||
*
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnScrollDraw ( settings )
|
||
{
|
||
// Given that this is such a monster function, a lot of variables are use
|
||
// to try and keep the minimised size as small as possible
|
||
var
|
||
scroll = settings.oScroll,
|
||
scrollX = scroll.sX,
|
||
scrollXInner = scroll.sXInner,
|
||
scrollY = scroll.sY,
|
||
barWidth = scroll.iBarWidth,
|
||
divHeader = $(settings.nScrollHead),
|
||
divHeaderStyle = divHeader[0].style,
|
||
divHeaderInner = divHeader.children('div'),
|
||
divHeaderInnerStyle = divHeaderInner[0].style,
|
||
divHeaderTable = divHeaderInner.children('table'),
|
||
divBodyEl = settings.nScrollBody,
|
||
divBody = $(divBodyEl),
|
||
divBodyStyle = divBodyEl.style,
|
||
divFooter = $(settings.nScrollFoot),
|
||
divFooterInner = divFooter.children('div'),
|
||
divFooterTable = divFooterInner.children('table'),
|
||
header = $(settings.nTHead),
|
||
table = $(settings.nTable),
|
||
tableEl = table[0],
|
||
tableStyle = tableEl.style,
|
||
footer = settings.nTFoot ? $(settings.nTFoot) : null,
|
||
browser = settings.oBrowser,
|
||
ie67 = browser.bScrollOversize,
|
||
headerTrgEls, footerTrgEls,
|
||
headerSrcEls, footerSrcEls,
|
||
headerCopy, footerCopy,
|
||
headerWidths=[], footerWidths=[],
|
||
headerContent=[],
|
||
idx, correction, sanityWidth,
|
||
zeroOut = function(nSizer) {
|
||
var style = nSizer.style;
|
||
style.paddingTop = "0";
|
||
style.paddingBottom = "0";
|
||
style.borderTopWidth = "0";
|
||
style.borderBottomWidth = "0";
|
||
style.height = 0;
|
||
};
|
||
|
||
/*
|
||
* 1. Re-create the table inside the scrolling div
|
||
*/
|
||
|
||
// Remove the old minimised thead and tfoot elements in the inner table
|
||
table.children('thead, tfoot').remove();
|
||
|
||
// Clone the current header and footer elements and then place it into the inner table
|
||
headerCopy = header.clone().prependTo( table );
|
||
headerTrgEls = header.find('tr'); // original header is in its own table
|
||
headerSrcEls = headerCopy.find('tr');
|
||
headerCopy.find('th, td').removeAttr('tabindex');
|
||
|
||
if ( footer ) {
|
||
footerCopy = footer.clone().prependTo( table );
|
||
footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
|
||
footerSrcEls = footerCopy.find('tr');
|
||
}
|
||
|
||
|
||
/*
|
||
* 2. Take live measurements from the DOM - do not alter the DOM itself!
|
||
*/
|
||
|
||
// Remove old sizing and apply the calculated column widths
|
||
// Get the unique column headers in the newly created (cloned) header. We want to apply the
|
||
// calculated sizes to this header
|
||
if ( ! scrollX )
|
||
{
|
||
divBodyStyle.width = '100%';
|
||
divHeader[0].style.width = '100%';
|
||
}
|
||
|
||
$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
|
||
idx = _fnVisibleToColumnIndex( settings, i );
|
||
el.style.width = settings.aoColumns[idx].sWidth;
|
||
} );
|
||
|
||
if ( footer ) {
|
||
_fnApplyToChildren( function(n) {
|
||
n.style.width = "";
|
||
}, footerSrcEls );
|
||
}
|
||
|
||
// If scroll collapse is enabled, when we put the headers back into the body for sizing, we
|
||
// will end up forcing the scrollbar to appear, making our measurements wrong for when we
|
||
// then hide it (end of this function), so add the header height to the body scroller.
|
||
if ( scroll.bCollapse && scrollY !== "" ) {
|
||
divBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+"px";
|
||
}
|
||
|
||
// Size the table as a whole
|
||
sanityWidth = table.outerWidth();
|
||
if ( scrollX === "" ) {
|
||
// No x scrolling
|
||
tableStyle.width = "100%";
|
||
|
||
// IE7 will make the width of the table when 100% include the scrollbar
|
||
// - which is shouldn't. When there is a scrollbar we need to take this
|
||
// into account.
|
||
if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
|
||
divBody.css('overflow-y') == "scroll")
|
||
) {
|
||
tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// x scrolling
|
||
if ( scrollXInner !== "" ) {
|
||
// x scroll inner has been given - use it
|
||
tableStyle.width = _fnStringToCss(scrollXInner);
|
||
}
|
||
else if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {
|
||
// There is y-scrolling - try to take account of the y scroll bar
|
||
tableStyle.width = _fnStringToCss( sanityWidth-barWidth );
|
||
if ( table.outerWidth() > sanityWidth-barWidth ) {
|
||
// Not possible to take account of it
|
||
tableStyle.width = _fnStringToCss( sanityWidth );
|
||
}
|
||
}
|
||
else {
|
||
// When all else fails
|
||
tableStyle.width = _fnStringToCss( sanityWidth );
|
||
}
|
||
}
|
||
|
||
// Recalculate the sanity width - now that we've applied the required width,
|
||
// before it was a temporary variable. This is required because the column
|
||
// width calculation is done before this table DOM is created.
|
||
sanityWidth = table.outerWidth();
|
||
|
||
// Hidden header should have zero height, so remove padding and borders. Then
|
||
// set the width based on the real headers
|
||
|
||
// Apply all styles in one pass
|
||
_fnApplyToChildren( zeroOut, headerSrcEls );
|
||
|
||
// Read all widths in next pass
|
||
_fnApplyToChildren( function(nSizer) {
|
||
headerContent.push( nSizer.innerHTML );
|
||
headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
|
||
}, headerSrcEls );
|
||
|
||
// Apply all widths in final pass
|
||
_fnApplyToChildren( function(nToSize, i) {
|
||
nToSize.style.width = headerWidths[i];
|
||
}, headerTrgEls );
|
||
|
||
$(headerSrcEls).height(0);
|
||
|
||
/* Same again with the footer if we have one */
|
||
if ( footer )
|
||
{
|
||
_fnApplyToChildren( zeroOut, footerSrcEls );
|
||
|
||
_fnApplyToChildren( function(nSizer) {
|
||
footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
|
||
}, footerSrcEls );
|
||
|
||
_fnApplyToChildren( function(nToSize, i) {
|
||
nToSize.style.width = footerWidths[i];
|
||
}, footerTrgEls );
|
||
|
||
$(footerSrcEls).height(0);
|
||
}
|
||
|
||
|
||
/*
|
||
* 3. Apply the measurements
|
||
*/
|
||
|
||
// "Hide" the header and footer that we used for the sizing. We need to keep
|
||
// the content of the cell so that the width applied to the header and body
|
||
// both match, but we want to hide it completely. We want to also fix their
|
||
// width to what they currently are
|
||
_fnApplyToChildren( function(nSizer, i) {
|
||
nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
|
||
nSizer.style.width = headerWidths[i];
|
||
}, headerSrcEls );
|
||
|
||
if ( footer )
|
||
{
|
||
_fnApplyToChildren( function(nSizer, i) {
|
||
nSizer.innerHTML = "";
|
||
nSizer.style.width = footerWidths[i];
|
||
}, footerSrcEls );
|
||
}
|
||
|
||
// Sanity check that the table is of a sensible width. If not then we are going to get
|
||
// misalignment - try to prevent this by not allowing the table to shrink below its min width
|
||
if ( table.outerWidth() < sanityWidth )
|
||
{
|
||
// The min width depends upon if we have a vertical scrollbar visible or not */
|
||
correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
|
||
divBody.css('overflow-y') == "scroll")) ?
|
||
sanityWidth+barWidth :
|
||
sanityWidth;
|
||
|
||
// IE6/7 are a law unto themselves...
|
||
if ( ie67 && (divBodyEl.scrollHeight >
|
||
divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
|
||
) {
|
||
tableStyle.width = _fnStringToCss( correction-barWidth );
|
||
}
|
||
|
||
// And give the user a warning that we've stopped the table getting too small
|
||
if ( scrollX === "" || scrollXInner !== "" ) {
|
||
_fnLog( settings, 1, 'Possible column misalignment', 6 );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
correction = '100%';
|
||
}
|
||
|
||
// Apply to the container elements
|
||
divBodyStyle.width = _fnStringToCss( correction );
|
||
divHeaderStyle.width = _fnStringToCss( correction );
|
||
|
||
if ( footer ) {
|
||
settings.nScrollFoot.style.width = _fnStringToCss( correction );
|
||
}
|
||
|
||
|
||
/*
|
||
* 4. Clean up
|
||
*/
|
||
if ( ! scrollY ) {
|
||
/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
|
||
* the scrollbar height from the visible display, rather than adding it on. We need to
|
||
* set the height in order to sort this. Don't want to do it in any other browsers.
|
||
*/
|
||
if ( ie67 ) {
|
||
divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
|
||
}
|
||
}
|
||
|
||
if ( scrollY && scroll.bCollapse ) {
|
||
divBodyStyle.height = _fnStringToCss( scrollY );
|
||
|
||
var iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?
|
||
barWidth :
|
||
0;
|
||
|
||
if ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {
|
||
divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );
|
||
}
|
||
}
|
||
|
||
/* Finally set the width's of the header and footer tables */
|
||
var iOuterWidth = table.outerWidth();
|
||
divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
|
||
|
||
// Figure out if there are scrollbar present - if so then we need a the header and footer to
|
||
// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
|
||
var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
|
||
var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
|
||
divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
|
||
|
||
if ( footer ) {
|
||
divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
|
||
}
|
||
|
||
/* Adjust the position of the header in case we loose the y-scrollbar */
|
||
divBody.scroll();
|
||
|
||
/* If sorting or filtering has occurred, jump the scrolling back to the top */
|
||
if ( settings.bSorted || settings.bFiltered ) {
|
||
divBodyEl.scrollTop = 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Apply a given function to the display child nodes of an element array (typically
|
||
* TD children of TR rows
|
||
* @param {function} fn Method to apply to the objects
|
||
* @param array {nodes} an1 List of elements to look through for display children
|
||
* @param array {nodes} an2 Another list (identical structure to the first) - optional
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnApplyToChildren( fn, an1, an2 )
|
||
{
|
||
var index=0, i=0, iLen=an1.length;
|
||
var nNode1, nNode2;
|
||
|
||
while ( i < iLen ) {
|
||
nNode1 = an1[i].firstChild;
|
||
nNode2 = an2 ? an2[i].firstChild : null;
|
||
|
||
while ( nNode1 ) {
|
||
if ( nNode1.nodeType === 1 ) {
|
||
if ( an2 ) {
|
||
fn( nNode1, nNode2, index );
|
||
}
|
||
else {
|
||
fn( nNode1, index );
|
||
}
|
||
|
||
index++;
|
||
}
|
||
|
||
nNode1 = nNode1.nextSibling;
|
||
nNode2 = an2 ? nNode2.nextSibling : null;
|
||
}
|
||
|
||
i++;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
var __re_html_remove = /<.*?>/g;
|
||
|
||
|
||
/**
|
||
* Calculate the width of columns for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCalculateColumnWidths ( oSettings )
|
||
{
|
||
var
|
||
table = oSettings.nTable,
|
||
columns = oSettings.aoColumns,
|
||
scroll = oSettings.oScroll,
|
||
scrollY = scroll.sY,
|
||
scrollX = scroll.sX,
|
||
scrollXInner = scroll.sXInner,
|
||
columnCount = columns.length,
|
||
visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
|
||
headerCells = $('th', oSettings.nTHead),
|
||
tableWidthAttr = table.getAttribute('width'),
|
||
tableContainer = table.parentNode,
|
||
userInputs = false,
|
||
i, column, columnIdx, width, outerWidth;
|
||
|
||
/* Convert any user input sizes into pixel sizes */
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
|
||
if ( column.sWidth !== null ) {
|
||
column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
|
||
|
||
userInputs = true;
|
||
}
|
||
}
|
||
|
||
/* If the number of columns in the DOM equals the number that we have to
|
||
* process in DataTables, then we can use the offsets that are created by
|
||
* the web- browser. No custom sizes can be set in order for this to happen,
|
||
* nor scrolling used
|
||
*/
|
||
if ( ! userInputs && ! scrollX && ! scrollY &&
|
||
columnCount == _fnVisbleColumns( oSettings ) &&
|
||
columnCount == headerCells.length
|
||
) {
|
||
for ( i=0 ; i<columnCount ; i++ ) {
|
||
columns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Otherwise construct a single row table with the widest node in the
|
||
// data, assign any user defined widths, then insert it into the DOM and
|
||
// allow the browser to do all the hard work of calculating table widths
|
||
var tmpTable = $( table.cloneNode( false ) )
|
||
.css( 'visibility', 'hidden' )
|
||
.removeAttr( 'id' )
|
||
.append( $(oSettings.nTHead).clone( false ) )
|
||
.append( $(oSettings.nTFoot).clone( false ) )
|
||
.append( $('<tbody><tr/></tbody>') );
|
||
|
||
// Remove any assigned widths from the footer (from scrolling)
|
||
tmpTable.find('tfoot th, tfoot td').css('width', '');
|
||
|
||
var tr = tmpTable.find( 'tbody tr' );
|
||
|
||
// Apply custom sizing to the cloned header
|
||
headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
|
||
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
|
||
headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
|
||
_fnStringToCss( column.sWidthOrig ) :
|
||
'';
|
||
}
|
||
|
||
// Find the widest cell for each column and put it into the table
|
||
if ( oSettings.aoData.length ) {
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
columnIdx = visibleColumns[i];
|
||
column = columns[ columnIdx ];
|
||
|
||
$( _fnGetWidestNode( oSettings, columnIdx ) )
|
||
.clone( false )
|
||
.append( column.sContentPadding )
|
||
.appendTo( tr );
|
||
}
|
||
}
|
||
|
||
// Table has been built, attach to the document so we can work with it
|
||
tmpTable.appendTo( tableContainer );
|
||
|
||
// When scrolling (X or Y) we want to set the width of the table as
|
||
// appropriate. However, when not scrolling leave the table width as it
|
||
// is. This results in slightly different, but I think correct behaviour
|
||
if ( scrollX && scrollXInner ) {
|
||
tmpTable.width( scrollXInner );
|
||
}
|
||
else if ( scrollX ) {
|
||
tmpTable.css( 'width', 'auto' );
|
||
|
||
if ( tmpTable.width() < tableContainer.offsetWidth ) {
|
||
tmpTable.width( tableContainer.offsetWidth );
|
||
}
|
||
}
|
||
else if ( scrollY ) {
|
||
tmpTable.width( tableContainer.offsetWidth );
|
||
}
|
||
else if ( tableWidthAttr ) {
|
||
tmpTable.width( tableWidthAttr );
|
||
}
|
||
|
||
// Take into account the y scrollbar
|
||
_fnScrollingWidthAdjust( oSettings, tmpTable[0] );
|
||
|
||
// Browsers need a bit of a hand when a width is assigned to any columns
|
||
// when x-scrolling as they tend to collapse the table to the min-width,
|
||
// even if we sent the column widths. So we need to keep track of what
|
||
// the table width should be by summing the user given values, and the
|
||
// automatic values
|
||
if ( scrollX )
|
||
{
|
||
var total = 0;
|
||
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
outerWidth = $(headerCells[i]).outerWidth();
|
||
|
||
total += column.sWidthOrig === null ?
|
||
outerWidth :
|
||
parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
|
||
}
|
||
|
||
tmpTable.width( _fnStringToCss( total ) );
|
||
table.style.width = _fnStringToCss( total );
|
||
}
|
||
|
||
// Get the width of each column in the constructed table
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
width = $(headerCells[i]).width();
|
||
|
||
if ( width ) {
|
||
column.sWidth = _fnStringToCss( width );
|
||
}
|
||
}
|
||
|
||
table.style.width = _fnStringToCss( tmpTable.css('width') );
|
||
|
||
// Finished with the table - ditch it
|
||
tmpTable.remove();
|
||
}
|
||
|
||
// If there is a width attr, we want to attach an event listener which
|
||
// allows the table sizing to automatically adjust when the window is
|
||
// resized. Use the width attr rather than CSS, since we can't know if the
|
||
// CSS is a relative value or absolute - DOM read is always px.
|
||
if ( tableWidthAttr ) {
|
||
table.style.width = _fnStringToCss( tableWidthAttr );
|
||
}
|
||
|
||
if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
|
||
$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
|
||
_fnAdjustColumnSizing( oSettings );
|
||
} ) );
|
||
|
||
oSettings._reszEvt = true;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Throttle the calls to a function. Arguments and context are maintained for
|
||
* the throttled function
|
||
* @param {function} fn Function to be called
|
||
* @param {int} [freq=200] call frequency in mS
|
||
* @returns {function} wrapped function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnThrottle( fn, freq ) {
|
||
var
|
||
frequency = freq || 200,
|
||
last,
|
||
timer;
|
||
|
||
return function () {
|
||
var
|
||
that = this,
|
||
now = +new Date(),
|
||
args = arguments;
|
||
|
||
if ( last && now < last + frequency ) {
|
||
clearTimeout( timer );
|
||
|
||
timer = setTimeout( function () {
|
||
last = undefined;
|
||
fn.apply( that, args );
|
||
}, frequency );
|
||
}
|
||
else if ( last ) {
|
||
last = now;
|
||
fn.apply( that, args );
|
||
}
|
||
else {
|
||
last = now;
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* Convert a CSS unit width to pixels (e.g. 2em)
|
||
* @param {string} width width to be converted
|
||
* @param {node} parent parent to get the with for (required for relative widths) - optional
|
||
* @returns {int} width in pixels
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnConvertToWidth ( width, parent )
|
||
{
|
||
if ( ! width ) {
|
||
return 0;
|
||
}
|
||
|
||
var n = $('<div/>')
|
||
.css( 'width', _fnStringToCss( width ) )
|
||
.appendTo( parent || document.body );
|
||
|
||
var val = n[0].offsetWidth;
|
||
n.remove();
|
||
|
||
return val;
|
||
}
|
||
|
||
|
||
/**
|
||
* Adjust a table's width to take account of vertical scroll bar
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} n table node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
|
||
function _fnScrollingWidthAdjust ( settings, n )
|
||
{
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( scroll.sX || scroll.sY ) {
|
||
// When y-scrolling only, we want to remove the width of the scroll bar
|
||
// so the table + scroll bar will fit into the area available, otherwise
|
||
// we fix the table at its current size with no adjustment
|
||
var correction = ! scroll.sX ? scroll.iBarWidth : 0;
|
||
n.style.width = _fnStringToCss( $(n).outerWidth() - correction );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the widest node
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} colIdx column of interest
|
||
* @returns {node} widest table node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetWidestNode( settings, colIdx )
|
||
{
|
||
var idx = _fnGetMaxLenString( settings, colIdx );
|
||
if ( idx < 0 ) {
|
||
return null;
|
||
}
|
||
|
||
var data = settings.aoData[ idx ];
|
||
return ! data.nTr ? // Might not have been created when deferred rendering
|
||
$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
|
||
data.anCells[ colIdx ];
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the maximum strlen for each data column
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} colIdx column of interest
|
||
* @returns {string} max string length for each column
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetMaxLenString( settings, colIdx )
|
||
{
|
||
var s, max=-1, maxIdx = -1;
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
|
||
s = s.replace( __re_html_remove, '' );
|
||
|
||
if ( s.length > max ) {
|
||
max = s.length;
|
||
maxIdx = i;
|
||
}
|
||
}
|
||
|
||
return maxIdx;
|
||
}
|
||
|
||
|
||
/**
|
||
* Append a CSS unit (only if required) to a string
|
||
* @param {string} value to css-ify
|
||
* @returns {string} value with css unit
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnStringToCss( s )
|
||
{
|
||
if ( s === null ) {
|
||
return '0px';
|
||
}
|
||
|
||
if ( typeof s == 'number' ) {
|
||
return s < 0 ?
|
||
'0px' :
|
||
s+'px';
|
||
}
|
||
|
||
// Check it has a unit character already
|
||
return s.match(/\d$/) ?
|
||
s+'px' :
|
||
s;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the width of a scroll bar in this browser being used
|
||
* @returns {int} width in pixels
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnScrollBarWidth ()
|
||
{
|
||
// On first run a static variable is set, since this is only needed once.
|
||
// Subsequent runs will just use the previously calculated value
|
||
if ( ! DataTable.__scrollbarWidth ) {
|
||
var inner = $('<p/>').css( {
|
||
width: '100%',
|
||
height: 200,
|
||
padding: 0
|
||
} )[0];
|
||
|
||
var outer = $('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
width: 200,
|
||
height: 150,
|
||
padding: 0,
|
||
overflow: 'hidden',
|
||
visibility: 'hidden'
|
||
} )
|
||
.append( inner )
|
||
.appendTo( 'body' );
|
||
|
||
var w1 = inner.offsetWidth;
|
||
outer.css( 'overflow', 'scroll' );
|
||
var w2 = inner.offsetWidth;
|
||
|
||
if ( w1 === w2 ) {
|
||
w2 = outer[0].clientWidth;
|
||
}
|
||
|
||
outer.remove();
|
||
|
||
DataTable.__scrollbarWidth = w1 - w2;
|
||
}
|
||
|
||
return DataTable.__scrollbarWidth;
|
||
}
|
||
|
||
|
||
|
||
function _fnSortFlatten ( settings )
|
||
{
|
||
var
|
||
i, iLen, k, kLen,
|
||
aSort = [],
|
||
aiOrig = [],
|
||
aoColumns = settings.aoColumns,
|
||
aDataSort, iCol, sType, srcCol,
|
||
fixed = settings.aaSortingFixed,
|
||
fixedObj = $.isPlainObject( fixed ),
|
||
nestedSort = [],
|
||
add = function ( a ) {
|
||
if ( a.length && ! $.isArray( a[0] ) ) {
|
||
// 1D array
|
||
nestedSort.push( a );
|
||
}
|
||
else {
|
||
// 2D array
|
||
nestedSort.push.apply( nestedSort, a );
|
||
}
|
||
};
|
||
|
||
// Build the sort array, with pre-fix and post-fix options if they have been
|
||
// specified
|
||
if ( $.isArray( fixed ) ) {
|
||
add( fixed );
|
||
}
|
||
|
||
if ( fixedObj && fixed.pre ) {
|
||
add( fixed.pre );
|
||
}
|
||
|
||
add( settings.aaSorting );
|
||
|
||
if (fixedObj && fixed.post ) {
|
||
add( fixed.post );
|
||
}
|
||
|
||
for ( i=0 ; i<nestedSort.length ; i++ )
|
||
{
|
||
srcCol = nestedSort[i][0];
|
||
aDataSort = aoColumns[ srcCol ].aDataSort;
|
||
|
||
for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
|
||
{
|
||
iCol = aDataSort[k];
|
||
sType = aoColumns[ iCol ].sType || 'string';
|
||
|
||
aSort.push( {
|
||
src: srcCol,
|
||
col: iCol,
|
||
dir: nestedSort[i][1],
|
||
index: nestedSort[i][2],
|
||
type: sType,
|
||
formatter: DataTable.ext.type.order[ sType+"-pre" ]
|
||
} );
|
||
}
|
||
}
|
||
|
||
return aSort;
|
||
}
|
||
|
||
/**
|
||
* Change the order of the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
* @todo This really needs split up!
|
||
*/
|
||
function _fnSort ( oSettings )
|
||
{
|
||
var
|
||
i, ien, iLen, j, jLen, k, kLen,
|
||
sDataType, nTh,
|
||
aiOrig = [],
|
||
oExtSort = DataTable.ext.type.order,
|
||
aoData = oSettings.aoData,
|
||
aoColumns = oSettings.aoColumns,
|
||
aDataSort, data, iCol, sType, oSort,
|
||
formatters = 0,
|
||
sortCol,
|
||
displayMaster = oSettings.aiDisplayMaster,
|
||
aSort;
|
||
|
||
// Resolve any column types that are unknown due to addition or invalidation
|
||
// @todo Can this be moved into a 'data-ready' handler which is called when
|
||
// data is going to be used in the table?
|
||
_fnColumnTypes( oSettings );
|
||
|
||
aSort = _fnSortFlatten( oSettings );
|
||
|
||
for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
|
||
sortCol = aSort[i];
|
||
|
||
// Track if we can use the fast sort algorithm
|
||
if ( sortCol.formatter ) {
|
||
formatters++;
|
||
}
|
||
|
||
// Load the data needed for the sort, for each cell
|
||
_fnSortData( oSettings, sortCol.col );
|
||
}
|
||
|
||
/* No sorting required if server-side or no sorting array */
|
||
if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
|
||
{
|
||
// Create a value - key array of the current row positions such that we can use their
|
||
// current position during the sort, if values match, in order to perform stable sorting
|
||
for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
|
||
aiOrig[ displayMaster[i] ] = i;
|
||
}
|
||
|
||
/* Do the sort - here we want multi-column sorting based on a given data source (column)
|
||
* and sorting function (from oSort) in a certain direction. It's reasonably complex to
|
||
* follow on it's own, but this is what we want (example two column sorting):
|
||
* fnLocalSorting = function(a,b){
|
||
* var iTest;
|
||
* iTest = oSort['string-asc']('data11', 'data12');
|
||
* if (iTest !== 0)
|
||
* return iTest;
|
||
* iTest = oSort['numeric-desc']('data21', 'data22');
|
||
* if (iTest !== 0)
|
||
* return iTest;
|
||
* return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
|
||
* }
|
||
* Basically we have a test for each sorting column, if the data in that column is equal,
|
||
* test the next column. If all columns match, then we use a numeric sort on the row
|
||
* positions in the original data array to provide a stable sort.
|
||
*
|
||
* Note - I know it seems excessive to have two sorting methods, but the first is around
|
||
* 15% faster, so the second is only maintained for backwards compatibility with sorting
|
||
* methods which do not have a pre-sort formatting function.
|
||
*/
|
||
if ( formatters === aSort.length ) {
|
||
// All sort types have formatting functions
|
||
displayMaster.sort( function ( a, b ) {
|
||
var
|
||
x, y, k, test, sort,
|
||
len=aSort.length,
|
||
dataA = aoData[a]._aSortData,
|
||
dataB = aoData[b]._aSortData;
|
||
|
||
for ( k=0 ; k<len ; k++ ) {
|
||
sort = aSort[k];
|
||
|
||
x = dataA[ sort.col ];
|
||
y = dataB[ sort.col ];
|
||
|
||
test = x<y ? -1 : x>y ? 1 : 0;
|
||
if ( test !== 0 ) {
|
||
return sort.dir === 'asc' ? test : -test;
|
||
}
|
||
}
|
||
|
||
x = aiOrig[a];
|
||
y = aiOrig[b];
|
||
return x<y ? -1 : x>y ? 1 : 0;
|
||
} );
|
||
}
|
||
else {
|
||
// Depreciated - remove in 1.11 (providing a plug-in option)
|
||
// Not all sort types have formatting methods, so we have to call their sorting
|
||
// methods.
|
||
displayMaster.sort( function ( a, b ) {
|
||
var
|
||
x, y, k, l, test, sort, fn,
|
||
len=aSort.length,
|
||
dataA = aoData[a]._aSortData,
|
||
dataB = aoData[b]._aSortData;
|
||
|
||
for ( k=0 ; k<len ; k++ ) {
|
||
sort = aSort[k];
|
||
|
||
x = dataA[ sort.col ];
|
||
y = dataB[ sort.col ];
|
||
|
||
fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
|
||
test = fn( x, y );
|
||
if ( test !== 0 ) {
|
||
return test;
|
||
}
|
||
}
|
||
|
||
x = aiOrig[a];
|
||
y = aiOrig[b];
|
||
return x<y ? -1 : x>y ? 1 : 0;
|
||
} );
|
||
}
|
||
}
|
||
|
||
/* Tell the draw function that we have sorted the data */
|
||
oSettings.bSorted = true;
|
||
}
|
||
|
||
|
||
function _fnSortAria ( settings )
|
||
{
|
||
var label;
|
||
var nextSort;
|
||
var columns = settings.aoColumns;
|
||
var aSort = _fnSortFlatten( settings );
|
||
var oAria = settings.oLanguage.oAria;
|
||
|
||
// ARIA attributes - need to loop all columns, to update all (removing old
|
||
// attributes as needed)
|
||
for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
var col = columns[i];
|
||
var asSorting = col.asSorting;
|
||
var sTitle = col.sTitle.replace( /<.*?>/g, "" );
|
||
var th = col.nTh;
|
||
|
||
// IE7 is throwing an error when setting these properties with jQuery's
|
||
// attr() and removeAttr() methods...
|
||
th.removeAttribute('aria-sort');
|
||
|
||
/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
|
||
if ( col.bSortable ) {
|
||
if ( aSort.length > 0 && aSort[0].col == i ) {
|
||
th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
|
||
nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
|
||
}
|
||
else {
|
||
nextSort = asSorting[0];
|
||
}
|
||
|
||
label = sTitle + ( nextSort === "asc" ?
|
||
oAria.sSortAscending :
|
||
oAria.sSortDescending
|
||
);
|
||
}
|
||
else {
|
||
label = sTitle;
|
||
}
|
||
|
||
th.setAttribute('aria-label', label);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to run on user sort request
|
||
* @param {object} settings dataTables settings object
|
||
* @param {node} attachTo node to attach the handler to
|
||
* @param {int} colIdx column sorting index
|
||
* @param {boolean} [append=false] Append the requested sort to the existing
|
||
* sort if true (i.e. multi-column sort)
|
||
* @param {function} [callback] callback function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortListener ( settings, colIdx, append, callback )
|
||
{
|
||
var col = settings.aoColumns[ colIdx ];
|
||
var sorting = settings.aaSorting;
|
||
var asSorting = col.asSorting;
|
||
var nextSortIdx;
|
||
var next = function ( a ) {
|
||
var idx = a._idx;
|
||
if ( idx === undefined ) {
|
||
idx = $.inArray( a[1], asSorting );
|
||
}
|
||
|
||
return idx+1 >= asSorting.length ? 0 : idx+1;
|
||
};
|
||
|
||
// If appending the sort then we are multi-column sorting
|
||
if ( append && settings.oFeatures.bSortMulti ) {
|
||
// Are we already doing some kind of sort on this column?
|
||
var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
|
||
|
||
if ( sortIdx !== -1 ) {
|
||
// Yes, modify the sort
|
||
nextSortIdx = next( sorting[sortIdx] );
|
||
|
||
sorting[sortIdx][1] = asSorting[ nextSortIdx ];
|
||
sorting[sortIdx]._idx = nextSortIdx;
|
||
}
|
||
else {
|
||
// No sort on this column yet
|
||
sorting.push( [ colIdx, asSorting[0], 0 ] );
|
||
sorting[sorting.length-1]._idx = 0;
|
||
}
|
||
}
|
||
else if ( sorting.length && sorting[0][0] == colIdx ) {
|
||
// Single column - already sorting on this column, modify the sort
|
||
nextSortIdx = next( sorting[0] );
|
||
|
||
sorting.length = 1;
|
||
sorting[0][1] = asSorting[ nextSortIdx ];
|
||
sorting[0]._idx = nextSortIdx;
|
||
}
|
||
else {
|
||
// Single column - sort only on this column
|
||
sorting.length = 0;
|
||
sorting.push( [ colIdx, asSorting[0] ] );
|
||
sorting[0]._idx = 0;
|
||
}
|
||
|
||
// Run the sort by calling a full redraw
|
||
_fnReDraw( settings );
|
||
|
||
// callback used for async user interaction
|
||
if ( typeof callback == 'function' ) {
|
||
callback( settings );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Attach a sort handler (click) to a node
|
||
* @param {object} settings dataTables settings object
|
||
* @param {node} attachTo node to attach the handler to
|
||
* @param {int} colIdx column sorting index
|
||
* @param {function} [callback] callback function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
|
||
{
|
||
var col = settings.aoColumns[ colIdx ];
|
||
|
||
_fnBindAction( attachTo, {}, function (e) {
|
||
/* If the column is not sortable - don't to anything */
|
||
if ( col.bSortable === false ) {
|
||
return;
|
||
}
|
||
|
||
// If processing is enabled use a timeout to allow the processing
|
||
// display to be shown - otherwise to it synchronously
|
||
if ( settings.oFeatures.bProcessing ) {
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
setTimeout( function() {
|
||
_fnSortListener( settings, colIdx, e.shiftKey, callback );
|
||
|
||
// In server-side processing, the draw callback will remove the
|
||
// processing display
|
||
if ( _fnDataSource( settings ) !== 'ssp' ) {
|
||
_fnProcessingDisplay( settings, false );
|
||
}
|
||
}, 0 );
|
||
}
|
||
else {
|
||
_fnSortListener( settings, colIdx, e.shiftKey, callback );
|
||
}
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Set the sorting classes on table's body, Note: it is safe to call this function
|
||
* when bSort and bSortClasses are false
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortingClasses( settings )
|
||
{
|
||
var oldSort = settings.aLastSort;
|
||
var sortClass = settings.oClasses.sSortColumn;
|
||
var sort = _fnSortFlatten( settings );
|
||
var features = settings.oFeatures;
|
||
var i, ien, colIdx;
|
||
|
||
if ( features.bSort && features.bSortClasses ) {
|
||
// Remove old sorting classes
|
||
for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
|
||
colIdx = oldSort[i].src;
|
||
|
||
// Remove column sorting
|
||
$( _pluck( settings.aoData, 'anCells', colIdx ) )
|
||
.removeClass( sortClass + (i<2 ? i+1 : 3) );
|
||
}
|
||
|
||
// Add new column sorting
|
||
for ( i=0, ien=sort.length ; i<ien ; i++ ) {
|
||
colIdx = sort[i].src;
|
||
|
||
$( _pluck( settings.aoData, 'anCells', colIdx ) )
|
||
.addClass( sortClass + (i<2 ? i+1 : 3) );
|
||
}
|
||
}
|
||
|
||
settings.aLastSort = sort;
|
||
}
|
||
|
||
|
||
// Get the data to sort a column, be it from cache, fresh (populating the
|
||
// cache), or from a sort formatter
|
||
function _fnSortData( settings, idx )
|
||
{
|
||
// Custom sorting function - provided by the sort data type
|
||
var column = settings.aoColumns[ idx ];
|
||
var customSort = DataTable.ext.order[ column.sSortDataType ];
|
||
var customData;
|
||
|
||
if ( customSort ) {
|
||
customData = customSort.call( settings.oInstance, settings, idx,
|
||
_fnColumnIndexToVisible( settings, idx )
|
||
);
|
||
}
|
||
|
||
// Use / populate cache
|
||
var row, cellData;
|
||
var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( ! row._aSortData ) {
|
||
row._aSortData = [];
|
||
}
|
||
|
||
if ( ! row._aSortData[idx] || customSort ) {
|
||
cellData = customSort ?
|
||
customData[i] : // If there was a custom sort function, use data from there
|
||
_fnGetCellData( settings, i, idx, 'sort' );
|
||
|
||
row._aSortData[ idx ] = formatter ?
|
||
formatter( cellData ) :
|
||
cellData;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Save the state of a table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSaveState ( oSettings )
|
||
{
|
||
if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying )
|
||
{
|
||
return;
|
||
}
|
||
|
||
/* Store the interesting variables */
|
||
var i, iLen;
|
||
var oState = {
|
||
"iCreate": +new Date(),
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iLength": oSettings._iDisplayLength,
|
||
"aaSorting": $.extend( true, [], oSettings.aaSorting ),
|
||
"oSearch": $.extend( true, {}, oSettings.oPreviousSearch ),
|
||
"aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ),
|
||
"abVisCols": _pluck( oSettings.aoColumns, 'bVisible' )
|
||
};
|
||
|
||
_fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
|
||
|
||
oSettings.fnStateSaveCallback.call( oSettings.oInstance, oSettings, oState );
|
||
}
|
||
|
||
|
||
/**
|
||
* Attempt to load a saved table state
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} oInit DataTables init object so we can override settings
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLoadState ( oSettings, oInit )
|
||
{
|
||
var i, ien;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
if ( ! oSettings.oFeatures.bStateSave ) {
|
||
return;
|
||
}
|
||
|
||
var oData = oSettings.fnStateLoadCallback.call( oSettings.oInstance, oSettings );
|
||
if ( !oData ) {
|
||
return;
|
||
}
|
||
|
||
/* Allow custom and plug-in manipulation functions to alter the saved data set and
|
||
* cancelling of loading by returning false
|
||
*/
|
||
var abStateLoad = _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
|
||
if ( $.inArray( false, abStateLoad ) !== -1 ) {
|
||
return;
|
||
}
|
||
|
||
/* Reject old data */
|
||
var duration = oSettings.iStateDuration;
|
||
if ( duration > 0 && oData.iCreate < +new Date() - (duration*1000) ) {
|
||
return;
|
||
}
|
||
|
||
// Number of columns have changed - all bets are off, no restore of settings
|
||
if ( columns.length !== oData.aoSearchCols.length ) {
|
||
return;
|
||
}
|
||
|
||
/* Store the saved state so it might be accessed at any time */
|
||
oSettings.oLoadedState = $.extend( true, {}, oData );
|
||
|
||
/* Restore key features */
|
||
oSettings._iDisplayStart = oData.iStart;
|
||
oSettings.iInitDisplayStart = oData.iStart;
|
||
oSettings._iDisplayLength = oData.iLength;
|
||
oSettings.aaSorting = $.map( oData.aaSorting, function ( col, i ) {
|
||
return col[0] >= columns.length ?
|
||
[ 0, col[1] ] :
|
||
col;
|
||
} );
|
||
|
||
/* Search filtering */
|
||
$.extend( oSettings.oPreviousSearch, oData.oSearch );
|
||
$.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
|
||
|
||
/* Column visibility state */
|
||
var visColumns = oData.abVisCols;
|
||
for ( i=0, ien=visColumns.length ; i<ien ; i++ ) {
|
||
columns[i].bVisible = visColumns[i];
|
||
}
|
||
|
||
_fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Return the settings object for a particular table
|
||
* @param {node} table table we are using as a dataTable
|
||
* @returns {object} Settings object - or null if not found
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSettingsFromNode ( table )
|
||
{
|
||
var settings = DataTable.settings;
|
||
var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
|
||
|
||
return idx !== -1 ?
|
||
settings[ idx ] :
|
||
null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Log an error message
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} level log error messages, or display them to the user
|
||
* @param {string} msg error message
|
||
* @param {int} tn Technical note id to get more information about the error.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLog( settings, level, msg, tn )
|
||
{
|
||
msg = 'DataTables warning: '+
|
||
(settings!==null ? 'table id='+settings.sTableId+' - ' : '')+msg;
|
||
|
||
if ( tn ) {
|
||
msg += '. For more information about this error, please see '+
|
||
'http://datatables.net/tn/'+tn;
|
||
}
|
||
|
||
if ( ! level ) {
|
||
// Backwards compatibility pre 1.10
|
||
var ext = DataTable.ext;
|
||
var type = ext.sErrMode || ext.errMode;
|
||
|
||
if ( type == 'alert' ) {
|
||
alert( msg );
|
||
}
|
||
else {
|
||
throw new Error(msg);
|
||
}
|
||
}
|
||
else if ( window.console && console.log ) {
|
||
console.log( msg );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* See if a property is defined on one object, if so assign it to the other object
|
||
* @param {object} ret target object
|
||
* @param {object} src source object
|
||
* @param {string} name property
|
||
* @param {string} [mappedName] name to map too - optional, name used if not given
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnMap( ret, src, name, mappedName )
|
||
{
|
||
if ( $.isArray( name ) ) {
|
||
$.each( name, function (i, val) {
|
||
if ( $.isArray( val ) ) {
|
||
_fnMap( ret, src, val[0], val[1] );
|
||
}
|
||
else {
|
||
_fnMap( ret, src, val );
|
||
}
|
||
} );
|
||
|
||
return;
|
||
}
|
||
|
||
if ( mappedName === undefined ) {
|
||
mappedName = name;
|
||
}
|
||
|
||
if ( src[name] !== undefined ) {
|
||
ret[mappedName] = src[name];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Extend objects - very similar to jQuery.extend, but deep copy objects, and
|
||
* shallow copy arrays. The reason we need to do this, is that we don't want to
|
||
* deep copy array init values (such as aaSorting) since the dev wouldn't be
|
||
* able to override them, but we do want to deep copy arrays.
|
||
* @param {object} out Object to extend
|
||
* @param {object} extender Object from which the properties will be applied to
|
||
* out
|
||
* @param {boolean} breakRefs If true, then arrays will be sliced to take an
|
||
* independent copy with the exception of the `data` or `aaData` parameters
|
||
* if they are present. This is so you can pass in a collection to
|
||
* DataTables and have that used as your data source without breaking the
|
||
* references
|
||
* @returns {object} out Reference, just for convenience - out === the return.
|
||
* @memberof DataTable#oApi
|
||
* @todo This doesn't take account of arrays inside the deep copied objects.
|
||
*/
|
||
function _fnExtend( out, extender, breakRefs )
|
||
{
|
||
var val;
|
||
|
||
for ( var prop in extender ) {
|
||
if ( extender.hasOwnProperty(prop) ) {
|
||
val = extender[prop];
|
||
|
||
if ( $.isPlainObject( val ) ) {
|
||
if ( ! $.isPlainObject( out[prop] ) ) {
|
||
out[prop] = {};
|
||
}
|
||
$.extend( true, out[prop], val );
|
||
}
|
||
else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
|
||
out[prop] = val.slice();
|
||
}
|
||
else {
|
||
out[prop] = val;
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
}
|
||
|
||
|
||
/**
|
||
* Bind an event handers to allow a click or return key to activate the callback.
|
||
* This is good for accessibility since a return on the keyboard will have the
|
||
* same effect as a click, if the element has focus.
|
||
* @param {element} n Element to bind the action to
|
||
* @param {object} oData Data object to pass to the triggered function
|
||
* @param {function} fn Callback function for when the event is triggered
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBindAction( n, oData, fn )
|
||
{
|
||
$(n)
|
||
.bind( 'click.DT', oData, function (e) {
|
||
n.blur(); // Remove focus outline for mouse users
|
||
fn(e);
|
||
} )
|
||
.bind( 'keypress.DT', oData, function (e){
|
||
if ( e.which === 13 ) {
|
||
e.preventDefault();
|
||
fn(e);
|
||
}
|
||
} )
|
||
.bind( 'selectstart.DT', function () {
|
||
/* Take the brutal approach to cancelling text selection */
|
||
return false;
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Register a callback function. Easily allows a callback function to be added to
|
||
* an array store of callback functions that can then all be called together.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sStore Name of the array storage for the callbacks in oSettings
|
||
* @param {function} fn Function to be called back
|
||
* @param {string} sName Identifying name for the callback (i.e. a label)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCallbackReg( oSettings, sStore, fn, sName )
|
||
{
|
||
if ( fn )
|
||
{
|
||
oSettings[sStore].push( {
|
||
"fn": fn,
|
||
"sName": sName
|
||
} );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Fire callback functions and trigger events. Note that the loop over the
|
||
* callback array store is done backwards! Further note that you do not want to
|
||
* fire off triggers in time sensitive applications (for example cell creation)
|
||
* as its slow.
|
||
* @param {object} settings dataTables settings object
|
||
* @param {string} callbackArr Name of the array storage for the callbacks in
|
||
* oSettings
|
||
* @param {string} event Name of the jQuery custom event to trigger. If null no
|
||
* trigger is fired
|
||
* @param {array} args Array of arguments to pass to the callback function /
|
||
* trigger
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCallbackFire( settings, callbackArr, event, args )
|
||
{
|
||
var ret = [];
|
||
|
||
if ( callbackArr ) {
|
||
ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
|
||
return val.fn.apply( settings.oInstance, args );
|
||
} );
|
||
}
|
||
|
||
if ( event !== null ) {
|
||
$(settings.nTable).trigger( event+'.dt', args );
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
function _fnLengthOverflow ( settings )
|
||
{
|
||
var
|
||
start = settings._iDisplayStart,
|
||
end = settings.fnDisplayEnd(),
|
||
len = settings._iDisplayLength;
|
||
|
||
/* If we have space to show extra rows (backing up from the end point - then do so */
|
||
if ( end === settings.fnRecordsDisplay() )
|
||
{
|
||
start = end - len;
|
||
}
|
||
|
||
if ( len === -1 || start < 0 )
|
||
{
|
||
start = 0;
|
||
}
|
||
|
||
settings._iDisplayStart = start;
|
||
}
|
||
|
||
|
||
function _fnRenderer( settings, type )
|
||
{
|
||
var renderer = settings.renderer;
|
||
var host = DataTable.ext.renderer[type];
|
||
|
||
if ( $.isPlainObject( renderer ) && renderer[type] ) {
|
||
// Specific renderer for this type. If available use it, otherwise use
|
||
// the default.
|
||
return host[renderer[type]] || host._;
|
||
}
|
||
else if ( typeof renderer === 'string' ) {
|
||
// Common renderer - if there is one available for this type use it,
|
||
// otherwise use the default
|
||
return host[renderer] || host._;
|
||
}
|
||
|
||
// Use the default
|
||
return host._;
|
||
}
|
||
|
||
|
||
/**
|
||
* Detect the data source being used for the table. Used to simplify the code
|
||
* a little (ajax) and to make it compress a little smaller.
|
||
*
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {string} Data source
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDataSource ( settings )
|
||
{
|
||
if ( settings.oFeatures.bServerSide ) {
|
||
return 'ssp';
|
||
}
|
||
else if ( settings.ajax || settings.sAjaxSource ) {
|
||
return 'ajax';
|
||
}
|
||
return 'dom';
|
||
}
|
||
|
||
|
||
DataTable = function( options )
|
||
{
|
||
/**
|
||
* Perform a jQuery selector action on the table's TR elements (from the tbody) and
|
||
* return the resulting jQuery object.
|
||
* @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
|
||
* @param {object} [oOpts] Optional parameters for modifying the rows to be included
|
||
* @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
|
||
* criterion ("applied") or all TR elements (i.e. no filter).
|
||
* @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
|
||
* Can be either 'current', whereby the current sorting of the table is used, or
|
||
* 'original' whereby the original order the data was read into the table is used.
|
||
* @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
|
||
* ("current") or not ("all"). If 'current' is given, then order is assumed to be
|
||
* 'current' and filter is 'applied', regardless of what they might be given as.
|
||
* @returns {object} jQuery object, filtered by the given selector.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Highlight every second row
|
||
* oTable.$('tr:odd').css('backgroundColor', 'blue');
|
||
* } );
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Filter to rows with 'Webkit' in them, add a background colour and then
|
||
* // remove the filter, thus highlighting the 'Webkit' rows only.
|
||
* oTable.fnFilter('Webkit');
|
||
* oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
|
||
* oTable.fnFilter('');
|
||
* } );
|
||
*/
|
||
this.$ = function ( sSelector, oOpts )
|
||
{
|
||
return this.api(true).$( sSelector, oOpts );
|
||
};
|
||
|
||
|
||
/**
|
||
* Almost identical to $ in operation, but in this case returns the data for the matched
|
||
* rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
|
||
* rather than any descendants, so the data can be obtained for the row/cell. If matching
|
||
* rows are found, the data returned is the original data array/object that was used to
|
||
* create the row (or a generated array if from a DOM source).
|
||
*
|
||
* This method is often useful in-combination with $ where both functions are given the
|
||
* same parameters and the array indexes will match identically.
|
||
* @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
|
||
* @param {object} [oOpts] Optional parameters for modifying the rows to be included
|
||
* @param {string} [oOpts.filter=none] Select elements that meet the current filter
|
||
* criterion ("applied") or all elements (i.e. no filter).
|
||
* @param {string} [oOpts.order=current] Order of the data in the processed array.
|
||
* Can be either 'current', whereby the current sorting of the table is used, or
|
||
* 'original' whereby the original order the data was read into the table is used.
|
||
* @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
|
||
* ("current") or not ("all"). If 'current' is given, then order is assumed to be
|
||
* 'current' and filter is 'applied', regardless of what they might be given as.
|
||
* @returns {array} Data for the matched elements. If any elements, as a result of the
|
||
* selector, were not TR, TD or TH elements in the DataTable, they will have a null
|
||
* entry in the array.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Get the data from the first row in the table
|
||
* var data = oTable._('tr:first');
|
||
*
|
||
* // Do something useful with the data
|
||
* alert( "First cell is: "+data[0] );
|
||
* } );
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Filter to 'Webkit' and get all data for
|
||
* oTable.fnFilter('Webkit');
|
||
* var data = oTable._('tr', {"search": "applied"});
|
||
*
|
||
* // Do something with the data
|
||
* alert( data.length+" rows matched the search" );
|
||
* } );
|
||
*/
|
||
this._ = function ( sSelector, oOpts )
|
||
{
|
||
return this.api(true).rows( sSelector, oOpts ).data();
|
||
};
|
||
|
||
|
||
/**
|
||
* Create a DataTables Api instance, with the currently selected tables for
|
||
* the Api's context.
|
||
* @param {boolean} [traditional=false] Set the API instance's context to be
|
||
* only the table referred to by the `DataTable.ext.iApiIndex` option, as was
|
||
* used in the API presented by DataTables 1.9- (i.e. the traditional mode),
|
||
* or if all tables captured in the jQuery object should be used.
|
||
* @return {DataTables.Api}
|
||
*/
|
||
this.api = function ( traditional )
|
||
{
|
||
return traditional ?
|
||
new _Api(
|
||
_fnSettingsFromNode( this[ _ext.iApiIndex ] )
|
||
) :
|
||
new _Api( this );
|
||
};
|
||
|
||
|
||
/**
|
||
* Add a single new row or multiple rows of data to the table. Please note
|
||
* that this is suitable for client-side processing only - if you are using
|
||
* server-side processing (i.e. "bServerSide": true), then to add data, you
|
||
* must add it to the data source, i.e. the server-side, through an Ajax call.
|
||
* @param {array|object} data The data to be added to the table. This can be:
|
||
* <ul>
|
||
* <li>1D array of data - add a single row with the data provided</li>
|
||
* <li>2D array of arrays - add multiple rows in a single call</li>
|
||
* <li>object - data object when using <i>mData</i></li>
|
||
* <li>array of objects - multiple data objects when using <i>mData</i></li>
|
||
* </ul>
|
||
* @param {bool} [redraw=true] redraw the table or not
|
||
* @returns {array} An array of integers, representing the list of indexes in
|
||
* <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
|
||
* the table.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* // Global var for counter
|
||
* var giCount = 2;
|
||
*
|
||
* $(document).ready(function() {
|
||
* $('#example').dataTable();
|
||
* } );
|
||
*
|
||
* function fnClickAddRow() {
|
||
* $('#example').dataTable().fnAddData( [
|
||
* giCount+".1",
|
||
* giCount+".2",
|
||
* giCount+".3",
|
||
* giCount+".4" ]
|
||
* );
|
||
*
|
||
* giCount++;
|
||
* }
|
||
*/
|
||
this.fnAddData = function( data, redraw )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
/* Check if we want to add multiple rows or not */
|
||
var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
|
||
api.rows.add( data ) :
|
||
api.row.add( data );
|
||
|
||
if ( redraw === undefined || redraw ) {
|
||
api.draw();
|
||
}
|
||
|
||
return rows.flatten().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* This function will make DataTables recalculate the column sizes, based on the data
|
||
* contained in the table and the sizes applied to the columns (in the DOM, CSS or
|
||
* through the sWidth parameter). This can be useful when the width of the table's
|
||
* parent element changes (for example a window resize).
|
||
* @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable( {
|
||
* "sScrollY": "200px",
|
||
* "bPaginate": false
|
||
* } );
|
||
*
|
||
* $(window).bind('resize', function () {
|
||
* oTable.fnAdjustColumnSizing();
|
||
* } );
|
||
* } );
|
||
*/
|
||
this.fnAdjustColumnSizing = function ( bRedraw )
|
||
{
|
||
var api = this.api( true ).columns.adjust();
|
||
var settings = api.settings()[0];
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw( false );
|
||
}
|
||
else if ( scroll.sX !== "" || scroll.sY !== "" ) {
|
||
/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
|
||
_fnScrollDraw( settings );
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Quickly and simply clear a table
|
||
* @param {bool} [bRedraw=true] redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
|
||
* oTable.fnClearTable();
|
||
* } );
|
||
*/
|
||
this.fnClearTable = function( bRedraw )
|
||
{
|
||
var api = this.api( true ).clear();
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* The exact opposite of 'opening' a row, this function will close any rows which
|
||
* are currently 'open'.
|
||
* @param {node} nTr the table row to 'close'
|
||
* @returns {int} 0 on success, or 1 if failed (can't find the row)
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnClose = function( nTr )
|
||
{
|
||
this.api( true ).row( nTr ).child.hide();
|
||
};
|
||
|
||
|
||
/**
|
||
* Remove a row for the table
|
||
* @param {mixed} target The index of the row from aoData to be deleted, or
|
||
* the TR element you want to delete
|
||
* @param {function|null} [callBack] Callback function
|
||
* @param {bool} [redraw=true] Redraw the table or not
|
||
* @returns {array} The row that was deleted
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Immediately remove the first row
|
||
* oTable.fnDeleteRow( 0 );
|
||
* } );
|
||
*/
|
||
this.fnDeleteRow = function( target, callback, redraw )
|
||
{
|
||
var api = this.api( true );
|
||
var rows = api.rows( target );
|
||
var settings = rows.settings()[0];
|
||
var data = settings.aoData[ rows[0][0] ];
|
||
|
||
rows.remove();
|
||
|
||
if ( callback ) {
|
||
callback.call( this, settings, data );
|
||
}
|
||
|
||
if ( redraw === undefined || redraw ) {
|
||
api.draw();
|
||
}
|
||
|
||
return data;
|
||
};
|
||
|
||
|
||
/**
|
||
* Restore the table to it's original state in the DOM by removing all of DataTables
|
||
* enhancements, alterations to the DOM structure of the table and event listeners.
|
||
* @param {boolean} [remove=false] Completely remove the table from the DOM
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* // This example is fairly pointless in reality, but shows how fnDestroy can be used
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnDestroy();
|
||
* } );
|
||
*/
|
||
this.fnDestroy = function ( remove )
|
||
{
|
||
this.api( true ).destroy( remove );
|
||
};
|
||
|
||
|
||
/**
|
||
* Redraw the table
|
||
* @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
|
||
* oTable.fnDraw();
|
||
* } );
|
||
*/
|
||
this.fnDraw = function( complete )
|
||
{
|
||
// Note that this isn't an exact match to the old call to _fnDraw - it takes
|
||
// into account the new data, but can old position.
|
||
this.api( true ).draw( ! complete );
|
||
};
|
||
|
||
|
||
/**
|
||
* Filter the input based on data
|
||
* @param {string} sInput String to filter the table on
|
||
* @param {int|null} [iColumn] Column to limit filtering to
|
||
* @param {bool} [bRegex=false] Treat as regular expression or not
|
||
* @param {bool} [bSmart=true] Perform smart filtering or not
|
||
* @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
|
||
* @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sometime later - filter...
|
||
* oTable.fnFilter( 'test string' );
|
||
* } );
|
||
*/
|
||
this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( iColumn === null || iColumn === undefined ) {
|
||
api.search( sInput, bRegex, bSmart, bCaseInsensitive );
|
||
}
|
||
else {
|
||
api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
|
||
}
|
||
|
||
api.draw();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the data for the whole table, an individual row or an individual cell based on the
|
||
* provided parameters.
|
||
* @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
|
||
* a TR node then the data source for the whole row will be returned. If given as a
|
||
* TD/TH cell node then iCol will be automatically calculated and the data for the
|
||
* cell returned. If given as an integer, then this is treated as the aoData internal
|
||
* data index for the row (see fnGetPosition) and the data for that row used.
|
||
* @param {int} [col] Optional column index that you want the data of.
|
||
* @returns {array|object|string} If mRow is undefined, then the data for all rows is
|
||
* returned. If mRow is defined, just data for that row, and is iCol is
|
||
* defined, only data for the designated cell is returned.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* // Row data
|
||
* $(document).ready(function() {
|
||
* oTable = $('#example').dataTable();
|
||
*
|
||
* oTable.$('tr').click( function () {
|
||
* var data = oTable.fnGetData( this );
|
||
* // ... do something with the array / object of data for the row
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Individual cell data
|
||
* $(document).ready(function() {
|
||
* oTable = $('#example').dataTable();
|
||
*
|
||
* oTable.$('td').click( function () {
|
||
* var sData = oTable.fnGetData( this );
|
||
* alert( 'The cell clicked on had the value of '+sData );
|
||
* } );
|
||
* } );
|
||
*/
|
||
this.fnGetData = function( src, col )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( src !== undefined ) {
|
||
var type = src.nodeName ? src.nodeName.toLowerCase() : '';
|
||
|
||
return col !== undefined || type == 'td' || type == 'th' ?
|
||
api.cell( src, col ).data() :
|
||
api.row( src ).data() || null;
|
||
}
|
||
|
||
return api.data().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get an array of the TR nodes that are used in the table's body. Note that you will
|
||
* typically want to use the '$' API method in preference to this as it is more
|
||
* flexible.
|
||
* @param {int} [iRow] Optional row index for the TR element you want
|
||
* @returns {array|node} If iRow is undefined, returns an array of all TR elements
|
||
* in the table's body, or iRow is defined, just the TR element requested.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Get the nodes from the table
|
||
* var nNodes = oTable.fnGetNodes( );
|
||
* } );
|
||
*/
|
||
this.fnGetNodes = function( iRow )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
return iRow !== undefined ?
|
||
api.row( iRow ).node() :
|
||
api.rows().nodes().flatten().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the array indexes of a particular cell from it's DOM element
|
||
* and column index including hidden columns
|
||
* @param {node} node this can either be a TR, TD or TH in the table's body
|
||
* @returns {int} If nNode is given as a TR, then a single index is returned, or
|
||
* if given as a cell, an array of [row index, column index (visible),
|
||
* column index (all)] is given.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* $('#example tbody td').click( function () {
|
||
* // Get the position of the current data from the node
|
||
* var aPos = oTable.fnGetPosition( this );
|
||
*
|
||
* // Get the data array for this row
|
||
* var aData = oTable.fnGetData( aPos[0] );
|
||
*
|
||
* // Update the data array and return the value
|
||
* aData[ aPos[1] ] = 'clicked';
|
||
* this.innerHTML = 'clicked';
|
||
* } );
|
||
*
|
||
* // Init DataTables
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnGetPosition = function( node )
|
||
{
|
||
var api = this.api( true );
|
||
var nodeName = node.nodeName.toUpperCase();
|
||
|
||
if ( nodeName == 'TR' ) {
|
||
return api.row( node ).index();
|
||
}
|
||
else if ( nodeName == 'TD' || nodeName == 'TH' ) {
|
||
var cell = api.cell( node ).index();
|
||
|
||
return [
|
||
cell.row,
|
||
cell.columnVisible,
|
||
cell.column
|
||
];
|
||
}
|
||
return null;
|
||
};
|
||
|
||
|
||
/**
|
||
* Check to see if a row is 'open' or not.
|
||
* @param {node} nTr the table row to check
|
||
* @returns {boolean} true if the row is currently open, false otherwise
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnIsOpen = function( nTr )
|
||
{
|
||
return this.api( true ).row( nTr ).child.isShown();
|
||
};
|
||
|
||
|
||
/**
|
||
* This function will place a new row directly after a row which is currently
|
||
* on display on the page, with the HTML contents that is passed into the
|
||
* function. This can be used, for example, to ask for confirmation that a
|
||
* particular record should be deleted.
|
||
* @param {node} nTr The table row to 'open'
|
||
* @param {string|node|jQuery} mHtml The HTML to put into the row
|
||
* @param {string} sClass Class to give the new TD cell
|
||
* @returns {node} The row opened. Note that if the table row passed in as the
|
||
* first parameter, is not found in the table, this method will silently
|
||
* return.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnOpen = function( nTr, mHtml, sClass )
|
||
{
|
||
return this.api( true )
|
||
.row( nTr )
|
||
.child( mHtml, sClass )
|
||
.show()
|
||
.child()[0];
|
||
};
|
||
|
||
|
||
/**
|
||
* Change the pagination - provides the internal logic for pagination in a simple API
|
||
* function. With this function you can have a DataTables table go to the next,
|
||
* previous, first or last pages.
|
||
* @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
|
||
* or page number to jump to (integer), note that page 0 is the first page.
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnPageChange( 'next' );
|
||
* } );
|
||
*/
|
||
this.fnPageChange = function ( mAction, bRedraw )
|
||
{
|
||
var api = this.api( true ).page( mAction );
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw(false);
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Show a particular column
|
||
* @param {int} iCol The column whose display should be changed
|
||
* @param {bool} bShow Show (true) or hide (false) the column
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Hide the second column after initialisation
|
||
* oTable.fnSetColumnVis( 1, false );
|
||
* } );
|
||
*/
|
||
this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
|
||
{
|
||
var api = this.api( true ).column( iCol ).visible( bShow );
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.columns.adjust().draw();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the settings for a particular table for external manipulation
|
||
* @returns {object} DataTables settings object. See
|
||
* {@link DataTable.models.oSettings}
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* var oSettings = oTable.fnSettings();
|
||
*
|
||
* // Show an example parameter from the settings
|
||
* alert( oSettings._iDisplayStart );
|
||
* } );
|
||
*/
|
||
this.fnSettings = function()
|
||
{
|
||
return _fnSettingsFromNode( this[_ext.iApiIndex] );
|
||
};
|
||
|
||
|
||
/**
|
||
* Sort the table by a particular column
|
||
* @param {int} iCol the data index to sort on. Note that this will not match the
|
||
* 'display index' if you have hidden data entries
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sort immediately with columns 0 and 1
|
||
* oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
|
||
* } );
|
||
*/
|
||
this.fnSort = function( aaSort )
|
||
{
|
||
this.api( true ).order( aaSort ).draw();
|
||
};
|
||
|
||
|
||
/**
|
||
* Attach a sort listener to an element for a given column
|
||
* @param {node} nNode the element to attach the sort listener to
|
||
* @param {int} iColumn the column that a click on this node will sort on
|
||
* @param {function} [fnCallback] callback function when sort is run
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sort on column 1, when 'sorter' is clicked on
|
||
* oTable.fnSortListener( document.getElementById('sorter'), 1 );
|
||
* } );
|
||
*/
|
||
this.fnSortListener = function( nNode, iColumn, fnCallback )
|
||
{
|
||
this.api( true ).order.listener( nNode, iColumn, fnCallback );
|
||
};
|
||
|
||
|
||
/**
|
||
* Update a table cell or row - this method will accept either a single value to
|
||
* update the cell with, an array of values with one element for each column or
|
||
* an object in the same format as the original data source. The function is
|
||
* self-referencing in order to make the multi column updates easier.
|
||
* @param {object|array|string} mData Data to update the cell/row with
|
||
* @param {node|int} mRow TR element you want to update or the aoData index
|
||
* @param {int} [iColumn] The column to update, give as null or undefined to
|
||
* update a whole row.
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @param {bool} [bAction=true] Perform pre-draw actions or not
|
||
* @returns {int} 0 on success, 1 on error
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
|
||
* oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
|
||
* } );
|
||
*/
|
||
this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( iColumn === undefined || iColumn === null ) {
|
||
api.row( mRow ).data( mData );
|
||
}
|
||
else {
|
||
api.cell( mRow, iColumn ).data( mData );
|
||
}
|
||
|
||
if ( bAction === undefined || bAction ) {
|
||
api.columns.adjust();
|
||
}
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw();
|
||
}
|
||
return 0;
|
||
};
|
||
|
||
|
||
/**
|
||
* Provide a common method for plug-ins to check the version of DataTables being used, in order
|
||
* to ensure compatibility.
|
||
* @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
|
||
* formats "X" and "X.Y" are also acceptable.
|
||
* @returns {boolean} true if this version of DataTables is greater or equal to the required
|
||
* version, or false if this version of DataTales is not suitable
|
||
* @method
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* alert( oTable.fnVersionCheck( '1.9.0' ) );
|
||
* } );
|
||
*/
|
||
this.fnVersionCheck = _ext.fnVersionCheck;
|
||
|
||
|
||
var _that = this;
|
||
var emptyInit = options === undefined;
|
||
var len = this.length;
|
||
|
||
if ( emptyInit ) {
|
||
options = {};
|
||
}
|
||
|
||
this.oApi = this.internal = _ext.internal;
|
||
|
||
// Extend with old style plug-in API methods
|
||
for ( var fn in DataTable.ext.internal ) {
|
||
if ( fn ) {
|
||
this[fn] = _fnExternApiFunc(fn);
|
||
}
|
||
}
|
||
|
||
this.each(function() {
|
||
// For each initialisation we want to give it a clean initialisation
|
||
// object that can be bashed around
|
||
var o = {};
|
||
var oInit = len > 1 ? // optimisation for single table case
|
||
_fnExtend( o, options, true ) :
|
||
options;
|
||
|
||
/*global oInit,_that,emptyInit*/
|
||
var i=0, iLen, j, jLen, k, kLen;
|
||
var sId = this.getAttribute( 'id' );
|
||
var bInitHandedOff = false;
|
||
var defaults = DataTable.defaults;
|
||
|
||
|
||
/* Sanity check */
|
||
if ( this.nodeName.toLowerCase() != 'table' )
|
||
{
|
||
_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
|
||
return;
|
||
}
|
||
|
||
/* Backwards compatibility for the defaults */
|
||
_fnCompatOpts( defaults );
|
||
_fnCompatCols( defaults.column );
|
||
|
||
/* Convert the camel-case defaults to Hungarian */
|
||
_fnCamelToHungarian( defaults, defaults, true );
|
||
_fnCamelToHungarian( defaults.column, defaults.column, true );
|
||
|
||
/* Setting up the initialisation object */
|
||
_fnCamelToHungarian( defaults, oInit );
|
||
|
||
/* Check to see if we are re-initialising a table */
|
||
var allSettings = DataTable.settings;
|
||
for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
|
||
{
|
||
/* Base check on table node */
|
||
if ( allSettings[i].nTable == this )
|
||
{
|
||
var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
|
||
var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
|
||
|
||
if ( emptyInit || bRetrieve )
|
||
{
|
||
return allSettings[i].oInstance;
|
||
}
|
||
else if ( bDestroy )
|
||
{
|
||
allSettings[i].oInstance.fnDestroy();
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
_fnLog( allSettings[i], 0, 'Cannot reinitialise DataTable', 3 );
|
||
return;
|
||
}
|
||
}
|
||
|
||
/* If the element we are initialising has the same ID as a table which was previously
|
||
* initialised, but the table nodes don't match (from before) then we destroy the old
|
||
* instance by simply deleting it. This is under the assumption that the table has been
|
||
* destroyed by other methods. Anyone using non-id selectors will need to do this manually
|
||
*/
|
||
if ( allSettings[i].sTableId == this.id )
|
||
{
|
||
allSettings.splice( i, 1 );
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* Ensure the table has an ID - required for accessibility */
|
||
if ( sId === null || sId === "" )
|
||
{
|
||
sId = "DataTables_Table_"+(DataTable.ext._unique++);
|
||
this.id = sId;
|
||
}
|
||
|
||
/* Create the settings object for this table and set some of the default parameters */
|
||
var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
|
||
"nTable": this,
|
||
"oApi": _that.internal,
|
||
"oInit": oInit,
|
||
"sDestroyWidth": $(this)[0].style.width,
|
||
"sInstance": sId,
|
||
"sTableId": sId
|
||
} );
|
||
allSettings.push( oSettings );
|
||
|
||
// Need to add the instance after the instance after the settings object has been added
|
||
// to the settings array, so we can self reference the table instance if more than one
|
||
oSettings.oInstance = (_that.length===1) ? _that : $(this).dataTable();
|
||
|
||
// Backwards compatibility, before we apply all the defaults
|
||
_fnCompatOpts( oInit );
|
||
|
||
if ( oInit.oLanguage )
|
||
{
|
||
_fnLanguageCompat( oInit.oLanguage );
|
||
}
|
||
|
||
// If the length menu is given, but the init display length is not, use the length menu
|
||
if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
|
||
{
|
||
oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
|
||
oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
|
||
}
|
||
|
||
// Apply the defaults and init options to make a single init object will all
|
||
// options defined from defaults and instance options.
|
||
oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
|
||
|
||
|
||
// Map the initialisation options onto the settings object
|
||
_fnMap( oSettings.oFeatures, oInit, [
|
||
"bPaginate",
|
||
"bLengthChange",
|
||
"bFilter",
|
||
"bSort",
|
||
"bSortMulti",
|
||
"bInfo",
|
||
"bProcessing",
|
||
"bAutoWidth",
|
||
"bSortClasses",
|
||
"bServerSide",
|
||
"bDeferRender"
|
||
] );
|
||
_fnMap( oSettings, oInit, [
|
||
"asStripeClasses",
|
||
"ajax",
|
||
"fnServerData",
|
||
"fnFormatNumber",
|
||
"sServerMethod",
|
||
"aaSorting",
|
||
"aaSortingFixed",
|
||
"aLengthMenu",
|
||
"sPaginationType",
|
||
"sAjaxSource",
|
||
"sAjaxDataProp",
|
||
"iStateDuration",
|
||
"sDom",
|
||
"bSortCellsTop",
|
||
"iTabIndex",
|
||
"fnStateLoadCallback",
|
||
"fnStateSaveCallback",
|
||
"renderer",
|
||
[ "iCookieDuration", "iStateDuration" ], // backwards compat
|
||
[ "oSearch", "oPreviousSearch" ],
|
||
[ "aoSearchCols", "aoPreSearchCols" ],
|
||
[ "iDisplayLength", "_iDisplayLength" ],
|
||
[ "bJQueryUI", "bJUI" ]
|
||
] );
|
||
_fnMap( oSettings.oScroll, oInit, [
|
||
[ "sScrollX", "sX" ],
|
||
[ "sScrollXInner", "sXInner" ],
|
||
[ "sScrollY", "sY" ],
|
||
[ "bScrollCollapse", "bCollapse" ]
|
||
] );
|
||
_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
|
||
|
||
/* Callback functions which are array driven */
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
|
||
|
||
var oClasses = oSettings.oClasses;
|
||
|
||
// @todo Remove in 1.11
|
||
if ( oInit.bJQueryUI )
|
||
{
|
||
/* Use the JUI classes object for display. You could clone the oStdClasses object if
|
||
* you want to have multiple tables with multiple independent classes
|
||
*/
|
||
$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
|
||
|
||
if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
|
||
{
|
||
/* Set the DOM to use a layout suitable for jQuery UI's theming */
|
||
oSettings.sDom = '<"H"lfr>t<"F"ip>';
|
||
}
|
||
|
||
if ( ! oSettings.renderer ) {
|
||
oSettings.renderer = 'jqueryui';
|
||
}
|
||
else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
|
||
oSettings.renderer.header = 'jqueryui';
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
|
||
}
|
||
$(this).addClass( oClasses.sTable );
|
||
|
||
/* Calculate the scroll bar width and cache it for use later on */
|
||
if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
|
||
{
|
||
oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
|
||
}
|
||
if ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling
|
||
oSettings.oScroll.sX = '100%';
|
||
}
|
||
|
||
if ( oSettings.iInitDisplayStart === undefined )
|
||
{
|
||
/* Display start point, taking into account the save saving */
|
||
oSettings.iInitDisplayStart = oInit.iDisplayStart;
|
||
oSettings._iDisplayStart = oInit.iDisplayStart;
|
||
}
|
||
|
||
if ( oInit.iDeferLoading !== null )
|
||
{
|
||
oSettings.bDeferLoading = true;
|
||
var tmp = $.isArray( oInit.iDeferLoading );
|
||
oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
|
||
oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
|
||
}
|
||
|
||
/* Language definitions */
|
||
if ( oInit.oLanguage.sUrl !== "" )
|
||
{
|
||
/* Get the language definitions from a file - because this Ajax call makes the language
|
||
* get async to the remainder of this function we use bInitHandedOff to indicate that
|
||
* _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
|
||
*/
|
||
oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;
|
||
$.getJSON( oSettings.oLanguage.sUrl, null, function( json ) {
|
||
_fnLanguageCompat( json );
|
||
_fnCamelToHungarian( defaults.oLanguage, json );
|
||
$.extend( true, oSettings.oLanguage, oInit.oLanguage, json );
|
||
_fnInitialise( oSettings );
|
||
} );
|
||
bInitHandedOff = true;
|
||
}
|
||
else
|
||
{
|
||
$.extend( true, oSettings.oLanguage, oInit.oLanguage );
|
||
}
|
||
|
||
|
||
/*
|
||
* Stripes
|
||
*/
|
||
if ( oInit.asStripeClasses === null )
|
||
{
|
||
oSettings.asStripeClasses =[
|
||
oClasses.sStripeOdd,
|
||
oClasses.sStripeEven
|
||
];
|
||
}
|
||
|
||
/* Remove row stripe classes if they are already on the table row */
|
||
var stripeClasses = oSettings.asStripeClasses;
|
||
var rowOne = $('tbody tr:eq(0)', this);
|
||
if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
|
||
return rowOne.hasClass(el);
|
||
} ) ) !== -1 ) {
|
||
$('tbody tr', this).removeClass( stripeClasses.join(' ') );
|
||
oSettings.asDestroyStripes = stripeClasses.slice();
|
||
}
|
||
|
||
/*
|
||
* Columns
|
||
* See if we should load columns automatically or use defined ones
|
||
*/
|
||
var anThs = [];
|
||
var aoColumnsInit;
|
||
var nThead = this.getElementsByTagName('thead');
|
||
if ( nThead.length !== 0 )
|
||
{
|
||
_fnDetectHeader( oSettings.aoHeader, nThead[0] );
|
||
anThs = _fnGetUniqueThs( oSettings );
|
||
}
|
||
|
||
/* If not given a column array, generate one with nulls */
|
||
if ( oInit.aoColumns === null )
|
||
{
|
||
aoColumnsInit = [];
|
||
for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
|
||
{
|
||
aoColumnsInit.push( null );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
aoColumnsInit = oInit.aoColumns;
|
||
}
|
||
|
||
/* Add the columns */
|
||
for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
|
||
{
|
||
_fnAddColumn( oSettings, anThs ? anThs[i] : null );
|
||
}
|
||
|
||
/* Apply the column definitions */
|
||
_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
|
||
_fnColumnOptions( oSettings, iCol, oDef );
|
||
} );
|
||
|
||
/* HTML5 attribute detection - build an mData object automatically if the
|
||
* attributes are found
|
||
*/
|
||
if ( rowOne.length ) {
|
||
var a = function ( cell, name ) {
|
||
return cell.getAttribute( 'data-'+name ) ? name : null;
|
||
};
|
||
|
||
$.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {
|
||
var col = oSettings.aoColumns[i];
|
||
|
||
if ( col.mData === i ) {
|
||
var sort = a( cell, 'sort' ) || a( cell, 'order' );
|
||
var filter = a( cell, 'filter' ) || a( cell, 'search' );
|
||
|
||
if ( sort !== null || filter !== null ) {
|
||
col.mData = {
|
||
_: i+'.display',
|
||
sort: sort !== null ? i+'.@data-'+sort : undefined,
|
||
type: sort !== null ? i+'.@data-'+sort : undefined,
|
||
filter: filter !== null ? i+'.@data-'+filter : undefined
|
||
};
|
||
|
||
_fnColumnOptions( oSettings, i );
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
|
||
var features = oSettings.oFeatures;
|
||
|
||
/* Must be done after everything which can be overridden by the state saving! */
|
||
if ( oInit.bStateSave )
|
||
{
|
||
features.bStateSave = true;
|
||
_fnLoadState( oSettings, oInit );
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
|
||
}
|
||
|
||
|
||
/*
|
||
* Sorting
|
||
* @todo For modularisation (1.11) this needs to do into a sort start up handler
|
||
*/
|
||
|
||
// If aaSorting is not defined, then we use the first indicator in asSorting
|
||
// in case that has been altered, so the default sort reflects that option
|
||
if ( oInit.aaSorting === undefined )
|
||
{
|
||
var sorting = oSettings.aaSorting;
|
||
for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
|
||
{
|
||
sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
|
||
}
|
||
}
|
||
|
||
/* Do a first pass on the sorting classes (allows any size changes to be taken into
|
||
* account, and also will apply sorting disabled classes if disabled
|
||
*/
|
||
_fnSortingClasses( oSettings );
|
||
|
||
if ( features.bSort )
|
||
{
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
||
if ( oSettings.bSorted ) {
|
||
var aSort = _fnSortFlatten( oSettings );
|
||
var sortedColumns = {};
|
||
|
||
$.each( aSort, function (i, val) {
|
||
sortedColumns[ val.src ] = val.dir;
|
||
} );
|
||
|
||
_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
|
||
_fnSortAria( oSettings );
|
||
}
|
||
} );
|
||
}
|
||
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
||
if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
|
||
_fnSortingClasses( oSettings );
|
||
}
|
||
}, 'sc' );
|
||
|
||
|
||
/*
|
||
* Final init
|
||
* Cache the header, body and footer as required, creating them if needed
|
||
*/
|
||
|
||
/* Browser support detection */
|
||
_fnBrowserDetect( oSettings );
|
||
|
||
// Work around for Webkit bug 83867 - store the caption-side before removing from doc
|
||
var captions = $(this).children('caption').each( function () {
|
||
this._captionSide = $(this).css('caption-side');
|
||
} );
|
||
|
||
var thead = $(this).children('thead');
|
||
if ( thead.length === 0 )
|
||
{
|
||
thead = $('<thead/>').appendTo(this);
|
||
}
|
||
oSettings.nTHead = thead[0];
|
||
|
||
var tbody = $(this).children('tbody');
|
||
if ( tbody.length === 0 )
|
||
{
|
||
tbody = $('<tbody/>').appendTo(this);
|
||
}
|
||
oSettings.nTBody = tbody[0];
|
||
|
||
var tfoot = $(this).children('tfoot');
|
||
if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
|
||
{
|
||
// If we are a scrolling table, and no footer has been given, then we need to create
|
||
// a tfoot element for the caption element to be appended to
|
||
tfoot = $('<tfoot/>').appendTo(this);
|
||
}
|
||
|
||
if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
|
||
$(this).addClass( oClasses.sNoFooter );
|
||
}
|
||
else if ( tfoot.length > 0 ) {
|
||
oSettings.nTFoot = tfoot[0];
|
||
_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
|
||
}
|
||
|
||
/* Check if there is data passing into the constructor */
|
||
if ( oInit.aaData )
|
||
{
|
||
for ( i=0 ; i<oInit.aaData.length ; i++ )
|
||
{
|
||
_fnAddData( oSettings, oInit.aaData[ i ] );
|
||
}
|
||
}
|
||
else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
|
||
{
|
||
/* Grab the data from the page - only do this when deferred loading or no Ajax
|
||
* source since there is no point in reading the DOM data if we are then going
|
||
* to replace it with Ajax data
|
||
*/
|
||
_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
|
||
}
|
||
|
||
/* Copy the data index array */
|
||
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
|
||
|
||
/* Initialisation complete - table can be drawn */
|
||
oSettings.bInitialised = true;
|
||
|
||
/* Check if we need to initialise the table (it might not have been handed off to the
|
||
* language processor)
|
||
*/
|
||
if ( bInitHandedOff === false )
|
||
{
|
||
_fnInitialise( oSettings );
|
||
}
|
||
} );
|
||
_that = null;
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Computed structure of the DataTables API, defined by the options passed to
|
||
* `DataTable.Api.register()` when building the API.
|
||
*
|
||
* The structure is built in order to speed creation and extension of the Api
|
||
* objects since the extensions are effectively pre-parsed.
|
||
*
|
||
* The array is an array of objects with the following structure, where this
|
||
* base array represents the Api prototype base:
|
||
*
|
||
* [
|
||
* {
|
||
* name: 'data' -- string - Property name
|
||
* val: function () {}, -- function - Api method (or undefined if just an object
|
||
* methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
|
||
* propExt: [ ... ] -- array - Array of Api object definitions to extend the property
|
||
* },
|
||
* {
|
||
* name: 'row'
|
||
* val: {},
|
||
* methodExt: [ ... ],
|
||
* propExt: [
|
||
* {
|
||
* name: 'data'
|
||
* val: function () {},
|
||
* methodExt: [ ... ],
|
||
* propExt: [ ... ]
|
||
* },
|
||
* ...
|
||
* ]
|
||
* }
|
||
* ]
|
||
*
|
||
* @type {Array}
|
||
* @ignore
|
||
*/
|
||
var __apiStruct = [];
|
||
|
||
|
||
/**
|
||
* `Array.prototype` reference.
|
||
*
|
||
* @type object
|
||
* @ignore
|
||
*/
|
||
var __arrayProto = Array.prototype;
|
||
|
||
|
||
/**
|
||
* Abstraction for `context` parameter of the `Api` constructor to allow it to
|
||
* take several different forms for ease of use.
|
||
*
|
||
* Each of the input parameter types will be converted to a DataTables settings
|
||
* object where possible.
|
||
*
|
||
* @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
|
||
* of:
|
||
*
|
||
* * `string` - jQuery selector. Any DataTables' matching the given selector
|
||
* with be found and used.
|
||
* * `node` - `TABLE` node which has already been formed into a DataTable.
|
||
* * `jQuery` - A jQuery object of `TABLE` nodes.
|
||
* * `object` - DataTables settings object
|
||
* * `DataTables.Api` - API instance
|
||
* @return {array|null} Matching DataTables settings objects. `null` or
|
||
* `undefined` is returned if no matching DataTable is found.
|
||
* @ignore
|
||
*/
|
||
var _toSettings = function ( mixed )
|
||
{
|
||
var idx, jq;
|
||
var settings = DataTable.settings;
|
||
var tables = $.map( settings, function (el, i) {
|
||
return el.nTable;
|
||
} );
|
||
|
||
if ( ! mixed ) {
|
||
return [];
|
||
}
|
||
else if ( mixed.nTable && mixed.oApi ) {
|
||
// DataTables settings object
|
||
return [ mixed ];
|
||
}
|
||
else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
|
||
// Table node
|
||
idx = $.inArray( mixed, tables );
|
||
return idx !== -1 ? [ settings[idx] ] : null;
|
||
}
|
||
else if ( mixed && typeof mixed.settings === 'function' ) {
|
||
return mixed.settings().toArray();
|
||
}
|
||
else if ( typeof mixed === 'string' ) {
|
||
// jQuery selector
|
||
jq = $(mixed);
|
||
}
|
||
else if ( mixed instanceof $ ) {
|
||
// jQuery object (also DataTables instance)
|
||
jq = mixed;
|
||
}
|
||
|
||
if ( jq ) {
|
||
return jq.map( function(i) {
|
||
idx = $.inArray( this, tables );
|
||
return idx !== -1 ? settings[idx] : null;
|
||
} ).toArray();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* DataTables API class - used to control and interface with one or more
|
||
* DataTables enhanced tables.
|
||
*
|
||
* The API class is heavily based on jQuery, presenting a chainable interface
|
||
* that you can use to interact with tables. Each instance of the API class has
|
||
* a "context" - i.e. the tables that it will operate on. This could be a single
|
||
* table, all tables on a page or a sub-set thereof.
|
||
*
|
||
* Additionally the API is designed to allow you to easily work with the data in
|
||
* the tables, retrieving and manipulating it as required. This is done by
|
||
* presenting the API class as an array like interface. The contents of the
|
||
* array depend upon the actions requested by each method (for example
|
||
* `rows().nodes()` will return an array of nodes, while `rows().data()` will
|
||
* return an array of objects or arrays depending upon your table's
|
||
* configuration). The API object has a number of array like methods (`push`,
|
||
* `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
|
||
* `unique` etc) to assist your working with the data held in a table.
|
||
*
|
||
* Most methods (those which return an Api instance) are chainable, which means
|
||
* the return from a method call also has all of the methods available that the
|
||
* top level object had. For example, these two calls are equivalent:
|
||
*
|
||
* // Not chained
|
||
* api.row.add( {...} );
|
||
* api.draw();
|
||
*
|
||
* // Chained
|
||
* api.row.add( {...} ).draw();
|
||
*
|
||
* @class DataTable.Api
|
||
* @param {array|object|string|jQuery} context DataTable identifier. This is
|
||
* used to define which DataTables enhanced tables this API will operate on.
|
||
* Can be one of:
|
||
*
|
||
* * `string` - jQuery selector. Any DataTables' matching the given selector
|
||
* with be found and used.
|
||
* * `node` - `TABLE` node which has already been formed into a DataTable.
|
||
* * `jQuery` - A jQuery object of `TABLE` nodes.
|
||
* * `object` - DataTables settings object
|
||
* @param {array} [data] Data to initialise the Api instance with.
|
||
*
|
||
* @example
|
||
* // Direct initialisation during DataTables construction
|
||
* var api = $('#example').DataTable();
|
||
*
|
||
* @example
|
||
* // Initialisation using a DataTables jQuery object
|
||
* var api = $('#example').dataTable().api();
|
||
*
|
||
* @example
|
||
* // Initialisation as a constructor
|
||
* var api = new $.fn.DataTable.Api( 'table.dataTable' );
|
||
*/
|
||
DataTable.Api = _Api = function ( context, data )
|
||
{
|
||
if ( ! this instanceof _Api ) {
|
||
throw 'DT API must be constructed as a new object';
|
||
// or should it do the 'new' for the caller?
|
||
// return new _Api.apply( this, arguments );
|
||
}
|
||
|
||
var settings = [];
|
||
var ctxSettings = function ( o ) {
|
||
var a = _toSettings( o );
|
||
if ( a ) {
|
||
settings.push.apply( settings, a );
|
||
}
|
||
};
|
||
|
||
if ( $.isArray( context ) ) {
|
||
for ( var i=0, ien=context.length ; i<ien ; i++ ) {
|
||
ctxSettings( context[i] );
|
||
}
|
||
}
|
||
else {
|
||
ctxSettings( context );
|
||
}
|
||
|
||
// Remove duplicates
|
||
this.context = _unique( settings );
|
||
|
||
// Initial data
|
||
if ( data ) {
|
||
this.push.apply( this, data.toArray ? data.toArray() : data );
|
||
}
|
||
|
||
// selector
|
||
this.selector = {
|
||
rows: null,
|
||
cols: null,
|
||
opts: null
|
||
};
|
||
|
||
_Api.extend( this, this, __apiStruct );
|
||
};
|
||
|
||
|
||
_Api.prototype = /** @lends DataTables.Api */{
|
||
/**
|
||
* Return a new Api instance, comprised of the data held in the current
|
||
* instance, join with the other array(s) and/or value(s).
|
||
*
|
||
* An alias for `Array.prototype.concat`.
|
||
*
|
||
* @type method
|
||
* @param {*} value1 Arrays and/or values to concatenate.
|
||
* @param {*} [...] Additional arrays and/or values to concatenate.
|
||
* @returns {DataTables.Api} New API instance, comprising of the combined
|
||
* array.
|
||
*/
|
||
concat: __arrayProto.concat,
|
||
|
||
|
||
context: [], // array of table settings objects
|
||
|
||
|
||
each: function ( fn )
|
||
{
|
||
if ( __arrayProto.forEach ) {
|
||
// Where possible, use the built-in forEach
|
||
__arrayProto.forEach.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien; i++ ) {
|
||
// In strict mode the execution scope is the passed value
|
||
fn.call( this, this[i], i, this );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
|
||
eq: function ( idx )
|
||
{
|
||
var ctx = this.context;
|
||
|
||
return ctx.length > idx ?
|
||
new _Api( ctx[idx], this[idx] ) :
|
||
null;
|
||
},
|
||
|
||
|
||
filter: function ( fn )
|
||
{
|
||
var a = [];
|
||
|
||
if ( __arrayProto.filter ) {
|
||
a = __arrayProto.filter.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
|
||
if ( fn.call( this, this[i], i, this ) ) {
|
||
a.push( this[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return new _Api( this.context, a );
|
||
},
|
||
|
||
|
||
flatten: function ()
|
||
{
|
||
var a = [];
|
||
return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
|
||
},
|
||
|
||
|
||
join: __arrayProto.join,
|
||
|
||
|
||
indexOf: __arrayProto.indexOf || function (obj, start)
|
||
{
|
||
for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
|
||
if ( this[i] === obj ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
// Internal only at the moment - relax?
|
||
iterator: function ( flatten, type, fn ) {
|
||
var
|
||
a = [], ret,
|
||
i, ien, j, jen,
|
||
context = this.context,
|
||
rows, items, item,
|
||
selector = this.selector;
|
||
|
||
// Argument shifting
|
||
if ( typeof flatten === 'string' ) {
|
||
fn = type;
|
||
type = flatten;
|
||
flatten = false;
|
||
}
|
||
|
||
for ( i=0, ien=context.length ; i<ien ; i++ ) {
|
||
if ( type === 'table' ) {
|
||
ret = fn( context[i], i );
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
else if ( type === 'columns' || type === 'rows' ) {
|
||
// this has same length as context - one entry for each table
|
||
ret = fn( context[i], this[i], i );
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
|
||
// columns and rows share the same structure.
|
||
// 'this' is an array of column indexes for each context
|
||
items = this[i];
|
||
|
||
if ( type === 'column-rows' ) {
|
||
rows = _selector_row_indexes( context[i], selector.opts );
|
||
}
|
||
|
||
for ( j=0, jen=items.length ; j<jen ; j++ ) {
|
||
item = items[j];
|
||
|
||
if ( type === 'cell' ) {
|
||
ret = fn( context[i], item.row, item.column, i, j );
|
||
}
|
||
else {
|
||
ret = fn( context[i], item, i, j, rows );
|
||
}
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( a.length ) {
|
||
var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
|
||
var apiSelector = api.selector;
|
||
apiSelector.rows = selector.rows;
|
||
apiSelector.cols = selector.cols;
|
||
apiSelector.opts = selector.opts;
|
||
return api;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
|
||
lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
|
||
{
|
||
// Bit cheeky...
|
||
return this.indexOf.apply( this.toArray.reverse(), arguments );
|
||
},
|
||
|
||
|
||
length: 0,
|
||
|
||
|
||
map: function ( fn )
|
||
{
|
||
var a = [];
|
||
|
||
if ( __arrayProto.map ) {
|
||
a = __arrayProto.map.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
|
||
a.push( fn.call( this, this[i], i ) );
|
||
}
|
||
}
|
||
|
||
return new _Api( this.context, a );
|
||
},
|
||
|
||
|
||
pluck: function ( prop )
|
||
{
|
||
return this.map( function ( el ) {
|
||
return el[ prop ];
|
||
} );
|
||
},
|
||
|
||
pop: __arrayProto.pop,
|
||
|
||
|
||
push: __arrayProto.push,
|
||
|
||
|
||
// Does not return an API instance
|
||
reduce: __arrayProto.reduce || function ( fn, init )
|
||
{
|
||
return _fnReduce( this, fn, init, 0, this.length, 1 );
|
||
},
|
||
|
||
|
||
reduceRight: __arrayProto.reduceRight || function ( fn, init )
|
||
{
|
||
return _fnReduce( this, fn, init, this.length-1, -1, -1 );
|
||
},
|
||
|
||
|
||
reverse: __arrayProto.reverse,
|
||
|
||
|
||
// Object with rows, columns and opts
|
||
selector: null,
|
||
|
||
|
||
shift: __arrayProto.shift,
|
||
|
||
|
||
sort: __arrayProto.sort, // ? name - order?
|
||
|
||
|
||
splice: __arrayProto.splice,
|
||
|
||
|
||
toArray: function ()
|
||
{
|
||
return __arrayProto.slice.call( this );
|
||
},
|
||
|
||
|
||
to$: function ()
|
||
{
|
||
return $( this );
|
||
},
|
||
|
||
|
||
toJQuery: function ()
|
||
{
|
||
return $( this );
|
||
},
|
||
|
||
|
||
unique: function ()
|
||
{
|
||
return new _Api( this.context, _unique(this) );
|
||
},
|
||
|
||
|
||
unshift: __arrayProto.unshift
|
||
};
|
||
|
||
|
||
_Api.extend = function ( scope, obj, ext )
|
||
{
|
||
// Only extend API instances and static properties of the API
|
||
if ( ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
|
||
return;
|
||
}
|
||
|
||
var
|
||
i, ien,
|
||
j, jen,
|
||
struct, inner,
|
||
methodScoping = function ( fn, struc ) {
|
||
return function () {
|
||
var ret = fn.apply( scope, arguments );
|
||
|
||
// Method extension
|
||
_Api.extend( ret, ret, struc.methodExt );
|
||
return ret;
|
||
};
|
||
};
|
||
|
||
for ( i=0, ien=ext.length ; i<ien ; i++ ) {
|
||
struct = ext[i];
|
||
|
||
// Value
|
||
obj[ struct.name ] = typeof struct.val === 'function' ?
|
||
methodScoping( struct.val, struct ) :
|
||
$.isPlainObject( struct.val ) ?
|
||
{} :
|
||
struct.val;
|
||
|
||
obj[ struct.name ].__dt_wrapper = true;
|
||
|
||
// Property extension
|
||
_Api.extend( scope, obj[ struct.name ], struct.propExt );
|
||
}
|
||
};
|
||
|
||
|
||
// @todo - Is there need for an augment function?
|
||
// _Api.augment = function ( inst, name )
|
||
// {
|
||
// // Find src object in the structure from the name
|
||
// var parts = name.split('.');
|
||
|
||
// _Api.extend( inst, obj );
|
||
// };
|
||
|
||
|
||
// [
|
||
// {
|
||
// name: 'data' -- string - Property name
|
||
// val: function () {}, -- function - Api method (or undefined if just an object
|
||
// methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
|
||
// propExt: [ ... ] -- array - Array of Api object definitions to extend the property
|
||
// },
|
||
// {
|
||
// name: 'row'
|
||
// val: {},
|
||
// methodExt: [ ... ],
|
||
// propExt: [
|
||
// {
|
||
// name: 'data'
|
||
// val: function () {},
|
||
// methodExt: [ ... ],
|
||
// propExt: [ ... ]
|
||
// },
|
||
// ...
|
||
// ]
|
||
// }
|
||
// ]
|
||
|
||
_Api.register = _api_register = function ( name, val )
|
||
{
|
||
if ( $.isArray( name ) ) {
|
||
for ( var j=0, jen=name.length ; j<jen ; j++ ) {
|
||
_Api.register( name[j], val );
|
||
}
|
||
return;
|
||
}
|
||
|
||
var
|
||
i, ien,
|
||
heir = name.split('.'),
|
||
struct = __apiStruct,
|
||
key, method;
|
||
|
||
var find = function ( src, name ) {
|
||
for ( var i=0, ien=src.length ; i<ien ; i++ ) {
|
||
if ( src[i].name === name ) {
|
||
return src[i];
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
for ( i=0, ien=heir.length ; i<ien ; i++ ) {
|
||
method = heir[i].indexOf('()') !== -1;
|
||
key = method ?
|
||
heir[i].replace('()', '') :
|
||
heir[i];
|
||
|
||
var src = find( struct, key );
|
||
if ( ! src ) {
|
||
src = {
|
||
name: key,
|
||
val: {},
|
||
methodExt: [],
|
||
propExt: []
|
||
};
|
||
struct.push( src );
|
||
}
|
||
|
||
if ( i === ien-1 ) {
|
||
src.val = val;
|
||
}
|
||
else {
|
||
struct = method ?
|
||
src.methodExt :
|
||
src.propExt;
|
||
}
|
||
}
|
||
|
||
// Rebuild the API with the new construct
|
||
if ( _Api.ready ) {
|
||
DataTable.api.build();
|
||
}
|
||
};
|
||
|
||
|
||
_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
|
||
_Api.register( pluralName, val );
|
||
|
||
_Api.register( singularName, function () {
|
||
var ret = val.apply( this, arguments );
|
||
|
||
if ( ret === this ) {
|
||
// Returned item is the API instance that was passed in, return it
|
||
return this;
|
||
}
|
||
else if ( ret instanceof _Api ) {
|
||
// New API instance returned, want the value from the first item
|
||
// in the returned array for the singular result.
|
||
return ret.length ?
|
||
$.isArray( ret[0] ) ?
|
||
new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
|
||
ret[0] :
|
||
undefined;
|
||
}
|
||
|
||
// Non-API return - just fire it back
|
||
return ret;
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
* Selector for HTML tables. Apply the given selector to the give array of
|
||
* DataTables settings objects.
|
||
*
|
||
* @param {string|integer} [selector] jQuery selector string or integer
|
||
* @param {array} Array of DataTables settings objects to be filtered
|
||
* @return {array}
|
||
* @ignore
|
||
*/
|
||
var __table_selector = function ( selector, a )
|
||
{
|
||
// Integer is used to pick out a table by index
|
||
if ( typeof selector === 'number' ) {
|
||
return [ a[ selector ] ];
|
||
}
|
||
|
||
// Perform a jQuery selector on the table nodes
|
||
var nodes = $.map( a, function (el, i) {
|
||
return el.nTable;
|
||
} );
|
||
|
||
return $(nodes)
|
||
.filter( selector )
|
||
.map( function (i) {
|
||
// Need to translate back from the table node to the settings
|
||
var idx = $.inArray( this, nodes );
|
||
return a[ idx ];
|
||
} )
|
||
.toArray();
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Context selector for the API's context (i.e. the tables the API instance
|
||
* refers to.
|
||
*
|
||
* @name DataTable.Api#tables
|
||
* @param {string|integer} [selector] Selector to pick which tables the iterator
|
||
* should operate on. If not given, all tables in the current context are
|
||
* used. This can be given as a jQuery selector (for example `':gt(0)'`) to
|
||
* select multiple tables or as an integer to select a single table.
|
||
* @returns {DataTable.Api} Returns a new API instance if a selector is given.
|
||
*/
|
||
_api_register( 'tables()', function ( selector ) {
|
||
// A new instance is created if there was a selector specified
|
||
return selector ?
|
||
new _Api( __table_selector( selector, this.context ) ) :
|
||
this;
|
||
} );
|
||
|
||
|
||
_api_register( 'table()', function ( selector ) {
|
||
var tables = this.tables( selector );
|
||
var ctx = tables.context;
|
||
|
||
// Truncate to the first matched table
|
||
return ctx.length ?
|
||
new _Api( ctx[0] ) :
|
||
tables;
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTable;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().body()', 'table().body()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTBody;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().header()', 'table().header()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTHead;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTFoot;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Redraw the tables in the current context.
|
||
*
|
||
* @param {boolean} [reset=true] Reset (default) or hold the current paging
|
||
* position. A full re-sort and re-filter is performed when this method is
|
||
* called, which is why the pagination reset is the default action.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'draw()', function ( resetPaging ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnReDraw( settings, resetPaging===false );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Get the current page index.
|
||
*
|
||
* @return {integer} Current page index (zero based)
|
||
*//**
|
||
* Set the current page.
|
||
*
|
||
* Note that if you attempt to show a page which does not exist, DataTables will
|
||
* not throw an error, but rather reset the paging.
|
||
*
|
||
* @param {integer|string} action The paging action to take. This can be one of:
|
||
* * `integer` - The page index to jump to
|
||
* * `string` - An action to take:
|
||
* * `first` - Jump to first page.
|
||
* * `next` - Jump to the next page
|
||
* * `previous` - Jump to previous page
|
||
* * `last` - Jump to the last page.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'page()', function ( action ) {
|
||
if ( action === undefined ) {
|
||
return this.page.info().page; // not an expensive call
|
||
}
|
||
|
||
// else, have an action to take on all tables
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnPageChange( settings, action );
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Paging information for the first table in the current context.
|
||
*
|
||
* If you require paging information for another table, use the `table()` method
|
||
* with a suitable selector.
|
||
*
|
||
* @return {object} Object with the following properties set:
|
||
* * `page` - Current page index (zero based - i.e. the first page is `0`)
|
||
* * `pages` - Total number of pages
|
||
* * `start` - Display index for the first record shown on the current page
|
||
* * `end` - Display index for the last record shown on the current page
|
||
* * `length` - Display length (number of records). Note that generally `start
|
||
* + length = end`, but this is not always true, for example if there are
|
||
* only 2 records to show on the final page, with a length of 10.
|
||
* * `recordsTotal` - Full data set length
|
||
* * `recordsDisplay` - Data set length once the current filtering criterion
|
||
* are applied.
|
||
*/
|
||
_api_register( 'page.info()', function ( action ) {
|
||
if ( this.context.length === 0 ) {
|
||
return undefined;
|
||
}
|
||
|
||
var
|
||
settings = this.context[0],
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
visRecords = settings.fnRecordsDisplay(),
|
||
all = len === -1;
|
||
|
||
return {
|
||
"page": all ? 0 : Math.floor( start / len ),
|
||
"pages": all ? 1 : Math.ceil( visRecords / len ),
|
||
"start": start,
|
||
"end": settings.fnDisplayEnd(),
|
||
"length": len,
|
||
"recordsTotal": settings.fnRecordsTotal(),
|
||
"recordsDisplay": visRecords
|
||
};
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the current page length.
|
||
*
|
||
* @return {integer} Current page length. Note `-1` indicates that all records
|
||
* are to be shown.
|
||
*//**
|
||
* Set the current page length.
|
||
*
|
||
* @param {integer} Page length to set. Use `-1` to show all records.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'page.len()', function ( len ) {
|
||
// Note that we can't call this function 'length()' because `length`
|
||
// is a Javascript property of functions which defines how many arguments
|
||
// the function expects.
|
||
if ( len === undefined ) {
|
||
return this.context.length !== 0 ?
|
||
this.context[0]._iDisplayLength :
|
||
undefined;
|
||
}
|
||
|
||
// else, set the page length
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnLengthChange( settings, len );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
var __reload = function ( settings, holdPosition, callback ) {
|
||
if ( _fnDataSource( settings ) == 'ssp' ) {
|
||
_fnReDraw( settings, holdPosition );
|
||
}
|
||
else {
|
||
// Trigger xhr
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
_fnBuildAjax( settings, [], function( json ) {
|
||
_fnClearTable( settings );
|
||
|
||
var data = _fnAjaxDataSrc( settings, json );
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
_fnAddData( settings, data[i] );
|
||
}
|
||
|
||
_fnReDraw( settings, holdPosition );
|
||
_fnProcessingDisplay( settings, false );
|
||
} );
|
||
}
|
||
|
||
// Use the draw event to trigger a callback, regardless of if it is an async
|
||
// or sync draw
|
||
if ( callback ) {
|
||
var api = new _Api( settings );
|
||
|
||
api.one( 'draw', function () {
|
||
callback( api.ajax.json() );
|
||
} );
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the JSON response from the last Ajax request that DataTables made to the
|
||
* server. Note that this returns the JSON from the first table in the current
|
||
* context.
|
||
*
|
||
* @return {object} JSON received from the server.
|
||
*/
|
||
_api_register( 'ajax.json()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length > 0 ) {
|
||
return ctx[0].json;
|
||
}
|
||
|
||
// else return undefined;
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the data submitted in the last Ajax request
|
||
*/
|
||
_api_register( 'ajax.params()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length > 0 ) {
|
||
return ctx[0].oAjaxData;
|
||
}
|
||
|
||
// else return undefined;
|
||
} );
|
||
|
||
|
||
/**
|
||
* Reload tables from the Ajax data source. Note that this function will
|
||
* automatically re-draw the table when the remote data has been loaded.
|
||
*
|
||
* @param {boolean} [reset=true] Reset (default) or hold the current paging
|
||
* position. A full re-sort and re-filter is performed when this method is
|
||
* called, which is why the pagination reset is the default action.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
|
||
return this.iterator( 'table', function (settings) {
|
||
__reload( settings, resetPaging===false, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the current Ajax URL. Note that this returns the URL from the first
|
||
* table in the current context.
|
||
*
|
||
* @return {string} Current Ajax source URL
|
||
*//**
|
||
* Set the Ajax URL. Note that this will set the URL for all tables in the
|
||
* current context.
|
||
*
|
||
* @param {string} url URL to set.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.url()', function ( url ) {
|
||
var ctx = this.context;
|
||
|
||
if ( url === undefined ) {
|
||
// get
|
||
if ( ctx.length === 0 ) {
|
||
return undefined;
|
||
}
|
||
ctx = ctx[0];
|
||
|
||
return ctx.ajax ?
|
||
$.isPlainObject( ctx.ajax ) ?
|
||
ctx.ajax.url :
|
||
ctx.ajax :
|
||
ctx.sAjaxSource;
|
||
}
|
||
|
||
// set
|
||
return this.iterator( 'table', function ( settings ) {
|
||
if ( $.isPlainObject( settings.ajax ) ) {
|
||
settings.ajax.url = url;
|
||
}
|
||
else {
|
||
settings.ajax = url;
|
||
}
|
||
// No need to consider sAjaxSource here since DataTables gives priority
|
||
// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
|
||
// value of `sAjaxSource` redundant.
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Load data from the newly set Ajax URL. Note that this method is only
|
||
* available when `ajax.url()` is used to set a URL. Additionally, this method
|
||
* has the same effect as calling `ajax.reload()` but is provided for
|
||
* convenience when setting a new URL. Like `ajax.reload()` it will
|
||
* automatically redraw the table once the remote data has been loaded.
|
||
*
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
|
||
// Same as a reload, but makes sense to present it for easy access after a
|
||
// url change
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
__reload( ctx, resetPaging===false, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
|
||
var _selector_run = function ( selector, select )
|
||
{
|
||
var
|
||
out = [], res,
|
||
a, i, ien, j, jen;
|
||
|
||
// Can't just check for isArray here, as an API or jQuery instance might be
|
||
// given with their array like look
|
||
if ( ! selector || typeof selector === 'string' || selector.length === undefined ) {
|
||
selector = [ selector ];
|
||
}
|
||
|
||
for ( i=0, ien=selector.length ; i<ien ; i++ ) {
|
||
a = selector[i] && selector[i].split ?
|
||
selector[i].split(',') :
|
||
[ selector[i] ];
|
||
|
||
for ( j=0, jen=a.length ; j<jen ; j++ ) {
|
||
res = select( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
|
||
|
||
if ( res && res.length ) {
|
||
out.push.apply( out, res );
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _selector_opts = function ( opts )
|
||
{
|
||
if ( ! opts ) {
|
||
opts = {};
|
||
}
|
||
|
||
// Backwards compatibility for 1.9- which used the terminology filter rather
|
||
// than search
|
||
if ( opts.filter && ! opts.search ) {
|
||
opts.search = opts.filter;
|
||
}
|
||
|
||
return {
|
||
search: opts.search || 'none',
|
||
order: opts.order || 'current',
|
||
page: opts.page || 'all'
|
||
};
|
||
};
|
||
|
||
|
||
var _selector_first = function ( inst )
|
||
{
|
||
// Reduce the API instance to the first item found
|
||
for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
|
||
if ( inst[i].length > 0 ) {
|
||
// Assign the first element to the first item in the instance
|
||
// and truncate the instance and context
|
||
inst[0] = inst[i];
|
||
inst.length = 1;
|
||
inst.context = [ inst.context[i] ];
|
||
|
||
return inst;
|
||
}
|
||
}
|
||
|
||
// Not found - return an empty instance
|
||
inst.length = 0;
|
||
return inst;
|
||
};
|
||
|
||
|
||
var _selector_row_indexes = function ( settings, opts )
|
||
{
|
||
var
|
||
i, ien, tmp, a=[],
|
||
displayFiltered = settings.aiDisplay,
|
||
displayMaster = settings.aiDisplayMaster;
|
||
|
||
var
|
||
search = opts.search, // none, applied, removed
|
||
order = opts.order, // applied, current, index (original - compatibility with 1.9)
|
||
page = opts.page; // all, current
|
||
|
||
if ( _fnDataSource( settings ) == 'ssp' ) {
|
||
// In server-side processing mode, most options are irrelevant since
|
||
// rows not shown don't exist and the index order is the applied order
|
||
// Removed is a special case - for consistency just return an empty
|
||
// array
|
||
return search === 'removed' ?
|
||
[] :
|
||
_range( 0, displayMaster.length );
|
||
}
|
||
else if ( page == 'current' ) {
|
||
// Current page implies that order=current and fitler=applied, since it is
|
||
// fairly senseless otherwise, regardless of what order and search actually
|
||
// are
|
||
for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
|
||
a.push( displayFiltered[i] );
|
||
}
|
||
}
|
||
else if ( order == 'current' || order == 'applied' ) {
|
||
a = search == 'none' ?
|
||
displayMaster.slice() : // no search
|
||
search == 'applied' ?
|
||
displayFiltered.slice() : // applied search
|
||
$.map( displayMaster, function (el, i) { // removed search
|
||
return $.inArray( el, displayFiltered ) === -1 ? el : null;
|
||
} );
|
||
}
|
||
else if ( order == 'index' || order == 'original' ) {
|
||
for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
if ( search == 'none' ) {
|
||
a.push( i );
|
||
}
|
||
else { // applied | removed
|
||
tmp = $.inArray( i, displayFiltered );
|
||
|
||
if ((tmp === -1 && search == 'removed') ||
|
||
(tmp === 1 && search == 'applied') )
|
||
{
|
||
a.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return a;
|
||
};
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Rows
|
||
*
|
||
* {} - no selector - use all available rows
|
||
* {integer} - row aoData index
|
||
* {node} - TR node
|
||
* {string} - jQuery selector to apply to the TR elements
|
||
* {array} - jQuery array of nodes, or simply an array of TR nodes
|
||
*
|
||
*/
|
||
|
||
|
||
var __row_selector = function ( settings, selector, opts )
|
||
{
|
||
return _selector_run( selector, function ( sel ) {
|
||
var selInt = _intVal( sel );
|
||
|
||
// Short cut - selector is a number and no options provided (default is
|
||
// all records, so no need to check if the index is in there, since it
|
||
// must be - dev error if the index doesn't exist).
|
||
if ( selInt !== null && ! opts ) {
|
||
return [ selInt ];
|
||
}
|
||
|
||
var rows = _selector_row_indexes( settings, opts );
|
||
|
||
if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
|
||
// Selector - integer
|
||
return [ selInt ];
|
||
}
|
||
else if ( ! sel ) {
|
||
// Selector - none
|
||
return rows;
|
||
}
|
||
|
||
// Get nodes in the order from the `rows` array (can't use `pluck`) @todo - use pluck_order
|
||
var nodes = [];
|
||
for ( var i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
nodes.push( settings.aoData[ rows[i] ].nTr );
|
||
}
|
||
|
||
if ( sel.nodeName ) {
|
||
// Selector - node
|
||
if ( $.inArray( sel, nodes ) !== -1 ) {
|
||
return [ sel._DT_RowIndex ];// sel is a TR node that is in the table
|
||
// and DataTables adds a prop for fast lookup
|
||
}
|
||
}
|
||
|
||
// Selector - jQuery selector string, array of nodes or jQuery object/
|
||
// As jQuery's .filter() allows jQuery objects to be passed in filter,
|
||
// it also allows arrays, so this will cope with all three options
|
||
return $(nodes)
|
||
.filter( sel )
|
||
.map( function () {
|
||
return this._DT_RowIndex;
|
||
} )
|
||
.toArray();
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'rows()', function ( selector, opts ) {
|
||
// argument shifting
|
||
if ( selector === undefined ) {
|
||
selector = '';
|
||
}
|
||
else if ( $.isPlainObject( selector ) ) {
|
||
opts = selector;
|
||
selector = '';
|
||
}
|
||
|
||
opts = _selector_opts( opts );
|
||
|
||
var inst = this.iterator( 'table', function ( settings ) {
|
||
return __row_selector( settings, selector, opts );
|
||
} );
|
||
|
||
// Want argument shifting here and in __row_selector?
|
||
inst.selector.rows = selector;
|
||
inst.selector.opts = opts;
|
||
|
||
return inst;
|
||
} );
|
||
|
||
|
||
_api_register( 'rows().nodes()', function () {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
return settings.aoData[ row ].nTr || undefined;
|
||
} );
|
||
} );
|
||
|
||
_api_register( 'rows().data()', function () {
|
||
return this.iterator( true, 'rows', function ( settings, rows ) {
|
||
return _pluck_order( settings.aoData, rows, '_aData' );
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
var r = settings.aoData[ row ];
|
||
return type === 'search' ? r._aFilterData : r._aSortData;
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
_fnInvalidateRow( settings, row, src );
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
return row;
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
|
||
var that = this;
|
||
|
||
return this.iterator( 'row', function ( settings, row, thatIdx ) {
|
||
var data = settings.aoData;
|
||
|
||
data.splice( row, 1 );
|
||
|
||
// Update the _DT_RowIndex parameter on all rows in the table
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
if ( data[i].nTr !== null ) {
|
||
data[i].nTr._DT_RowIndex = i;
|
||
}
|
||
}
|
||
|
||
// Remove the target row from the search array
|
||
var displayIndex = $.inArray( row, settings.aiDisplay );
|
||
|
||
// Delete from the display arrays
|
||
_fnDeleteIndex( settings.aiDisplayMaster, row );
|
||
_fnDeleteIndex( settings.aiDisplay, row );
|
||
_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
|
||
|
||
// Check for an 'overflow' they case for displaying the table
|
||
_fnLengthOverflow( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'rows.add()', function ( rows ) {
|
||
var newRows = this.iterator( 'table', function ( settings ) {
|
||
var row, i, ien;
|
||
var out = [];
|
||
|
||
for ( i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
row = rows[i];
|
||
|
||
if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
|
||
out.push( _fnAddTr( settings, row )[0] );
|
||
}
|
||
else {
|
||
out.push( _fnAddData( settings, row ) );
|
||
}
|
||
}
|
||
|
||
return out;
|
||
} );
|
||
|
||
// Return an Api.rows() extended instance, so rows().nodes() etc can be used
|
||
var modRows = this.rows( -1 );
|
||
modRows.pop();
|
||
modRows.push.apply( modRows, newRows.toArray() );
|
||
|
||
return modRows;
|
||
} );
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'row()', function ( selector, opts ) {
|
||
return _selector_first( this.rows( selector, opts ) );
|
||
} );
|
||
|
||
|
||
_api_register( 'row().data()', function ( data ) {
|
||
var ctx = this.context;
|
||
|
||
if ( data === undefined ) {
|
||
// Get
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ]._aData :
|
||
undefined;
|
||
}
|
||
|
||
// Set
|
||
ctx[0].aoData[ this[0] ]._aData = data;
|
||
|
||
// Automatically invalidate
|
||
_fnInvalidateRow( ctx[0], this[0], 'data' );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
_api_register( 'row().node()', function () {
|
||
var ctx = this.context;
|
||
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ].nTr || null :
|
||
null;
|
||
} );
|
||
|
||
|
||
_api_register( 'row.add()', function ( row ) {
|
||
// Allow a jQuery object to be passed in - only a single row is added from
|
||
// it though - the first element in the set
|
||
if ( row instanceof $ && row.length ) {
|
||
row = row[0];
|
||
}
|
||
|
||
var rows = this.iterator( 'table', function ( settings ) {
|
||
if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
|
||
return _fnAddTr( settings, row )[0];
|
||
}
|
||
return _fnAddData( settings, row );
|
||
} );
|
||
|
||
// Return an Api.rows() extended instance, with the newly added row selected
|
||
return this.row( rows[0] );
|
||
} );
|
||
|
||
|
||
|
||
var __details_add = function ( ctx, row, data, klass )
|
||
{
|
||
// Convert to array of TR elements
|
||
var rows = [];
|
||
var addRow = function ( r, k ) {
|
||
// If we get a TR element, then just add it directly - up to the dev
|
||
// to add the correct number of columns etc
|
||
if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
|
||
rows.push( r );
|
||
}
|
||
else {
|
||
// Otherwise create a row with a wrapper
|
||
var created = $('<tr><td/></tr>');
|
||
$('td', created)
|
||
.addClass( k )
|
||
.html( r )
|
||
[0].colSpan = _fnVisbleColumns( ctx );
|
||
|
||
rows.push( created[0] );
|
||
}
|
||
};
|
||
|
||
if ( $.isArray( data ) || data instanceof $ ) {
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
addRow( data[i], klass );
|
||
}
|
||
}
|
||
else {
|
||
addRow( data, klass );
|
||
}
|
||
|
||
if ( row._details ) {
|
||
row._details.remove();
|
||
}
|
||
|
||
row._details = $(rows);
|
||
|
||
// If the children were already shown, that state should be retained
|
||
if ( row._detailsShow ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
};
|
||
|
||
|
||
var __details_display = function ( show ) {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length && this.length ) {
|
||
var row = ctx[0].aoData[ this[0] ];
|
||
|
||
if ( row._details ) {
|
||
row._detailsShow = show;
|
||
if ( show ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
else {
|
||
row._details.remove();
|
||
}
|
||
|
||
__details_events( ctx[0] );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
var __details_events = function ( settings )
|
||
{
|
||
var api = new _Api( settings );
|
||
var namespace = '.dt.DT_details';
|
||
var drawEvent = 'draw'+namespace;
|
||
var colvisEvent = 'column-visibility'+namespace;
|
||
|
||
api.off( drawEvent +' '+ colvisEvent );
|
||
|
||
if ( _pluck( settings.aoData, '_details' ).length > 0 ) {
|
||
// On each draw, insert the required elements into the document
|
||
api.on( drawEvent, function () {
|
||
api.rows( {page:'current'} ).eq(0).each( function (idx) {
|
||
// Internal data grab
|
||
var row = settings.aoData[ idx ];
|
||
|
||
if ( row._detailsShow ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
} );
|
||
} );
|
||
|
||
// Column visibility change - update the colspan
|
||
api.on( colvisEvent, function ( e, settings, idx, vis ) {
|
||
// Update the colspan for the details rows (note, only if it already has
|
||
// a colspan)
|
||
var row, visible = _fnVisbleColumns( settings );
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( row._details ) {
|
||
row._details.children('td[colspan]').attr('colspan', visible );
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
};
|
||
|
||
// data can be:
|
||
// tr
|
||
// string
|
||
// jQuery or array of any of the above
|
||
_api_register( 'row().child()', function ( data, klass ) {
|
||
var ctx = this.context;
|
||
|
||
if ( data === undefined ) {
|
||
// get
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ]._details :
|
||
undefined;
|
||
}
|
||
else if ( ctx.length && this.length ) {
|
||
// set
|
||
__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
|
||
}
|
||
|
||
return this;
|
||
} );
|
||
|
||
_api_register( [
|
||
'row().child.show()',
|
||
'row().child().show()'
|
||
], function () {
|
||
__details_display.call( this, true );
|
||
return this;
|
||
} );
|
||
|
||
_api_register( [
|
||
'row().child.hide()',
|
||
'row().child().hide()'
|
||
], function () {
|
||
__details_display.call( this, false );
|
||
return this;
|
||
} );
|
||
|
||
_api_register( 'row().child.isShown()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length && this.length ) {
|
||
// _detailsShown as false or undefined will fall through to return false
|
||
return ctx[0].aoData[ this[0] ]._detailsShow || false;
|
||
}
|
||
return false;
|
||
} );
|
||
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Columns
|
||
*
|
||
* {integer} - column index (>=0 count from left, <0 count from right)
|
||
* "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
|
||
* "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
|
||
* "{string}:name" - column name
|
||
* "{string}" - jQuery selector on column header nodes
|
||
*
|
||
*/
|
||
|
||
// can be an array of these items, comma separated list, or an array of comma
|
||
// separated lists
|
||
|
||
var __re_column_selector = /^(.*):(name|visIdx|visible)$/;
|
||
|
||
var __column_selector = function ( settings, selector, opts )
|
||
{
|
||
var
|
||
columns = settings.aoColumns,
|
||
names = _pluck( columns, 'sName' ),
|
||
nodes = _pluck( columns, 'nTh' );
|
||
|
||
return _selector_run( selector, function ( s ) {
|
||
var selInt = _intVal( s );
|
||
|
||
if ( s === '' ) {
|
||
// All columns
|
||
return _range( columns.length );
|
||
}
|
||
else if ( selInt !== null ) {
|
||
// Integer selector
|
||
return [ selInt >= 0 ?
|
||
selInt : // Count from left
|
||
columns.length + selInt // Count from right (+ because its a negative value)
|
||
];
|
||
}
|
||
else {
|
||
var match = typeof s === 'string' ?
|
||
s.match( __re_column_selector ) :
|
||
'';
|
||
|
||
if ( match ) {
|
||
switch( match[2] ) {
|
||
case 'visIdx':
|
||
case 'visible':
|
||
var idx = parseInt( match[1], 10 );
|
||
// Visible index given, convert to column index
|
||
if ( idx < 0 ) {
|
||
// Counting from the right
|
||
var visColumns = $.map( columns, function (col,i) {
|
||
return col.bVisible ? i : null;
|
||
} );
|
||
return [ visColumns[ visColumns.length + idx ] ];
|
||
}
|
||
// Counting from the left
|
||
return [ _fnVisibleToColumnIndex( settings, idx ) ];
|
||
|
||
case 'name':
|
||
// match by name. `names` is column index complete and in order
|
||
return $.map( names, function (name, i) {
|
||
return name === match[1] ? i : null;
|
||
} );
|
||
}
|
||
}
|
||
else {
|
||
// jQuery selector on the TH elements for the columns
|
||
return $( nodes )
|
||
.filter( s )
|
||
.map( function () {
|
||
return $.inArray( this, nodes ); // `nodes` is column index complete and in order
|
||
} )
|
||
.toArray();
|
||
}
|
||
}
|
||
} );
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
var __setColumnVis = function ( settings, column, vis ) {
|
||
var
|
||
cols = settings.aoColumns,
|
||
col = cols[ column ],
|
||
data = settings.aoData,
|
||
row, cells, i, ien, tr;
|
||
|
||
// Get
|
||
if ( vis === undefined ) {
|
||
return col.bVisible;
|
||
}
|
||
|
||
// Set
|
||
// No change
|
||
if ( col.bVisible === vis ) {
|
||
return;
|
||
}
|
||
|
||
if ( vis ) {
|
||
// Insert column
|
||
// Need to decide if we should use appendChild or insertBefore
|
||
var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
|
||
|
||
for ( i=0, ien=data.length ; i<ien ; i++ ) {
|
||
tr = data[i].nTr;
|
||
cells = data[i].anCells;
|
||
|
||
if ( tr ) {
|
||
// insertBefore can act like appendChild if 2nd arg is null
|
||
tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// Remove column
|
||
$( _pluck( settings.aoData, 'anCells', column ) ).detach();
|
||
|
||
col.bVisible = false;
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
_fnSaveState( settings );
|
||
}
|
||
|
||
// Common actions
|
||
col.bVisible = vis;
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
// Automatically adjust column sizing
|
||
_fnAdjustColumnSizing( settings );
|
||
|
||
// Realign columns for scrolling
|
||
if ( settings.oScroll.sX || settings.oScroll.sY ) {
|
||
_fnScrollDraw( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
|
||
|
||
_fnSaveState( settings );
|
||
};
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'columns()', function ( selector, opts ) {
|
||
// argument shifting
|
||
if ( selector === undefined ) {
|
||
selector = '';
|
||
}
|
||
else if ( $.isPlainObject( selector ) ) {
|
||
opts = selector;
|
||
selector = '';
|
||
}
|
||
|
||
opts = _selector_opts( opts );
|
||
|
||
var inst = this.iterator( 'table', function ( settings ) {
|
||
return __column_selector( settings, selector, opts );
|
||
} );
|
||
|
||
// Want argument shifting here and in _row_selector?
|
||
inst.selector.cols = selector;
|
||
inst.selector.opts = opts;
|
||
|
||
return inst;
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return settings.aoColumns[column].nTh;
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return settings.aoColumns[column].nTf;
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().data()', 'column().data()', function () {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
var a = [];
|
||
for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
|
||
a.push( _fnGetCellData( settings, rows[row], column, '' ) );
|
||
}
|
||
return a;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
return _pluck_order( settings.aoData, rows,
|
||
type === 'search' ? '_aFilterData' : '_aSortData', column
|
||
);
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return vis === undefined ?
|
||
settings.aoColumns[ column ].bVisible :
|
||
__setColumnVis( settings, column, vis );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return type === 'visible' ?
|
||
_fnColumnIndexToVisible( settings, column ) :
|
||
column;
|
||
} );
|
||
} );
|
||
|
||
|
||
// _api_register( 'columns().show()', function () {
|
||
// var selector = this.selector;
|
||
// return this.columns( selector.cols, selector.opts ).visible( true );
|
||
// } );
|
||
|
||
|
||
// _api_register( 'columns().hide()', function () {
|
||
// var selector = this.selector;
|
||
// return this.columns( selector.cols, selector.opts ).visible( false );
|
||
// } );
|
||
|
||
|
||
|
||
_api_register( 'columns.adjust()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnAdjustColumnSizing( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
// Convert from one column index type, to another type
|
||
_api_register( 'column.index()', function ( type, idx ) {
|
||
if ( this.context.length !== 0 ) {
|
||
var ctx = this.context[0];
|
||
|
||
if ( type === 'fromVisible' || type === 'toData' ) {
|
||
return _fnVisibleToColumnIndex( ctx, idx );
|
||
}
|
||
else if ( type === 'fromData' || type === 'toVisible' ) {
|
||
return _fnColumnIndexToVisible( ctx, idx );
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
_api_register( 'column()', function ( selector, opts ) {
|
||
return _selector_first( this.columns( selector, opts ) );
|
||
} );
|
||
|
||
|
||
|
||
|
||
var __cell_selector = function ( settings, selector, opts )
|
||
{
|
||
var data = settings.aoData;
|
||
var rows = _selector_row_indexes( settings, opts );
|
||
var cells = _pluck_order( data, rows, 'anCells' );
|
||
var allCells = $( [].concat.apply([], cells) );
|
||
var row;
|
||
var columns = settings.aoColumns.length;
|
||
var a, i, ien, j;
|
||
|
||
return _selector_run( selector, function ( s ) {
|
||
if ( ! s ) {
|
||
// All cells
|
||
a = [];
|
||
|
||
for ( i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
row = rows[i];
|
||
|
||
for ( j=0 ; j<columns ; j++ ) {
|
||
a.push( {
|
||
row: row,
|
||
column: j
|
||
} );
|
||
}
|
||
}
|
||
|
||
return a;
|
||
}
|
||
else if ( $.isPlainObject( s ) ) {
|
||
return [s];
|
||
}
|
||
|
||
// jQuery filtered cells
|
||
return allCells
|
||
.filter( s )
|
||
.map( function (i, el) {
|
||
row = el.parentNode._DT_RowIndex;
|
||
|
||
return {
|
||
row: row,
|
||
column: $.inArray( el, data[ row ].anCells )
|
||
};
|
||
} )
|
||
.toArray();
|
||
} );
|
||
};
|
||
|
||
|
||
|
||
|
||
_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
|
||
// Argument shifting
|
||
if ( $.isPlainObject( rowSelector ) ) {
|
||
// If passing in a cell index
|
||
if ( rowSelector.row ) {
|
||
opts = columnSelector;
|
||
columnSelector = null;
|
||
}
|
||
else {
|
||
opts = rowSelector;
|
||
rowSelector = null;
|
||
}
|
||
}
|
||
if ( $.isPlainObject( columnSelector ) ) {
|
||
opts = columnSelector;
|
||
columnSelector = null;
|
||
}
|
||
|
||
// Cell selector
|
||
if ( columnSelector === null || columnSelector === undefined ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
|
||
} );
|
||
}
|
||
|
||
// Row + column selector
|
||
var columns = this.columns( columnSelector, opts );
|
||
var rows = this.rows( rowSelector, opts );
|
||
var a, i, ien, j, jen;
|
||
|
||
var cells = this.iterator( 'table', function ( settings, idx ) {
|
||
a = [];
|
||
|
||
for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
|
||
for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
|
||
a.push( {
|
||
row: rows[idx][i],
|
||
column: columns[idx][j]
|
||
} );
|
||
}
|
||
}
|
||
|
||
return a;
|
||
} );
|
||
|
||
$.extend( cells.selector, {
|
||
cols: columnSelector,
|
||
rows: rowSelector,
|
||
opts: opts
|
||
} );
|
||
|
||
return cells;
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return settings.aoData[ row ].anCells[ column ];
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'cells().data()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return _fnGetCellData( settings, row, column );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
|
||
type = type === 'search' ? '_aFilterData' : '_aSortData';
|
||
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return settings.aoData[ row ][ type ][ column ];
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return {
|
||
row: row,
|
||
column: column,
|
||
columnVisible: _fnColumnIndexToVisible( settings, column )
|
||
};
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( [
|
||
'cells().invalidate()',
|
||
'cell().invalidate()'
|
||
], function ( src ) {
|
||
var selector = this.selector;
|
||
|
||
// Use the rows method of the instance to perform the invalidation, rather
|
||
// than doing it here. This avoids needing to handle duplicate rows from
|
||
// the cells.
|
||
this.rows( selector.rows, selector.opts ).invalidate( src );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
|
||
|
||
_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
|
||
return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
|
||
} );
|
||
|
||
|
||
|
||
_api_register( 'cell().data()', function ( data ) {
|
||
var ctx = this.context;
|
||
var cell = this[0];
|
||
|
||
if ( data === undefined ) {
|
||
// Get
|
||
return ctx.length && cell.length ?
|
||
_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
|
||
undefined;
|
||
}
|
||
|
||
// Set
|
||
_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
|
||
_fnInvalidateRow( ctx[0], cell[0].row, 'data', cell[0].column );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Get current ordering (sorting) that has been applied to the table.
|
||
*
|
||
* @returns {array} 2D array containing the sorting information for the first
|
||
* table in the current context. Each element in the parent array represents
|
||
* a column being sorted upon (i.e. multi-sorting with two columns would have
|
||
* 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
|
||
* the column index that the sorting condition applies to, the second is the
|
||
* direction of the sort (`desc` or `asc`) and, optionally, the third is the
|
||
* index of the sorting order from the `column.sorting` initialisation array.
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {integer} order Column index to sort upon.
|
||
* @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
|
||
* @returns {DataTables.Api} this
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {array} order 1D array of sorting information to be applied.
|
||
* @param {array} [...] Optional additional sorting conditions
|
||
* @returns {DataTables.Api} this
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {array} order 2D array of sorting information to be applied.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'order()', function ( order, dir ) {
|
||
var ctx = this.context;
|
||
|
||
if ( order === undefined ) {
|
||
// get
|
||
return ctx.length !== 0 ?
|
||
ctx[0].aaSorting :
|
||
undefined;
|
||
}
|
||
|
||
// set
|
||
if ( typeof order === 'number' ) {
|
||
// Simple column / direction passed in
|
||
order = [ [ order, dir ] ];
|
||
}
|
||
else if ( ! $.isArray( order[0] ) ) {
|
||
// Arguments passed in (list of 1D arrays)
|
||
order = Array.prototype.slice.call( arguments );
|
||
}
|
||
// otherwise a 2D array was passed in
|
||
|
||
return this.iterator( 'table', function ( settings ) {
|
||
settings.aaSorting = order.slice();
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Attach a sort listener to an element for a given column
|
||
*
|
||
* @param {node|jQuery|string} node Identifier for the element(s) to attach the
|
||
* listener to. This can take the form of a single DOM node, a jQuery
|
||
* collection of nodes or a jQuery selector which will identify the node(s).
|
||
* @param {integer} column the column that a click on this node will sort on
|
||
* @param {function} [callback] callback function when sort is run
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'order.listener()', function ( node, column, callback ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnSortAttachListener( settings, node, column, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
// Order by the selected column(s)
|
||
_api_register( [
|
||
'columns().order()',
|
||
'column().order()'
|
||
], function ( dir ) {
|
||
var that = this;
|
||
|
||
return this.iterator( 'table', function ( settings, i ) {
|
||
var sort = [];
|
||
|
||
$.each( that[i], function (j, col) {
|
||
sort.push( [ col, dir ] );
|
||
} );
|
||
|
||
settings.aaSorting = sort;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
|
||
var ctx = this.context;
|
||
|
||
if ( input === undefined ) {
|
||
// get
|
||
return ctx.length !== 0 ?
|
||
ctx[0].oPreviousSearch.sSearch :
|
||
undefined;
|
||
}
|
||
|
||
// set
|
||
return this.iterator( 'table', function ( settings ) {
|
||
if ( ! settings.oFeatures.bFilter ) {
|
||
return;
|
||
}
|
||
|
||
_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
|
||
"sSearch": input+"",
|
||
"bRegex": regex === null ? false : regex,
|
||
"bSmart": smart === null ? true : smart,
|
||
"bCaseInsensitive": caseInsen === null ? true : caseInsen
|
||
} ), 1 );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( [
|
||
'columns().search()',
|
||
'column().search()'
|
||
], function ( input, regex, smart, caseInsen ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
var preSearch = settings.aoPreSearchCols;
|
||
|
||
if ( input === undefined ) {
|
||
// get
|
||
return preSearch[ column ].sSearch;
|
||
}
|
||
|
||
// set
|
||
if ( ! settings.oFeatures.bFilter ) {
|
||
return;
|
||
}
|
||
|
||
$.extend( preSearch[ column ], {
|
||
"sSearch": input+"",
|
||
"bRegex": regex === null ? false : regex,
|
||
"bSmart": smart === null ? true : smart,
|
||
"bCaseInsensitive": caseInsen === null ? true : caseInsen
|
||
} );
|
||
|
||
_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Provide a common method for plug-ins to check the version of DataTables being
|
||
* used, in order to ensure compatibility.
|
||
*
|
||
* @param {string} version Version string to check for, in the format "X.Y.Z".
|
||
* Note that the formats "X" and "X.Y" are also acceptable.
|
||
* @returns {boolean} true if this version of DataTables is greater or equal to
|
||
* the required version, or false if this version of DataTales is not
|
||
* suitable
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
|
||
*/
|
||
DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
|
||
{
|
||
var aThis = DataTable.version.split('.');
|
||
var aThat = version.split('.');
|
||
var iThis, iThat;
|
||
|
||
for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
|
||
iThis = parseInt( aThis[i], 10 ) || 0;
|
||
iThat = parseInt( aThat[i], 10 ) || 0;
|
||
|
||
// Parts are the same, keep comparing
|
||
if (iThis === iThat) {
|
||
continue;
|
||
}
|
||
|
||
// Parts are different, return immediately
|
||
return iThis > iThat;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/**
|
||
* Check if a `<table>` node is a DataTable table already or not.
|
||
*
|
||
* @param {node|jquery|string} table Table node, jQuery object or jQuery
|
||
* selector for the table to test. Note that if more than more than one
|
||
* table is passed on, only the first will be checked
|
||
* @returns {boolean} true the table given is a DataTable, or false otherwise
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
|
||
* $('#example').dataTable();
|
||
* }
|
||
*/
|
||
DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
|
||
{
|
||
var t = $(table).get(0);
|
||
var is = false;
|
||
|
||
$.each( DataTable.settings, function (i, o) {
|
||
if ( o.nTable === t || o.nScrollHead === t || o.nScrollFoot === t ) {
|
||
is = true;
|
||
}
|
||
} );
|
||
|
||
return is;
|
||
};
|
||
|
||
|
||
/**
|
||
* Get all DataTable tables that have been initialised - optionally you can
|
||
* select to get only currently visible tables.
|
||
*
|
||
* @param {boolean} [visible=false] Flag to indicate if you want all (default)
|
||
* or visible tables only.
|
||
* @returns {array} Array of `table` nodes (not DataTable instances) which are
|
||
* DataTables
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* $.each( $.fn.dataTable.tables(true), function () {
|
||
* $(table).DataTable().columns.adjust();
|
||
* } );
|
||
*/
|
||
DataTable.tables = DataTable.fnTables = function ( visible )
|
||
{
|
||
return jQuery.map( DataTable.settings, function (o) {
|
||
if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
|
||
return o.nTable;
|
||
}
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
* Convert from camel case parameters to Hungarian notation. This is made public
|
||
* for the extensions to provide the same ability as DataTables core to accept
|
||
* either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
|
||
* parameters.
|
||
*
|
||
* @param {object} src The model object which holds all parameters that can be
|
||
* mapped.
|
||
* @param {object} user The object to convert from camel case to Hungarian.
|
||
* @param {boolean} force When set to `true`, properties which already have a
|
||
* Hungarian value in the `user` object will be overwritten. Otherwise they
|
||
* won't be.
|
||
*/
|
||
DataTable.camelToHungarian = _fnCamelToHungarian;
|
||
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( '$()', function ( selector, opts ) {
|
||
var
|
||
rows = this.rows( opts ).nodes(), // Get all rows
|
||
jqRows = $(rows);
|
||
|
||
return $( [].concat(
|
||
jqRows.filter( selector ).toArray(),
|
||
jqRows.find( selector ).toArray()
|
||
) );
|
||
} );
|
||
|
||
|
||
// jQuery functions to operate on the tables
|
||
$.each( [ 'on', 'one', 'off' ], function (i, key) {
|
||
_api_register( key+'()', function ( /* event, handler */ ) {
|
||
var args = Array.prototype.slice.call(arguments);
|
||
|
||
// Add the `dt` namespace automatically if it isn't already present
|
||
if ( args[0].indexOf( '.dt' ) === -1 ) {
|
||
args[0] += '.dt';
|
||
}
|
||
|
||
var inst = $( this.tables().nodes() );
|
||
inst[key].apply( inst, args );
|
||
return this;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'clear()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnClearTable( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'settings()', function () {
|
||
return new _Api( this.context, this.context );
|
||
} );
|
||
|
||
|
||
_api_register( 'data()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
return _pluck( settings.aoData, '_aData' );
|
||
} ).flatten();
|
||
} );
|
||
|
||
|
||
_api_register( 'destroy()', function ( remove ) {
|
||
remove = remove || false;
|
||
|
||
return this.iterator( 'table', function ( settings ) {
|
||
var orig = settings.nTableWrapper.parentNode;
|
||
var classes = settings.oClasses;
|
||
var table = settings.nTable;
|
||
var tbody = settings.nTBody;
|
||
var thead = settings.nTHead;
|
||
var tfoot = settings.nTFoot;
|
||
var jqTable = $(table);
|
||
var jqTbody = $(tbody);
|
||
var jqWrapper = $(settings.nTableWrapper);
|
||
var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
|
||
var i, ien;
|
||
|
||
// Flag to note that the table is currently being destroyed - no action
|
||
// should be taken
|
||
settings.bDestroying = true;
|
||
|
||
// Fire off the destroy callbacks for plug-ins etc
|
||
_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
|
||
|
||
// If not being removed from the document, make all columns visible
|
||
if ( ! remove ) {
|
||
new _Api( settings ).columns().visible( true );
|
||
}
|
||
|
||
// Blitz all `DT` namespaced events (these are internal events, the
|
||
// lowercase, `dt` events are user subscribed and they are responsible
|
||
// for removing them
|
||
jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
|
||
$(window).unbind('.DT-'+settings.sInstance);
|
||
|
||
// When scrolling we had to break the table up - restore it
|
||
if ( table != thead.parentNode ) {
|
||
jqTable.children('thead').detach();
|
||
jqTable.append( thead );
|
||
}
|
||
|
||
if ( tfoot && table != tfoot.parentNode ) {
|
||
jqTable.children('tfoot').detach();
|
||
jqTable.append( tfoot );
|
||
}
|
||
|
||
// Remove the DataTables generated nodes, events and classes
|
||
jqTable.detach();
|
||
jqWrapper.detach();
|
||
|
||
settings.aaSorting = [];
|
||
settings.aaSortingFixed = [];
|
||
_fnSortingClasses( settings );
|
||
|
||
$( rows ).removeClass( settings.asStripeClasses.join(' ') );
|
||
|
||
$('th, td', thead).removeClass( classes.sSortable+' '+
|
||
classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
|
||
);
|
||
|
||
if ( settings.bJUI ) {
|
||
$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
|
||
$('th, td', thead).each( function () {
|
||
var wrapper = $('div.'+classes.sSortJUIWrapper, this);
|
||
$(this).append( wrapper.contents() );
|
||
wrapper.detach();
|
||
} );
|
||
}
|
||
|
||
if ( ! remove && orig ) {
|
||
// insertBefore acts like appendChild if !arg[1]
|
||
orig.insertBefore( table, settings.nTableReinsertBefore );
|
||
}
|
||
|
||
// Add the TR elements back into the table in their original order
|
||
jqTbody.children().detach();
|
||
jqTbody.append( rows );
|
||
|
||
// Restore the width of the original table - was read from the style property,
|
||
// so we can restore directly to that
|
||
jqTable
|
||
.css( 'width', settings.sDestroyWidth )
|
||
.removeClass( classes.sTable );
|
||
|
||
// If the were originally stripe classes - then we add them back here.
|
||
// Note this is not fool proof (for example if not all rows had stripe
|
||
// classes - but it's a good effort without getting carried away
|
||
ien = settings.asDestroyStripes.length;
|
||
|
||
if ( ien ) {
|
||
jqTbody.children().each( function (i) {
|
||
$(this).addClass( settings.asDestroyStripes[i % ien] );
|
||
} );
|
||
}
|
||
|
||
/* Remove the settings object from the settings array */
|
||
var idx = $.inArray( settings, DataTable.settings );
|
||
if ( idx !== -1 ) {
|
||
DataTable.settings.splice( idx, 1 );
|
||
}
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Version string for plug-ins to check compatibility. Allowed format is
|
||
* `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
|
||
* only for non-release builds. See http://semver.org/ for more information.
|
||
* @member
|
||
* @type string
|
||
* @default Version number
|
||
*/
|
||
DataTable.version = "1.10.0";
|
||
|
||
/**
|
||
* Private data store, containing all of the settings objects that are
|
||
* created for the tables on a given page.
|
||
*
|
||
* Note that the `DataTable.settings` object is aliased to
|
||
* `jQuery.fn.dataTableExt` through which it may be accessed and
|
||
* manipulated, or `jQuery.fn.dataTable.settings`.
|
||
* @member
|
||
* @type array
|
||
* @default []
|
||
* @private
|
||
*/
|
||
DataTable.settings = [];
|
||
|
||
/**
|
||
* Object models container, for the various models that DataTables has
|
||
* available to it. These models define the objects that are used to hold
|
||
* the active state and configuration of the table.
|
||
* @namespace
|
||
*/
|
||
DataTable.models = {};
|
||
|
||
|
||
|
||
/**
|
||
* Template object for the way in which DataTables holds information about
|
||
* search information for the global filter and individual column filters.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oSearch = {
|
||
/**
|
||
* Flag to indicate if the filtering should be case insensitive or not
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bCaseInsensitive": true,
|
||
|
||
/**
|
||
* Applied search term
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*/
|
||
"sSearch": "",
|
||
|
||
/**
|
||
* Flag to indicate if the search term should be interpreted as a
|
||
* regular expression (true) or not (false) and therefore and special
|
||
* regex characters escaped.
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bRegex": false,
|
||
|
||
/**
|
||
* Flag to indicate if DataTables is to use its smart filtering or not.
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bSmart": true
|
||
};
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Template object for the way in which DataTables holds information about
|
||
* each individual row. This is the object format used for the settings
|
||
* aoData array.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oRow = {
|
||
/**
|
||
* TR element for the row
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTr": null,
|
||
|
||
/**
|
||
* Array of TD elements for each row. This is null until the row has been
|
||
* created.
|
||
* @type array nodes
|
||
* @default []
|
||
*/
|
||
"anCells": null,
|
||
|
||
/**
|
||
* Data object from the original data source for the row. This is either
|
||
* an array if using the traditional form of DataTables, or an object if
|
||
* using mData options. The exact type will depend on the passed in
|
||
* data from the data source, or will be an array if using DOM a data
|
||
* source.
|
||
* @type array|object
|
||
* @default []
|
||
*/
|
||
"_aData": [],
|
||
|
||
/**
|
||
* Sorting data cache - this array is ostensibly the same length as the
|
||
* number of columns (although each index is generated only as it is
|
||
* needed), and holds the data that is used for sorting each column in the
|
||
* row. We do this cache generation at the start of the sort in order that
|
||
* the formatting of the sort data need be done only once for each cell
|
||
* per sort. This array should not be read from or written to by anything
|
||
* other than the master sorting methods.
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_aSortData": null,
|
||
|
||
/**
|
||
* Per cell filtering data cache. As per the sort data cache, used to
|
||
* increase the performance of the filtering in DataTables
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_aFilterData": null,
|
||
|
||
/**
|
||
* Filtering data cache. This is the same as the cell filtering cache, but
|
||
* in this case a string rather than an array. This is easily computed with
|
||
* a join on `_aFilterData`, but is provided as a cache so the join isn't
|
||
* needed on every search (memory traded for performance)
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_sFilterRow": null,
|
||
|
||
/**
|
||
* Cache of the class name that DataTables has applied to the row, so we
|
||
* can quickly look at this variable rather than needing to do a DOM check
|
||
* on className for the nTr property.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
* @private
|
||
*/
|
||
"_sRowStripe": "",
|
||
|
||
/**
|
||
* Denote if the original data source was from the DOM, or the data source
|
||
* object. This is used for invalidating data, so DataTables can
|
||
* automatically read data from the original source, unless uninstructed
|
||
* otherwise.
|
||
* @type string
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"src": null
|
||
};
|
||
|
||
|
||
/**
|
||
* Template object for the column information object in DataTables. This object
|
||
* is held in the settings aoColumns array and contains all the information that
|
||
* DataTables needs about each individual column.
|
||
*
|
||
* Note that this object is related to {@link DataTable.defaults.column}
|
||
* but this one is the internal data store for DataTables's cache of columns.
|
||
* It should NOT be manipulated outside of DataTables. Any configuration should
|
||
* be done through the initialisation options.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oColumn = {
|
||
/**
|
||
* Column index. This could be worked out on-the-fly with $.inArray, but it
|
||
* is faster to just hold it as a variable
|
||
* @type integer
|
||
* @default null
|
||
*/
|
||
"idx": null,
|
||
|
||
/**
|
||
* A list of the columns that sorting should occur on when this column
|
||
* is sorted. That this property is an array allows multi-column sorting
|
||
* to be defined for a column (for example first name / last name columns
|
||
* would benefit from this). The values are integers pointing to the
|
||
* columns to be sorted on (typically it will be a single integer pointing
|
||
* at itself, but that doesn't need to be the case).
|
||
* @type array
|
||
*/
|
||
"aDataSort": null,
|
||
|
||
/**
|
||
* Define the sorting directions that are applied to the column, in sequence
|
||
* as the column is repeatedly sorted upon - i.e. the first value is used
|
||
* as the sorting direction when the column if first sorted (clicked on).
|
||
* Sort it again (click again) and it will move on to the next index.
|
||
* Repeat until loop.
|
||
* @type array
|
||
*/
|
||
"asSorting": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is searchable, and thus should be included
|
||
* in the filtering or not.
|
||
* @type boolean
|
||
*/
|
||
"bSearchable": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is sortable or not.
|
||
* @type boolean
|
||
*/
|
||
"bSortable": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is currently visible in the table or not
|
||
* @type boolean
|
||
*/
|
||
"bVisible": null,
|
||
|
||
/**
|
||
* Store for manual type assignment using the `column.type` option. This
|
||
* is held in store so we can manipulate the column's `sType` property.
|
||
* @type string
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_sManualType": null,
|
||
|
||
/**
|
||
* Flag to indicate if HTML5 data attributes should be used as the data
|
||
* source for filtering or sorting. True is either are.
|
||
* @type boolean
|
||
* @default false
|
||
* @private
|
||
*/
|
||
"_bAttrSrc": false,
|
||
|
||
/**
|
||
* Developer definable function that is called whenever a cell is created (Ajax source,
|
||
* etc) or processed for input (DOM source). This can be used as a compliment to mRender
|
||
* allowing you to modify the DOM element (add background colour for example) when the
|
||
* element is available.
|
||
* @type function
|
||
* @param {element} nTd The TD node that has been created
|
||
* @param {*} sData The Data for the cell
|
||
* @param {array|object} oData The data for the whole row
|
||
* @param {int} iRow The row index for the aoData data store
|
||
* @default null
|
||
*/
|
||
"fnCreatedCell": null,
|
||
|
||
/**
|
||
* Function to get data from a cell in a column. You should <b>never</b>
|
||
* access data directly through _aData internally in DataTables - always use
|
||
* the method attached to this property. It allows mData to function as
|
||
* required. This function is automatically assigned by the column
|
||
* initialisation method
|
||
* @type function
|
||
* @param {array|object} oData The data array/object for the array
|
||
* (i.e. aoData[]._aData)
|
||
* @param {string} sSpecific The specific data type you want to get -
|
||
* 'display', 'type' 'filter' 'sort'
|
||
* @returns {*} The data for the cell from the given row's data
|
||
* @default null
|
||
*/
|
||
"fnGetData": null,
|
||
|
||
/**
|
||
* Function to set data for a cell in the column. You should <b>never</b>
|
||
* set the data directly to _aData internally in DataTables - always use
|
||
* this method. It allows mData to function as required. This function
|
||
* is automatically assigned by the column initialisation method
|
||
* @type function
|
||
* @param {array|object} oData The data array/object for the array
|
||
* (i.e. aoData[]._aData)
|
||
* @param {*} sValue Value to set
|
||
* @default null
|
||
*/
|
||
"fnSetData": null,
|
||
|
||
/**
|
||
* Property to read the value for the cells in the column from the data
|
||
* source array / object. If null, then the default content is used, if a
|
||
* function is given then the return from the function is used.
|
||
* @type function|int|string|null
|
||
* @default null
|
||
*/
|
||
"mData": null,
|
||
|
||
/**
|
||
* Partner property to mData which is used (only when defined) to get
|
||
* the data - i.e. it is basically the same as mData, but without the
|
||
* 'set' option, and also the data fed to it is the result from mData.
|
||
* This is the rendering method to match the data method of mData.
|
||
* @type function|int|string|null
|
||
* @default null
|
||
*/
|
||
"mRender": null,
|
||
|
||
/**
|
||
* Unique header TH/TD element for this column - this is what the sorting
|
||
* listener is attached to (if sorting is enabled.)
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTh": null,
|
||
|
||
/**
|
||
* Unique footer TH/TD element for this column (if there is one). Not used
|
||
* in DataTables as such, but can be used for plug-ins to reference the
|
||
* footer for each column.
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTf": null,
|
||
|
||
/**
|
||
* The class to apply to all TD elements in the table's TBODY for the column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sClass": null,
|
||
|
||
/**
|
||
* When DataTables calculates the column widths to assign to each column,
|
||
* it finds the longest string in each column and then constructs a
|
||
* temporary table and reads the widths from that. The problem with this
|
||
* is that "mmm" is much wider then "iiii", but the latter is a longer
|
||
* string - thus the calculation can go wrong (doing it properly and putting
|
||
* it into an DOM object and measuring that is horribly(!) slow). Thus as
|
||
* a "work around" we provide this option. It will append its value to the
|
||
* text that is found to be the longest string for the column - i.e. padding.
|
||
* @type string
|
||
*/
|
||
"sContentPadding": null,
|
||
|
||
/**
|
||
* Allows a default value to be given for a column's data, and will be used
|
||
* whenever a null data source is encountered (this can be because mData
|
||
* is set to null, or because the data source itself is null).
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sDefaultContent": null,
|
||
|
||
/**
|
||
* Name for the column, allowing reference to the column by name as well as
|
||
* by index (needs a lookup to work by name).
|
||
* @type string
|
||
*/
|
||
"sName": null,
|
||
|
||
/**
|
||
* Custom sorting data type - defines which of the available plug-ins in
|
||
* afnSortData the custom sorting will use - if any is defined.
|
||
* @type string
|
||
* @default std
|
||
*/
|
||
"sSortDataType": 'std',
|
||
|
||
/**
|
||
* Class to be applied to the header element when sorting on this column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sSortingClass": null,
|
||
|
||
/**
|
||
* Class to be applied to the header element when sorting on this column -
|
||
* when jQuery UI theming is used.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sSortingClassJUI": null,
|
||
|
||
/**
|
||
* Title of the column - what is seen in the TH element (nTh).
|
||
* @type string
|
||
*/
|
||
"sTitle": null,
|
||
|
||
/**
|
||
* Column sorting and filtering type
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sType": null,
|
||
|
||
/**
|
||
* Width of the column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sWidth": null,
|
||
|
||
/**
|
||
* Width of the column when it was first "encountered"
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sWidthOrig": null
|
||
};
|
||
|
||
|
||
/*
|
||
* Developer note: The properties of the object below are given in Hungarian
|
||
* notation, that was used as the interface for DataTables prior to v1.10, however
|
||
* from v1.10 onwards the primary interface is camel case. In order to avoid
|
||
* breaking backwards compatibility utterly with this change, the Hungarian
|
||
* version is still, internally the primary interface, but is is not documented
|
||
* - hence the @name tags in each doc comment. This allows a Javascript function
|
||
* to create a map from Hungarian notation to camel case (going the other direction
|
||
* would require each property to be listed, which would at around 3K to the size
|
||
* of DataTables, while this method is about a 0.5K hit.
|
||
*
|
||
* Ultimately this does pave the way for Hungarian notation to be dropped
|
||
* completely, but that is a massive amount of work and will break current
|
||
* installs (therefore is on-hold until v2).
|
||
*/
|
||
|
||
/**
|
||
* Initialisation options that can be given to DataTables at initialisation
|
||
* time.
|
||
* @namespace
|
||
*/
|
||
DataTable.defaults = {
|
||
/**
|
||
* An array of data to use for the table, passed in at initialisation which
|
||
* will be used in preference to any data which is already in the DOM. This is
|
||
* particularly useful for constructing tables purely in Javascript, for
|
||
* example with a custom Ajax call.
|
||
* @type array
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.data
|
||
*
|
||
* @example
|
||
* // Using a 2D array data source
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "data": [
|
||
* ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
|
||
* ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
|
||
* ],
|
||
* "columns": [
|
||
* { "title": "Engine" },
|
||
* { "title": "Browser" },
|
||
* { "title": "Platform" },
|
||
* { "title": "Version" },
|
||
* { "title": "Grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using an array of objects as a data source (`data`)
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "data": [
|
||
* {
|
||
* "engine": "Trident",
|
||
* "browser": "Internet Explorer 4.0",
|
||
* "platform": "Win 95+",
|
||
* "version": 4,
|
||
* "grade": "X"
|
||
* },
|
||
* {
|
||
* "engine": "Trident",
|
||
* "browser": "Internet Explorer 5.0",
|
||
* "platform": "Win 95+",
|
||
* "version": 5,
|
||
* "grade": "C"
|
||
* }
|
||
* ],
|
||
* "columns": [
|
||
* { "title": "Engine", "data": "engine" },
|
||
* { "title": "Browser", "data": "browser" },
|
||
* { "title": "Platform", "data": "platform" },
|
||
* { "title": "Version", "data": "version" },
|
||
* { "title": "Grade", "data": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aaData": null,
|
||
|
||
|
||
/**
|
||
* If ordering is enabled, then DataTables will perform a first pass sort on
|
||
* initialisation. You can define which column(s) the sort is performed
|
||
* upon, and the sorting direction, with this variable. The `sorting` array
|
||
* should contain an array for each column to be sorted initially containing
|
||
* the column's index and a direction string ('asc' or 'desc').
|
||
* @type array
|
||
* @default [[0,'asc']]
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.order
|
||
*
|
||
* @example
|
||
* // Sort by 3rd column first, and then 4th column
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "order": [[2,'asc'], [3,'desc']]
|
||
* } );
|
||
* } );
|
||
*
|
||
* // No initial sorting
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "order": []
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aaSorting": [[0,'asc']],
|
||
|
||
|
||
/**
|
||
* This parameter is basically identical to the `sorting` parameter, but
|
||
* cannot be overridden by user interaction with the table. What this means
|
||
* is that you could have a column (visible or hidden) which the sorting
|
||
* will always be forced on first - any sorting after that (from the user)
|
||
* will then be performed as required. This can be useful for grouping rows
|
||
* together.
|
||
* @type array
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.orderFixed
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "orderFixed": [[0,'asc']]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"aaSortingFixed": [],
|
||
|
||
|
||
/**
|
||
* DataTables can be instructed to load data to display in the table from a
|
||
* Ajax source. This option defines how that Ajax call is made and where to.
|
||
*
|
||
* The `ajax` property has three different modes of operation, depending on
|
||
* how it is defined. These are:
|
||
*
|
||
* * `string` - Set the URL from where the data should be loaded from.
|
||
* * `object` - Define properties for `jQuery.ajax`.
|
||
* * `function` - Custom data get function
|
||
*
|
||
* `string`
|
||
* --------
|
||
*
|
||
* As a string, the `ajax` property simply defines the URL from which
|
||
* DataTables will load data.
|
||
*
|
||
* `object`
|
||
* --------
|
||
*
|
||
* As an object, the parameters in the object are passed to
|
||
* [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
|
||
* of the Ajax request. DataTables has a number of default parameters which
|
||
* you can override using this option. Please refer to the jQuery
|
||
* documentation for a full description of the options available, although
|
||
* the following parameters provide additional options in DataTables or
|
||
* require special consideration:
|
||
*
|
||
* * `data` - As with jQuery, `data` can be provided as an object, but it
|
||
* can also be used as a function to manipulate the data DataTables sends
|
||
* to the server. The function takes a single parameter, an object of
|
||
* parameters with the values that DataTables has readied for sending. An
|
||
* object may be returned which will be merged into the DataTables
|
||
* defaults, or you can add the items to the object that was passed in and
|
||
* not return anything from the function. This supersedes `fnServerParams`
|
||
* from DataTables 1.9-.
|
||
*
|
||
* * `dataSrc` - By default DataTables will look for the property `data` (or
|
||
* `aaData` for compatibility with DataTables 1.9-) when obtaining data
|
||
* from an Ajax source or for server-side processing - this parameter
|
||
* allows that property to be changed. You can use Javascript dotted
|
||
* object notation to get a data source for multiple levels of nesting, or
|
||
* it my be used as a function. As a function it takes a single parameter,
|
||
* the JSON returned from the server, which can be manipulated as
|
||
* required, with the returned value being that used by DataTables as the
|
||
* data source for the table. This supersedes `sAjaxDataProp` from
|
||
* DataTables 1.9-.
|
||
*
|
||
* * `success` - Should not be overridden it is used internally in
|
||
* DataTables. To manipulate / transform the data returned by the server
|
||
* use `ajax.dataSrc`, or use `ajax` as a function (see below).
|
||
*
|
||
* `function`
|
||
* ----------
|
||
*
|
||
* As a function, making the Ajax call is left up to yourself allowing
|
||
* complete control of the Ajax request. Indeed, if desired, a method other
|
||
* than Ajax could be used to obtain the required data, such as Web storage
|
||
* or an AIR database.
|
||
*
|
||
* The function is given four parameters and no return is required. The
|
||
* parameters are:
|
||
*
|
||
* 1. _object_ - Data to send to the server
|
||
* 2. _function_ - Callback function that must be executed when the required
|
||
* data has been obtained. That data should be passed into the callback
|
||
* as the only parameter
|
||
* 3. _object_ - DataTables settings object for the table
|
||
*
|
||
* Note that this supersedes `fnServerData` from DataTables 1.9-.
|
||
*
|
||
* @type string|object|function
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.ajax
|
||
* @since 1.10.0
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax.
|
||
* // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
|
||
* $('#example').dataTable( {
|
||
* "ajax": "data.json"
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax, using `dataSrc` to change
|
||
* // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": "tableData"
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax, using `dataSrc` to read data
|
||
* // from a plain array rather than an array in an object
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": ""
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Manipulate the data returned from the server - add a link to data
|
||
* // (note this can, should, be done using `render` for the column - this
|
||
* // is just a simple example of how the data can be manipulated).
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": function ( json ) {
|
||
* for ( var i=0, ien=json.length ; i<ien ; i++ ) {
|
||
* json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
|
||
* }
|
||
* return json;
|
||
* }
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Add data to the request
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "data": function ( d ) {
|
||
* return {
|
||
* "extra_search": $('#extra').val()
|
||
* };
|
||
* }
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Send request as POST
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "type": "POST"
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get the data from localStorage (could interface with a form for
|
||
* // adding, editing and removing rows).
|
||
* $('#example').dataTable( {
|
||
* "ajax": function (data, callback, settings) {
|
||
* callback(
|
||
* JSON.parse( localStorage.getItem('dataTablesData') )
|
||
* );
|
||
* }
|
||
* } );
|
||
*/
|
||
"ajax": null,
|
||
|
||
|
||
/**
|
||
* This parameter allows you to readily specify the entries in the length drop
|
||
* down menu that DataTables shows when pagination is enabled. It can be
|
||
* either a 1D array of options which will be used for both the displayed
|
||
* option and the value, or a 2D array which will use the array in the first
|
||
* position as the value, and the array in the second position as the
|
||
* displayed options (useful for language strings such as 'All').
|
||
*
|
||
* Note that the `pageLength` property will be automatically set to the
|
||
* first value given in this array, unless `pageLength` is also provided.
|
||
* @type array
|
||
* @default [ 10, 25, 50, 100 ]
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.lengthMenu
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aLengthMenu": [ 10, 25, 50, 100 ],
|
||
|
||
|
||
/**
|
||
* The `columns` option in the initialisation parameter allows you to define
|
||
* details about the way individual columns behave. For a full list of
|
||
* column options that can be set, please see
|
||
* {@link DataTable.defaults.column}. Note that if you use `columns` to
|
||
* define your columns, you must have an entry in the array for every single
|
||
* column that you have in your table (these can be null if you don't which
|
||
* to specify any options).
|
||
* @member
|
||
*
|
||
* @name DataTable.defaults.column
|
||
*/
|
||
"aoColumns": null,
|
||
|
||
/**
|
||
* Very similar to `columns`, `columnDefs` allows you to target a specific
|
||
* column, multiple columns, or all columns, using the `targets` property of
|
||
* each object in the array. This allows great flexibility when creating
|
||
* tables, as the `columnDefs` arrays can be of any length, targeting the
|
||
* columns you specifically want. `columnDefs` may use any of the column
|
||
* options available: {@link DataTable.defaults.column}, but it _must_
|
||
* have `targets` defined in each object in the array. Values in the `targets`
|
||
* array may be:
|
||
* <ul>
|
||
* <li>a string - class name will be matched on the TH for the column</li>
|
||
* <li>0 or a positive integer - column index counting from the left</li>
|
||
* <li>a negative integer - column index counting from the right</li>
|
||
* <li>the string "_all" - all columns (i.e. assign a default)</li>
|
||
* </ul>
|
||
* @member
|
||
*
|
||
* @name DataTable.defaults.columnDefs
|
||
*/
|
||
"aoColumnDefs": null,
|
||
|
||
|
||
/**
|
||
* Basically the same as `search`, this parameter defines the individual column
|
||
* filtering state at initialisation time. The array must be of the same size
|
||
* as the number of columns, and each element be an object with the parameters
|
||
* `search` and `escapeRegex` (the latter is optional). 'null' is also
|
||
* accepted and the default will be used.
|
||
* @type array
|
||
* @default []
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.searchCols
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "searchCols": [
|
||
* null,
|
||
* { "search": "My filter" },
|
||
* null,
|
||
* { "search": "^[0-9]", "escapeRegex": false }
|
||
* ]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"aoSearchCols": [],
|
||
|
||
|
||
/**
|
||
* An array of CSS classes that should be applied to displayed rows. This
|
||
* array may be of any length, and DataTables will apply each class
|
||
* sequentially, looping when required.
|
||
* @type array
|
||
* @default null <i>Will take the values determined by the `oClasses.stripe*`
|
||
* options</i>
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.stripeClasses
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"asStripeClasses": null,
|
||
|
||
|
||
/**
|
||
* Enable or disable automatic column width calculation. This can be disabled
|
||
* as an optimisation (it takes some time to calculate the widths) if the
|
||
* tables widths are passed in using `columns`.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.autoWidth
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "autoWidth": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bAutoWidth": true,
|
||
|
||
|
||
/**
|
||
* Deferred rendering can provide DataTables with a huge speed boost when you
|
||
* are using an Ajax or JS data source for the table. This option, when set to
|
||
* true, will cause DataTables to defer the creation of the table elements for
|
||
* each row until they are needed for a draw - saving a significant amount of
|
||
* time.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.deferRender
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajax": "sources/arrays.txt",
|
||
* "deferRender": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bDeferRender": false,
|
||
|
||
|
||
/**
|
||
* Replace a DataTable which matches the given selector and replace it with
|
||
* one which has the properties of the new initialisation object passed. If no
|
||
* table matches the selector, then the new DataTable will be constructed as
|
||
* per normal.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.destroy
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "srollY": "200px",
|
||
* "paginate": false
|
||
* } );
|
||
*
|
||
* // Some time later....
|
||
* $('#example').dataTable( {
|
||
* "filter": false,
|
||
* "destroy": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bDestroy": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable filtering of data. Filtering in DataTables is "smart" in
|
||
* that it allows the end user to input multiple words (space separated) and
|
||
* will match a row containing those words, even if not in the order that was
|
||
* specified (this allow matching across multiple columns). Note that if you
|
||
* wish to use filtering in DataTables this must remain 'true' - to remove the
|
||
* default filtering input box and retain filtering abilities, please use
|
||
* {@link DataTable.defaults.dom}.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.searching
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "searching": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bFilter": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the table information display. This shows information
|
||
* about the data that is currently visible on the page, including information
|
||
* about filtered data if that action is being performed.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.info
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "info": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bInfo": true,
|
||
|
||
|
||
/**
|
||
* Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
|
||
* slightly different and additional mark-up from what DataTables has
|
||
* traditionally used).
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.jQueryUI
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "jQueryUI": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bJQueryUI": false,
|
||
|
||
|
||
/**
|
||
* Allows the end user to select the size of a formatted page from a select
|
||
* menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.lengthChange
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "lengthChange": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bLengthChange": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable pagination.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.paging
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "paging": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bPaginate": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the display of a 'processing' indicator when the table is
|
||
* being processed (e.g. a sort). This is particularly useful for tables with
|
||
* large amounts of data where it can take a noticeable amount of time to sort
|
||
* the entries.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.processing
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "processing": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bProcessing": false,
|
||
|
||
|
||
/**
|
||
* Retrieve the DataTables object for the given selector. Note that if the
|
||
* table has already been initialised, this parameter will cause DataTables
|
||
* to simply return the object that has already been set up - it will not take
|
||
* account of any changes you might have made to the initialisation object
|
||
* passed to DataTables (setting this parameter to true is an acknowledgement
|
||
* that you understand this). `destroy` can be used to reinitialise a table if
|
||
* you need.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.retrieve
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* initTable();
|
||
* tableActions();
|
||
* } );
|
||
*
|
||
* function initTable ()
|
||
* {
|
||
* return $('#example').dataTable( {
|
||
* "scrollY": "200px",
|
||
* "paginate": false,
|
||
* "retrieve": true
|
||
* } );
|
||
* }
|
||
*
|
||
* function tableActions ()
|
||
* {
|
||
* var table = initTable();
|
||
* // perform API operations with oTable
|
||
* }
|
||
*/
|
||
"bRetrieve": false,
|
||
|
||
|
||
/**
|
||
* When vertical (y) scrolling is enabled, DataTables will force the height of
|
||
* the table's viewport to the given height at all times (useful for layout).
|
||
* However, this can look odd when filtering data down to a small data set,
|
||
* and the footer is left "floating" further down. This parameter (when
|
||
* enabled) will cause DataTables to collapse the table's viewport down when
|
||
* the result set will fit within the given Y height.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.scrollCollapse
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollY": "200",
|
||
* "scrollCollapse": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bScrollCollapse": false,
|
||
|
||
|
||
/**
|
||
* Configure DataTables to use server-side processing. Note that the
|
||
* `ajax` parameter must also be given in order to give DataTables a
|
||
* source to obtain the required data for each draw.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverSide
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "xhr.php"
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bServerSide": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable sorting of columns. Sorting of individual columns can be
|
||
* disabled by the `sortable` option for each column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.ordering
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "ordering": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSort": true,
|
||
|
||
|
||
/**
|
||
* Enable or display DataTables' ability to sort multiple columns at the
|
||
* same time (activated by shift-click by the user).
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.orderMulti
|
||
*
|
||
* @example
|
||
* // Disable multiple column sorting ability
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "orderMulti": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortMulti": true,
|
||
|
||
|
||
/**
|
||
* Allows control over whether DataTables should use the top (true) unique
|
||
* cell that is found for a single column, or the bottom (false - default).
|
||
* This is useful when using complex headers.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.orderCellsTop
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "orderCellsTop": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortCellsTop": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
|
||
* `sorting\_3` to the columns which are currently being sorted on. This is
|
||
* presented as a feature switch as it can increase processing time (while
|
||
* classes are removed and added) so for large data sets you might want to
|
||
* turn this off.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.orderClasses
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "orderClasses": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortClasses": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable state saving. When enabled HTML5 `localStorage` will be
|
||
* used to save table display information such as pagination information,
|
||
* display length, filtering and sorting. As such when the end user reloads
|
||
* the page the display display will match what thy had previously set up.
|
||
*
|
||
* Due to the use of `localStorage` the default state saving is not supported
|
||
* in IE6 or 7. If state saving is required in those browsers, use
|
||
* `stateSaveCallback` to provide a storage solution such as cookies.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.stateSave
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bStateSave": false,
|
||
|
||
|
||
/**
|
||
* This function is called when a TR element is created (and all TD child
|
||
* elements have been inserted), or registered if using a DOM source, allowing
|
||
* manipulation of the TR element (adding classes etc).
|
||
* @type function
|
||
* @param {node} row "TR" element for the current row
|
||
* @param {array} data Raw data array for this row
|
||
* @param {int} dataIndex The index of this row in the internal aoData array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.createdRow
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "createdRow": function( row, data, dataIndex ) {
|
||
* // Bold the grade for all 'A' grade browsers
|
||
* if ( data[4] == "A" )
|
||
* {
|
||
* $('td:eq(4)', row).html( '<b>A</b>' );
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnCreatedRow": null,
|
||
|
||
|
||
/**
|
||
* This function is called on every 'draw' event, and allows you to
|
||
* dynamically modify any aspect you want about the created DOM.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.drawCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "drawCallback": function( settings ) {
|
||
* alert( 'DataTables has redrawn the table' );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnDrawCallback": null,
|
||
|
||
|
||
/**
|
||
* Identical to fnHeaderCallback() but for the table footer this function
|
||
* allows you to modify the table footer on every 'draw' event.
|
||
* @type function
|
||
* @param {node} foot "TR" element for the footer
|
||
* @param {array} data Full table data (as derived from the original HTML)
|
||
* @param {int} start Index for the current display starting point in the
|
||
* display array
|
||
* @param {int} end Index for the current display ending point in the
|
||
* display array
|
||
* @param {array int} display Index array to translate the visual position
|
||
* to the full data array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.footerCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "footerCallback": function( tfoot, data, start, end, display ) {
|
||
* tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnFooterCallback": null,
|
||
|
||
|
||
/**
|
||
* When rendering large numbers in the information element for the table
|
||
* (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
|
||
* to have a comma separator for the 'thousands' units (e.g. 1 million is
|
||
* rendered as "1,000,000") to help readability for the end user. This
|
||
* function will override the default method DataTables uses.
|
||
* @type function
|
||
* @member
|
||
* @param {int} toFormat number to be formatted
|
||
* @returns {string} formatted string for DataTables to show the number
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.formatNumber
|
||
*
|
||
* @example
|
||
* // Format a number using a single quote for the separator (note that
|
||
* // this can also be done with the language.thousands option)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "formatNumber": function ( toFormat ) {
|
||
* return toFormat.toString().replace(
|
||
* /\B(?=(\d{3})+(?!\d))/g, "'"
|
||
* );
|
||
* };
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnFormatNumber": function ( toFormat ) {
|
||
return toFormat.toString().replace(
|
||
/\B(?=(\d{3})+(?!\d))/g,
|
||
this.oLanguage.sThousands
|
||
);
|
||
},
|
||
|
||
|
||
/**
|
||
* This function is called on every 'draw' event, and allows you to
|
||
* dynamically modify the header row. This can be used to calculate and
|
||
* display useful information about the table.
|
||
* @type function
|
||
* @param {node} head "TR" element for the header
|
||
* @param {array} data Full table data (as derived from the original HTML)
|
||
* @param {int} start Index for the current display starting point in the
|
||
* display array
|
||
* @param {int} end Index for the current display ending point in the
|
||
* display array
|
||
* @param {array int} display Index array to translate the visual position
|
||
* to the full data array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.headerCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "fheaderCallback": function( head, data, start, end, display ) {
|
||
* head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnHeaderCallback": null,
|
||
|
||
|
||
/**
|
||
* The information element can be used to convey information about the current
|
||
* state of the table. Although the internationalisation options presented by
|
||
* DataTables are quite capable of dealing with most customisations, there may
|
||
* be times where you wish to customise the string further. This callback
|
||
* allows you to do exactly that.
|
||
* @type function
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {int} start Starting position in data for the draw
|
||
* @param {int} end End position in data for the draw
|
||
* @param {int} max Total number of rows in the table (regardless of
|
||
* filtering)
|
||
* @param {int} total Total number of rows in the data set, after filtering
|
||
* @param {string} pre The string that DataTables has formatted using it's
|
||
* own rules
|
||
* @returns {string} The string to be displayed in the information element.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.infoCallback
|
||
*
|
||
* @example
|
||
* $('#example').dataTable( {
|
||
* "infoCallback": function( settings, start, end, max, total, pre ) {
|
||
* return start +" to "+ end;
|
||
* }
|
||
* } );
|
||
*/
|
||
"fnInfoCallback": null,
|
||
|
||
|
||
/**
|
||
* Called when the table has been initialised. Normally DataTables will
|
||
* initialise sequentially and there will be no need for this function,
|
||
* however, this does not hold true when using external language information
|
||
* since that is obtained using an async XHR call.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} json The JSON object request from the server - only
|
||
* present if client-side Ajax sourced data is used
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.initComplete
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "initComplete": function(settings, json) {
|
||
* alert( 'DataTables has finished its initialisation.' );
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnInitComplete": null,
|
||
|
||
|
||
/**
|
||
* Called at the very start of each table draw and can be used to cancel the
|
||
* draw by returning false, any other return (including undefined) results in
|
||
* the full draw occurring).
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @returns {boolean} False will cancel the draw, anything else (including no
|
||
* return) will allow it to complete.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.preDrawCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "preDrawCallback": function( settings ) {
|
||
* if ( $('#test').val() == 1 ) {
|
||
* return false;
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnPreDrawCallback": null,
|
||
|
||
|
||
/**
|
||
* This function allows you to 'post process' each row after it have been
|
||
* generated for each table draw, but before it is rendered on screen. This
|
||
* function might be used for setting the row class name etc.
|
||
* @type function
|
||
* @param {node} row "TR" element for the current row
|
||
* @param {array} data Raw data array for this row
|
||
* @param {int} displayIndex The display index for the current table draw
|
||
* @param {int} displayIndexFull The index of the data in the full list of
|
||
* rows (after filtering)
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.rowCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
|
||
* // Bold the grade for all 'A' grade browsers
|
||
* if ( data[4] == "A" ) {
|
||
* $('td:eq(4)', row).html( '<b>A</b>' );
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnRowCallback": null,
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* This parameter allows you to override the default function which obtains
|
||
* the data from the server so something more suitable for your application.
|
||
* For example you could use POST data, or pull information from a Gears or
|
||
* AIR database.
|
||
* @type function
|
||
* @member
|
||
* @param {string} source HTTP source to obtain the data from (`ajax`)
|
||
* @param {array} data A key/value pair object containing the data to send
|
||
* to the server
|
||
* @param {function} callback to be called on completion of the data get
|
||
* process that will draw the data on the page.
|
||
* @param {object} settings DataTables settings object
|
||
*
|
||
* @dtopt Callbacks
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverData
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"fnServerData": null,
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* It is often useful to send extra data to the server when making an Ajax
|
||
* request - for example custom filtering information, and this callback
|
||
* function makes it trivial to send extra information to the server. The
|
||
* passed in parameter is the data set that has been constructed by
|
||
* DataTables, and you can add to this or modify it as you require.
|
||
* @type function
|
||
* @param {array} data Data array (array of objects which are name/value
|
||
* pairs) that has been constructed by DataTables and will be sent to the
|
||
* server. In the case of Ajax sourced data with server-side processing
|
||
* this will be an empty array, for server-side processing there will be a
|
||
* significant number of parameters!
|
||
* @returns {undefined} Ensure that you modify the data array passed in,
|
||
* as this is passed by reference.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverParams
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"fnServerParams": null,
|
||
|
||
|
||
/**
|
||
* Load the table state. With this function you can define from where, and how, the
|
||
* state of a table is loaded. By default DataTables will load from `localStorage`
|
||
* but you might wish to use a server-side database or cookies.
|
||
* @type function
|
||
* @member
|
||
* @param {object} settings DataTables settings object
|
||
* @return {object} The DataTables state object to be loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoadCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadCallback": function (settings) {
|
||
* var o;
|
||
*
|
||
* // Send an Ajax request to the server to get the data. Note that
|
||
* // this is a synchronous request.
|
||
* $.ajax( {
|
||
* "url": "/state_load",
|
||
* "async": false,
|
||
* "dataType": "json",
|
||
* "success": function (json) {
|
||
* o = json;
|
||
* }
|
||
* } );
|
||
*
|
||
* return o;
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoadCallback": function ( settings ) {
|
||
try {
|
||
return JSON.parse(
|
||
(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
|
||
'DataTables_'+settings.sInstance+'_'+location.pathname
|
||
)
|
||
);
|
||
} catch (e) {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Callback which allows modification of the saved state prior to loading that state.
|
||
* This callback is called when the table is loading state from the stored data, but
|
||
* prior to the settings object being modified by the saved state. Note that for
|
||
* plug-in authors, you should use the `stateLoadParams` event to load parameters for
|
||
* a plug-in.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object that is to be loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoadParams
|
||
*
|
||
* @example
|
||
* // Remove a saved filter, so filtering is never loaded
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadParams": function (settings, data) {
|
||
* data.oSearch.sSearch = "";
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Disallow state loading by returning false
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadParams": function (settings, data) {
|
||
* return false;
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoadParams": null,
|
||
|
||
|
||
/**
|
||
* Callback that is called when the state has been loaded from the state saving method
|
||
* and the DataTables settings object has been modified as a result of the loaded state.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object that was loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoaded
|
||
*
|
||
* @example
|
||
* // Show an alert with the filtering value that was saved
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoaded": function (settings, data) {
|
||
* alert( 'Saved filter was: '+data.oSearch.sSearch );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoaded": null,
|
||
|
||
|
||
/**
|
||
* Save the table state. This function allows you to define where and how the state
|
||
* information for the table is stored By default DataTables will use `localStorage`
|
||
* but you might wish to use a server-side database or cookies.
|
||
* @type function
|
||
* @member
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object to be saved
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateSaveCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateSaveCallback": function (settings, data) {
|
||
* // Send an Ajax request to the server with the state object
|
||
* $.ajax( {
|
||
* "url": "/state_save",
|
||
* "data": data,
|
||
* "dataType": "json",
|
||
* "method": "POST"
|
||
* "success": function () {}
|
||
* } );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateSaveCallback": function ( settings, data ) {
|
||
try {
|
||
(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
|
||
'DataTables_'+settings.sInstance+'_'+location.pathname,
|
||
JSON.stringify( data )
|
||
);
|
||
} catch (e) {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Callback which allows modification of the state to be saved. Called when the table
|
||
* has changed state a new state save is required. This method allows modification of
|
||
* the state saving object prior to actually doing the save, including addition or
|
||
* other state properties or modification. Note that for plug-in authors, you should
|
||
* use the `stateSaveParams` event to save parameters for a plug-in.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object to be saved
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateSaveParams
|
||
*
|
||
* @example
|
||
* // Remove a saved filter, so filtering is never saved
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateSaveParams": function (settings, data) {
|
||
* data.oSearch.sSearch = "";
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateSaveParams": null,
|
||
|
||
|
||
/**
|
||
* Duration for which the saved state information is considered valid. After this period
|
||
* has elapsed the state will be returned to the default.
|
||
* Value is given in seconds.
|
||
* @type int
|
||
* @default 7200 <i>(2 hours)</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.stateDuration
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateDuration": 60*60*24; // 1 day
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iStateDuration": 7200,
|
||
|
||
|
||
/**
|
||
* When enabled DataTables will not make a request to the server for the first
|
||
* page draw - rather it will use the data already on the page (no sorting etc
|
||
* will be applied to it), thus saving on an XHR at load time. `deferLoading`
|
||
* is used to indicate that deferred loading is required, but it is also used
|
||
* to tell DataTables how many records there are in the full table (allowing
|
||
* the information element and pagination to be displayed correctly). In the case
|
||
* where a filtering is applied to the table on initial load, this can be
|
||
* indicated by giving the parameter as an array, where the first element is
|
||
* the number of records available after filtering and the second element is the
|
||
* number of records without filtering (allowing the table information element
|
||
* to be shown correctly).
|
||
* @type int | array
|
||
* @default null
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.deferLoading
|
||
*
|
||
* @example
|
||
* // 57 records available in the table, no filtering applied
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "scripts/server_processing.php",
|
||
* "deferLoading": 57
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // 57 records after filtering, 100 without filtering (an initial filter applied)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "scripts/server_processing.php",
|
||
* "deferLoading": [ 57, 100 ],
|
||
* "search": {
|
||
* "search": "my_filter"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"iDeferLoading": null,
|
||
|
||
|
||
/**
|
||
* Number of rows to display on a single page when using pagination. If
|
||
* feature enabled (`lengthChange`) then the end user will be able to override
|
||
* this to a custom setting using a pop-up menu.
|
||
* @type int
|
||
* @default 10
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.pageLength
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "pageLength": 50
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iDisplayLength": 10,
|
||
|
||
|
||
/**
|
||
* Define the starting point for data display when using DataTables with
|
||
* pagination. Note that this parameter is the number of records, rather than
|
||
* the page number, so if you have 10 records per page and want to start on
|
||
* the third page, it should be "20".
|
||
* @type int
|
||
* @default 0
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.displayStart
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "displayStart": 20
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iDisplayStart": 0,
|
||
|
||
|
||
/**
|
||
* By default DataTables allows keyboard navigation of the table (sorting, paging,
|
||
* and filtering) by adding a `tabindex` attribute to the required elements. This
|
||
* allows you to tab through the controls and press the enter key to activate them.
|
||
* The tabindex is default 0, meaning that the tab follows the flow of the document.
|
||
* You can overrule this using this parameter if you wish. Use a value of -1 to
|
||
* disable built-in keyboard navigation.
|
||
* @type int
|
||
* @default 0
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.tabIndex
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "tabIndex": 1
|
||
* } );
|
||
* } );
|
||
*/
|
||
"iTabIndex": 0,
|
||
|
||
|
||
/**
|
||
* Classes that DataTables assigns to the various components and features
|
||
* that it adds to the HTML table. This allows classes to be configured
|
||
* during initialisation in addition to through the static
|
||
* {@link DataTable.ext.oStdClasses} object).
|
||
* @namespace
|
||
* @name DataTable.defaults.classes
|
||
*/
|
||
"oClasses": {},
|
||
|
||
|
||
/**
|
||
* All strings that DataTables uses in the user interface that it creates
|
||
* are defined in this object, allowing you to modified them individually or
|
||
* completely replace them all as required.
|
||
* @namespace
|
||
* @name DataTable.defaults.language
|
||
*/
|
||
"oLanguage": {
|
||
/**
|
||
* Strings that are used for WAI-ARIA labels and controls only (these are not
|
||
* actually visible on the page, but will be read by screenreaders, and thus
|
||
* must be internationalised as well).
|
||
* @namespace
|
||
* @name DataTable.defaults.language.aria
|
||
*/
|
||
"oAria": {
|
||
/**
|
||
* ARIA label that is added to the table headers when the column may be
|
||
* sorted ascending by activing the column (click or return when focused).
|
||
* Note that the column header is prefixed to this string.
|
||
* @type string
|
||
* @default : activate to sort column ascending
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.aria.sortAscending
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "aria": {
|
||
* "sortAscending": " - click/return to sort ascending"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortAscending": ": activate to sort column ascending",
|
||
|
||
/**
|
||
* ARIA label that is added to the table headers when the column may be
|
||
* sorted descending by activing the column (click or return when focused).
|
||
* Note that the column header is prefixed to this string.
|
||
* @type string
|
||
* @default : activate to sort column ascending
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.aria.sortDescending
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "aria": {
|
||
* "sortDescending": " - click/return to sort descending"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortDescending": ": activate to sort column descending"
|
||
},
|
||
|
||
/**
|
||
* Pagination string used by DataTables for the built-in pagination
|
||
* control types.
|
||
* @namespace
|
||
* @name DataTable.defaults.language.paginate
|
||
*/
|
||
"oPaginate": {
|
||
/**
|
||
* Text to use when using the 'full_numbers' type of pagination for the
|
||
* button to take the user to the first page.
|
||
* @type string
|
||
* @default First
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.first
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "first": "First page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sFirst": "First",
|
||
|
||
|
||
/**
|
||
* Text to use when using the 'full_numbers' type of pagination for the
|
||
* button to take the user to the last page.
|
||
* @type string
|
||
* @default Last
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.last
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "last": "Last page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLast": "Last",
|
||
|
||
|
||
/**
|
||
* Text to use for the 'next' pagination button (to take the user to the
|
||
* next page).
|
||
* @type string
|
||
* @default Next
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.next
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "next": "Next page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sNext": "Next",
|
||
|
||
|
||
/**
|
||
* Text to use for the 'previous' pagination button (to take the user to
|
||
* the previous page).
|
||
* @type string
|
||
* @default Previous
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.previous
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "previous": "Previous page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sPrevious": "Previous"
|
||
},
|
||
|
||
/**
|
||
* This string is shown in preference to `zeroRecords` when the table is
|
||
* empty of data (regardless of filtering). Note that this is an optional
|
||
* parameter - if it is not given, the value of `zeroRecords` will be used
|
||
* instead (either the default or given value).
|
||
* @type string
|
||
* @default No data available in table
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.emptyTable
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "emptyTable": "No data available in table"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sEmptyTable": "No data available in table",
|
||
|
||
|
||
/**
|
||
* This string gives information to the end user about the information
|
||
* that is current on display on the page. The following tokens can be
|
||
* used in the string and will be dynamically replaced as the table
|
||
* display updates. This tokens can be placed anywhere in the string, or
|
||
* removed as needed by the language requires:
|
||
*
|
||
* * `\_START\_` - Display index of the first record on the current page
|
||
* * `\_END\_` - Display index of the last record on the current page
|
||
* * `\_TOTAL\_` - Number of records in the table after filtering
|
||
* * `\_MAX\_` - Number of records in the table without filtering
|
||
* * `\_PAGE\_` - Current page number
|
||
* * `\_PAGES\_` - Total number of pages of data in the table
|
||
*
|
||
* @type string
|
||
* @default Showing _START_ to _END_ of _TOTAL_ entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.info
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "info": "Showing page _PAGE_ of _PAGES_"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||
|
||
|
||
/**
|
||
* Display information string for when the table is empty. Typically the
|
||
* format of this string should match `info`.
|
||
* @type string
|
||
* @default Showing 0 to 0 of 0 entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoEmpty
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoEmpty": "No entries to show"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
|
||
|
||
|
||
/**
|
||
* When a user filters the information in a table, this string is appended
|
||
* to the information (`info`) to give an idea of how strong the filtering
|
||
* is. The variable _MAX_ is dynamically updated.
|
||
* @type string
|
||
* @default (filtered from _MAX_ total entries)
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoFiltered
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoFiltered": " - filtering from _MAX_ records"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoFiltered": "(filtered from _MAX_ total entries)",
|
||
|
||
|
||
/**
|
||
* If can be useful to append extra information to the info string at times,
|
||
* and this variable does exactly that. This information will be appended to
|
||
* the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
|
||
* being used) at all times.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoPostFix
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoPostFix": "All records shown are derived from real information."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoPostFix": "",
|
||
|
||
|
||
/**
|
||
* This decimal place operator is a little different from the other
|
||
* language options since DataTables doesn't output floating point
|
||
* numbers, so it won't ever use this for display of a number. Rather,
|
||
* what this parameter does is modify the sort methods of the table so
|
||
* that numbers which are in a format which has a character other than
|
||
* a period (`.`) as a decimal place will be sorted numerically.
|
||
*
|
||
* Note that numbers with different decimal places cannot be shown in
|
||
* the same table and still be sortable, the table must be consistent.
|
||
* However, multiple different tables on the page can use different
|
||
* decimal place characters.
|
||
* @type string
|
||
* @default
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.decimal
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "decimal": ","
|
||
* "thousands": "."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDecimal": "",
|
||
|
||
|
||
/**
|
||
* DataTables has a build in number formatter (`formatNumber`) which is
|
||
* used to format large numbers that are used in the table information.
|
||
* By default a comma is used, but this can be trivially changed to any
|
||
* character you wish with this parameter.
|
||
* @type string
|
||
* @default ,
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.thousands
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "thousands": "'"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sThousands": ",",
|
||
|
||
|
||
/**
|
||
* Detail the action that will be taken when the drop down menu for the
|
||
* pagination length option is changed. The '_MENU_' variable is replaced
|
||
* with a default select list of 10, 25, 50 and 100, and can be replaced
|
||
* with a custom select box if required.
|
||
* @type string
|
||
* @default Show _MENU_ entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.lengthMenu
|
||
*
|
||
* @example
|
||
* // Language change only
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "lengthMenu": "Display _MENU_ records"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Language and options change
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "lengthMenu": 'Display <select>'+
|
||
* '<option value="10">10</option>'+
|
||
* '<option value="20">20</option>'+
|
||
* '<option value="30">30</option>'+
|
||
* '<option value="40">40</option>'+
|
||
* '<option value="50">50</option>'+
|
||
* '<option value="-1">All</option>'+
|
||
* '</select> records'
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLengthMenu": "Show _MENU_ entries",
|
||
|
||
|
||
/**
|
||
* When using Ajax sourced data and during the first draw when DataTables is
|
||
* gathering the data, this message is shown in an empty row in the table to
|
||
* indicate to the end user the the data is being loaded. Note that this
|
||
* parameter is not used when loading data by server-side processing, just
|
||
* Ajax sourced data with client-side processing.
|
||
* @type string
|
||
* @default Loading...
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.loadingRecords
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "loadingRecords": "Please wait - loading..."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLoadingRecords": "Loading...",
|
||
|
||
|
||
/**
|
||
* Text which is displayed when the table is processing a user action
|
||
* (usually a sort command or similar).
|
||
* @type string
|
||
* @default Processing...
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.processing
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "processing": "DataTables is currently busy"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sProcessing": "Processing...",
|
||
|
||
|
||
/**
|
||
* Details the actions that will be taken when the user types into the
|
||
* filtering input text box. The variable "_INPUT_", if used in the string,
|
||
* is replaced with the HTML text box for the filtering input allowing
|
||
* control over where it appears in the string. If "_INPUT_" is not given
|
||
* then the input box is appended to the string automatically.
|
||
* @type string
|
||
* @default Search:
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.search
|
||
*
|
||
* @example
|
||
* // Input text box will be appended at the end automatically
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "search": "Filter records:"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Specify where the filter should appear
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "search": "Apply filter _INPUT_ to table"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSearch": "Search:",
|
||
|
||
|
||
/**
|
||
* All of the language information can be stored in a file on the
|
||
* server-side, which DataTables will look up if this parameter is passed.
|
||
* It must store the URL of the language file, which is in a JSON format,
|
||
* and the object has the same properties as the oLanguage object in the
|
||
* initialiser object (i.e. the above parameters). Please refer to one of
|
||
* the example language files to see how this works in action.
|
||
* @type string
|
||
* @default <i>Empty string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.url
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sUrl": "",
|
||
|
||
|
||
/**
|
||
* Text shown inside the table records when the is no information to be
|
||
* displayed after filtering. `emptyTable` is shown when there is simply no
|
||
* information in the table at all (regardless of filtering).
|
||
* @type string
|
||
* @default No matching records found
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.zeroRecords
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "zeroRecords": "No records to display"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sZeroRecords": "No matching records found"
|
||
},
|
||
|
||
|
||
/**
|
||
* This parameter allows you to have define the global filtering state at
|
||
* initialisation time. As an object the `search` parameter must be
|
||
* defined, but all other parameters are optional. When `regex` is true,
|
||
* the search string will be treated as a regular expression, when false
|
||
* (default) it will be treated as a straight string. When `smart`
|
||
* DataTables will use it's smart filtering methods (to word match at
|
||
* any point in the data), when false this will not be done.
|
||
* @namespace
|
||
* @extends DataTable.models.oSearch
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.search
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "search": {"search": "Initial search"}
|
||
* } );
|
||
* } )
|
||
*/
|
||
"oSearch": $.extend( {}, DataTable.models.oSearch ),
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* By default DataTables will look for the property `data` (or `aaData` for
|
||
* compatibility with DataTables 1.9-) when obtaining data from an Ajax
|
||
* source or for server-side processing - this parameter allows that
|
||
* property to be changed. You can use Javascript dotted object notation to
|
||
* get a data source for multiple levels of nesting.
|
||
* @type string
|
||
* @default data
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.ajaxDataProp
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sAjaxDataProp": "data",
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* You can instruct DataTables to load data from an external
|
||
* source using this parameter (use aData if you want to pass data in you
|
||
* already have). Simply provide a url a JSON object can be obtained from.
|
||
* @type string
|
||
* @default null
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.ajaxSource
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sAjaxSource": null,
|
||
|
||
|
||
/**
|
||
* This initialisation variable allows you to specify exactly where in the
|
||
* DOM you want DataTables to inject the various controls it adds to the page
|
||
* (for example you might want the pagination controls at the top of the
|
||
* table). DIV elements (with or without a custom class) can also be added to
|
||
* aid styling. The follow syntax is used:
|
||
* <ul>
|
||
* <li>The following options are allowed:
|
||
* <ul>
|
||
* <li>'l' - Length changing</li>
|
||
* <li>'f' - Filtering input</li>
|
||
* <li>'t' - The table!</li>
|
||
* <li>'i' - Information</li>
|
||
* <li>'p' - Pagination</li>
|
||
* <li>'r' - pRocessing</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>The following constants are allowed:
|
||
* <ul>
|
||
* <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
|
||
* <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>The following syntax is expected:
|
||
* <ul>
|
||
* <li>'<' and '>' - div elements</li>
|
||
* <li>'<"class" and '>' - div with a class</li>
|
||
* <li>'<"#id" and '>' - div with an ID</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>Examples:
|
||
* <ul>
|
||
* <li>'<"wrapper"flipt>'</li>
|
||
* <li>'<lf<t>ip>'</li>
|
||
* </ul>
|
||
* </li>
|
||
* </ul>
|
||
* @type string
|
||
* @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
|
||
* <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.dom
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "dom": '<"top"i>rt<"bottom"flp><"clear">'
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDom": "lfrtip",
|
||
|
||
|
||
/**
|
||
* DataTables features four different built-in options for the buttons to
|
||
* display for pagination control:
|
||
*
|
||
* * `simple` - 'Previous' and 'Next' buttons only
|
||
* * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
|
||
* * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
|
||
* * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
|
||
* page numbers
|
||
*
|
||
* Further methods can be added using {@link DataTable.ext.oPagination}.
|
||
* @type string
|
||
* @default simple_numbers
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.pagingType
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "pagingType": "full_numbers"
|
||
* } );
|
||
* } )
|
||
*/
|
||
"sPaginationType": "simple_numbers",
|
||
|
||
|
||
/**
|
||
* Enable horizontal scrolling. When a table is too wide to fit into a
|
||
* certain layout, or you have a large number of columns in the table, you
|
||
* can enable x-scrolling to show the table in a viewport, which can be
|
||
* scrolled. This property can be `true` which will allow the table to
|
||
* scroll horizontally when needed, or any CSS unit, or a number (in which
|
||
* case it will be treated as a pixel measurement). Setting as simply `true`
|
||
* is recommended.
|
||
* @type boolean|string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.scrollX
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollX": true,
|
||
* "scrollCollapse": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollX": "",
|
||
|
||
|
||
/**
|
||
* This property can be used to force a DataTable to use more width than it
|
||
* might otherwise do when x-scrolling is enabled. For example if you have a
|
||
* table which requires to be well spaced, this parameter is useful for
|
||
* "over-sizing" the table, and thus forcing scrolling. This property can by
|
||
* any CSS unit, or a number (in which case it will be treated as a pixel
|
||
* measurement).
|
||
* @type string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.scrollXInner
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollX": "100%",
|
||
* "scrollXInner": "110%"
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollXInner": "",
|
||
|
||
|
||
/**
|
||
* Enable vertical scrolling. Vertical scrolling will constrain the DataTable
|
||
* to the given height, and enable scrolling for any data which overflows the
|
||
* current viewport. This can be used as an alternative to paging to display
|
||
* a lot of data in a small area (although paging and scrolling can both be
|
||
* enabled at the same time). This property can be any CSS unit, or a number
|
||
* (in which case it will be treated as a pixel measurement).
|
||
* @type string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.scrollY
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollY": "200px",
|
||
* "paginate": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollY": "",
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* Set the HTTP method that is used to make the Ajax call for server-side
|
||
* processing or Ajax sourced data.
|
||
* @type string
|
||
* @default GET
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverMethod
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sServerMethod": "GET",
|
||
|
||
|
||
/**
|
||
* DataTables makes use of renderers when displaying HTML elements for
|
||
* a table. These renderers can be added or modified by plug-ins to
|
||
* generate suitable mark-up for a site. For example the Bootstrap
|
||
* integration plug-in for DataTables uses a paging button renderer to
|
||
* display pagination buttons in the mark-up required by Bootstrap.
|
||
*
|
||
* For further information about the renderers available see
|
||
* DataTable.ext.renderer
|
||
* @type string|object
|
||
* @default null
|
||
*
|
||
* @name DataTable.defaults.renderer
|
||
*
|
||
*/
|
||
"renderer": null
|
||
};
|
||
|
||
_fnHungarianMap( DataTable.defaults );
|
||
|
||
|
||
|
||
/*
|
||
* Developer note - See note in model.defaults.js about the use of Hungarian
|
||
* notation and camel case.
|
||
*/
|
||
|
||
/**
|
||
* Column options that can be given to DataTables at initialisation time.
|
||
* @namespace
|
||
*/
|
||
DataTable.defaults.column = {
|
||
/**
|
||
* Define which column(s) an order will occur on for this column. This
|
||
* allows a column's ordering to take multiple columns into account when
|
||
* doing a sort or use the data from a different column. For example first
|
||
* name / last name columns make sense to do a multi-column sort over the
|
||
* two columns.
|
||
* @type array|int
|
||
* @default null <i>Takes the value of the column index automatically</i>
|
||
*
|
||
* @name DataTable.defaults.column.orderData
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderData": [ 0, 1 ], "targets": [ 0 ] },
|
||
* { "orderData": [ 1, 0 ], "targets": [ 1 ] },
|
||
* { "orderData": 2, "targets": [ 2 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "orderData": [ 0, 1 ] },
|
||
* { "orderData": [ 1, 0 ] },
|
||
* { "orderData": 2 },
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aDataSort": null,
|
||
"iDataSort": -1,
|
||
|
||
|
||
/**
|
||
* You can control the default ordering direction, and even alter the
|
||
* behaviour of the sort handler (i.e. only allow ascending ordering etc)
|
||
* using this parameter.
|
||
* @type array
|
||
* @default [ 'asc', 'desc' ]
|
||
*
|
||
* @name DataTable.defaults.column.orderSequence
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderSequence": [ "asc" ], "targets": [ 1 ] },
|
||
* { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
|
||
* { "orderSequence": [ "desc" ], "targets": [ 3 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* { "orderSequence": [ "asc" ] },
|
||
* { "orderSequence": [ "desc", "asc", "asc" ] },
|
||
* { "orderSequence": [ "desc" ] },
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"asSorting": [ 'asc', 'desc' ],
|
||
|
||
|
||
/**
|
||
* Enable or disable filtering on the data in this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.searchable
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "searchable": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "searchable": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bSearchable": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable ordering on this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.orderable
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderable": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "orderable": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bSortable": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the display of this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.visible
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "visible": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "visible": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bVisible": true,
|
||
|
||
|
||
/**
|
||
* Developer definable function that is called whenever a cell is created (Ajax source,
|
||
* etc) or processed for input (DOM source). This can be used as a compliment to mRender
|
||
* allowing you to modify the DOM element (add background colour for example) when the
|
||
* element is available.
|
||
* @type function
|
||
* @param {element} td The TD node that has been created
|
||
* @param {*} cellData The Data for the cell
|
||
* @param {array|object} rowData The data for the whole row
|
||
* @param {int} row The row index for the aoData data store
|
||
* @param {int} col The column index for aoColumns
|
||
*
|
||
* @name DataTable.defaults.column.createdCell
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [3],
|
||
* "createdCell": function (td, cellData, rowData, row, col) {
|
||
* if ( cellData == "1.7" ) {
|
||
* $(td).css('color', 'blue')
|
||
* }
|
||
* }
|
||
* } ]
|
||
* });
|
||
* } );
|
||
*/
|
||
"fnCreatedCell": null,
|
||
|
||
|
||
/**
|
||
* This parameter has been replaced by `data` in DataTables to ensure naming
|
||
* consistency. `dataProp` can still be used, as there is backwards
|
||
* compatibility in DataTables for this option, but it is strongly
|
||
* recommended that you use `data` in preference to `dataProp`.
|
||
* @name DataTable.defaults.column.dataProp
|
||
*/
|
||
|
||
|
||
/**
|
||
* This property can be used to read data from any data source property,
|
||
* including deeply nested objects / properties. `data` can be given in a
|
||
* number of different ways which effect its behaviour:
|
||
*
|
||
* * `integer` - treated as an array index for the data source. This is the
|
||
* default that DataTables uses (incrementally increased for each column).
|
||
* * `string` - read an object property from the data source. There are
|
||
* three 'special' options that can be used in the string to alter how
|
||
* DataTables reads the data from the source object:
|
||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||
* Javascript to read from nested objects, so to can the options
|
||
* specified in `data`. For example: `browser.version` or
|
||
* `browser.name`. If your object parameter name contains a period, use
|
||
* `\\` to escape it - i.e. `first\\.name`.
|
||
* * `[]` - Array notation. DataTables can automatically combine data
|
||
* from and array source, joining the data with the characters provided
|
||
* between the two brackets. For example: `name[, ]` would provide a
|
||
* comma-space separated list from the source array. If no characters
|
||
* are provided between the brackets, the original array source is
|
||
* returned.
|
||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||
* execute a function of the name given. For example: `browser()` for a
|
||
* simple function on the data source, `browser.version()` for a
|
||
* function in a nested property or even `browser().version` to get an
|
||
* object property if the function called returns an object. Note that
|
||
* function notation is recommended for use in `render` rather than
|
||
* `data` as it is much simpler to use as a renderer.
|
||
* * `null` - use the original data source for the row rather than plucking
|
||
* data directly from it. This action has effects on two other
|
||
* initialisation options:
|
||
* * `defaultContent` - When null is given as the `data` option and
|
||
* `defaultContent` is specified for the column, the value defined by
|
||
* `defaultContent` will be used for the cell.
|
||
* * `render` - When null is used for the `data` option and the `render`
|
||
* option is specified for the column, the whole data source for the
|
||
* row is used for the renderer.
|
||
* * `function` - the function given will be executed whenever DataTables
|
||
* needs to set or get the data for a cell in the column. The function
|
||
* takes three parameters:
|
||
* * Parameters:
|
||
* * `{array|object}` The data source for the row
|
||
* * `{string}` The type call data requested - this will be 'set' when
|
||
* setting data or 'filter', 'display', 'type', 'sort' or undefined
|
||
* when gathering data. Note that when `undefined` is given for the
|
||
* type DataTables expects to get the raw data for the object back<
|
||
* * `{*}` Data to set when the second parameter is 'set'.
|
||
* * Return:
|
||
* * The return value from the function is not required when 'set' is
|
||
* the type of call, but otherwise the return is what will be used
|
||
* for the data requested.
|
||
*
|
||
* Note that `data` is a getter and setter option. If you just require
|
||
* formatting of data for output, you will likely want to use `render` which
|
||
* is simply a getter and thus simpler to use.
|
||
*
|
||
* Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
|
||
* name change reflects the flexibility of this property and is consistent
|
||
* with the naming of mRender. If 'mDataProp' is given, then it will still
|
||
* be used by DataTables, as it automatically maps the old name to the new
|
||
* if required.
|
||
*
|
||
* @type string|int|function|null
|
||
* @default null <i>Use automatically calculated column index</i>
|
||
*
|
||
* @name DataTable.defaults.column.data
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Read table data from objects
|
||
* // JSON structure for each row:
|
||
* // {
|
||
* // "engine": {value},
|
||
* // "browser": {value},
|
||
* // "platform": {value},
|
||
* // "version": {value},
|
||
* // "grade": {value}
|
||
* // }
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/objects.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* { "data": "platform" },
|
||
* { "data": "version" },
|
||
* { "data": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Read information from deeply nested objects
|
||
* // JSON structure for each row:
|
||
* // {
|
||
* // "engine": {value},
|
||
* // "browser": {value},
|
||
* // "platform": {
|
||
* // "inner": {value}
|
||
* // },
|
||
* // "details": [
|
||
* // {value}, {value}
|
||
* // ]
|
||
* // }
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/deep.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* { "data": "platform.inner" },
|
||
* { "data": "platform.details.0" },
|
||
* { "data": "platform.details.1" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `data` as a function to provide different information for
|
||
* // sorting, filtering and display. In this case, currency (price)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": function ( source, type, val ) {
|
||
* if (type === 'set') {
|
||
* source.price = val;
|
||
* // Store the computed dislay and filter values for efficiency
|
||
* source.price_display = val=="" ? "" : "$"+numberFormat(val);
|
||
* source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
|
||
* return;
|
||
* }
|
||
* else if (type === 'display') {
|
||
* return source.price_display;
|
||
* }
|
||
* else if (type === 'filter') {
|
||
* return source.price_filter;
|
||
* }
|
||
* // 'sort', 'type' and undefined all just use the integer
|
||
* return source.price;
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using default content
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null,
|
||
* "defaultContent": "Click to edit"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using array notation - outputting a list from an array
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": "name[, ]"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
*/
|
||
"mData": null,
|
||
|
||
|
||
/**
|
||
* This property is the rendering partner to `data` and it is suggested that
|
||
* when you want to manipulate data for display (including filtering,
|
||
* sorting etc) without altering the underlying data for the table, use this
|
||
* property. `render` can be considered to be the the read only companion to
|
||
* `data` which is read / write (then as such more complex). Like `data`
|
||
* this option can be given in a number of different ways to effect its
|
||
* behaviour:
|
||
*
|
||
* * `integer` - treated as an array index for the data source. This is the
|
||
* default that DataTables uses (incrementally increased for each column).
|
||
* * `string` - read an object property from the data source. There are
|
||
* three 'special' options that can be used in the string to alter how
|
||
* DataTables reads the data from the source object:
|
||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||
* Javascript to read from nested objects, so to can the options
|
||
* specified in `data`. For example: `browser.version` or
|
||
* `browser.name`. If your object parameter name contains a period, use
|
||
* `\\` to escape it - i.e. `first\\.name`.
|
||
* * `[]` - Array notation. DataTables can automatically combine data
|
||
* from and array source, joining the data with the characters provided
|
||
* between the two brackets. For example: `name[, ]` would provide a
|
||
* comma-space separated list from the source array. If no characters
|
||
* are provided between the brackets, the original array source is
|
||
* returned.
|
||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||
* execute a function of the name given. For example: `browser()` for a
|
||
* simple function on the data source, `browser.version()` for a
|
||
* function in a nested property or even `browser().version` to get an
|
||
* object property if the function called returns an object.
|
||
* * `object` - use different data for the different data types requested by
|
||
* DataTables ('filter', 'display', 'type' or 'sort'). The property names
|
||
* of the object is the data type the property refers to and the value can
|
||
* defined using an integer, string or function using the same rules as
|
||
* `render` normally does. Note that an `_` option _must_ be specified.
|
||
* This is the default value to use if you haven't specified a value for
|
||
* the data type requested by DataTables.
|
||
* * `function` - the function given will be executed whenever DataTables
|
||
* needs to set or get the data for a cell in the column. The function
|
||
* takes three parameters:
|
||
* * Parameters:
|
||
* * {array|object} The data source for the row (based on `data`)
|
||
* * {string} The type call data requested - this will be 'filter',
|
||
* 'display', 'type' or 'sort'.
|
||
* * {array|object} The full data source for the row (not based on
|
||
* `data`)
|
||
* * Return:
|
||
* * The return value from the function is what will be used for the
|
||
* data requested.
|
||
*
|
||
* @type string|int|function|object|null
|
||
* @default null Use the data source value.
|
||
*
|
||
* @name DataTable.defaults.column.render
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Create a comma separated list from an array of objects
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/deep.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* {
|
||
* "data": "platform",
|
||
* "render": "[, ].name"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Execute a function to obtain data
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null, // Use the full data source object for the renderer's source
|
||
* "render": "browserName()"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // As an object, extracting different data for the different types
|
||
* // This would be used with a data source such as:
|
||
* // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
|
||
* // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
|
||
* // (which has both forms) is used for filtering for if a user inputs either format, while
|
||
* // the formatted phone number is the one that is shown in the table.
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null, // Use the full data source object for the renderer's source
|
||
* "render": {
|
||
* "_": "phone",
|
||
* "filter": "phone_filter",
|
||
* "display": "phone_display"
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Use as a function to create a link from the data source
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": "download_link",
|
||
* "render": function ( data, type, full ) {
|
||
* return '<a href="'+data+'">Download</a>';
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"mRender": null,
|
||
|
||
|
||
/**
|
||
* Change the cell type created for the column - either TD cells or TH cells. This
|
||
* can be useful as TH cells have semantic meaning in the table body, allowing them
|
||
* to act as a header for a row (you may wish to add scope='row' to the TH elements).
|
||
* @type string
|
||
* @default td
|
||
*
|
||
* @name DataTable.defaults.column.cellType
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Make the first column use TH cells
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "cellType": "th"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sCellType": "td",
|
||
|
||
|
||
/**
|
||
* Class to give to each cell in this column.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @name DataTable.defaults.column.class
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "class": "my_class", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "class": "my_class" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sClass": "",
|
||
|
||
/**
|
||
* When DataTables calculates the column widths to assign to each column,
|
||
* it finds the longest string in each column and then constructs a
|
||
* temporary table and reads the widths from that. The problem with this
|
||
* is that "mmm" is much wider then "iiii", but the latter is a longer
|
||
* string - thus the calculation can go wrong (doing it properly and putting
|
||
* it into an DOM object and measuring that is horribly(!) slow). Thus as
|
||
* a "work around" we provide this option. It will append its value to the
|
||
* text that is found to be the longest string for the column - i.e. padding.
|
||
* Generally you shouldn't need this!
|
||
* @type string
|
||
* @default <i>Empty string<i>
|
||
*
|
||
* @name DataTable.defaults.column.contentPadding
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* {
|
||
* "contentPadding": "mmm"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sContentPadding": "",
|
||
|
||
|
||
/**
|
||
* Allows a default value to be given for a column's data, and will be used
|
||
* whenever a null data source is encountered (this can be because `data`
|
||
* is set to null, or because the data source itself is null).
|
||
* @type string
|
||
* @default null
|
||
*
|
||
* @name DataTable.defaults.column.defaultContent
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* {
|
||
* "data": null,
|
||
* "defaultContent": "Edit",
|
||
* "targets": [ -1 ]
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* {
|
||
* "data": null,
|
||
* "defaultContent": "Edit"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDefaultContent": null,
|
||
|
||
|
||
/**
|
||
* This parameter is only used in DataTables' server-side processing. It can
|
||
* be exceptionally useful to know what columns are being displayed on the
|
||
* client side, and to map these to database fields. When defined, the names
|
||
* also allow DataTables to reorder information from the server if it comes
|
||
* back in an unexpected order (i.e. if you switch your columns around on the
|
||
* client-side, your server-side code does not also need updating).
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @name DataTable.defaults.column.name
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "name": "engine", "targets": [ 0 ] },
|
||
* { "name": "browser", "targets": [ 1 ] },
|
||
* { "name": "platform", "targets": [ 2 ] },
|
||
* { "name": "version", "targets": [ 3 ] },
|
||
* { "name": "grade", "targets": [ 4 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "name": "engine" },
|
||
* { "name": "browser" },
|
||
* { "name": "platform" },
|
||
* { "name": "version" },
|
||
* { "name": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sName": "",
|
||
|
||
|
||
/**
|
||
* Defines a data source type for the ordering which can be used to read
|
||
* real-time information from the table (updating the internally cached
|
||
* version) prior to ordering. This allows ordering to occur on user
|
||
* editable elements such as form inputs.
|
||
* @type string
|
||
* @default std
|
||
*
|
||
* @name DataTable.defaults.column.orderDataType
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
|
||
* { "type": "numeric", "targets": [ 3 ] },
|
||
* { "orderDataType": "dom-select", "targets": [ 4 ] },
|
||
* { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* { "orderDataType": "dom-text" },
|
||
* { "orderDataType": "dom-text", "type": "numeric" },
|
||
* { "orderDataType": "dom-select" },
|
||
* { "orderDataType": "dom-checkbox" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortDataType": "std",
|
||
|
||
|
||
/**
|
||
* The title of this column.
|
||
* @type string
|
||
* @default null <i>Derived from the 'TH' value for this column in the
|
||
* original HTML table.</i>
|
||
*
|
||
* @name DataTable.defaults.column.title
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "title": "My column title", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "title": "My column title" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sTitle": null,
|
||
|
||
|
||
/**
|
||
* The type allows you to specify how the data for this column will be
|
||
* ordered. Four types (string, numeric, date and html (which will strip
|
||
* HTML tags before ordering)) are currently available. Note that only date
|
||
* formats understood by Javascript's Date() object will be accepted as type
|
||
* date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
|
||
* 'numeric', 'date' or 'html' (by default). Further types can be adding
|
||
* through plug-ins.
|
||
* @type string
|
||
* @default null <i>Auto-detected from raw data</i>
|
||
*
|
||
* @name DataTable.defaults.column.type
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "type": "html", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "type": "html" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sType": null,
|
||
|
||
|
||
/**
|
||
* Defining the width of the column, this parameter may take any CSS value
|
||
* (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
|
||
* been given a specific width through this interface ensuring that the table
|
||
* remains readable.
|
||
* @type string
|
||
* @default null <i>Automatic</i>
|
||
*
|
||
* @name DataTable.defaults.column.width
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "width": "20%", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "width": "20%" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sWidth": null
|
||
};
|
||
|
||
_fnHungarianMap( DataTable.defaults.column );
|
||
|
||
|
||
|
||
/**
|
||
* DataTables settings object - this holds all the information needed for a
|
||
* given table, including configuration, data and current application of the
|
||
* table options. DataTables does not have a single instance for each DataTable
|
||
* with the settings attached to that instance, but rather instances of the
|
||
* DataTable "class" are created on-the-fly as needed (typically by a
|
||
* $().dataTable() call) and the settings object is then applied to that
|
||
* instance.
|
||
*
|
||
* Note that this object is related to {@link DataTable.defaults} but this
|
||
* one is the internal data store for DataTables's cache of columns. It should
|
||
* NOT be manipulated outside of DataTables. Any configuration should be done
|
||
* through the initialisation options.
|
||
* @namespace
|
||
* @todo Really should attach the settings object to individual instances so we
|
||
* don't need to create new instances on each $().dataTable() call (if the
|
||
* table already exists). It would also save passing oSettings around and
|
||
* into every single function. However, this is a very significant
|
||
* architecture change for DataTables and will almost certainly break
|
||
* backwards compatibility with older installations. This is something that
|
||
* will be done in 2.0.
|
||
*/
|
||
DataTable.models.oSettings = {
|
||
/**
|
||
* Primary features of DataTables and their enablement state.
|
||
* @namespace
|
||
*/
|
||
"oFeatures": {
|
||
|
||
/**
|
||
* Flag to say if DataTables should automatically try to calculate the
|
||
* optimum table and columns widths (true) or not (false).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bAutoWidth": null,
|
||
|
||
/**
|
||
* Delay the creation of TR and TD elements until they are actually
|
||
* needed by a driven page draw. This can give a significant speed
|
||
* increase for Ajax source and Javascript source data, but makes no
|
||
* difference at all fro DOM and server-side processing tables.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bDeferRender": null,
|
||
|
||
/**
|
||
* Enable filtering on the table or not. Note that if this is disabled
|
||
* then there is no filtering at all on the table, including fnFilter.
|
||
* To just remove the filtering input use sDom and remove the 'f' option.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bFilter": null,
|
||
|
||
/**
|
||
* Table information element (the 'Showing x of y records' div) enable
|
||
* flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bInfo": null,
|
||
|
||
/**
|
||
* Present a user control allowing the end user to change the page size
|
||
* when pagination is enabled.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bLengthChange": null,
|
||
|
||
/**
|
||
* Pagination enabled or not. Note that if this is disabled then length
|
||
* changing must also be disabled.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bPaginate": null,
|
||
|
||
/**
|
||
* Processing indicator enable flag whenever DataTables is enacting a
|
||
* user request - typically an Ajax request for server-side processing.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bProcessing": null,
|
||
|
||
/**
|
||
* Server-side processing enabled flag - when enabled DataTables will
|
||
* get all data from the server for every draw - there is no filtering,
|
||
* sorting or paging done on the client-side.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bServerSide": null,
|
||
|
||
/**
|
||
* Sorting enablement flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSort": null,
|
||
|
||
/**
|
||
* Multi-column sorting
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortMulti": null,
|
||
|
||
/**
|
||
* Apply a class to the columns which are being sorted to provide a
|
||
* visual highlight or not. This can slow things down when enabled since
|
||
* there is a lot of DOM interaction.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortClasses": null,
|
||
|
||
/**
|
||
* State saving enablement flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bStateSave": null
|
||
},
|
||
|
||
|
||
/**
|
||
* Scrolling settings for a table.
|
||
* @namespace
|
||
*/
|
||
"oScroll": {
|
||
/**
|
||
* When the table is shorter in height than sScrollY, collapse the
|
||
* table container down to the height of the table (when true).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bCollapse": null,
|
||
|
||
/**
|
||
* Width of the scrollbar for the web-browser's platform. Calculated
|
||
* during table initialisation.
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iBarWidth": 0,
|
||
|
||
/**
|
||
* Viewport width for horizontal scrolling. Horizontal scrolling is
|
||
* disabled if an empty string.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sX": null,
|
||
|
||
/**
|
||
* Width to expand the table to when using x-scrolling. Typically you
|
||
* should not need to use this.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @deprecated
|
||
*/
|
||
"sXInner": null,
|
||
|
||
/**
|
||
* Viewport height for vertical scrolling. Vertical scrolling is disabled
|
||
* if an empty string.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sY": null
|
||
},
|
||
|
||
/**
|
||
* Language information for the table.
|
||
* @namespace
|
||
* @extends DataTable.defaults.oLanguage
|
||
*/
|
||
"oLanguage": {
|
||
/**
|
||
* Information callback function. See
|
||
* {@link DataTable.defaults.fnInfoCallback}
|
||
* @type function
|
||
* @default null
|
||
*/
|
||
"fnInfoCallback": null
|
||
},
|
||
|
||
/**
|
||
* Browser support parameters
|
||
* @namespace
|
||
*/
|
||
"oBrowser": {
|
||
/**
|
||
* Indicate if the browser incorrectly calculates width:100% inside a
|
||
* scrolling element (IE6/7)
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bScrollOversize": false,
|
||
|
||
/**
|
||
* Determine if the vertical scrollbar is on the right or left of the
|
||
* scrolling container - needed for rtl language layout, although not
|
||
* all browsers move the scrollbar (Safari).
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bScrollbarLeft": false
|
||
},
|
||
|
||
|
||
"ajax": null,
|
||
|
||
|
||
/**
|
||
* Array referencing the nodes which are used for the features. The
|
||
* parameters of this object match what is allowed by sDom - i.e.
|
||
* <ul>
|
||
* <li>'l' - Length changing</li>
|
||
* <li>'f' - Filtering input</li>
|
||
* <li>'t' - The table!</li>
|
||
* <li>'i' - Information</li>
|
||
* <li>'p' - Pagination</li>
|
||
* <li>'r' - pRocessing</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aanFeatures": [],
|
||
|
||
/**
|
||
* Store data information - see {@link DataTable.models.oRow} for detailed
|
||
* information.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoData": [],
|
||
|
||
/**
|
||
* Array of indexes which are in the current display (after filtering etc)
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aiDisplay": [],
|
||
|
||
/**
|
||
* Array of indexes for display - no filtering
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aiDisplayMaster": [],
|
||
|
||
/**
|
||
* Store information about each column that is in use
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoColumns": [],
|
||
|
||
/**
|
||
* Store information about the table's header
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoHeader": [],
|
||
|
||
/**
|
||
* Store information about the table's footer
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoFooter": [],
|
||
|
||
/**
|
||
* Store the applied global search information in case we want to force a
|
||
* research or compare the old search to a new one.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @namespace
|
||
* @extends DataTable.models.oSearch
|
||
*/
|
||
"oPreviousSearch": {},
|
||
|
||
/**
|
||
* Store the applied search for each column - see
|
||
* {@link DataTable.models.oSearch} for the format that is used for the
|
||
* filtering information for each column.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoPreSearchCols": [],
|
||
|
||
/**
|
||
* Sorting that is applied to the table. Note that the inner arrays are
|
||
* used in the following manner:
|
||
* <ul>
|
||
* <li>Index 0 - column number</li>
|
||
* <li>Index 1 - current sorting direction</li>
|
||
* </ul>
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @todo These inner arrays should really be objects
|
||
*/
|
||
"aaSorting": null,
|
||
|
||
/**
|
||
* Sorting that is always applied to the table (i.e. prefixed in front of
|
||
* aaSorting).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aaSortingFixed": [],
|
||
|
||
/**
|
||
* Classes to use for the striping of a table.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"asStripeClasses": null,
|
||
|
||
/**
|
||
* If restoring a table - we should restore its striping classes as well
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"asDestroyStripes": [],
|
||
|
||
/**
|
||
* If restoring a table - we should restore its width
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"sDestroyWidth": 0,
|
||
|
||
/**
|
||
* Callback functions array for every time a row is inserted (i.e. on a draw).
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoRowCallback": [],
|
||
|
||
/**
|
||
* Callback functions for the header on each draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoHeaderCallback": [],
|
||
|
||
/**
|
||
* Callback function for the footer on each draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoFooterCallback": [],
|
||
|
||
/**
|
||
* Array of callback functions for draw callback functions
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoDrawCallback": [],
|
||
|
||
/**
|
||
* Array of callback functions for row created function
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoRowCreatedCallback": [],
|
||
|
||
/**
|
||
* Callback functions for just before the table is redrawn. A return of
|
||
* false will be used to cancel the draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoPreDrawCallback": [],
|
||
|
||
/**
|
||
* Callback functions for when the table has been initialised.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoInitComplete": [],
|
||
|
||
|
||
/**
|
||
* Callbacks for modifying the settings to be stored for state saving, prior to
|
||
* saving state.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateSaveParams": [],
|
||
|
||
/**
|
||
* Callbacks for modifying the settings that have been stored for state saving
|
||
* prior to using the stored values to restore the state.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoadParams": [],
|
||
|
||
/**
|
||
* Callbacks for operating on the settings object once the saved state has been
|
||
* loaded
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoaded": [],
|
||
|
||
/**
|
||
* Cache the table ID for quick access
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*/
|
||
"sTableId": "",
|
||
|
||
/**
|
||
* The TABLE node for the main table
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTable": null,
|
||
|
||
/**
|
||
* Permanent ref to the thead element
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTHead": null,
|
||
|
||
/**
|
||
* Permanent ref to the tfoot element - if it exists
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTFoot": null,
|
||
|
||
/**
|
||
* Permanent ref to the tbody element
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTBody": null,
|
||
|
||
/**
|
||
* Cache the wrapper node (contains all DataTables controlled elements)
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTableWrapper": null,
|
||
|
||
/**
|
||
* Indicate if when using server-side processing the loading of data
|
||
* should be deferred until the second draw.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bDeferLoading": false,
|
||
|
||
/**
|
||
* Indicate if all required information has been read in
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bInitialised": false,
|
||
|
||
/**
|
||
* Information about open rows. Each object in the array has the parameters
|
||
* 'nTr' and 'nParent'
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoOpenRows": [],
|
||
|
||
/**
|
||
* Dictate the positioning of DataTables' control elements - see
|
||
* {@link DataTable.model.oInit.sDom}.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sDom": null,
|
||
|
||
/**
|
||
* Which type of pagination should be used.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default two_button
|
||
*/
|
||
"sPaginationType": "two_button",
|
||
|
||
/**
|
||
* The state duration (for `stateSave`) in seconds.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iStateDuration": 0,
|
||
|
||
/**
|
||
* Array of callback functions for state saving. Each array element is an
|
||
* object with the following parameters:
|
||
* <ul>
|
||
* <li>function:fn - function to call. Takes two parameters, oSettings
|
||
* and the JSON string to save that has been thus far created. Returns
|
||
* a JSON string to be inserted into a json object
|
||
* (i.e. '"param": [ 0, 1, 2]')</li>
|
||
* <li>string:sName - name of callback</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateSave": [],
|
||
|
||
/**
|
||
* Array of callback functions for state loading. Each array element is an
|
||
* object with the following parameters:
|
||
* <ul>
|
||
* <li>function:fn - function to call. Takes two parameters, oSettings
|
||
* and the object stored. May return false to cancel state loading</li>
|
||
* <li>string:sName - name of callback</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoad": [],
|
||
|
||
/**
|
||
* State that was loaded. Useful for back reference
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oLoadedState": null,
|
||
|
||
/**
|
||
* Source url for AJAX data for the table.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sAjaxSource": null,
|
||
|
||
/**
|
||
* Property from a given object from which to read the table data from. This
|
||
* can be an empty string (when not server-side processing), in which case
|
||
* it is assumed an an array is given directly.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sAjaxDataProp": null,
|
||
|
||
/**
|
||
* Note if draw should be blocked while getting data
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bAjaxDataGet": true,
|
||
|
||
/**
|
||
* The last jQuery XHR object that was used for server-side data gathering.
|
||
* This can be used for working with the XHR information in one of the
|
||
* callbacks
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"jqXHR": null,
|
||
|
||
/**
|
||
* JSON returned from the server in the last Ajax request
|
||
* @type object
|
||
* @default undefined
|
||
*/
|
||
"json": undefined,
|
||
|
||
/**
|
||
* Data submitted as part of the last Ajax request
|
||
* @type object
|
||
* @default undefined
|
||
*/
|
||
"oAjaxData": undefined,
|
||
|
||
/**
|
||
* Function to get the server-side data.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type function
|
||
*/
|
||
"fnServerData": null,
|
||
|
||
/**
|
||
* Functions which are called prior to sending an Ajax request so extra
|
||
* parameters can easily be sent to the server
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoServerParams": [],
|
||
|
||
/**
|
||
* Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
|
||
* required).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sServerMethod": null,
|
||
|
||
/**
|
||
* Format numbers for display.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type function
|
||
*/
|
||
"fnFormatNumber": null,
|
||
|
||
/**
|
||
* List of options that can be used for the user selectable length menu.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aLengthMenu": null,
|
||
|
||
/**
|
||
* Counter for the draws that the table does. Also used as a tracker for
|
||
* server-side processing
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iDraw": 0,
|
||
|
||
/**
|
||
* Indicate if a redraw is being done - useful for Ajax
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bDrawing": false,
|
||
|
||
/**
|
||
* Draw index (iDraw) of the last error when parsing the returned data
|
||
* @type int
|
||
* @default -1
|
||
*/
|
||
"iDrawError": -1,
|
||
|
||
/**
|
||
* Paging display length
|
||
* @type int
|
||
* @default 10
|
||
*/
|
||
"_iDisplayLength": 10,
|
||
|
||
/**
|
||
* Paging start point - aiDisplay index
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"_iDisplayStart": 0,
|
||
|
||
/**
|
||
* Server-side processing - number of records in the result set
|
||
* (i.e. before filtering), Use fnRecordsTotal rather than
|
||
* this property to get the value of the number of records, regardless of
|
||
* the server-side processing setting.
|
||
* @type int
|
||
* @default 0
|
||
* @private
|
||
*/
|
||
"_iRecordsTotal": 0,
|
||
|
||
/**
|
||
* Server-side processing - number of records in the current display set
|
||
* (i.e. after filtering). Use fnRecordsDisplay rather than
|
||
* this property to get the value of the number of records, regardless of
|
||
* the server-side processing setting.
|
||
* @type boolean
|
||
* @default 0
|
||
* @private
|
||
*/
|
||
"_iRecordsDisplay": 0,
|
||
|
||
/**
|
||
* Flag to indicate if jQuery UI marking and classes should be used.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bJUI": null,
|
||
|
||
/**
|
||
* The classes to use for the table
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
"oClasses": {},
|
||
|
||
/**
|
||
* Flag attached to the settings object so you can check in the draw
|
||
* callback if filtering has been done in the draw. Deprecated in favour of
|
||
* events.
|
||
* @type boolean
|
||
* @default false
|
||
* @deprecated
|
||
*/
|
||
"bFiltered": false,
|
||
|
||
/**
|
||
* Flag attached to the settings object so you can check in the draw
|
||
* callback if sorting has been done in the draw. Deprecated in favour of
|
||
* events.
|
||
* @type boolean
|
||
* @default false
|
||
* @deprecated
|
||
*/
|
||
"bSorted": false,
|
||
|
||
/**
|
||
* Indicate that if multiple rows are in the header and there is more than
|
||
* one unique cell per column, if the top one (true) or bottom one (false)
|
||
* should be used for sorting / title by DataTables.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortCellsTop": null,
|
||
|
||
/**
|
||
* Initialisation object that is used for the table
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oInit": null,
|
||
|
||
/**
|
||
* Destroy callback functions - for plug-ins to attach themselves to the
|
||
* destroy so they can clean up markup and events.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoDestroyCallback": [],
|
||
|
||
|
||
/**
|
||
* Get the number of records in the current record set, before filtering
|
||
* @type function
|
||
*/
|
||
"fnRecordsTotal": function ()
|
||
{
|
||
return _fnDataSource( this ) == 'ssp' ?
|
||
this._iRecordsTotal * 1 :
|
||
this.aiDisplayMaster.length;
|
||
},
|
||
|
||
/**
|
||
* Get the number of records in the current record set, after filtering
|
||
* @type function
|
||
*/
|
||
"fnRecordsDisplay": function ()
|
||
{
|
||
return _fnDataSource( this ) == 'ssp' ?
|
||
this._iRecordsDisplay * 1 :
|
||
this.aiDisplay.length;
|
||
},
|
||
|
||
/**
|
||
* Get the display end point - aiDisplay index
|
||
* @type function
|
||
*/
|
||
"fnDisplayEnd": function ()
|
||
{
|
||
var
|
||
len = this._iDisplayLength,
|
||
start = this._iDisplayStart,
|
||
calc = start + len,
|
||
records = this.aiDisplay.length,
|
||
features = this.oFeatures,
|
||
paginate = features.bPaginate;
|
||
|
||
if ( features.bServerSide ) {
|
||
return paginate === false || len === -1 ?
|
||
start + records :
|
||
Math.min( start+len, this._iRecordsDisplay );
|
||
}
|
||
else {
|
||
return ! paginate || calc>records || len===-1 ?
|
||
records :
|
||
calc;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* The DataTables object for this table
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oInstance": null,
|
||
|
||
/**
|
||
* Unique identifier for each instance of the DataTables object. If there
|
||
* is an ID on the table node, then it takes that value, otherwise an
|
||
* incrementing internal counter is used.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sInstance": null,
|
||
|
||
/**
|
||
* tabindex attribute value that is added to DataTables control elements, allowing
|
||
* keyboard navigation of the table and its controls.
|
||
*/
|
||
"iTabIndex": 0,
|
||
|
||
/**
|
||
* DIV container for the footer scrolling table if scrolling
|
||
*/
|
||
"nScrollHead": null,
|
||
|
||
/**
|
||
* DIV container for the footer scrolling table if scrolling
|
||
*/
|
||
"nScrollFoot": null,
|
||
|
||
/**
|
||
* Last applied sort
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aLastSort": [],
|
||
|
||
/**
|
||
* Stored plug-in instances
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
"oPlugins": {}
|
||
};
|
||
|
||
/**
|
||
* Extension object for DataTables that is used to provide all extension
|
||
* options.
|
||
*
|
||
* Note that the `DataTable.ext` object is available through
|
||
* `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
|
||
* also aliased to `jQuery.fn.dataTableExt` for historic reasons.
|
||
* @namespace
|
||
* @extends DataTable.models.ext
|
||
*/
|
||
|
||
|
||
/**
|
||
* DataTables extensions
|
||
*
|
||
* This namespace acts as a collection area for plug-ins that can be used to
|
||
* extend DataTables capabilities. Indeed many of the build in methods
|
||
* use this method to provide their own capabilities (sorting methods for
|
||
* example).
|
||
*
|
||
* Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
|
||
* reasons
|
||
*
|
||
* @namespace
|
||
*/
|
||
DataTable.ext = _ext = {
|
||
/**
|
||
* Element class names
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
classes: {},
|
||
|
||
|
||
/**
|
||
* Error reporting.
|
||
*
|
||
* How should DataTables report an error. Can take the value 'alert' or
|
||
* 'throw'
|
||
*
|
||
* @type string
|
||
* @default alert
|
||
*/
|
||
errMode: "alert",
|
||
|
||
|
||
/**
|
||
* Feature plug-ins.
|
||
*
|
||
* This is an array of objects which describe the feature plug-ins that are
|
||
* available to DataTables. These feature plug-ins are then available for
|
||
* use through the `dom` initialisation option.
|
||
*
|
||
* Each feature plug-in is described by an object which must have the
|
||
* following properties:
|
||
*
|
||
* * `fnInit` - function that is used to initialise the plug-in,
|
||
* * `cFeature` - a character so the feature can be enabled by the `dom`
|
||
* instillation option. This is case sensitive.
|
||
*
|
||
* The `fnInit` function has the following input parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
*
|
||
* And the following return is expected:
|
||
*
|
||
* * {node|null} The element which contains your feature. Note that the
|
||
* return may also be void if your plug-in does not require to inject any
|
||
* DOM elements into DataTables control (`dom`) - for example this might
|
||
* be useful when developing a plug-in which allows table control via
|
||
* keyboard entry
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* $.fn.dataTable.ext.features.push( {
|
||
* "fnInit": function( oSettings ) {
|
||
* return new TableTools( { "oDTSettings": oSettings } );
|
||
* },
|
||
* "cFeature": "T"
|
||
* } );
|
||
*/
|
||
feature: [],
|
||
|
||
|
||
/**
|
||
* Row searching.
|
||
*
|
||
* This method of searching is complimentary to the default type based
|
||
* searching, and a lot more comprehensive as it allows you complete control
|
||
* over the searching logic. Each element in this array is a function
|
||
* (parameters described below) that is called for every row in the table,
|
||
* and your logic decides if it should be included in the searching data set
|
||
* or not.
|
||
*
|
||
* Searching functions have the following input parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
* 2. `{array|object}` Data for the row to be processed (same as the
|
||
* original format that was passed in as the data source, or an array
|
||
* from a DOM data source
|
||
* 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
|
||
* can be useful to retrieve the `TR` element if you need DOM interaction.
|
||
*
|
||
* And the following return is expected:
|
||
*
|
||
* * {boolean} Include the row in the searched result set (true) or not
|
||
* (false)
|
||
*
|
||
* Note that as with the main search ability in DataTables, technically this
|
||
* is "filtering", since it is subtractive. However, for consistency in
|
||
* naming we call it searching here.
|
||
*
|
||
* @type array
|
||
* @default []
|
||
*
|
||
* @example
|
||
* // The following example shows custom search being applied to the
|
||
* // fourth column (i.e. the data[3] index) based on two input values
|
||
* // from the end-user, matching the data in a certain range.
|
||
* $.fn.dataTable.ext.search.push(
|
||
* function( settings, data, dataIndex ) {
|
||
* var min = document.getElementById('min').value * 1;
|
||
* var max = document.getElementById('max').value * 1;
|
||
* var version = data[3] == "-" ? 0 : data[3]*1;
|
||
*
|
||
* if ( min == "" && max == "" ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min == "" && version < max ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min < version && "" == max ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min < version && version < max ) {
|
||
* return true;
|
||
* }
|
||
* return false;
|
||
* }
|
||
* );
|
||
*/
|
||
search: [],
|
||
|
||
|
||
/**
|
||
* Internal functions, exposed for used in plug-ins.
|
||
*
|
||
* Please note that you should not need to use the internal methods for
|
||
* anything other than a plug-in (and even then, try to avoid if possible).
|
||
* The internal function may change between releases.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
internal: {},
|
||
|
||
|
||
/**
|
||
* Legacy configuration options. Enable and disable legacy options that
|
||
* are available in DataTables.
|
||
*
|
||
* @type object
|
||
*/
|
||
legacy: {
|
||
/**
|
||
* Enable / disable DataTables 1.9 compatible server-side processing
|
||
* requests
|
||
*
|
||
* @type boolean
|
||
* @default null
|
||
*/
|
||
ajax: null
|
||
},
|
||
|
||
|
||
/**
|
||
* Pagination plug-in methods.
|
||
*
|
||
* Each entry in this object is a function and defines which buttons should
|
||
* be shown by the pagination rendering method that is used for the table:
|
||
* {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
|
||
* buttons are displayed in the document, while the functions here tell it
|
||
* what buttons to display. This is done by returning an array of button
|
||
* descriptions (what each button will do).
|
||
*
|
||
* Pagination types (the four built in options and any additional plug-in
|
||
* options defined here) can be used through the `paginationType`
|
||
* initialisation parameter.
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{int} page` The current page index
|
||
* 2. `{int} pages` The number of pages in the table
|
||
*
|
||
* Each function is expected to return an array where each element of the
|
||
* array can be one of:
|
||
*
|
||
* * `first` - Jump to first page when activated
|
||
* * `last` - Jump to last page when activated
|
||
* * `previous` - Show previous page when activated
|
||
* * `next` - Show next page when activated
|
||
* * `{int}` - Show page of the index given
|
||
* * `{array}` - A nested array containing the above elements to add a
|
||
* containing 'DIV' element (might be useful for styling).
|
||
*
|
||
* Note that DataTables v1.9- used this object slightly differently whereby
|
||
* an object with two functions would be defined for each plug-in. That
|
||
* ability is still supported by DataTables 1.10+ to provide backwards
|
||
* compatibility, but this option of use is now decremented and no longer
|
||
* documented in DataTables 1.10+.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* // Show previous, next and current page buttons only
|
||
* $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
|
||
* return [ 'previous', page, 'next' ];
|
||
* };
|
||
*/
|
||
pager: {},
|
||
|
||
|
||
renderer: {
|
||
pageButton: {},
|
||
header: {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Ordering plug-ins - custom data source
|
||
*
|
||
* The extension options for ordering of data available here is complimentary
|
||
* to the default type based ordering that DataTables typically uses. It
|
||
* allows much greater control over the the data that is being used to
|
||
* order a column, but is necessarily therefore more complex.
|
||
*
|
||
* This type of ordering is useful if you want to do ordering based on data
|
||
* live from the DOM (for example the contents of an 'input' element) rather
|
||
* than just the static string that DataTables knows of.
|
||
*
|
||
* The way these plug-ins work is that you create an array of the values you
|
||
* wish to be ordering for the column in question and then return that
|
||
* array. The data in the array much be in the index order of the rows in
|
||
* the table (not the currently ordering order!). Which order data gathering
|
||
* function is run here depends on the `dt-init columns.orderDataType`
|
||
* parameter that is used for the column (if any).
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
* 2. `{int}` Target column index
|
||
*
|
||
* Each function is expected to return an array:
|
||
*
|
||
* * `{array}` Data for the column to be ordering upon
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* // Ordering using `input` node values
|
||
* $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
|
||
* {
|
||
* return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
|
||
* return $('input', td).val();
|
||
* } );
|
||
* }
|
||
*/
|
||
order: {},
|
||
|
||
|
||
/**
|
||
* Type based plug-ins.
|
||
*
|
||
* Each column in DataTables has a type assigned to it, either by automatic
|
||
* detection or by direct assignment using the `type` option for the column.
|
||
* The type of a column will effect how it is ordering and search (plug-ins
|
||
* can also make use of the column type if required).
|
||
*
|
||
* @namespace
|
||
*/
|
||
type: {
|
||
/**
|
||
* Type detection functions.
|
||
*
|
||
* The functions defined in this object are used to automatically detect
|
||
* a column's type, making initialisation of DataTables super easy, even
|
||
* when complex data is in the table.
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be analysed
|
||
* 2. `{settings}` DataTables settings object. This can be used to
|
||
* perform context specific type detection - for example detection
|
||
* based on language settings such as using a comma for a decimal
|
||
* place. Generally speaking the options from the settings will not
|
||
* be required
|
||
*
|
||
* Each function is expected to return:
|
||
*
|
||
* * `{string|null}` Data type detected, or null if unknown (and thus
|
||
* pass it on to the other type detection functions.
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* // Currency type detection plug-in:
|
||
* $.fn.dataTable.ext.type.detect.push(
|
||
* function ( data, settings ) {
|
||
* // Check the numeric part
|
||
* if ( ! $.isNumeric( data.substring(1) ) ) {
|
||
* return null;
|
||
* }
|
||
*
|
||
* // Check prefixed by currency
|
||
* if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {
|
||
* return 'currency';
|
||
* }
|
||
* return null;
|
||
* }
|
||
* );
|
||
*/
|
||
detect: [],
|
||
|
||
|
||
/**
|
||
* Type based search formatting.
|
||
*
|
||
* The type based searching functions can be used to pre-format the
|
||
* data to be search on. For example, it can be used to strip HTML
|
||
* tags or to de-format telephone numbers for numeric only searching.
|
||
*
|
||
* Note that is a search is not defined for a column of a given type,
|
||
* no search formatting will be performed.
|
||
*
|
||
* Pre-processing of searching data plug-ins - When you assign the sType
|
||
* for a column (or have it automatically detected for you by DataTables
|
||
* or a type detection plug-in), you will typically be using this for
|
||
* custom sorting, but it can also be used to provide custom searching
|
||
* by allowing you to pre-processing the data and returning the data in
|
||
* the format that should be searched upon. This is done by adding
|
||
* functions this object with a parameter name which matches the sType
|
||
* for that target column. This is the corollary of <i>afnSortData</i>
|
||
* for searching data.
|
||
*
|
||
* The functions defined take a single parameter:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be prepared for searching
|
||
*
|
||
* Each function is expected to return:
|
||
*
|
||
* * `{string|null}` Formatted string that will be used for the searching.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
|
||
* return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
|
||
* }
|
||
*/
|
||
search: {},
|
||
|
||
|
||
/**
|
||
* Type based ordering.
|
||
*
|
||
* The column type tells DataTables what ordering to apply to the table
|
||
* when a column is sorted upon. The order for each type that is defined,
|
||
* is defined by the functions available in this object.
|
||
*
|
||
* Each ordering option can be described by three properties added to
|
||
* this object:
|
||
*
|
||
* * `{type}-pre` - Pre-formatting function
|
||
* * `{type}-asc` - Ascending order function
|
||
* * `{type}-desc` - Descending order function
|
||
*
|
||
* All three can be used together, only `{type}-pre` or only
|
||
* `{type}-asc` and `{type}-desc` together. It is generally recommended
|
||
* that only `{type}-pre` is used, as this provides the optimal
|
||
* implementation in terms of speed, although the others are provided
|
||
* for compatibility with existing Javascript sort functions.
|
||
*
|
||
* `{type}-pre`: Functions defined take a single parameter:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be prepared for ordering
|
||
*
|
||
* And return:
|
||
*
|
||
* * `{*}` Data to be sorted upon
|
||
*
|
||
* `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
|
||
* functions, taking two parameters:
|
||
*
|
||
* 1. `{*}` Data to compare to the second parameter
|
||
* 2. `{*}` Data to compare to the first parameter
|
||
*
|
||
* And returning:
|
||
*
|
||
* * `{*}` Ordering match: <0 if first parameter should be sorted lower
|
||
* than the second parameter, ===0 if the two parameters are equal and
|
||
* >0 if the first parameter should be sorted height than the second
|
||
* parameter.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* // Numeric ordering of formatted numbers with a pre-formatter
|
||
* $.extend( $.fn.dataTable.ext.type.order, {
|
||
* "string-pre": function(x) {
|
||
* a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
|
||
* return parseFloat( a );
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Case-sensitive string ordering, with no pre-formatting method
|
||
* $.extend( $.fn.dataTable.ext.order, {
|
||
* "string-case-asc": function(x,y) {
|
||
* return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||
* },
|
||
* "string-case-desc": function(x,y) {
|
||
* return ((x < y) ? 1 : ((x > y) ? -1 : 0));
|
||
* }
|
||
* } );
|
||
*/
|
||
order: {}
|
||
},
|
||
|
||
/**
|
||
* Unique DataTables instance counter
|
||
*
|
||
* @type int
|
||
* @private
|
||
*/
|
||
_unique: 0,
|
||
|
||
|
||
//
|
||
// Depreciated
|
||
// The following properties are retained for backwards compatiblity only.
|
||
// The should not be used in new projects and will be removed in a future
|
||
// version
|
||
//
|
||
|
||
/**
|
||
* Version check function.
|
||
* @type function
|
||
* @depreciated Since 1.10
|
||
*/
|
||
fnVersionCheck: DataTable.fnVersionCheck,
|
||
|
||
|
||
/**
|
||
* Index for what 'this' index API functions should use
|
||
* @type int
|
||
* @deprecated Since v1.10
|
||
*/
|
||
iApiIndex: 0,
|
||
|
||
|
||
/**
|
||
* jQuery UI class container
|
||
* @type object
|
||
* @deprecated Since v1.10
|
||
*/
|
||
oJUIClasses: {},
|
||
|
||
|
||
/**
|
||
* Software version
|
||
* @type string
|
||
* @deprecated Since v1.10
|
||
*/
|
||
sVersion: DataTable.version
|
||
};
|
||
|
||
|
||
//
|
||
// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
|
||
//
|
||
$.extend( _ext, {
|
||
afnFiltering: _ext.search,
|
||
aTypes: _ext.type.detect,
|
||
ofnSearch: _ext.type.search,
|
||
oSort: _ext.type.order,
|
||
afnSortData: _ext.order,
|
||
aoFeatures: _ext.feature,
|
||
oApi: _ext.internal,
|
||
oStdClasses: _ext.classes,
|
||
oPagination: _ext.pager
|
||
} );
|
||
|
||
|
||
$.extend( DataTable.ext.classes, {
|
||
"sTable": "dataTable",
|
||
"sNoFooter": "no-footer",
|
||
|
||
/* Paging buttons */
|
||
"sPageButton": "paginate_button",
|
||
"sPageButtonActive": "current",
|
||
"sPageButtonDisabled": "disabled",
|
||
|
||
/* Striping classes */
|
||
"sStripeOdd": "odd",
|
||
"sStripeEven": "even",
|
||
|
||
/* Empty row */
|
||
"sRowEmpty": "dataTables_empty",
|
||
|
||
/* Features */
|
||
"sWrapper": "dataTables_wrapper",
|
||
"sFilter": "dataTables_filter",
|
||
"sInfo": "dataTables_info",
|
||
"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
|
||
"sLength": "dataTables_length",
|
||
"sProcessing": "dataTables_processing",
|
||
|
||
/* Sorting */
|
||
"sSortAsc": "sorting_asc",
|
||
"sSortDesc": "sorting_desc",
|
||
"sSortable": "sorting", /* Sortable in both directions */
|
||
"sSortableAsc": "sorting_asc_disabled",
|
||
"sSortableDesc": "sorting_desc_disabled",
|
||
"sSortableNone": "sorting_disabled",
|
||
"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
|
||
|
||
/* Filtering */
|
||
"sFilterInput": "",
|
||
|
||
/* Page length */
|
||
"sLengthSelect": "",
|
||
|
||
/* Scrolling */
|
||
"sScrollWrapper": "dataTables_scroll",
|
||
"sScrollHead": "dataTables_scrollHead",
|
||
"sScrollHeadInner": "dataTables_scrollHeadInner",
|
||
"sScrollBody": "dataTables_scrollBody",
|
||
"sScrollFoot": "dataTables_scrollFoot",
|
||
"sScrollFootInner": "dataTables_scrollFootInner",
|
||
|
||
/* Misc */
|
||
"sHeaderTH": "",
|
||
"sFooterTH": "",
|
||
|
||
// Deprecated
|
||
"sSortJUIAsc": "",
|
||
"sSortJUIDesc": "",
|
||
"sSortJUI": "",
|
||
"sSortJUIAscAllowed": "",
|
||
"sSortJUIDescAllowed": "",
|
||
"sSortJUIWrapper": "",
|
||
"sSortIcon": "",
|
||
"sJUIHeader": "",
|
||
"sJUIFooter": ""
|
||
} );
|
||
|
||
|
||
(function() {
|
||
|
||
// Reused strings for better compression. Closure compiler appears to have a
|
||
// weird edge case where it is trying to expand strings rather than use the
|
||
// variable version. This results in about 200 bytes being added, for very
|
||
// little preference benefit since it this run on script load only.
|
||
var _empty = '';
|
||
_empty = '';
|
||
|
||
var _stateDefault = _empty + 'ui-state-default';
|
||
var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
|
||
var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
|
||
|
||
$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
|
||
/* Full numbers paging buttons */
|
||
"sPageButton": "fg-button ui-button "+_stateDefault,
|
||
"sPageButtonActive": "ui-state-disabled",
|
||
"sPageButtonDisabled": "ui-state-disabled",
|
||
|
||
/* Features */
|
||
"sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
|
||
"ui-buttonset-multi paging_", /* Note that the type is postfixed */
|
||
|
||
/* Sorting */
|
||
"sSortAsc": _stateDefault+" sorting_asc",
|
||
"sSortDesc": _stateDefault+" sorting_desc",
|
||
"sSortable": _stateDefault+" sorting",
|
||
"sSortableAsc": _stateDefault+" sorting_asc_disabled",
|
||
"sSortableDesc": _stateDefault+" sorting_desc_disabled",
|
||
"sSortableNone": _stateDefault+" sorting_disabled",
|
||
"sSortJUIAsc": _sortIcon+"triangle-1-n",
|
||
"sSortJUIDesc": _sortIcon+"triangle-1-s",
|
||
"sSortJUI": _sortIcon+"carat-2-n-s",
|
||
"sSortJUIAscAllowed": _sortIcon+"carat-1-n",
|
||
"sSortJUIDescAllowed": _sortIcon+"carat-1-s",
|
||
"sSortJUIWrapper": "DataTables_sort_wrapper",
|
||
"sSortIcon": "DataTables_sort_icon",
|
||
|
||
/* Scrolling */
|
||
"sScrollHead": "dataTables_scrollHead "+_stateDefault,
|
||
"sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
|
||
|
||
/* Misc */
|
||
"sHeaderTH": _stateDefault,
|
||
"sFooterTH": _stateDefault,
|
||
"sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
|
||
"sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
|
||
} );
|
||
|
||
}());
|
||
|
||
|
||
|
||
var extPagination = DataTable.ext.pager;
|
||
|
||
function _numbers ( page, pages ) {
|
||
var
|
||
numbers = [],
|
||
buttons = extPagination.numbers_length,
|
||
half = Math.floor( buttons / 2 ),
|
||
i = 1;
|
||
|
||
if ( pages <= buttons ) {
|
||
numbers = _range( 0, pages );
|
||
}
|
||
else if ( page <= half ) {
|
||
numbers = _range( 0, buttons-2 );
|
||
numbers.push( 'ellipsis' );
|
||
numbers.push( pages-1 );
|
||
}
|
||
else if ( page >= pages - 1 - half ) {
|
||
numbers = _range( pages-(buttons-2), pages );
|
||
numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
|
||
numbers.splice( 0, 0, 0 );
|
||
}
|
||
else {
|
||
numbers = _range( page-1, page+2 );
|
||
numbers.push( 'ellipsis' );
|
||
numbers.push( pages-1 );
|
||
numbers.splice( 0, 0, 'ellipsis' );
|
||
numbers.splice( 0, 0, 0 );
|
||
}
|
||
|
||
numbers.DT_el = 'span';
|
||
return numbers;
|
||
}
|
||
|
||
|
||
$.extend( extPagination, {
|
||
simple: function ( page, pages ) {
|
||
return [ 'previous', 'next' ];
|
||
},
|
||
|
||
full: function ( page, pages ) {
|
||
return [ 'first', 'previous', 'next', 'last' ];
|
||
},
|
||
|
||
simple_numbers: function ( page, pages ) {
|
||
return [ 'previous', _numbers(page, pages), 'next' ];
|
||
},
|
||
|
||
full_numbers: function ( page, pages ) {
|
||
return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
|
||
},
|
||
|
||
// For testing and plug-ins to use
|
||
_numbers: _numbers,
|
||
numbers_length: 7
|
||
} );
|
||
|
||
|
||
$.extend( true, DataTable.ext.renderer, {
|
||
pageButton: {
|
||
_: function ( settings, host, idx, buttons, page, pages ) {
|
||
var classes = settings.oClasses;
|
||
var lang = settings.oLanguage.oPaginate;
|
||
var btnDisplay, btnClass, counter=0;
|
||
|
||
var attach = function( container, buttons ) {
|
||
var i, ien, node, button;
|
||
var clickHandler = function ( e ) {
|
||
_fnPageChange( settings, e.data.action, true );
|
||
};
|
||
|
||
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
|
||
button = buttons[i];
|
||
|
||
if ( $.isArray( button ) ) {
|
||
var inner = $( '<'+(button.DT_el || 'div')+'/>' )
|
||
.appendTo( container );
|
||
attach( inner, button );
|
||
}
|
||
else {
|
||
btnDisplay = '';
|
||
btnClass = '';
|
||
|
||
switch ( button ) {
|
||
case 'ellipsis':
|
||
container.append('<span>…</span>');
|
||
break;
|
||
|
||
case 'first':
|
||
btnDisplay = lang.sFirst;
|
||
btnClass = button + (page > 0 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'previous':
|
||
btnDisplay = lang.sPrevious;
|
||
btnClass = button + (page > 0 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'next':
|
||
btnDisplay = lang.sNext;
|
||
btnClass = button + (page < pages-1 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'last':
|
||
btnDisplay = lang.sLast;
|
||
btnClass = button + (page < pages-1 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
default:
|
||
btnDisplay = button + 1;
|
||
btnClass = page === button ?
|
||
classes.sPageButtonActive : '';
|
||
break;
|
||
}
|
||
|
||
if ( btnDisplay ) {
|
||
node = $('<a>', {
|
||
'class': classes.sPageButton+' '+btnClass,
|
||
'aria-controls': settings.sTableId,
|
||
'data-dt-idx': counter,
|
||
'tabindex': settings.iTabIndex,
|
||
'id': idx === 0 && typeof button === 'string' ?
|
||
settings.sTableId +'_'+ button :
|
||
null
|
||
} )
|
||
.html( btnDisplay )
|
||
.appendTo( container );
|
||
|
||
_fnBindAction(
|
||
node, {action: button}, clickHandler
|
||
);
|
||
|
||
counter++;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Because this approach is destroying and recreating the paging
|
||
// elements, focus is lost on the select button which is bad for
|
||
// accessibility. So we want to restore focus once the draw has
|
||
// completed
|
||
var activeEl = $(document.activeElement).data('dt-idx');
|
||
|
||
attach( $(host).empty(), buttons );
|
||
|
||
if ( activeEl !== null ) {
|
||
$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
|
||
if ( !d || d === '-' ) {
|
||
return -Infinity;
|
||
}
|
||
|
||
// If a decimal place other than `.` is used, it needs to be given to the
|
||
// function so we can detect it and replace with a `.` which is the only
|
||
// decimal place Javascript recognises - it is not locale aware.
|
||
if ( decimalPlace ) {
|
||
d = _numToDecimal( d, decimalPlace );
|
||
}
|
||
|
||
if ( d.replace ) {
|
||
if ( re1 ) {
|
||
d = d.replace( re1, '' );
|
||
}
|
||
|
||
if ( re2 ) {
|
||
d = d.replace( re2, '' );
|
||
}
|
||
}
|
||
|
||
return d * 1;
|
||
};
|
||
|
||
|
||
// Add the numeric 'deformatting' functions for sorting. This is done in a
|
||
// function to provide an easy ability for the language options to add
|
||
// additional methods if a non-period decimal place is used.
|
||
function _addNumericSort ( decimalPlace ) {
|
||
$.each(
|
||
{
|
||
// Plain numbers
|
||
"num": function ( d ) {
|
||
return __numericReplace( d, decimalPlace );
|
||
},
|
||
|
||
// Formatted numbers
|
||
"num-fmt": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_formatted_numeric );
|
||
},
|
||
|
||
// HTML numeric
|
||
"html-num": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_html );
|
||
},
|
||
|
||
// HTML numeric, formatted
|
||
"html-num-fmt": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
|
||
}
|
||
},
|
||
function ( key, fn ) {
|
||
_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
|
||
}
|
||
);
|
||
}
|
||
|
||
|
||
// Default sort methods
|
||
$.extend( _ext.type.order, {
|
||
// Dates
|
||
"date-pre": function ( d ) {
|
||
return Date.parse( d ) || 0;
|
||
},
|
||
|
||
// html
|
||
"html-pre": function ( a ) {
|
||
return ! a ?
|
||
'' :
|
||
a.replace ?
|
||
a.replace( /<.*?>/g, "" ).toLowerCase() :
|
||
a+'';
|
||
},
|
||
|
||
// string
|
||
"string-pre": function ( a ) {
|
||
return typeof a === 'string' ?
|
||
a.toLowerCase() :
|
||
! a || ! a.toString ?
|
||
'' :
|
||
a.toString();
|
||
},
|
||
|
||
// string-asc and -desc are retained only for compatibility with the old
|
||
// sort methods
|
||
"string-asc": function ( x, y ) {
|
||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||
},
|
||
|
||
"string-desc": function ( x, y ) {
|
||
return ((x < y) ? 1 : ((x > y) ? -1 : 0));
|
||
}
|
||
} );
|
||
|
||
|
||
// Numeric sorting types - order doesn't matter here
|
||
_addNumericSort( '' );
|
||
|
||
|
||
// Built in type detection. See model.ext.aTypes for information about
|
||
// what is required from this methods.
|
||
$.extend( DataTable.ext.type.detect, [
|
||
// Plain numbers - first since V8 detects some plain numbers as dates
|
||
// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _isNumber( d, decimal ) ? 'num'+decimal : null;
|
||
},
|
||
|
||
// Dates (only those recognised by the browser's Date.parse)
|
||
function ( d, settings )
|
||
{
|
||
// V8 will remove any unknown characters at the start of the expression,
|
||
// leading to false matches such as `$245.12` being a valid date. See
|
||
// forum thread 18941 for detail.
|
||
if ( d && ! _re_date_start.test(d) ) {
|
||
return null;
|
||
}
|
||
var parsed = Date.parse(d);
|
||
return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
|
||
},
|
||
|
||
// Formatted numbers
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
|
||
},
|
||
|
||
// HTML numeric
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
|
||
},
|
||
|
||
// HTML numeric, formatted
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
|
||
},
|
||
|
||
// HTML (this is strict checking - there must be html)
|
||
function ( d, settings )
|
||
{
|
||
return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
|
||
'html' : null;
|
||
}
|
||
] );
|
||
|
||
|
||
|
||
// Filter formatting functions. See model.ext.ofnSearch for information about
|
||
// what is required from these methods.
|
||
|
||
|
||
$.extend( DataTable.ext.type.search, {
|
||
html: function ( data ) {
|
||
return _empty(data) ?
|
||
'' :
|
||
typeof data === 'string' ?
|
||
data
|
||
.replace( _re_new_lines, " " )
|
||
.replace( _re_html, "" ) :
|
||
'';
|
||
},
|
||
|
||
string: function ( data ) {
|
||
return _empty(data) ?
|
||
'' :
|
||
typeof data === 'string' ?
|
||
data.replace( _re_new_lines, " " ) :
|
||
data;
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
$.extend( true, DataTable.ext.renderer, {
|
||
header: {
|
||
_: function ( settings, cell, column, classes ) {
|
||
// No additional mark-up required
|
||
// Attach a sort listener to update on sort - note that using the
|
||
// `DT` namespace will allow the event to be removed automatically
|
||
// on destroy, while the `dt` namespaced event is the one we are
|
||
// listening for
|
||
$(settings.nTable).on( 'order.dt.DT', function ( e, settings, sorting, columns ) {
|
||
var colIdx = column.idx;
|
||
|
||
cell
|
||
.removeClass(
|
||
column.sSortingClass +' '+
|
||
classes.sSortAsc +' '+
|
||
classes.sSortDesc
|
||
)
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortDesc :
|
||
column.sSortingClass
|
||
);
|
||
} );
|
||
},
|
||
|
||
jqueryui: function ( settings, cell, column, classes ) {
|
||
var colIdx = column.idx;
|
||
|
||
$('<div/>')
|
||
.addClass( classes.sSortJUIWrapper )
|
||
.append( cell.contents() )
|
||
.append( $('<span/>')
|
||
.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
|
||
)
|
||
.appendTo( cell );
|
||
|
||
// Attach a sort listener to update on sort
|
||
$(settings.nTable).on( 'order.dt.DT', function ( e, settings, sorting, columns ) {
|
||
cell
|
||
.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortDesc :
|
||
column.sSortingClass
|
||
);
|
||
|
||
cell
|
||
.find( 'span.'+classes.sSortIcon )
|
||
.removeClass(
|
||
classes.sSortJUIAsc +" "+
|
||
classes.sSortJUIDesc +" "+
|
||
classes.sSortJUI +" "+
|
||
classes.sSortJUIAscAllowed +" "+
|
||
classes.sSortJUIDescAllowed
|
||
)
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortJUIDesc :
|
||
column.sSortingClassJUI
|
||
);
|
||
} );
|
||
}
|
||
}
|
||
} );
|
||
|
||
/*
|
||
* Public helper functions. These aren't used internally by DataTables, or
|
||
* called by any of the options passed into DataTables, but they can be used
|
||
* externally by developers working with DataTables. They are helper functions
|
||
* to make working with DataTables a little bit easier.
|
||
*/
|
||
|
||
/**
|
||
* Helpers for `columns.render`.
|
||
*
|
||
* The options defined here can be used with the `columns.render` initialisation
|
||
* option to provide a display renderer. The following functions are defined:
|
||
*
|
||
* * `number` - Will format numeric data (defined by `columns.data`) for
|
||
* display, retaining the original unformatted data for sorting and filtering.
|
||
* It takes 4 parameters:
|
||
* * `string` - Thousands grouping separator
|
||
* * `string` - Decimal point indicator
|
||
* * `integer` - Number of decimal points to show
|
||
* * `string` (optional) - Prefix.
|
||
*
|
||
* @example
|
||
* // Column definition using the number renderer
|
||
* {
|
||
* data: "salary",
|
||
* render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
|
||
* }
|
||
*
|
||
* @namespace
|
||
*/
|
||
DataTable.render = {
|
||
number: function ( thousands, decimal, precision, prefix ) {
|
||
return {
|
||
display: function ( d ) {
|
||
d = parseFloat( d );
|
||
var intPart = parseInt( d, 10 );
|
||
var floatPart = precision ?
|
||
(decimal+(d - intPart).toFixed( precision )).substring( 2 ):
|
||
'';
|
||
|
||
return (prefix||'') +
|
||
intPart.toString().replace(
|
||
/\B(?=(\d{3})+(?!\d))/g, thousands
|
||
) +
|
||
floatPart;
|
||
}
|
||
};
|
||
}
|
||
};
|
||
|
||
|
||
/*
|
||
* This is really a good bit rubbish this method of exposing the internal methods
|
||
* publicly... - To be fixed in 2.0 using methods on the prototype
|
||
*/
|
||
|
||
|
||
/**
|
||
* Create a wrapper function for exporting an internal functions to an external API.
|
||
* @param {string} fn API function name
|
||
* @returns {function} wrapped function
|
||
* @memberof DataTable#internal
|
||
*/
|
||
function _fnExternApiFunc (fn)
|
||
{
|
||
return function() {
|
||
var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
|
||
Array.prototype.slice.call(arguments)
|
||
);
|
||
return DataTable.ext.internal[fn].apply( this, args );
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* Reference to internal functions for use by plug-in developers. Note that
|
||
* these methods are references to internal functions and are considered to be
|
||
* private. If you use these methods, be aware that they are liable to change
|
||
* between versions.
|
||
* @namespace
|
||
*/
|
||
$.extend( DataTable.ext.internal, {
|
||
_fnExternApiFunc: _fnExternApiFunc,
|
||
_fnBuildAjax: _fnBuildAjax,
|
||
_fnAjaxUpdate: _fnAjaxUpdate,
|
||
_fnAjaxParameters: _fnAjaxParameters,
|
||
_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
|
||
_fnAjaxDataSrc: _fnAjaxDataSrc,
|
||
_fnAddColumn: _fnAddColumn,
|
||
_fnColumnOptions: _fnColumnOptions,
|
||
_fnAdjustColumnSizing: _fnAdjustColumnSizing,
|
||
_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
|
||
_fnColumnIndexToVisible: _fnColumnIndexToVisible,
|
||
_fnVisbleColumns: _fnVisbleColumns,
|
||
_fnGetColumns: _fnGetColumns,
|
||
_fnColumnTypes: _fnColumnTypes,
|
||
_fnApplyColumnDefs: _fnApplyColumnDefs,
|
||
_fnHungarianMap: _fnHungarianMap,
|
||
_fnCamelToHungarian: _fnCamelToHungarian,
|
||
_fnLanguageCompat: _fnLanguageCompat,
|
||
_fnBrowserDetect: _fnBrowserDetect,
|
||
_fnAddData: _fnAddData,
|
||
_fnAddTr: _fnAddTr,
|
||
_fnNodeToDataIndex: _fnNodeToDataIndex,
|
||
_fnNodeToColumnIndex: _fnNodeToColumnIndex,
|
||
_fnGetCellData: _fnGetCellData,
|
||
_fnSetCellData: _fnSetCellData,
|
||
_fnSplitObjNotation: _fnSplitObjNotation,
|
||
_fnGetObjectDataFn: _fnGetObjectDataFn,
|
||
_fnSetObjectDataFn: _fnSetObjectDataFn,
|
||
_fnGetDataMaster: _fnGetDataMaster,
|
||
_fnClearTable: _fnClearTable,
|
||
_fnDeleteIndex: _fnDeleteIndex,
|
||
_fnInvalidateRow: _fnInvalidateRow,
|
||
_fnGetRowElements: _fnGetRowElements,
|
||
_fnCreateTr: _fnCreateTr,
|
||
_fnBuildHead: _fnBuildHead,
|
||
_fnDrawHead: _fnDrawHead,
|
||
_fnDraw: _fnDraw,
|
||
_fnReDraw: _fnReDraw,
|
||
_fnAddOptionsHtml: _fnAddOptionsHtml,
|
||
_fnDetectHeader: _fnDetectHeader,
|
||
_fnGetUniqueThs: _fnGetUniqueThs,
|
||
_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
|
||
_fnFilterComplete: _fnFilterComplete,
|
||
_fnFilterCustom: _fnFilterCustom,
|
||
_fnFilterColumn: _fnFilterColumn,
|
||
_fnFilter: _fnFilter,
|
||
_fnFilterCreateSearch: _fnFilterCreateSearch,
|
||
_fnEscapeRegex: _fnEscapeRegex,
|
||
_fnFilterData: _fnFilterData,
|
||
_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
|
||
_fnUpdateInfo: _fnUpdateInfo,
|
||
_fnInfoMacros: _fnInfoMacros,
|
||
_fnInitialise: _fnInitialise,
|
||
_fnInitComplete: _fnInitComplete,
|
||
_fnLengthChange: _fnLengthChange,
|
||
_fnFeatureHtmlLength: _fnFeatureHtmlLength,
|
||
_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
|
||
_fnPageChange: _fnPageChange,
|
||
_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
|
||
_fnProcessingDisplay: _fnProcessingDisplay,
|
||
_fnFeatureHtmlTable: _fnFeatureHtmlTable,
|
||
_fnScrollDraw: _fnScrollDraw,
|
||
_fnApplyToChildren: _fnApplyToChildren,
|
||
_fnCalculateColumnWidths: _fnCalculateColumnWidths,
|
||
_fnThrottle: _fnThrottle,
|
||
_fnConvertToWidth: _fnConvertToWidth,
|
||
_fnScrollingWidthAdjust: _fnScrollingWidthAdjust,
|
||
_fnGetWidestNode: _fnGetWidestNode,
|
||
_fnGetMaxLenString: _fnGetMaxLenString,
|
||
_fnStringToCss: _fnStringToCss,
|
||
_fnScrollBarWidth: _fnScrollBarWidth,
|
||
_fnSortFlatten: _fnSortFlatten,
|
||
_fnSort: _fnSort,
|
||
_fnSortAria: _fnSortAria,
|
||
_fnSortListener: _fnSortListener,
|
||
_fnSortAttachListener: _fnSortAttachListener,
|
||
_fnSortingClasses: _fnSortingClasses,
|
||
_fnSortData: _fnSortData,
|
||
_fnSaveState: _fnSaveState,
|
||
_fnLoadState: _fnLoadState,
|
||
_fnSettingsFromNode: _fnSettingsFromNode,
|
||
_fnLog: _fnLog,
|
||
_fnMap: _fnMap,
|
||
_fnBindAction: _fnBindAction,
|
||
_fnCallbackReg: _fnCallbackReg,
|
||
_fnCallbackFire: _fnCallbackFire,
|
||
_fnLengthOverflow: _fnLengthOverflow,
|
||
_fnRenderer: _fnRenderer,
|
||
_fnDataSource: _fnDataSource,
|
||
_fnRowAttributes: _fnRowAttributes,
|
||
_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
|
||
// in 1.10, so this dead-end function is
|
||
// added to prevent errors
|
||
} );
|
||
|
||
|
||
// jQuery access
|
||
$.fn.dataTable = DataTable;
|
||
|
||
// Legacy aliases
|
||
$.fn.dataTableSettings = DataTable.settings;
|
||
$.fn.dataTableExt = DataTable.ext;
|
||
|
||
// With a capital `D` we return a DataTables API instance rather than a
|
||
// jQuery object
|
||
$.fn.DataTable = function ( opts ) {
|
||
return $(this).dataTable( opts ).api();
|
||
};
|
||
|
||
// All properties that are available to $.fn.dataTable should also be
|
||
// available on $.fn.DataTable
|
||
$.each( DataTable, function ( prop, val ) {
|
||
$.fn.DataTable[ prop ] = val;
|
||
} );
|
||
|
||
|
||
// Information about events fired by DataTables - for documentation.
|
||
/**
|
||
* Draw event, fired whenever the table is redrawn on the page, at the same
|
||
* point as fnDrawCallback. This may be useful for binding events or
|
||
* performing calculations when the table is altered at all.
|
||
* @name DataTable#draw.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Search event, fired when the searching applied to the table (using the
|
||
* built-in global search, or column filters) is altered.
|
||
* @name DataTable#search.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Page change event, fired when the paging of the table is altered.
|
||
* @name DataTable#page.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Order event, fired when the ordering applied to the table is altered.
|
||
* @name DataTable#order.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* DataTables initialisation complete event, fired when the table is fully
|
||
* drawn, including Ajax data loaded, if Ajax data is required.
|
||
* @name DataTable#init.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The JSON object request from the server - only
|
||
* present if client-side Ajax sourced data is used</li></ol>
|
||
*/
|
||
|
||
/**
|
||
* State save event, fired when the table has changed state a new state save
|
||
* is required. This event allows modification of the state saving object
|
||
* prior to actually doing the save, including addition or other state
|
||
* properties (for plug-ins) or modification of a DataTables core property.
|
||
* @name DataTable#stateSaveParams.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The state information to be saved
|
||
*/
|
||
|
||
/**
|
||
* State load event, fired when the table is loading state from the stored
|
||
* data, but prior to the settings object being modified by the saved state
|
||
* - allowing modification of the saved state is required or loading of
|
||
* state for a plug-in.
|
||
* @name DataTable#stateLoadParams.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The saved state information
|
||
*/
|
||
|
||
/**
|
||
* State loaded event, fired when state has been loaded from stored data and
|
||
* the settings object has been modified by the loaded data.
|
||
* @name DataTable#stateLoaded.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The saved state information
|
||
*/
|
||
|
||
/**
|
||
* Processing event, fired when DataTables is doing some kind of processing
|
||
* (be it, order, searcg or anything else). It can be used to indicate to
|
||
* the end user that there is something happening, or that something has
|
||
* finished.
|
||
* @name DataTable#processing.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {boolean} bShow Flag for if DataTables is doing processing or not
|
||
*/
|
||
|
||
/**
|
||
* Ajax (XHR) event, fired whenever an Ajax request is completed from a
|
||
* request to made to the server for new data. This event is called before
|
||
* DataTables processed the returned data, so it can also be used to pre-
|
||
* process the data returned from the server, if needed.
|
||
*
|
||
* Note that this trigger is called in `fnServerData`, if you override
|
||
* `fnServerData` and which to use this event, you need to trigger it in you
|
||
* success function.
|
||
* @name DataTable#xhr.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {object} json JSON returned from the server
|
||
*
|
||
* @example
|
||
* // Use a custom property returned from the server in another DOM element
|
||
* $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
|
||
* $('#status').html( json.status );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Pre-process the data returned from the server
|
||
* $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
|
||
* for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
|
||
* json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
|
||
* }
|
||
* // Note no return - manipulate the data directly in the JSON object.
|
||
* } );
|
||
*/
|
||
|
||
/**
|
||
* Destroy event, fired when the DataTable is destroyed by calling fnDestroy
|
||
* or passing the bDestroy:true parameter in the initialisation object. This
|
||
* can be used to remove bound events, added DOM nodes, etc.
|
||
* @name DataTable#destroy.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Page length change event, fired when number of records to show on each
|
||
* page (the length) is changed.
|
||
* @name DataTable#length.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {integer} len New length
|
||
*/
|
||
|
||
/**
|
||
* Column sizing has changed.
|
||
* @name DataTable#column-sizing.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Column visibility has changed.
|
||
* @name DataTable#column-visibility.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {int} column Column index
|
||
* @param {bool} vis `false` if column now hidden, or `true` if visible
|
||
*/
|
||
|
||
return $.fn.dataTable;
|
||
}));
|
||
|
||
}(window, document));
|
||
|
||
|
||
(function (factory) {
|
||
if (typeof define === 'function' && define.amd) {
|
||
define(['jquery','datatables'], factory);
|
||
}
|
||
else {
|
||
factory(jQuery);
|
||
}
|
||
}(function ($) {
|
||
/* Set the defaults for DataTables initialisation */
|
||
$.extend( true, $.fn.dataTable.defaults, {
|
||
"sDom": "<'row'<'col-sm-12'<'pull-right'f><'pull-left'l>r<'clearfix'>>>t<'row'<'col-sm-12'<'pull-left'i><'pull-right'p><'clearfix'>>>",
|
||
"sPaginationType": "bs_normal",
|
||
/* At the moment, this is the easiest way I could find to sneak these into oSettings without them getting wiped by _fnMap. */
|
||
"oLanguage": {
|
||
"sIconClassFirst": "glyphicon glyphicon-backward",
|
||
"sIconClassLast": "glyphicon glyphicon-forward",
|
||
"sIconClassPrevious": "glyphicon glyphicon-chevron-left",
|
||
"sIconClassNext": "glyphicon glyphicon-chevron-right"
|
||
}
|
||
} );
|
||
|
||
/* Default class modification */
|
||
$.extend( $.fn.dataTableExt.oStdClasses, {
|
||
"sWrapper": "dataTables_wrapper form-inline"
|
||
} );
|
||
|
||
/* API method to get paging information */
|
||
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
|
||
{
|
||
return {
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iEnd": oSettings.fnDisplayEnd(),
|
||
"iLength": oSettings._iDisplayLength,
|
||
"iTotal": oSettings.fnRecordsTotal(),
|
||
"iFilteredTotal": oSettings.fnRecordsDisplay(),
|
||
"iPage": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
|
||
"iTotalPages": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
|
||
};
|
||
};
|
||
|
||
/* Bootstrap style pagination control */
|
||
$.extend( $.fn.dataTableExt.oPagination, {
|
||
"bs_normal": {
|
||
"fnInit": function( oSettings, nPaging, fnDraw ) {
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="prev disabled"><a href="#"><span class="'+oSettings.oLanguage.sIconClassPrevious+'"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li class="next disabled"><a href="#">'+oLang.sNext+' <span class="'+oSettings.oLanguage.sIconClassNext+'"></span></a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
$(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
|
||
$(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
|
||
},
|
||
"fnUpdate": function ( oSettings, fnDraw ) {
|
||
var iListLength = 5;
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var an = oSettings.aanFeatures.p;
|
||
var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
|
||
if ( oPaging.iTotalPages < iListLength) {
|
||
iStart = 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
}
|
||
else if ( oPaging.iPage <= iHalf ) {
|
||
iStart = 1;
|
||
iEnd = iListLength;
|
||
} else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
|
||
iStart = oPaging.iTotalPages - iListLength + 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
} else {
|
||
iStart = oPaging.iPage - iHalf + 1;
|
||
iEnd = iStart + iListLength - 1;
|
||
}
|
||
for ( i=0, ien=an.length ; i<ien ; i++ ) {
|
||
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
|
||
for ( j=iStart ; j<=iEnd ; j++ ) {
|
||
sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
|
||
$('<li '+sClass+'><a href="#">'+j+'</a></li>')
|
||
.insertBefore( $('li:last', an[i])[0] )
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, parseInt($('a', this).text(),10)-1) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
} );
|
||
}
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_two_button": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
var sAppend = '<ul class="pagination">'+
|
||
'<li class="prev"><a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oLanguage.sIconClassPrevious+'"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li class="next"><a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sNext+' <span class="'+oSettings.oLanguage.sIconClassNext+'"></span></a></li>'+
|
||
'</ul>';
|
||
$(nPaging).append( sAppend );
|
||
var els = $('a', nPaging);
|
||
var nPrevious = els[0],
|
||
nNext = els[1];
|
||
oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nPrevious.id = oSettings.sTableId+'_previous';
|
||
nNext.id = oSettings.sTableId+'_next';
|
||
nPrevious.setAttribute('aria-controls', oSettings.sTableId);
|
||
nNext.setAttribute('aria-controls', oSettings.sTableId);
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var oClasses = oSettings.oClasses;
|
||
var an = oSettings.aanFeatures.p;
|
||
var nNode;
|
||
for ( var i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_four_button": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault()
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'"><span class="'+oSettings.oLanguage.sIconClassFirst+'"></span> '+oLang.sFirst+'</a></li>'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'"><span class="'+oSettings.oLanguage.sIconClassPrevious+'"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+' <span class="'+oSettings.oLanguage.sIconClassNext+'"></span></a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+' <span class="'+oSettings.oLanguage.sIconClassLast+'"></span></a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
var nFirst = els[0],
|
||
nPrev = els[1],
|
||
nNext = els[2],
|
||
nLast = els[3];
|
||
oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nFirst.id =oSettings.sTableId+'_first';
|
||
nPrev.id =oSettings.sTableId+'_previous';
|
||
nNext.id =oSettings.sTableId+'_next';
|
||
nLast.id =oSettings.sTableId+'_last';
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var oClasses = oSettings.oClasses;
|
||
var an = oSettings.aanFeatures.p;
|
||
var nNode;
|
||
for ( var i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:eq(0)', an[i]).addClass('disabled');
|
||
$('li:eq(1)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(0)', an[i]).removeClass('disabled');
|
||
$('li:eq(1)', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:eq(2)', an[i]).addClass('disabled');
|
||
$('li:eq(3)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(2)', an[i]).removeClass('disabled');
|
||
$('li:eq(3)', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_full": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a></li>'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
var nFirst = els[0],
|
||
nPrev = els[1],
|
||
nNext = els[2],
|
||
nLast = els[3];
|
||
oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nFirst.id =oSettings.sTableId+'_first';
|
||
nPrev.id =oSettings.sTableId+'_previous';
|
||
nNext.id =oSettings.sTableId+'_next';
|
||
nLast.id =oSettings.sTableId+'_last';
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var iPageCount = $.fn.dataTableExt.oPagination.iFullNumbersShowPages;
|
||
var iPageCountHalf = Math.floor(iPageCount / 2);
|
||
var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
|
||
var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
|
||
var sList = "";
|
||
var iStartButton, iEndButton, i, iLen;
|
||
var oClasses = oSettings.oClasses;
|
||
var anButtons, anStatic, nPaginateList, nNode;
|
||
var an = oSettings.aanFeatures.p;
|
||
var fnBind = function (j) {
|
||
oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
|
||
if( oSettings.oApi._fnPageChange( oSettings, e.data.page ) ){
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
e.preventDefault();
|
||
} );
|
||
};
|
||
if ( oSettings._iDisplayLength === -1 )
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = 1;
|
||
iCurrentPage = 1;
|
||
}
|
||
else if (iPages < iPageCount)
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = iPages;
|
||
}
|
||
else if (iCurrentPage <= iPageCountHalf)
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = iPageCount;
|
||
}
|
||
else if (iCurrentPage >= (iPages - iPageCountHalf))
|
||
{
|
||
iStartButton = iPages - iPageCount + 1;
|
||
iEndButton = iPages;
|
||
}
|
||
else
|
||
{
|
||
iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
|
||
iEndButton = iStartButton + iPageCount - 1;
|
||
}
|
||
for ( i=iStartButton ; i<=iEndButton ; i++ )
|
||
{
|
||
sList += (iCurrentPage !== i) ?
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'">'+oSettings.fnFormatNumber(i)+'</a></li>' :
|
||
'<li class="active"><a tabindex="'+oSettings.iTabIndex+'">'+oSettings.fnFormatNumber(i)+'</a></li>';
|
||
}
|
||
for ( i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
nNode = an[i];
|
||
if ( !nNode.hasChildNodes() )
|
||
{
|
||
continue;
|
||
}
|
||
$('li:gt(1)', an[i]).filter(':not(li:eq(-2))').filter(':not(li:eq(-1))').remove();
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:eq(0)', an[i]).addClass('disabled');
|
||
$('li:eq(1)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(0)', an[i]).removeClass('disabled');
|
||
$('li:eq(1)', an[i]).removeClass('disabled');
|
||
}
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:eq(-1)', an[i]).addClass('disabled');
|
||
$('li:eq(-2)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(-1)', an[i]).removeClass('disabled');
|
||
$('li:eq(-2)', an[i]).removeClass('disabled');
|
||
}
|
||
$(sList)
|
||
.insertBefore($('li:eq(-2)', an[i]))
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, parseInt($('a', this).text(),10)-1) ) {
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
/*
|
||
* TableTools Bootstrap compatibility
|
||
* Required TableTools 2.1+
|
||
*/
|
||
if ( $.fn.DataTable.TableTools ) {
|
||
// Set the classes that TableTools uses to something suitable for Bootstrap
|
||
$.extend( true, $.fn.DataTable.TableTools.classes, {
|
||
"container": "DTTT btn-group",
|
||
"buttons": {
|
||
"normal": "btn",
|
||
"disabled": "disabled"
|
||
},
|
||
"collection": {
|
||
"container": "DTTT_dropdown dropdown-menu",
|
||
"buttons": {
|
||
"normal": "",
|
||
"disabled": "disabled"
|
||
}
|
||
},
|
||
"print": {
|
||
"info": "DTTT_print_info modal"
|
||
},
|
||
"select": {
|
||
"row": "active"
|
||
}
|
||
} );
|
||
|
||
// Have the collection use a bootstrap compatible dropdown
|
||
$.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
|
||
"collection": {
|
||
"container": "ul",
|
||
"button": "li",
|
||
"liner": "a"
|
||
}
|
||
} );
|
||
}
|
||
}));
|
||
|
||
|
||
|
||
|
||
|
||
// Knockout JavaScript library v3.1.0
|
||
// (c) Steven Sanderson - http://knockoutjs.com/
|
||
// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
||
|
||
(function() {(function(p){var A=this||(0,eval)("this"),w=A.document,K=A.navigator,t=A.jQuery,C=A.JSON;(function(p){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?p(module.exports||exports):"function"===typeof define&&define.amd?define(["exports"],p):p(A.ko={})})(function(z){function G(a,c){return null===a||typeof a in M?a===c:!1}function N(a,c){var d;return function(){d||(d=setTimeout(function(){d=p;a()},c))}}function O(a,c){var d;return function(){clearTimeout(d);d=setTimeout(a,
|
||
c)}}function H(b,c,d,e){a.d[b]={init:function(b,h,g,k,l){var n,r;a.ba(function(){var g=a.a.c(h()),k=!d!==!g,s=!r;if(s||c||k!==n)s&&a.ca.fa()&&(r=a.a.lb(a.e.childNodes(b),!0)),k?(s||a.e.U(b,a.a.lb(r)),a.gb(e?e(l,g):l,b)):a.e.da(b),n=k},null,{G:b});return{controlsDescendantBindings:!0}}};a.g.aa[b]=!1;a.e.Q[b]=!0}var a="undefined"!==typeof z?z:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=c};a.s=function(a,c,d){a[c]=d};a.version="3.1.0";a.b("version",
|
||
a.version);a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function c(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function d(a,b){a.__proto__=b;return a}var e={__proto__:[]}instanceof Array,f={},h={};f[K&&/Firefox\/2/i.test(K.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];f.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(f,function(a,b){if(b.length)for(var c=0,
|
||
d=b.length;c<d;c++)h[b[c]]=a});var g={propertychange:!0},k=w&&function(){for(var a=3,b=w.createElement("div"),c=b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:p}();return{mb:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],r:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},l:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===
|
||
b)return c;return-1},hb:function(a,b,c){for(var d=0,e=a.length;d<e;d++)if(b.call(c,a[d],d))return a[d];return null},ma:function(b,c){var d=a.a.l(b,c);0<d?b.splice(d,1):0===d&&b.shift()},ib:function(b){b=b||[];for(var c=[],d=0,e=b.length;d<e;d++)0>a.a.l(c,b[d])&&c.push(b[d]);return c},ya:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)c.push(b(a[d],d));return c},la:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)b(a[d],d)&&c.push(a[d]);return c},$:function(a,b){if(b instanceof Array)a.push.apply(a,
|
||
b);else for(var c=0,d=b.length;c<d;c++)a.push(b[c]);return a},Y:function(b,c,d){var e=a.a.l(a.a.Sa(b),c);0>e?d&&b.push(c):d||b.splice(e,1)},na:e,extend:c,ra:d,sa:e?d:c,A:b,Oa:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},Fa:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},ec:function(b){b=a.a.R(b);for(var c=w.createElement("div"),d=0,e=b.length;d<e;d++)c.appendChild(a.M(b[d]));return c},lb:function(b,c){for(var d=0,e=b.length,g=[];d<
|
||
e;d++){var k=b[d].cloneNode(!0);g.push(c?a.M(k):k)}return g},U:function(b,c){a.a.Fa(b);if(c)for(var d=0,e=c.length;d<e;d++)b.appendChild(c[d])},Bb:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var e=d[0],g=e.parentNode,k=0,h=c.length;k<h;k++)g.insertBefore(c[k],e);k=0;for(h=d.length;k<h;k++)a.removeNode(d[k])}},ea:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.shift();if(1<a.length){var c=a[0],d=a[a.length-1];for(a.length=0;c!==d;)if(a.push(c),
|
||
c=c.nextSibling,!c)return;a.push(d)}}return a},Db:function(a,b){7>k?a.setAttribute("selected",b):a.selected=b},ta:function(a){return null===a||a===p?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},oc:function(b,c){for(var d=[],e=(b||"").split(c),g=0,k=e.length;g<k;g++){var h=a.a.ta(e[g]);""!==h&&d.push(h)}return d},kc:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Sb:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===
|
||
a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},Ea:function(b){return a.a.Sb(b,b.ownerDocument.documentElement)},eb:function(b){return!!a.a.hb(b,a.a.Ea)},B:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},q:function(b,c,d){var e=k&&g[c];if(!e&&t)t(b).bind(c,d);else if(e||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var h=function(a){d.call(b,a)},f="on"+c;b.attachEvent(f,
|
||
h);a.a.u.ja(b,function(){b.detachEvent(f,h)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,d,!1)},ha:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===a.a.B(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==d||"radio"==d):d=!1;if(t&&!d)t(b).trigger(c);else if("function"==typeof w.createEvent)if("function"==typeof b.dispatchEvent)d=w.createEvent(h[c]||"HTMLEvents"),
|
||
d.initEvent(c,!0,!0,A,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");},c:function(b){return a.v(b)?b():b},Sa:function(b){return a.v(b)?b.o():b},ua:function(b,c,d){if(c){var e=/\S+/g,g=b.className.match(e)||[];a.a.r(c.match(e),function(b){a.a.Y(g,b,d)});b.className=g.join(" ")}},Xa:function(b,
|
||
c){var d=a.a.c(c);if(null===d||d===p)d="";var e=a.e.firstChild(b);!e||3!=e.nodeType||a.e.nextSibling(e)?a.e.U(b,[b.ownerDocument.createTextNode(d)]):e.data=d;a.a.Vb(b)},Cb:function(a,b){a.name=b;if(7>=k)try{a.mergeAttributes(w.createElement("<input name='"+a.name+"'/>"),!1)}catch(c){}},Vb:function(a){9<=k&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Tb:function(a){if(k){var b=a.style.width;a.style.width=0;a.style.width=b}},ic:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=
|
||
[],e=b;e<=c;e++)d.push(e);return d},R:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},mc:6===k,nc:7===k,oa:k,ob:function(b,c){for(var d=a.a.R(b.getElementsByTagName("input")).concat(a.a.R(b.getElementsByTagName("textarea"))),e="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},g=[],k=d.length-1;0<=k;k--)e(d[k])&&g.push(d[k]);return g},fc:function(b){return"string"==typeof b&&(b=a.a.ta(b))?C&&C.parse?C.parse(b):(new Function("return "+b))():
|
||
null},Ya:function(b,c,d){if(!C||!C.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");return C.stringify(a.a.c(b),c,d)},gc:function(c,d,e){e=e||{};var g=e.params||{},k=e.includeFields||this.mb,h=c;if("object"==typeof c&&"form"===a.a.B(c))for(var h=c.action,f=k.length-1;0<=f;f--)for(var u=a.a.ob(c,k[f]),D=u.length-1;0<=D;D--)g[u[D].name]=
|
||
u[D].value;d=a.a.c(d);var y=w.createElement("form");y.style.display="none";y.action=h;y.method="post";for(var p in d)c=w.createElement("input"),c.name=p,c.value=a.a.Ya(a.a.c(d[p])),y.appendChild(c);b(g,function(a,b){var c=w.createElement("input");c.name=a;c.value=b;y.appendChild(c)});w.body.appendChild(y);e.submitter?e.submitter(y):y.submit();setTimeout(function(){y.parentNode.removeChild(y)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.r);a.b("utils.arrayFirst",a.a.hb);a.b("utils.arrayFilter",
|
||
a.a.la);a.b("utils.arrayGetDistinctValues",a.a.ib);a.b("utils.arrayIndexOf",a.a.l);a.b("utils.arrayMap",a.a.ya);a.b("utils.arrayPushAll",a.a.$);a.b("utils.arrayRemoveItem",a.a.ma);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",a.a.mb);a.b("utils.getFormFields",a.a.ob);a.b("utils.peekObservable",a.a.Sa);a.b("utils.postJson",a.a.gc);a.b("utils.parseJson",a.a.fc);a.b("utils.registerEventHandler",a.a.q);a.b("utils.stringifyJson",a.a.Ya);a.b("utils.range",a.a.ic);a.b("utils.toggleDomNodeCssClass",
|
||
a.a.ua);a.b("utils.triggerEvent",a.a.ha);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.A);a.b("utils.addOrRemoveItem",a.a.Y);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=function(a){var c=this,d=Array.prototype.slice.call(arguments);a=d.shift();return function(){return c.apply(a,d.concat(Array.prototype.slice.call(arguments)))}});a.a.f=new function(){function a(b,h){var g=b[d];if(!g||"null"===g||!e[g]){if(!h)return p;g=b[d]="ko"+c++;e[g]={}}return e[g]}
|
||
var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===p?p:e[d]},set:function(c,d,e){if(e!==p||a(c,!1)!==p)a(c,!0)[d]=e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},L:function(){return c++ +d}}};a.b("utils.domData",a.a.f);a.b("utils.domData.clear",a.a.f.clear);a.a.u=new function(){function b(b,c){var e=a.a.f.get(b,d);e===p&&c&&(e=[],a.a.f.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),k=0;k<e.length;k++)e[k](d);
|
||
a.a.f.clear(d);a.a.u.cleanExternalData(d);if(f[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.f.L(),e={1:!0,8:!0,9:!0},f={1:!0,9:!0};return{ja:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},Ab:function(c,e){var k=b(c,!1);k&&(a.a.ma(k,e),0==k.length&&a.a.f.set(c,d,p))},M:function(b){if(e[b.nodeType]&&(c(b),f[b.nodeType])){var d=[];a.a.$(d,b.getElementsByTagName("*"));for(var k=0,l=d.length;k<l;k++)c(d[k])}return b},
|
||
removeNode:function(b){a.M(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){t&&"function"==typeof t.cleanData&&t.cleanData([a])}}};a.M=a.a.u.M;a.removeNode=a.a.u.removeNode;a.b("cleanNode",a.M);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.u);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.u.ja);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.u.Ab);(function(){a.a.Qa=function(b){var c;if(t)if(t.parseHTML)c=t.parseHTML(b)||[];else{if((c=t.clean([b]))&&
|
||
c[0]){for(b=c[0];b.parentNode&&11!==b.parentNode.nodeType;)b=b.parentNode;b.parentNode&&b.parentNode.removeChild(b)}}else{var d=a.a.ta(b).toLowerCase();c=w.createElement("div");d=d.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!d.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!d.indexOf("<td")||!d.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];b="ignored<div>"+d[1]+b+d[2]+"</div>";for("function"==typeof A.innerShiv?c.appendChild(A.innerShiv(b)):
|
||
c.innerHTML=b;d[0]--;)c=c.lastChild;c=a.a.R(c.lastChild.childNodes)}return c};a.a.Va=function(b,c){a.a.Fa(b);c=a.a.c(c);if(null!==c&&c!==p)if("string"!=typeof c&&(c=c.toString()),t)t(b).html(c);else for(var d=a.a.Qa(c),e=0;e<d.length;e++)b.appendChild(d[e])}})();a.b("utils.parseHtmlFragment",a.a.Qa);a.b("utils.setHtml",a.a.Va);a.w=function(){function b(c,e){if(c)if(8==c.nodeType){var f=a.w.xb(c.nodeValue);null!=f&&e.push({Rb:c,cc:f})}else if(1==c.nodeType)for(var f=0,h=c.childNodes,g=h.length;f<g;f++)b(h[f],
|
||
e)}var c={};return{Na:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},Hb:function(a,b){var f=c[a];if(f===p)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return f.apply(null,b||[]),!0}finally{delete c[a]}},Ib:function(c,e){var f=
|
||
[];b(c,f);for(var h=0,g=f.length;h<g;h++){var k=f[h].Rb,l=[k];e&&a.a.$(l,e);a.w.Hb(f[h].cc,l);k.nodeValue="";k.parentNode&&k.parentNode.removeChild(k)}},xb:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.w);a.b("memoization.memoize",a.w.Na);a.b("memoization.unmemoize",a.w.Hb);a.b("memoization.parseMemoText",a.w.xb);a.b("memoization.unmemoizeDomNodeAndDescendants",a.w.Ib);a.Ga={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.h({read:b,write:function(a){clearTimeout(d);
|
||
d=setTimeout(function(){b(a)},c)}})},rateLimit:function(a,c){var d,e,f;"number"==typeof c?d=c:(d=c.timeout,e=c.method);f="notifyWhenChangesStop"==e?O:N;a.Ma(function(a){return f(a,d)})},notify:function(a,c){a.equalityComparer="always"==c?null:G}};var M={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.Ga);a.Fb=function(b,c,d){this.target=b;this.za=c;this.Qb=d;this.sb=!1;a.s(this,"dispose",this.F)};a.Fb.prototype.F=function(){this.sb=!0;this.Qb()};a.N=function(){a.a.sa(this,a.N.fn);this.H=
|
||
{}};var F="change";z={V:function(b,c,d){var e=this;d=d||F;var f=new a.Fb(e,c?b.bind(c):b,function(){a.a.ma(e.H[d],f)});e.o&&e.o();e.H[d]||(e.H[d]=[]);e.H[d].push(f);return f},notifySubscribers:function(b,c){c=c||F;if(this.qb(c))try{a.k.jb();for(var d=this.H[c].slice(0),e=0,f;f=d[e];++e)f.sb||f.za(b)}finally{a.k.end()}},Ma:function(b){var c=this,d=a.v(c),e,f,h;c.ia||(c.ia=c.notifySubscribers,c.notifySubscribers=function(a,b){b&&b!==F?"beforeChange"===b?c.bb(a):c.ia(a,b):c.cb(a)});var g=b(function(){d&&
|
||
h===c&&(h=c());e=!1;c.Ka(f,h)&&c.ia(f=h)});c.cb=function(a){e=!0;h=a;g()};c.bb=function(a){e||(f=a,c.ia(a,"beforeChange"))}},qb:function(a){return this.H[a]&&this.H[a].length},Wb:function(){var b=0;a.a.A(this.H,function(a,d){b+=d.length});return b},Ka:function(a,c){return!this.equalityComparer||!this.equalityComparer(a,c)},extend:function(b){var c=this;b&&a.a.A(b,function(b,e){var f=a.Ga[b];"function"==typeof f&&(c=f(c,e)||c)});return c}};a.s(z,"subscribe",z.V);a.s(z,"extend",z.extend);a.s(z,"getSubscriptionsCount",
|
||
z.Wb);a.a.na&&a.a.ra(z,Function.prototype);a.N.fn=z;a.tb=function(a){return null!=a&&"function"==typeof a.V&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.N);a.b("isSubscribable",a.tb);a.ca=a.k=function(){function b(a){d.push(e);e=a}function c(){e=d.pop()}var d=[],e,f=0;return{jb:b,end:c,zb:function(b){if(e){if(!a.tb(b))throw Error("Only subscribable things can act as dependencies");e.za(b,b.Kb||(b.Kb=++f))}},t:function(a,d,e){try{return b(),a.apply(d,e||[])}finally{c()}},fa:function(){if(e)return e.ba.fa()},
|
||
pa:function(){if(e)return e.pa}}}();a.b("computedContext",a.ca);a.b("computedContext.getDependenciesCount",a.ca.fa);a.b("computedContext.isInitial",a.ca.pa);a.m=function(b){function c(){if(0<arguments.length)return c.Ka(d,arguments[0])&&(c.P(),d=arguments[0],c.O()),this;a.k.zb(c);return d}var d=b;a.N.call(c);a.a.sa(c,a.m.fn);c.o=function(){return d};c.O=function(){c.notifySubscribers(d)};c.P=function(){c.notifySubscribers(d,"beforeChange")};a.s(c,"peek",c.o);a.s(c,"valueHasMutated",c.O);a.s(c,"valueWillMutate",
|
||
c.P);return c};a.m.fn={equalityComparer:G};var E=a.m.hc="__ko_proto__";a.m.fn[E]=a.m;a.a.na&&a.a.ra(a.m.fn,a.N.fn);a.Ha=function(b,c){return null===b||b===p||b[E]===p?!1:b[E]===c?!0:a.Ha(b[E],c)};a.v=function(b){return a.Ha(b,a.m)};a.ub=function(b){return"function"==typeof b&&b[E]===a.m||"function"==typeof b&&b[E]===a.h&&b.Yb?!0:!1};a.b("observable",a.m);a.b("isObservable",a.v);a.b("isWriteableObservable",a.ub);a.T=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");
|
||
b=a.m(b);a.a.sa(b,a.T.fn);return b.extend({trackArrayChanges:!0})};a.T.fn={remove:function(b){for(var c=this.o(),d=[],e="function"!=typeof b||a.v(b)?function(a){return a===b}:b,f=0;f<c.length;f++){var h=c[f];e(h)&&(0===d.length&&this.P(),d.push(h),c.splice(f,1),f--)}d.length&&this.O();return d},removeAll:function(b){if(b===p){var c=this.o(),d=c.slice(0);this.P();c.splice(0,c.length);this.O();return d}return b?this.remove(function(c){return 0<=a.a.l(b,c)}):[]},destroy:function(b){var c=this.o(),d=
|
||
"function"!=typeof b||a.v(b)?function(a){return a===b}:b;this.P();for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.O()},destroyAll:function(b){return b===p?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.l(b,c)}):[]},indexOf:function(b){var c=this();return a.a.l(c,b)},replace:function(a,c){var d=this.indexOf(a);0<=d&&(this.P(),this.o()[d]=c,this.O())}};a.a.r("pop push reverse shift sort splice unshift".split(" "),function(b){a.T.fn[b]=function(){var a=this.o();
|
||
this.P();this.kb(a,b,arguments);a=a[b].apply(a,arguments);this.O();return a}});a.a.r(["slice"],function(b){a.T.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.a.na&&a.a.ra(a.T.fn,a.m.fn);a.b("observableArray",a.T);var I="arrayChange";a.Ga.trackArrayChanges=function(b){function c(){if(!d){d=!0;var c=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==F||++f;return c.apply(this,arguments)};var k=[].concat(b.o()||[]);e=null;b.V(function(c){c=[].concat(c||[]);if(b.qb(I)){var d;
|
||
if(!e||1<f)e=a.a.Aa(k,c,{sparse:!0});d=e;d.length&&b.notifySubscribers(d,I)}k=c;e=null;f=0})}}if(!b.kb){var d=!1,e=null,f=0,h=b.V;b.V=b.subscribe=function(a,b,d){d===I&&c();return h.apply(this,arguments)};b.kb=function(b,c,l){function h(a,b,c){return r[r.length]={status:a,value:b,index:c}}if(d&&!f){var r=[],m=b.length,q=l.length,s=0;switch(c){case "push":s=m;case "unshift":for(c=0;c<q;c++)h("added",l[c],s+c);break;case "pop":s=m-1;case "shift":m&&h("deleted",b[s],s);break;case "splice":c=Math.min(Math.max(0,
|
||
0>l[0]?m+l[0]:l[0]),m);for(var m=1===q?m:Math.min(c+(l[1]||0),m),q=c+q-2,s=Math.max(m,q),B=[],u=[],D=2;c<s;++c,++D)c<m&&u.push(h("deleted",b[c],c)),c<q&&B.push(h("added",l[D],c));a.a.nb(u,B);break;default:return}e=r}}}};a.ba=a.h=function(b,c,d){function e(){q=!0;a.a.A(v,function(a,b){b.F()});v={};x=0;n=!1}function f(){var a=g.throttleEvaluation;a&&0<=a?(clearTimeout(t),t=setTimeout(h,a)):g.wa?g.wa():h()}function h(){if(!r&&!q){if(y&&y()){if(!m){p();return}}else m=!1;r=!0;try{var b=v,d=x;a.k.jb({za:function(a,
|
||
c){q||(d&&b[c]?(v[c]=b[c],++x,delete b[c],--d):v[c]||(v[c]=a.V(f),++x))},ba:g,pa:!x});v={};x=0;try{var e=c?s.call(c):s()}finally{a.k.end(),d&&a.a.A(b,function(a,b){b.F()}),n=!1}g.Ka(l,e)&&(g.notifySubscribers(l,"beforeChange"),l=e,g.wa&&!g.throttleEvaluation||g.notifySubscribers(l))}finally{r=!1}x||p()}}function g(){if(0<arguments.length){if("function"===typeof B)B.apply(c,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
|
||
return this}n&&h();a.k.zb(g);return l}function k(){return n||0<x}var l,n=!0,r=!1,m=!1,q=!1,s=b;s&&"object"==typeof s?(d=s,s=d.read):(d=d||{},s||(s=d.read));if("function"!=typeof s)throw Error("Pass a function that returns the value of the ko.computed");var B=d.write,u=d.disposeWhenNodeIsRemoved||d.G||null,D=d.disposeWhen||d.Da,y=D,p=e,v={},x=0,t=null;c||(c=d.owner);a.N.call(g);a.a.sa(g,a.h.fn);g.o=function(){n&&!x&&h();return l};g.fa=function(){return x};g.Yb="function"===typeof d.write;g.F=function(){p()};
|
||
g.ga=k;var w=g.Ma;g.Ma=function(a){w.call(g,a);g.wa=function(){g.bb(l);n=!0;g.cb(g)}};a.s(g,"peek",g.o);a.s(g,"dispose",g.F);a.s(g,"isActive",g.ga);a.s(g,"getDependenciesCount",g.fa);u&&(m=!0,u.nodeType&&(y=function(){return!a.a.Ea(u)||D&&D()}));!0!==d.deferEvaluation&&h();u&&k()&&u.nodeType&&(p=function(){a.a.u.Ab(u,p);e()},a.a.u.ja(u,p));return g};a.$b=function(b){return a.Ha(b,a.h)};z=a.m.hc;a.h[z]=a.m;a.h.fn={equalityComparer:G};a.h.fn[z]=a.h;a.a.na&&a.a.ra(a.h.fn,a.N.fn);a.b("dependentObservable",
|
||
a.h);a.b("computed",a.h);a.b("isComputed",a.$b);(function(){function b(a,f,h){h=h||new d;a=f(a);if("object"!=typeof a||null===a||a===p||a instanceof Date||a instanceof String||a instanceof Number||a instanceof Boolean)return a;var g=a instanceof Array?[]:{};h.save(a,g);c(a,function(c){var d=f(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":g[c]=d;break;case "object":case "undefined":var n=h.get(d);g[c]=n!==p?n:b(d,f,h)}});return g}function c(a,b){if(a instanceof Array){for(var c=
|
||
0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=[];this.ab=[]}a.Gb=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return b(c,function(b){for(var c=0;a.v(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.Gb(b);return a.a.Ya(b,c,d)};d.prototype={save:function(b,c){var d=a.a.l(this.keys,b);0<=d?this.ab[d]=c:(this.keys.push(b),this.ab.push(c))},get:function(b){b=a.a.l(this.keys,
|
||
b);return 0<=b?this.ab[b]:p}}})();a.b("toJS",a.Gb);a.b("toJSON",a.toJSON);(function(){a.i={p:function(b){switch(a.a.B(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.f.get(b,a.d.options.Pa):7>=a.a.oa?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.i.p(b.options[b.selectedIndex]):p;default:return b.value}},X:function(b,c,d){switch(a.a.B(b)){case "option":switch(typeof c){case "string":a.a.f.set(b,a.d.options.Pa,
|
||
p);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.f.set(b,a.d.options.Pa,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof c?c:""}break;case "select":if(""===c||null===c)c=p;for(var e=-1,f=0,h=b.options.length,g;f<h;++f)if(g=a.i.p(b.options[f]),g==c||""==g&&c===p){e=f;break}if(d||0<=e||c===p&&1<b.size)b.selectedIndex=e;break;default:if(null===c||c===p)c="";b.value=c}}}})();a.b("selectExtensions",a.i);a.b("selectExtensions.readValue",
|
||
a.i.p);a.b("selectExtensions.writeValue",a.i.X);a.g=function(){function b(b){b=a.a.ta(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),g,m,q=0;if(d){d.push(",");for(var s=0,B;B=d[s];++s){var u=B.charCodeAt(0);if(44===u){if(0>=q){g&&c.push(m?{key:g,value:m.join("")}:{unknown:g});g=m=q=0;continue}}else if(58===u){if(!m)continue}else if(47===u&&s&&1<B.length)(u=d[s-1].match(f))&&!h[u[0]]&&(b=b.substr(b.indexOf(B)+1),d=b.match(e),d.push(","),s=-1,B="/");else if(40===u||123===u||91===
|
||
u)++q;else if(41===u||125===u||93===u)--q;else if(!g&&!m){g=34===u||39===u?B.slice(1,-1):B;continue}m?m.push(B):m=[B]}}return c}var c=["true","false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),f=/[\])"'A-Za-z0-9_$]+$/,h={"in":1,"return":1,"typeof":1},g={};return{aa:[],W:g,Ra:b,qa:function(e,l){function f(b,e){var l,k=a.getBindingHandler(b);
|
||
if(k&&k.preprocess?e=k.preprocess(e,b,f):1){if(k=g[b])l=e,0<=a.a.l(c,l)?l=!1:(k=l.match(d),l=null===k?!1:k[1]?"Object("+k[1]+")"+k[2]:l),k=l;k&&m.push("'"+b+"':function(_z){"+l+"=_z}");q&&(e="function(){return "+e+" }");h.push("'"+b+"':"+e)}}l=l||{};var h=[],m=[],q=l.valueAccessors,s="string"===typeof e?b(e):e;a.a.r(s,function(a){f(a.key||a.unknown,a.value)});m.length&&f("_ko_property_writers","{"+m.join(",")+" }");return h.join(",")},bc:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;
|
||
return!1},va:function(b,c,d,e,g){if(b&&a.v(b))!a.ub(b)||g&&b.o()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.g);a.b("expressionRewriting.bindingRewriteValidators",a.g.aa);a.b("expressionRewriting.parseObjectLiteral",a.g.Ra);a.b("expressionRewriting.preProcessBindings",a.g.qa);a.b("expressionRewriting._twoWayBindings",a.g.W);a.b("jsonExpressionRewriting",a.g);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.g.qa);(function(){function b(a){return 8==
|
||
a.nodeType&&h.test(f?a.text:a.nodeValue)}function c(a){return 8==a.nodeType&&g.test(f?a.text:a.nodeValue)}function d(a,d){for(var e=a,g=1,k=[];e=e.nextSibling;){if(c(e)&&(g--,0===g))return k;k.push(e);b(e)&&g++}if(!d)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var c=d(a,b);return c?0<c.length?c[c.length-1].nextSibling:a.nextSibling:null}var f=w&&"\x3c!--test--\x3e"===w.createComment("test").text,h=f?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,
|
||
g=f?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,k={ul:!0,ol:!0};a.e={Q:{},childNodes:function(a){return b(a)?d(a):a.childNodes},da:function(c){if(b(c)){c=a.e.childNodes(c);for(var d=0,e=c.length;d<e;d++)a.removeNode(c[d])}else a.a.Fa(c)},U:function(c,d){if(b(c)){a.e.da(c);for(var e=c.nextSibling,g=0,k=d.length;g<k;g++)e.parentNode.insertBefore(d[g],e)}else a.a.U(c,d)},yb:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},rb:function(c,
|
||
d,e){e?b(c)?c.parentNode.insertBefore(d,e.nextSibling):e.nextSibling?c.insertBefore(d,e.nextSibling):c.appendChild(d):a.e.yb(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||c(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&c(a.nextSibling)?null:a.nextSibling},Xb:b,lc:function(a){return(a=(f?a.text:a.nodeValue).match(h))?a[1]:null},wb:function(d){if(k[a.a.B(d)]){var g=d.firstChild;if(g){do if(1===g.nodeType){var f;f=g.firstChild;
|
||
var h=null;if(f){do if(h)h.push(f);else if(b(f)){var q=e(f,!0);q?f=q:h=[f]}else c(f)&&(h=[f]);while(f=f.nextSibling)}if(f=h)for(h=g.nextSibling,q=0;q<f.length;q++)h?d.insertBefore(f[q],h):d.appendChild(f[q])}while(g=g.nextSibling)}}}}})();a.b("virtualElements",a.e);a.b("virtualElements.allowedBindings",a.e.Q);a.b("virtualElements.emptyNode",a.e.da);a.b("virtualElements.insertAfter",a.e.rb);a.b("virtualElements.prepend",a.e.yb);a.b("virtualElements.setDomNodeChildren",a.e.U);(function(){a.J=function(){this.Nb=
|
||
{}};a.a.extend(a.J.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=b.getAttribute("data-bind");case 8:return a.e.Xb(b);default:return!1}},getBindings:function(a,c){var d=this.getBindingsString(a,c);return d?this.parseBindingsString(d,c,a):null},getBindingAccessors:function(a,c){var d=this.getBindingsString(a,c);return d?this.parseBindingsString(d,c,a,{valueAccessors:!0}):null},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");
|
||
case 8:return a.e.lc(b);default:return null}},parseBindingsString:function(b,c,d,e){try{var f=this.Nb,h=b+(e&&e.valueAccessors||""),g;if(!(g=f[h])){var k,l="with($context){with($data||{}){return{"+a.g.qa(b,e)+"}}}";k=new Function("$context","$element",l);g=f[h]=k}return g(c,d)}catch(n){throw n.message="Unable to parse bindings.\nBindings value: "+b+"\nMessage: "+n.message,n;}}});a.J.instance=new a.J})();a.b("bindingProvider",a.J);(function(){function b(a){return function(){return a}}function c(a){return a()}
|
||
function d(b){return a.a.Oa(a.k.t(b),function(a,c){return function(){return b()[c]}})}function e(a,b){return d(this.getBindings.bind(this,a,b))}function f(b,c,d){var e,g=a.e.firstChild(c),k=a.J.instance,f=k.preprocessNode;if(f){for(;e=g;)g=a.e.nextSibling(e),f.call(k,e);g=a.e.firstChild(c)}for(;e=g;)g=a.e.nextSibling(e),h(b,e,d)}function h(b,c,d){var e=!0,g=1===c.nodeType;g&&a.e.wb(c);if(g&&d||a.J.instance.nodeHasBindings(c))e=k(c,null,b,d).shouldBindDescendants;e&&!n[a.a.B(c)]&&f(b,c,!g)}function g(b){var c=
|
||
[],d={},e=[];a.a.A(b,function y(g){if(!d[g]){var k=a.getBindingHandler(g);k&&(k.after&&(e.push(g),a.a.r(k.after,function(c){if(b[c]){if(-1!==a.a.l(e,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+e.join(", "));y(c)}}),e.length--),c.push({key:g,pb:k}));d[g]=!0}});return c}function k(b,d,k,f){var h=a.a.f.get(b,r);if(!d){if(h)throw Error("You cannot apply bindings multiple times to the same element.");a.a.f.set(b,r,!0)}!h&&f&&a.Eb(b,k);var l;if(d&&"function"!==
|
||
typeof d)l=d;else{var n=a.J.instance,m=n.getBindingAccessors||e,x=a.h(function(){(l=d?d(k,b):m.call(n,b,k))&&k.D&&k.D();return l},null,{G:b});l&&x.ga()||(x=null)}var t;if(l){var w=x?function(a){return function(){return c(x()[a])}}:function(a){return l[a]},z=function(){return a.a.Oa(x?x():l,c)};z.get=function(a){return l[a]&&c(w(a))};z.has=function(a){return a in l};f=g(l);a.a.r(f,function(c){var d=c.pb.init,e=c.pb.update,g=c.key;if(8===b.nodeType&&!a.e.Q[g])throw Error("The binding '"+g+"' cannot be used with virtual elements");
|
||
try{"function"==typeof d&&a.k.t(function(){var a=d(b,w(g),z,k.$data,k);if(a&&a.controlsDescendantBindings){if(t!==p)throw Error("Multiple bindings ("+t+" and "+g+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");t=g}}),"function"==typeof e&&a.h(function(){e(b,w(g),z,k.$data,k)},null,{G:b})}catch(f){throw f.message='Unable to process binding "'+g+": "+l[g]+'"\nMessage: '+f.message,f;}})}return{shouldBindDescendants:t===p}}
|
||
function l(b){return b&&b instanceof a.I?b:new a.I(b)}a.d={};var n={script:!0};a.getBindingHandler=function(b){return a.d[b]};a.I=function(b,c,d,e){var g=this,k="function"==typeof b&&!a.v(b),f,h=a.h(function(){var f=k?b():b,l=a.a.c(f);c?(c.D&&c.D(),a.a.extend(g,c),h&&(g.D=h)):(g.$parents=[],g.$root=l,g.ko=a);g.$rawData=f;g.$data=l;d&&(g[d]=l);e&&e(g,c,l);return g.$data},null,{Da:function(){return f&&!a.a.eb(f)},G:!0});h.ga()&&(g.D=h,h.equalityComparer=null,f=[],h.Jb=function(b){f.push(b);a.a.u.ja(b,
|
||
function(b){a.a.ma(f,b);f.length||(h.F(),g.D=h=p)})})};a.I.prototype.createChildContext=function(b,c,d){return new a.I(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);d&&d(a)})};a.I.prototype.extend=function(b){return new a.I(this.D||this.$data,this,null,function(c,d){c.$rawData=d.$rawData;a.a.extend(c,"function"==typeof b?b():b)})};var r=a.a.f.L(),m=a.a.f.L();a.Eb=function(b,c){if(2==arguments.length)a.a.f.set(b,m,c),
|
||
c.D&&c.D.Jb(b);else return a.a.f.get(b,m)};a.xa=function(b,c,d){1===b.nodeType&&a.e.wb(b);return k(b,c,l(d),!0)};a.Lb=function(c,e,g){g=l(g);return a.xa(c,"function"===typeof e?d(e.bind(null,g,c)):a.a.Oa(e,b),g)};a.gb=function(a,b){1!==b.nodeType&&8!==b.nodeType||f(l(a),b,!0)};a.fb=function(a,b){!t&&A.jQuery&&(t=A.jQuery);if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||A.document.body;h(l(a),
|
||
b,!0)};a.Ca=function(b){switch(b.nodeType){case 1:case 8:var c=a.Eb(b);if(c)return c;if(b.parentNode)return a.Ca(b.parentNode)}return p};a.Pb=function(b){return(b=a.Ca(b))?b.$data:p};a.b("bindingHandlers",a.d);a.b("applyBindings",a.fb);a.b("applyBindingsToDescendants",a.gb);a.b("applyBindingAccessorsToNode",a.xa);a.b("applyBindingsToNode",a.Lb);a.b("contextFor",a.Ca);a.b("dataFor",a.Pb)})();var L={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,c){var d=a.a.c(c())||{};a.a.A(d,function(c,
|
||
d){d=a.a.c(d);var h=!1===d||null===d||d===p;h&&b.removeAttribute(c);8>=a.a.oa&&c in L?(c=L[c],h?b.removeAttribute(c):b[c]=d):h||b.setAttribute(c,d.toString());"name"===c&&a.a.Cb(b,h?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,c,d){function e(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):b.value}function f(){var g=b.checked,f=r?e():g;if(!a.ca.pa()&&(!k||g)){var h=a.k.t(c);l?n!==f?(g&&(a.a.Y(h,f,!0),a.a.Y(h,n,!1)),n=f):a.a.Y(h,f,g):a.g.va(h,d,"checked",
|
||
f,!0)}}function h(){var d=a.a.c(c());b.checked=l?0<=a.a.l(d,e()):g?d:e()===d}var g="checkbox"==b.type,k="radio"==b.type;if(g||k){var l=g&&a.a.c(c())instanceof Array,n=l?e():p,r=k||l;k&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.ba(f,null,{G:b});a.a.q(b,"click",f);a.ba(h,null,{G:b})}}};a.g.W.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());"object"==typeof d?a.a.A(d,function(c,d){d=a.a.c(d);a.a.ua(b,c,d)}):(d=String(d||
|
||
""),a.a.ua(b,b.__ko__cssValue,!1),b.__ko__cssValue=d,a.a.ua(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());d&&b.disabled?b.removeAttribute("disabled"):d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,f){var h=c()||{};a.a.A(h,function(g){"string"==typeof g&&a.a.q(b,g,function(b){var h,n=c()[g];if(n){try{var r=a.a.R(arguments);e=f.$data;r.unshift(e);h=n.apply(e,r)}finally{!0!==h&&(b.preventDefault?
|
||
b.preventDefault():b.returnValue=!1)}!1===d.get(g+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={vb:function(b){return function(){var c=b(),d=a.a.Sa(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.K.Ja};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.K.Ja}}},init:function(b,
|
||
c){return a.d.template.init(b,a.d.foreach.vb(c))},update:function(b,c,d,e,f){return a.d.template.update(b,a.d.foreach.vb(c),d,e,f)}};a.g.aa.foreach=!1;a.e.Q.foreach=!0;a.d.hasfocus={init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var k=b.ownerDocument;if("activeElement"in k){var f;try{f=k.activeElement}catch(h){f=k.body}e=f===b}k=c();a.g.va(k,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var f=e.bind(null,!0),h=e.bind(null,!1);a.a.q(b,"focus",f);a.a.q(b,"focusin",
|
||
f);a.a.q(b,"blur",h);a.a.q(b,"focusout",h)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===d||(d?b.focus():b.blur(),a.k.t(a.a.ha,null,[b,d?"focusin":"focusout"]))}};a.g.W.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.g.W.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Va(b,c())}};H("if");H("ifnot",!1,!0);H("with",!0,!1,function(a,c){return a.createChildContext(c)});var J={};a.d.options={init:function(b){if("select"!==
|
||
a.a.B(b))throw Error("options binding applies only to SELECT elements");for(;0<b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,c,d){function e(){return a.a.la(b.options,function(a){return a.selected})}function f(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function h(c,d){if(r.length){var e=0<=a.a.l(r,a.i.p(d[0]));a.a.Db(d[0],e);m&&!e&&a.k.t(a.a.ha,null,[b,"change"])}}var g=0!=b.length&&b.multiple?b.scrollTop:null,k=a.a.c(c()),l=d.get("optionsIncludeDestroyed");
|
||
c={};var n,r;r=b.multiple?a.a.ya(e(),a.i.p):0<=b.selectedIndex?[a.i.p(b.options[b.selectedIndex])]:[];k&&("undefined"==typeof k.length&&(k=[k]),n=a.a.la(k,function(b){return l||b===p||null===b||!a.a.c(b._destroy)}),d.has("optionsCaption")&&(k=a.a.c(d.get("optionsCaption")),null!==k&&k!==p&&n.unshift(J)));var m=!1;c.beforeRemove=function(a){b.removeChild(a)};k=h;d.has("optionsAfterRender")&&(k=function(b,c){h(0,c);a.k.t(d.get("optionsAfterRender"),null,[c[0],b!==J?b:p])});a.a.Ua(b,n,function(c,e,g){g.length&&
|
||
(r=g[0].selected?[a.i.p(g[0])]:[],m=!0);e=b.ownerDocument.createElement("option");c===J?(a.a.Xa(e,d.get("optionsCaption")),a.i.X(e,p)):(g=f(c,d.get("optionsValue"),c),a.i.X(e,a.a.c(g)),c=f(c,d.get("optionsText"),g),a.a.Xa(e,c));return[e]},c,k);a.k.t(function(){d.get("valueAllowUnset")&&d.has("value")?a.i.X(b,a.a.c(d.get("value")),!0):(b.multiple?r.length&&e().length<r.length:r.length&&0<=b.selectedIndex?a.i.p(b.options[b.selectedIndex])!==r[0]:r.length||0<=b.selectedIndex)&&a.a.ha(b,"change")});a.a.Tb(b);
|
||
g&&20<Math.abs(g-b.scrollTop)&&(b.scrollTop=g)}};a.d.options.Pa=a.a.f.L();a.d.selectedOptions={after:["options","foreach"],init:function(b,c,d){a.a.q(b,"change",function(){var e=c(),f=[];a.a.r(b.getElementsByTagName("option"),function(b){b.selected&&f.push(a.i.p(b))});a.g.va(e,d,"selectedOptions",f)})},update:function(b,c){if("select"!=a.a.B(b))throw Error("values binding applies only to SELECT elements");var d=a.a.c(c());d&&"number"==typeof d.length&&a.a.r(b.getElementsByTagName("option"),function(b){var c=
|
||
0<=a.a.l(d,a.i.p(b));a.a.Db(b,c)})}};a.g.W.selectedOptions=!0;a.d.style={update:function(b,c){var d=a.a.c(c()||{});a.a.A(d,function(c,d){d=a.a.c(d);b.style[c]=d||""})}};a.d.submit={init:function(b,c,d,e,f){if("function"!=typeof c())throw Error("The value for a submit binding must be a function");a.a.q(b,"submit",function(a){var d,e=c();try{d=e.call(f.$data,b)}finally{!0!==d&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},
|
||
update:function(b,c){a.a.Xa(b,c())}};a.e.Q.text=!0;a.d.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+ ++a.d.uniqueName.Ob;a.a.Cb(b,d)}}};a.d.uniqueName.Ob=0;a.d.value={after:["options","foreach"],init:function(b,c,d){function e(){g=!1;var e=c(),f=a.i.p(b);a.g.va(e,d,"value",f)}var f=["change"],h=d.get("valueUpdate"),g=!1;h&&("string"==typeof h&&(h=[h]),a.a.$(f,h),f=a.a.ib(f));!a.a.oa||"input"!=b.tagName.toLowerCase()||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||
|
||
-1!=a.a.l(f,"propertychange")||(a.a.q(b,"propertychange",function(){g=!0}),a.a.q(b,"focus",function(){g=!1}),a.a.q(b,"blur",function(){g&&e()}));a.a.r(f,function(c){var d=e;a.a.kc(c,"after")&&(d=function(){setTimeout(e,0)},c=c.substring(5));a.a.q(b,c,d)})},update:function(b,c,d){var e=a.a.c(c());c=a.i.p(b);if(e!==c)if("select"===a.a.B(b)){var f=d.get("valueAllowUnset");d=function(){a.i.X(b,e,f)};d();f||e===a.i.p(b)?setTimeout(d,0):a.k.t(a.a.ha,null,[b,"change"])}else a.i.X(b,e)}};a.g.W.value=!0;a.d.visible=
|
||
{update:function(b,c){var d=a.a.c(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(c,d,e,f,h){return a.d.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,f,h)}}})("click");a.C=function(){};a.C.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource");};a.C.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.C.prototype.makeTemplateSource=
|
||
function(b,c){if("string"==typeof b){c=c||w;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.n.j(d)}if(1==b.nodeType||8==b.nodeType)return new a.n.Z(b);throw Error("Unknown template type: "+b);};a.C.prototype.renderTemplate=function(a,c,d,e){a=this.makeTemplateSource(a,e);return this.renderTemplateSource(a,c,d)};a.C.prototype.isTemplateRewritten=function(a,c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.C.prototype.rewriteTemplate=
|
||
function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.C);a.Za=function(){function b(b,c,d,g){b=a.g.Ra(b);for(var k=a.g.aa,l=0;l<b.length;l++){var n=b[l].key;if(k.hasOwnProperty(n)){var r=k[n];if("function"===typeof r){if(n=r(b[l].value))throw Error(n);}else if(!r)throw Error("This template engine does not support the '"+n+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.g.qa(b,
|
||
{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return g.createJavaScriptEvaluatorBlock(d)+c}var c=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Ub:function(b,c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.Za.dc(b,c)},d)},dc:function(a,f){return a.replace(c,function(a,c,d,e,n){return b(n,c,d,f)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e",
|
||
"#comment",f)})},Mb:function(b,c){return a.w.Na(function(d,g){var k=d.nextSibling;k&&k.nodeName.toLowerCase()===c&&a.xa(k,b,g)})}}}();a.b("__tr_ambtns",a.Za.Mb);(function(){a.n={};a.n.j=function(a){this.j=a};a.n.j.prototype.text=function(){var b=a.a.B(this.j),b="script"===b?"text":"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.j[b];var c=arguments[0];"innerHTML"===b?a.a.Va(this.j,c):this.j[b]=c};var b=a.a.f.L()+"_";a.n.j.prototype.data=function(c){if(1===arguments.length)return a.a.f.get(this.j,
|
||
b+c);a.a.f.set(this.j,b+c,arguments[1])};var c=a.a.f.L();a.n.Z=function(a){this.j=a};a.n.Z.prototype=new a.n.j;a.n.Z.prototype.text=function(){if(0==arguments.length){var b=a.a.f.get(this.j,c)||{};b.$a===p&&b.Ba&&(b.$a=b.Ba.innerHTML);return b.$a}a.a.f.set(this.j,c,{$a:arguments[0]})};a.n.j.prototype.nodes=function(){if(0==arguments.length)return(a.a.f.get(this.j,c)||{}).Ba;a.a.f.set(this.j,c,{Ba:arguments[0]})};a.b("templateSources",a.n);a.b("templateSources.domElement",a.n.j);a.b("templateSources.anonymousTemplate",
|
||
a.n.Z)})();(function(){function b(b,c,d){var e;for(c=a.e.nextSibling(c);b&&(e=b)!==c;)b=a.e.nextSibling(e),d(e,b)}function c(c,d){if(c.length){var e=c[0],f=c[c.length-1],h=e.parentNode,m=a.J.instance,q=m.preprocessNode;if(q){b(e,f,function(a,b){var c=a.previousSibling,d=q.call(m,a);d&&(a===e&&(e=d[0]||b),a===f&&(f=d[d.length-1]||c))});c.length=0;if(!e)return;e===f?c.push(e):(c.push(e,f),a.a.ea(c,h))}b(e,f,function(b){1!==b.nodeType&&8!==b.nodeType||a.fb(d,b)});b(e,f,function(b){1!==b.nodeType&&8!==
|
||
b.nodeType||a.w.Ib(b,[d])});a.a.ea(c,h)}}function d(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,e,h,n,r){r=r||{};var m=b&&d(b),m=m&&m.ownerDocument,q=r.templateEngine||f;a.Za.Ub(h,q,m);h=q.renderTemplate(h,n,r,m);if("number"!=typeof h.length||0<h.length&&"number"!=typeof h[0].nodeType)throw Error("Template engine must return an array of DOM nodes");m=!1;switch(e){case "replaceChildren":a.e.U(b,h);m=!0;break;case "replaceNode":a.a.Bb(b,h);m=!0;break;case "ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+
|
||
e);}m&&(c(h,n),r.afterRender&&a.k.t(r.afterRender,null,[h,n.$data]));return h}var f;a.Wa=function(b){if(b!=p&&!(b instanceof a.C))throw Error("templateEngine must inherit from ko.templateEngine");f=b};a.Ta=function(b,c,h,n,r){h=h||{};if((h.templateEngine||f)==p)throw Error("Set a template engine before calling renderTemplate");r=r||"replaceChildren";if(n){var m=d(n);return a.h(function(){var f=c&&c instanceof a.I?c:new a.I(a.a.c(c)),p=a.v(b)?b():"function"==typeof b?b(f.$data,f):b,f=e(n,r,p,f,h);
|
||
"replaceNode"==r&&(n=f,m=d(n))},null,{Da:function(){return!m||!a.a.Ea(m)},G:m&&"replaceNode"==r?m.parentNode:m})}return a.w.Na(function(d){a.Ta(b,c,h,d,"replaceNode")})};a.jc=function(b,d,f,h,r){function m(a,b){c(b,s);f.afterRender&&f.afterRender(b,a)}function q(a,c){s=r.createChildContext(a,f.as,function(a){a.$index=c});var d="function"==typeof b?b(a,s):b;return e(null,"ignoreTargetNode",d,s,f)}var s;return a.h(function(){var b=a.a.c(d)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.la(b,function(b){return f.includeDestroyed||
|
||
b===p||null===b||!a.a.c(b._destroy)});a.k.t(a.a.Ua,null,[h,b,q,f,m])},null,{G:h})};var h=a.a.f.L();a.d.template={init:function(b,c){var d=a.a.c(c());"string"==typeof d||d.name?a.e.da(b):(d=a.e.childNodes(b),d=a.a.ec(d),(new a.n.Z(b)).nodes(d));return{controlsDescendantBindings:!0}},update:function(b,c,d,e,f){var m=c(),q;c=a.a.c(m);d=!0;e=null;"string"==typeof c?c={}:(m=c.name,"if"in c&&(d=a.a.c(c["if"])),d&&"ifnot"in c&&(d=!a.a.c(c.ifnot)),q=a.a.c(c.data));"foreach"in c?e=a.jc(m||b,d&&c.foreach||
|
||
[],c,b,f):d?(f="data"in c?f.createChildContext(q,c.as):f,e=a.Ta(m||b,f,c,b)):a.e.da(b);f=e;(q=a.a.f.get(b,h))&&"function"==typeof q.F&&q.F();a.a.f.set(b,h,f&&f.ga()?f:p)}};a.g.aa.template=function(b){b=a.g.Ra(b);return 1==b.length&&b[0].unknown||a.g.bc(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};a.e.Q.template=!0})();a.b("setTemplateEngine",a.Wa);a.b("renderTemplate",a.Ta);a.a.nb=function(a,c,d){if(a.length&&c.length){var e,f,h,g,k;for(e=
|
||
f=0;(!d||e<d)&&(g=a[f]);++f){for(h=0;k=c[h];++h)if(g.value===k.value){g.moved=k.index;k.moved=g.index;c.splice(h,1);e=h=0;break}e+=h}}};a.a.Aa=function(){function b(b,d,e,f,h){var g=Math.min,k=Math.max,l=[],n,p=b.length,m,q=d.length,s=q-p||1,t=p+q+1,u,w,y;for(n=0;n<=p;n++)for(w=u,l.push(u=[]),y=g(q,n+s),m=k(0,n-1);m<=y;m++)u[m]=m?n?b[n-1]===d[m-1]?w[m-1]:g(w[m]||t,u[m-1]||t)+1:m+1:n+1;g=[];k=[];s=[];n=p;for(m=q;n||m;)q=l[n][m]-1,m&&q===l[n][m-1]?k.push(g[g.length]={status:e,value:d[--m],index:m}):
|
||
n&&q===l[n-1][m]?s.push(g[g.length]={status:f,value:b[--n],index:n}):(--m,--n,h.sparse||g.push({status:"retained",value:d[m]}));a.a.nb(k,s,10*p);return g.reverse()}return function(a,d,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};a=a||[];d=d||[];return a.length<=d.length?b(a,d,"added","deleted",e):b(d,a,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.Aa);(function(){function b(b,c,f,h,g){var k=[],l=a.h(function(){var l=c(f,g,a.a.ea(k,b))||[];0<k.length&&(a.a.Bb(k,l),h&&a.k.t(h,null,[f,
|
||
l,g]));k.length=0;a.a.$(k,l)},null,{G:b,Da:function(){return!a.a.eb(k)}});return{S:k,h:l.ga()?l:p}}var c=a.a.f.L();a.a.Ua=function(d,e,f,h,g){function k(b,c){v=r[c];u!==c&&(z[b]=v);v.Ia(u++);a.a.ea(v.S,d);s.push(v);y.push(v)}function l(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.r(c[d].S,function(a){b(a,d,c[d].ka)})}e=e||[];h=h||{};var n=a.a.f.get(d,c)===p,r=a.a.f.get(d,c)||[],m=a.a.ya(r,function(a){return a.ka}),q=a.a.Aa(m,e,h.dontLimitMoves),s=[],t=0,u=0,w=[],y=[];e=[];for(var z=[],m=[],
|
||
v,x=0,A,C;A=q[x];x++)switch(C=A.moved,A.status){case "deleted":C===p&&(v=r[t],v.h&&v.h.F(),w.push.apply(w,a.a.ea(v.S,d)),h.beforeRemove&&(e[x]=v,y.push(v)));t++;break;case "retained":k(x,t++);break;case "added":C!==p?k(x,C):(v={ka:A.value,Ia:a.m(u++)},s.push(v),y.push(v),n||(m[x]=v))}l(h.beforeMove,z);a.a.r(w,h.beforeRemove?a.M:a.removeNode);for(var x=0,n=a.e.firstChild(d),E;v=y[x];x++){v.S||a.a.extend(v,b(d,f,v.ka,g,v.Ia));for(t=0;q=v.S[t];n=q.nextSibling,E=q,t++)q!==n&&a.e.rb(d,q,E);!v.Zb&&g&&(g(v.ka,
|
||
v.S,v.Ia),v.Zb=!0)}l(h.beforeRemove,e);l(h.afterMove,z);l(h.afterAdd,m);a.a.f.set(d,c,s)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Ua);a.K=function(){this.allowTemplateRewriting=!1};a.K.prototype=new a.C;a.K.prototype.renderTemplateSource=function(b){var c=(9>a.a.oa?0:b.nodes)?b.nodes():null;if(c)return a.a.R(c.cloneNode(!0).childNodes);b=b.text();return a.a.Qa(b)};a.K.Ja=new a.K;a.Wa(a.K.Ja);a.b("nativeTemplateEngine",a.K);(function(){a.La=function(){var a=this.ac=function(){if(!t||
|
||
!t.tmpl)return 0;try{if(0<=t.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,f){f=f||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=t.template(null,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=t.extend({koBindingContext:e},f.templateOptions);e=t.tmpl(h,b,e);e.appendTo(w.createElement("div"));
|
||
t.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){w.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(t.tmpl.tag.ko_code={open:"__.push($1 || '');"},t.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.La.prototype=new a.C;var b=new a.La;0<b.ac&&a.Wa(b);a.b("jqueryTmplTemplateEngine",a.La)})()})})();})();
|
||
/// Knockout Mapping plugin v2.4.1
|
||
/// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/
|
||
/// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
||
(function(e){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?e(require("knockout"),exports):"function"===typeof define&&define.amd?define(["knockout","exports"],e):e(ko,ko.mapping={})})(function(e,f){function y(b,c){var a,d;for(d in c)if(c.hasOwnProperty(d)&&c[d])if(a=f.getType(b[d]),d&&b[d]&&"array"!==a&&"string"!==a)y(b[d],c[d]);else if("array"===f.getType(b[d])&&"array"===f.getType(c[d])){a=b;for(var e=d,l=b[d],n=c[d],t={},g=l.length-1;0<=g;--g)t[l[g]]=l[g];for(g=
|
||
n.length-1;0<=g;--g)t[n[g]]=n[g];l=[];n=void 0;for(n in t)l.push(t[n]);a[e]=l}else b[d]=c[d]}function E(b,c){var a={};y(a,b);y(a,c);return a}function z(b,c){for(var a=E({},b),e=L.length-1;0<=e;e--){var f=L[e];a[f]&&(a[""]instanceof Object||(a[""]={}),a[""][f]=a[f],delete a[f])}c&&(a.ignore=h(c.ignore,a.ignore),a.include=h(c.include,a.include),a.copy=h(c.copy,a.copy),a.observe=h(c.observe,a.observe));a.ignore=h(a.ignore,j.ignore);a.include=h(a.include,j.include);a.copy=h(a.copy,j.copy);a.observe=h(a.observe,
|
||
j.observe);a.mappedProperties=a.mappedProperties||{};a.copiedProperties=a.copiedProperties||{};return a}function h(b,c){"array"!==f.getType(b)&&(b="undefined"===f.getType(b)?[]:[b]);"array"!==f.getType(c)&&(c="undefined"===f.getType(c)?[]:[c]);return e.utils.arrayGetDistinctValues(b.concat(c))}function F(b,c,a,d,k,l,n){var t="array"===f.getType(e.utils.unwrapObservable(c));l=l||"";if(f.isMapped(b)){var g=e.utils.unwrapObservable(b)[p];a=E(g,a)}var j=n||k,h=function(){return a[d]&&a[d].create instanceof
|
||
Function},x=function(b){var f=G,g=e.dependentObservable;e.dependentObservable=function(a,b,c){c=c||{};a&&"object"==typeof a&&(c=a);var d=c.deferEvaluation,M=!1;c.deferEvaluation=!0;a=new H(a,b,c);if(!d){var g=a,d=e.dependentObservable;e.dependentObservable=H;a=e.isWriteableObservable(g);e.dependentObservable=d;d=H({read:function(){M||(e.utils.arrayRemoveItem(f,g),M=!0);return g.apply(g,arguments)},write:a&&function(a){return g(a)},deferEvaluation:!0});d.__DO=g;a=d;f.push(a)}return a};e.dependentObservable.fn=
|
||
H.fn;e.computed=e.dependentObservable;b=e.utils.unwrapObservable(k)instanceof Array?a[d].create({data:b||c,parent:j,skip:N}):a[d].create({data:b||c,parent:j});e.dependentObservable=g;e.computed=e.dependentObservable;return b},u=function(){return a[d]&&a[d].update instanceof Function},v=function(b,f){var g={data:f||c,parent:j,target:e.utils.unwrapObservable(b)};e.isWriteableObservable(b)&&(g.observable=b);return a[d].update(g)};if(n=I.get(c))return n;d=d||"";if(t){var t=[],s=!1,m=function(a){return a};
|
||
a[d]&&a[d].key&&(m=a[d].key,s=!0);e.isObservable(b)||(b=e.observableArray([]),b.mappedRemove=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.remove(function(a){return c(m(a))})},b.mappedRemoveAll=function(a){var c=C(a,m);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,m(a))})},b.mappedDestroy=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.destroy(function(a){return c(m(a))})},b.mappedDestroyAll=function(a){var c=C(a,m);return b.destroy(function(a){return-1!=
|
||
e.utils.arrayIndexOf(c,m(a))})},b.mappedIndexOf=function(a){var c=C(b(),m);a=m(a);return e.utils.arrayIndexOf(c,a)},b.mappedGet=function(a){return b()[b.mappedIndexOf(a)]},b.mappedCreate=function(a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?x(a):a;u()&&(a=v(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c});n=C(e.utils.unwrapObservable(b),m).sort();g=C(c,m);s&&g.sort();s=e.utils.compareArrays(n,g);n={};var J,A=e.utils.unwrapObservable(c),
|
||
y={},z=!0,g=0;for(J=A.length;g<J;g++){var r=m(A[g]);if(void 0===r||r instanceof Object){z=!1;break}y[r]=A[g]}var A=[],B=0,g=0;for(J=s.length;g<J;g++){var r=s[g],q,w=l+"["+g+"]";switch(r.status){case "added":var D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=F(void 0,D,a,d,b,w,k);h()||(q=e.utils.unwrapObservable(q));w=O(e.utils.unwrapObservable(c),D,n);q===N?B++:A[w-B]=q;n[w]=!0;break;case "retained":D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=K(b,r.value,m);F(q,D,a,d,b,w,
|
||
k);w=O(e.utils.unwrapObservable(c),D,n);A[w]=q;n[w]=!0;break;case "deleted":q=K(b,r.value,m)}t.push({event:r.status,item:q})}b(A);a[d]&&a[d].arrayChanged&&e.utils.arrayForEach(t,function(b){a[d].arrayChanged(b.event,b.item)})}else if(P(c)){b=e.utils.unwrapObservable(b);if(!b){if(h())return s=x(),u()&&(s=v(s)),s;if(u())return v(s);b={}}u()&&(b=v(b));I.save(c,b);if(u())return b;Q(c,function(d){var f=l.length?l+"."+d:d;if(-1==e.utils.arrayIndexOf(a.ignore,f))if(-1!=e.utils.arrayIndexOf(a.copy,f))b[d]=
|
||
c[d];else if("object"!=typeof c[d]&&"array"!=typeof c[d]&&0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=c[d],a.copiedProperties[f]=!0;else{var g=I.get(c[d]),k=F(b[d],c[d],a,d,b,f,b),g=g||k;if(0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=g(),a.copiedProperties[f]=!0;else{if(e.isWriteableObservable(b[d])){if(g=e.utils.unwrapObservable(g),b[d]()!==g)b[d](g)}else g=void 0===b[d]?g:e.utils.unwrapObservable(g),b[d]=g;a.mappedProperties[f]=!0}}})}else switch(f.getType(c)){case "function":u()?
|
||
e.isWriteableObservable(c)?(c(v(c)),b=c):b=v(c):b=c;break;default:if(e.isWriteableObservable(b))return q=u()?v(b):e.utils.unwrapObservable(c),b(q),q;h()||u();b=h()?x():e.observable(e.utils.unwrapObservable(c));u()&&b(v(b))}return b}function O(b,c,a){for(var d=0,e=b.length;d<e;d++)if(!0!==a[d]&&b[d]===c)return d;return null}function R(b,c){var a;c&&(a=c(b));"undefined"===f.getType(a)&&(a=b);return e.utils.unwrapObservable(a)}function K(b,c,a){b=e.utils.unwrapObservable(b);for(var d=0,f=b.length;d<
|
||
f;d++){var l=b[d];if(R(l,a)===c)return l}throw Error("When calling ko.update*, the key '"+c+"' was not found!");}function C(b,c){return e.utils.arrayMap(e.utils.unwrapObservable(b),function(a){return c?R(a,c):a})}function Q(b,c){if("array"===f.getType(b))for(var a=0;a<b.length;a++)c(a);else for(a in b)c(a)}function P(b){var c=f.getType(b);return("object"===c||"array"===c)&&null!==b}function T(){var b=[],c=[];this.save=function(a,d){var f=e.utils.arrayIndexOf(b,a);0<=f?c[f]=d:(b.push(a),c.push(d))};
|
||
this.get=function(a){a=e.utils.arrayIndexOf(b,a);return 0<=a?c[a]:void 0}}function S(){var b={},c=function(a){var c;try{c=a}catch(e){c="$$$"}a=b[c];void 0===a&&(a=new T,b[c]=a);return a};this.save=function(a,b){c(a).save(a,b)};this.get=function(a){return c(a).get(a)}}var p="__ko_mapping__",H=e.dependentObservable,B=0,G,I,L=["create","update","key","arrayChanged"],N={},x={include:["_destroy"],ignore:[],copy:[],observe:[]},j=x;f.isMapped=function(b){return(b=e.utils.unwrapObservable(b))&&b[p]};f.fromJS=
|
||
function(b){if(0==arguments.length)throw Error("When calling ko.fromJS, pass the object you want to convert.");try{B++||(G=[],I=new S);var c,a;2==arguments.length&&(arguments[1][p]?a=arguments[1]:c=arguments[1]);3==arguments.length&&(c=arguments[1],a=arguments[2]);a&&(c=E(c,a[p]));c=z(c);var d=F(a,b,c);a&&(d=a);if(!--B)for(;G.length;){var e=G.pop();e&&(e(),e.__DO.throttleEvaluation=e.throttleEvaluation)}d[p]=E(d[p],c);return d}catch(f){throw B=0,f;}};f.fromJSON=function(b){var c=e.utils.parseJson(b);
|
||
arguments[0]=c;return f.fromJS.apply(this,arguments)};f.updateFromJS=function(){throw Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");};f.updateFromJSON=function(){throw Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");};f.toJS=function(b,c){j||f.resetDefaultOptions();if(0==arguments.length)throw Error("When calling ko.mapping.toJS, pass the object you want to convert.");
|
||
if("array"!==f.getType(j.ignore))throw Error("ko.mapping.defaultOptions().ignore should be an array.");if("array"!==f.getType(j.include))throw Error("ko.mapping.defaultOptions().include should be an array.");if("array"!==f.getType(j.copy))throw Error("ko.mapping.defaultOptions().copy should be an array.");c=z(c,b[p]);return f.visitModel(b,function(a){return e.utils.unwrapObservable(a)},c)};f.toJSON=function(b,c){var a=f.toJS(b,c);return e.utils.stringifyJson(a)};f.defaultOptions=function(){if(0<arguments.length)j=
|
||
arguments[0];else return j};f.resetDefaultOptions=function(){j={include:x.include.slice(0),ignore:x.ignore.slice(0),copy:x.copy.slice(0)}};f.getType=function(b){if(b&&"object"===typeof b){if(b.constructor===Date)return"date";if(b.constructor===Array)return"array"}return typeof b};f.visitModel=function(b,c,a){a=a||{};a.visitedObjects=a.visitedObjects||new S;var d,k=e.utils.unwrapObservable(b);if(P(k))a=z(a,k[p]),c(b,a.parentName),d="array"===f.getType(k)?[]:{};else return c(b,a.parentName);a.visitedObjects.save(b,
|
||
d);var l=a.parentName;Q(k,function(b){if(!(a.ignore&&-1!=e.utils.arrayIndexOf(a.ignore,b))){var j=k[b],g=a,h=l||"";"array"===f.getType(k)?l&&(h+="["+b+"]"):(l&&(h+="."),h+=b);g.parentName=h;if(!(-1===e.utils.arrayIndexOf(a.copy,b)&&-1===e.utils.arrayIndexOf(a.include,b)&&k[p]&&k[p].mappedProperties&&!k[p].mappedProperties[b]&&k[p].copiedProperties&&!k[p].copiedProperties[b]&&"array"!==f.getType(k)))switch(f.getType(e.utils.unwrapObservable(j))){case "object":case "array":case "undefined":g=a.visitedObjects.get(j);
|
||
d[b]="undefined"!==f.getType(g)?g:f.visitModel(j,c,a);break;default:d[b]=c(j,a.parentName)}}});return d}});
|
||
|
||
// knockout-sortable 0.8.8 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license
|
||
!function(a){"function"==typeof define&&define.amd?define(["knockout","jquery","jquery.ui.sortable"],a):a(window.ko,jQuery)}(function(a,b){var c="ko_sortItem",d="ko_sourceIndex",e="ko_sortList",f="ko_parentList",g="ko_dragItem",h=a.utils.unwrapObservable,i=a.utils.domData.get,j=a.utils.domData.set,k=function(b,d){a.utils.arrayForEach(b,function(a){1===a.nodeType&&(j(a,c,d),j(a,f,i(a.parentNode,e)))})},l=function(b,c){var d,e={},f=h(b())||{};return f.data?(e[c]=f.data,e.name=f.template):e[c]=b(),a.utils.arrayForEach(["afterAdd","afterRender","as","beforeRemove","includeDestroyed","templateEngine","templateOptions"],function(b){e[b]=f[b]||a.bindingHandlers.sortable[b]}),"foreach"===c&&(e.afterRender?(d=e.afterRender,e.afterRender=function(a,b){k.call(b,a,b),d.call(b,a,b)}):e.afterRender=k),e},m=function(a,b){var c=h(b);if(c)for(var d=0;a>d;d++)c[d]&&h(c[d]._destroy)&&a++;return a};a.bindingHandlers.sortable={init:function(k,n,o,p,q){var r,s,t=b(k),u=h(n())||{},v=l(n,"foreach"),w={};t.contents().each(function(){this&&1!==this.nodeType&&k.removeChild(this)}),b.extend(!0,w,a.bindingHandlers.sortable),u.options&&w.options&&(a.utils.extend(w.options,u.options),delete u.options),a.utils.extend(w,u),w.connectClass&&(a.isObservable(w.allowDrop)||"function"==typeof w.allowDrop)?a.computed({read:function(){var b=h(w.allowDrop),c="function"==typeof b?b.call(this,v.foreach):b;a.utils.toggleDomNodeCssClass(k,w.connectClass,c)},disposeWhenNodeIsRemoved:k},this):a.utils.toggleDomNodeCssClass(k,w.connectClass,w.allowDrop),a.bindingHandlers.template.init(k,function(){return v},o,p,q),r=w.options.start,s=w.options.update;var x=setTimeout(function(){var l;t.sortable(a.utils.extend(w.options,{start:function(b,c){var e=c.item[0];j(e,d,a.utils.arrayIndexOf(c.item.parent().children(),e)),c.item.find("input:focus").change(),r&&r.apply(this,arguments)},receive:function(a,b){l=i(b.item[0],g),l&&(l.clone&&(l=l.clone()),w.dragged&&(l=w.dragged.call(this,l,a,b)||l))},update:function(g,h){var k,n,o,p,q,r=h.item[0],t=h.item.parent()[0],u=i(r,c)||l;if(l=null,u&&(this===t||b.contains(this,t))){if(k=i(r,f),o=i(r,d),n=i(r.parentNode,e),p=a.utils.arrayIndexOf(h.item.parent().children(),r),v.includeDestroyed||(o=m(o,k),p=m(p,n)),(w.beforeMove||w.afterMove)&&(q={item:u,sourceParent:k,sourceParentNode:k&&h.sender||r.parentNode,sourceIndex:o,targetParent:n,targetIndex:p,cancelDrop:!1},w.beforeMove&&w.beforeMove.call(this,q,g,h)),k?b(k===n?this:h.sender).sortable("cancel"):b(r).remove(),q&&q.cancelDrop)return;p>=0&&(k&&(k.splice(o,1),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates()),n.splice(p,0,u)),j(r,c,null),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates(),w.afterMove&&w.afterMove.call(this,q,g,h)}s&&s.apply(this,arguments)},connectWith:w.connectClass?"."+w.connectClass:!1})),void 0!==w.isEnabled&&a.computed({read:function(){t.sortable(h(w.isEnabled)?"enable":"disable")},disposeWhenNodeIsRemoved:k})},0);return a.utils.domNodeDisposal.addDisposeCallback(k,function(){(t.data("ui-sortable")||t.data("sortable"))&&t.sortable("destroy"),clearTimeout(x)}),{controlsDescendantBindings:!0}},update:function(b,c,d,f,g){var h=l(c,"foreach");j(b,e,h.foreach),a.bindingHandlers.template.update(b,function(){return h},d,f,g)},connectClass:"ko_container",allowDrop:!0,afterMove:null,beforeMove:null,options:{}},a.bindingHandlers.draggable={init:function(c,d,e,f,i){var k=h(d())||{},m=k.options||{},n=a.utils.extend({},a.bindingHandlers.draggable.options),o=l(d,"data"),p=k.connectClass||a.bindingHandlers.draggable.connectClass,q=void 0!==k.isEnabled?k.isEnabled:a.bindingHandlers.draggable.isEnabled;return k=k.data||k,j(c,g,k),a.utils.extend(n,m),n.connectToSortable=p?"."+p:!1,b(c).draggable(n),void 0!==q&&a.computed({read:function(){b(c).draggable(h(q)?"enable":"disable")},disposeWhenNodeIsRemoved:c}),a.bindingHandlers.template.init(c,function(){return o},e,f,i)},update:function(b,c,d,e,f){var g=l(c,"data");return a.bindingHandlers.template.update(b,function(){return g},d,e,f)},connectClass:a.bindingHandlers.sortable.connectClass,options:{helper:"clone"}}});
|
||
// Underscore.js 1.6.0
|
||
// http://underscorejs.org
|
||
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
// Underscore may be freely distributed under the MIT license.
|
||
|
||
(function() {
|
||
|
||
// Baseline setup
|
||
// --------------
|
||
|
||
// Establish the root object, `window` in the browser, or `exports` on the server.
|
||
var root = this;
|
||
|
||
// Save the previous value of the `_` variable.
|
||
var previousUnderscore = root._;
|
||
|
||
// Establish the object that gets returned to break out of a loop iteration.
|
||
var breaker = {};
|
||
|
||
// Save bytes in the minified (but not gzipped) version:
|
||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||
|
||
// Create quick reference variables for speed access to core prototypes.
|
||
var
|
||
push = ArrayProto.push,
|
||
slice = ArrayProto.slice,
|
||
concat = ArrayProto.concat,
|
||
toString = ObjProto.toString,
|
||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||
|
||
// All **ECMAScript 5** native function implementations that we hope to use
|
||
// are declared here.
|
||
var
|
||
nativeForEach = ArrayProto.forEach,
|
||
nativeMap = ArrayProto.map,
|
||
nativeReduce = ArrayProto.reduce,
|
||
nativeReduceRight = ArrayProto.reduceRight,
|
||
nativeFilter = ArrayProto.filter,
|
||
nativeEvery = ArrayProto.every,
|
||
nativeSome = ArrayProto.some,
|
||
nativeIndexOf = ArrayProto.indexOf,
|
||
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
||
nativeIsArray = Array.isArray,
|
||
nativeKeys = Object.keys,
|
||
nativeBind = FuncProto.bind;
|
||
|
||
// Create a safe reference to the Underscore object for use below.
|
||
var _ = function(obj) {
|
||
if (obj instanceof _) return obj;
|
||
if (!(this instanceof _)) return new _(obj);
|
||
this._wrapped = obj;
|
||
};
|
||
|
||
// Export the Underscore object for **Node.js**, with
|
||
// backwards-compatibility for the old `require()` API. If we're in
|
||
// the browser, add `_` as a global object via a string identifier,
|
||
// for Closure Compiler "advanced" mode.
|
||
if (typeof exports !== 'undefined') {
|
||
if (typeof module !== 'undefined' && module.exports) {
|
||
exports = module.exports = _;
|
||
}
|
||
exports._ = _;
|
||
} else {
|
||
root._ = _;
|
||
}
|
||
|
||
// Current version.
|
||
_.VERSION = '1.6.0';
|
||
|
||
// Collection Functions
|
||
// --------------------
|
||
|
||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
||
var each = _.each = _.forEach = function(obj, iterator, context) {
|
||
if (obj == null) return obj;
|
||
if (nativeForEach && obj.forEach === nativeForEach) {
|
||
obj.forEach(iterator, context);
|
||
} else if (obj.length === +obj.length) {
|
||
for (var i = 0, length = obj.length; i < length; i++) {
|
||
if (iterator.call(context, obj[i], i, obj) === breaker) return;
|
||
}
|
||
} else {
|
||
var keys = _.keys(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Return the results of applying the iterator to each element.
|
||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
||
_.map = _.collect = function(obj, iterator, context) {
|
||
var results = [];
|
||
if (obj == null) return results;
|
||
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
||
each(obj, function(value, index, list) {
|
||
results.push(iterator.call(context, value, index, list));
|
||
});
|
||
return results;
|
||
};
|
||
|
||
var reduceError = 'Reduce of empty array with no initial value';
|
||
|
||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
||
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
||
var initial = arguments.length > 2;
|
||
if (obj == null) obj = [];
|
||
if (nativeReduce && obj.reduce === nativeReduce) {
|
||
if (context) iterator = _.bind(iterator, context);
|
||
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
|
||
}
|
||
each(obj, function(value, index, list) {
|
||
if (!initial) {
|
||
memo = value;
|
||
initial = true;
|
||
} else {
|
||
memo = iterator.call(context, memo, value, index, list);
|
||
}
|
||
});
|
||
if (!initial) throw new TypeError(reduceError);
|
||
return memo;
|
||
};
|
||
|
||
// The right-associative version of reduce, also known as `foldr`.
|
||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
||
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
||
var initial = arguments.length > 2;
|
||
if (obj == null) obj = [];
|
||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
||
if (context) iterator = _.bind(iterator, context);
|
||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||
}
|
||
var length = obj.length;
|
||
if (length !== +length) {
|
||
var keys = _.keys(obj);
|
||
length = keys.length;
|
||
}
|
||
each(obj, function(value, index, list) {
|
||
index = keys ? keys[--length] : --length;
|
||
if (!initial) {
|
||
memo = obj[index];
|
||
initial = true;
|
||
} else {
|
||
memo = iterator.call(context, memo, obj[index], index, list);
|
||
}
|
||
});
|
||
if (!initial) throw new TypeError(reduceError);
|
||
return memo;
|
||
};
|
||
|
||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||
_.find = _.detect = function(obj, predicate, context) {
|
||
var result;
|
||
any(obj, function(value, index, list) {
|
||
if (predicate.call(context, value, index, list)) {
|
||
result = value;
|
||
return true;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Return all the elements that pass a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
||
// Aliased as `select`.
|
||
_.filter = _.select = function(obj, predicate, context) {
|
||
var results = [];
|
||
if (obj == null) return results;
|
||
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (predicate.call(context, value, index, list)) results.push(value);
|
||
});
|
||
return results;
|
||
};
|
||
|
||
// Return all the elements for which a truth test fails.
|
||
_.reject = function(obj, predicate, context) {
|
||
return _.filter(obj, function(value, index, list) {
|
||
return !predicate.call(context, value, index, list);
|
||
}, context);
|
||
};
|
||
|
||
// Determine whether all of the elements match a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `every` if available.
|
||
// Aliased as `all`.
|
||
_.every = _.all = function(obj, predicate, context) {
|
||
predicate || (predicate = _.identity);
|
||
var result = true;
|
||
if (obj == null) return result;
|
||
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
|
||
});
|
||
return !!result;
|
||
};
|
||
|
||
// Determine if at least one element in the object matches a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `some` if available.
|
||
// Aliased as `any`.
|
||
var any = _.some = _.any = function(obj, predicate, context) {
|
||
predicate || (predicate = _.identity);
|
||
var result = false;
|
||
if (obj == null) return result;
|
||
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (result || (result = predicate.call(context, value, index, list))) return breaker;
|
||
});
|
||
return !!result;
|
||
};
|
||
|
||
// Determine if the array or object contains a given value (using `===`).
|
||
// Aliased as `include`.
|
||
_.contains = _.include = function(obj, target) {
|
||
if (obj == null) return false;
|
||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||
return any(obj, function(value) {
|
||
return value === target;
|
||
});
|
||
};
|
||
|
||
// Invoke a method (with arguments) on every item in a collection.
|
||
_.invoke = function(obj, method) {
|
||
var args = slice.call(arguments, 2);
|
||
var isFunc = _.isFunction(method);
|
||
return _.map(obj, function(value) {
|
||
return (isFunc ? method : value[method]).apply(value, args);
|
||
});
|
||
};
|
||
|
||
// Convenience version of a common use case of `map`: fetching a property.
|
||
_.pluck = function(obj, key) {
|
||
return _.map(obj, _.property(key));
|
||
};
|
||
|
||
// Convenience version of a common use case of `filter`: selecting only objects
|
||
// containing specific `key:value` pairs.
|
||
_.where = function(obj, attrs) {
|
||
return _.filter(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Convenience version of a common use case of `find`: getting the first object
|
||
// containing specific `key:value` pairs.
|
||
_.findWhere = function(obj, attrs) {
|
||
return _.find(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Return the maximum element or (element-based computation).
|
||
// Can't optimize arrays of integers longer than 65,535 elements.
|
||
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
|
||
_.max = function(obj, iterator, context) {
|
||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
||
return Math.max.apply(Math, obj);
|
||
}
|
||
var result = -Infinity, lastComputed = -Infinity;
|
||
each(obj, function(value, index, list) {
|
||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||
if (computed > lastComputed) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Return the minimum element (or element-based computation).
|
||
_.min = function(obj, iterator, context) {
|
||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
||
return Math.min.apply(Math, obj);
|
||
}
|
||
var result = Infinity, lastComputed = Infinity;
|
||
each(obj, function(value, index, list) {
|
||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||
if (computed < lastComputed) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Shuffle an array, using the modern version of the
|
||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
||
_.shuffle = function(obj) {
|
||
var rand;
|
||
var index = 0;
|
||
var shuffled = [];
|
||
each(obj, function(value) {
|
||
rand = _.random(index++);
|
||
shuffled[index - 1] = shuffled[rand];
|
||
shuffled[rand] = value;
|
||
});
|
||
return shuffled;
|
||
};
|
||
|
||
// Sample **n** random values from a collection.
|
||
// If **n** is not specified, returns a single random element.
|
||
// The internal `guard` argument allows it to work with `map`.
|
||
_.sample = function(obj, n, guard) {
|
||
if (n == null || guard) {
|
||
if (obj.length !== +obj.length) obj = _.values(obj);
|
||
return obj[_.random(obj.length - 1)];
|
||
}
|
||
return _.shuffle(obj).slice(0, Math.max(0, n));
|
||
};
|
||
|
||
// An internal function to generate lookup iterators.
|
||
var lookupIterator = function(value) {
|
||
if (value == null) return _.identity;
|
||
if (_.isFunction(value)) return value;
|
||
return _.property(value);
|
||
};
|
||
|
||
// Sort the object's values by a criterion produced by an iterator.
|
||
_.sortBy = function(obj, iterator, context) {
|
||
iterator = lookupIterator(iterator);
|
||
return _.pluck(_.map(obj, function(value, index, list) {
|
||
return {
|
||
value: value,
|
||
index: index,
|
||
criteria: iterator.call(context, value, index, list)
|
||
};
|
||
}).sort(function(left, right) {
|
||
var a = left.criteria;
|
||
var b = right.criteria;
|
||
if (a !== b) {
|
||
if (a > b || a === void 0) return 1;
|
||
if (a < b || b === void 0) return -1;
|
||
}
|
||
return left.index - right.index;
|
||
}), 'value');
|
||
};
|
||
|
||
// An internal function used for aggregate "group by" operations.
|
||
var group = function(behavior) {
|
||
return function(obj, iterator, context) {
|
||
var result = {};
|
||
iterator = lookupIterator(iterator);
|
||
each(obj, function(value, index) {
|
||
var key = iterator.call(context, value, index, obj);
|
||
behavior(result, key, value);
|
||
});
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Groups the object's values by a criterion. Pass either a string attribute
|
||
// to group by, or a function that returns the criterion.
|
||
_.groupBy = group(function(result, key, value) {
|
||
_.has(result, key) ? result[key].push(value) : result[key] = [value];
|
||
});
|
||
|
||
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
||
// when you know that your index values will be unique.
|
||
_.indexBy = group(function(result, key, value) {
|
||
result[key] = value;
|
||
});
|
||
|
||
// Counts instances of an object that group by a certain criterion. Pass
|
||
// either a string attribute to count by, or a function that returns the
|
||
// criterion.
|
||
_.countBy = group(function(result, key) {
|
||
_.has(result, key) ? result[key]++ : result[key] = 1;
|
||
});
|
||
|
||
// Use a comparator function to figure out the smallest index at which
|
||
// an object should be inserted so as to maintain order. Uses binary search.
|
||
_.sortedIndex = function(array, obj, iterator, context) {
|
||
iterator = lookupIterator(iterator);
|
||
var value = iterator.call(context, obj);
|
||
var low = 0, high = array.length;
|
||
while (low < high) {
|
||
var mid = (low + high) >>> 1;
|
||
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
|
||
}
|
||
return low;
|
||
};
|
||
|
||
// Safely create a real, live array from anything iterable.
|
||
_.toArray = function(obj) {
|
||
if (!obj) return [];
|
||
if (_.isArray(obj)) return slice.call(obj);
|
||
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
||
return _.values(obj);
|
||
};
|
||
|
||
// Return the number of elements in an object.
|
||
_.size = function(obj) {
|
||
if (obj == null) return 0;
|
||
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
|
||
};
|
||
|
||
// Array Functions
|
||
// ---------------
|
||
|
||
// Get the first element of an array. Passing **n** will return the first N
|
||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||
// allows it to work with `_.map`.
|
||
_.first = _.head = _.take = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if ((n == null) || guard) return array[0];
|
||
if (n < 0) return [];
|
||
return slice.call(array, 0, n);
|
||
};
|
||
|
||
// Returns everything but the last entry of the array. Especially useful on
|
||
// the arguments object. Passing **n** will return all the values in
|
||
// the array, excluding the last N. The **guard** check allows it to work with
|
||
// `_.map`.
|
||
_.initial = function(array, n, guard) {
|
||
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
|
||
};
|
||
|
||
// Get the last element of an array. Passing **n** will return the last N
|
||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||
_.last = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if ((n == null) || guard) return array[array.length - 1];
|
||
return slice.call(array, Math.max(array.length - n, 0));
|
||
};
|
||
|
||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
||
// Especially useful on the arguments object. Passing an **n** will return
|
||
// the rest N values in the array. The **guard**
|
||
// check allows it to work with `_.map`.
|
||
_.rest = _.tail = _.drop = function(array, n, guard) {
|
||
return slice.call(array, (n == null) || guard ? 1 : n);
|
||
};
|
||
|
||
// Trim out all falsy values from an array.
|
||
_.compact = function(array) {
|
||
return _.filter(array, _.identity);
|
||
};
|
||
|
||
// Internal implementation of a recursive `flatten` function.
|
||
var flatten = function(input, shallow, output) {
|
||
if (shallow && _.every(input, _.isArray)) {
|
||
return concat.apply(output, input);
|
||
}
|
||
each(input, function(value) {
|
||
if (_.isArray(value) || _.isArguments(value)) {
|
||
shallow ? push.apply(output, value) : flatten(value, shallow, output);
|
||
} else {
|
||
output.push(value);
|
||
}
|
||
});
|
||
return output;
|
||
};
|
||
|
||
// Flatten out an array, either recursively (by default), or just one level.
|
||
_.flatten = function(array, shallow) {
|
||
return flatten(array, shallow, []);
|
||
};
|
||
|
||
// Return a version of the array that does not contain the specified value(s).
|
||
_.without = function(array) {
|
||
return _.difference(array, slice.call(arguments, 1));
|
||
};
|
||
|
||
// Split an array into two arrays: one whose elements all satisfy the given
|
||
// predicate, and one whose elements all do not satisfy the predicate.
|
||
_.partition = function(array, predicate) {
|
||
var pass = [], fail = [];
|
||
each(array, function(elem) {
|
||
(predicate(elem) ? pass : fail).push(elem);
|
||
});
|
||
return [pass, fail];
|
||
};
|
||
|
||
// Produce a duplicate-free version of the array. If the array has already
|
||
// been sorted, you have the option of using a faster algorithm.
|
||
// Aliased as `unique`.
|
||
_.uniq = _.unique = function(array, isSorted, iterator, context) {
|
||
if (_.isFunction(isSorted)) {
|
||
context = iterator;
|
||
iterator = isSorted;
|
||
isSorted = false;
|
||
}
|
||
var initial = iterator ? _.map(array, iterator, context) : array;
|
||
var results = [];
|
||
var seen = [];
|
||
each(initial, function(value, index) {
|
||
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
|
||
seen.push(value);
|
||
results.push(array[index]);
|
||
}
|
||
});
|
||
return results;
|
||
};
|
||
|
||
// Produce an array that contains the union: each distinct element from all of
|
||
// the passed-in arrays.
|
||
_.union = function() {
|
||
return _.uniq(_.flatten(arguments, true));
|
||
};
|
||
|
||
// Produce an array that contains every item shared between all the
|
||
// passed-in arrays.
|
||
_.intersection = function(array) {
|
||
var rest = slice.call(arguments, 1);
|
||
return _.filter(_.uniq(array), function(item) {
|
||
return _.every(rest, function(other) {
|
||
return _.contains(other, item);
|
||
});
|
||
});
|
||
};
|
||
|
||
// Take the difference between one array and a number of other arrays.
|
||
// Only the elements present in just the first array will remain.
|
||
_.difference = function(array) {
|
||
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
return _.filter(array, function(value){ return !_.contains(rest, value); });
|
||
};
|
||
|
||
// Zip together multiple lists into a single array -- elements that share
|
||
// an index go together.
|
||
_.zip = function() {
|
||
var length = _.max(_.pluck(arguments, 'length').concat(0));
|
||
var results = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
results[i] = _.pluck(arguments, '' + i);
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Converts lists into objects. Pass either a single array of `[key, value]`
|
||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||
// the corresponding values.
|
||
_.object = function(list, values) {
|
||
if (list == null) return {};
|
||
var result = {};
|
||
for (var i = 0, length = list.length; i < length; i++) {
|
||
if (values) {
|
||
result[list[i]] = values[i];
|
||
} else {
|
||
result[list[i][0]] = list[i][1];
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
||
// we need this function. Return the position of the first occurrence of an
|
||
// item in an array, or -1 if the item is not included in the array.
|
||
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
||
// If the array is large and already in sort order, pass `true`
|
||
// for **isSorted** to use binary search.
|
||
_.indexOf = function(array, item, isSorted) {
|
||
if (array == null) return -1;
|
||
var i = 0, length = array.length;
|
||
if (isSorted) {
|
||
if (typeof isSorted == 'number') {
|
||
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
|
||
} else {
|
||
i = _.sortedIndex(array, item);
|
||
return array[i] === item ? i : -1;
|
||
}
|
||
}
|
||
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
|
||
for (; i < length; i++) if (array[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||
_.lastIndexOf = function(array, item, from) {
|
||
if (array == null) return -1;
|
||
var hasIndex = from != null;
|
||
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
|
||
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
|
||
}
|
||
var i = (hasIndex ? from : array.length);
|
||
while (i--) if (array[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
// Generate an integer Array containing an arithmetic progression. A port of
|
||
// the native Python `range()` function. See
|
||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||
_.range = function(start, stop, step) {
|
||
if (arguments.length <= 1) {
|
||
stop = start || 0;
|
||
start = 0;
|
||
}
|
||
step = arguments[2] || 1;
|
||
|
||
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
||
var idx = 0;
|
||
var range = new Array(length);
|
||
|
||
while(idx < length) {
|
||
range[idx++] = start;
|
||
start += step;
|
||
}
|
||
|
||
return range;
|
||
};
|
||
|
||
// Function (ahem) Functions
|
||
// ------------------
|
||
|
||
// Reusable constructor function for prototype setting.
|
||
var ctor = function(){};
|
||
|
||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||
// available.
|
||
_.bind = function(func, context) {
|
||
var args, bound;
|
||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||
if (!_.isFunction(func)) throw new TypeError;
|
||
args = slice.call(arguments, 2);
|
||
return bound = function() {
|
||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||
ctor.prototype = func.prototype;
|
||
var self = new ctor;
|
||
ctor.prototype = null;
|
||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||
if (Object(result) === result) return result;
|
||
return self;
|
||
};
|
||
};
|
||
|
||
// Partially apply a function by creating a version that has had some of its
|
||
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
||
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
||
_.partial = function(func) {
|
||
var boundArgs = slice.call(arguments, 1);
|
||
return function() {
|
||
var position = 0;
|
||
var args = boundArgs.slice();
|
||
for (var i = 0, length = args.length; i < length; i++) {
|
||
if (args[i] === _) args[i] = arguments[position++];
|
||
}
|
||
while (position < arguments.length) args.push(arguments[position++]);
|
||
return func.apply(this, args);
|
||
};
|
||
};
|
||
|
||
// Bind a number of an object's methods to that object. Remaining arguments
|
||
// are the method names to be bound. Useful for ensuring that all callbacks
|
||
// defined on an object belong to it.
|
||
_.bindAll = function(obj) {
|
||
var funcs = slice.call(arguments, 1);
|
||
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
|
||
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
||
return obj;
|
||
};
|
||
|
||
// Memoize an expensive function by storing its results.
|
||
_.memoize = function(func, hasher) {
|
||
var memo = {};
|
||
hasher || (hasher = _.identity);
|
||
return function() {
|
||
var key = hasher.apply(this, arguments);
|
||
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
|
||
};
|
||
};
|
||
|
||
// Delays a function for the given number of milliseconds, and then calls
|
||
// it with the arguments supplied.
|
||
_.delay = function(func, wait) {
|
||
var args = slice.call(arguments, 2);
|
||
return setTimeout(function(){ return func.apply(null, args); }, wait);
|
||
};
|
||
|
||
// Defers a function, scheduling it to run after the current call stack has
|
||
// cleared.
|
||
_.defer = function(func) {
|
||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||
};
|
||
|
||
// Returns a function, that, when invoked, will only be triggered at most once
|
||
// during a given window of time. Normally, the throttled function will run
|
||
// as much as it can, without ever going more than once per `wait` duration;
|
||
// but if you'd like to disable the execution on the leading edge, pass
|
||
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
||
_.throttle = function(func, wait, options) {
|
||
var context, args, result;
|
||
var timeout = null;
|
||
var previous = 0;
|
||
options || (options = {});
|
||
var later = function() {
|
||
previous = options.leading === false ? 0 : _.now();
|
||
timeout = null;
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
};
|
||
return function() {
|
||
var now = _.now();
|
||
if (!previous && options.leading === false) previous = now;
|
||
var remaining = wait - (now - previous);
|
||
context = this;
|
||
args = arguments;
|
||
if (remaining <= 0) {
|
||
clearTimeout(timeout);
|
||
timeout = null;
|
||
previous = now;
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
} else if (!timeout && options.trailing !== false) {
|
||
timeout = setTimeout(later, remaining);
|
||
}
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function, that, as long as it continues to be invoked, will not
|
||
// be triggered. The function will be called after it stops being called for
|
||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||
// leading edge, instead of the trailing.
|
||
_.debounce = function(func, wait, immediate) {
|
||
var timeout, args, context, timestamp, result;
|
||
|
||
var later = function() {
|
||
var last = _.now() - timestamp;
|
||
if (last < wait) {
|
||
timeout = setTimeout(later, wait - last);
|
||
} else {
|
||
timeout = null;
|
||
if (!immediate) {
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
return function() {
|
||
context = this;
|
||
args = arguments;
|
||
timestamp = _.now();
|
||
var callNow = immediate && !timeout;
|
||
if (!timeout) {
|
||
timeout = setTimeout(later, wait);
|
||
}
|
||
if (callNow) {
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
}
|
||
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function that will be executed at most one time, no matter how
|
||
// often you call it. Useful for lazy initialization.
|
||
_.once = function(func) {
|
||
var ran = false, memo;
|
||
return function() {
|
||
if (ran) return memo;
|
||
ran = true;
|
||
memo = func.apply(this, arguments);
|
||
func = null;
|
||
return memo;
|
||
};
|
||
};
|
||
|
||
// Returns the first function passed as an argument to the second,
|
||
// allowing you to adjust arguments, run code before and after, and
|
||
// conditionally execute the original function.
|
||
_.wrap = function(func, wrapper) {
|
||
return _.partial(wrapper, func);
|
||
};
|
||
|
||
// Returns a function that is the composition of a list of functions, each
|
||
// consuming the return value of the function that follows.
|
||
_.compose = function() {
|
||
var funcs = arguments;
|
||
return function() {
|
||
var args = arguments;
|
||
for (var i = funcs.length - 1; i >= 0; i--) {
|
||
args = [funcs[i].apply(this, args)];
|
||
}
|
||
return args[0];
|
||
};
|
||
};
|
||
|
||
// Returns a function that will only be executed after being called N times.
|
||
_.after = function(times, func) {
|
||
return function() {
|
||
if (--times < 1) {
|
||
return func.apply(this, arguments);
|
||
}
|
||
};
|
||
};
|
||
|
||
// Object Functions
|
||
// ----------------
|
||
|
||
// Retrieve the names of an object's properties.
|
||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||
_.keys = function(obj) {
|
||
if (!_.isObject(obj)) return [];
|
||
if (nativeKeys) return nativeKeys(obj);
|
||
var keys = [];
|
||
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
||
return keys;
|
||
};
|
||
|
||
// Retrieve the values of an object's properties.
|
||
_.values = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var values = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
values[i] = obj[keys[i]];
|
||
}
|
||
return values;
|
||
};
|
||
|
||
// Convert an object into a list of `[key, value]` pairs.
|
||
_.pairs = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var pairs = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
pairs[i] = [keys[i], obj[keys[i]]];
|
||
}
|
||
return pairs;
|
||
};
|
||
|
||
// Invert the keys and values of an object. The values must be serializable.
|
||
_.invert = function(obj) {
|
||
var result = {};
|
||
var keys = _.keys(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
result[obj[keys[i]]] = keys[i];
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return a sorted list of the function names available on the object.
|
||
// Aliased as `methods`
|
||
_.functions = _.methods = function(obj) {
|
||
var names = [];
|
||
for (var key in obj) {
|
||
if (_.isFunction(obj[key])) names.push(key);
|
||
}
|
||
return names.sort();
|
||
};
|
||
|
||
// Extend a given object with all the properties in passed-in object(s).
|
||
_.extend = function(obj) {
|
||
each(slice.call(arguments, 1), function(source) {
|
||
if (source) {
|
||
for (var prop in source) {
|
||
obj[prop] = source[prop];
|
||
}
|
||
}
|
||
});
|
||
return obj;
|
||
};
|
||
|
||
// Return a copy of the object only containing the whitelisted properties.
|
||
_.pick = function(obj) {
|
||
var copy = {};
|
||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
each(keys, function(key) {
|
||
if (key in obj) copy[key] = obj[key];
|
||
});
|
||
return copy;
|
||
};
|
||
|
||
// Return a copy of the object without the blacklisted properties.
|
||
_.omit = function(obj) {
|
||
var copy = {};
|
||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
for (var key in obj) {
|
||
if (!_.contains(keys, key)) copy[key] = obj[key];
|
||
}
|
||
return copy;
|
||
};
|
||
|
||
// Fill in a given object with default properties.
|
||
_.defaults = function(obj) {
|
||
each(slice.call(arguments, 1), function(source) {
|
||
if (source) {
|
||
for (var prop in source) {
|
||
if (obj[prop] === void 0) obj[prop] = source[prop];
|
||
}
|
||
}
|
||
});
|
||
return obj;
|
||
};
|
||
|
||
// Create a (shallow-cloned) duplicate of an object.
|
||
_.clone = function(obj) {
|
||
if (!_.isObject(obj)) return obj;
|
||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||
};
|
||
|
||
// Invokes interceptor with the obj, and then returns obj.
|
||
// The primary purpose of this method is to "tap into" a method chain, in
|
||
// order to perform operations on intermediate results within the chain.
|
||
_.tap = function(obj, interceptor) {
|
||
interceptor(obj);
|
||
return obj;
|
||
};
|
||
|
||
// Internal recursive comparison function for `isEqual`.
|
||
var eq = function(a, b, aStack, bStack) {
|
||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||
// A strict comparison is necessary because `null == undefined`.
|
||
if (a == null || b == null) return a === b;
|
||
// Unwrap any wrapped objects.
|
||
if (a instanceof _) a = a._wrapped;
|
||
if (b instanceof _) b = b._wrapped;
|
||
// Compare `[[Class]]` names.
|
||
var className = toString.call(a);
|
||
if (className != toString.call(b)) return false;
|
||
switch (className) {
|
||
// Strings, numbers, dates, and booleans are compared by value.
|
||
case '[object String]':
|
||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||
// equivalent to `new String("5")`.
|
||
return a == String(b);
|
||
case '[object Number]':
|
||
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||
// other numeric values.
|
||
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
|
||
case '[object Date]':
|
||
case '[object Boolean]':
|
||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||
// millisecond representations. Note that invalid dates with millisecond representations
|
||
// of `NaN` are not equivalent.
|
||
return +a == +b;
|
||
// RegExps are compared by their source patterns and flags.
|
||
case '[object RegExp]':
|
||
return a.source == b.source &&
|
||
a.global == b.global &&
|
||
a.multiline == b.multiline &&
|
||
a.ignoreCase == b.ignoreCase;
|
||
}
|
||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||
var length = aStack.length;
|
||
while (length--) {
|
||
// Linear search. Performance is inversely proportional to the number of
|
||
// unique nested structures.
|
||
if (aStack[length] == a) return bStack[length] == b;
|
||
}
|
||
// Objects with different constructors are not equivalent, but `Object`s
|
||
// from different frames are.
|
||
var aCtor = a.constructor, bCtor = b.constructor;
|
||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
|
||
_.isFunction(bCtor) && (bCtor instanceof bCtor))
|
||
&& ('constructor' in a && 'constructor' in b)) {
|
||
return false;
|
||
}
|
||
// Add the first object to the stack of traversed objects.
|
||
aStack.push(a);
|
||
bStack.push(b);
|
||
var size = 0, result = true;
|
||
// Recursively compare objects and arrays.
|
||
if (className == '[object Array]') {
|
||
// Compare array lengths to determine if a deep comparison is necessary.
|
||
size = a.length;
|
||
result = size == b.length;
|
||
if (result) {
|
||
// Deep compare the contents, ignoring non-numeric properties.
|
||
while (size--) {
|
||
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
|
||
}
|
||
}
|
||
} else {
|
||
// Deep compare objects.
|
||
for (var key in a) {
|
||
if (_.has(a, key)) {
|
||
// Count the expected number of properties.
|
||
size++;
|
||
// Deep compare each member.
|
||
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
|
||
}
|
||
}
|
||
// Ensure that both objects contain the same number of properties.
|
||
if (result) {
|
||
for (key in b) {
|
||
if (_.has(b, key) && !(size--)) break;
|
||
}
|
||
result = !size;
|
||
}
|
||
}
|
||
// Remove the first object from the stack of traversed objects.
|
||
aStack.pop();
|
||
bStack.pop();
|
||
return result;
|
||
};
|
||
|
||
// Perform a deep comparison to check if two objects are equal.
|
||
_.isEqual = function(a, b) {
|
||
return eq(a, b, [], []);
|
||
};
|
||
|
||
// Is a given array, string, or object empty?
|
||
// An "empty" object has no enumerable own-properties.
|
||
_.isEmpty = function(obj) {
|
||
if (obj == null) return true;
|
||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
||
for (var key in obj) if (_.has(obj, key)) return false;
|
||
return true;
|
||
};
|
||
|
||
// Is a given value a DOM element?
|
||
_.isElement = function(obj) {
|
||
return !!(obj && obj.nodeType === 1);
|
||
};
|
||
|
||
// Is a given value an array?
|
||
// Delegates to ECMA5's native Array.isArray
|
||
_.isArray = nativeIsArray || function(obj) {
|
||
return toString.call(obj) == '[object Array]';
|
||
};
|
||
|
||
// Is a given variable an object?
|
||
_.isObject = function(obj) {
|
||
return obj === Object(obj);
|
||
};
|
||
|
||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
|
||
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
|
||
_['is' + name] = function(obj) {
|
||
return toString.call(obj) == '[object ' + name + ']';
|
||
};
|
||
});
|
||
|
||
// Define a fallback version of the method in browsers (ahem, IE), where
|
||
// there isn't any inspectable "Arguments" type.
|
||
if (!_.isArguments(arguments)) {
|
||
_.isArguments = function(obj) {
|
||
return !!(obj && _.has(obj, 'callee'));
|
||
};
|
||
}
|
||
|
||
// Optimize `isFunction` if appropriate.
|
||
if (typeof (/./) !== 'function') {
|
||
_.isFunction = function(obj) {
|
||
return typeof obj === 'function';
|
||
};
|
||
}
|
||
|
||
// Is a given object a finite number?
|
||
_.isFinite = function(obj) {
|
||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||
};
|
||
|
||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||
_.isNaN = function(obj) {
|
||
return _.isNumber(obj) && obj != +obj;
|
||
};
|
||
|
||
// Is a given value a boolean?
|
||
_.isBoolean = function(obj) {
|
||
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
|
||
};
|
||
|
||
// Is a given value equal to null?
|
||
_.isNull = function(obj) {
|
||
return obj === null;
|
||
};
|
||
|
||
// Is a given variable undefined?
|
||
_.isUndefined = function(obj) {
|
||
return obj === void 0;
|
||
};
|
||
|
||
// Shortcut function for checking if an object has a given property directly
|
||
// on itself (in other words, not on a prototype).
|
||
_.has = function(obj, key) {
|
||
return hasOwnProperty.call(obj, key);
|
||
};
|
||
|
||
// Utility Functions
|
||
// -----------------
|
||
|
||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||
// previous owner. Returns a reference to the Underscore object.
|
||
_.noConflict = function() {
|
||
root._ = previousUnderscore;
|
||
return this;
|
||
};
|
||
|
||
// Keep the identity function around for default iterators.
|
||
_.identity = function(value) {
|
||
return value;
|
||
};
|
||
|
||
_.constant = function(value) {
|
||
return function () {
|
||
return value;
|
||
};
|
||
};
|
||
|
||
_.property = function(key) {
|
||
return function(obj) {
|
||
return obj[key];
|
||
};
|
||
};
|
||
|
||
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
|
||
_.matches = function(attrs) {
|
||
return function(obj) {
|
||
if (obj === attrs) return true; //avoid comparing an object to itself.
|
||
for (var key in attrs) {
|
||
if (attrs[key] !== obj[key])
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
};
|
||
|
||
// Run a function **n** times.
|
||
_.times = function(n, iterator, context) {
|
||
var accum = Array(Math.max(0, n));
|
||
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
|
||
return accum;
|
||
};
|
||
|
||
// Return a random integer between min and max (inclusive).
|
||
_.random = function(min, max) {
|
||
if (max == null) {
|
||
max = min;
|
||
min = 0;
|
||
}
|
||
return min + Math.floor(Math.random() * (max - min + 1));
|
||
};
|
||
|
||
// A (possibly faster) way to get the current timestamp as an integer.
|
||
_.now = Date.now || function() { return new Date().getTime(); };
|
||
|
||
// List of HTML entities for escaping.
|
||
var entityMap = {
|
||
escape: {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
"'": '''
|
||
}
|
||
};
|
||
entityMap.unescape = _.invert(entityMap.escape);
|
||
|
||
// Regexes containing the keys and values listed immediately above.
|
||
var entityRegexes = {
|
||
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
|
||
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
|
||
};
|
||
|
||
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
||
_.each(['escape', 'unescape'], function(method) {
|
||
_[method] = function(string) {
|
||
if (string == null) return '';
|
||
return ('' + string).replace(entityRegexes[method], function(match) {
|
||
return entityMap[method][match];
|
||
});
|
||
};
|
||
});
|
||
|
||
// If the value of the named `property` is a function then invoke it with the
|
||
// `object` as context; otherwise, return it.
|
||
_.result = function(object, property) {
|
||
if (object == null) return void 0;
|
||
var value = object[property];
|
||
return _.isFunction(value) ? value.call(object) : value;
|
||
};
|
||
|
||
// Add your own custom functions to the Underscore object.
|
||
_.mixin = function(obj) {
|
||
each(_.functions(obj), function(name) {
|
||
var func = _[name] = obj[name];
|
||
_.prototype[name] = function() {
|
||
var args = [this._wrapped];
|
||
push.apply(args, arguments);
|
||
return result.call(this, func.apply(_, args));
|
||
};
|
||
});
|
||
};
|
||
|
||
// Generate a unique integer id (unique within the entire client session).
|
||
// Useful for temporary DOM ids.
|
||
var idCounter = 0;
|
||
_.uniqueId = function(prefix) {
|
||
var id = ++idCounter + '';
|
||
return prefix ? prefix + id : id;
|
||
};
|
||
|
||
// By default, Underscore uses ERB-style template delimiters, change the
|
||
// following template settings to use alternative delimiters.
|
||
_.templateSettings = {
|
||
evaluate : /<%([\s\S]+?)%>/g,
|
||
interpolate : /<%=([\s\S]+?)%>/g,
|
||
escape : /<%-([\s\S]+?)%>/g
|
||
};
|
||
|
||
// When customizing `templateSettings`, if you don't want to define an
|
||
// interpolation, evaluation or escaping regex, we need one that is
|
||
// guaranteed not to match.
|
||
var noMatch = /(.)^/;
|
||
|
||
// Certain characters need to be escaped so that they can be put into a
|
||
// string literal.
|
||
var escapes = {
|
||
"'": "'",
|
||
'\\': '\\',
|
||
'\r': 'r',
|
||
'\n': 'n',
|
||
'\t': 't',
|
||
'\u2028': 'u2028',
|
||
'\u2029': 'u2029'
|
||
};
|
||
|
||
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
|
||
|
||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||
// and correctly escapes quotes within interpolated code.
|
||
_.template = function(text, data, settings) {
|
||
var render;
|
||
settings = _.defaults({}, settings, _.templateSettings);
|
||
|
||
// Combine delimiters into one regular expression via alternation.
|
||
var matcher = new RegExp([
|
||
(settings.escape || noMatch).source,
|
||
(settings.interpolate || noMatch).source,
|
||
(settings.evaluate || noMatch).source
|
||
].join('|') + '|$', 'g');
|
||
|
||
// Compile the template source, escaping string literals appropriately.
|
||
var index = 0;
|
||
var source = "__p+='";
|
||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||
source += text.slice(index, offset)
|
||
.replace(escaper, function(match) { return '\\' + escapes[match]; });
|
||
|
||
if (escape) {
|
||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||
}
|
||
if (interpolate) {
|
||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||
}
|
||
if (evaluate) {
|
||
source += "';\n" + evaluate + "\n__p+='";
|
||
}
|
||
index = offset + match.length;
|
||
return match;
|
||
});
|
||
source += "';\n";
|
||
|
||
// If a variable is not specified, place data values in local scope.
|
||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
|
||
|
||
source = "var __t,__p='',__j=Array.prototype.join," +
|
||
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
||
source + "return __p;\n";
|
||
|
||
try {
|
||
render = new Function(settings.variable || 'obj', '_', source);
|
||
} catch (e) {
|
||
e.source = source;
|
||
throw e;
|
||
}
|
||
|
||
if (data) return render(data, _);
|
||
var template = function(data) {
|
||
return render.call(this, data, _);
|
||
};
|
||
|
||
// Provide the compiled function source as a convenience for precompilation.
|
||
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
|
||
|
||
return template;
|
||
};
|
||
|
||
// Add a "chain" function, which will delegate to the wrapper.
|
||
_.chain = function(obj) {
|
||
return _(obj).chain();
|
||
};
|
||
|
||
// OOP
|
||
// ---------------
|
||
// If Underscore is called as a function, it returns a wrapped object that
|
||
// can be used OO-style. This wrapper holds altered versions of all the
|
||
// underscore functions. Wrapped objects may be chained.
|
||
|
||
// Helper function to continue chaining intermediate results.
|
||
var result = function(obj) {
|
||
return this._chain ? _(obj).chain() : obj;
|
||
};
|
||
|
||
// Add all of the Underscore functions to the wrapper object.
|
||
_.mixin(_);
|
||
|
||
// Add all mutator Array functions to the wrapper.
|
||
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
var obj = this._wrapped;
|
||
method.apply(obj, arguments);
|
||
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
|
||
return result.call(this, obj);
|
||
};
|
||
});
|
||
|
||
// Add all accessor Array functions to the wrapper.
|
||
each(['concat', 'join', 'slice'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
return result.call(this, method.apply(this._wrapped, arguments));
|
||
};
|
||
});
|
||
|
||
_.extend(_.prototype, {
|
||
|
||
// Start chaining a wrapped Underscore object.
|
||
chain: function() {
|
||
this._chain = true;
|
||
return this;
|
||
},
|
||
|
||
// Extracts the result from a wrapped and chained object.
|
||
value: function() {
|
||
return this._wrapped;
|
||
}
|
||
|
||
});
|
||
|
||
// AMD registration happens at the end for compatibility with AMD loaders
|
||
// that may not enforce next-turn semantics on modules. Even though general
|
||
// practice for AMD registration is to be anonymous, underscore registers
|
||
// as a named module because, like jQuery, it is a base library that is
|
||
// popular enough to be bundled in a third party lib, but not be part of
|
||
// an AMD load request. Those cases could generate an error when an
|
||
// anonymous define() is called outside of a loader request.
|
||
if (typeof define === 'function' && define.amd) {
|
||
define('underscore', [], function() {
|
||
return _;
|
||
});
|
||
}
|
||
}).call(this);
|
||
|
||
/* =========================================================
|
||
* bootstrap-datepicker.js
|
||
* Repo: https://github.com/eternicode/bootstrap-datepicker/
|
||
* Demo: http://eternicode.github.io/bootstrap-datepicker/
|
||
* Docs: http://bootstrap-datepicker.readthedocs.org/
|
||
* Forked from http://www.eyecon.ro/bootstrap-datepicker
|
||
* =========================================================
|
||
* Started by Stefan Petre; improvements by Andrew Rowls + contributors
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
* ========================================================= */
|
||
|
||
(function($, undefined){
|
||
|
||
var $window = $(window);
|
||
|
||
function UTCDate(){
|
||
return new Date(Date.UTC.apply(Date, arguments));
|
||
}
|
||
function UTCToday(){
|
||
var today = new Date();
|
||
return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
|
||
}
|
||
function alias(method){
|
||
return function(){
|
||
return this[method].apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
var DateArray = (function(){
|
||
var extras = {
|
||
get: function(i){
|
||
return this.slice(i)[0];
|
||
},
|
||
contains: function(d){
|
||
// Array.indexOf is not cross-browser;
|
||
// $.inArray doesn't work with Dates
|
||
var val = d && d.valueOf();
|
||
for (var i=0, l=this.length; i < l; i++)
|
||
if (this[i].valueOf() === val)
|
||
return i;
|
||
return -1;
|
||
},
|
||
remove: function(i){
|
||
this.splice(i,1);
|
||
},
|
||
replace: function(new_array){
|
||
if (!new_array)
|
||
return;
|
||
if (!$.isArray(new_array))
|
||
new_array = [new_array];
|
||
this.clear();
|
||
this.push.apply(this, new_array);
|
||
},
|
||
clear: function(){
|
||
this.splice(0);
|
||
},
|
||
copy: function(){
|
||
var a = new DateArray();
|
||
a.replace(this);
|
||
return a;
|
||
}
|
||
};
|
||
|
||
return function(){
|
||
var a = [];
|
||
a.push.apply(a, arguments);
|
||
$.extend(a, extras);
|
||
return a;
|
||
};
|
||
})();
|
||
|
||
|
||
// Picker object
|
||
|
||
var Datepicker = function(element, options){
|
||
this.dates = new DateArray();
|
||
this.viewDate = UTCToday();
|
||
this.focusDate = null;
|
||
|
||
this._process_options(options);
|
||
|
||
this.element = $(element);
|
||
this.isInline = false;
|
||
this.isInput = this.element.is('input');
|
||
this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
|
||
this.hasInput = this.component && this.element.find('input').length;
|
||
if (this.component && this.component.length === 0)
|
||
this.component = false;
|
||
|
||
this.picker = $(DPGlobal.template);
|
||
this._buildEvents();
|
||
this._attachEvents();
|
||
|
||
if (this.isInline){
|
||
this.picker.addClass('datepicker-inline').appendTo(this.element);
|
||
}
|
||
else {
|
||
this.picker.addClass('datepicker-dropdown dropdown-menu');
|
||
}
|
||
|
||
if (this.o.rtl){
|
||
this.picker.addClass('datepicker-rtl');
|
||
}
|
||
|
||
this.viewMode = this.o.startView;
|
||
|
||
if (this.o.calendarWeeks)
|
||
this.picker.find('tfoot th.today')
|
||
.attr('colspan', function(i, val){
|
||
return parseInt(val) + 1;
|
||
});
|
||
|
||
this._allow_update = false;
|
||
|
||
this.setStartDate(this._o.startDate);
|
||
this.setEndDate(this._o.endDate);
|
||
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
|
||
|
||
this.fillDow();
|
||
this.fillMonths();
|
||
|
||
this._allow_update = true;
|
||
|
||
this.update();
|
||
this.showMode();
|
||
|
||
if (this.isInline){
|
||
this.show();
|
||
}
|
||
};
|
||
|
||
Datepicker.prototype = {
|
||
constructor: Datepicker,
|
||
|
||
_process_options: function(opts){
|
||
// Store raw options for reference
|
||
this._o = $.extend({}, this._o, opts);
|
||
// Processed options
|
||
var o = this.o = $.extend({}, this._o);
|
||
|
||
// Check if "de-DE" style date is available, if not language should
|
||
// fallback to 2 letter code eg "de"
|
||
var lang = o.language;
|
||
if (!dates[lang]){
|
||
lang = lang.split('-')[0];
|
||
if (!dates[lang])
|
||
lang = defaults.language;
|
||
}
|
||
o.language = lang;
|
||
|
||
switch (o.startView){
|
||
case 2:
|
||
case 'decade':
|
||
o.startView = 2;
|
||
break;
|
||
case 1:
|
||
case 'year':
|
||
o.startView = 1;
|
||
break;
|
||
default:
|
||
o.startView = 0;
|
||
}
|
||
|
||
switch (o.minViewMode){
|
||
case 1:
|
||
case 'months':
|
||
o.minViewMode = 1;
|
||
break;
|
||
case 2:
|
||
case 'years':
|
||
o.minViewMode = 2;
|
||
break;
|
||
default:
|
||
o.minViewMode = 0;
|
||
}
|
||
|
||
o.startView = Math.max(o.startView, o.minViewMode);
|
||
|
||
// true, false, or Number > 0
|
||
if (o.multidate !== true){
|
||
o.multidate = Number(o.multidate) || false;
|
||
if (o.multidate !== false)
|
||
o.multidate = Math.max(0, o.multidate);
|
||
else
|
||
o.multidate = 1;
|
||
}
|
||
o.multidateSeparator = String(o.multidateSeparator);
|
||
|
||
o.weekStart %= 7;
|
||
o.weekEnd = ((o.weekStart + 6) % 7);
|
||
|
||
var format = DPGlobal.parseFormat(o.format);
|
||
if (o.startDate !== -Infinity){
|
||
if (!!o.startDate){
|
||
if (o.startDate instanceof Date)
|
||
o.startDate = this._local_to_utc(this._zero_time(o.startDate));
|
||
else
|
||
o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
|
||
}
|
||
else {
|
||
o.startDate = -Infinity;
|
||
}
|
||
}
|
||
if (o.endDate !== Infinity){
|
||
if (!!o.endDate){
|
||
if (o.endDate instanceof Date)
|
||
o.endDate = this._local_to_utc(this._zero_time(o.endDate));
|
||
else
|
||
o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
|
||
}
|
||
else {
|
||
o.endDate = Infinity;
|
||
}
|
||
}
|
||
|
||
o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
|
||
if (!$.isArray(o.daysOfWeekDisabled))
|
||
o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
|
||
o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
|
||
return parseInt(d, 10);
|
||
});
|
||
|
||
var plc = String(o.orientation).toLowerCase().split(/\s+/g),
|
||
_plc = o.orientation.toLowerCase();
|
||
plc = $.grep(plc, function(word){
|
||
return (/^auto|left|right|top|bottom$/).test(word);
|
||
});
|
||
o.orientation = {x: 'auto', y: 'auto'};
|
||
if (!_plc || _plc === 'auto')
|
||
; // no action
|
||
else if (plc.length === 1){
|
||
switch (plc[0]){
|
||
case 'top':
|
||
case 'bottom':
|
||
o.orientation.y = plc[0];
|
||
break;
|
||
case 'left':
|
||
case 'right':
|
||
o.orientation.x = plc[0];
|
||
break;
|
||
}
|
||
}
|
||
else {
|
||
_plc = $.grep(plc, function(word){
|
||
return (/^left|right$/).test(word);
|
||
});
|
||
o.orientation.x = _plc[0] || 'auto';
|
||
|
||
_plc = $.grep(plc, function(word){
|
||
return (/^top|bottom$/).test(word);
|
||
});
|
||
o.orientation.y = _plc[0] || 'auto';
|
||
}
|
||
},
|
||
_events: [],
|
||
_secondaryEvents: [],
|
||
_applyEvents: function(evs){
|
||
for (var i=0, el, ch, ev; i < evs.length; i++){
|
||
el = evs[i][0];
|
||
if (evs[i].length === 2){
|
||
ch = undefined;
|
||
ev = evs[i][1];
|
||
}
|
||
else if (evs[i].length === 3){
|
||
ch = evs[i][1];
|
||
ev = evs[i][2];
|
||
}
|
||
el.on(ev, ch);
|
||
}
|
||
},
|
||
_unapplyEvents: function(evs){
|
||
for (var i=0, el, ev, ch; i < evs.length; i++){
|
||
el = evs[i][0];
|
||
if (evs[i].length === 2){
|
||
ch = undefined;
|
||
ev = evs[i][1];
|
||
}
|
||
else if (evs[i].length === 3){
|
||
ch = evs[i][1];
|
||
ev = evs[i][2];
|
||
}
|
||
el.off(ev, ch);
|
||
}
|
||
},
|
||
_buildEvents: function(){
|
||
if (this.isInput){ // single input
|
||
this._events = [
|
||
[this.element, {
|
||
focus: $.proxy(this.show, this),
|
||
keyup: $.proxy(function(e){
|
||
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
|
||
this.update();
|
||
}, this),
|
||
keydown: $.proxy(this.keydown, this)
|
||
}]
|
||
];
|
||
}
|
||
else if (this.component && this.hasInput){ // component: input + button
|
||
this._events = [
|
||
// For components that are not readonly, allow keyboard nav
|
||
[this.element.find('input'), {
|
||
focus: $.proxy(this.show, this),
|
||
keyup: $.proxy(function(e){
|
||
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
|
||
this.update();
|
||
}, this),
|
||
keydown: $.proxy(this.keydown, this)
|
||
}],
|
||
[this.component, {
|
||
click: $.proxy(this.show, this)
|
||
}]
|
||
];
|
||
}
|
||
else if (this.element.is('div')){ // inline datepicker
|
||
this.isInline = true;
|
||
}
|
||
else {
|
||
this._events = [
|
||
[this.element, {
|
||
click: $.proxy(this.show, this)
|
||
}]
|
||
];
|
||
}
|
||
this._events.push(
|
||
// Component: listen for blur on element descendants
|
||
[this.element, '*', {
|
||
blur: $.proxy(function(e){
|
||
this._focused_from = e.target;
|
||
}, this)
|
||
}],
|
||
// Input: listen for blur on element
|
||
[this.element, {
|
||
blur: $.proxy(function(e){
|
||
this._focused_from = e.target;
|
||
}, this)
|
||
}]
|
||
);
|
||
|
||
this._secondaryEvents = [
|
||
[this.picker, {
|
||
click: $.proxy(this.click, this)
|
||
}],
|
||
[$(window), {
|
||
resize: $.proxy(this.place, this)
|
||
}],
|
||
[$(document), {
|
||
'mousedown touchstart': $.proxy(function(e){
|
||
// Clicked outside the datepicker, hide it
|
||
if (!(
|
||
this.element.is(e.target) ||
|
||
this.element.find(e.target).length ||
|
||
this.picker.is(e.target) ||
|
||
this.picker.find(e.target).length
|
||
)){
|
||
this.hide();
|
||
}
|
||
}, this)
|
||
}]
|
||
];
|
||
},
|
||
_attachEvents: function(){
|
||
this._detachEvents();
|
||
this._applyEvents(this._events);
|
||
},
|
||
_detachEvents: function(){
|
||
this._unapplyEvents(this._events);
|
||
},
|
||
_attachSecondaryEvents: function(){
|
||
this._detachSecondaryEvents();
|
||
this._applyEvents(this._secondaryEvents);
|
||
},
|
||
_detachSecondaryEvents: function(){
|
||
this._unapplyEvents(this._secondaryEvents);
|
||
},
|
||
_trigger: function(event, altdate){
|
||
var date = altdate || this.dates.get(-1),
|
||
local_date = this._utc_to_local(date);
|
||
|
||
this.element.trigger({
|
||
type: event,
|
||
date: local_date,
|
||
dates: $.map(this.dates, this._utc_to_local),
|
||
format: $.proxy(function(ix, format){
|
||
if (arguments.length === 0){
|
||
ix = this.dates.length - 1;
|
||
format = this.o.format;
|
||
}
|
||
else if (typeof ix === 'string'){
|
||
format = ix;
|
||
ix = this.dates.length - 1;
|
||
}
|
||
format = format || this.o.format;
|
||
var date = this.dates.get(ix);
|
||
return DPGlobal.formatDate(date, format, this.o.language);
|
||
}, this)
|
||
});
|
||
},
|
||
|
||
show: function(){
|
||
if (!this.isInline)
|
||
this.picker.appendTo('body');
|
||
this.picker.show();
|
||
this.place();
|
||
this._attachSecondaryEvents();
|
||
this._trigger('show');
|
||
},
|
||
|
||
hide: function(){
|
||
if (this.isInline)
|
||
return;
|
||
if (!this.picker.is(':visible'))
|
||
return;
|
||
this.focusDate = null;
|
||
this.picker.hide().detach();
|
||
this._detachSecondaryEvents();
|
||
this.viewMode = this.o.startView;
|
||
this.showMode();
|
||
|
||
if (
|
||
this.o.forceParse &&
|
||
(
|
||
this.isInput && this.element.val() ||
|
||
this.hasInput && this.element.find('input').val()
|
||
)
|
||
)
|
||
this.setValue();
|
||
this._trigger('hide');
|
||
},
|
||
|
||
remove: function(){
|
||
this.hide();
|
||
this._detachEvents();
|
||
this._detachSecondaryEvents();
|
||
this.picker.remove();
|
||
delete this.element.data().datepicker;
|
||
if (!this.isInput){
|
||
delete this.element.data().date;
|
||
}
|
||
},
|
||
|
||
_utc_to_local: function(utc){
|
||
return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
|
||
},
|
||
_local_to_utc: function(local){
|
||
return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
|
||
},
|
||
_zero_time: function(local){
|
||
return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
|
||
},
|
||
_zero_utc_time: function(utc){
|
||
return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
|
||
},
|
||
|
||
getDates: function(){
|
||
return $.map(this.dates, this._utc_to_local);
|
||
},
|
||
|
||
getUTCDates: function(){
|
||
return $.map(this.dates, function(d){
|
||
return new Date(d);
|
||
});
|
||
},
|
||
|
||
getDate: function(){
|
||
return this._utc_to_local(this.getUTCDate());
|
||
},
|
||
|
||
getUTCDate: function(){
|
||
return new Date(this.dates.get(-1));
|
||
},
|
||
|
||
setDates: function(){
|
||
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
|
||
this.update.apply(this, args);
|
||
this._trigger('changeDate');
|
||
this.setValue();
|
||
},
|
||
|
||
setUTCDates: function(){
|
||
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
|
||
this.update.apply(this, $.map(args, this._utc_to_local));
|
||
this._trigger('changeDate');
|
||
this.setValue();
|
||
},
|
||
|
||
setDate: alias('setDates'),
|
||
setUTCDate: alias('setUTCDates'),
|
||
|
||
setValue: function(){
|
||
var formatted = this.getFormattedDate();
|
||
if (!this.isInput){
|
||
if (this.component){
|
||
this.element.find('input').val(formatted).change();
|
||
}
|
||
}
|
||
else {
|
||
this.element.val(formatted).change();
|
||
}
|
||
},
|
||
|
||
getFormattedDate: function(format){
|
||
if (format === undefined)
|
||
format = this.o.format;
|
||
|
||
var lang = this.o.language;
|
||
return $.map(this.dates, function(d){
|
||
return DPGlobal.formatDate(d, format, lang);
|
||
}).join(this.o.multidateSeparator);
|
||
},
|
||
|
||
setStartDate: function(startDate){
|
||
this._process_options({startDate: startDate});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
setEndDate: function(endDate){
|
||
this._process_options({endDate: endDate});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
setDaysOfWeekDisabled: function(daysOfWeekDisabled){
|
||
this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
place: function(){
|
||
if (this.isInline)
|
||
return;
|
||
var calendarWidth = this.picker.outerWidth(),
|
||
calendarHeight = this.picker.outerHeight(),
|
||
visualPadding = 10,
|
||
windowWidth = $window.width(),
|
||
windowHeight = $window.height(),
|
||
scrollTop = $window.scrollTop();
|
||
|
||
var zIndex = parseInt(this.element.parents().filter(function(){
|
||
return $(this).css('z-index') !== 'auto';
|
||
}).first().css('z-index'))+10;
|
||
var offset = this.component ? this.component.parent().offset() : this.element.offset();
|
||
var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
|
||
var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
|
||
var left = offset.left,
|
||
top = offset.top;
|
||
|
||
this.picker.removeClass(
|
||
'datepicker-orient-top datepicker-orient-bottom '+
|
||
'datepicker-orient-right datepicker-orient-left'
|
||
);
|
||
|
||
if (this.o.orientation.x !== 'auto'){
|
||
this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
|
||
if (this.o.orientation.x === 'right')
|
||
left -= calendarWidth - width;
|
||
}
|
||
// auto x orientation is best-placement: if it crosses a window
|
||
// edge, fudge it sideways
|
||
else {
|
||
// Default to left
|
||
this.picker.addClass('datepicker-orient-left');
|
||
if (offset.left < 0)
|
||
left -= offset.left - visualPadding;
|
||
else if (offset.left + calendarWidth > windowWidth)
|
||
left = windowWidth - calendarWidth - visualPadding;
|
||
}
|
||
|
||
// auto y orientation is best-situation: top or bottom, no fudging,
|
||
// decision based on which shows more of the calendar
|
||
var yorient = this.o.orientation.y,
|
||
top_overflow, bottom_overflow;
|
||
if (yorient === 'auto'){
|
||
top_overflow = -scrollTop + offset.top - calendarHeight;
|
||
bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight);
|
||
if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
|
||
yorient = 'top';
|
||
else
|
||
yorient = 'bottom';
|
||
}
|
||
this.picker.addClass('datepicker-orient-' + yorient);
|
||
if (yorient === 'top')
|
||
top += height;
|
||
else
|
||
top -= calendarHeight + parseInt(this.picker.css('padding-top'));
|
||
|
||
this.picker.css({
|
||
top: top,
|
||
left: left,
|
||
zIndex: zIndex
|
||
});
|
||
},
|
||
|
||
_allow_update: true,
|
||
update: function(){
|
||
if (!this._allow_update)
|
||
return;
|
||
|
||
var oldDates = this.dates.copy(),
|
||
dates = [],
|
||
fromArgs = false;
|
||
if (arguments.length){
|
||
$.each(arguments, $.proxy(function(i, date){
|
||
if (date instanceof Date)
|
||
date = this._local_to_utc(date);
|
||
dates.push(date);
|
||
}, this));
|
||
fromArgs = true;
|
||
}
|
||
else {
|
||
dates = this.isInput
|
||
? this.element.val()
|
||
: this.element.data('date') || this.element.find('input').val();
|
||
if (dates && this.o.multidate)
|
||
dates = dates.split(this.o.multidateSeparator);
|
||
else
|
||
dates = [dates];
|
||
delete this.element.data().date;
|
||
}
|
||
|
||
dates = $.map(dates, $.proxy(function(date){
|
||
return DPGlobal.parseDate(date, this.o.format, this.o.language);
|
||
}, this));
|
||
dates = $.grep(dates, $.proxy(function(date){
|
||
return (
|
||
date < this.o.startDate ||
|
||
date > this.o.endDate ||
|
||
!date
|
||
);
|
||
}, this), true);
|
||
this.dates.replace(dates);
|
||
|
||
if (this.dates.length)
|
||
this.viewDate = new Date(this.dates.get(-1));
|
||
else if (this.viewDate < this.o.startDate)
|
||
this.viewDate = new Date(this.o.startDate);
|
||
else if (this.viewDate > this.o.endDate)
|
||
this.viewDate = new Date(this.o.endDate);
|
||
|
||
if (fromArgs){
|
||
// setting date by clicking
|
||
this.setValue();
|
||
}
|
||
else if (dates.length){
|
||
// setting date by typing
|
||
if (String(oldDates) !== String(this.dates))
|
||
this._trigger('changeDate');
|
||
}
|
||
if (!this.dates.length && oldDates.length)
|
||
this._trigger('clearDate');
|
||
|
||
this.fill();
|
||
},
|
||
|
||
fillDow: function(){
|
||
var dowCnt = this.o.weekStart,
|
||
html = '<tr>';
|
||
if (this.o.calendarWeeks){
|
||
var cell = '<th class="cw"> </th>';
|
||
html += cell;
|
||
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
|
||
}
|
||
while (dowCnt < this.o.weekStart + 7){
|
||
html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
|
||
}
|
||
html += '</tr>';
|
||
this.picker.find('.datepicker-days thead').append(html);
|
||
},
|
||
|
||
fillMonths: function(){
|
||
var html = '',
|
||
i = 0;
|
||
while (i < 12){
|
||
html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
|
||
}
|
||
this.picker.find('.datepicker-months td').html(html);
|
||
},
|
||
|
||
setRange: function(range){
|
||
if (!range || !range.length)
|
||
delete this.range;
|
||
else
|
||
this.range = $.map(range, function(d){
|
||
return d.valueOf();
|
||
});
|
||
this.fill();
|
||
},
|
||
|
||
getClassNames: function(date){
|
||
var cls = [],
|
||
year = this.viewDate.getUTCFullYear(),
|
||
month = this.viewDate.getUTCMonth(),
|
||
today = new Date();
|
||
if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
|
||
cls.push('old');
|
||
}
|
||
else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
|
||
cls.push('new');
|
||
}
|
||
if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
|
||
cls.push('focused');
|
||
// Compare internal UTC date with local today, not UTC today
|
||
if (this.o.todayHighlight &&
|
||
date.getUTCFullYear() === today.getFullYear() &&
|
||
date.getUTCMonth() === today.getMonth() &&
|
||
date.getUTCDate() === today.getDate()){
|
||
cls.push('today');
|
||
}
|
||
if (this.dates.contains(date) !== -1)
|
||
cls.push('active');
|
||
if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
|
||
$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
|
||
cls.push('disabled');
|
||
}
|
||
if (this.range){
|
||
if (date > this.range[0] && date < this.range[this.range.length-1]){
|
||
cls.push('range');
|
||
}
|
||
if ($.inArray(date.valueOf(), this.range) !== -1){
|
||
cls.push('selected');
|
||
}
|
||
}
|
||
return cls;
|
||
},
|
||
|
||
fill: function(){
|
||
var d = new Date(this.viewDate),
|
||
year = d.getUTCFullYear(),
|
||
month = d.getUTCMonth(),
|
||
startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
|
||
startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
|
||
endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
|
||
endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
|
||
todaytxt = dates[this.o.language].today || dates['en'].today || '',
|
||
cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
|
||
tooltip;
|
||
this.picker.find('.datepicker-days thead th.datepicker-switch')
|
||
.text(dates[this.o.language].months[month]+' '+year);
|
||
this.picker.find('tfoot th.today')
|
||
.text(todaytxt)
|
||
.toggle(this.o.todayBtn !== false);
|
||
this.picker.find('tfoot th.clear')
|
||
.text(cleartxt)
|
||
.toggle(this.o.clearBtn !== false);
|
||
this.updateNavArrows();
|
||
this.fillMonths();
|
||
var prevMonth = UTCDate(year, month-1, 28),
|
||
day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
|
||
prevMonth.setUTCDate(day);
|
||
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
|
||
var nextMonth = new Date(prevMonth);
|
||
nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
|
||
nextMonth = nextMonth.valueOf();
|
||
var html = [];
|
||
var clsName;
|
||
while (prevMonth.valueOf() < nextMonth){
|
||
if (prevMonth.getUTCDay() === this.o.weekStart){
|
||
html.push('<tr>');
|
||
if (this.o.calendarWeeks){
|
||
// ISO 8601: First week contains first thursday.
|
||
// ISO also states week starts on Monday, but we can be more abstract here.
|
||
var
|
||
// Start of current week: based on weekstart/current date
|
||
ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
|
||
// Thursday of this week
|
||
th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
|
||
// First Thursday of year, year from thursday
|
||
yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
|
||
// Calendar week: ms between thursdays, div ms per day, div 7 days
|
||
calWeek = (th - yth) / 864e5 / 7 + 1;
|
||
html.push('<td class="cw">'+ calWeek +'</td>');
|
||
|
||
}
|
||
}
|
||
clsName = this.getClassNames(prevMonth);
|
||
clsName.push('day');
|
||
|
||
if (this.o.beforeShowDay !== $.noop){
|
||
var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
|
||
if (before === undefined)
|
||
before = {};
|
||
else if (typeof(before) === 'boolean')
|
||
before = {enabled: before};
|
||
else if (typeof(before) === 'string')
|
||
before = {classes: before};
|
||
if (before.enabled === false)
|
||
clsName.push('disabled');
|
||
if (before.classes)
|
||
clsName = clsName.concat(before.classes.split(/\s+/));
|
||
if (before.tooltip)
|
||
tooltip = before.tooltip;
|
||
}
|
||
|
||
clsName = $.unique(clsName);
|
||
html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
|
||
if (prevMonth.getUTCDay() === this.o.weekEnd){
|
||
html.push('</tr>');
|
||
}
|
||
prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
|
||
}
|
||
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||
|
||
var months = this.picker.find('.datepicker-months')
|
||
.find('th:eq(1)')
|
||
.text(year)
|
||
.end()
|
||
.find('span').removeClass('active');
|
||
|
||
$.each(this.dates, function(i, d){
|
||
if (d.getUTCFullYear() === year)
|
||
months.eq(d.getUTCMonth()).addClass('active');
|
||
});
|
||
|
||
if (year < startYear || year > endYear){
|
||
months.addClass('disabled');
|
||
}
|
||
if (year === startYear){
|
||
months.slice(0, startMonth).addClass('disabled');
|
||
}
|
||
if (year === endYear){
|
||
months.slice(endMonth+1).addClass('disabled');
|
||
}
|
||
|
||
html = '';
|
||
year = parseInt(year/10, 10) * 10;
|
||
var yearCont = this.picker.find('.datepicker-years')
|
||
.find('th:eq(1)')
|
||
.text(year + '-' + (year + 9))
|
||
.end()
|
||
.find('td');
|
||
year -= 1;
|
||
var years = $.map(this.dates, function(d){
|
||
return d.getUTCFullYear();
|
||
}),
|
||
classes;
|
||
for (var i = -1; i < 11; i++){
|
||
classes = ['year'];
|
||
if (i === -1)
|
||
classes.push('old');
|
||
else if (i === 10)
|
||
classes.push('new');
|
||
if ($.inArray(year, years) !== -1)
|
||
classes.push('active');
|
||
if (year < startYear || year > endYear)
|
||
classes.push('disabled');
|
||
html += '<span class="' + classes.join(' ') + '">'+year+'</span>';
|
||
year += 1;
|
||
}
|
||
yearCont.html(html);
|
||
},
|
||
|
||
updateNavArrows: function(){
|
||
if (!this._allow_update)
|
||
return;
|
||
|
||
var d = new Date(this.viewDate),
|
||
year = d.getUTCFullYear(),
|
||
month = d.getUTCMonth();
|
||
switch (this.viewMode){
|
||
case 0:
|
||
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
|
||
this.picker.find('.prev').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.prev').css({visibility: 'visible'});
|
||
}
|
||
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
|
||
this.picker.find('.next').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.next').css({visibility: 'visible'});
|
||
}
|
||
break;
|
||
case 1:
|
||
case 2:
|
||
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){
|
||
this.picker.find('.prev').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.prev').css({visibility: 'visible'});
|
||
}
|
||
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){
|
||
this.picker.find('.next').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.next').css({visibility: 'visible'});
|
||
}
|
||
break;
|
||
}
|
||
},
|
||
|
||
click: function(e){
|
||
e.preventDefault();
|
||
var target = $(e.target).closest('span, td, th'),
|
||
year, month, day;
|
||
if (target.length === 1){
|
||
switch (target[0].nodeName.toLowerCase()){
|
||
case 'th':
|
||
switch (target[0].className){
|
||
case 'datepicker-switch':
|
||
this.showMode(1);
|
||
break;
|
||
case 'prev':
|
||
case 'next':
|
||
var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
|
||
switch (this.viewMode){
|
||
case 0:
|
||
this.viewDate = this.moveMonth(this.viewDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
break;
|
||
case 1:
|
||
case 2:
|
||
this.viewDate = this.moveYear(this.viewDate, dir);
|
||
if (this.viewMode === 1)
|
||
this._trigger('changeYear', this.viewDate);
|
||
break;
|
||
}
|
||
this.fill();
|
||
break;
|
||
case 'today':
|
||
var date = new Date();
|
||
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
||
|
||
this.showMode(-2);
|
||
var which = this.o.todayBtn === 'linked' ? null : 'view';
|
||
this._setDate(date, which);
|
||
break;
|
||
case 'clear':
|
||
var element;
|
||
if (this.isInput)
|
||
element = this.element;
|
||
else if (this.component)
|
||
element = this.element.find('input');
|
||
if (element)
|
||
element.val("").change();
|
||
this.update();
|
||
this._trigger('changeDate');
|
||
if (this.o.autoclose)
|
||
this.hide();
|
||
break;
|
||
}
|
||
break;
|
||
case 'span':
|
||
if (!target.is('.disabled')){
|
||
this.viewDate.setUTCDate(1);
|
||
if (target.is('.month')){
|
||
day = 1;
|
||
month = target.parent().find('span').index(target);
|
||
year = this.viewDate.getUTCFullYear();
|
||
this.viewDate.setUTCMonth(month);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
if (this.o.minViewMode === 1){
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
}
|
||
else {
|
||
day = 1;
|
||
month = 0;
|
||
year = parseInt(target.text(), 10)||0;
|
||
this.viewDate.setUTCFullYear(year);
|
||
this._trigger('changeYear', this.viewDate);
|
||
if (this.o.minViewMode === 2){
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
}
|
||
this.showMode(-1);
|
||
this.fill();
|
||
}
|
||
break;
|
||
case 'td':
|
||
if (target.is('.day') && !target.is('.disabled')){
|
||
day = parseInt(target.text(), 10)||1;
|
||
year = this.viewDate.getUTCFullYear();
|
||
month = this.viewDate.getUTCMonth();
|
||
if (target.is('.old')){
|
||
if (month === 0){
|
||
month = 11;
|
||
year -= 1;
|
||
}
|
||
else {
|
||
month -= 1;
|
||
}
|
||
}
|
||
else if (target.is('.new')){
|
||
if (month === 11){
|
||
month = 0;
|
||
year += 1;
|
||
}
|
||
else {
|
||
month += 1;
|
||
}
|
||
}
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (this.picker.is(':visible') && this._focused_from){
|
||
$(this._focused_from).focus();
|
||
}
|
||
delete this._focused_from;
|
||
},
|
||
|
||
_toggle_multidate: function(date){
|
||
var ix = this.dates.contains(date);
|
||
if (!date){
|
||
this.dates.clear();
|
||
}
|
||
else if (ix !== -1){
|
||
this.dates.remove(ix);
|
||
}
|
||
else {
|
||
this.dates.push(date);
|
||
}
|
||
if (typeof this.o.multidate === 'number')
|
||
while (this.dates.length > this.o.multidate)
|
||
this.dates.remove(0);
|
||
},
|
||
|
||
_setDate: function(date, which){
|
||
if (!which || which === 'date')
|
||
this._toggle_multidate(date && new Date(date));
|
||
if (!which || which === 'view')
|
||
this.viewDate = date && new Date(date);
|
||
|
||
this.fill();
|
||
this.setValue();
|
||
this._trigger('changeDate');
|
||
var element;
|
||
if (this.isInput){
|
||
element = this.element;
|
||
}
|
||
else if (this.component){
|
||
element = this.element.find('input');
|
||
}
|
||
if (element){
|
||
element.change();
|
||
}
|
||
if (this.o.autoclose && (!which || which === 'date')){
|
||
this.hide();
|
||
}
|
||
},
|
||
|
||
moveMonth: function(date, dir){
|
||
if (!date)
|
||
return undefined;
|
||
if (!dir)
|
||
return date;
|
||
var new_date = new Date(date.valueOf()),
|
||
day = new_date.getUTCDate(),
|
||
month = new_date.getUTCMonth(),
|
||
mag = Math.abs(dir),
|
||
new_month, test;
|
||
dir = dir > 0 ? 1 : -1;
|
||
if (mag === 1){
|
||
test = dir === -1
|
||
// If going back one month, make sure month is not current month
|
||
// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
|
||
? function(){
|
||
return new_date.getUTCMonth() === month;
|
||
}
|
||
// If going forward one month, make sure month is as expected
|
||
// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
|
||
: function(){
|
||
return new_date.getUTCMonth() !== new_month;
|
||
};
|
||
new_month = month + dir;
|
||
new_date.setUTCMonth(new_month);
|
||
// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
|
||
if (new_month < 0 || new_month > 11)
|
||
new_month = (new_month + 12) % 12;
|
||
}
|
||
else {
|
||
// For magnitudes >1, move one month at a time...
|
||
for (var i=0; i < mag; i++)
|
||
// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
|
||
new_date = this.moveMonth(new_date, dir);
|
||
// ...then reset the day, keeping it in the new month
|
||
new_month = new_date.getUTCMonth();
|
||
new_date.setUTCDate(day);
|
||
test = function(){
|
||
return new_month !== new_date.getUTCMonth();
|
||
};
|
||
}
|
||
// Common date-resetting loop -- if date is beyond end of month, make it
|
||
// end of month
|
||
while (test()){
|
||
new_date.setUTCDate(--day);
|
||
new_date.setUTCMonth(new_month);
|
||
}
|
||
return new_date;
|
||
},
|
||
|
||
moveYear: function(date, dir){
|
||
return this.moveMonth(date, dir*12);
|
||
},
|
||
|
||
dateWithinRange: function(date){
|
||
return date >= this.o.startDate && date <= this.o.endDate;
|
||
},
|
||
|
||
keydown: function(e){
|
||
if (this.picker.is(':not(:visible)')){
|
||
if (e.keyCode === 27) // allow escape to hide and re-show picker
|
||
this.show();
|
||
return;
|
||
}
|
||
var dateChanged = false,
|
||
dir, newDate, newViewDate,
|
||
focusDate = this.focusDate || this.viewDate;
|
||
switch (e.keyCode){
|
||
case 27: // escape
|
||
if (this.focusDate){
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.fill();
|
||
}
|
||
else
|
||
this.hide();
|
||
e.preventDefault();
|
||
break;
|
||
case 37: // left
|
||
case 39: // right
|
||
if (!this.o.keyboardNavigation)
|
||
break;
|
||
dir = e.keyCode === 37 ? -1 : 1;
|
||
if (e.ctrlKey){
|
||
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveYear(focusDate, dir);
|
||
this._trigger('changeYear', this.viewDate);
|
||
}
|
||
else if (e.shiftKey){
|
||
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveMonth(focusDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
}
|
||
else {
|
||
newDate = new Date(this.dates.get(-1) || UTCToday());
|
||
newDate.setUTCDate(newDate.getUTCDate() + dir);
|
||
newViewDate = new Date(focusDate);
|
||
newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
|
||
}
|
||
if (this.dateWithinRange(newDate)){
|
||
this.focusDate = this.viewDate = newViewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
e.preventDefault();
|
||
}
|
||
break;
|
||
case 38: // up
|
||
case 40: // down
|
||
if (!this.o.keyboardNavigation)
|
||
break;
|
||
dir = e.keyCode === 38 ? -1 : 1;
|
||
if (e.ctrlKey){
|
||
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveYear(focusDate, dir);
|
||
this._trigger('changeYear', this.viewDate);
|
||
}
|
||
else if (e.shiftKey){
|
||
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveMonth(focusDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
}
|
||
else {
|
||
newDate = new Date(this.dates.get(-1) || UTCToday());
|
||
newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
|
||
newViewDate = new Date(focusDate);
|
||
newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
|
||
}
|
||
if (this.dateWithinRange(newDate)){
|
||
this.focusDate = this.viewDate = newViewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
e.preventDefault();
|
||
}
|
||
break;
|
||
case 32: // spacebar
|
||
// Spacebar is used in manually typing dates in some formats.
|
||
// As such, its behavior should not be hijacked.
|
||
break;
|
||
case 13: // enter
|
||
focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
|
||
this._toggle_multidate(focusDate);
|
||
dateChanged = true;
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
if (this.picker.is(':visible')){
|
||
e.preventDefault();
|
||
if (this.o.autoclose)
|
||
this.hide();
|
||
}
|
||
break;
|
||
case 9: // tab
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.fill();
|
||
this.hide();
|
||
break;
|
||
}
|
||
if (dateChanged){
|
||
if (this.dates.length)
|
||
this._trigger('changeDate');
|
||
else
|
||
this._trigger('clearDate');
|
||
var element;
|
||
if (this.isInput){
|
||
element = this.element;
|
||
}
|
||
else if (this.component){
|
||
element = this.element.find('input');
|
||
}
|
||
if (element){
|
||
element.change();
|
||
}
|
||
}
|
||
},
|
||
|
||
showMode: function(dir){
|
||
if (dir){
|
||
this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
|
||
}
|
||
this.picker
|
||
.find('>div')
|
||
.hide()
|
||
.filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName)
|
||
.css('display', 'block');
|
||
this.updateNavArrows();
|
||
}
|
||
};
|
||
|
||
var DateRangePicker = function(element, options){
|
||
this.element = $(element);
|
||
this.inputs = $.map(options.inputs, function(i){
|
||
return i.jquery ? i[0] : i;
|
||
});
|
||
delete options.inputs;
|
||
|
||
$(this.inputs)
|
||
.datepicker(options)
|
||
.bind('changeDate', $.proxy(this.dateUpdated, this));
|
||
|
||
this.pickers = $.map(this.inputs, function(i){
|
||
return $(i).data('datepicker');
|
||
});
|
||
this.updateDates();
|
||
};
|
||
DateRangePicker.prototype = {
|
||
updateDates: function(){
|
||
this.dates = $.map(this.pickers, function(i){
|
||
return i.getUTCDate();
|
||
});
|
||
this.updateRanges();
|
||
},
|
||
updateRanges: function(){
|
||
var range = $.map(this.dates, function(d){
|
||
return d.valueOf();
|
||
});
|
||
$.each(this.pickers, function(i, p){
|
||
p.setRange(range);
|
||
});
|
||
},
|
||
dateUpdated: function(e){
|
||
// `this.updating` is a workaround for preventing infinite recursion
|
||
// between `changeDate` triggering and `setUTCDate` calling. Until
|
||
// there is a better mechanism.
|
||
if (this.updating)
|
||
return;
|
||
this.updating = true;
|
||
|
||
var dp = $(e.target).data('datepicker'),
|
||
new_date = dp.getUTCDate(),
|
||
i = $.inArray(e.target, this.inputs),
|
||
l = this.inputs.length;
|
||
if (i === -1)
|
||
return;
|
||
|
||
$.each(this.pickers, function(i, p){
|
||
if (!p.getUTCDate())
|
||
p.setUTCDate(new_date);
|
||
});
|
||
|
||
if (new_date < this.dates[i]){
|
||
// Date being moved earlier/left
|
||
while (i >= 0 && new_date < this.dates[i]){
|
||
this.pickers[i--].setUTCDate(new_date);
|
||
}
|
||
}
|
||
else if (new_date > this.dates[i]){
|
||
// Date being moved later/right
|
||
while (i < l && new_date > this.dates[i]){
|
||
this.pickers[i++].setUTCDate(new_date);
|
||
}
|
||
}
|
||
this.updateDates();
|
||
|
||
delete this.updating;
|
||
},
|
||
remove: function(){
|
||
$.map(this.pickers, function(p){ p.remove(); });
|
||
delete this.element.data().datepicker;
|
||
}
|
||
};
|
||
|
||
function opts_from_el(el, prefix){
|
||
// Derive options from element data-attrs
|
||
var data = $(el).data(),
|
||
out = {}, inkey,
|
||
replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
|
||
prefix = new RegExp('^' + prefix.toLowerCase());
|
||
function re_lower(_,a){
|
||
return a.toLowerCase();
|
||
}
|
||
for (var key in data)
|
||
if (prefix.test(key)){
|
||
inkey = key.replace(replace, re_lower);
|
||
out[inkey] = data[key];
|
||
}
|
||
return out;
|
||
}
|
||
|
||
function opts_from_locale(lang){
|
||
// Derive options from locale plugins
|
||
var out = {};
|
||
// Check if "de-DE" style date is available, if not language should
|
||
// fallback to 2 letter code eg "de"
|
||
if (!dates[lang]){
|
||
lang = lang.split('-')[0];
|
||
if (!dates[lang])
|
||
return;
|
||
}
|
||
var d = dates[lang];
|
||
$.each(locale_opts, function(i,k){
|
||
if (k in d)
|
||
out[k] = d[k];
|
||
});
|
||
return out;
|
||
}
|
||
|
||
var old = $.fn.datepicker;
|
||
$.fn.datepicker = function(option){
|
||
var args = Array.apply(null, arguments);
|
||
args.shift();
|
||
var internal_return;
|
||
this.each(function(){
|
||
var $this = $(this),
|
||
data = $this.data('datepicker'),
|
||
options = typeof option === 'object' && option;
|
||
if (!data){
|
||
var elopts = opts_from_el(this, 'date'),
|
||
// Preliminary otions
|
||
xopts = $.extend({}, defaults, elopts, options),
|
||
locopts = opts_from_locale(xopts.language),
|
||
// Options priority: js args, data-attrs, locales, defaults
|
||
opts = $.extend({}, defaults, locopts, elopts, options);
|
||
if ($this.is('.input-daterange') || opts.inputs){
|
||
var ropts = {
|
||
inputs: opts.inputs || $this.find('input').toArray()
|
||
};
|
||
$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
|
||
}
|
||
else {
|
||
$this.data('datepicker', (data = new Datepicker(this, opts)));
|
||
}
|
||
}
|
||
if (typeof option === 'string' && typeof data[option] === 'function'){
|
||
internal_return = data[option].apply(data, args);
|
||
if (internal_return !== undefined)
|
||
return false;
|
||
}
|
||
});
|
||
if (internal_return !== undefined)
|
||
return internal_return;
|
||
else
|
||
return this;
|
||
};
|
||
|
||
var defaults = $.fn.datepicker.defaults = {
|
||
autoclose: false,
|
||
beforeShowDay: $.noop,
|
||
calendarWeeks: false,
|
||
clearBtn: false,
|
||
daysOfWeekDisabled: [],
|
||
endDate: Infinity,
|
||
forceParse: true,
|
||
format: 'mm/dd/yyyy',
|
||
keyboardNavigation: true,
|
||
language: 'en',
|
||
minViewMode: 0,
|
||
multidate: false,
|
||
multidateSeparator: ',',
|
||
orientation: "auto",
|
||
rtl: false,
|
||
startDate: -Infinity,
|
||
startView: 0,
|
||
todayBtn: false,
|
||
todayHighlight: false,
|
||
weekStart: 0
|
||
};
|
||
var locale_opts = $.fn.datepicker.locale_opts = [
|
||
'format',
|
||
'rtl',
|
||
'weekStart'
|
||
];
|
||
$.fn.datepicker.Constructor = Datepicker;
|
||
var dates = $.fn.datepicker.dates = {
|
||
en: {
|
||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||
today: "Today",
|
||
clear: "Clear"
|
||
}
|
||
};
|
||
|
||
var DPGlobal = {
|
||
modes: [
|
||
{
|
||
clsName: 'days',
|
||
navFnc: 'Month',
|
||
navStep: 1
|
||
},
|
||
{
|
||
clsName: 'months',
|
||
navFnc: 'FullYear',
|
||
navStep: 1
|
||
},
|
||
{
|
||
clsName: 'years',
|
||
navFnc: 'FullYear',
|
||
navStep: 10
|
||
}],
|
||
isLeapYear: function(year){
|
||
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
|
||
},
|
||
getDaysInMonth: function(year, month){
|
||
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
|
||
},
|
||
validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
|
||
nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
|
||
parseFormat: function(format){
|
||
// IE treats \0 as a string end in inputs (truncating the value),
|
||
// so it's a bad format delimiter, anyway
|
||
var separators = format.replace(this.validParts, '\0').split('\0'),
|
||
parts = format.match(this.validParts);
|
||
if (!separators || !separators.length || !parts || parts.length === 0){
|
||
throw new Error("Invalid date format.");
|
||
}
|
||
return {separators: separators, parts: parts};
|
||
},
|
||
parseDate: function(date, format, language){
|
||
if (!date)
|
||
return undefined;
|
||
if (date instanceof Date)
|
||
return date;
|
||
if (typeof format === 'string')
|
||
format = DPGlobal.parseFormat(format);
|
||
var part_re = /([\-+]\d+)([dmwy])/,
|
||
parts = date.match(/([\-+]\d+)([dmwy])/g),
|
||
part, dir, i;
|
||
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
|
||
date = new Date();
|
||
for (i=0; i < parts.length; i++){
|
||
part = part_re.exec(parts[i]);
|
||
dir = parseInt(part[1]);
|
||
switch (part[2]){
|
||
case 'd':
|
||
date.setUTCDate(date.getUTCDate() + dir);
|
||
break;
|
||
case 'm':
|
||
date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
|
||
break;
|
||
case 'w':
|
||
date.setUTCDate(date.getUTCDate() + dir * 7);
|
||
break;
|
||
case 'y':
|
||
date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
|
||
break;
|
||
}
|
||
}
|
||
return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
|
||
}
|
||
parts = date && date.match(this.nonpunctuation) || [];
|
||
date = new Date();
|
||
var parsed = {},
|
||
setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
|
||
setters_map = {
|
||
yyyy: function(d,v){
|
||
return d.setUTCFullYear(v);
|
||
},
|
||
yy: function(d,v){
|
||
return d.setUTCFullYear(2000+v);
|
||
},
|
||
m: function(d,v){
|
||
if (isNaN(d))
|
||
return d;
|
||
v -= 1;
|
||
while (v < 0) v += 12;
|
||
v %= 12;
|
||
d.setUTCMonth(v);
|
||
while (d.getUTCMonth() !== v)
|
||
d.setUTCDate(d.getUTCDate()-1);
|
||
return d;
|
||
},
|
||
d: function(d,v){
|
||
return d.setUTCDate(v);
|
||
}
|
||
},
|
||
val, filtered;
|
||
setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
|
||
setters_map['dd'] = setters_map['d'];
|
||
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
||
var fparts = format.parts.slice();
|
||
// Remove noop parts
|
||
if (parts.length !== fparts.length){
|
||
fparts = $(fparts).filter(function(i,p){
|
||
return $.inArray(p, setters_order) !== -1;
|
||
}).toArray();
|
||
}
|
||
// Process remainder
|
||
function match_part(){
|
||
var m = this.slice(0, parts[i].length),
|
||
p = parts[i].slice(0, m.length);
|
||
return m === p;
|
||
}
|
||
if (parts.length === fparts.length){
|
||
var cnt;
|
||
for (i=0, cnt = fparts.length; i < cnt; i++){
|
||
val = parseInt(parts[i], 10);
|
||
part = fparts[i];
|
||
if (isNaN(val)){
|
||
switch (part){
|
||
case 'MM':
|
||
filtered = $(dates[language].months).filter(match_part);
|
||
val = $.inArray(filtered[0], dates[language].months) + 1;
|
||
break;
|
||
case 'M':
|
||
filtered = $(dates[language].monthsShort).filter(match_part);
|
||
val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
|
||
break;
|
||
}
|
||
}
|
||
parsed[part] = val;
|
||
}
|
||
var _date, s;
|
||
for (i=0; i < setters_order.length; i++){
|
||
s = setters_order[i];
|
||
if (s in parsed && !isNaN(parsed[s])){
|
||
_date = new Date(date);
|
||
setters_map[s](_date, parsed[s]);
|
||
if (!isNaN(_date))
|
||
date = _date;
|
||
}
|
||
}
|
||
}
|
||
return date;
|
||
},
|
||
formatDate: function(date, format, language){
|
||
if (!date)
|
||
return '';
|
||
if (typeof format === 'string')
|
||
format = DPGlobal.parseFormat(format);
|
||
var val = {
|
||
d: date.getUTCDate(),
|
||
D: dates[language].daysShort[date.getUTCDay()],
|
||
DD: dates[language].days[date.getUTCDay()],
|
||
m: date.getUTCMonth() + 1,
|
||
M: dates[language].monthsShort[date.getUTCMonth()],
|
||
MM: dates[language].months[date.getUTCMonth()],
|
||
yy: date.getUTCFullYear().toString().substring(2),
|
||
yyyy: date.getUTCFullYear()
|
||
};
|
||
val.dd = (val.d < 10 ? '0' : '') + val.d;
|
||
val.mm = (val.m < 10 ? '0' : '') + val.m;
|
||
date = [];
|
||
var seps = $.extend([], format.separators);
|
||
for (var i=0, cnt = format.parts.length; i <= cnt; i++){
|
||
if (seps.length)
|
||
date.push(seps.shift());
|
||
date.push(val[format.parts[i]]);
|
||
}
|
||
return date.join('');
|
||
},
|
||
headTemplate: '<thead>'+
|
||
'<tr>'+
|
||
'<th class="prev">«</th>'+
|
||
'<th colspan="5" class="datepicker-switch"></th>'+
|
||
'<th class="next">»</th>'+
|
||
'</tr>'+
|
||
'</thead>',
|
||
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
|
||
footTemplate: '<tfoot>'+
|
||
'<tr>'+
|
||
'<th colspan="7" class="today"></th>'+
|
||
'</tr>'+
|
||
'<tr>'+
|
||
'<th colspan="7" class="clear"></th>'+
|
||
'</tr>'+
|
||
'</tfoot>'
|
||
};
|
||
DPGlobal.template = '<div class="datepicker">'+
|
||
'<div class="datepicker-days">'+
|
||
'<table class=" table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
'<tbody></tbody>'+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'<div class="datepicker-months">'+
|
||
'<table class="table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
DPGlobal.contTemplate+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'<div class="datepicker-years">'+
|
||
'<table class="table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
DPGlobal.contTemplate+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'</div>';
|
||
|
||
$.fn.datepicker.DPGlobal = DPGlobal;
|
||
|
||
|
||
/* DATEPICKER NO CONFLICT
|
||
* =================== */
|
||
|
||
$.fn.datepicker.noConflict = function(){
|
||
$.fn.datepicker = old;
|
||
return this;
|
||
};
|
||
|
||
|
||
/* DATEPICKER DATA-API
|
||
* ================== */
|
||
|
||
$(document).on(
|
||
'focus.datepicker.data-api click.datepicker.data-api',
|
||
'[data-provide="datepicker"]',
|
||
function(e){
|
||
var $this = $(this);
|
||
if ($this.data('datepicker'))
|
||
return;
|
||
e.preventDefault();
|
||
// component click requires us to explicitly show it
|
||
$this.datepicker('show');
|
||
}
|
||
);
|
||
$(function(){
|
||
$('[data-provide="datepicker-inline"]').datepicker();
|
||
});
|
||
|
||
}(window.jQuery));
|
||
|
||
/*!
|
||
* typeahead.js 0.9.3
|
||
* https://github.com/twitter/typeahead
|
||
* Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT
|
||
*/
|
||
|
||
!function(a){var b="0.9.3",c={isMsie:function(){var a=/(msie) ([\w.]+)/i.exec(navigator.userAgent);return a?parseInt(a[2],10):!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},bind:a.proxy,bindAll:function(b){var c;for(var d in b)a.isFunction(c=b[d])&&(b[d]=a.proxy(c,b))},indexOf:function(a,b){for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1},each:a.each,map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},tokenizeQuery:function(b){return a.trim(b).toLowerCase().split(/[\s]+/)},tokenizeText:function(b){return a.trim(b).toLowerCase().split(/[\s\-_]+/)},getProtocol:function(){return location.protocol},noop:function(){}},d=function(){var a=/\s+/;return{on:function(b,c){var d;if(!c)return this;for(this._callbacks=this._callbacks||{},b=b.split(a);d=b.shift();)this._callbacks[d]=this._callbacks[d]||[],this._callbacks[d].push(c);return this},trigger:function(b,c){var d,e;if(!this._callbacks)return this;for(b=b.split(a);d=b.shift();)if(e=this._callbacks[d])for(var f=0;f<e.length;f+=1)e[f].call(this,{type:d,data:c});return this}}}(),e=function(){function b(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return c.mixin(b.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),b}(),f=function(){function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+this.prefix)}function b(){return(new Date).getTime()}function d(a){return JSON.stringify(c.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return c.isNumber(g)?f.setItem(this._ttlKey(a),d(b()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return c.isNumber(d)&&b()>d?!0:!1}}:{get:c.noop,set:c.noop,remove:c.noop,clear:c.noop,isExpired:c.noop},c.mixin(a.prototype,g),a}(),g=function(){function a(a){c.bindAll(this),a=a||{},this.sizeLimit=a.sizeLimit||10,this.cache={},this.cachedKeysByAge=[]}return c.mixin(a.prototype,{get:function(a){return this.cache[a]},set:function(a,b){var c;this.cachedKeysByAge.length===this.sizeLimit&&(c=this.cachedKeysByAge.shift(),delete this.cache[c]),this.cache[a]=b,this.cachedKeysByAge.push(a)}}),a}(),h=function(){function b(a){c.bindAll(this),a=c.isString(a)?{url:a}:a,i=i||new g,h=c.isNumber(a.maxParallelRequests)?a.maxParallelRequests:h||6,this.url=a.url,this.wildcard=a.wildcard||"%QUERY",this.filter=a.filter,this.replace=a.replace,this.ajaxSettings={type:"get",cache:a.cache,timeout:a.timeout,dataType:a.dataType||"json",beforeSend:a.beforeSend},this._get=(/^throttle$/i.test(a.rateLimitFn)?c.throttle:c.debounce)(this._get,a.rateLimitWait||300)}function d(){j++}function e(){j--}function f(){return h>j}var h,i,j=0,k={};return c.mixin(b.prototype,{_get:function(a,b){function c(c){var e=d.filter?d.filter(c):c;b&&b(e),i.set(a,c)}var d=this;f()?this._sendRequest(a).done(c):this.onDeckRequestArgs=[].slice.call(arguments,0)},_sendRequest:function(b){function c(){e(),k[b]=null,f.onDeckRequestArgs&&(f._get.apply(f,f.onDeckRequestArgs),f.onDeckRequestArgs=null)}var f=this,g=k[b];return g||(d(),g=k[b]=a.ajax(b,this.ajaxSettings).always(c)),g},get:function(a,b){var d,e,f=this,g=encodeURIComponent(a||"");return b=b||c.noop,d=this.replace?this.replace(this.url,g):this.url.replace(this.wildcard,g),(e=i.get(d))?c.defer(function(){b(f.filter?f.filter(e):e)}):this._get(d,b),!!e}}),b}(),i=function(){function d(b){c.bindAll(this),c.isString(b.template)&&!b.engine&&a.error("no template engine specified"),b.local||b.prefetch||b.remote||a.error("one of local, prefetch, or remote is required"),this.name=b.name||c.getUniqueId(),this.limit=b.limit||5,this.minLength=b.minLength||1,this.header=b.header,this.footer=b.footer,this.valueKey=b.valueKey||"value",this.template=e(b.template,b.engine,this.valueKey),this.local=b.local,this.prefetch=b.prefetch,this.remote=b.remote,this.itemHash={},this.adjacencyList={},this.storage=b.name?new f(b.name):null}function e(a,b,d){var e,f;return c.isFunction(a)?e=a:c.isString(a)?(f=b.compile(a),e=c.bind(f.render,f)):e=function(a){return"<p>"+a[d]+"</p>"},e}var g={thumbprint:"thumbprint",protocol:"protocol",itemHash:"itemHash",adjacencyList:"adjacencyList"};return c.mixin(d.prototype,{_processLocalData:function(a){this._mergeProcessedData(this._processData(a))},_loadPrefetchData:function(d){function e(a){var b=d.filter?d.filter(a):a,e=m._processData(b),f=e.itemHash,h=e.adjacencyList;m.storage&&(m.storage.set(g.itemHash,f,d.ttl),m.storage.set(g.adjacencyList,h,d.ttl),m.storage.set(g.thumbprint,n,d.ttl),m.storage.set(g.protocol,c.getProtocol(),d.ttl)),m._mergeProcessedData(e)}var f,h,i,j,k,l,m=this,n=b+(d.thumbprint||"");return this.storage&&(f=this.storage.get(g.thumbprint),h=this.storage.get(g.protocol),i=this.storage.get(g.itemHash),j=this.storage.get(g.adjacencyList)),k=f!==n||h!==c.getProtocol(),d=c.isString(d)?{url:d}:d,d.ttl=c.isNumber(d.ttl)?d.ttl:864e5,i&&j&&!k?(this._mergeProcessedData({itemHash:i,adjacencyList:j}),l=a.Deferred().resolve()):l=a.getJSON(d.url).done(e),l},_transformDatum:function(a){var b=c.isString(a)?a:a[this.valueKey],d=a.tokens||c.tokenizeText(b),e={value:b,tokens:d};return c.isString(a)?(e.datum={},e.datum[this.valueKey]=a):e.datum=a,e.tokens=c.filter(e.tokens,function(a){return!c.isBlankString(a)}),e.tokens=c.map(e.tokens,function(a){return a.toLowerCase()}),e},_processData:function(a){var b=this,d={},e={};return c.each(a,function(a,f){var g=b._transformDatum(f),h=c.getUniqueId(g.value);d[h]=g,c.each(g.tokens,function(a,b){var d=b.charAt(0),f=e[d]||(e[d]=[h]);!~c.indexOf(f,h)&&f.push(h)})}),{itemHash:d,adjacencyList:e}},_mergeProcessedData:function(a){var b=this;c.mixin(this.itemHash,a.itemHash),c.each(a.adjacencyList,function(a,c){var d=b.adjacencyList[a];b.adjacencyList[a]=d?d.concat(c):c})},_getLocalSuggestions:function(a){var b,d=this,e=[],f=[],g=[];return c.each(a,function(a,b){var d=b.charAt(0);!~c.indexOf(e,d)&&e.push(d)}),c.each(e,function(a,c){var e=d.adjacencyList[c];return e?(f.push(e),(!b||e.length<b.length)&&(b=e),void 0):!1}),f.length<e.length?[]:(c.each(b,function(b,e){var h,i,j=d.itemHash[e];h=c.every(f,function(a){return~c.indexOf(a,e)}),i=h&&c.every(a,function(a){return c.some(j.tokens,function(b){return 0===b.indexOf(a)})}),i&&g.push(j)}),g)},initialize:function(){var b;return this.local&&this._processLocalData(this.local),this.transport=this.remote?new h(this.remote):null,b=this.prefetch?this._loadPrefetchData(this.prefetch):a.Deferred().resolve(),this.local=this.prefetch=this.remote=null,this.initialize=function(){return b},b},getSuggestions:function(a,b){function d(a){f=f.slice(0),c.each(a,function(a,b){var d,e=g._transformDatum(b);return d=c.some(f,function(a){return e.value===a.value}),!d&&f.push(e),f.length<g.limit}),b&&b(f)}var e,f,g=this,h=!1;a.length<this.minLength||(e=c.tokenizeQuery(a),f=this._getLocalSuggestions(e).slice(0,this.limit),f.length<this.limit&&this.transport&&(h=this.transport.get(a,d)),!h&&b&&b(f))}}),d}(),j=function(){function b(b){var d=this;c.bindAll(this),this.specialKeyCodeMap={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},this.$hint=a(b.hint),this.$input=a(b.input).on("blur.tt",this._handleBlur).on("focus.tt",this._handleFocus).on("keydown.tt",this._handleSpecialKeyEvent),c.isMsie()?this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){d.specialKeyCodeMap[a.which||a.keyCode]||c.defer(d._compareQueryToInputValue)}):this.$input.on("input.tt",this._compareQueryToInputValue),this.query=this.$input.val(),this.$overflowHelper=e(this.$input)}function e(b){return a("<span></span>").css({position:"absolute",left:"-9999px",visibility:"hidden",whiteSpace:"nowrap",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function f(a,b){return a=(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),b=(b||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),a===b}return c.mixin(b.prototype,d,{_handleFocus:function(){this.trigger("focused")},_handleBlur:function(){this.trigger("blured")},_handleSpecialKeyEvent:function(a){var b=this.specialKeyCodeMap[a.which||a.keyCode];b&&this.trigger(b+"Keyed",a)},_compareQueryToInputValue:function(){var a=this.getInputValue(),b=f(this.query,a),c=b?this.query.length!==a.length:!1;c?this.trigger("whitespaceChanged",{value:this.query}):b||this.trigger("queryChanged",{value:this.query=a})},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),!b&&this._compareQueryToInputValue()},getHintValue:function(){return this.$hint.val()},setHintValue:function(a){this.$hint.val(a)},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},isOverflow:function(){return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>this.$input.width()},isCursorAtEnd:function(){var a,b=this.$input.val().length,d=this.$input[0].selectionStart;return c.isNumber(d)?d===b:document.selection?(a=document.selection.createRange(),a.moveStart("character",-b),b===a.text.length):!0}}),b}(),k=function(){function b(b){c.bindAll(this),this.isOpen=!1,this.isEmpty=!0,this.isMouseOverDropdown=!1,this.$menu=a(b.menu).on("mouseenter.tt",this._handleMouseenter).on("mouseleave.tt",this._handleMouseleave).on("click.tt",".tt-suggestion",this._handleSelection).on("mouseover.tt",".tt-suggestion",this._handleMouseover)}function e(a){return a.data("suggestion")}var f={suggestionsList:'<span class="tt-suggestions"></span>'},g={suggestionsList:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"}};return c.mixin(b.prototype,d,{_handleMouseenter:function(){this.isMouseOverDropdown=!0},_handleMouseleave:function(){this.isMouseOverDropdown=!1},_handleMouseover:function(b){var c=a(b.currentTarget);this._getSuggestions().removeClass("tt-is-under-cursor"),c.addClass("tt-is-under-cursor")},_handleSelection:function(b){var c=a(b.currentTarget);this.trigger("suggestionSelected",e(c))},_show:function(){this.$menu.css("display","block")},_hide:function(){this.$menu.hide()},_moveCursor:function(a){var b,c,d,f;if(this.isVisible()){if(b=this._getSuggestions(),c=b.filter(".tt-is-under-cursor"),c.removeClass("tt-is-under-cursor"),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return this.trigger("cursorRemoved"),void 0;-1>d&&(d=b.length-1),f=b.eq(d).addClass("tt-is-under-cursor"),this._ensureVisibility(f),this.trigger("cursorMoved",e(f))}},_getSuggestions:function(){return this.$menu.find(".tt-suggestions > .tt-suggestion")},_ensureVisibility:function(a){var b=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),c=this.$menu.scrollTop(),d=a.position().top,e=d+a.outerHeight(!0);0>d?this.$menu.scrollTop(c+d):e>b&&this.$menu.scrollTop(c+(e-b))},destroy:function(){this.$menu.off(".tt"),this.$menu=null},isVisible:function(){return this.isOpen&&!this.isEmpty},closeUnlessMouseIsOverDropdown:function(){this.isMouseOverDropdown||this.close()},close:function(){this.isOpen&&(this.isOpen=!1,this.isMouseOverDropdown=!1,this._hide(),this.$menu.find(".tt-suggestions > .tt-suggestion").removeClass("tt-is-under-cursor"),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){var b={left:"0",right:"auto"},c={left:"auto",right:" 0"};"ltr"===a?this.$menu.css(b):this.$menu.css(c)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getSuggestionUnderCursor:function(){var a=this._getSuggestions().filter(".tt-is-under-cursor").first();return a.length>0?e(a):null},getFirstSuggestion:function(){var a=this._getSuggestions().first();return a.length>0?e(a):null},renderSuggestions:function(b,d){var e,h,i,j,k,l="tt-dataset-"+b.name,m='<div class="tt-suggestion">%body</div>',n=this.$menu.find("."+l);0===n.length&&(h=a(f.suggestionsList).css(g.suggestionsList),n=a("<div></div>").addClass(l).append(b.header).append(h).append(b.footer).appendTo(this.$menu)),d.length>0?(this.isEmpty=!1,this.isOpen&&this._show(),i=document.createElement("div"),j=document.createDocumentFragment(),c.each(d,function(c,d){d.dataset=b.name,e=b.template(d.datum),i.innerHTML=m.replace("%body",e),k=a(i.firstChild).css(g.suggestion).data("suggestion",d),k.children().each(function(){a(this).css(g.suggestionChild)}),j.appendChild(k[0])}),n.show().find(".tt-suggestions").html(j)):this.clearSuggestions(b.name),this.trigger("suggestionsRendered")},clearSuggestions:function(a){var b=a?this.$menu.find(".tt-dataset-"+a):this.$menu.find('[class^="tt-dataset-"]'),c=b.find(".tt-suggestions");b.hide(),c.empty(),0===this._getSuggestions().length&&(this.isEmpty=!0,this._hide())}}),b}(),l=function(){function b(a){var b,d,f;c.bindAll(this),this.$node=e(a.input),this.datasets=a.datasets,this.dir=null,this.eventBus=a.eventBus,b=this.$node.find(".tt-dropdown-menu"),d=this.$node.find(".tt-query"),f=this.$node.find(".tt-hint"),this.dropdownView=new k({menu:b}).on("suggestionSelected",this._handleSelection).on("cursorMoved",this._clearHint).on("cursorMoved",this._setInputValueToSuggestionUnderCursor).on("cursorRemoved",this._setInputValueToQuery).on("cursorRemoved",this._updateHint).on("suggestionsRendered",this._updateHint).on("opened",this._updateHint).on("closed",this._clearHint).on("opened closed",this._propagateEvent),this.inputView=new j({input:d,hint:f}).on("focused",this._openDropdown).on("blured",this._closeDropdown).on("blured",this._setInputValueToQuery).on("enterKeyed tabKeyed",this._handleSelection).on("queryChanged",this._clearHint).on("queryChanged",this._clearSuggestions).on("queryChanged",this._getSuggestions).on("whitespaceChanged",this._updateHint).on("queryChanged whitespaceChanged",this._openDropdown).on("queryChanged whitespaceChanged",this._setLanguageDirection).on("escKeyed",this._closeDropdown).on("escKeyed",this._setInputValueToQuery).on("tabKeyed upKeyed downKeyed",this._managePreventDefault).on("upKeyed downKeyed",this._moveDropdownCursor).on("upKeyed downKeyed",this._openDropdown).on("tabKeyed leftKeyed rightKeyed",this._autocomplete)}function e(b){var c=a(g.wrapper),d=a(g.dropdown),e=a(b),f=a(g.hint);c=c.css(h.wrapper),d=d.css(h.dropdown),f.css(h.hint).css({backgroundAttachment:e.css("background-attachment"),backgroundClip:e.css("background-clip"),backgroundColor:e.css("background-color"),backgroundImage:e.css("background-image"),backgroundOrigin:e.css("background-origin"),backgroundPosition:e.css("background-position"),backgroundRepeat:e.css("background-repeat"),backgroundSize:e.css("background-size")}),e.data("ttAttrs",{dir:e.attr("dir"),autocomplete:e.attr("autocomplete"),spellcheck:e.attr("spellcheck"),style:e.attr("style")}),e.addClass("tt-query").attr({autocomplete:"off",spellcheck:!1}).css(h.query);try{!e.attr("dir")&&e.attr("dir","auto")}catch(i){}return e.wrap(c).parent().prepend(f).append(d)}function f(a){var b=a.find(".tt-query");c.each(b.data("ttAttrs"),function(a,d){c.isUndefined(d)?b.removeAttr(a):b.attr(a,d)}),b.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter(a),a.remove()}var g={wrapper:'<span class="twitter-typeahead"></span>',hint:'<input class="tt-hint" type="text" autocomplete="off" spellcheck="off" disabled>',dropdown:'<span class="tt-dropdown-menu"></span>'},h={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},query:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"}};return c.isMsie()&&c.mixin(h.query,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),c.isMsie()&&c.isMsie()<=7&&(c.mixin(h.wrapper,{display:"inline",zoom:"1"}),c.mixin(h.query,{marginTop:"-1px"})),c.mixin(b.prototype,d,{_managePreventDefault:function(a){var b,c,d=a.data,e=!1;switch(a.type){case"tabKeyed":b=this.inputView.getHintValue(),c=this.inputView.getInputValue(),e=b&&b!==c;break;case"upKeyed":case"downKeyed":e=!d.shiftKey&&!d.ctrlKey&&!d.metaKey}e&&d.preventDefault()},_setLanguageDirection:function(){var a=this.inputView.getLanguageDirection();a!==this.dir&&(this.dir=a,this.$node.css("direction",a),this.dropdownView.setLanguageDirection(a))},_updateHint:function(){var a,b,d,e,f,g=this.dropdownView.getFirstSuggestion(),h=g?g.value:null,i=this.dropdownView.isVisible(),j=this.inputView.isOverflow();h&&i&&!j&&(a=this.inputView.getInputValue(),b=a.replace(/\s{2,}/g," ").replace(/^\s+/g,""),d=c.escapeRegExChars(b),e=new RegExp("^(?:"+d+")(.*$)","i"),f=e.exec(h),this.inputView.setHintValue(a+(f?f[1]:"")))},_clearHint:function(){this.inputView.setHintValue("")},_clearSuggestions:function(){this.dropdownView.clearSuggestions()},_setInputValueToQuery:function(){this.inputView.setInputValue(this.inputView.getQuery())},_setInputValueToSuggestionUnderCursor:function(a){var b=a.data;this.inputView.setInputValue(b.value,!0)},_openDropdown:function(){this.dropdownView.open()},_closeDropdown:function(a){this.dropdownView["blured"===a.type?"closeUnlessMouseIsOverDropdown":"close"]()},_moveDropdownCursor:function(a){var b=a.data;b.shiftKey||b.ctrlKey||b.metaKey||this.dropdownView["upKeyed"===a.type?"moveCursorUp":"moveCursorDown"]()},_handleSelection:function(a){var b="suggestionSelected"===a.type,d=b?a.data:this.dropdownView.getSuggestionUnderCursor();d&&(this.inputView.setInputValue(d.value),b?this.inputView.focus():a.data.preventDefault(),b&&c.isMsie()?c.defer(this.dropdownView.close):this.dropdownView.close(),this.eventBus.trigger("selected",d.datum,d.dataset))},_getSuggestions:function(){var a=this,b=this.inputView.getQuery();c.isBlankString(b)||c.each(this.datasets,function(c,d){d.getSuggestions(b,function(c){b===a.inputView.getQuery()&&a.dropdownView.renderSuggestions(d,c)})})},_autocomplete:function(a){var b,c,d,e,f;("rightKeyed"!==a.type&&"leftKeyed"!==a.type||(b=this.inputView.isCursorAtEnd(),c="ltr"===this.inputView.getLanguageDirection()?"leftKeyed"===a.type:"rightKeyed"===a.type,b&&!c))&&(d=this.inputView.getQuery(),e=this.inputView.getHintValue(),""!==e&&d!==e&&(f=this.dropdownView.getFirstSuggestion(),this.inputView.setInputValue(f.value),this.eventBus.trigger("autocompleted",f.datum,f.dataset)))},_propagateEvent:function(a){this.eventBus.trigger(a.type)},destroy:function(){this.inputView.destroy(),this.dropdownView.destroy(),f(this.$node),this.$node=null},setQuery:function(a){this.inputView.setQuery(a),this.inputView.setInputValue(a),this._clearHint(),this._clearSuggestions(),this._getSuggestions()}}),b}();!function(){var b,d={},f="ttView";b={initialize:function(b){function g(){var b,d=a(this),g=new e({el:d});b=c.map(h,function(a){return a.initialize()}),d.data(f,new l({input:d,eventBus:g=new e({el:d}),datasets:h})),a.when.apply(a,b).always(function(){c.defer(function(){g.trigger("initialized")})})}var h;return b=c.isArray(b)?b:[b],0===b.length&&a.error("no datasets provided"),h=c.map(b,function(a){var b=d[a.name]?d[a.name]:new i(a);return a.name&&(d[a.name]=b),b}),this.each(g)},destroy:function(){function b(){var b=a(this),c=b.data(f);c&&(c.destroy(),b.removeData(f))}return this.each(b)},setQuery:function(b){function c(){var c=a(this).data(f);c&&c.setQuery(b)}return this.each(c)}},jQuery.fn.typeahead=function(a){return b[a]?b[a].apply(this,[].slice.call(arguments,1)):b.initialize.apply(this,arguments)}}()}(window.jQuery);
|
||
/*!
|
||
* accounting.js v0.3.2, copyright 2011 Joss Crowcroft, MIT license, http://josscrowcroft.github.com/accounting.js
|
||
*/
|
||
(function(p,z){function q(a){return!!(""===a||a&&a.charCodeAt&&a.substr)}function m(a){return u?u(a):"[object Array]"===v.call(a)}function r(a){return"[object Object]"===v.call(a)}function s(a,b){var d,a=a||{},b=b||{};for(d in b)b.hasOwnProperty(d)&&null==a[d]&&(a[d]=b[d]);return a}function j(a,b,d){var c=[],e,h;if(!a)return c;if(w&&a.map===w)return a.map(b,d);for(e=0,h=a.length;e<h;e++)c[e]=b.call(d,a[e],e,a);return c}function n(a,b){a=Math.round(Math.abs(a));return isNaN(a)?b:a}function x(a){var b=c.settings.currency.format;"function"===typeof a&&(a=a());return q(a)&&a.match("%v")?{pos:a,neg:a.replace("-","").replace("%v","-%v"),zero:a}:!a||!a.pos||!a.pos.match("%v")?!q(b)?b:c.settings.currency.format={pos:b,neg:b.replace("%v","-%v"),zero:b}:a}var c={version:"0.3.2",settings:{currency:{symbol:"$",format:"%s%v",decimal:".",thousand:",",precision:2,grouping:3},number:{precision:0,grouping:3,thousand:",",decimal:"."}}},w=Array.prototype.map,u=Array.isArray,v=Object.prototype.toString,o=c.unformat=c.parse=function(a,b){if(m(a))return j(a,function(a){return o(a,b)});a=a||0;if("number"===typeof a)return a;var b=b||".",c=RegExp("[^0-9-"+b+"]",["g"]),c=parseFloat((""+a).replace(/\((.*)\)/,"-$1").replace(c,"").replace(b,"."));return!isNaN(c)?c:0},y=c.toFixed=function(a,b){var b=n(b,c.settings.number.precision),d=Math.pow(10,b);return(Math.round(c.unformat(a)*d)/d).toFixed(b)},t=c.formatNumber=function(a,b,d,i){if(m(a))return j(a,function(a){return t(a,b,d,i)});var a=o(a),e=s(r(b)?b:{precision:b,thousand:d,decimal:i},c.settings.number),h=n(e.precision),f=0>a?"-":"",g=parseInt(y(Math.abs(a||0),h),10)+"",l=3<g.length?g.length%3:0;return f+(l?g.substr(0,l)+e.thousand:"")+g.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+e.thousand)+(h?e.decimal+y(Math.abs(a),h).split(".")[1]:"")},A=c.formatMoney=function(a,b,d,i,e,h){if(m(a))return j(a,function(a){return A(a,b,d,i,e,h)});var a=o(a),f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format);return(0<a?g.pos:0>a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal))};c.formatColumn=function(a,b,d,i,e,h){if(!a)return[];var f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format),l=g.pos.indexOf("%s")<g.pos.indexOf("%v")?!0:!1,k=0,a=j(a,function(a){if(m(a))return c.formatColumn(a,f);a=o(a);a=(0<a?g.pos:0>a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal));if(a.length>k)k=a.length;return a});return j(a,function(a){return q(a)&&a.length<k?l?a.replace(f.symbol,f.symbol+Array(k-a.length+1).join(" ")):Array(k-a.length+1).join(" ")+a:a})};if("undefined"!==typeof exports){if("undefined"!==typeof module&&module.exports)exports=module.exports=c;exports.accounting=c}else"function"===typeof define&&define.amd?define([],function(){return c}):(c.noConflict=function(a){return function(){p.accounting=a;c.noConflict=z;return c}}(p.accounting),p.accounting=c)})(this);
|
||
// Spectrum Colorpicker v1.3.4
|
||
// https://github.com/bgrins/spectrum
|
||
// Author: Brian Grinstead
|
||
// License: MIT
|
||
|
||
(function (window, $, undefined) {
|
||
var defaultOpts = {
|
||
|
||
// Callbacks
|
||
beforeShow: noop,
|
||
move: noop,
|
||
change: noop,
|
||
show: noop,
|
||
hide: noop,
|
||
|
||
// Options
|
||
color: false,
|
||
flat: false,
|
||
showInput: false,
|
||
allowEmpty: false,
|
||
showButtons: true,
|
||
clickoutFiresChange: false,
|
||
showInitial: false,
|
||
showPalette: false,
|
||
showPaletteOnly: false,
|
||
showSelectionPalette: true,
|
||
localStorageKey: false,
|
||
appendTo: "body",
|
||
maxSelectionSize: 7,
|
||
cancelText: "cancel",
|
||
chooseText: "choose",
|
||
clearText: "Clear Color Selection",
|
||
preferredFormat: false,
|
||
className: "", // Deprecated - use containerClassName and replacerClassName instead.
|
||
containerClassName: "",
|
||
replacerClassName: "",
|
||
showAlpha: false,
|
||
theme: "sp-light",
|
||
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
|
||
selectionPalette: [],
|
||
disabled: false
|
||
},
|
||
spectrums = [],
|
||
IE = !!/msie/i.exec( window.navigator.userAgent ),
|
||
rgbaSupport = (function() {
|
||
function contains( str, substr ) {
|
||
return !!~('' + str).indexOf(substr);
|
||
}
|
||
|
||
var elem = document.createElement('div');
|
||
var style = elem.style;
|
||
style.cssText = 'background-color:rgba(0,0,0,.5)';
|
||
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
|
||
})(),
|
||
inputTypeColorSupport = (function() {
|
||
var colorInput = $("<input type='color' value='!' />")[0];
|
||
return colorInput.type === "color" && colorInput.value !== "!";
|
||
})(),
|
||
replaceInput = [
|
||
"<div class='sp-replacer'>",
|
||
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
|
||
"<div class='sp-dd'>▼</div>",
|
||
"</div>"
|
||
].join(''),
|
||
markup = (function () {
|
||
|
||
// IE does not support gradients with multiple stops, so we need to simulate
|
||
// that for the rainbow slider with 8 divs that each have a single gradient
|
||
var gradientFix = "";
|
||
if (IE) {
|
||
for (var i = 1; i <= 6; i++) {
|
||
gradientFix += "<div class='sp-" + i + "'></div>";
|
||
}
|
||
}
|
||
|
||
return [
|
||
"<div class='sp-container sp-hidden'>",
|
||
"<div class='sp-palette-container'>",
|
||
"<div class='sp-palette sp-thumb sp-cf'></div>",
|
||
"</div>",
|
||
"<div class='sp-picker-container'>",
|
||
"<div class='sp-top sp-cf'>",
|
||
"<div class='sp-fill'></div>",
|
||
"<div class='sp-top-inner'>",
|
||
"<div class='sp-color'>",
|
||
"<div class='sp-sat'>",
|
||
"<div class='sp-val'>",
|
||
"<div class='sp-dragger'></div>",
|
||
"</div>",
|
||
"</div>",
|
||
"</div>",
|
||
"<div class='sp-clear sp-clear-display'>",
|
||
"</div>",
|
||
"<div class='sp-hue'>",
|
||
"<div class='sp-slider'></div>",
|
||
gradientFix,
|
||
"</div>",
|
||
"</div>",
|
||
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
||
"</div>",
|
||
"<div class='sp-input-container sp-cf'>",
|
||
"<input class='sp-input' type='text' spellcheck='false' />",
|
||
"</div>",
|
||
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
||
"<div class='sp-button-container sp-cf'>",
|
||
"<a class='sp-cancel' href='#'></a>",
|
||
"<button type='button' class='sp-choose'></button>",
|
||
"</div>",
|
||
"</div>",
|
||
"</div>"
|
||
].join("");
|
||
})();
|
||
|
||
function paletteTemplate (p, color, className, tooltipFormat) {
|
||
var html = [];
|
||
for (var i = 0; i < p.length; i++) {
|
||
var current = p[i];
|
||
if(current) {
|
||
var tiny = tinycolor(current);
|
||
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
|
||
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
|
||
|
||
var formattedString = tiny.toString(tooltipFormat || "rgb");
|
||
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
|
||
html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
|
||
} else {
|
||
var cls = 'sp-clear-display';
|
||
html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>');
|
||
}
|
||
}
|
||
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
|
||
}
|
||
|
||
function hideAll() {
|
||
for (var i = 0; i < spectrums.length; i++) {
|
||
if (spectrums[i]) {
|
||
spectrums[i].hide();
|
||
}
|
||
}
|
||
}
|
||
|
||
function instanceOptions(o, callbackContext) {
|
||
var opts = $.extend({}, defaultOpts, o);
|
||
opts.callbacks = {
|
||
'move': bind(opts.move, callbackContext),
|
||
'change': bind(opts.change, callbackContext),
|
||
'show': bind(opts.show, callbackContext),
|
||
'hide': bind(opts.hide, callbackContext),
|
||
'beforeShow': bind(opts.beforeShow, callbackContext)
|
||
};
|
||
|
||
return opts;
|
||
}
|
||
|
||
function spectrum(element, o) {
|
||
|
||
var opts = instanceOptions(o, element),
|
||
flat = opts.flat,
|
||
showSelectionPalette = opts.showSelectionPalette,
|
||
localStorageKey = opts.localStorageKey,
|
||
theme = opts.theme,
|
||
callbacks = opts.callbacks,
|
||
resize = throttle(reflow, 10),
|
||
visible = false,
|
||
dragWidth = 0,
|
||
dragHeight = 0,
|
||
dragHelperHeight = 0,
|
||
slideHeight = 0,
|
||
slideWidth = 0,
|
||
alphaWidth = 0,
|
||
alphaSlideHelperWidth = 0,
|
||
slideHelperHeight = 0,
|
||
currentHue = 0,
|
||
currentSaturation = 0,
|
||
currentValue = 0,
|
||
currentAlpha = 1,
|
||
palette = [],
|
||
paletteArray = [],
|
||
paletteLookup = {},
|
||
selectionPalette = opts.selectionPalette.slice(0),
|
||
maxSelectionSize = opts.maxSelectionSize,
|
||
draggingClass = "sp-dragging",
|
||
shiftMovementDirection = null;
|
||
|
||
var doc = element.ownerDocument,
|
||
body = doc.body,
|
||
boundElement = $(element),
|
||
disabled = false,
|
||
container = $(markup, doc).addClass(theme),
|
||
dragger = container.find(".sp-color"),
|
||
dragHelper = container.find(".sp-dragger"),
|
||
slider = container.find(".sp-hue"),
|
||
slideHelper = container.find(".sp-slider"),
|
||
alphaSliderInner = container.find(".sp-alpha-inner"),
|
||
alphaSlider = container.find(".sp-alpha"),
|
||
alphaSlideHelper = container.find(".sp-alpha-handle"),
|
||
textInput = container.find(".sp-input"),
|
||
paletteContainer = container.find(".sp-palette"),
|
||
initialColorContainer = container.find(".sp-initial"),
|
||
cancelButton = container.find(".sp-cancel"),
|
||
clearButton = container.find(".sp-clear"),
|
||
chooseButton = container.find(".sp-choose"),
|
||
isInput = boundElement.is("input"),
|
||
isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
|
||
shouldReplace = isInput && !flat,
|
||
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
|
||
offsetElement = (shouldReplace) ? replacer : boundElement,
|
||
previewElement = replacer.find(".sp-preview-inner"),
|
||
initialColor = opts.color || (isInput && boundElement.val()),
|
||
colorOnShow = false,
|
||
preferredFormat = opts.preferredFormat,
|
||
currentPreferredFormat = preferredFormat,
|
||
clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
|
||
isEmpty = !initialColor,
|
||
allowEmpty = opts.allowEmpty && !isInputTypeColor;
|
||
|
||
function applyOptions() {
|
||
|
||
if (opts.showPaletteOnly) {
|
||
opts.showPalette = true;
|
||
}
|
||
|
||
if (opts.palette) {
|
||
palette = opts.palette.slice(0);
|
||
paletteArray = $.isArray(palette[0]) ? palette : [palette];
|
||
paletteLookup = {};
|
||
for (var i = 0; i < paletteArray.length; i++) {
|
||
for (var j = 0; j < paletteArray[i].length; j++) {
|
||
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
||
paletteLookup[rgb] = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
container.toggleClass("sp-flat", flat);
|
||
container.toggleClass("sp-input-disabled", !opts.showInput);
|
||
container.toggleClass("sp-alpha-enabled", opts.showAlpha);
|
||
container.toggleClass("sp-clear-enabled", allowEmpty);
|
||
container.toggleClass("sp-buttons-disabled", !opts.showButtons);
|
||
container.toggleClass("sp-palette-disabled", !opts.showPalette);
|
||
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
|
||
container.toggleClass("sp-initial-disabled", !opts.showInitial);
|
||
container.addClass(opts.className).addClass(opts.containerClassName);
|
||
|
||
reflow();
|
||
}
|
||
|
||
function initialize() {
|
||
|
||
if (IE) {
|
||
container.find("*:not(input)").attr("unselectable", "on");
|
||
}
|
||
|
||
applyOptions();
|
||
|
||
if (shouldReplace) {
|
||
boundElement.after(replacer).hide();
|
||
}
|
||
|
||
if (!allowEmpty) {
|
||
clearButton.hide();
|
||
}
|
||
|
||
if (flat) {
|
||
boundElement.after(container).hide();
|
||
}
|
||
else {
|
||
|
||
var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
|
||
if (appendTo.length !== 1) {
|
||
appendTo = $("body");
|
||
}
|
||
|
||
appendTo.append(container);
|
||
}
|
||
|
||
updateSelectionPaletteFromStorage();
|
||
|
||
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
|
||
if (!disabled) {
|
||
toggle();
|
||
}
|
||
|
||
e.stopPropagation();
|
||
|
||
if (!$(e.target).is("input")) {
|
||
e.preventDefault();
|
||
}
|
||
});
|
||
|
||
if(boundElement.is(":disabled") || (opts.disabled === true)) {
|
||
disable();
|
||
}
|
||
|
||
// Prevent clicks from bubbling up to document. This would cause it to be hidden.
|
||
container.click(stopPropagation);
|
||
|
||
// Handle user typed input
|
||
textInput.change(setFromTextInput);
|
||
textInput.bind("paste", function () {
|
||
setTimeout(setFromTextInput, 1);
|
||
});
|
||
textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
|
||
|
||
cancelButton.text(opts.cancelText);
|
||
cancelButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
hide("cancel");
|
||
});
|
||
|
||
clearButton.attr("title", opts.clearText);
|
||
clearButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
isEmpty = true;
|
||
move();
|
||
|
||
if(flat) {
|
||
//for the flat style, this is a change event
|
||
updateOriginalInput(true);
|
||
}
|
||
});
|
||
|
||
chooseButton.text(opts.chooseText);
|
||
chooseButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
|
||
if (isValid()) {
|
||
updateOriginalInput(true);
|
||
hide();
|
||
}
|
||
});
|
||
|
||
draggable(alphaSlider, function (dragX, dragY, e) {
|
||
currentAlpha = (dragX / alphaWidth);
|
||
isEmpty = false;
|
||
if (e.shiftKey) {
|
||
currentAlpha = Math.round(currentAlpha * 10) / 10;
|
||
}
|
||
|
||
move();
|
||
}, dragStart, dragStop);
|
||
|
||
draggable(slider, function (dragX, dragY) {
|
||
currentHue = parseFloat(dragY / slideHeight);
|
||
isEmpty = false;
|
||
if (!opts.showAlpha) {
|
||
currentAlpha = 1;
|
||
}
|
||
move();
|
||
}, dragStart, dragStop);
|
||
|
||
draggable(dragger, function (dragX, dragY, e) {
|
||
|
||
// shift+drag should snap the movement to either the x or y axis.
|
||
if (!e.shiftKey) {
|
||
shiftMovementDirection = null;
|
||
}
|
||
else if (!shiftMovementDirection) {
|
||
var oldDragX = currentSaturation * dragWidth;
|
||
var oldDragY = dragHeight - (currentValue * dragHeight);
|
||
var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
|
||
|
||
shiftMovementDirection = furtherFromX ? "x" : "y";
|
||
}
|
||
|
||
var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
|
||
var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
|
||
|
||
if (setSaturation) {
|
||
currentSaturation = parseFloat(dragX / dragWidth);
|
||
}
|
||
if (setValue) {
|
||
currentValue = parseFloat((dragHeight - dragY) / dragHeight);
|
||
}
|
||
|
||
isEmpty = false;
|
||
if (!opts.showAlpha) {
|
||
currentAlpha = 1;
|
||
}
|
||
|
||
move();
|
||
|
||
}, dragStart, dragStop);
|
||
|
||
if (!!initialColor) {
|
||
set(initialColor);
|
||
|
||
// In case color was black - update the preview UI and set the format
|
||
// since the set function will not run (default color is black).
|
||
updateUI();
|
||
currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
|
||
|
||
addColorToSelectionPalette(initialColor);
|
||
}
|
||
else {
|
||
updateUI();
|
||
}
|
||
|
||
if (flat) {
|
||
show();
|
||
}
|
||
|
||
function palletElementClick(e) {
|
||
if (e.data && e.data.ignore) {
|
||
set($(this).data("color"));
|
||
move();
|
||
}
|
||
else {
|
||
set($(this).data("color"));
|
||
move();
|
||
updateOriginalInput(true);
|
||
hide();
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
|
||
paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick);
|
||
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
|
||
}
|
||
|
||
function updateSelectionPaletteFromStorage() {
|
||
|
||
if (localStorageKey && window.localStorage) {
|
||
|
||
// Migrate old palettes over to new format. May want to remove this eventually.
|
||
try {
|
||
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
||
if (oldPalette.length > 1) {
|
||
delete window.localStorage[localStorageKey];
|
||
$.each(oldPalette, function(i, c) {
|
||
addColorToSelectionPalette(c);
|
||
});
|
||
}
|
||
}
|
||
catch(e) { }
|
||
|
||
try {
|
||
selectionPalette = window.localStorage[localStorageKey].split(";");
|
||
}
|
||
catch (e) { }
|
||
}
|
||
}
|
||
|
||
function addColorToSelectionPalette(color) {
|
||
if (showSelectionPalette) {
|
||
var rgb = tinycolor(color).toRgbString();
|
||
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
|
||
selectionPalette.push(rgb);
|
||
while(selectionPalette.length > maxSelectionSize) {
|
||
selectionPalette.shift();
|
||
}
|
||
}
|
||
|
||
if (localStorageKey && window.localStorage) {
|
||
try {
|
||
window.localStorage[localStorageKey] = selectionPalette.join(";");
|
||
}
|
||
catch(e) { }
|
||
}
|
||
}
|
||
}
|
||
|
||
function getUniqueSelectionPalette() {
|
||
var unique = [];
|
||
if (opts.showPalette) {
|
||
for (i = 0; i < selectionPalette.length; i++) {
|
||
var rgb = tinycolor(selectionPalette[i]).toRgbString();
|
||
|
||
if (!paletteLookup[rgb]) {
|
||
unique.push(selectionPalette[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
return unique.reverse().slice(0, opts.maxSelectionSize);
|
||
}
|
||
|
||
function drawPalette() {
|
||
|
||
var currentColor = get();
|
||
|
||
var html = $.map(paletteArray, function (palette, i) {
|
||
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts.preferredFormat);
|
||
});
|
||
|
||
updateSelectionPaletteFromStorage();
|
||
|
||
if (selectionPalette) {
|
||
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts.preferredFormat));
|
||
}
|
||
|
||
paletteContainer.html(html.join(""));
|
||
}
|
||
|
||
function drawInitial() {
|
||
if (opts.showInitial) {
|
||
var initial = colorOnShow;
|
||
var current = get();
|
||
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts.preferredFormat));
|
||
}
|
||
}
|
||
|
||
function dragStart() {
|
||
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
|
||
reflow();
|
||
}
|
||
container.addClass(draggingClass);
|
||
shiftMovementDirection = null;
|
||
boundElement.trigger('dragstart.spectrum', [ get() ]);
|
||
}
|
||
|
||
function dragStop() {
|
||
container.removeClass(draggingClass);
|
||
boundElement.trigger('dragstop.spectrum', [ get() ]);
|
||
}
|
||
|
||
function setFromTextInput() {
|
||
|
||
var value = textInput.val();
|
||
|
||
if ((value === null || value === "") && allowEmpty) {
|
||
set(null);
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
var tiny = tinycolor(value);
|
||
if (tiny.ok) {
|
||
set(tiny);
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
textInput.addClass("sp-validation-error");
|
||
}
|
||
}
|
||
}
|
||
|
||
function toggle() {
|
||
if (visible) {
|
||
hide();
|
||
}
|
||
else {
|
||
show();
|
||
}
|
||
}
|
||
|
||
function show() {
|
||
var event = $.Event('beforeShow.spectrum');
|
||
|
||
if (visible) {
|
||
reflow();
|
||
return;
|
||
}
|
||
|
||
boundElement.trigger(event, [ get() ]);
|
||
|
||
if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
|
||
return;
|
||
}
|
||
|
||
hideAll();
|
||
visible = true;
|
||
|
||
$(doc).bind("click.spectrum", hide);
|
||
$(window).bind("resize.spectrum", resize);
|
||
replacer.addClass("sp-active");
|
||
container.removeClass("sp-hidden");
|
||
|
||
reflow();
|
||
updateUI();
|
||
|
||
colorOnShow = get();
|
||
|
||
drawInitial();
|
||
callbacks.show(colorOnShow);
|
||
boundElement.trigger('show.spectrum', [ colorOnShow ]);
|
||
}
|
||
|
||
function hide(e) {
|
||
|
||
// Return on right click
|
||
if (e && e.type == "click" && e.button == 2) { return; }
|
||
|
||
// Return if hiding is unnecessary
|
||
if (!visible || flat) { return; }
|
||
visible = false;
|
||
|
||
$(doc).unbind("click.spectrum", hide);
|
||
$(window).unbind("resize.spectrum", resize);
|
||
|
||
replacer.removeClass("sp-active");
|
||
container.addClass("sp-hidden");
|
||
|
||
var colorHasChanged = !tinycolor.equals(get(), colorOnShow);
|
||
|
||
if (colorHasChanged) {
|
||
if (clickoutFiresChange && e !== "cancel") {
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
revert();
|
||
}
|
||
}
|
||
|
||
callbacks.hide(get());
|
||
boundElement.trigger('hide.spectrum', [ get() ]);
|
||
}
|
||
|
||
function revert() {
|
||
set(colorOnShow, true);
|
||
}
|
||
|
||
function set(color, ignoreFormatChange) {
|
||
if (tinycolor.equals(color, get())) {
|
||
// Update UI just in case a validation error needs
|
||
// to be cleared.
|
||
updateUI();
|
||
return;
|
||
}
|
||
|
||
var newColor, newHsv;
|
||
if (!color && allowEmpty) {
|
||
isEmpty = true;
|
||
} else {
|
||
isEmpty = false;
|
||
newColor = tinycolor(color);
|
||
newHsv = newColor.toHsv();
|
||
|
||
currentHue = (newHsv.h % 360) / 360;
|
||
currentSaturation = newHsv.s;
|
||
currentValue = newHsv.v;
|
||
currentAlpha = newHsv.a;
|
||
}
|
||
updateUI();
|
||
|
||
if (newColor && newColor.ok && !ignoreFormatChange) {
|
||
currentPreferredFormat = preferredFormat || newColor.format;
|
||
}
|
||
}
|
||
|
||
function get(opts) {
|
||
opts = opts || { };
|
||
|
||
if (allowEmpty && isEmpty) {
|
||
return null;
|
||
}
|
||
|
||
return tinycolor.fromRatio({
|
||
h: currentHue,
|
||
s: currentSaturation,
|
||
v: currentValue,
|
||
a: Math.round(currentAlpha * 100) / 100
|
||
}, { format: opts.format || currentPreferredFormat });
|
||
}
|
||
|
||
function isValid() {
|
||
return !textInput.hasClass("sp-validation-error");
|
||
}
|
||
|
||
function move() {
|
||
updateUI();
|
||
|
||
callbacks.move(get());
|
||
boundElement.trigger('move.spectrum', [ get() ]);
|
||
}
|
||
|
||
function updateUI() {
|
||
|
||
textInput.removeClass("sp-validation-error");
|
||
|
||
updateHelperLocations();
|
||
|
||
// Update dragger background color (gradients take care of saturation and value).
|
||
var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
|
||
dragger.css("background-color", flatColor.toHexString());
|
||
|
||
// Get a format that alpha will be included in (hex and names ignore alpha)
|
||
var format = currentPreferredFormat;
|
||
if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
|
||
if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
|
||
format = "rgb";
|
||
}
|
||
}
|
||
|
||
var realColor = get({ format: format }),
|
||
displayColor = '';
|
||
|
||
//reset background info for preview element
|
||
previewElement.removeClass("sp-clear-display");
|
||
previewElement.css('background-color', 'transparent');
|
||
|
||
if (!realColor && allowEmpty) {
|
||
// Update the replaced elements background with icon indicating no color selection
|
||
previewElement.addClass("sp-clear-display");
|
||
}
|
||
else {
|
||
var realHex = realColor.toHexString(),
|
||
realRgb = realColor.toRgbString();
|
||
|
||
// Update the replaced elements background color (with actual selected color)
|
||
if (rgbaSupport || realColor.alpha === 1) {
|
||
previewElement.css("background-color", realRgb);
|
||
}
|
||
else {
|
||
previewElement.css("background-color", "transparent");
|
||
previewElement.css("filter", realColor.toFilter());
|
||
}
|
||
|
||
if (opts.showAlpha) {
|
||
var rgb = realColor.toRgb();
|
||
rgb.a = 0;
|
||
var realAlpha = tinycolor(rgb).toRgbString();
|
||
var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
|
||
|
||
if (IE) {
|
||
alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
|
||
}
|
||
else {
|
||
alphaSliderInner.css("background", "-webkit-" + gradient);
|
||
alphaSliderInner.css("background", "-moz-" + gradient);
|
||
alphaSliderInner.css("background", "-ms-" + gradient);
|
||
// Use current syntax gradient on unprefixed property.
|
||
alphaSliderInner.css("background",
|
||
"linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
|
||
}
|
||
}
|
||
|
||
displayColor = realColor.toString(format);
|
||
}
|
||
|
||
// Update the text entry input as it changes happen
|
||
if (opts.showInput) {
|
||
textInput.val(displayColor);
|
||
}
|
||
|
||
if (opts.showPalette) {
|
||
drawPalette();
|
||
}
|
||
|
||
drawInitial();
|
||
}
|
||
|
||
function updateHelperLocations() {
|
||
var s = currentSaturation;
|
||
var v = currentValue;
|
||
|
||
if(allowEmpty && isEmpty) {
|
||
//if selected color is empty, hide the helpers
|
||
alphaSlideHelper.hide();
|
||
slideHelper.hide();
|
||
dragHelper.hide();
|
||
}
|
||
else {
|
||
//make sure helpers are visible
|
||
alphaSlideHelper.show();
|
||
slideHelper.show();
|
||
dragHelper.show();
|
||
|
||
// Where to show the little circle in that displays your current selected color
|
||
var dragX = s * dragWidth;
|
||
var dragY = dragHeight - (v * dragHeight);
|
||
dragX = Math.max(
|
||
-dragHelperHeight,
|
||
Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
|
||
);
|
||
dragY = Math.max(
|
||
-dragHelperHeight,
|
||
Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
|
||
);
|
||
dragHelper.css({
|
||
"top": dragY + "px",
|
||
"left": dragX + "px"
|
||
});
|
||
|
||
var alphaX = currentAlpha * alphaWidth;
|
||
alphaSlideHelper.css({
|
||
"left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
|
||
});
|
||
|
||
// Where to show the bar that displays your current selected hue
|
||
var slideY = (currentHue) * slideHeight;
|
||
slideHelper.css({
|
||
"top": (slideY - slideHelperHeight) + "px"
|
||
});
|
||
}
|
||
}
|
||
|
||
function updateOriginalInput(fireCallback) {
|
||
var color = get(),
|
||
displayColor = '',
|
||
hasChanged = !tinycolor.equals(color, colorOnShow);
|
||
|
||
if (color) {
|
||
displayColor = color.toString(currentPreferredFormat);
|
||
// Update the selection palette with the current color
|
||
addColorToSelectionPalette(color);
|
||
}
|
||
|
||
if (isInput) {
|
||
boundElement.val(displayColor);
|
||
}
|
||
|
||
colorOnShow = color;
|
||
|
||
if (fireCallback && hasChanged) {
|
||
callbacks.change(color);
|
||
boundElement.trigger('change', [ color ]);
|
||
}
|
||
}
|
||
|
||
function reflow() {
|
||
dragWidth = dragger.width();
|
||
dragHeight = dragger.height();
|
||
dragHelperHeight = dragHelper.height();
|
||
slideWidth = slider.width();
|
||
slideHeight = slider.height();
|
||
slideHelperHeight = slideHelper.height();
|
||
alphaWidth = alphaSlider.width();
|
||
alphaSlideHelperWidth = alphaSlideHelper.width();
|
||
|
||
if (!flat) {
|
||
container.css("position", "absolute");
|
||
container.offset(getOffset(container, offsetElement));
|
||
}
|
||
|
||
updateHelperLocations();
|
||
|
||
if (opts.showPalette) {
|
||
drawPalette();
|
||
}
|
||
|
||
boundElement.trigger('reflow.spectrum');
|
||
}
|
||
|
||
function destroy() {
|
||
boundElement.show();
|
||
offsetElement.unbind("click.spectrum touchstart.spectrum");
|
||
container.remove();
|
||
replacer.remove();
|
||
spectrums[spect.id] = null;
|
||
}
|
||
|
||
function option(optionName, optionValue) {
|
||
if (optionName === undefined) {
|
||
return $.extend({}, opts);
|
||
}
|
||
if (optionValue === undefined) {
|
||
return opts[optionName];
|
||
}
|
||
|
||
opts[optionName] = optionValue;
|
||
applyOptions();
|
||
}
|
||
|
||
function enable() {
|
||
disabled = false;
|
||
boundElement.attr("disabled", false);
|
||
offsetElement.removeClass("sp-disabled");
|
||
}
|
||
|
||
function disable() {
|
||
hide();
|
||
disabled = true;
|
||
boundElement.attr("disabled", true);
|
||
offsetElement.addClass("sp-disabled");
|
||
}
|
||
|
||
initialize();
|
||
|
||
var spect = {
|
||
show: show,
|
||
hide: hide,
|
||
toggle: toggle,
|
||
reflow: reflow,
|
||
option: option,
|
||
enable: enable,
|
||
disable: disable,
|
||
set: function (c) {
|
||
set(c);
|
||
updateOriginalInput();
|
||
},
|
||
get: get,
|
||
destroy: destroy,
|
||
container: container
|
||
};
|
||
|
||
spect.id = spectrums.push(spect) - 1;
|
||
|
||
return spect;
|
||
}
|
||
|
||
/**
|
||
* checkOffset - get the offset below/above and left/right element depending on screen position
|
||
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
|
||
*/
|
||
function getOffset(picker, input) {
|
||
var extraY = 0;
|
||
var dpWidth = picker.outerWidth();
|
||
var dpHeight = picker.outerHeight();
|
||
var inputHeight = input.outerHeight();
|
||
var doc = picker[0].ownerDocument;
|
||
var docElem = doc.documentElement;
|
||
var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
|
||
var viewHeight = docElem.clientHeight + $(doc).scrollTop();
|
||
var offset = input.offset();
|
||
offset.top += inputHeight;
|
||
|
||
offset.left -=
|
||
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
||
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
||
|
||
offset.top -=
|
||
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
||
Math.abs(dpHeight + inputHeight - extraY) : extraY));
|
||
|
||
return offset;
|
||
}
|
||
|
||
/**
|
||
* noop - do nothing
|
||
*/
|
||
function noop() {
|
||
|
||
}
|
||
|
||
/**
|
||
* stopPropagation - makes the code only doing this a little easier to read in line
|
||
*/
|
||
function stopPropagation(e) {
|
||
e.stopPropagation();
|
||
}
|
||
|
||
/**
|
||
* Create a function bound to a given object
|
||
* Thanks to underscore.js
|
||
*/
|
||
function bind(func, obj) {
|
||
var slice = Array.prototype.slice;
|
||
var args = slice.call(arguments, 2);
|
||
return function () {
|
||
return func.apply(obj, args.concat(slice.call(arguments)));
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Lightweight drag helper. Handles containment within the element, so that
|
||
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
|
||
*/
|
||
function draggable(element, onmove, onstart, onstop) {
|
||
onmove = onmove || function () { };
|
||
onstart = onstart || function () { };
|
||
onstop = onstop || function () { };
|
||
var doc = element.ownerDocument || document;
|
||
var dragging = false;
|
||
var offset = {};
|
||
var maxHeight = 0;
|
||
var maxWidth = 0;
|
||
var hasTouch = ('ontouchstart' in window);
|
||
|
||
var duringDragEvents = {};
|
||
duringDragEvents["selectstart"] = prevent;
|
||
duringDragEvents["dragstart"] = prevent;
|
||
duringDragEvents["touchmove mousemove"] = move;
|
||
duringDragEvents["touchend mouseup"] = stop;
|
||
|
||
function prevent(e) {
|
||
if (e.stopPropagation) {
|
||
e.stopPropagation();
|
||
}
|
||
if (e.preventDefault) {
|
||
e.preventDefault();
|
||
}
|
||
e.returnValue = false;
|
||
}
|
||
|
||
function move(e) {
|
||
if (dragging) {
|
||
// Mouseup happened outside of window
|
||
if (IE && document.documentMode < 9 && !e.button) {
|
||
return stop();
|
||
}
|
||
|
||
var touches = e.originalEvent.touches;
|
||
var pageX = touches ? touches[0].pageX : e.pageX;
|
||
var pageY = touches ? touches[0].pageY : e.pageY;
|
||
|
||
var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
|
||
var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
|
||
|
||
if (hasTouch) {
|
||
// Stop scrolling in iOS
|
||
prevent(e);
|
||
}
|
||
|
||
onmove.apply(element, [dragX, dragY, e]);
|
||
}
|
||
}
|
||
|
||
function start(e) {
|
||
var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
|
||
var touches = e.originalEvent.touches;
|
||
|
||
if (!rightclick && !dragging) {
|
||
if (onstart.apply(element, arguments) !== false) {
|
||
dragging = true;
|
||
maxHeight = $(element).height();
|
||
maxWidth = $(element).width();
|
||
offset = $(element).offset();
|
||
|
||
$(doc).bind(duringDragEvents);
|
||
$(doc.body).addClass("sp-dragging");
|
||
|
||
if (!hasTouch) {
|
||
move(e);
|
||
}
|
||
|
||
prevent(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
function stop() {
|
||
if (dragging) {
|
||
$(doc).unbind(duringDragEvents);
|
||
$(doc.body).removeClass("sp-dragging");
|
||
onstop.apply(element, arguments);
|
||
}
|
||
dragging = false;
|
||
}
|
||
|
||
$(element).bind("touchstart mousedown", start);
|
||
}
|
||
|
||
function throttle(func, wait, debounce) {
|
||
var timeout;
|
||
return function () {
|
||
var context = this, args = arguments;
|
||
var throttler = function () {
|
||
timeout = null;
|
||
func.apply(context, args);
|
||
};
|
||
if (debounce) clearTimeout(timeout);
|
||
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
||
};
|
||
}
|
||
|
||
function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
|
||
|
||
/**
|
||
* Define a jQuery plugin
|
||
*/
|
||
var dataID = "spectrum.id";
|
||
$.fn.spectrum = function (opts, extra) {
|
||
|
||
if (typeof opts == "string") {
|
||
|
||
var returnValue = this;
|
||
var args = Array.prototype.slice.call( arguments, 1 );
|
||
|
||
this.each(function () {
|
||
var spect = spectrums[$(this).data(dataID)];
|
||
if (spect) {
|
||
var method = spect[opts];
|
||
if (!method) {
|
||
throw new Error( "Spectrum: no such method: '" + opts + "'" );
|
||
}
|
||
|
||
if (opts == "get") {
|
||
returnValue = spect.get();
|
||
}
|
||
else if (opts == "container") {
|
||
returnValue = spect.container;
|
||
}
|
||
else if (opts == "option") {
|
||
returnValue = spect.option.apply(spect, args);
|
||
}
|
||
else if (opts == "destroy") {
|
||
spect.destroy();
|
||
$(this).removeData(dataID);
|
||
}
|
||
else {
|
||
method.apply(spect, args);
|
||
}
|
||
}
|
||
});
|
||
|
||
return returnValue;
|
||
}
|
||
|
||
// Initializing a new instance of spectrum
|
||
return this.spectrum("destroy").each(function () {
|
||
var options = $.extend({}, opts, $(this).data());
|
||
var spect = spectrum(this, options);
|
||
$(this).data(dataID, spect.id);
|
||
});
|
||
};
|
||
|
||
$.fn.spectrum.load = true;
|
||
$.fn.spectrum.loadOpts = {};
|
||
$.fn.spectrum.draggable = draggable;
|
||
$.fn.spectrum.defaults = defaultOpts;
|
||
|
||
$.spectrum = { };
|
||
$.spectrum.localization = { };
|
||
$.spectrum.palettes = { };
|
||
|
||
$.fn.spectrum.processNativeColorInputs = function () {
|
||
if (!inputTypeColorSupport) {
|
||
$("input[type=color]").spectrum({
|
||
preferredFormat: "hex6"
|
||
});
|
||
}
|
||
};
|
||
|
||
// TinyColor v0.9.17
|
||
// https://github.com/bgrins/TinyColor
|
||
// 2013-08-10, Brian Grinstead, MIT License
|
||
|
||
(function() {
|
||
|
||
var trimLeft = /^[\s,#]+/,
|
||
trimRight = /\s+$/,
|
||
tinyCounter = 0,
|
||
math = Math,
|
||
mathRound = math.round,
|
||
mathMin = math.min,
|
||
mathMax = math.max,
|
||
mathRandom = math.random;
|
||
|
||
function tinycolor (color, opts) {
|
||
|
||
color = (color) ? color : '';
|
||
opts = opts || { };
|
||
|
||
// If input is already a tinycolor, return itself
|
||
if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
|
||
return color;
|
||
}
|
||
|
||
var rgb = inputToRGB(color);
|
||
var r = rgb.r,
|
||
g = rgb.g,
|
||
b = rgb.b,
|
||
a = rgb.a,
|
||
roundA = mathRound(100*a) / 100,
|
||
format = opts.format || rgb.format;
|
||
|
||
// Don't let the range of [0,255] come back in [0,1].
|
||
// Potentially lose a little bit of precision here, but will fix issues where
|
||
// .5 gets interpreted as half of the total, instead of half of 1
|
||
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
||
if (r < 1) { r = mathRound(r); }
|
||
if (g < 1) { g = mathRound(g); }
|
||
if (b < 1) { b = mathRound(b); }
|
||
|
||
return {
|
||
ok: rgb.ok,
|
||
format: format,
|
||
_tc_id: tinyCounter++,
|
||
alpha: a,
|
||
getAlpha: function() {
|
||
return a;
|
||
},
|
||
setAlpha: function(value) {
|
||
a = boundAlpha(value);
|
||
roundA = mathRound(100*a) / 100;
|
||
},
|
||
toHsv: function() {
|
||
var hsv = rgbToHsv(r, g, b);
|
||
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
|
||
},
|
||
toHsvString: function() {
|
||
var hsv = rgbToHsv(r, g, b);
|
||
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
||
return (a == 1) ?
|
||
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
||
"hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
|
||
},
|
||
toHsl: function() {
|
||
var hsl = rgbToHsl(r, g, b);
|
||
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
|
||
},
|
||
toHslString: function() {
|
||
var hsl = rgbToHsl(r, g, b);
|
||
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
||
return (a == 1) ?
|
||
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
||
"hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
|
||
},
|
||
toHex: function(allow3Char) {
|
||
return rgbToHex(r, g, b, allow3Char);
|
||
},
|
||
toHexString: function(allow3Char) {
|
||
return '#' + this.toHex(allow3Char);
|
||
},
|
||
toHex8: function() {
|
||
return rgbaToHex(r, g, b, a);
|
||
},
|
||
toHex8String: function() {
|
||
return '#' + this.toHex8();
|
||
},
|
||
toRgb: function() {
|
||
return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
|
||
},
|
||
toRgbString: function() {
|
||
return (a == 1) ?
|
||
"rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
|
||
"rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
|
||
},
|
||
toPercentageRgb: function() {
|
||
return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
|
||
},
|
||
toPercentageRgbString: function() {
|
||
return (a == 1) ?
|
||
"rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
|
||
"rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
|
||
},
|
||
toName: function() {
|
||
if (a === 0) {
|
||
return "transparent";
|
||
}
|
||
|
||
return hexNames[rgbToHex(r, g, b, true)] || false;
|
||
},
|
||
toFilter: function(secondColor) {
|
||
var hex8String = '#' + rgbaToHex(r, g, b, a);
|
||
var secondHex8String = hex8String;
|
||
var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
|
||
|
||
if (secondColor) {
|
||
var s = tinycolor(secondColor);
|
||
secondHex8String = s.toHex8String();
|
||
}
|
||
|
||
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
||
},
|
||
toString: function(format) {
|
||
var formatSet = !!format;
|
||
format = format || this.format;
|
||
|
||
var formattedString = false;
|
||
var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
|
||
var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
|
||
|
||
if (format === "rgb") {
|
||
formattedString = this.toRgbString();
|
||
}
|
||
if (format === "prgb") {
|
||
formattedString = this.toPercentageRgbString();
|
||
}
|
||
if (format === "hex" || format === "hex6") {
|
||
formattedString = this.toHexString();
|
||
}
|
||
if (format === "hex3") {
|
||
formattedString = this.toHexString(true);
|
||
}
|
||
if (format === "hex8") {
|
||
formattedString = this.toHex8String();
|
||
}
|
||
if (format === "name") {
|
||
formattedString = this.toName();
|
||
}
|
||
if (format === "hsl") {
|
||
formattedString = this.toHslString();
|
||
}
|
||
if (format === "hsv") {
|
||
formattedString = this.toHsvString();
|
||
}
|
||
|
||
if (formatWithAlpha) {
|
||
return this.toRgbString();
|
||
}
|
||
|
||
return formattedString || this.toHexString();
|
||
}
|
||
};
|
||
}
|
||
|
||
// If input is an object, force 1 into "1.0" to handle ratios properly
|
||
// String input requires "1.0" as input, so 1 will be treated as 1
|
||
tinycolor.fromRatio = function(color, opts) {
|
||
if (typeof color == "object") {
|
||
var newColor = {};
|
||
for (var i in color) {
|
||
if (color.hasOwnProperty(i)) {
|
||
if (i === "a") {
|
||
newColor[i] = color[i];
|
||
}
|
||
else {
|
||
newColor[i] = convertToPercentage(color[i]);
|
||
}
|
||
}
|
||
}
|
||
color = newColor;
|
||
}
|
||
|
||
return tinycolor(color, opts);
|
||
};
|
||
|
||
// Given a string or object, convert that input to RGB
|
||
// Possible string inputs:
|
||
//
|
||
// "red"
|
||
// "#f00" or "f00"
|
||
// "#ff0000" or "ff0000"
|
||
// "#ff000000" or "ff000000"
|
||
// "rgb 255 0 0" or "rgb (255, 0, 0)"
|
||
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
|
||
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
|
||
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
|
||
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
|
||
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
|
||
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
|
||
//
|
||
function inputToRGB(color) {
|
||
|
||
var rgb = { r: 0, g: 0, b: 0 };
|
||
var a = 1;
|
||
var ok = false;
|
||
var format = false;
|
||
|
||
if (typeof color == "string") {
|
||
color = stringInputToObject(color);
|
||
}
|
||
|
||
if (typeof color == "object") {
|
||
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
||
rgb = rgbToRgb(color.r, color.g, color.b);
|
||
ok = true;
|
||
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
||
}
|
||
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
||
color.s = convertToPercentage(color.s);
|
||
color.v = convertToPercentage(color.v);
|
||
rgb = hsvToRgb(color.h, color.s, color.v);
|
||
ok = true;
|
||
format = "hsv";
|
||
}
|
||
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
||
color.s = convertToPercentage(color.s);
|
||
color.l = convertToPercentage(color.l);
|
||
rgb = hslToRgb(color.h, color.s, color.l);
|
||
ok = true;
|
||
format = "hsl";
|
||
}
|
||
|
||
if (color.hasOwnProperty("a")) {
|
||
a = color.a;
|
||
}
|
||
}
|
||
|
||
a = boundAlpha(a);
|
||
|
||
return {
|
||
ok: ok,
|
||
format: color.format || format,
|
||
r: mathMin(255, mathMax(rgb.r, 0)),
|
||
g: mathMin(255, mathMax(rgb.g, 0)),
|
||
b: mathMin(255, mathMax(rgb.b, 0)),
|
||
a: a
|
||
};
|
||
}
|
||
|
||
|
||
// Conversion Functions
|
||
// --------------------
|
||
|
||
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
|
||
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
|
||
|
||
// `rgbToRgb`
|
||
// Handle bounds / percentage checking to conform to CSS color spec
|
||
// <http://www.w3.org/TR/css3-color/>
|
||
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
||
// *Returns:* { r, g, b } in [0, 255]
|
||
function rgbToRgb(r, g, b){
|
||
return {
|
||
r: bound01(r, 255) * 255,
|
||
g: bound01(g, 255) * 255,
|
||
b: bound01(b, 255) * 255
|
||
};
|
||
}
|
||
|
||
// `rgbToHsl`
|
||
// Converts an RGB color value to HSL.
|
||
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
||
// *Returns:* { h, s, l } in [0,1]
|
||
function rgbToHsl(r, g, b) {
|
||
|
||
r = bound01(r, 255);
|
||
g = bound01(g, 255);
|
||
b = bound01(b, 255);
|
||
|
||
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
||
var h, s, l = (max + min) / 2;
|
||
|
||
if(max == min) {
|
||
h = s = 0; // achromatic
|
||
}
|
||
else {
|
||
var d = max - min;
|
||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||
switch(max) {
|
||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||
case g: h = (b - r) / d + 2; break;
|
||
case b: h = (r - g) / d + 4; break;
|
||
}
|
||
|
||
h /= 6;
|
||
}
|
||
|
||
return { h: h, s: s, l: l };
|
||
}
|
||
|
||
// `hslToRgb`
|
||
// Converts an HSL color value to RGB.
|
||
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
||
// *Returns:* { r, g, b } in the set [0, 255]
|
||
function hslToRgb(h, s, l) {
|
||
var r, g, b;
|
||
|
||
h = bound01(h, 360);
|
||
s = bound01(s, 100);
|
||
l = bound01(l, 100);
|
||
|
||
function hue2rgb(p, q, t) {
|
||
if(t < 0) t += 1;
|
||
if(t > 1) t -= 1;
|
||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||
if(t < 1/2) return q;
|
||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||
return p;
|
||
}
|
||
|
||
if(s === 0) {
|
||
r = g = b = l; // achromatic
|
||
}
|
||
else {
|
||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||
var p = 2 * l - q;
|
||
r = hue2rgb(p, q, h + 1/3);
|
||
g = hue2rgb(p, q, h);
|
||
b = hue2rgb(p, q, h - 1/3);
|
||
}
|
||
|
||
return { r: r * 255, g: g * 255, b: b * 255 };
|
||
}
|
||
|
||
// `rgbToHsv`
|
||
// Converts an RGB color value to HSV
|
||
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
||
// *Returns:* { h, s, v } in [0,1]
|
||
function rgbToHsv(r, g, b) {
|
||
|
||
r = bound01(r, 255);
|
||
g = bound01(g, 255);
|
||
b = bound01(b, 255);
|
||
|
||
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
||
var h, s, v = max;
|
||
|
||
var d = max - min;
|
||
s = max === 0 ? 0 : d / max;
|
||
|
||
if(max == min) {
|
||
h = 0; // achromatic
|
||
}
|
||
else {
|
||
switch(max) {
|
||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||
case g: h = (b - r) / d + 2; break;
|
||
case b: h = (r - g) / d + 4; break;
|
||
}
|
||
h /= 6;
|
||
}
|
||
return { h: h, s: s, v: v };
|
||
}
|
||
|
||
// `hsvToRgb`
|
||
// Converts an HSV color value to RGB.
|
||
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
||
// *Returns:* { r, g, b } in the set [0, 255]
|
||
function hsvToRgb(h, s, v) {
|
||
|
||
h = bound01(h, 360) * 6;
|
||
s = bound01(s, 100);
|
||
v = bound01(v, 100);
|
||
|
||
var i = math.floor(h),
|
||
f = h - i,
|
||
p = v * (1 - s),
|
||
q = v * (1 - f * s),
|
||
t = v * (1 - (1 - f) * s),
|
||
mod = i % 6,
|
||
r = [v, q, p, p, t, v][mod],
|
||
g = [t, v, v, q, p, p][mod],
|
||
b = [p, p, t, v, v, q][mod];
|
||
|
||
return { r: r * 255, g: g * 255, b: b * 255 };
|
||
}
|
||
|
||
// `rgbToHex`
|
||
// Converts an RGB color to hex
|
||
// Assumes r, g, and b are contained in the set [0, 255]
|
||
// Returns a 3 or 6 character hex
|
||
function rgbToHex(r, g, b, allow3Char) {
|
||
|
||
var hex = [
|
||
pad2(mathRound(r).toString(16)),
|
||
pad2(mathRound(g).toString(16)),
|
||
pad2(mathRound(b).toString(16))
|
||
];
|
||
|
||
// Return a 3 character hex if possible
|
||
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)) {
|
||
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
||
}
|
||
|
||
return hex.join("");
|
||
}
|
||
// `rgbaToHex`
|
||
// Converts an RGBA color plus alpha transparency to hex
|
||
// Assumes r, g, b and a are contained in the set [0, 255]
|
||
// Returns an 8 character hex
|
||
function rgbaToHex(r, g, b, a) {
|
||
|
||
var hex = [
|
||
pad2(convertDecimalToHex(a)),
|
||
pad2(mathRound(r).toString(16)),
|
||
pad2(mathRound(g).toString(16)),
|
||
pad2(mathRound(b).toString(16))
|
||
];
|
||
|
||
return hex.join("");
|
||
}
|
||
|
||
// `equals`
|
||
// Can be called with any tinycolor input
|
||
tinycolor.equals = function (color1, color2) {
|
||
if (!color1 || !color2) { return false; }
|
||
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
||
};
|
||
tinycolor.random = function() {
|
||
return tinycolor.fromRatio({
|
||
r: mathRandom(),
|
||
g: mathRandom(),
|
||
b: mathRandom()
|
||
});
|
||
};
|
||
|
||
|
||
// Modification Functions
|
||
// ----------------------
|
||
// Thanks to less.js for some of the basics here
|
||
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
||
|
||
tinycolor.desaturate = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.s -= amount / 100;
|
||
hsl.s = clamp01(hsl.s);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.saturate = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.s += amount / 100;
|
||
hsl.s = clamp01(hsl.s);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.greyscale = function(color) {
|
||
return tinycolor.desaturate(color, 100);
|
||
};
|
||
tinycolor.lighten = function(color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.l += amount / 100;
|
||
hsl.l = clamp01(hsl.l);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.darken = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.l -= amount / 100;
|
||
hsl.l = clamp01(hsl.l);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.complement = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.h = (hsl.h + 180) % 360;
|
||
return tinycolor(hsl);
|
||
};
|
||
|
||
|
||
// Combination Functions
|
||
// ---------------------
|
||
// Thanks to jQuery xColor for some of the ideas behind these
|
||
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
||
|
||
tinycolor.triad = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
||
];
|
||
};
|
||
tinycolor.tetrad = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
||
];
|
||
};
|
||
tinycolor.splitcomplement = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
||
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
||
];
|
||
};
|
||
tinycolor.analogous = function(color, results, slices) {
|
||
results = results || 6;
|
||
slices = slices || 30;
|
||
|
||
var hsl = tinycolor(color).toHsl();
|
||
var part = 360 / slices;
|
||
var ret = [tinycolor(color)];
|
||
|
||
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
||
hsl.h = (hsl.h + part) % 360;
|
||
ret.push(tinycolor(hsl));
|
||
}
|
||
return ret;
|
||
};
|
||
tinycolor.monochromatic = function(color, results) {
|
||
results = results || 6;
|
||
var hsv = tinycolor(color).toHsv();
|
||
var h = hsv.h, s = hsv.s, v = hsv.v;
|
||
var ret = [];
|
||
var modification = 1 / results;
|
||
|
||
while (results--) {
|
||
ret.push(tinycolor({ h: h, s: s, v: v}));
|
||
v = (v + modification) % 1;
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
// Readability Functions
|
||
// ---------------------
|
||
// <http://www.w3.org/TR/AERT#color-contrast>
|
||
|
||
// `readability`
|
||
// Analyze the 2 colors and returns an object with the following properties:
|
||
// `brightness`: difference in brightness between the two colors
|
||
// `color`: difference in color/hue between the two colors
|
||
tinycolor.readability = function(color1, color2) {
|
||
var a = tinycolor(color1).toRgb();
|
||
var b = tinycolor(color2).toRgb();
|
||
var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
|
||
var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
|
||
var colorDiff = (
|
||
Math.max(a.r, b.r) - Math.min(a.r, b.r) +
|
||
Math.max(a.g, b.g) - Math.min(a.g, b.g) +
|
||
Math.max(a.b, b.b) - Math.min(a.b, b.b)
|
||
);
|
||
|
||
return {
|
||
brightness: Math.abs(brightnessA - brightnessB),
|
||
color: colorDiff
|
||
};
|
||
};
|
||
|
||
// `readable`
|
||
// http://www.w3.org/TR/AERT#color-contrast
|
||
// Ensure that foreground and background color combinations provide sufficient contrast.
|
||
// *Example*
|
||
// tinycolor.readable("#000", "#111") => false
|
||
tinycolor.readable = function(color1, color2) {
|
||
var readability = tinycolor.readability(color1, color2);
|
||
return readability.brightness > 125 && readability.color > 500;
|
||
};
|
||
|
||
// `mostReadable`
|
||
// Given a base color and a list of possible foreground or background
|
||
// colors for that base, returns the most readable color.
|
||
// *Example*
|
||
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
|
||
tinycolor.mostReadable = function(baseColor, colorList) {
|
||
var bestColor = null;
|
||
var bestScore = 0;
|
||
var bestIsReadable = false;
|
||
for (var i=0; i < colorList.length; i++) {
|
||
|
||
// We normalize both around the "acceptable" breaking point,
|
||
// but rank brightness constrast higher than hue.
|
||
|
||
var readability = tinycolor.readability(baseColor, colorList[i]);
|
||
var readable = readability.brightness > 125 && readability.color > 500;
|
||
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
|
||
|
||
if ((readable && ! bestIsReadable) ||
|
||
(readable && bestIsReadable && score > bestScore) ||
|
||
((! readable) && (! bestIsReadable) && score > bestScore)) {
|
||
bestIsReadable = readable;
|
||
bestScore = score;
|
||
bestColor = tinycolor(colorList[i]);
|
||
}
|
||
}
|
||
return bestColor;
|
||
};
|
||
|
||
|
||
// Big List of Colors
|
||
// ------------------
|
||
// <http://www.w3.org/TR/css3-color/#svg-color>
|
||
var names = tinycolor.names = {
|
||
aliceblue: "f0f8ff",
|
||
antiquewhite: "faebd7",
|
||
aqua: "0ff",
|
||
aquamarine: "7fffd4",
|
||
azure: "f0ffff",
|
||
beige: "f5f5dc",
|
||
bisque: "ffe4c4",
|
||
black: "000",
|
||
blanchedalmond: "ffebcd",
|
||
blue: "00f",
|
||
blueviolet: "8a2be2",
|
||
brown: "a52a2a",
|
||
burlywood: "deb887",
|
||
burntsienna: "ea7e5d",
|
||
cadetblue: "5f9ea0",
|
||
chartreuse: "7fff00",
|
||
chocolate: "d2691e",
|
||
coral: "ff7f50",
|
||
cornflowerblue: "6495ed",
|
||
cornsilk: "fff8dc",
|
||
crimson: "dc143c",
|
||
cyan: "0ff",
|
||
darkblue: "00008b",
|
||
darkcyan: "008b8b",
|
||
darkgoldenrod: "b8860b",
|
||
darkgray: "a9a9a9",
|
||
darkgreen: "006400",
|
||
darkgrey: "a9a9a9",
|
||
darkkhaki: "bdb76b",
|
||
darkmagenta: "8b008b",
|
||
darkolivegreen: "556b2f",
|
||
darkorange: "ff8c00",
|
||
darkorchid: "9932cc",
|
||
darkred: "8b0000",
|
||
darksalmon: "e9967a",
|
||
darkseagreen: "8fbc8f",
|
||
darkslateblue: "483d8b",
|
||
darkslategray: "2f4f4f",
|
||
darkslategrey: "2f4f4f",
|
||
darkturquoise: "00ced1",
|
||
darkviolet: "9400d3",
|
||
deeppink: "ff1493",
|
||
deepskyblue: "00bfff",
|
||
dimgray: "696969",
|
||
dimgrey: "696969",
|
||
dodgerblue: "1e90ff",
|
||
firebrick: "b22222",
|
||
floralwhite: "fffaf0",
|
||
forestgreen: "228b22",
|
||
fuchsia: "f0f",
|
||
gainsboro: "dcdcdc",
|
||
ghostwhite: "f8f8ff",
|
||
gold: "ffd700",
|
||
goldenrod: "daa520",
|
||
gray: "808080",
|
||
green: "008000",
|
||
greenyellow: "adff2f",
|
||
grey: "808080",
|
||
honeydew: "f0fff0",
|
||
hotpink: "ff69b4",
|
||
indianred: "cd5c5c",
|
||
indigo: "4b0082",
|
||
ivory: "fffff0",
|
||
khaki: "f0e68c",
|
||
lavender: "e6e6fa",
|
||
lavenderblush: "fff0f5",
|
||
lawngreen: "7cfc00",
|
||
lemonchiffon: "fffacd",
|
||
lightblue: "add8e6",
|
||
lightcoral: "f08080",
|
||
lightcyan: "e0ffff",
|
||
lightgoldenrodyellow: "fafad2",
|
||
lightgray: "d3d3d3",
|
||
lightgreen: "90ee90",
|
||
lightgrey: "d3d3d3",
|
||
lightpink: "ffb6c1",
|
||
lightsalmon: "ffa07a",
|
||
lightseagreen: "20b2aa",
|
||
lightskyblue: "87cefa",
|
||
lightslategray: "789",
|
||
lightslategrey: "789",
|
||
lightsteelblue: "b0c4de",
|
||
lightyellow: "ffffe0",
|
||
lime: "0f0",
|
||
limegreen: "32cd32",
|
||
linen: "faf0e6",
|
||
magenta: "f0f",
|
||
maroon: "800000",
|
||
mediumaquamarine: "66cdaa",
|
||
mediumblue: "0000cd",
|
||
mediumorchid: "ba55d3",
|
||
mediumpurple: "9370db",
|
||
mediumseagreen: "3cb371",
|
||
mediumslateblue: "7b68ee",
|
||
mediumspringgreen: "00fa9a",
|
||
mediumturquoise: "48d1cc",
|
||
mediumvioletred: "c71585",
|
||
midnightblue: "191970",
|
||
mintcream: "f5fffa",
|
||
mistyrose: "ffe4e1",
|
||
moccasin: "ffe4b5",
|
||
navajowhite: "ffdead",
|
||
navy: "000080",
|
||
oldlace: "fdf5e6",
|
||
olive: "808000",
|
||
olivedrab: "6b8e23",
|
||
orange: "ffa500",
|
||
orangered: "ff4500",
|
||
orchid: "da70d6",
|
||
palegoldenrod: "eee8aa",
|
||
palegreen: "98fb98",
|
||
paleturquoise: "afeeee",
|
||
palevioletred: "db7093",
|
||
papayawhip: "ffefd5",
|
||
peachpuff: "ffdab9",
|
||
peru: "cd853f",
|
||
pink: "ffc0cb",
|
||
plum: "dda0dd",
|
||
powderblue: "b0e0e6",
|
||
purple: "800080",
|
||
red: "f00",
|
||
rosybrown: "bc8f8f",
|
||
royalblue: "4169e1",
|
||
saddlebrown: "8b4513",
|
||
salmon: "fa8072",
|
||
sandybrown: "f4a460",
|
||
seagreen: "2e8b57",
|
||
seashell: "fff5ee",
|
||
sienna: "a0522d",
|
||
silver: "c0c0c0",
|
||
skyblue: "87ceeb",
|
||
slateblue: "6a5acd",
|
||
slategray: "708090",
|
||
slategrey: "708090",
|
||
snow: "fffafa",
|
||
springgreen: "00ff7f",
|
||
steelblue: "4682b4",
|
||
tan: "d2b48c",
|
||
teal: "008080",
|
||
thistle: "d8bfd8",
|
||
tomato: "ff6347",
|
||
turquoise: "40e0d0",
|
||
violet: "ee82ee",
|
||
wheat: "f5deb3",
|
||
white: "fff",
|
||
whitesmoke: "f5f5f5",
|
||
yellow: "ff0",
|
||
yellowgreen: "9acd32"
|
||
};
|
||
|
||
// Make it easy to access colors via `hexNames[hex]`
|
||
var hexNames = tinycolor.hexNames = flip(names);
|
||
|
||
|
||
// Utilities
|
||
// ---------
|
||
|
||
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
|
||
function flip(o) {
|
||
var flipped = { };
|
||
for (var i in o) {
|
||
if (o.hasOwnProperty(i)) {
|
||
flipped[o[i]] = i;
|
||
}
|
||
}
|
||
return flipped;
|
||
}
|
||
|
||
// Return a valid alpha value [0,1] with all invalid values being set to 1
|
||
function boundAlpha(a) {
|
||
a = parseFloat(a);
|
||
|
||
if (isNaN(a) || a < 0 || a > 1) {
|
||
a = 1;
|
||
}
|
||
|
||
return a;
|
||
}
|
||
|
||
// Take input from [0, n] and return it as [0, 1]
|
||
function bound01(n, max) {
|
||
if (isOnePointZero(n)) { n = "100%"; }
|
||
|
||
var processPercent = isPercentage(n);
|
||
n = mathMin(max, mathMax(0, parseFloat(n)));
|
||
|
||
// Automatically convert percentage into number
|
||
if (processPercent) {
|
||
n = parseInt(n * max, 10) / 100;
|
||
}
|
||
|
||
// Handle floating point rounding errors
|
||
if ((math.abs(n - max) < 0.000001)) {
|
||
return 1;
|
||
}
|
||
|
||
// Convert into [0, 1] range if it isn't already
|
||
return (n % max) / parseFloat(max);
|
||
}
|
||
|
||
// Force a number between 0 and 1
|
||
function clamp01(val) {
|
||
return mathMin(1, mathMax(0, val));
|
||
}
|
||
|
||
// Parse a base-16 hex value into a base-10 integer
|
||
function parseIntFromHex(val) {
|
||
return parseInt(val, 16);
|
||
}
|
||
|
||
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
||
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
||
function isOnePointZero(n) {
|
||
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
||
}
|
||
|
||
// Check to see if string passed in is a percentage
|
||
function isPercentage(n) {
|
||
return typeof n === "string" && n.indexOf('%') != -1;
|
||
}
|
||
|
||
// Force a hex value to have 2 characters
|
||
function pad2(c) {
|
||
return c.length == 1 ? '0' + c : '' + c;
|
||
}
|
||
|
||
// Replace a decimal with it's percentage value
|
||
function convertToPercentage(n) {
|
||
if (n <= 1) {
|
||
n = (n * 100) + "%";
|
||
}
|
||
|
||
return n;
|
||
}
|
||
|
||
// Converts a decimal to a hex value
|
||
function convertDecimalToHex(d) {
|
||
return Math.round(parseFloat(d) * 255).toString(16);
|
||
}
|
||
// Converts a hex value to a decimal
|
||
function convertHexToDecimal(h) {
|
||
return (parseIntFromHex(h) / 255);
|
||
}
|
||
|
||
var matchers = (function() {
|
||
|
||
// <http://www.w3.org/TR/css3-values/#integers>
|
||
var CSS_INTEGER = "[-\\+]?\\d+%?";
|
||
|
||
// <http://www.w3.org/TR/css3-values/#number-value>
|
||
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
||
|
||
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
||
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
||
|
||
// Actual matching.
|
||
// Parentheses and commas are optional, but not required.
|
||
// Whitespace can take the place of commas or opening paren
|
||
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
||
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
||
|
||
return {
|
||
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
||
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
||
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
||
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
||
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
||
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
||
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
||
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
||
};
|
||
})();
|
||
|
||
// `stringInputToObject`
|
||
// Permissive string parsing. Take in a number of formats, and output an object
|
||
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
||
function stringInputToObject(color) {
|
||
|
||
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
|
||
var named = false;
|
||
if (names[color]) {
|
||
color = names[color];
|
||
named = true;
|
||
}
|
||
else if (color == 'transparent') {
|
||
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
||
}
|
||
|
||
// Try to match string input using regular expressions.
|
||
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
||
// Just return an object and let the conversion functions handle that.
|
||
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
||
var match;
|
||
if ((match = matchers.rgb.exec(color))) {
|
||
return { r: match[1], g: match[2], b: match[3] };
|
||
}
|
||
if ((match = matchers.rgba.exec(color))) {
|
||
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
||
}
|
||
if ((match = matchers.hsl.exec(color))) {
|
||
return { h: match[1], s: match[2], l: match[3] };
|
||
}
|
||
if ((match = matchers.hsla.exec(color))) {
|
||
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
||
}
|
||
if ((match = matchers.hsv.exec(color))) {
|
||
return { h: match[1], s: match[2], v: match[3] };
|
||
}
|
||
if ((match = matchers.hex8.exec(color))) {
|
||
return {
|
||
a: convertHexToDecimal(match[1]),
|
||
r: parseIntFromHex(match[2]),
|
||
g: parseIntFromHex(match[3]),
|
||
b: parseIntFromHex(match[4]),
|
||
format: named ? "name" : "hex8"
|
||
};
|
||
}
|
||
if ((match = matchers.hex6.exec(color))) {
|
||
return {
|
||
r: parseIntFromHex(match[1]),
|
||
g: parseIntFromHex(match[2]),
|
||
b: parseIntFromHex(match[3]),
|
||
format: named ? "name" : "hex"
|
||
};
|
||
}
|
||
if ((match = matchers.hex3.exec(color))) {
|
||
return {
|
||
r: parseIntFromHex(match[1] + '' + match[1]),
|
||
g: parseIntFromHex(match[2] + '' + match[2]),
|
||
b: parseIntFromHex(match[3] + '' + match[3]),
|
||
format: named ? "name" : "hex"
|
||
};
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Expose tinycolor to window, does not need to run in non-browser context.
|
||
window.tinycolor = tinycolor;
|
||
|
||
})();
|
||
|
||
|
||
$(function () {
|
||
if ($.fn.spectrum.load) {
|
||
$.fn.spectrum.processNativeColorInputs();
|
||
}
|
||
});
|
||
|
||
})(window, jQuery);
|
||
|
||
/* =============================================================
|
||
* bootstrap-combobox.js v1.1.5
|
||
* =============================================================
|
||
* Copyright 2012 Daniel Farrell
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
* ============================================================ */
|
||
|
||
!function( $ ) {
|
||
|
||
"use strict";
|
||
|
||
/* COMBOBOX PUBLIC CLASS DEFINITION
|
||
* ================================ */
|
||
|
||
var Combobox = function ( element, options ) {
|
||
this.options = $.extend({}, $.fn.combobox.defaults, options);
|
||
this.$source = $(element);
|
||
this.$container = this.setup();
|
||
this.$element = this.$container.find('input[type=text]');
|
||
this.$target = this.$container.find('input[type=hidden]');
|
||
this.$button = this.$container.find('.dropdown-toggle');
|
||
this.$menu = $(this.options.menu).appendTo('body');
|
||
this.matcher = this.options.matcher || this.matcher;
|
||
this.sorter = this.options.sorter || this.sorter;
|
||
this.highlighter = this.options.highlighter || this.highlighter;
|
||
this.shown = false;
|
||
this.selected = false;
|
||
this.refresh();
|
||
this.transferAttributes();
|
||
this.listen();
|
||
};
|
||
|
||
Combobox.prototype = {
|
||
|
||
constructor: Combobox
|
||
|
||
, setup: function () {
|
||
var combobox = $(this.options.template);
|
||
this.$source.before(combobox);
|
||
this.$source.hide();
|
||
return combobox;
|
||
}
|
||
|
||
, parse: function () {
|
||
var that = this
|
||
, map = {}
|
||
, source = []
|
||
, selected = false
|
||
, selectedValue = '';
|
||
this.$source.find('option').each(function() {
|
||
var option = $(this);
|
||
if (option.val() === '') {
|
||
that.options.placeholder = option.text();
|
||
return;
|
||
}
|
||
map[option.text()] = option.val();
|
||
source.push(option.text());
|
||
if (option.prop('selected')) {
|
||
selected = option.text();
|
||
selectedValue = option.val();
|
||
}
|
||
})
|
||
this.map = map;
|
||
if (selected) {
|
||
this.$element.val(selected);
|
||
this.$target.val(selectedValue);
|
||
this.$container.addClass('combobox-selected');
|
||
this.selected = true;
|
||
}
|
||
return source;
|
||
}
|
||
|
||
, transferAttributes: function() {
|
||
this.options.placeholder = this.$source.attr('data-placeholder') || this.options.placeholder;
|
||
this.$element.attr('placeholder', this.options.placeholder);
|
||
this.$target.prop('name', this.$source.prop('name'));
|
||
this.$target.val(this.$source.val());
|
||
this.$source.removeAttr('name'); // Remove from source otherwise form will pass parameter twice.
|
||
this.$element.attr('required', this.$source.attr('required'));
|
||
this.$element.attr('rel', this.$source.attr('rel'));
|
||
this.$element.attr('title', this.$source.attr('title'));
|
||
this.$element.attr('class', this.$source.attr('class'));
|
||
this.$element.attr('tabindex', this.$source.attr('tabindex'));
|
||
this.$source.removeAttr('tabindex');
|
||
this.$source.removeAttr('required');
|
||
}
|
||
|
||
, setSelected: function() {
|
||
this.selected = true;
|
||
}
|
||
|
||
, select: function () {
|
||
var val = this.$menu.find('.active').attr('data-value');
|
||
this.$element.val(this.updater(val));
|
||
this.$target.val(this.map[val]);
|
||
this.$source.val(this.map[val]);
|
||
this.$element.trigger('change');
|
||
this.$target.trigger('change');
|
||
this.$source.trigger('change');
|
||
this.$container.addClass('combobox-selected');
|
||
this.selected = true;
|
||
return this.hide();
|
||
}
|
||
|
||
, updater: function (item) {
|
||
return item;
|
||
}
|
||
|
||
, show: function () {
|
||
var pos = $.extend({}, this.$element.position(), {
|
||
height: this.$element[0].offsetHeight
|
||
});
|
||
|
||
this.$menu
|
||
.insertAfter(this.$element)
|
||
.css({
|
||
top: pos.top + pos.height
|
||
, left: pos.left
|
||
})
|
||
.show();
|
||
|
||
this.shown = true;
|
||
return this;
|
||
}
|
||
|
||
, hide: function () {
|
||
this.$menu.hide();
|
||
this.shown = false;
|
||
return this;
|
||
}
|
||
|
||
, lookup: function (event) {
|
||
this.query = this.$element.val();
|
||
return this.process(this.source);
|
||
}
|
||
|
||
, process: function (items) {
|
||
var that = this;
|
||
|
||
items = $.grep(items, function (item) {
|
||
return that.matcher(item);
|
||
})
|
||
|
||
items = this.sorter(items);
|
||
|
||
if (!items.length) {
|
||
return this.shown ? this.hide() : this;
|
||
}
|
||
|
||
return this.render(items.slice(0, this.options.items)).show();
|
||
}
|
||
|
||
, matcher: function (item) {
|
||
return ~item.toLowerCase().indexOf(this.query.toLowerCase());
|
||
}
|
||
|
||
, sorter: function (items) {
|
||
var beginswith = []
|
||
, caseSensitive = []
|
||
, caseInsensitive = []
|
||
, item;
|
||
|
||
while (item = items.shift()) {
|
||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) {beginswith.push(item);}
|
||
else if (~item.indexOf(this.query)) {caseSensitive.push(item);}
|
||
else {caseInsensitive.push(item);}
|
||
}
|
||
|
||
return beginswith.concat(caseSensitive, caseInsensitive);
|
||
}
|
||
|
||
, highlighter: function (item) {
|
||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
|
||
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
||
return '<strong>' + match + '</strong>';
|
||
})
|
||
}
|
||
|
||
, render: function (items) {
|
||
var that = this;
|
||
|
||
items = $(items).map(function (i, item) {
|
||
i = $(that.options.item).attr('data-value', item);
|
||
i.find('a').html(that.highlighter(item));
|
||
return i[0];
|
||
})
|
||
|
||
items.first().addClass('active');
|
||
this.$menu.html(items);
|
||
return this;
|
||
}
|
||
|
||
, next: function (event) {
|
||
var active = this.$menu.find('.active').removeClass('active')
|
||
, next = active.next();
|
||
|
||
if (!next.length) {
|
||
next = $(this.$menu.find('li')[0]);
|
||
}
|
||
|
||
next.addClass('active');
|
||
}
|
||
|
||
, prev: function (event) {
|
||
var active = this.$menu.find('.active').removeClass('active')
|
||
, prev = active.prev();
|
||
|
||
if (!prev.length) {
|
||
prev = this.$menu.find('li').last();
|
||
}
|
||
|
||
prev.addClass('active');
|
||
}
|
||
|
||
, toggle: function () {
|
||
if (this.$container.hasClass('combobox-selected')) {
|
||
this.clearTarget();
|
||
this.triggerChange();
|
||
this.clearElement();
|
||
} else {
|
||
if (this.shown) {
|
||
this.hide();
|
||
} else {
|
||
this.clearElement();
|
||
this.lookup();
|
||
}
|
||
}
|
||
|
||
this.$element.trigger('change');
|
||
this.$target.trigger('change');
|
||
this.$source.trigger('change');
|
||
}
|
||
|
||
, clearElement: function () {
|
||
this.$element.val('').focus();
|
||
}
|
||
|
||
, clearTarget: function () {
|
||
this.$source.val('');
|
||
this.$target.val('');
|
||
this.$container.removeClass('combobox-selected');
|
||
this.selected = false;
|
||
}
|
||
|
||
, triggerChange: function () {
|
||
this.$source.trigger('change');
|
||
}
|
||
|
||
, refresh: function () {
|
||
this.source = this.parse();
|
||
this.options.items = this.source.length;
|
||
}
|
||
|
||
, listen: function () {
|
||
this.$element
|
||
.on('focus', $.proxy(this.focus, this))
|
||
.on('blur', $.proxy(this.blur, this))
|
||
.on('keypress', $.proxy(this.keypress, this))
|
||
.on('keyup', $.proxy(this.keyup, this));
|
||
|
||
if (this.eventSupported('keydown')) {
|
||
this.$element.on('keydown', $.proxy(this.keydown, this));
|
||
}
|
||
|
||
this.$menu
|
||
.on('click', $.proxy(this.click, this))
|
||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this));
|
||
|
||
this.$button
|
||
.on('click', $.proxy(this.toggle, this));
|
||
}
|
||
|
||
, eventSupported: function(eventName) {
|
||
var isSupported = eventName in this.$element;
|
||
if (!isSupported) {
|
||
this.$element.setAttribute(eventName, 'return;');
|
||
isSupported = typeof this.$element[eventName] === 'function';
|
||
}
|
||
return isSupported;
|
||
}
|
||
|
||
, move: function (e) {
|
||
if (!this.shown) {return;}
|
||
|
||
switch(e.keyCode) {
|
||
case 9: // tab
|
||
case 13: // enter
|
||
case 27: // escape
|
||
e.preventDefault();
|
||
break;
|
||
|
||
case 38: // up arrow
|
||
e.preventDefault();
|
||
this.prev();
|
||
break;
|
||
|
||
case 40: // down arrow
|
||
e.preventDefault();
|
||
this.next();
|
||
break;
|
||
}
|
||
|
||
e.stopPropagation();
|
||
}
|
||
|
||
, keydown: function (e) {
|
||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]);
|
||
this.move(e);
|
||
}
|
||
|
||
, keypress: function (e) {
|
||
if (this.suppressKeyPressRepeat) {return;}
|
||
this.move(e);
|
||
}
|
||
|
||
, keyup: function (e) {
|
||
switch(e.keyCode) {
|
||
case 40: // down arrow
|
||
case 39: // right arrow
|
||
case 38: // up arrow
|
||
case 37: // left arrow
|
||
case 36: // home
|
||
case 35: // end
|
||
case 33: // page up
|
||
case 34: // page down
|
||
case 16: // shift
|
||
case 17: // ctrl
|
||
case 18: // alt
|
||
case 20: // cap lock
|
||
break;
|
||
|
||
case 9: // tab
|
||
case 13: // enter
|
||
if (!this.shown) {return;}
|
||
this.select();
|
||
break;
|
||
|
||
case 27: // escape
|
||
if (!this.shown) {return;}
|
||
this.hide();
|
||
break;
|
||
|
||
default:
|
||
this.clearTarget();
|
||
this.lookup();
|
||
}
|
||
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
}
|
||
|
||
, focus: function (e) {
|
||
this.focused = true;
|
||
}
|
||
|
||
, blur: function (e) {
|
||
var that = this;
|
||
this.focused = false;
|
||
var val = this.$element.val();
|
||
if (!this.selected && val !== '' ) {
|
||
this.$element.val('');
|
||
this.$source.val('').trigger('change');
|
||
this.$target.val('').trigger('change');
|
||
}
|
||
if (!this.mousedover && this.shown) {setTimeout(function () { that.hide(); }, 200);}
|
||
}
|
||
|
||
, click: function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
this.select();
|
||
this.$element.focus();
|
||
}
|
||
|
||
, mouseenter: function (e) {
|
||
this.mousedover = true;
|
||
this.$menu.find('.active').removeClass('active');
|
||
$(e.currentTarget).addClass('active');
|
||
}
|
||
|
||
, mouseleave: function (e) {
|
||
this.mousedover = false;
|
||
}
|
||
};
|
||
|
||
/* COMBOBOX PLUGIN DEFINITION
|
||
* =========================== */
|
||
|
||
$.fn.combobox = function ( option ) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
, data = $this.data('combobox')
|
||
, options = typeof option == 'object' && option;
|
||
if(!data) {$this.data('combobox', (data = new Combobox(this, options)));}
|
||
if (typeof option == 'string') {data[option]();}
|
||
});
|
||
};
|
||
|
||
$.fn.combobox.defaults = {
|
||
template: '<div class="combobox-container"> <input type="hidden" /> <div class="input-group"> <input type="text" autocomplete="off" /> <span class="input-group-addon dropdown-toggle" data-dropdown="dropdown"> <span class="caret" /> <i class="fa fa-times"></i> </span> </div> </div> '
|
||
, menu: '<ul class="typeahead typeahead-long dropdown-menu"></ul>'
|
||
, item: '<li><a href="#"></a></li>'
|
||
};
|
||
|
||
$.fn.combobox.Constructor = Combobox;
|
||
|
||
}( window.jQuery );
|
||
|
||
/**
|
||
* jsPDF - PDF Document creation from JavaScript
|
||
* Version 1.0.178-git Built on 2014-06-27T15:34
|
||
* CommitID 78eac7128d
|
||
*
|
||
* Copyright (c) 2010-2014 James Hall, https://github.com/MrRio/jsPDF
|
||
* 2010 Aaron Spike, https://github.com/acspike
|
||
* 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2012 Pablo Hess, https://github.com/pablohess
|
||
* 2012 Florian Jenett, https://github.com/fjenett
|
||
* 2013 Warren Weckesser, https://github.com/warrenweckesser
|
||
* 2013 Youssef Beddad, https://github.com/lifof
|
||
* 2013 Lee Driscoll, https://github.com/lsdriscoll
|
||
* 2013 Stefan Slonevskiy, https://github.com/stefslon
|
||
* 2013 Jeremy Morel, https://github.com/jmorel
|
||
* 2013 Christoph Hartmann, https://github.com/chris-rock
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 James Makes, https://github.com/dollaruw
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining
|
||
* a copy of this software and associated documentation files (the
|
||
* "Software"), to deal in the Software without restriction, including
|
||
* without limitation the rights to use, copy, modify, merge, publish,
|
||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||
* permit persons to whom the Software is furnished to do so, subject to
|
||
* the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be
|
||
* included in all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
*
|
||
* Contributor(s):
|
||
* siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
|
||
* kim3er, mfo, alnorth,
|
||
*/
|
||
/**
|
||
* jsPDF addHTML PlugIn
|
||
* Copyright (c) 2014 Diego Casorran
|
||
* Licensed under the MIT License.
|
||
* http://opensource.org/licenses/mit-license
|
||
*/
|
||
/**
|
||
* jsPDF addImage plugin
|
||
* Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
|
||
* 2013 Chris Dowling, https://github.com/gingerchris
|
||
* 2013 Trinh Ho, https://github.com/ineedfat
|
||
* 2013 Edwin Alejandro Perez, https://github.com/eaparango
|
||
* 2013 Norah Smith, https://github.com/burnburnrocket
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
* 2014 James Robb, https://github.com/jamesbrobb
|
||
*/
|
||
/**
|
||
* jsPDF Cell plugin
|
||
* Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
|
||
* 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
|
||
* 2013 Lee Driscoll, https://github.com/lsdriscoll
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 James Hall, james@parall.ax
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*/
|
||
/**
|
||
* jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
|
||
* Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
* 2014 Daniel Husar, https://github.com/danielhusar
|
||
* 2014 Wolfgang Gassler, https://github.com/woolfg
|
||
*/
|
||
/**
|
||
* jsPDF JavaScript plugin
|
||
* Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
|
||
*/
|
||
/**
|
||
* jsPDF PNG PlugIn
|
||
* Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
|
||
*/
|
||
/**
|
||
jsPDF Silly SVG plugin
|
||
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
*/
|
||
/**
|
||
* jsPDF split_text_to_size plugin - MIT license.
|
||
* Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*/
|
||
/**
|
||
jsPDF standard_fonts_metrics plugin
|
||
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
MIT license.
|
||
*/
|
||
/**
|
||
* jsPDF total_pages plugin
|
||
* Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
|
||
*/
|
||
/* Blob.js
|
||
* A Blob implementation.
|
||
* 2014-05-31
|
||
* By Eli Grey, http://eligrey.com
|
||
* By Devin Samarin, https://github.com/eboyjr
|
||
* License: X11/MIT
|
||
* See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
|
||
*/
|
||
/* FileSaver.js
|
||
* A saveAs() FileSaver implementation.
|
||
* 2014-05-27
|
||
* By Eli Grey, http://eligrey.com
|
||
* License: X11/MIT
|
||
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
|
||
*/
|
||
/*
|
||
* Copyright (c) 2012 chick307 <chick307@gmail.com>
|
||
* Licensed under the MIT License.
|
||
* http://opensource.org/licenses/mit-license
|
||
*/
|
||
/*
|
||
Deflate.js - https://github.com/gildas-lormeau/zip.js
|
||
Copyright (c) 2013 Gildas Lormeau. All rights reserved.
|
||
Redistribution and use in source and binary forms, with or without
|
||
modification, are permitted provided that the following conditions are met:
|
||
1. Redistributions of source code must retain the above copyright notice,
|
||
this list of conditions and the following disclaimer.
|
||
2. Redistributions in binary form must reproduce the above copyright
|
||
notice, this list of conditions and the following disclaimer in
|
||
the documentation and/or other materials provided with the distribution.
|
||
3. The names of the authors may not be used to endorse or promote products
|
||
derived from this software without specific prior written permission.
|
||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
/*
|
||
# PNG.js
|
||
# Copyright (c) 2011 Devon Govett
|
||
# MIT LICENSE
|
||
#
|
||
*/
|
||
/*
|
||
* Extracted from pdf.js
|
||
* https://github.com/andreasgal/pdf.js
|
||
* Copyright (c) 2011 Mozilla Foundation
|
||
* Contributors: Andreas Gal <gal@mozilla.com>
|
||
* Chris G Jones <cjones@mozilla.com>
|
||
* Shaon Barman <shaon.barman@gmail.com>
|
||
* Vivien Nicolas <21@vingtetun.org>
|
||
* Justin D'Arcangelo <justindarc@gmail.com>
|
||
* Yury Delendik
|
||
*/
|
||
/**
|
||
* JavaScript Polyfill functions for jsPDF
|
||
* Collected from public resources by
|
||
* https://github.com/diegocr
|
||
*/
|
||
!function(t,e){e["true"]=t;var n=function(t){"use strict";function e(e){var n={};this.subscribe=function(t,e,r){if("function"!=typeof e)return!1;n.hasOwnProperty(t)||(n[t]={});var s=Math.random().toString(35);return n[t][s]=[e,!!r],s},this.unsubscribe=function(t){for(var e in n)if(n[e][t])return delete n[e][t],!0;return!1},this.publish=function(r){if(n.hasOwnProperty(r)){var s=Array.prototype.slice.call(arguments,1),i=[];for(var o in n[r]){var a=n[r][o];try{a[0].apply(e,s)}catch(u){t.console&&console.error("jsPDF PubSub Error",u.message,u)}a[1]&&i.push(o)}i.length&&i.forEach(this.unsubscribe)}}}function n(a,u,c,l){var f={};"object"==typeof a&&(f=a,a=f.orientation,u=f.unit||u,c=f.format||c,l=f.compress||f.compressPdf||l),u=u||"mm",c=c||"a4",a=(""+(a||"P")).toLowerCase();var d,h,p,m,w,g=(""+c).toLowerCase(),y=!!l&&"function"==typeof Uint8Array,v=f.textColor||"0 g",b=f.drawColor||"0 G",q=f.fontSize||16,x=f.lineHeight||1.15,k=f.lineWidth||.200025,_=2,A=!1,C=[],S={},E={},z=0,T=[],I=[],B=0,O=0,P=0,F={title:"",subject:"",author:"",keywords:"",creator:""},R={},D=new e(R),U=function(t){return t.toFixed(2)},N=function(t){return t.toFixed(3)},L=function(t){return("0"+parseInt(t)).slice(-2)},j=function(t){A?T[z].push(t):(P+=t.length+1,I.push(t))},M=function(){return _++,C[_]=P,j(_+" 0 obj"),_},H=function(t){j("stream"),j(t),j("endstream")},G=function(){var e,r,i,o,a,u,c,l=m*h,f=w*h;for(c=t.adler32cs||n.adler32cs,y&&"undefined"==typeof c&&(y=!1),e=1;z>=e;e++){if(M(),j("<</Type /Page"),j("/Parent 1 0 R"),j("/Resources 2 0 R"),j("/Contents "+(_+1)+" 0 R>>"),j("endobj"),r=T[e].join("\n"),M(),y){for(i=[],o=r.length;o--;)i[o]=r.charCodeAt(o);u=c.from(r),a=new s(6),a.append(new Uint8Array(i)),r=a.flush(),i=new Uint8Array(r.length+6),i.set(new Uint8Array([120,156])),i.set(r,2),i.set(new Uint8Array([255&u,u>>8&255,u>>16&255,u>>24&255]),r.length+2),r=String.fromCharCode.apply(null,i),j("<</Length "+r.length+" /Filter [/FlateDecode]>>")}else j("<</Length "+r.length+">>");H(r),j("endobj")}C[1]=P,j("1 0 obj"),j("<</Type /Pages");var d="/Kids [";for(o=0;z>o;o++)d+=3+2*o+" 0 R ";j(d+"]"),j("/Count "+z),j("/MediaBox [0 0 "+U(l)+" "+U(f)+"]"),j(">>"),j("endobj")},W=function(t){t.objectNumber=M(),j("<</BaseFont/"+t.PostScriptName+"/Type/Font"),"string"==typeof t.encoding&&j("/Encoding/"+t.encoding),j("/Subtype/Type1>>"),j("endobj")},J=function(){for(var t in S)S.hasOwnProperty(t)&&W(S[t])},V=function(){D.publish("putXobjectDict")},X=function(){j("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),j("/Font <<");for(var t in S)S.hasOwnProperty(t)&&j("/"+t+" "+S[t].objectNumber+" 0 R");j(">>"),j("/XObject <<"),V(),j(">>")},Y=function(){J(),D.publish("putResources"),C[2]=P,j("2 0 obj"),j("<<"),X(),j(">>"),j("endobj"),D.publish("postPutResources")},K=function(t,e,n){E.hasOwnProperty(e)||(E[e]={}),E[e][n]=t},Q=function(t,e,n,r){var s="F"+(Object.keys(S).length+1).toString(10),i=S[s]={id:s,PostScriptName:t,fontName:e,fontStyle:n,encoding:r,metadata:{}};return K(s,e,n),D.publish("addFont",i),s},$=function(){for(var t="helvetica",e="times",n="courier",r="normal",s="bold",i="italic",o="bolditalic",a="StandardEncoding",u=[["Helvetica",t,r],["Helvetica-Bold",t,s],["Helvetica-Oblique",t,i],["Helvetica-BoldOblique",t,o],["Courier",n,r],["Courier-Bold",n,s],["Courier-Oblique",n,i],["Courier-BoldOblique",n,o],["Times-Roman",e,r],["Times-Bold",e,s],["Times-Italic",e,i],["Times-BoldItalic",e,o]],c=0,l=u.length;l>c;c++){var f=Q(u[c][0],u[c][1],u[c][2],a),d=u[c][0].split("-");K(f,d[0],d[1]||"")}D.publish("addFonts",{fonts:S,dictionary:E})},Z=function(e){return e.foo=function(){try{return e.apply(this,arguments)}catch(n){var r=n.stack||"";~r.indexOf(" at ")&&(r=r.split(" at ")[1]);var s="Error in function "+r.split("\n")[0].split("<")[0]+": "+n.message;if(!t.console)throw new Error(s);console.log(s,n),t.alert&&alert(s),console.trace()}},e.foo.bar=e,e.foo},te=function(t,e){var n,r,s,i,o,a,u,c,l;if(e=e||{},s=e.sourceEncoding||"Unicode",o=e.outputEncoding,(e.autoencode||o)&&S[d].metadata&&S[d].metadata[s]&&S[d].metadata[s].encoding&&(i=S[d].metadata[s].encoding,!o&&S[d].encoding&&(o=S[d].encoding),!o&&i.codePages&&(o=i.codePages[0]),"string"==typeof o&&(o=i[o]),o)){for(u=!1,a=[],n=0,r=t.length;r>n;n++)c=o[t.charCodeAt(n)],c?a.push(String.fromCharCode(c)):a.push(t[n]),a[n].charCodeAt(0)>>8&&(u=!0);t=a.join("")}for(n=t.length;void 0===u&&0!==n;)t.charCodeAt(n-1)>>8&&(u=!0),n--;if(!u)return t;for(a=e.noBOM?[]:[254,255],n=0,r=t.length;r>n;n++){if(c=t.charCodeAt(n),l=c>>8,l>>8)throw new Error("Character at position "+n+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");a.push(l),a.push(c-(l<<8))}return String.fromCharCode.apply(void 0,a)},ee=function(t,e){return te(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},ne=function(){j("/Producer (jsPDF "+n.version+")");for(var t in F)F.hasOwnProperty(t)&&F[t]&&j("/"+t.substr(0,1).toUpperCase()+t.substr(1)+" ("+ee(F[t])+")");var e=new Date;j(["/CreationDate (D:",e.getFullYear(),L(e.getMonth()+1),L(e.getDate()),L(e.getHours()),L(e.getMinutes()),L(e.getSeconds()),")"].join(""))},re=function(){j("/Type /Catalog"),j("/Pages 1 0 R"),j("/OpenAction [3 0 R /FitH null]"),j("/PageLayout /OneColumn"),D.publish("putCatalog")},se=function(){j("/Size "+(_+1)),j("/Root "+_+" 0 R"),j("/Info "+(_-1)+" 0 R")},ie=function(){z++,A=!0,T[z]=[]},oe=function(){ie(),j(U(k*h)+" w"),j(b),0!==B&&j(B+" J"),0!==O&&j(O+" j"),D.publish("addPage",{pageNumber:z})},ae=function(t,e){var n;t=void 0!==t?t:S[d].fontName,e=void 0!==e?e:S[d].fontStyle;try{n=E[t][e]}catch(r){}if(!n)throw new Error("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts.");return n},ue=function(){A=!1,_=2,I=[],C=[],j("%PDF-"+i),G(),Y(),M(),j("<<"),ne(),j(">>"),j("endobj"),M(),j("<<"),re(),j(">>"),j("endobj");var t,e=P,n="0000000000";for(j("xref"),j("0 "+(_+1)),j(n+" 65535 f "),t=1;_>=t;t++)j((n+C[t]).slice(-10)+" 00000 n ");return j("trailer"),j("<<"),se(),j(">>"),j("startxref"),j(e),j("%%EOF"),A=!0,I.join("\n")},ce=function(t){var e="S";return"F"===t?e="f":"FD"===t||"DF"===t?e="B":("f"===t||"f*"===t||"B"===t||"B*"===t)&&(e=t),e},le=function(){for(var t=ue(),e=t.length,n=new ArrayBuffer(e),r=new Uint8Array(n);e--;)r[e]=t.charCodeAt(e);return n},fe=function(){return new Blob([le()],{type:"application/pdf"})},de=Z(function(e,n){switch(e){case void 0:return ue();case"save":if(navigator.getUserMedia&&(void 0===t.URL||void 0===t.URL.createObjectURL))return R.output("dataurlnewwindow");r(fe(),n),"function"==typeof r.unload&&t.setTimeout&&setTimeout(r.unload,70);break;case"arraybuffer":return le();case"blob":return fe();case"datauristring":case"dataurlstring":return"data:application/pdf;base64,"+btoa(ue());case"datauri":case"dataurl":t.document.location.href="data:application/pdf;base64,"+btoa(ue());break;case"dataurlnewwindow":t.open("data:application/pdf;base64,"+btoa(ue()));break;default:throw new Error('Output type "'+e+'" is not supported.')}});switch(u){case"pt":h=1;break;case"mm":h=72/25.4;break;case"cm":h=72/2.54;break;case"in":h=72;break;case"px":h=96/72;break;case"pc":h=12;break;case"em":h=12;break;case"ex":h=6;break;default:throw"Invalid unit: "+u}if(o.hasOwnProperty(g))w=o[g][1]/h,m=o[g][0]/h;else try{w=c[1],m=c[0]}catch(he){throw new Error("Invalid format: "+c)}if("p"===a||"portrait"===a)a="p",m>w&&(p=m,m=w,w=p);else{if("l"!==a&&"landscape"!==a)throw"Invalid orientation: "+a;a="l",w>m&&(p=m,m=w,w=p)}R.internal={pdfEscape:ee,getStyle:ce,getFont:function(){return S[ae.apply(R,arguments)]},getFontSize:function(){return q},getLineHeight:function(){return q*x},write:function(t){j(1===arguments.length?t:Array.prototype.join.call(arguments," "))},getCoordinateString:function(t){return U(t*h)},getVerticalCoordinateString:function(t){return U((w-t)*h)},collections:{},newObject:M,putStream:H,events:D,scaleFactor:h,pageSize:{width:m,height:w},output:function(t,e){return de(t,e)},getNumberOfPages:function(){return T.length-1},pages:T},R.addPage=function(){return oe(),this},R.text=function(t,e,n,r,s){function i(t){return t=t.split(" ").join(Array(f.TabLen||9).join(" ")),ee(t,r)}"number"==typeof t&&(p=n,n=e,e=t,t=p),"string"==typeof t&&t.match(/[\n\r]/)&&(t=t.split(/\r\n|\r|\n/g)),"number"==typeof r&&(s=r,r=null);var o="",a="Td";if(s){s*=Math.PI/180;var u=Math.cos(s),c=Math.sin(s);o=[U(u),U(c),U(-1*c),U(u),""].join(" "),a="Tm"}if(r=r||{},"noBOM"in r||(r.noBOM=!0),"autoencode"in r||(r.autoencode=!0),"string"==typeof t)t=i(t);else{if(!(t instanceof Array))throw new Error('Type of text must be string or Array. "'+t+'" is not recognized.');for(var l=t.concat(),m=[],g=l.length;g--;)m.push(i(l.shift()));t=m.join(") Tj\nT* (")}return j("BT\n/"+d+" "+q+" Tf\n"+q*x+" TL\n"+v+"\n"+o+U(e*h)+" "+U((w-n)*h)+" "+a+"\n("+t+") Tj\nET"),this},R.line=function(t,e,n,r){return this.lines([[n-t,r-e]],t,e)},R.lines=function(t,e,n,r,s,i){var o,a,u,c,l,f,d,m,g,y,v;for("number"==typeof t&&(p=n,n=e,e=t,t=p),r=r||[1,1],j(N(e*h)+" "+N((w-n)*h)+" m "),o=r[0],a=r[1],c=t.length,y=e,v=n,u=0;c>u;u++)l=t[u],2===l.length?(y=l[0]*o+y,v=l[1]*a+v,j(N(y*h)+" "+N((w-v)*h)+" l")):(f=l[0]*o+y,d=l[1]*a+v,m=l[2]*o+y,g=l[3]*a+v,y=l[4]*o+y,v=l[5]*a+v,j(N(f*h)+" "+N((w-d)*h)+" "+N(m*h)+" "+N((w-g)*h)+" "+N(y*h)+" "+N((w-v)*h)+" c"));return i&&j(" h"),null!==s&&j(ce(s)),this},R.rect=function(t,e,n,r,s){ce(s);return j([U(t*h),U((w-e)*h),U(n*h),U(-r*h),"re"].join(" ")),null!==s&&j(ce(s)),this},R.triangle=function(t,e,n,r,s,i,o){return this.lines([[n-t,r-e],[s-n,i-r],[t-s,e-i]],t,e,[1,1],o,!0),this},R.roundedRect=function(t,e,n,r,s,i,o){var a=4/3*(Math.SQRT2-1);return this.lines([[n-2*s,0],[s*a,0,s,i-i*a,s,i],[0,r-2*i],[0,i*a,-(s*a),i,-s,i],[-n+2*s,0],[-(s*a),0,-s,-(i*a),-s,-i],[0,-r+2*i],[0,-(i*a),s*a,-i,s,-i]],t+s,e,[1,1],o),this},R.ellipse=function(t,e,n,r,s){var i=4/3*(Math.SQRT2-1)*n,o=4/3*(Math.SQRT2-1)*r;return j([U((t+n)*h),U((w-e)*h),"m",U((t+n)*h),U((w-(e-o))*h),U((t+i)*h),U((w-(e-r))*h),U(t*h),U((w-(e-r))*h),"c"].join(" ")),j([U((t-i)*h),U((w-(e-r))*h),U((t-n)*h),U((w-(e-o))*h),U((t-n)*h),U((w-e)*h),"c"].join(" ")),j([U((t-n)*h),U((w-(e+o))*h),U((t-i)*h),U((w-(e+r))*h),U(t*h),U((w-(e+r))*h),"c"].join(" ")),j([U((t+i)*h),U((w-(e+r))*h),U((t+n)*h),U((w-(e+o))*h),U((t+n)*h),U((w-e)*h),"c"].join(" ")),null!==s&&j(ce(s)),this},R.circle=function(t,e,n,r){return this.ellipse(t,e,n,n,r)},R.setProperties=function(t){for(var e in F)F.hasOwnProperty(e)&&t[e]&&(F[e]=t[e]);return this},R.setFontSize=function(t){return q=t,this},R.setFont=function(t,e){return d=ae(t,e),this},R.setFontStyle=R.setFontType=function(t){return d=ae(void 0,t),this},R.getFontList=function(){var t,e,n,r={};for(t in E)if(E.hasOwnProperty(t)){r[t]=n=[];for(e in E[t])E[t].hasOwnProperty(e)&&n.push(e)}return r},R.setLineWidth=function(t){return j((t*h).toFixed(2)+" w"),this},R.setDrawColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" G":U(t/255)+" G":void 0===r?"string"==typeof t?[t,e,n,"RG"].join(" "):[U(t/255),U(e/255),U(n/255),"RG"].join(" "):"string"==typeof t?[t,e,n,r,"K"].join(" "):[U(t),U(e),U(n),U(r),"K"].join(" "),j(s),this},R.setFillColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" g":U(t/255)+" g":void 0===r?"string"==typeof t?[t,e,n,"rg"].join(" "):[U(t/255),U(e/255),U(n/255),"rg"].join(" "):"string"==typeof t?[t,e,n,r,"k"].join(" "):[U(t),U(e),U(n),U(r),"k"].join(" "),j(s),this},R.setTextColor=function(t,e,n){if("string"==typeof t&&/^#[0-9A-Fa-f]{6}$/.test(t)){var r=parseInt(t.substr(1),16);t=r>>16&255,e=r>>8&255,n=255&r}return v=0===t&&0===e&&0===n||"undefined"==typeof e?N(t/255)+" g":[N(t/255),N(e/255),N(n/255),"rg"].join(" "),this},R.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},R.setLineCap=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line cap style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return B=e,j(e+" J"),this},R.setLineJoin=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line join style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return O=e,j(e+" j"),this},R.output=de,R.save=function(t){R.output("save",t)};for(var pe in n.API)n.API.hasOwnProperty(pe)&&("events"===pe&&n.API.events.length?!function(t,e){var n,r,s;for(s=e.length-1;-1!==s;s--)n=e[s][0],r=e[s][1],t.subscribe.apply(t,[n].concat("function"==typeof r?[r]:r))}(D,n.API.events):R[pe]=n.API[pe]);return $(),d="F1",oe(),D.publish("initialized"),R}var i="1.3",o={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};return n.API={events:[]},n.version="1.0.178-git 2014-06-27T15:34:diegocr","function"==typeof define&&define.amd?define(function(){return n}):t.jsPDF=n,n}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);!function(t){"use strict";t.addHTML=function(t,e,n,r,s){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof e&&(r=e,s=n),"function"==typeof r&&(s=r,r=null);var i=this.internal,o=i.scaleFactor,a=i.pageSize.width,u=i.pageSize.height;if(r=r||{},r.onrendered=function(t){e=parseInt(e)||0,n=parseInt(n)||0;var i=r.dim||{},c=i.h||0,l=i.w||Math.min(a,t.width/o)-e,f="JPEG";if(r.format&&(f=r.format),t.height>u&&r.pagesplit){var d=function(){for(var r=0;;){var i=document.createElement("canvas");i.width=Math.min(a*o,t.width),i.height=Math.min(u*o,t.height-r);var c=i.getContext("2d");c.drawImage(t,0,r,t.width,i.height,0,0,i.width,i.height);var d=[i,e,r?0:n,i.width/o,i.height/o,f,null,"SLOW"];if(this.addImage.apply(this,d),r+=i.height,r>=t.height)break;this.addPage()}s(l,r,null,d)}.bind(this);if("CANVAS"===t.nodeName){var h=new Image;h.onload=d,h.src=t.toDataURL("image/png"),t=h}else d()}else{var p=Math.random().toString(35),m=[t,e,n,l,c,f,p,"SLOW"];this.addImage.apply(this,m),s(l,c,p,m)}}.bind(this),"undefined"!=typeof html2canvas&&!r.rstz)return html2canvas(t,r);if("undefined"!=typeof rasterizeHTML){var c="drawDocument";return"string"==typeof t&&(c=/^http/.test(t)?"drawURL":"drawHTML"),r.width=r.width||a*o,rasterizeHTML[c](t,void 0,r).then(function(t){r.onrendered(t.image)},function(t){s(null,t)})}return null}}(n.API),function(t){"use strict";var e="addImage_",n=["jpeg","jpg","png"],r=function(t){var e=this.internal.newObject(),n=this.internal.write,s=this.internal.putStream;if(t.n=e,n("<</Type /XObject"),n("/Subtype /Image"),n("/Width "+t.w),n("/Height "+t.h),t.cs===this.color_spaces.INDEXED?n("/ColorSpace [/Indexed /DeviceRGB "+(t.pal.length/3-1)+" "+("smask"in t?e+2:e+1)+" 0 R]"):(n("/ColorSpace /"+t.cs),t.cs===this.color_spaces.DEVICE_CMYK&&n("/Decode [1 0 1 0 1 0 1 0]")),n("/BitsPerComponent "+t.bpc),"f"in t&&n("/Filter /"+t.f),"dp"in t&&n("/DecodeParms <<"+t.dp+">>"),"trns"in t&&t.trns.constructor==Array){for(var i="",o=0,a=t.trns.length;a>o;o++)i+=t.trns[o]+" "+t.trns[o]+" ";n("/Mask ["+i+"]")}if("smask"in t&&n("/SMask "+(e+1)+" 0 R"),n("/Length "+t.data.length+">>"),s(t.data),n("endobj"),"smask"in t){var u="/Predictor 15 /Colors 1 /BitsPerComponent "+t.bpc+" /Columns "+t.w,c={w:t.w,h:t.h,cs:"DeviceGray",bpc:t.bpc,dp:u,data:t.smask};"f"in t&&(c.f=t.f),r.call(this,c)}t.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),n("<< /Length "+t.pal.length+">>"),s(this.arrayBufferToBinaryString(new Uint8Array(t.pal))),n("endobj"))},s=function(){var t=this.internal.collections[e+"images"];for(var n in t)r.call(this,t[n])},i=function(){var t,n=this.internal.collections[e+"images"],r=this.internal.write;for(var s in n)t=n[s],r("/I"+t.i,t.n,"0","R")},o=function(e){return e&&"string"==typeof e&&(e=e.toUpperCase()),e in t.image_compression?e:t.image_compression.NONE},a=function(){var t=this.internal.collections[e+"images"];return t||(this.internal.collections[e+"images"]=t={},this.internal.events.subscribe("putResources",s),this.internal.events.subscribe("putXobjectDict",i)),t},u=function(t){var e=0;return t&&(e=Object.keys?Object.keys(t).length:function(t){var e=0;for(var n in t)t.hasOwnProperty(n)&&e++;return e}(t)),e},c=function(t){return"undefined"==typeof t||null===t},l=function(){return void 0},f=function(t){return-1===n.indexOf(t)},d=function(e){return"function"!=typeof t["process"+e.toUpperCase()]},h=function(t){return"object"==typeof t&&1===t.nodeType},p=function(t,e){if("IMG"===t.nodeName&&t.hasAttribute("src")&&0===(""+t.getAttribute("src")).indexOf("data:image/"))return t.getAttribute("src");if("CANVAS"===t.nodeName)var n=t;else{var n=document.createElement("canvas");n.width=t.clientWidth||t.width,n.height=t.clientHeight||t.height;var r=n.getContext("2d");if(!r)throw"addImage requires canvas to be supported by browser.";r.drawImage(t,0,0,n.width,n.height)}return n.toDataURL("png"==e?"image/png":"image/jpeg")},m=function(t,e){var n;if(e)for(var r in e)if(t===e[r].alias){n=e[r];break}return n},w=function(t,e,n){return t||e||(t=-96,e=-96),0>t&&(t=-1*n.w*72/t/this.internal.scaleFactor),0>e&&(e=-1*n.h*72/e/this.internal.scaleFactor),0===t&&(t=e*n.w/n.h),0===e&&(e=t*n.h/n.w),[t,e]},g=function(t,e,n,r,s,i,o){var a=w.call(this,n,r,s),u=this.internal.getCoordinateString,c=this.internal.getVerticalCoordinateString;n=a[0],r=a[1],o[i]=s,this.internal.write("q",u(n),"0 0",u(r),u(t),c(e+r),"cm /I"+s.i,"Do Q")};t.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPERATION:"Seperation",DEVICE_N:"DeviceN"},t.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},t.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},t.isString=function(t){return"string"==typeof t},t.extractInfoFromBase64DataURI=function(t){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(t)},t.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},t.isArrayBuffer=function(t){return this.supportsArrayBuffer()?t instanceof ArrayBuffer:!1},t.isArrayBufferView=function(t){return this.supportsArrayBuffer()?"undefined"==typeof Uint32Array?!1:t instanceof Int8Array||t instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array:!1},t.binaryStringToUint8Array=function(t){for(var e=t.length,n=new Uint8Array(e),r=0;e>r;r++)n[r]=t.charCodeAt(r);return n},t.arrayBufferToBinaryString=function(t){this.isArrayBuffer(t)&&(t=new Uint8Array(t));for(var e="",n=t.byteLength,r=0;n>r;r++)e+=String.fromCharCode(t[r]);return e},t.arrayBufferToBase64=function(t){for(var e,n,r,s,i,o="",a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=new Uint8Array(t),c=u.byteLength,l=c%3,f=c-l,d=0;f>d;d+=3)i=u[d]<<16|u[d+1]<<8|u[d+2],e=(16515072&i)>>18,n=(258048&i)>>12,r=(4032&i)>>6,s=63&i,o+=a[e]+a[n]+a[r]+a[s];return 1==l?(i=u[f],e=(252&i)>>2,n=(3&i)<<4,o+=a[e]+a[n]+"=="):2==l&&(i=u[f]<<8|u[f+1],e=(64512&i)>>10,n=(1008&i)>>4,r=(15&i)<<2,o+=a[e]+a[n]+a[r]+"="),o},t.createImageInfo=function(t,e,n,r,s,i,o,a,u,c,l,f){var d={alias:a,w:e,h:n,cs:r,bpc:s,i:o,data:t};return i&&(d.f=i),u&&(d.dp=u),c&&(d.trns=c),l&&(d.pal=l),f&&(d.smask=f),d},t.addImage=function(t,e,r,s,i,w,y,v){if("number"==typeof e){var b=w;w=i,i=s,s=r,r=e,e=b}var q,x,k=a.call(this);if(v=o(v),e=(e||"JPEG").toLowerCase(),c(y)&&(y=l(t)),h(t)&&(t=p(t,e)),this.isString(t)){var _=this.extractInfoFromBase64DataURI(t);_?(e=_[2],t=atob(_[3]),this.supportsArrayBuffer()&&(x=t,t=this.binaryStringToUint8Array(t))):255!==t.charCodeAt(0)&&(q=m(t,k))}if(f(e))throw new Error("addImage currently only supports formats "+n+", not '"+e+"'");if(d(e))throw new Error("please ensure that the plugin for '"+e+"' support is added");var A=u(k),C=q;if(C||(C=this["process"+e.toUpperCase()](t,A,y,v,x)),!C)throw new Error("An unkwown error occurred whilst processing the image");return g.call(this,r,s,i,w,C,A,k),this};var y=function(t){var e,n;if(255===!t.charCodeAt(0)||216===!t.charCodeAt(1)||255===!t.charCodeAt(2)||224===!t.charCodeAt(3)||!t.charCodeAt(6)==="J".charCodeAt(0)||!t.charCodeAt(7)==="F".charCodeAt(0)||!t.charCodeAt(8)==="I".charCodeAt(0)||!t.charCodeAt(9)==="F".charCodeAt(0)||0===!t.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var r=256*t.charCodeAt(4)+t.charCodeAt(5),s=4,i=t.length;i>s;){if(s+=r,255!==t.charCodeAt(s))throw new Error("getJpegSize could not find the size of the image");if(192===t.charCodeAt(s+1)||193===t.charCodeAt(s+1)||194===t.charCodeAt(s+1)||195===t.charCodeAt(s+1)||196===t.charCodeAt(s+1)||197===t.charCodeAt(s+1)||198===t.charCodeAt(s+1)||199===t.charCodeAt(s+1))return n=256*t.charCodeAt(s+5)+t.charCodeAt(s+6),e=256*t.charCodeAt(s+7)+t.charCodeAt(s+8),[e,n];s+=2,r=256*t.charCodeAt(s)+t.charCodeAt(s+1)}},v=function(t){var e=t[0]<<8|t[1];if(65496!==e)throw new Error("Supplied data is not a JPEG");for(var n,r,s,i=t.length,o=(t[4]<<8)+t[5],a=4;i>a;){if(a+=o,n=b(t,a),o=(n[2]<<8)+n[3],(192===n[1]||194===n[1])&&255===n[0]&&o>7)return n=b(t,a+5),r=(n[2]<<8)+n[3],s=(n[0]<<8)+n[1],{width:r,height:s};a+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")},b=function(t,e){return t.subarray(e,e+4)};t.processJPEG=function(t,e,n,r,s){var i,o=this.color_spaces.DEVICE_RGB,a=this.decode.DCT_DECODE,u=8;return this.isString(t)?(i=y(t),this.createImageInfo(t,i[0],i[1],o,u,a,e,n)):(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)?(i=v(t),t=s||this.arrayBufferToBinaryString(t),this.createImageInfo(t,i.width,i.height,o,u,a,e,n)):null)},t.processJPG=function(){return this.processJPEG.apply(this,arguments)}}(n.API),function(t){"use strict";t.autoPrint=function(){var t;return this.internal.events.subscribe("postPutResources",function(){t=this.internal.newObject(),this.internal.write("<< /S/Named /Type/Action /N/Print >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.write("/OpenAction "+t+" 0 R")}),this}}(n.API),function(t){"use strict";var e,n,r,s,i=3,o=13,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,c=function(t,e,n,r,s){a={x:t,y:e,w:n,h:r,ln:s}},l=function(){return a},f={left:0,top:0,bottom:0};t.setHeaderFunction=function(t){s=t},t.getTextDimensions=function(t){e=this.internal.getFont().fontName,n=this.table_font_size||this.internal.getFontSize(),r=this.internal.getFont().fontStyle;var s,i,o=19.049976/25.4;return i=document.createElement("font"),i.id="jsPDFCell",i.style.fontStyle=r,i.style.fontName=e,i.style.fontSize=n+"pt",i.innerText=t,document.body.appendChild(i),s={w:(i.offsetWidth+1)*o,h:(i.offsetHeight+1)*o},document.body.removeChild(i),s},t.cellAddPage=function(){var t=this.margins||f;this.addPage(),c(t.left,t.top,void 0,void 0),u+=1},t.cellInitialize=function(){a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1},t.cell=function(t,e,n,r,s,a,u){var d=l();if(void 0!==d.ln)if(d.ln===a)t=d.x+d.w,e=d.y;else{var h=this.margins||f;d.y+d.h+r+o>=this.internal.pageSize.height-h.bottom&&(this.cellAddPage(),this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(a,!0)),e=l().y+l().h}if(void 0!==s[0])if(this.printingHeaderRow?this.rect(t,e,n,r,"FD"):this.rect(t,e,n,r),"right"===u){if(s instanceof Array)for(var p=0;p<s.length;p++){var m=s[p],w=this.getStringUnitWidth(m)*this.internal.getFontSize();this.text(m,t+n-w-i,e+this.internal.getLineHeight()*(p+1))}}else this.text(s,t+i,e+this.internal.getLineHeight());return c(t,e,n,r,a),this},t.arrayMax=function(t,e){var n,r,s,i=t[0];for(n=0,r=t.length;r>n;n+=1)s=t[n],e?-1===e(i,s)&&(i=s):s>i&&(i=s);return i},t.table=function(e,n,r,s,i){if(!r)throw"No data for PDF table";var o,c,l,d,h,p,m,w,g,y,v=[],b=[],q={},x={},k=[],_=[],A=!1,C=!0,S=12,E=f;if(E.width=this.internal.pageSize.width,i&&(i.autoSize===!0&&(A=!0),i.printHeaders===!1&&(C=!1),i.fontSize&&(S=i.fontSize),i.margins&&(E=i.margins)),this.lnMod=0,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,this.printHeaders=C,this.margins=E,this.setFontSize(S),this.table_font_size=S,void 0===s||null===s)v=Object.keys(r[0]);else if(s[0]&&"string"!=typeof s[0]){var z=19.049976/25.4;for(c=0,l=s.length;l>c;c+=1)o=s[c],v.push(o.name),b.push(o.prompt),x[o.name]=o.width*z}else v=s;if(A)for(y=function(t){return t[o]},c=0,l=v.length;l>c;c+=1){for(o=v[c],q[o]=r.map(y),k.push(this.getTextDimensions(b[c]||o).w),p=q[o],m=0,d=p.length;d>m;m+=1)h=p[m],k.push(this.getTextDimensions(h).w);x[o]=t.arrayMax(k)}if(C){var T=this.calculateLineHeight(v,x,b.length?b:v);for(c=0,l=v.length;l>c;c+=1)o=v[c],_.push([e,n,x[o],T,String(b.length?b[c]:o)]);this.setTableHeaderRow(_),this.printHeaderRow(1,!1)}for(c=0,l=r.length;l>c;c+=1){var T;for(w=r[c],T=this.calculateLineHeight(v,x,w),m=0,g=v.length;g>m;m+=1)o=v[m],this.cell(e,n,x[o],T,w[o],c+2,o.align)}return this.lastCellPos=a,this.table_x=e,this.table_y=n,this},t.calculateLineHeight=function(t,e,n){for(var r,s=0,o=0;o<t.length;o++){r=t[o],n[r]=this.splitTextToSize(String(n[r]),e[r]-i);var a=this.internal.getLineHeight()*n[r].length+i;a>s&&(s=a)}return s},t.setTableHeaderRow=function(t){this.tableHeaderRow=t},t.printHeaderRow=function(t,e){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var n,r,i,o;if(this.printingHeaderRow=!0,void 0!==s){var a=s(this,u);c(a[0],a[1],a[2],a[3],-1)}this.setFontStyle("bold");var l=[];for(i=0,o=this.tableHeaderRow.length;o>i;i+=1)this.setFillColor(200,200,200),n=this.tableHeaderRow[i],e&&(n[1]=this.margins&&this.margins.top||0,l.push(n)),r=[].concat(n),this.cell.apply(this,r.concat(t));l.length>0&&this.setTableHeaderRow(l),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(n.API),function(t){var e,n,r,s,i,o,a,u,c,l,f,d,h,p,m,w,g,y,v;e=function(){function t(){}return function(e){return t.prototype=e,new t}}(),c=function(t){var e,n,r,s,i,o,a;for(n=0,r=t.length,e=void 0,s=!1,o=!1;!s&&n!==r;)e=t[n]=t[n].trimLeft(),e&&(s=!0),n++;for(n=r-1;r&&!o&&-1!==n;)e=t[n]=t[n].trimRight(),e&&(o=!0),n--;for(i=/\s+$/g,a=!0,n=0;n!==r;)e=t[n].replace(/\s+/g," "),a&&(e=e.trimLeft()),e&&(a=i.test(e)),t[n]=e,n++;return t},l=function(t,e,n,r){return this.pdf=t,this.x=e,this.y=n,this.settings=r,this.watchFunctions=[],this.init(),this},f=function(t){var e,n,s;for(e=void 0,s=t.split(","),n=s.shift();!e&&n;)e=r[n.trim().toLowerCase()],n=s.shift();return e},d=function(t){t="auto"===t?"0px":t,t.indexOf("em")>-1&&!isNaN(Number(t.replace("em","")))&&(t=18.719*Number(t.replace("em",""))+"px"),t.indexOf("pt")>-1&&!isNaN(Number(t.replace("pt","")))&&(t=1.333*Number(t.replace("pt",""))+"px");var e,n,r;return n=void 0,e=16,(r=h[t])?r:(r={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:t}],r!==n?h[t]=r/e:(r=parseFloat(t))?h[t]=r/e:(r=t.match(/([\d\.]+)(px)/),h[t]=3===r.length?parseFloat(r[1])/e:1))},u=function(t){var e,n,r;return r=function(t){var e;return e=function(t){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(t,null):t.currentStyle?t.currentStyle:t.style}(t),function(t){return t=t.replace(/-\D/g,function(t){return t.charAt(1).toUpperCase()}),e[t]}}(t),e={},n=void 0,e["font-family"]=f(r("font-family"))||"times",e["font-style"]=s[r("font-style")]||"normal",e["text-align"]=TextAlignMap[r("text-align")]||"left",n=i[r("font-weight")]||"normal","bold"===n&&(e["font-style"]="normal"===e["font-style"]?n:n+e["font-style"]),e["font-size"]=d(r("font-size"))||1,e["line-height"]=d(r("line-height"))||1,e.display="inline"===r("display")?"inline":"block","block"===e.display&&(e["margin-top"]=d(r("margin-top"))||0,e["margin-bottom"]=d(r("margin-bottom"))||0,e["padding-top"]=d(r("padding-top"))||0,e["padding-bottom"]=d(r("padding-bottom"))||0,e["margin-left"]=d(r("margin-left"))||0,e["margin-right"]=d(r("margin-right"))||0,e["padding-left"]=d(r("padding-left"))||0,e["padding-right"]=d(r("padding-right"))||0),e["float"]=o[r("cssFloat")]||"none",e.clear=a[r("clear")]||"none",e},p=function(t,e,n){var r,s,i,o,a;if(i=!1,s=void 0,o=void 0,a=void 0,r=n["#"+t.id])if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;if(r=n[t.nodeName],!i&&r)if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;return i},v=function(t,e){var n,r,s,i,o,a,u,c,l,f;for(n=[],r=[],s=0,f=t.rows[0].cells.length,c=t.clientWidth;f>s;)l=t.rows[0].cells[s],r[s]={name:l.textContent.toLowerCase().replace(/\s+/g,""),prompt:l.textContent.replace(/\r?\n/g,""),width:l.clientWidth/c*e.pdf.internal.pageSize.width},s++;for(s=1;s<t.rows.length;){for(a=t.rows[s],o={},i=0;i<a.cells.length;)o[r[i].name]=a.cells[i].textContent.replace(/\r?\n/g,""),i++;n.push(o),s++}return u={rows:n,headers:r}};var b={SCRIPT:1,STYLE:1,NOSCRIPT:1,OBJECT:1,EMBED:1,SELECT:1},q=1;n=function(t,e,r){var s,i,o,a,c,l,f,d,h;for(i=t.childNodes,s=void 0,o=u(t),c="block"===o.display,c&&(e.setBlockBoundary(),e.setBlockStyle(o)),f=19.049976/25.4,a=0,l=i.length;l>a;){if(s=i[a],"object"==typeof s){if(e.executeWatchFunctions(s),1===s.nodeType&&"HEADER"===s.nodeName){var w=s,g=e.pdf.margins_doc.top;e.pdf.internal.events.subscribe("addPage",function(){e.y=g,n(w,e,r),e.pdf.margins_doc.top=e.y+10,e.y+=10},!1)}if(8===s.nodeType&&"#comment"===s.nodeName)~s.textContent.indexOf("ADD_PAGE")&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top);else if(1!==s.nodeType||b[s.nodeName])if(3===s.nodeType){var y=s.nodeValue;if(s.nodeValue&&"LI"===s.parentNode.nodeName)if("OL"===s.parentNode.parentNode.nodeName)y=q++ +". "+y;else{var x=16*o["font-size"],k=2;x>20&&(k=3),h=function(t,e){this.pdf.circle(t,e,k,"FD")}}e.addText(y,o)}else"string"==typeof s&&e.addText(s,o);else if("IMG"===s.nodeName&&m[s.getAttribute("src")]){e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottom<e.y+s.height&&e.y>e.pdf.margins_doc.top&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top,e.executeWatchFunctions(s));var _=u(s),A=e.x;void 0!==_["float"]&&"right"===_["float"]&&(A+=e.settings.width-s.width),e.pdf.addImage(m[s.getAttribute("src")],A,e.y,s.width,s.height),void 0!==_["float"]?("right"===_["float"]||"left"===_["float"])&&(e.watchFunctions.push(function(t,n,r,s){return e.y>=n?(e.x+=t,e.settings.width+=r,!0):s&&1===s.nodeType&&!b[s.nodeName]&&e.x+s.width>e.pdf.margins_doc.left+e.pdf.margins_doc.width?(e.x+=t,e.y=n,e.settings.width+=r,!0):!1}.bind(this,"left"===_["float"]?-s.width:0,e.y+s.height,s.width)),e.watchFunctions.push(function(t,n,r){return e.y<t&&n===e.pdf.internal.getNumberOfPages()?1===r.nodeType&&"both"===u(r).clear?(e.y=t,!0):!1:!0}.bind(this,e.y+s.height,e.pdf.internal.getNumberOfPages())),e.settings.width-=s.width,"left"===_["float"]&&(e.x+=s.width)):e.y+=s.height}else if("TABLE"===s.nodeName)d=v(s,e),e.y+=10,e.pdf.table(e.x,e.y,d.rows,d.headers,{autoSize:!1,printHeaders:!0,margins:e.pdf.margins_doc}),e.y=e.pdf.lastCellPos.y+e.pdf.lastCellPos.h+20;else if("OL"===s.nodeName||"UL"===s.nodeName)q=1,p(s,e,r)||n(s,e,r),e.y+=10;
|
||
else if("LI"===s.nodeName){var C=e.x;e.x+="UL"===s.parentNode.nodeName?22:10,e.y+=3,p(s,e,r)||n(s,e,r),e.x=C}else p(s,e,r)||n(s,e,r)}a++}return c?e.setBlockBoundary(h):void 0},m={},w=function(t,e,n,r){function s(){e.pdf.internal.events.publish("imagesLoaded"),r()}function i(t,e,n){if(t){var r=new Image;++u,r.crossOrigin="",r.onerror=r.onload=function(){r.complete&&(0===r.src.indexOf("data:image/")&&(r.width=e||r.width||0,r.height=n||r.height||0),r.width+r.height&&(m[t]=m[t]||r)),--u||s()},r.src=t}}for(var o=t.getElementsByTagName("img"),a=o.length,u=0;a--;)i(o[a].getAttribute("src"),o[a].width,o[a].height);return u||s()},g=function(t,e,r,s){var i=t.getElementsByTagName("footer");if(i.length>0){i=i[0];var o=e.pdf.internal.write,a=e.y;e.pdf.internal.write=function(){},n(i,e,r);var u=Math.ceil(e.y-a)+5;e.y=a,e.pdf.internal.write=o,e.pdf.margins_doc.bottom+=u;for(var c=function(t){var s=void 0!==t?t.pageNumber:1,o=e.y;e.y=e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottom,e.pdf.margins_doc.bottom-=u;for(var a=i.getElementsByTagName("span"),c=0;c<a.length;++c)(" "+a[c].className+" ").replace(/[\n\t]/g," ").indexOf(" pageCounter ")>-1&&(a[c].innerHTML=s),(" "+a[c].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&(a[c].innerHTML="###jsPDFVarTotalPages###");n(i,e,r),e.pdf.margins_doc.bottom+=u,e.y=o},l=i.getElementsByTagName("span"),f=0;f<l.length;++f)(" "+l[f].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&e.pdf.internal.events.subscribe("htmlRenderingFinished",e.pdf.putTotalPages.bind(e.pdf,"###jsPDFVarTotalPages###"),!0);e.pdf.internal.events.subscribe("addPage",c,!1),c(),b.FOOTER=1}s()},y=function(t,e,r,s,i,o){if(!e)return!1;"string"==typeof e||e.parentNode||(e=""+e.innerHTML),"string"==typeof e&&(e=function(t){var e,n,r,s;return r="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),s="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",n=document.createElement("div"),n.style.cssText=s,n.innerHTML='<iframe style="height:1px;width:1px" name="'+r+'" />',document.body.appendChild(n),e=window.frames[r],e.document.body.innerHTML=t,e.document.body}(e.replace(/<\/?script[^>]*?>/gi,"")));var a=new l(t,r,s,i);return o=o||function(){},w.call(this,e,a,i.elementHandlers,function(){g.call(this,e,a,i.elementHandlers,function(){n(e,a,i.elementHandlers),a.pdf.internal.events.publish("htmlRenderingFinished"),o(a.dispose())})}),a.dispose()},l.prototype.init=function(){return this.paragraph={text:[],style:[]},this.pdf.internal.write("q")},l.prototype.dispose=function(){return this.pdf.internal.write("Q"),{x:this.x,y:this.y}},l.prototype.executeWatchFunctions=function(t){var e=!1,n=[];if(this.watchFunctions.length>0){for(var r=0;r<this.watchFunctions.length;++r)this.watchFunctions[r](t)===!0?e=!0:n.push(this.watchFunctions[r]);this.watchFunctions=n}return e},l.prototype.splitFragmentsIntoLines=function(t,n){var r,s,i,o,a,u,c,l,f,d,h,p,m,w,g;for(s=12,h=this.pdf.internal.scaleFactor,a={},i=void 0,d=void 0,o=void 0,u=void 0,g=void 0,f=void 0,l=void 0,c=void 0,p=[],m=[p],r=0,w=this.settings.width;t.length;)if(u=t.shift(),g=n.shift(),u)if(i=g["font-family"],d=g["font-style"],o=a[i+d],o||(o=this.pdf.internal.getFont(i,d).metadata.Unicode,a[i+d]=o),f={widths:o.widths,kerning:o.kerning,fontSize:g["font-size"]*s,textIndent:r},l=this.pdf.getStringUnitWidth(u,f)*f.fontSize/h,r+l>w){for(c=this.pdf.splitTextToSize(u,w,f),p.push([c.shift(),g]);c.length;)p=[[c.shift(),g]],m.push(p);r=this.pdf.getStringUnitWidth(p[0][0],f)*f.fontSize/h}else p.push([u,g]),r+=l;if(void 0!==g["text-align"]&&("center"===g["text-align"]||"right"===g["text-align"]||"justify"===g["text-align"]))for(var y=0;y<m.length;++y){var v=this.pdf.getStringUnitWidth(m[y][0][0],f)*f.fontSize/h;y>0&&(m[y][0][1]=e(m[y][0][1]));var b=w-v;if("right"===g["text-align"])m[y][0][1]["margin-left"]=b;else if("center"===g["text-align"])m[y][0][1]["margin-left"]=b/2;else if("justify"===g["text-align"]){var q=m[y][0][0].split(" ").length-1;m[y][0][1]["word-spacing"]=b/q,y===m.length-1&&(m[y][0][1]["word-spacing"]=0)}}return m},l.prototype.RenderTextFragment=function(t,e){var n,r,s;s=0,n=12,this.pdf.internal.pageSize.height-this.pdf.margins_doc.bottom<this.y+this.pdf.internal.getFontSize()&&(this.pdf.internal.write("ET","Q"),this.pdf.addPage(),this.y=this.pdf.margins_doc.top,this.pdf.internal.write("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td"),s=Math.max(s,e["line-height"],e["font-size"]),this.pdf.internal.write(0,(-1*n*s).toFixed(2),"Td")),r=this.pdf.internal.getFont(e["font-family"],e["font-style"]),void 0!==e["word-spacing"]&&e["word-spacing"]>0&&this.pdf.internal.write(e["word-spacing"].toFixed(2),"Tw"),this.pdf.internal.write("/"+r.id,(n*e["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(t)+") Tj"),void 0!==e["word-spacing"]&&this.pdf.internal.write(0,"Tw")},l.prototype.renderParagraph=function(t){var e,n,r,s,i,o,a,u,l,f,d,h,p,m,w;if(s=c(this.paragraph.text),m=this.paragraph.style,e=this.paragraph.blockstyle,p=this.paragraph.blockstyle||{},this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:e},s.join("").trim()){u=this.splitFragmentsIntoLines(s,m),a=void 0,l=void 0,n=12,r=n/this.pdf.internal.scaleFactor,h=(Math.max((e["margin-top"]||0)-(p["margin-bottom"]||0),0)+(e["padding-top"]||0))*r,d=((e["margin-bottom"]||0)+(e["padding-bottom"]||0))*r,f=this.pdf.internal.write,i=void 0,o=void 0,this.y+=h,f("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");for(var g=0;u.length;){for(a=u.shift(),l=0,i=0,o=a.length;i!==o;)a[i][0].trim()&&(l=Math.max(l,a[i][1]["line-height"],a[i][1]["font-size"]),w=7*a[i][1]["font-size"]),i++;var y=0;for(void 0!==a[0][1]["margin-left"]&&a[0][1]["margin-left"]>0&&(wantedIndent=this.pdf.internal.getCoordinateString(a[0][1]["margin-left"]),y=wantedIndent-g,g=wantedIndent),f(y,(-1*n*l).toFixed(2),"Td"),i=0,o=a.length;i!==o;)a[i][0]&&this.RenderTextFragment(a[i][0],a[i][1]),i++;if(this.y+=l*r,this.executeWatchFunctions(a[0][1])&&u.length>0){var v=[],b=[];u.forEach(function(t){for(var e=0,n=t.length;e!==n;)t[e][0]&&(v.push(t[e][0]+" "),b.push(t[e][1])),++e}),u=this.splitFragmentsIntoLines(c(v),b),f("ET","Q"),f("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td")}}return t&&"function"==typeof t&&t.call(this,this.x-9,this.y-w/2),f("ET","Q"),this.y+=d}},l.prototype.setBlockBoundary=function(t){return this.renderParagraph(t)},l.prototype.setBlockStyle=function(t){return this.paragraph.blockstyle=t},l.prototype.addText=function(t,e){return this.paragraph.text.push(t),this.paragraph.style.push(e)},r={helvetica:"helvetica","sans-serif":"helvetica","times new roman":"times",serif:"times",times:"times",monospace:"courier",courier:"courier"},i={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},s={normal:"normal",italic:"italic",oblique:"italic"},TextAlignMap={left:"left",right:"right",center:"center",justify:"justify"},o={none:"none",right:"right",left:"left"},a={none:"none",both:"both"},h={normal:1},t.fromHTML=function(t,e,n,r,s,i){"use strict";return this.margins_doc=i||{top:0,bottom:0},r||(r={}),r.elementHandlers||(r.elementHandlers={}),y(this,t,isNaN(e)?4:e,isNaN(n)?4:n,r,s)}}(n.API),function(t){"use strict";var e,n,r;t.addJS=function(t){return r=t,this.internal.events.subscribe("postPutResources",function(){e=this.internal.newObject(),this.internal.write("<< /Names [(EmbeddedJS) "+(e+1)+" 0 R] >>","endobj"),n=this.internal.newObject(),this.internal.write("<< /S /JavaScript /JS (",r,") >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){void 0!==e&&void 0!==n&&this.internal.write("/Names <</JavaScript "+e+" 0 R>>")}),this}}(n.API),function(t){"use strict";var e=function(){return"function"!=typeof PNG||"function"!=typeof o},n=function(e){return e!==t.image_compression.NONE&&r()},r=function(){var t="function"==typeof s;if(!t)throw new Error("requires deflate.js for compression");return t},i=function(e,n,r,i){var o=5,l=d;switch(i){case t.image_compression.FAST:o=3,l=f;break;case t.image_compression.MEDIUM:o=6,l=h;break;case t.image_compression.SLOW:o=9,l=p}e=c(e,n,r,l);var m=new Uint8Array(a(o)),w=u(e),g=new s(o),y=g.append(e),v=g.flush(),b=m.length+y.length+v.length,q=new Uint8Array(b+4);return q.set(m),q.set(y,m.length),q.set(v,m.length+y.length),q[b++]=w>>>24&255,q[b++]=w>>>16&255,q[b++]=w>>>8&255,q[b++]=255&w,t.arrayBufferToBinaryString(q)},a=function(t,e){var n=8,r=Math.LOG2E*Math.log(32768)-8,s=r<<4|n,i=s<<8,o=Math.min(3,(e-1&255)>>1);return i|=o<<6,i|=0,i+=31-i%31,[s,255&i&255]},u=function(t,e){for(var n,r=1,s=65535&r,i=r>>>16&65535,o=t.length,a=0;o>0;){n=o>e?e:o,o-=n;do s+=t[a++],i+=s;while(--n);s%=65521,i%=65521}return(i<<16|s)>>>0},c=function(t,e,n,r){for(var s,i,o,a=t.length/e,u=new Uint8Array(t.length+a),c=w(),l=0;a>l;l++){if(o=l*e,s=t.subarray(o,o+e),r)u.set(r(s,n,i),o+l);else{for(var f=0,d=c.length,h=[];d>f;f++)h[f]=c[f](s,n,i);var p=g(h.concat());u.set(h[p],o+l)}i=s}return u},l=function(t){var e=Array.apply([],t);return e.unshift(0),e},f=function(t,e){var n,r=[],s=0,i=t.length;for(r[0]=1;i>s;s++)n=t[s-e]||0,r[s+1]=t[s]-n+256&255;return r},d=function(t,e,n){var r,s=[],i=0,o=t.length;for(s[0]=2;o>i;i++)r=n&&n[i]||0,s[i+1]=t[i]-r+256&255;return s},h=function(t,e,n){var r,s,i=[],o=0,a=t.length;for(i[0]=3;a>o;o++)r=t[o-e]||0,s=n&&n[o]||0,i[o+1]=t[o]+256-(r+s>>>1)&255;return i},p=function(t,e,n){var r,s,i,o,a=[],u=0,c=t.length;for(a[0]=4;c>u;u++)r=t[u-e]||0,s=n&&n[u]||0,i=n&&n[u-e]||0,o=m(r,s,i),a[u+1]=t[u]-o+256&255;return a},m=function(t,e,n){var r=t+e-n,s=Math.abs(r-t),i=Math.abs(r-e),o=Math.abs(r-n);return i>=s&&o>=s?t:o>=i?e:n},w=function(){return[l,f,d,h,p]},g=function(t){for(var e,n,r,s=0,i=t.length;i>s;)e=y(t[s].slice(1)),(n>e||!n)&&(n=e,r=s),s++;return r},y=function(t){for(var e=0,n=t.length,r=0;n>e;)r+=Math.abs(t[e++]);return r};t.processPNG=function(t,r,s,o){var a,u,c,l,f,d,h=this.color_spaces.DEVICE_RGB,p=this.decode.FLATE_DECODE,m=8;if(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)){if(e())throw new Error("PNG support requires png.js and zlib.js");if(a=new PNG(t),t=a.imgData,m=a.bits,h=a.colorSpace,l=a.colors,-1!==[4,6].indexOf(a.colorType)){if(8===a.bits)for(var w,g,y=window["Uint"+a.pixelBitlength+"Array"],v=new y(a.decodePixels().buffer),b=v.length,q=new Uint8Array(b*a.colors),x=new Uint8Array(b),k=a.pixelBitlength-a.bits,_=0,A=0;b>_;_++){for(w=v[_],g=0;k>g;)q[A++]=w>>>g&255,g+=a.bits;x[_]=w>>>g&255}if(16===a.bits){for(var w,v=new Uint32Array(a.decodePixels().buffer),b=v.length,q=new Uint8Array(b*(32/a.pixelBitlength)*a.colors),x=new Uint8Array(b*(32/a.pixelBitlength)),C=a.colors>1,_=0,A=0,S=0;b>_;)w=v[_++],q[A++]=w>>>0&255,C&&(q[A++]=w>>>16&255,w=v[_++],q[A++]=w>>>0&255),x[S++]=w>>>16&255;m=8}n(o)?(t=i(q,a.width*a.colors,a.colors,o),d=i(x,a.width,1,o)):(t=q,d=x,p=null)}if(3===a.colorType&&(h=this.color_spaces.INDEXED,f=a.palette,a.transparency.indexed)){for(var E=a.transparency.indexed,z=0,_=0,b=E.length;b>_;++_)z+=E[_];if(z/=255,z===b-1&&-1!==E.indexOf(0))c=[E.indexOf(0)];else if(z!==b){for(var v=a.decodePixels(),x=new Uint8Array(v.length),_=0,b=v.length;b>_;_++)x[_]=E[v[_]];d=i(x,a.width,1)}}return u=p===this.decode.FLATE_DECODE?"/Predictor 15 /Colors "+l+" /BitsPerComponent "+m+" /Columns "+a.width:"/Colors "+l+" /BitsPerComponent "+m+" /Columns "+a.width,(this.isArrayBuffer(t)||this.isArrayBufferView(t))&&(t=this.arrayBufferToBinaryString(t)),(d&&this.isArrayBuffer(d)||this.isArrayBufferView(d))&&(d=this.arrayBufferToBinaryString(d)),this.createImageInfo(t,a.width,a.height,h,m,p,r,s,u,c,f,d)}throw new Error("Unsupported PNG image data, try using JPEG instead.")}}(n.API),function(t){"use strict";t.addSVG=function(t,e,n,r,s){function i(t,e){var n=e.createElement("style");n.type="text/css",n.styleSheet?n.styleSheet.cssText=t:n.appendChild(e.createTextNode(t)),e.getElementsByTagName("head")[0].appendChild(n)}function o(t){var e="childframe",n=t.createElement("iframe");return i(".jsPDF_sillysvg_iframe {display:none;position:absolute;}",t),n.name=e,n.setAttribute("width",0),n.setAttribute("height",0),n.setAttribute("frameborder","0"),n.setAttribute("scrolling","no"),n.setAttribute("seamless","seamless"),n.setAttribute("class","jsPDF_sillysvg_iframe"),t.body.appendChild(n),n}function a(t,e){var n=(e.contentWindow||e.contentDocument).document;return n.write(t),n.close(),n.getElementsByTagName("svg")[0]}function u(t){for(var e=parseFloat(t[1]),n=parseFloat(t[2]),r=[],s=3,i=t.length;i>s;)"c"===t[s]?(r.push([parseFloat(t[s+1]),parseFloat(t[s+2]),parseFloat(t[s+3]),parseFloat(t[s+4]),parseFloat(t[s+5]),parseFloat(t[s+6])]),s+=7):"l"===t[s]?(r.push([parseFloat(t[s+1]),parseFloat(t[s+2])]),s+=3):s+=1;return[e,n,r]}var c;if(e===c||n===c)throw new Error("addSVG needs values for 'x' and 'y'");var l=o(document),f=a(t,l),d=[1,1],h=parseFloat(f.getAttribute("width")),p=parseFloat(f.getAttribute("height"));h&&p&&(r&&s?d=[r/h,s/p]:r?d=[r/h,r/h]:s&&(d=[s/p,s/p]));var m,w,g,y,v=f.childNodes;for(m=0,w=v.length;w>m;m++)g=v[m],g.tagName&&"PATH"===g.tagName.toUpperCase()&&(y=u(g.getAttribute("d").split(" ")),y[0]=y[0]*d[0]+e,y[1]=y[1]*d[1]+n,this.lines.call(this,y[2],y[0],y[1],d));return this}}(n.API),function(t){"use strict";var e=t.getCharWidthsArray=function(t,e){e||(e={});var n,r,s,i=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,o=i.fof?i.fof:1,a=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,u=a.fof?a.fof:1,c=0,l=i[0]||o,f=[];for(n=0,r=t.length;r>n;n++)s=t.charCodeAt(n),f.push((i[s]||l)/o+(a[s]&&a[s][c]||0)/u),c=s;return f},n=function(t){for(var e=t.length,n=0;e;)e--,n+=t[e];return n},r=t.getStringUnitWidth=function(t,r){return n(e.call(this,t,r))},s=function(t,e,n,r){for(var s=[],i=0,o=t.length,a=0;i!==o&&a+e[i]<n;)a+=e[i],i++;s.push(t.slice(0,i));var u=i;for(a=0;i!==o;)a+e[i]>r&&(s.push(t.slice(u,i)),a=0,u=i),a+=e[i],i++;return u!==i&&s.push(t.slice(u,i)),s},i=function(t,i,o){o||(o={});var a,u,c,l,f,d,h=[],p=[h],m=o.textIndent||0,w=0,g=0,y=t.split(" "),v=e(" ",o)[0];if(d=-1===o.lineIndent?y[0].length+2:o.lineIndent||0){var b=Array(d).join(" "),q=[];y.map(function(t){t=t.split(/\s*\n/),t.length>1?q=q.concat(t.map(function(t,e){return(e&&t.length?"\n":"")+t})):q.push(t[0])}),y=q,d=r(b,o)}for(c=0,l=y.length;l>c;c++){var x=0;if(a=y[c],d&&"\n"==a[0]&&(a=a.substr(1),x=1),u=e(a,o),g=n(u),m+w+g>i||x){if(g>i){for(f=s(a,u,i-(m+w),i),h.push(f.shift()),h=[f.pop()];f.length;)p.push([f.shift()]);g=n(u.slice(a.length-h[0].length))}else h=[a];p.push(h),m=g+d,w=v}else h.push(a),m+=w+g,w=v}if(d)var k=function(t,e){return(e?b:"")+t.join(" ")};else var k=function(t){return t.join(" ")};return p.map(k)};t.splitTextToSize=function(t,e,n){n||(n={});var r,s=n.fontSize||this.internal.getFontSize(),o=function(t){var e={0:1},n={};if(t.widths&&t.kerning)return{widths:t.widths,kerning:t.kerning};var r=this.internal.getFont(t.fontName,t.fontStyle),s="Unicode";return r.metadata[s]?{widths:r.metadata[s].widths||e,kerning:r.metadata[s].kerning||n}:{widths:e,kerning:n}}.call(this,n);r=Array.isArray(t)?t:t.split(/\r?\n/);var a=1*this.internal.scaleFactor*e/s;o.textIndent=n.textIndent?1*n.textIndent*this.internal.scaleFactor/s:0,o.lineIndent=n.lineIndent;var u,c,l=[];for(u=0,c=r.length;c>u;u++)l=l.concat(i(r[u],a,o));return l}}(n.API),function(t){"use strict";var e=function(t){for(var e="0123456789abcdef",n="klmnopqrstuvwxyz",r={},s=0;s<n.length;s++)r[n[s]]=e[s];var i,o,a,u,c,l={},f=1,d=l,h=[],p="",m="",w=t.length-1;for(s=1;s!=w;)c=t[s],s+=1,"'"==c?o?(u=o.join(""),o=i):o=[]:o?o.push(c):"{"==c?(h.push([d,u]),d={},u=i):"}"==c?(a=h.pop(),a[0][a[1]]=d,u=i,d=a[0]):"-"==c?f=-1:u===i?r.hasOwnProperty(c)?(p+=r[c],u=parseInt(p,16)*f,f=1,p=""):p+=c:r.hasOwnProperty(c)?(m+=r[c],d[u]=parseInt(m,16)*f,f=1,u=i,m=""):m+=c;return l},n={codePages:["WinAnsiEncoding"],WinAnsiEncoding:e("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},r={Unicode:{Courier:n,"Courier-Bold":n,"Courier-BoldOblique":n,"Courier-Oblique":n,Helvetica:n,"Helvetica-Bold":n,"Helvetica-BoldOblique":n,"Helvetica-Oblique":n,"Times-Roman":n,"Times-Bold":n,"Times-BoldItalic":n,"Times-Italic":n}},s={Unicode:{"Courier-Oblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":e("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":e("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Helvetica:e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),"Courier-Bold":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":e("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":e("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};t.events.push(["addFonts",function(t){var e,n,i,o,a,u="Unicode";for(n in t.fonts)t.fonts.hasOwnProperty(n)&&(e=t.fonts[n],i=s[u][e.PostScriptName],i&&(o=e.metadata[u]?e.metadata[u]:e.metadata[u]={},o.widths=i.widths,o.kerning=i.kerning),a=r[u][e.PostScriptName],a&&(o=e.metadata[u]?e.metadata[u]:e.metadata[u]={},o.encoding=a,a.codePages&&a.codePages.length&&(e.encoding=a.codePages[0])))}])}(n.API),function(t){"use strict";t.putTotalPages=function(t){for(var e=new RegExp(t,"g"),n=1;n<=this.internal.getNumberOfPages();n++)for(var r=0;r<this.internal.pages[n].length;r++)this.internal.pages[n][r]=this.internal.pages[n][r].replace(e,this.internal.getNumberOfPages());return this}}(n.API),function(t){"use strict";if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return new Blob,void 0}catch(e){}var n=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},n=function(){this.data=[]
|
||
},r=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},s=n.prototype,i=r.prototype,o=t.FileReaderSync,a=function(t){this.code=this[this.name=t]},u="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),c=u.length,l=t.URL||t.webkitURL||t,f=l.createObjectURL,d=l.revokeObjectURL,h=l,p=t.btoa,m=t.atob,w=t.ArrayBuffer,g=t.Uint8Array;for(r.fake=i.fake=!0;c--;)a.prototype[u[c]]=c+1;return l.createObjectURL||(h=t.URL={}),h.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof r?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):f?f.call(l,t):void 0},h.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&d&&d.call(l,t)},s.append=function(t){var n=this.data;if(g&&(t instanceof w||t instanceof g)){for(var s="",i=new g(t),u=0,c=i.length;c>u;u++)s+=String.fromCharCode(i[u]);n.push(s)}else if("Blob"===e(t)||"File"===e(t)){if(!o)throw new a("NOT_READABLE_ERR");var l=new o;n.push(l.readAsBinaryString(t))}else t instanceof r?"base64"===t.encoding&&m?n.push(m(t.data)):"URI"===t.encoding?n.push(decodeURIComponent(t.data)):"raw"===t.encoding&&n.push(t.data):("string"!=typeof t&&(t+=""),n.push(unescape(encodeURIComponent(t))))},s.getBlob=function(t){return arguments.length||(t=null),new r(this.data.join(""),t,"raw")},s.toString=function(){return"[object BlobBuilder]"},i.slice=function(t,e,n){var s=arguments.length;return 3>s&&(n=null),new r(this.data.slice(t,s>1?e:this.data.length),n,this.encoding)},i.toString=function(){return"[object Blob]"},i.close=function(){this.size=0,delete this.data},n}(t);t.Blob=function(t,e){var r=e?e.type||"":"",s=new n;if(t)for(var i=0,o=t.length;o>i;i++)s.append(t[i]);return s.getBlob(r)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this);var r=r||"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(t){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var e=t.document,n=function(){return t.URL||t.webkitURL||t},r=e.createElementNS("http://www.w3.org/1999/xhtml","a"),s=!t.externalHost&&"download"in r,i=function(n){var r=e.createEvent("MouseEvents");r.initMouseEvent("click",!0,!1,t,0,0,0,0,0,!1,!1,!1,!1,0,null),n.dispatchEvent(r)},o=t.webkitRequestFileSystem,a=t.requestFileSystem||o||t.mozRequestFileSystem,u=function(e){(t.setImmediate||t.setTimeout)(function(){throw e},0)},c="application/octet-stream",l=0,f=[],d=function(){for(var t=f.length;t--;){var e=f[t];"string"==typeof e?n().revokeObjectURL(e):e.remove()}f.length=0},h=function(t,e,n){e=[].concat(e);for(var r=e.length;r--;){var s=t["on"+e[r]];if("function"==typeof s)try{s.call(t,n||t)}catch(i){u(i)}}},p=function(e,u){var d,p,m,w=this,g=e.type,y=!1,v=function(){var t=n().createObjectURL(e);return f.push(t),t},b=function(){h(w,"writestart progress write writeend".split(" "))},q=function(){(y||!d)&&(d=v(e)),p?p.location.href=d:window.open(d,"_blank"),w.readyState=w.DONE,b()},x=function(t){return function(){return w.readyState!==w.DONE?t.apply(this,arguments):void 0}},k={create:!0,exclusive:!1};return w.readyState=w.INIT,u||(u="download"),s?(d=v(e),r.href=d,r.download=u,i(r),w.readyState=w.DONE,b(),void 0):(t.chrome&&g&&g!==c&&(m=e.slice||e.webkitSlice,e=m.call(e,0,e.size,c),y=!0),o&&"download"!==u&&(u+=".download"),(g===c||o)&&(p=t),a?(l+=e.size,a(t.TEMPORARY,l,x(function(t){t.root.getDirectory("saved",k,x(function(t){var n=function(){t.getFile(u,k,x(function(t){t.createWriter(x(function(n){n.onwriteend=function(e){p.location.href=t.toURL(),f.push(t),w.readyState=w.DONE,h(w,"writeend",e)},n.onerror=function(){var t=n.error;t.code!==t.ABORT_ERR&&q()},"writestart progress write abort".split(" ").forEach(function(t){n["on"+t]=w["on"+t]}),n.write(e),w.abort=function(){n.abort(),w.readyState=w.DONE},w.readyState=w.WRITING}),q)}),q)};t.getFile(u,{create:!1},x(function(t){t.remove(),n()}),x(function(t){t.code===t.NOT_FOUND_ERR?n():q()}))}),q)}),q),void 0):(q(),void 0))},m=p.prototype,w=function(t,e){return new p(t,e)};return m.abort=function(){var t=this;t.readyState=t.DONE,h(t,"abort")},m.readyState=m.INIT=0,m.WRITING=1,m.DONE=2,m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null,t.addEventListener("unload",d,!1),w.unload=function(){d(),t.removeEventListener("unload",d,!1)},w}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&null!==module&&(module.exports=r),void function(t,e){"object"==typeof module?module.exports=e():t.adler32cs=e()}(n,function(){var t="function"==typeof ArrayBuffer&&"function"==typeof Uint8Array,e=null,n=function(){if(!t)return function(){return!1};try{var n=require("buffer");"function"==typeof n.Buffer&&(e=n.Buffer)}catch(r){}return function(t){return t instanceof ArrayBuffer||null!==e&&t instanceof e}}(),r=function(){return null!==e?function(t){return new e(t,"utf8").toString("binary")}:function(t){return unescape(encodeURIComponent(t))}}(),s=65521,i=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;o>i;i++)n=(n+(255&e.charCodeAt(i)))%s,r=(r+n)%s;return(r<<16|n)>>>0},o=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;o>i;i++)n=(n+e[i])%s,r=(r+n)%s;return(r<<16|n)>>>0},a={},u=a.Adler32=function(){var e=function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(t=null==t?1:+t))throw new Error("First arguments needs to be a finite number.");this.checksum=t>>>0},s=e.prototype={};return s.constructor=e,e.from=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");this.checksum=i(1,t.toString())}),e.fromUtf8=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");var n=r(t.toString());this.checksum=i(1,n)}),t&&(e.fromBuffer=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!n(t))throw new Error("First argument needs to be ArrayBuffer.");var r=new Uint8Array(t);return this.checksum=o(1,r)})),s.update=function(t){if(null==t)throw new Error("First argument needs to be a string.");return t=t.toString(),this.checksum=i(this.checksum,t)},s.updateUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=r(t.toString());return this.checksum=i(this.checksum,e)},t&&(s.updateBuffer=function(t){if(!n(t))throw new Error("First argument needs to be ArrayBuffer.");var e=new Uint8Array(t);return this.checksum=o(this.checksum,e)}),s.clone=function(){return new u(this.checksum)},e}();return a.from=function(t){if(null==t)throw new Error("First argument needs to be a string.");return i(1,t.toString())},a.fromUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=r(t.toString());return i(1,e)},t&&(a.fromBuffer=function(t){if(!n(t))throw new Error("First argument need to be ArrayBuffer.");var e=new Uint8Array(t);return o(1,e)}),a});var s=function(){function t(){function t(t){var e,n,s,i,a,u,c=r.dyn_tree,l=r.stat_desc.static_tree,f=r.stat_desc.extra_bits,h=r.stat_desc.extra_base,p=r.stat_desc.max_length,m=0;for(i=0;o>=i;i++)t.bl_count[i]=0;for(c[2*t.heap[t.heap_max]+1]=0,e=t.heap_max+1;d>e;e++)n=t.heap[e],i=c[2*c[2*n+1]+1]+1,i>p&&(i=p,m++),c[2*n+1]=i,n>r.max_code||(t.bl_count[i]++,a=0,n>=h&&(a=f[n-h]),u=c[2*n],t.opt_len+=u*(i+a),l&&(t.static_len+=u*(l[2*n+1]+a)));if(0!==m){do{for(i=p-1;0===t.bl_count[i];)i--;t.bl_count[i]--,t.bl_count[i+1]+=2,t.bl_count[p]--,m-=2}while(m>0);for(i=p;0!==i;i--)for(n=t.bl_count[i];0!==n;)s=t.heap[--e],s>r.max_code||(c[2*s+1]!=i&&(t.opt_len+=(i-c[2*s+1])*c[2*s],c[2*s+1]=i),n--)}}function e(t,e){var n=0;do n|=1&t,t>>>=1,n<<=1;while(--e>0);return n>>>1}function n(t,n,r){var s,i,a,u=[],c=0;for(s=1;o>=s;s++)u[s]=c=c+r[s-1]<<1;for(i=0;n>=i;i++)a=t[2*i+1],0!==a&&(t[2*i]=e(u[a]++,a))}var r=this;r.build_tree=function(e){var s,i,o,a=r.dyn_tree,u=r.stat_desc.static_tree,c=r.stat_desc.elems,l=-1;for(e.heap_len=0,e.heap_max=d,s=0;c>s;s++)0!==a[2*s]?(e.heap[++e.heap_len]=l=s,e.depth[s]=0):a[2*s+1]=0;for(;e.heap_len<2;)o=e.heap[++e.heap_len]=2>l?++l:0,a[2*o]=1,e.depth[o]=0,e.opt_len--,u&&(e.static_len-=u[2*o+1]);for(r.max_code=l,s=Math.floor(e.heap_len/2);s>=1;s--)e.pqdownheap(a,s);o=c;do s=e.heap[1],e.heap[1]=e.heap[e.heap_len--],e.pqdownheap(a,1),i=e.heap[1],e.heap[--e.heap_max]=s,e.heap[--e.heap_max]=i,a[2*o]=a[2*s]+a[2*i],e.depth[o]=Math.max(e.depth[s],e.depth[i])+1,a[2*s+1]=a[2*i+1]=o,e.heap[1]=o++,e.pqdownheap(a,1);while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],t(e),n(a,r.max_code,e.bl_count)}}function e(t,e,n,r,s){var i=this;i.static_tree=t,i.extra_bits=e,i.extra_base=n,i.elems=r,i.max_length=s}function n(t,e,n,r,s){var i=this;i.good_length=t,i.max_lazy=e,i.nice_length=n,i.max_chain=r,i.func=s}function r(t,e,n,r){var s=t[2*e],i=t[2*n];return i>s||s==i&&r[e]<=r[n]}function s(){function n(){var t;for(Te=2*Ce,Be[Pe-1]=0,t=0;Pe-1>t;t++)Be[t]=0;Ve=N[Xe].max_lazy,Ke=N[Xe].good_length,Qe=N[Xe].nice_length,Je=N[Xe].max_chain,Me=0,Ue=0,Ge=0,Ne=We=Z-1,je=0,Oe=0}function s(){var t;for(t=0;f>t;t++)$e[2*t]=0;for(t=0;a>t;t++)Ze[2*t]=0;for(t=0;u>t;t++)tn[2*t]=0;$e[2*h]=1,en.opt_len=en.static_len=0,un=ln=0}function i(){nn.dyn_tree=$e,nn.stat_desc=e.static_l_desc,rn.dyn_tree=Ze,rn.stat_desc=e.static_d_desc,sn.dyn_tree=tn,sn.stat_desc=e.static_bl_desc,dn=0,hn=0,fn=8,s()}function o(t,e){var n,r,s=-1,i=t[1],o=0,a=7,u=4;for(0===i&&(a=138,u=3),t[2*(e+1)+1]=65535,n=0;e>=n;n++)r=i,i=t[2*(n+1)+1],++o<a&&r==i||(u>o?tn[2*r]+=o:0!==r?(r!=s&&tn[2*r]++,tn[2*m]++):10>=o?tn[2*w]++:tn[2*g]++,o=0,s=r,0===i?(a=138,u=3):r==i?(a=6,u=3):(a=7,u=4))}function c(){var e;for(o($e,nn.max_code),o(Ze,rn.max_code),sn.build_tree(en),e=u-1;e>=3&&0===tn[2*t.bl_order[e]+1];e--);return en.opt_len+=3*(e+1)+5+5+4,e}function d(t){en.pending_buf[en.pending++]=t}function p(t){d(255&t),d(t>>>8&255)}function O(t){d(t>>8&255),d(255&t&255)}function ne(t,e){var n,r=e;hn>y-r?(n=t,dn|=n<<hn&65535,p(dn),dn=n>>>y-hn,hn+=r-y):(dn|=t<<hn&65535,hn+=r)}function re(t,e){var n=2*t;ne(65535&e[n],65535&e[n+1])}function se(t,e){var n,r,s=-1,i=t[1],o=0,a=7,u=4;for(0===i&&(a=138,u=3),n=0;e>=n;n++)if(r=i,i=t[2*(n+1)+1],!(++o<a&&r==i)){if(u>o){do re(r,tn);while(0!==--o)}else 0!==r?(r!=s&&(re(r,tn),o--),re(m,tn),ne(o-3,2)):10>=o?(re(w,tn),ne(o-3,3)):(re(g,tn),ne(o-11,7));o=0,s=r,0===i?(a=138,u=3):r==i?(a=6,u=3):(a=7,u=4)}}function ie(e,n,r){var s;for(ne(e-257,5),ne(n-1,5),ne(r-4,4),s=0;r>s;s++)ne(tn[2*t.bl_order[s]+1],3);se($e,e-1),se(Ze,n-1)}function oe(){16==hn?(p(dn),dn=0,hn=0):hn>=8&&(d(255&dn),dn>>>=8,hn-=8)}function ae(){ne(Q<<1,3),re(h,e.static_ltree),oe(),9>1+fn+10-hn&&(ne(Q<<1,3),re(h,e.static_ltree),oe()),fn=7}function ue(e,n){var r,s,i;if(en.pending_buf[cn+2*un]=e>>>8&255,en.pending_buf[cn+2*un+1]=255&e,en.pending_buf[on+un]=255&n,un++,0===e?$e[2*n]++:(ln++,e--,$e[2*(t._length_code[n]+l+1)]++,Ze[2*t.d_code(e)]++),0===(8191&un)&&Xe>2){for(r=8*un,s=Me-Ue,i=0;a>i;i++)r+=Ze[2*i]*(5+t.extra_dbits[i]);if(r>>>=3,ln<Math.floor(un/2)&&r<Math.floor(s/2))return!0}return un==an-1}function ce(e,n){var r,s,i,o,a=0;if(0!==un)do r=en.pending_buf[cn+2*a]<<8&65280|255&en.pending_buf[cn+2*a+1],s=255&en.pending_buf[on+a],a++,0===r?re(s,e):(i=t._length_code[s],re(i+l+1,e),o=t.extra_lbits[i],0!==o&&(s-=t.base_length[i],ne(s,o)),r--,i=t.d_code(r),re(i,n),o=t.extra_dbits[i],0!==o&&(r-=t.base_dist[i],ne(r,o)));while(un>a);re(h,e),fn=e[2*h+1]}function le(){hn>8?p(dn):hn>0&&d(255&dn),dn=0,hn=0}function fe(t,e,n){le(),fn=8,n&&(p(e),p(~e)),en.pending_buf.set(ze.subarray(t,t+e),en.pending),en.pending+=e}function de(t,e,n){ne((K<<1)+(n?1:0),3),fe(t,e,!0)}function he(t,n,r){var i,o,a=0;Xe>0?(nn.build_tree(en),rn.build_tree(en),a=c(),i=en.opt_len+3+7>>>3,o=en.static_len+3+7>>>3,i>=o&&(i=o)):i=o=n+5,i>=n+4&&-1!=t?de(t,n,r):o==i?(ne((Q<<1)+(r?1:0),3),ce(e.static_ltree,e.static_dtree)):(ne(($<<1)+(r?1:0),3),ie(nn.max_code+1,rn.max_code+1,a+1),ce($e,Ze)),s(),r&&le()}function pe(t){he(Ue>=0?Ue:-1,Me-Ue,t),Ue=Me,qe.flush_pending()}function me(){var t,e,n,r;do{if(r=Te-Ge-Me,0===r&&0===Me&&0===Ge)r=Ce;else if(-1==r)r--;else if(Me>=Ce+Ce-ee){ze.set(ze.subarray(Ce,Ce+Ce),0),He-=Ce,Me-=Ce,Ue-=Ce,t=Pe,n=t;do e=65535&Be[--n],Be[n]=e>=Ce?e-Ce:0;while(0!==--t);t=Ce,n=t;do e=65535&Ie[--n],Ie[n]=e>=Ce?e-Ce:0;while(0!==--t);r+=Ce}if(0===qe.avail_in)return;t=qe.read_buf(ze,Me+Ge,r),Ge+=t,Ge>=Z&&(Oe=255&ze[Me],Oe=(Oe<<De^255&ze[Me+1])&Re)}while(ee>Ge&&0!==qe.avail_in)}function we(t){var e,n=65535;for(n>ke-5&&(n=ke-5);;){if(1>=Ge){if(me(),0===Ge&&t==k)return j;if(0===Ge)break}if(Me+=Ge,Ge=0,e=Ue+n,(0===Me||Me>=e)&&(Ge=Me-e,Me=e,pe(!1),0===qe.avail_out))return j;if(Me-Ue>=Ce-ee&&(pe(!1),0===qe.avail_out))return j}return pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function ge(t){var e,n,r=Je,s=Me,i=We,o=Me>Ce-ee?Me-(Ce-ee):0,a=Qe,u=Ee,c=Me+te,l=ze[s+i-1],f=ze[s+i];We>=Ke&&(r>>=2),a>Ge&&(a=Ge);do if(e=t,ze[e+i]==f&&ze[e+i-1]==l&&ze[e]==ze[s]&&ze[++e]==ze[s+1]){s+=2,e++;do;while(ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&c>s);if(n=te-(c-s),s=c-te,n>i){if(He=t,i=n,n>=a)break;l=ze[s+i-1],f=ze[s+i]}}while((t=65535&Ie[t&u])>o&&0!==--r);return Ge>=i?i:Ge}function ye(t){for(var e,n=0;;){if(ee>Ge){if(me(),ee>Ge&&t==k)return j;if(0===Ge)break}if(Ge>=Z&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Re,n=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me),0!==n&&Ce-ee>=(Me-n&65535)&&Ye!=q&&(Ne=ge(n)),Ne>=Z)if(e=ue(Me-He,Ne-Z),Ge-=Ne,Ve>=Ne&&Ge>=Z){Ne--;do Me++,Oe=(Oe<<De^255&ze[Me+(Z-1)])&Re,n=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me;while(0!==--Ne);Me++}else Me+=Ne,Ne=0,Oe=255&ze[Me],Oe=(Oe<<De^255&ze[Me+1])ℜelse e=ue(0,255&ze[Me]),Ge--,Me++;if(e&&(pe(!1),0===qe.avail_out))return j}return pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function ve(t){for(var e,n,r=0;;){if(ee>Ge){if(me(),ee>Ge&&t==k)return j;if(0===Ge)break}if(Ge>=Z&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Re,r=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me),We=Ne,Le=He,Ne=Z-1,0!==r&&Ve>We&&Ce-ee>=(Me-r&65535)&&(Ye!=q&&(Ne=ge(r)),5>=Ne&&(Ye==b||Ne==Z&&Me-He>4096)&&(Ne=Z-1)),We>=Z&&We>=Ne){n=Me+Ge-Z,e=ue(Me-1-Le,We-Z),Ge-=We-1,We-=2;do++Me<=n&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Re,r=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me);while(0!==--We);if(je=0,Ne=Z-1,Me++,e&&(pe(!1),0===qe.avail_out))return j}else if(0!==je){if(e=ue(0,255&ze[Me-1]),e&&pe(!1),Me++,Ge--,0===qe.avail_out)return j}else je=1,Me++,Ge--}return 0!==je&&(e=ue(0,255&ze[Me-1]),je=0),pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function be(t){return t.total_in=t.total_out=0,t.msg=null,en.pending=0,en.pending_out=0,xe=V,Ae=k,i(),n(),S}var qe,xe,ke,_e,Ae,Ce,Se,Ee,ze,Te,Ie,Be,Oe,Pe,Fe,Re,De,Ue,Ne,Le,je,Me,He,Ge,We,Je,Ve,Xe,Ye,Ke,Qe,$e,Ze,tn,en=this,nn=new t,rn=new t,sn=new t;en.depth=[];var on,an,un,cn,ln,fn,dn,hn;en.bl_count=[],en.heap=[],$e=[],Ze=[],tn=[],en.pqdownheap=function(t,e){for(var n=en.heap,s=n[e],i=e<<1;i<=en.heap_len&&(i<en.heap_len&&r(t,n[i+1],n[i],en.depth)&&i++,!r(t,s,n[i],en.depth));)n[e]=n[i],e=i,i<<=1;n[e]=s},en.deflateInit=function(t,e,n,r,s,i){return r||(r=Y),s||(s=F),i||(i=x),t.msg=null,e==v&&(e=6),1>s||s>P||r!=Y||9>n||n>15||0>e||e>9||0>i||i>q?T:(t.dstate=en,Se=n,Ce=1<<Se,Ee=Ce-1,Fe=s+7,Pe=1<<Fe,Re=Pe-1,De=Math.floor((Fe+Z-1)/Z),ze=new Uint8Array(2*Ce),Ie=[],Be=[],an=1<<s+6,en.pending_buf=new Uint8Array(4*an),ke=4*an,cn=Math.floor(an/2),on=3*an,Xe=e,Ye=i,_e=255&r,be(t))},en.deflateEnd=function(){return xe!=J&&xe!=V&&xe!=X?T:(en.pending_buf=null,Be=null,Ie=null,ze=null,en.dstate=null,xe==V?I:S)},en.deflateParams=function(t,e,n){var r=S;return e==v&&(e=6),0>e||e>9||0>n||n>q?T:(N[Xe].func!=N[e].func&&0!==t.total_in&&(r=t.deflate(_)),Xe!=e&&(Xe=e,Ve=N[Xe].max_lazy,Ke=N[Xe].good_length,Qe=N[Xe].nice_length,Je=N[Xe].max_chain),Ye=n,r)},en.deflateSetDictionary=function(t,e,n){var r,s=n,i=0;if(!e||xe!=J)return T;if(Z>s)return S;for(s>Ce-ee&&(s=Ce-ee,i=n-s),ze.set(e.subarray(i,i+s),0),Me=s,Ue=s,Oe=255&ze[0],Oe=(Oe<<De^255&ze[1])&Re,r=0;s-Z>=r;r++)Oe=(Oe<<De^255&ze[r+(Z-1)])&Re,Ie[r&Ee]=Be[Oe],Be[Oe]=r;return S},en.deflate=function(t,e){var n,r,s,i,o;if(e>C||0>e)return T;if(!t.next_out||!t.next_in&&0!==t.avail_in||xe==X&&e!=C)return t.msg=L[z-T],T;if(0===t.avail_out)return t.msg=L[z-B],B;if(qe=t,i=Ae,Ae=e,xe==J&&(r=Y+(Se-8<<4)<<8,s=(Xe-1&255)>>1,s>3&&(s=3),r|=s<<6,0!==Me&&(r|=W),r+=31-r%31,xe=V,O(r)),0!==en.pending){if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}else if(0===qe.avail_in&&i>=e&&e!=C)return qe.msg=L[z-B],B;if(xe==X&&0!==qe.avail_in)return t.msg=L[z-B],B;if(0!==qe.avail_in||0!==Ge||e!=k&&xe!=X){switch(o=-1,N[Xe].func){case R:o=we(e);break;case D:o=ye(e);break;case U:o=ve(e)}if((o==H||o==G)&&(xe=X),o==j||o==H)return 0===qe.avail_out&&(Ae=-1),S;if(o==M){if(e==_)ae();else if(de(0,0,!1),e==A)for(n=0;Pe>n;n++)Be[n]=0;if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}}return e!=C?S:E}}function i(){var t=this;t.next_in_index=0,t.next_out_index=0,t.avail_in=0,t.total_in=0,t.avail_out=0,t.total_out=0}var o=15,a=30,u=19,c=29,l=256,f=l+1+c,d=2*f+1,h=256,p=7,m=16,w=17,g=18,y=16,v=-1,b=1,q=2,x=0,k=0,_=1,A=3,C=4,S=0,E=1,z=2,T=-2,I=-3,B=-5,O=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];t._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28],t.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],t.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],t.d_code=function(t){return 256>t?O[t]:O[256+(t>>>7)]},t.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],t.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],t.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],e.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],e.static_l_desc=new e(e.static_ltree,t.extra_lbits,l+1,f,o),e.static_d_desc=new e(e.static_dtree,t.extra_dbits,0,a,o),e.static_bl_desc=new e(null,t.extra_blbits,0,u,p);var P=9,F=8,R=0,D=1,U=2,N=[new n(0,0,0,0,R),new n(4,4,8,4,D),new n(4,5,16,8,D),new n(4,6,32,32,D),new n(4,4,16,16,U),new n(8,16,32,32,U),new n(8,16,128,128,U),new n(8,32,128,256,U),new n(32,128,258,1024,U),new n(32,258,258,4096,U)],L=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],j=0,M=1,H=2,G=3,W=32,J=42,V=113,X=666,Y=8,K=0,Q=1,$=2,Z=3,te=258,ee=te+Z+1;return i.prototype={deflateInit:function(t,e){var n=this;return n.dstate=new s,e||(e=o),n.dstate.deflateInit(n,t,e)},deflate:function(t){var e=this;return e.dstate?e.dstate.deflate(e,t):T},deflateEnd:function(){var t=this;if(!t.dstate)return T;var e=t.dstate.deflateEnd();return t.dstate=null,e},deflateParams:function(t,e){var n=this;return n.dstate?n.dstate.deflateParams(n,t,e):T},deflateSetDictionary:function(t,e){var n=this;return n.dstate?n.dstate.deflateSetDictionary(n,t,e):T},read_buf:function(t,e,n){var r=this,s=r.avail_in;return s>n&&(s=n),0===s?0:(r.avail_in-=s,t.set(r.next_in.subarray(r.next_in_index,r.next_in_index+s),e),r.next_in_index+=s,r.total_in+=s,s)},flush_pending:function(){var t=this,e=t.dstate.pending;e>t.avail_out&&(e=t.avail_out),0!==e&&(t.next_out.set(t.dstate.pending_buf.subarray(t.dstate.pending_out,t.dstate.pending_out+e),t.next_out_index),t.next_out_index+=e,t.dstate.pending_out+=e,t.total_out+=e,t.avail_out-=e,t.dstate.pending-=e,0===t.dstate.pending&&(t.dstate.pending_out=0))}},function(t){var e=this,n=new i,r=512,s=k,o=new Uint8Array(r);"undefined"==typeof t&&(t=v),n.deflateInit(t),n.next_out=o,e.append=function(t,e){var i,a,u=[],c=0,l=0,f=0;if(t.length){n.next_in_index=0,n.next_in=t,n.avail_in=t.length;do{if(n.next_out_index=0,n.avail_out=r,i=n.deflate(s),i!=S)throw"deflating: "+n.msg;n.next_out_index&&(n.next_out_index==r?u.push(new Uint8Array(o)):u.push(new Uint8Array(o.subarray(0,n.next_out_index)))),f+=n.next_out_index,e&&n.next_in_index>0&&n.next_in_index!=c&&(e(n.next_in_index),c=n.next_in_index)}while(n.avail_in>0||0===n.avail_out);return a=new Uint8Array(f),u.forEach(function(t){a.set(t,l),l+=t.length}),a}},e.flush=function(){var t,e,s=[],i=0,a=0;do{if(n.next_out_index=0,n.avail_out=r,t=n.deflate(C),t!=E&&t!=S)throw"deflating: "+n.msg;r-n.avail_out>0&&s.push(new Uint8Array(o.subarray(0,n.next_out_index))),a+=n.next_out_index}while(n.avail_in>0||0===n.avail_out);return n.deflateEnd(),e=new Uint8Array(a),s.forEach(function(t){e.set(t,i),i+=t.length}),e}}}(this);!function(t){var e;e=function(){function e(t){var e,n,r,s,i,o,a,u,c,l,f,d,h,p,m;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},o=null;;){switch(e=this.readUInt32(),l=function(){var t,e;for(e=[],a=t=0;4>t;a=++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join("")){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":o&&this.animation.frames.push(o),this.pos+=4,o={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},i=this.readUInt16(),s=this.readUInt16()||100,o.delay=1e3*i/s,o.disposeOp=this.data[this.pos++],o.blendOp=this.data[this.pos++],o.data=[];break;case"IDAT":case"fdAT":for("fdAT"===l&&(this.pos+=4,e-=4),t=(null!=o?o.data:void 0)||this.imgData,a=h=0;e>=0?e>h:h>e;a=e>=0?++h:--h)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(r=this.palette.length/3,this.transparency.indexed=this.read(e),this.transparency.indexed.length>r)throw new Error("More transparent colors than palette size");if(f=r-this.transparency.indexed.length,f>0)for(a=p=0;f>=0?f>p:p>f;a=f>=0?++p:--p)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":d=this.read(e),u=d.indexOf(0),c=String.fromCharCode.apply(String,d.slice(0,u)),this.text[c]=String.fromCharCode.apply(String,d.slice(u+1));break;case"IEND":return o&&this.animation.frames.push(o),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(m=this.colorType)||6===m,n=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*n,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),this.imgData=new Uint8Array(this.imgData),void 0;default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}var n,r,s,i,a,u,c,l;e.load=function(t,n,r){var s;return"function"==typeof n&&(r=n),s=new XMLHttpRequest,s.open("GET",t,!0),s.responseType="arraybuffer",s.onload=function(){var t,i;return t=new Uint8Array(s.response||s.mozResponseArrayBuffer),i=new e(t),"function"==typeof(null!=n?n.getContext:void 0)&&i.render(n),"function"==typeof r?r(i):void 0},s.send(null)},i=0,s=1,a=2,r=0,n=1,e.prototype.read=function(t){var e,n,r;for(r=[],e=n=0;t>=0?t>n:n>t;e=t>=0?++n:--n)r.push(this.data[this.pos++]);return r},e.prototype.readUInt32=function(){var t,e,n,r;return t=this.data[this.pos++]<<24,e=this.data[this.pos++]<<16,n=this.data[this.pos++]<<8,r=this.data[this.pos++],t|e|n|r},e.prototype.readUInt16=function(){var t,e;return t=this.data[this.pos++]<<8,e=this.data[this.pos++],t|e},e.prototype.decodePixels=function(t){var e,n,r,s,i,a,u,c,l,f,d,h,p,m,w,g,y,v,b,q,x,k,_;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);for(t=new o(t),t=t.getBytes(),h=this.pixelBitlength/8,g=h*this.width,p=new Uint8Array(g*this.height),a=t.length,w=0,m=0,n=0;a>m;){switch(t[m++]){case 0:for(s=b=0;g>b;s=b+=1)p[n++]=t[m++];break;case 1:for(s=q=0;g>q;s=q+=1)e=t[m++],i=h>s?0:p[n-h],p[n++]=(e+i)%256;break;case 2:for(s=x=0;g>x;s=x+=1)e=t[m++],r=(s-s%h)/h,y=w&&p[(w-1)*g+r*h+s%h],p[n++]=(y+e)%256;break;case 3:for(s=k=0;g>k;s=k+=1)e=t[m++],r=(s-s%h)/h,i=h>s?0:p[n-h],y=w&&p[(w-1)*g+r*h+s%h],p[n++]=(e+Math.floor((i+y)/2))%256;break;case 4:for(s=_=0;g>_;s=_+=1)e=t[m++],r=(s-s%h)/h,i=h>s?0:p[n-h],0===w?y=v=0:(y=p[(w-1)*g+r*h+s%h],v=r&&p[(w-1)*g+(r-1)*h+s%h]),u=i+y-v,c=Math.abs(u-i),f=Math.abs(u-y),d=Math.abs(u-v),l=f>=c&&d>=c?i:d>=f?y:v,p[n++]=(e+l)%256;break;default:throw new Error("Invalid filter algorithm: "+t[m-1])}w++}return p},e.prototype.decodePalette=function(){var t,e,n,r,s,i,o,a,u,c;for(r=this.palette,o=this.transparency.indexed||[],i=new Uint8Array((o.length||0)+r.length),s=0,n=r.length,t=0,e=a=0,u=r.length;u>a;e=a+=3)i[s++]=r[e],i[s++]=r[e+1],i[s++]=r[e+2],i[s++]=null!=(c=o[t++])?c:255;return i},e.prototype.copyToImageData=function(t,e){var n,r,s,i,o,a,u,c,l,f,d;if(r=this.colors,l=null,n=this.hasAlphaChannel,this.palette.length&&(l=null!=(d=this._decodedPalette)?d:this._decodedPalette=this.decodePalette(),r=4,n=!0),s=t.data||t,c=s.length,o=l||e,i=a=0,1===r)for(;c>i;)u=l?4*e[i/4]:a,f=o[u++],s[i++]=f,s[i++]=f,s[i++]=f,s[i++]=n?o[u++]:255,a=u;else for(;c>i;)u=l?4*e[i/4]:a,s[i++]=o[u++],s[i++]=o[u++],s[i++]=o[u++],s[i++]=n?o[u++]:255,a=u},e.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t};try{c=t.document.createElement("canvas"),l=c.getContext("2d")}catch(f){return-1}return u=function(t){var e;return l.width=t.width,l.height=t.height,l.clearRect(0,0,t.width,t.height),l.putImageData(t,0,0),e=new Image,e.src=c.toDataURL(),e},e.prototype.decodeFrames=function(t){var e,n,r,s,i,o,a,c;if(this.animation){for(a=this.animation.frames,c=[],n=i=0,o=a.length;o>i;n=++i)e=a[n],r=t.createImageData(e.width,e.height),s=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(r,s),e.imageData=r,c.push(e.image=u(r));return c}},e.prototype.renderFrame=function(t,e){var n,i,o;return i=this.animation.frames,n=i[e],o=i[e-1],0===e&&t.clearRect(0,0,this.width,this.height),(null!=o?o.disposeOp:void 0)===s?t.clearRect(o.xOffset,o.yOffset,o.width,o.height):(null!=o?o.disposeOp:void 0)===a&&t.putImageData(o.imageData,o.xOffset,o.yOffset),n.blendOp===r&&t.clearRect(n.xOffset,n.yOffset,n.width,n.height),t.drawImage(n.image,n.xOffset,n.yOffset)},e.prototype.animate=function(t){var e,n,r,s,i,o,a=this;return n=0,o=this.animation,s=o.numFrames,r=o.frames,i=o.numPlays,(e=function(){var o,u;return o=n++%s,u=r[o],a.renderFrame(t,o),s>1&&i>n/s?a.animation._timeout=setTimeout(e,u.delay):void 0})()},e.prototype.stopAnimation=function(){var t;return clearTimeout(null!=(t=this.animation)?t._timeout:void 0)},e.prototype.render=function(t){var e,n;return t._png&&t._png.stopAnimation(),t._png=this,t.width=this.width,t.height=this.height,e=t.getContext("2d"),this.animation?(this.decodeFrames(e),this.animate(e)):(n=e.createImageData(this.width,this.height),this.copyToImageData(n,this.decodePixels()),e.putImageData(n,0,0))},e}(),t.PNG=e}("undefined"!=typeof window&&window||this);var i=function(){function t(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return t.prototype={ensureBuffer:function(t){var e=this.buffer,n=e?e.byteLength:0;if(n>t)return e;for(var r=512;t>r;)r<<=1;for(var s=new Uint8Array(r),i=0;n>i;++i)s[i]=e[i];return this.buffer=s},getByte:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(t){var e=this.pos;if(t){this.ensureBuffer(e+t);for(var n=e+t;!this.eof&&this.bufferLength<n;)this.readBlock();var r=this.bufferLength;
|
||
n>r&&(n=r)}else{for(;!this.eof;)this.readBlock();var n=this.bufferLength}return this.pos=n,this.buffer.subarray(e,n)},lookChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(t,e,n){for(var r=t+e;this.bufferLength<=r&&!this.eof;)this.readBlock();return new Stream(this.buffer,t,e,n)},skip:function(t){t||(t=1),this.pos+=t},reset:function(){this.pos=0}},t}(),o=function(){function t(t){throw new Error(t)}function e(e){var n=0,r=e[n++],s=e[n++];(-1==r||-1==s)&&t("Invalid header in flate stream"),8!=(15&r)&&t("Unknown compression method in flate stream"),((r<<8)+s)%31!=0&&t("Bad FCHECK in flate stream"),32&s&&t("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=n,this.codeSize=0,this.codeBuf=0,i.call(this)}if("undefined"==typeof Uint32Array)return void 0;var n=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),r=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),s=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),o=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],a=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return e.prototype=Object.create(i.prototype),e.prototype.getBits=function(e){for(var n,r=this.codeSize,s=this.codeBuf,i=this.bytes,o=this.bytesPos;e>r;)"undefined"==typeof(n=i[o++])&&t("Bad encoding in flate stream"),s|=n<<r,r+=8;return n=s&(1<<e)-1,this.codeBuf=s>>e,this.codeSize=r-=e,this.bytesPos=o,n},e.prototype.getCode=function(e){for(var n=e[0],r=e[1],s=this.codeSize,i=this.codeBuf,o=this.bytes,a=this.bytesPos;r>s;){var u;"undefined"==typeof(u=o[a++])&&t("Bad encoding in flate stream"),i|=u<<s,s+=8}var c=n[i&(1<<r)-1],l=c>>16,f=65535&c;return(0==s||l>s||0==l)&&t("Bad encoding in flate stream"),this.codeBuf=i>>l,this.codeSize=s-l,this.bytesPos=a,f},e.prototype.generateHuffmanTable=function(t){for(var e=t.length,n=0,r=0;e>r;++r)t[r]>n&&(n=t[r]);for(var s=1<<n,i=new Uint32Array(s),o=1,a=0,u=2;n>=o;++o,a<<=1,u<<=1)for(var c=0;e>c;++c)if(t[c]==o){for(var l=0,f=a,r=0;o>r;++r)l=l<<1|1&f,f>>=1;for(var r=l;s>r;r+=u)i[r]=o<<16|c;++a}return[i,n]},e.prototype.readBlock=function(){function e(t,e,n,r,s){for(var i=t.getBits(n)+r;i-->0;)e[k++]=s}var i=this.getBits(3);if(1&i&&(this.eof=!0),i>>=1,0==i){var u,c=this.bytes,l=this.bytesPos;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var f=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),f|=u<<8,"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var d=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),d|=u<<8,d!=(65535&~f)&&t("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var h=this.bufferLength,p=this.ensureBuffer(h+f),m=h+f;this.bufferLength=m;for(var w=h;m>w;++w){if("undefined"==typeof(u=c[l++])){this.eof=!0;break}p[w]=u}return this.bytesPos=l,void 0}var g,y;if(1==i)g=o,y=a;else if(2==i){for(var v=this.getBits(5)+257,b=this.getBits(5)+1,q=this.getBits(4)+4,x=Array(n.length),k=0;q>k;)x[n[k++]]=this.getBits(3);for(var _=this.generateHuffmanTable(x),A=0,k=0,C=v+b,S=new Array(C);C>k;){var E=this.getCode(_);16==E?e(this,S,2,3,A):17==E?e(this,S,3,3,A=0):18==E?e(this,S,7,11,A=0):S[k++]=A=E}g=this.generateHuffmanTable(S.slice(0,v)),y=this.generateHuffmanTable(S.slice(v,C))}else t("Unknown block type in flate stream");for(var p=this.buffer,z=p?p.length:0,T=this.bufferLength;;){var I=this.getCode(g);if(256>I)T+1>=z&&(p=this.ensureBuffer(T+1),z=p.length),p[T++]=I;else{if(256==I)return this.bufferLength=T,void 0;I-=257,I=r[I];var B=I>>16;B>0&&(B=this.getBits(B));var A=(65535&I)+B;I=this.getCode(y),I=s[I],B=I>>16,B>0&&(B=this.getBits(B));var O=(65535&I)+B;T+A>=z&&(p=this.ensureBuffer(T+A),z=p.length);for(var P=0;A>P;++P,++T)p[T]=p[T-O]}}},e}();!function(t){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";"undefined"==typeof t.btoa&&(t.btoa=function(t){var n,r,s,i,o,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;do n=t.charCodeAt(l++),r=t.charCodeAt(l++),s=t.charCodeAt(l++),c=n<<16|r<<8|s,i=c>>18&63,o=c>>12&63,a=c>>6&63,u=63&c,h[f++]=e.charAt(i)+e.charAt(o)+e.charAt(a)+e.charAt(u);while(l<t.length);d=h.join("");var p=t.length%3;return(p?d.slice(0,p-3):d)+"===".slice(p||3)}),"undefined"==typeof t.atob&&(t.atob=function(t){var n,r,s,i,o,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;t+="";do i=e.indexOf(t.charAt(l++)),o=e.indexOf(t.charAt(l++)),a=e.indexOf(t.charAt(l++)),u=e.indexOf(t.charAt(l++)),c=i<<18|o<<12|a<<6|u,n=c>>16&255,r=c>>8&255,s=255&c,h[f++]=64==a?String.fromCharCode(n):64==u?String.fromCharCode(n,r):String.fromCharCode(n,r,s);while(l<t.length);return d=h.join("")}),Array.prototype.map||(Array.prototype.map=function(t){if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var e=Object(this),n=e.length>>>0,r=new Array(n),s=arguments.length>1?arguments[1]:void 0,i=0;n>i;i++)i in e&&(r[i]=t.call(s,e[i],i,e));return r}),Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){"use strict";if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var n=Object(this),r=n.length>>>0,s=0;r>s;s++)s in n&&t.call(e,n[s],s,n)}),Object.keys||(Object.keys=function(){"use strict";var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),n=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],r=n.length;return function(s){if("object"!=typeof s&&("function"!=typeof s||null===s))throw new TypeError;var i,o,a=[];for(i in s)t.call(s,i)&&a.push(i);if(e)for(o=0;r>o;o++)t.call(s,n[o])&&a.push(n[o]);return a}}()),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")})}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this)}({},function(){return this}());
|
||
// http://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
||
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
||
var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
|
||
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
|
||
var isChrome = !!window.chrome && !isOpera; // Chrome 1+
|
||
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
||
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||
|
||
function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', left, 30);
|
||
}
|
||
|
||
/* table header */
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
|
||
var detailsHeight = getInvoiceDetailsHeight(invoice, layout);
|
||
var left = layout.headerLeft - layout.tablePadding;
|
||
var top = layout.headerTop + detailsHeight - layout.rowHeight - layout.tablePadding;
|
||
var width = layout.headerRight - layout.headerLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 1;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontSize(10);
|
||
doc.setFontType("normal");
|
||
|
||
displayAccount(doc, invoice, layout.marginLeft, layout.accountTop, layout);
|
||
displayClient(doc, invoice, layout.marginLeft, layout.headerTop, layout);
|
||
|
||
displayInvoice(doc, invoice, layout.headerLeft, layout.headerTop, layout, layout.headerRight);
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
|
||
|
||
var headerY = layout.headerTop;
|
||
var total = 0;
|
||
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = layout.tableTop - layout.tablePadding;
|
||
var width = layout.headerRight - layout.marginLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 2;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
doc.setFontSize(10);
|
||
|
||
/* table footer */
|
||
/*
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setLineWidth(1);
|
||
doc.line(layout.marginLeft - layout.tablePadding, x, layout.lineTotalRight+layout.tablePadding, x);
|
||
*/
|
||
|
||
displayNotesAndTerms(doc, layout, invoice, y+20);
|
||
|
||
y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;
|
||
|
||
/*
|
||
if (checkMath && NINJA.parseFloat(total).toFixed(4) != NINJA.parseFloat(invoice.amount).toFixed(4))
|
||
{
|
||
var doc = new jsPDF('p', 'pt');
|
||
doc.setFont('Helvetica','');
|
||
doc.setFontSize(10);
|
||
doc.text(100, 100, "An error occurred, please try again later.");
|
||
onerror('Failed to generate PDF ' + total + ', ' + invoice.amount );
|
||
return doc;
|
||
}
|
||
*/
|
||
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
|
||
var left = layout.footerLeft - layout.tablePadding;
|
||
var top = y - layout.tablePadding;
|
||
var width = layout.headerRight - layout.footerLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 2;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontType("bold");
|
||
doc.text(layout.footerLeft, y, invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due);
|
||
|
||
total = formatMoney(invoice.balance_amount, currencyId);
|
||
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||
doc.text(totalX, y, total);
|
||
|
||
if (!invoice.is_pro) {
|
||
doc.setFontType("normal");
|
||
doc.text(layout.marginLeft, 790, "Created by InvoiceNinja.com");
|
||
}
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
var invoiceOld;
|
||
function generatePDF(invoice, force) {
|
||
invoice = calculateAmounts(invoice);
|
||
var a = copyInvoice(invoice);
|
||
var b = copyInvoice(invoiceOld);
|
||
if (!force && _.isEqual(a, b)) {
|
||
return;
|
||
}
|
||
invoiceOld = invoice;
|
||
report_id = invoice.invoice_design_id;
|
||
doc = GetPdf(invoice, false, report_id);
|
||
return doc;
|
||
}
|
||
|
||
function copyInvoice(orig) {
|
||
if (!orig) return false;
|
||
var copy = JSON.stringify(orig);
|
||
var copy = JSON.parse(copy);
|
||
return copy;
|
||
}
|
||
|
||
/* Handle converting variables in the invoices (ie, MONTH+1) */
|
||
function processVariables(str) {
|
||
if (!str) return '';
|
||
var variables = ['MONTH','QUARTER','YEAR'];
|
||
for (var i=0; i<variables.length; i++) {
|
||
var variable = variables[i];
|
||
var regexp = new RegExp(':' + variable + '[+-]?[\\d]*', 'g');
|
||
var matches = str.match(regexp);
|
||
if (!matches) {
|
||
continue;
|
||
}
|
||
for (var j=0; j<matches.length; j++) {
|
||
var match = matches[j];
|
||
var offset = 0;
|
||
if (match.split('+').length > 1) {
|
||
offset = match.split('+')[1];
|
||
} else if (match.split('-').length > 1) {
|
||
offset = parseInt(match.split('-')[1]) * -1;
|
||
}
|
||
str = str.replace(match, getDatePart(variable, offset));
|
||
}
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
function getDatePart(part, offset) {
|
||
offset = parseInt(offset);
|
||
if (!offset) {
|
||
offset = 0;
|
||
}
|
||
if (part == 'MONTH') {
|
||
return getMonth(offset);
|
||
} else if (part == 'QUARTER') {
|
||
return getQuarter(offset);
|
||
} else if (part == 'YEAR') {
|
||
return getYear(offset);
|
||
}
|
||
}
|
||
|
||
function getMonth(offset) {
|
||
var today = new Date();
|
||
var months = [ "January", "February", "March", "April", "May", "June",
|
||
"July", "August", "September", "October", "November", "December" ];
|
||
var month = today.getMonth();
|
||
month = parseInt(month) + offset;
|
||
month = month % 12;
|
||
if (month < 0) {
|
||
month += 12;
|
||
}
|
||
return months[month];
|
||
}
|
||
|
||
function getYear(offset) {
|
||
var today = new Date();
|
||
var year = today.getFullYear();
|
||
return parseInt(year) + offset;
|
||
}
|
||
|
||
function getQuarter(offset) {
|
||
var today = new Date();
|
||
var quarter = Math.floor((today.getMonth() + 3) / 3);
|
||
quarter += offset;
|
||
quarter = quarter % 4;
|
||
if (quarter == 0) {
|
||
quarter = 4;
|
||
}
|
||
return 'Q' + quarter;
|
||
}
|
||
|
||
|
||
/* Default class modification */
|
||
$.extend( $.fn.dataTableExt.oStdClasses, {
|
||
"sWrapper": "dataTables_wrapper form-inline"
|
||
} );
|
||
|
||
|
||
/* API method to get paging information */
|
||
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
|
||
{
|
||
return {
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iEnd": oSettings.fnDisplayEnd(),
|
||
"iLength": oSettings._iDisplayLength,
|
||
"iTotal": oSettings.fnRecordsTotal(),
|
||
"iFilteredTotal": oSettings.fnRecordsDisplay(),
|
||
"iPage": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
|
||
"iTotalPages": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
|
||
};
|
||
};
|
||
|
||
|
||
/* Bootstrap style pagination control */
|
||
$.extend( $.fn.dataTableExt.oPagination, {
|
||
"bootstrap": {
|
||
"fnInit": function( oSettings, nPaging, fnDraw ) {
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
};
|
||
|
||
$(nPaging).addClass('pagination').append(
|
||
'<ul class="pagination">'+
|
||
'<li class="prev disabled"><a href="#">«</a></li>'+
|
||
'<li class="next disabled"><a href="#">»</a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
$(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
|
||
$(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
|
||
},
|
||
|
||
"fnUpdate": function ( oSettings, fnDraw ) {
|
||
var iListLength = 5;
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var an = oSettings.aanFeatures.p;
|
||
var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
|
||
|
||
if ( oPaging.iTotalPages < iListLength) {
|
||
iStart = 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
}
|
||
else if ( oPaging.iPage <= iHalf ) {
|
||
iStart = 1;
|
||
iEnd = iListLength;
|
||
} else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
|
||
iStart = oPaging.iTotalPages - iListLength + 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
} else {
|
||
iStart = oPaging.iPage - iHalf + 1;
|
||
iEnd = iStart + iListLength - 1;
|
||
}
|
||
|
||
for ( i=0, ien=an.length ; i<ien ; i++ ) {
|
||
// Remove the middle elements
|
||
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
|
||
|
||
// Add the new list items and their event handlers
|
||
for ( j=iStart ; j<=iEnd ; j++ ) {
|
||
sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
|
||
$('<li '+sClass+'><a href="#">'+j+'</a></li>')
|
||
.insertBefore( $('li:last', an[i])[0] )
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
|
||
fnDraw( oSettings );
|
||
} );
|
||
}
|
||
|
||
// Add / remove disabled classes from the static elements
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
/*
|
||
* TableTools Bootstrap compatibility
|
||
* Required TableTools 2.1+
|
||
*/
|
||
if ( $.fn.DataTable.TableTools ) {
|
||
// Set the classes that TableTools uses to something suitable for Bootstrap
|
||
$.extend( true, $.fn.DataTable.TableTools.classes, {
|
||
"container": "DTTT btn-group",
|
||
"buttons": {
|
||
"normal": "btn",
|
||
"disabled": "disabled"
|
||
},
|
||
"collection": {
|
||
"container": "DTTT_dropdown dropdown-menu",
|
||
"buttons": {
|
||
"normal": "",
|
||
"disabled": "disabled"
|
||
}
|
||
},
|
||
"print": {
|
||
"info": "DTTT_print_info modal"
|
||
},
|
||
"select": {
|
||
"row": "active"
|
||
}
|
||
} );
|
||
|
||
// Have the collection use a bootstrap compatible dropdown
|
||
$.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
|
||
"collection": {
|
||
"container": "ul",
|
||
"button": "li",
|
||
"liner": "a"
|
||
}
|
||
} );
|
||
}
|
||
|
||
/*
|
||
$(document).ready(function() {
|
||
$('#example').dataTable( {
|
||
"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
|
||
"sPaginationType": "bootstrap",
|
||
"oLanguage": {
|
||
"sLengthMenu": "_MENU_ records per page"
|
||
}
|
||
} );
|
||
} );
|
||
*/
|
||
|
||
function isStorageSupported() {
|
||
try {
|
||
return 'localStorage' in window && window['localStorage'] !== null;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function isValidEmailAddress(emailAddress) {
|
||
var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
|
||
return pattern.test(emailAddress);
|
||
};
|
||
|
||
$(function() {
|
||
$.ajaxSetup({
|
||
headers: {
|
||
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
function enableHoverClick($combobox, $entityId, url) {
|
||
/*
|
||
$combobox.mouseleave(function() {
|
||
$combobox.css('text-decoration','none');
|
||
}).on('mouseenter', function(e) {
|
||
setAsLink($combobox, $combobox.closest('.combobox-container').hasClass('combobox-selected'));
|
||
}).on('focusout mouseleave', function(e) {
|
||
setAsLink($combobox, false);
|
||
}).on('click', function() {
|
||
var clientId = $entityId.val();
|
||
if ($(combobox).closest('.combobox-container').hasClass('combobox-selected')) {
|
||
if (parseInt(clientId) > 0) {
|
||
window.open(url + '/' + clientId, '_blank');
|
||
} else {
|
||
$('#myModal').modal('show');
|
||
}
|
||
};
|
||
});
|
||
*/
|
||
}
|
||
|
||
function setAsLink($input, enable) {
|
||
if (enable) {
|
||
$input.css('text-decoration','underline');
|
||
$input.css('cursor','pointer');
|
||
} else {
|
||
$input.css('text-decoration','none');
|
||
$input.css('cursor','text');
|
||
}
|
||
}
|
||
|
||
function setComboboxValue($combobox, id, name) {
|
||
$combobox.find('input').val(id);
|
||
$combobox.find('input.form-control').val(name);
|
||
if (id && name) {
|
||
$combobox.find('select').combobox('setSelected');
|
||
$combobox.find('.combobox-container').addClass('combobox-selected');
|
||
} else {
|
||
$combobox.find('.combobox-container').removeClass('combobox-selected');
|
||
}
|
||
}
|
||
|
||
|
||
var BASE64_MARKER = ';base64,';
|
||
function convertDataURIToBinary(dataURI) {
|
||
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
|
||
var base64 = dataURI.substring(base64Index);
|
||
return base64DecToArr(base64);
|
||
}
|
||
|
||
ko.bindingHandlers.dropdown = {
|
||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||
var options = allBindingsAccessor().dropdownOptions|| {};
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;
|
||
if (id) $(element).val(id);
|
||
//console.log("combo-init: %s", id);
|
||
$(element).combobox(options);
|
||
|
||
/*
|
||
ko.utils.registerEventHandler(element, "change", function () {
|
||
console.log("change: %s", $(element).val());
|
||
//var
|
||
valueAccessor($(element).val());
|
||
//$(element).combobox('refresh');
|
||
});
|
||
*/
|
||
},
|
||
update: function (element, valueAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;
|
||
//console.log("combo-update: %s", id);
|
||
if (id) {
|
||
$(element).val(id);
|
||
$(element).combobox('refresh');
|
||
} else {
|
||
$(element).combobox('clearTarget');
|
||
$(element).combobox('clearElement');
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
ko.bindingHandlers.datePicker = {
|
||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
if (value) $(element).datepicker('update', value);
|
||
$(element).change(function() {
|
||
var value = valueAccessor();
|
||
value($(element).val());
|
||
})
|
||
},
|
||
update: function (element, valueAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
if (value) $(element).datepicker('update', value);
|
||
}
|
||
};
|
||
|
||
|
||
function wordWrapText(value, width)
|
||
{
|
||
var doc = new jsPDF('p', 'pt');
|
||
doc.setFont('Helvetica','');
|
||
doc.setFontSize(10);
|
||
|
||
var lines = value.split("\n");
|
||
for (var i = 0; i < lines.length; i++) {
|
||
var numLines = doc.splitTextToSize(lines[i], width).length;
|
||
if (numLines <= 1) continue;
|
||
var j = 0; space = lines[i].length;
|
||
while (j++ < lines[i].length) {
|
||
if (lines[i].charAt(j) === ' ') space = j;
|
||
}
|
||
if (space == lines[i].length) space = width/6;
|
||
lines[i + 1] = lines[i].substring(space + 1) + ' ' + (lines[i + 1] || '');
|
||
lines[i] = lines[i].substring(0, space);
|
||
}
|
||
|
||
var newValue = (lines.join("\n")).trim();
|
||
|
||
if (value == newValue) {
|
||
return newValue;
|
||
} else {
|
||
return wordWrapText(newValue, width);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
function getClientDisplayName(client)
|
||
{
|
||
var contact = client.contacts[0];
|
||
if (client.name) {
|
||
return client.name;
|
||
} else if (contact.first_name || contact.last_name) {
|
||
return contact.first_name + ' ' + contact.last_name;
|
||
} else {
|
||
return contact.email;
|
||
}
|
||
}
|
||
|
||
|
||
function populateInvoiceComboboxes(clientId, invoiceId) {
|
||
var clientMap = {};
|
||
var invoiceMap = {};
|
||
var invoicesForClientMap = {};
|
||
var $clientSelect = $('select#client');
|
||
|
||
for (var i=0; i<invoices.length; i++) {
|
||
var invoice = invoices[i];
|
||
var client = invoice.client;
|
||
|
||
if (!invoicesForClientMap.hasOwnProperty(client.public_id)) {
|
||
invoicesForClientMap[client.public_id] = [];
|
||
}
|
||
|
||
invoicesForClientMap[client.public_id].push(invoice);
|
||
invoiceMap[invoice.public_id] = invoice;
|
||
}
|
||
|
||
for (var i=0; i<clients.length; i++) {
|
||
var client = clients[i];
|
||
clientMap[client.public_id] = client;
|
||
}
|
||
|
||
$clientSelect.append(new Option('', ''));
|
||
for (var i=0; i<clients.length; i++) {
|
||
var client = clients[i];
|
||
$clientSelect.append(new Option(getClientDisplayName(client), client.public_id));
|
||
}
|
||
|
||
if (clientId) {
|
||
$clientSelect.val(clientId);
|
||
}
|
||
|
||
$clientSelect.combobox();
|
||
$clientSelect.on('change', function(e) {
|
||
var clientId = $('input[name=client]').val();
|
||
var invoiceId = $('input[name=invoice]').val();
|
||
var invoice = invoiceMap[invoiceId];
|
||
if (invoice && invoice.client.public_id == clientId) {
|
||
e.preventDefault();
|
||
return;
|
||
}
|
||
setComboboxValue($('.invoice-select'), '', '');
|
||
$invoiceCombobox = $('select#invoice');
|
||
$invoiceCombobox.find('option').remove().end().combobox('refresh');
|
||
$invoiceCombobox.append(new Option('', ''));
|
||
var list = clientId ? (invoicesForClientMap.hasOwnProperty(clientId) ? invoicesForClientMap[clientId] : []) : invoices;
|
||
for (var i=0; i<list.length; i++) {
|
||
var invoice = list[i];
|
||
var client = clientMap[invoice.client.public_id];
|
||
if (!client) continue; // client is deleted/archived
|
||
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' +
|
||
getClientDisplayName(client) + ' - ' + formatMoney(invoice.amount, invoice.currency_id) + ' | ' +
|
||
formatMoney(invoice.balance, invoice.currency_id), invoice.public_id));
|
||
}
|
||
$('select#invoice').combobox('refresh');
|
||
});
|
||
|
||
var $invoiceSelect = $('select#invoice').on('change', function(e) {
|
||
$clientCombobox = $('select#client');
|
||
var invoiceId = $('input[name=invoice]').val();
|
||
if (invoiceId) {
|
||
var invoice = invoiceMap[invoiceId];
|
||
var client = clientMap[invoice.client.public_id];
|
||
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
|
||
if (!parseFloat($('#amount').val())) {
|
||
$('#amount').val(formatMoney(invoice.balance, invoice.currency_id, true));
|
||
}
|
||
}
|
||
});
|
||
|
||
$invoiceSelect.combobox();
|
||
|
||
if (invoiceId) {
|
||
var invoice = invoiceMap[invoiceId];
|
||
var client = clientMap[invoice.client.public_id];
|
||
setComboboxValue($('.invoice-select'), invoice.public_id, (invoice.invoice_number + ' - ' +
|
||
invoice.invoice_status.name + ' - ' + getClientDisplayName(client) + ' - ' +
|
||
formatMoney(invoice.amount, invoice.currency_id) + ' | ' + formatMoney(invoice.balance, invoice.currency_id)));
|
||
$invoiceSelect.trigger('change');
|
||
} else if (clientId) {
|
||
var client = clientMap[clientId];
|
||
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
|
||
$clientSelect.trigger('change');
|
||
} else {
|
||
$clientSelect.trigger('change');
|
||
}
|
||
}
|
||
|
||
|
||
var CONSTS = {};
|
||
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
||
CONSTS.INVOICE_STATUS_SENT = 2;
|
||
CONSTS.INVOICE_STATUS_VIEWED = 3;
|
||
CONSTS.INVOICE_STATUS_PARTIAL = 4;
|
||
CONSTS.INVOICE_STATUS_PAID = 5;
|
||
|
||
$.fn.datepicker.defaults.autoclose = true;
|
||
$.fn.datepicker.defaults.todayHighlight = true;
|
||
|
||
|
||
|
||
//====================================================================================================================
|
||
|
||
function GetPdf(invoice,checkMath,report_id){
|
||
var layout = {
|
||
accountTop: 40,
|
||
marginLeft: 50,
|
||
marginRight: 550,
|
||
headerTop: 150,
|
||
headerLeft: 360,
|
||
headerRight: 550,
|
||
rowHeight: 15,
|
||
tableRowHeight: 10,
|
||
footerLeft: 420,
|
||
tablePadding: 12,
|
||
tableTop: 250,
|
||
descriptionLeft: 162,
|
||
unitCostRight: 410,
|
||
qtyRight: 480,
|
||
taxRight: 480,
|
||
lineTotalRight: 550
|
||
};
|
||
|
||
if (invoice.has_taxes)
|
||
{
|
||
layout.descriptionLeft -= 20;
|
||
layout.unitCostRight -= 40;
|
||
layout.qtyRight -= 40;
|
||
}
|
||
|
||
/*
|
||
@param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l")
|
||
@param unit Measurement unit to be used when coordinates are specified. One of "pt" (points), "mm" (Default), "cm", "in"
|
||
@param format One of 'a3', 'a4' (Default),'a5' ,'letter' ,'legal'
|
||
@returns {jsPDF}
|
||
*/
|
||
var doc = new jsPDF('portrait', 'pt', 'a4');
|
||
|
||
|
||
//Set PDF properities
|
||
doc.setProperties({
|
||
title: 'Invoice ' + invoice.invoice_number,
|
||
subject: '',
|
||
author: 'InvoiceNinja.com',
|
||
keywords: 'pdf, invoice',
|
||
creator: 'InvoiceNinja.com'
|
||
});
|
||
|
||
//set default style for report
|
||
doc.setFont('Helvetica','');
|
||
|
||
if (report_id==1) {
|
||
return GetReportTemplate1(doc, invoice, layout, checkMath);
|
||
} else if (report_id==2) {
|
||
return GetReportTemplate2(doc, invoice, layout, checkMath);
|
||
} else if (report_id==3) {
|
||
return GetReportTemplate3(doc, invoice, layout, checkMath);
|
||
} else {
|
||
return GetReportTemplate4(doc, invoice, layout, checkMath);
|
||
}
|
||
}
|
||
|
||
function GetReportTemplate1(doc, invoice, layout, checkMath)
|
||
{
|
||
var GlobalY=0;//Y position of line at current page
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 550;
|
||
layout.rowHeight = 15;
|
||
|
||
doc.setFontSize(9);
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||
}
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo1)
|
||
{
|
||
pageHeight=820;
|
||
y=pageHeight-logoImages.imageLogoHeight1;
|
||
doc.addImage(logoImages.imageLogo1, 'JPEG', layout.marginLeft, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);
|
||
}
|
||
|
||
|
||
doc.setFontSize(9);
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
displayAccount(doc, invoice, 220, layout.accountTop, layout);
|
||
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
doc.setFontSize('11');
|
||
doc.text(50, layout.headerTop, (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase());
|
||
|
||
//doc.setDrawColor(220,220,220);
|
||
//doc.line(30, y, 560, y); // horizontal line
|
||
|
||
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontSize(9);
|
||
|
||
var invoiceHeight = displayInvoice(doc, invoice, 50, 170, layout);
|
||
var clientHeight = displayClient(doc, invoice, 220, 170, layout);
|
||
var detailsHeight = Math.max(invoiceHeight, clientHeight);
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (3 * layout.rowHeight));
|
||
|
||
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(200,200,200);
|
||
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + 6, layout.marginRight + layout.tablePadding, layout.headerTop + 6);
|
||
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + detailsHeight + 14, layout.marginRight + layout.tablePadding, layout.headerTop + detailsHeight + 14);
|
||
|
||
|
||
//doc.setDrawColor(220,220,220);
|
||
//doc.line(30, y-8, 560, y-8); // horizontal line
|
||
|
||
|
||
doc.setFontSize(10);
|
||
doc.setFontType("bold");
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
//doc.setFontType("normal");
|
||
doc.setFontSize(9);
|
||
|
||
doc.setFontType("bold");
|
||
|
||
GlobalY=GlobalY+25;
|
||
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(241,241,241);
|
||
doc.setFillColor(241,241,241);
|
||
var x1 = layout.marginLeft - 12;
|
||
var y1 = GlobalY-layout.tablePadding;
|
||
|
||
var w2 = 510 + 24;
|
||
var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;
|
||
|
||
if (invoice.discount) {
|
||
h2 += doc.internal.getFontSize()*2;
|
||
}
|
||
if (invoice.tax_amount) {
|
||
h2 += doc.internal.getFontSize()*2;
|
||
}
|
||
|
||
//doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
doc.setFontSize(9);
|
||
displayNotesAndTerms(doc, layout, invoice, y);
|
||
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
|
||
|
||
doc.setFontSize(10);
|
||
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
|
||
|
||
doc.text(TmpMsgX, y, Msg);
|
||
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
AmountText = formatMoney(invoice.balance_amount, currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var AmountX = layout.lineTotalRight - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
|
||
doc.text(AmountX, y, AmountText);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
function GetReportTemplate2(doc, invoice, layout, checkMath)
|
||
{
|
||
var GlobalY=0;//Y position of line at current page
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 150;
|
||
layout.rowHeight = 15;
|
||
layout.headerTop = 125;
|
||
layout.tableTop = 300;
|
||
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setFillColor(46,43,43);
|
||
}
|
||
|
||
var x1 =0;
|
||
var y1 = 0;
|
||
var w2 = 595;
|
||
var h2 = 100;
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||
}
|
||
|
||
Report2AddFooter (invoice,doc);
|
||
|
||
|
||
doc.setFontSize(7);
|
||
doc.setFontType("bold");
|
||
SetPdfColor('White',doc);
|
||
|
||
displayAccount(doc, invoice, 300, layout.accountTop, layout);
|
||
|
||
/*
|
||
var spacer = ' ';
|
||
var line1 = account.name + spacer + account.work_email + spacer + account.work_phone;
|
||
var lineWidth = doc.getStringUnitWidth(line1) * doc.internal.getFontSize();
|
||
var nameWidth = doc.getStringUnitWidth(account.name + spacer) * doc.internal.getFontSize();
|
||
var nameX = lineTotalRight - lineWidth;
|
||
var detailsX = lineTotalRight - (lineWidth - nameWidth);
|
||
|
||
doc.text(nameX, accountTop, account.name);
|
||
doc.setFontType("normal");
|
||
doc.text(detailsX, accountTop, account.work_email + spacer + account.work_phone);
|
||
|
||
var line2 = concatStrings(account.address1, account.address2) + spacer + concatStrings(account.city, account.state, account.postal_code);
|
||
var lineWidth = doc.getStringUnitWidth(line2) * doc.internal.getFontSize();
|
||
var line2X = lineTotalRight - lineWidth;
|
||
|
||
doc.text(line2X, accountTop + 16, line2);
|
||
*/
|
||
|
||
//-----------------------------Publish Client Details block--------------------------------------------
|
||
|
||
var y = layout.accountTop;
|
||
var left = layout.marginLeft;
|
||
|
||
var headerY = layout.headerTop;
|
||
|
||
|
||
|
||
SetPdfColor('GrayLogo',doc); //set black color
|
||
|
||
|
||
doc.setFontSize(7);
|
||
|
||
//show left column
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontType("normal");
|
||
|
||
|
||
//publish filled box
|
||
doc.setDrawColor(200,200,200);
|
||
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setFillColor(54,164,152);
|
||
}
|
||
|
||
GlobalY=190;
|
||
doc.setLineWidth(0.5);
|
||
|
||
var BlockLenght=220;
|
||
var x1 =595-BlockLenght;
|
||
var y1 = GlobalY-12;
|
||
var w2 = BlockLenght;
|
||
var h2 = getInvoiceDetailsHeight(invoice, layout) + layout.tablePadding + 2;
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
|
||
SetPdfColor('SomeGreen', doc, 'secondary');
|
||
doc.setFontSize('14');
|
||
doc.setFontType("bold");
|
||
doc.text(50, GlobalY, (invoice.is_quote ? invoiceLabels.your_quote : invoiceLabels.your_invoice).toUpperCase());
|
||
|
||
|
||
var z=GlobalY;
|
||
z=z+30;
|
||
|
||
|
||
doc.setFontSize('8');
|
||
SetPdfColor('Black',doc);
|
||
displayClient(doc, invoice, layout.marginLeft, z, layout);
|
||
|
||
|
||
marginLeft2=395;
|
||
|
||
//publish left side information
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontSize('8');
|
||
var detailsHeight = displayInvoice(doc, invoice, marginLeft2, z-25, layout) + 75;
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
|
||
|
||
y=z+60;
|
||
|
||
|
||
x = GlobalY + 100;
|
||
|
||
doc.setFontType("bold");
|
||
|
||
|
||
|
||
doc.setFontSize(12);
|
||
doc.setFontType("bold");
|
||
SetPdfColor('Black',doc);
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
//GlobalY=600;
|
||
|
||
doc.setLineWidth(0.3);
|
||
|
||
/*
|
||
doc.setDrawColor(251,251,251);
|
||
doc.setFillColor(251,251,251);
|
||
var x1 = layout.marginLeft-layout.tablePadding*2 +14;
|
||
var y1 = GlobalY-layout.tablePadding;
|
||
var w2 = 510+layout.tablePadding*2;//lineTotalRight-tablePadding*5;
|
||
var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
*/
|
||
|
||
displayNotesAndTerms(doc, layout, invoice, y);
|
||
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
|
||
doc.setFontType("bold");
|
||
|
||
doc.setFontSize(12);
|
||
x += doc.internal.getFontSize()*4;
|
||
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
|
||
|
||
|
||
|
||
doc.text(TmpMsgX, y, Msg);
|
||
|
||
|
||
//SetPdfColor('LightBlue',doc);
|
||
AmountText = formatMoney(invoice.balance_amount , currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var AmountX = headerLeft - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
|
||
SetPdfColor('SomeGreen', doc, 'secondary');
|
||
doc.text(AmountX, y, AmountText);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
function SetPdfColor(color, doc, role)
|
||
{
|
||
if (role === 'primary' && NINJA.primaryColor) {
|
||
return setDocHexColor(doc, NINJA.primaryColor);
|
||
} else if (role === 'secondary' && NINJA.secondaryColor) {
|
||
return setDocHexColor(doc, NINJA.secondaryColor);
|
||
}
|
||
|
||
if (color=='LightBlue') {
|
||
return doc.setTextColor(41,156, 194);
|
||
}
|
||
|
||
if (color=='Black') {
|
||
return doc.setTextColor(46,43,43);//select color black
|
||
}
|
||
if (color=='GrayLogo') {
|
||
return doc.setTextColor(207,241, 241);//select color Custom Report GRAY
|
||
}
|
||
|
||
if (color=='GrayBackground') {
|
||
return doc.setTextColor(251,251, 251);//select color Custom Report GRAY
|
||
}
|
||
|
||
if (color=='GrayText') {
|
||
return doc.setTextColor(161,160,160);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='White') {
|
||
return doc.setTextColor(255,255,255);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='SomeGreen') {
|
||
return doc.setTextColor(54,164,152);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='LightGrayReport2-gray') {
|
||
return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='LightGrayReport2-white') {
|
||
return doc.setTextColor(251,251,251);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
}
|
||
|
||
function Report2AddFooter (invoice,doc)
|
||
{
|
||
doc.setLineWidth(0.5);
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setFillColor(46,43,43);
|
||
doc.setDrawColor(46,43,43);
|
||
}
|
||
|
||
// return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour
|
||
var x1 = 0;//tableLeft-tablePadding ;
|
||
var y1 = 750;
|
||
var w2 = 596;
|
||
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
|
||
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo2)
|
||
{
|
||
pageHeight=820;
|
||
var left = 250;//headerRight ;
|
||
y=pageHeight-logoImages.imageLogoHeight2;
|
||
var headerRight=370;
|
||
|
||
var left = headerRight - logoImages.imageLogoWidth2;
|
||
doc.addImage(logoImages.imageLogo2, 'JPEG', left, y, logoImages.imageLogoWidth2, logoImages.imageLogoHeight2);
|
||
}
|
||
}
|
||
|
||
function Report3AddFooter (invoice, account, doc, layout)
|
||
{
|
||
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setDrawColor(242,101,34);
|
||
doc.setFillColor(242,101,34);
|
||
}
|
||
|
||
var x1 = 0;//tableLeft-tablePadding ;
|
||
var y1 = 750;
|
||
var w2 = 596;
|
||
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo3)
|
||
{
|
||
pageHeight=820;
|
||
// var left = 25;//250;//headerRight ;
|
||
y=pageHeight-logoImages.imageLogoHeight3;
|
||
//var headerRight=370;
|
||
|
||
//var left = headerRight - invoice.imageLogoWidth3;
|
||
doc.addImage(logoImages.imageLogo3, 'JPEG', 40, y, logoImages.imageLogoWidth3, logoImages.imageLogoHeight3);
|
||
}
|
||
|
||
doc.setFontSize(10);
|
||
var marginLeft = 340;
|
||
displayAccount(doc, invoice, marginLeft, 780, layout);
|
||
}
|
||
|
||
|
||
|
||
function GetReportTemplate3(doc, invoice, layout, checkMath)
|
||
{
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 400;
|
||
layout.rowHeight = 15;
|
||
|
||
|
||
doc.setFontSize(7);
|
||
|
||
Report3AddHeader(invoice, layout, doc);
|
||
|
||
if (invoice.image)
|
||
{
|
||
y=130;
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, y);
|
||
}
|
||
|
||
Report3AddFooter (invoice, account, doc, layout);
|
||
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontSize('8');
|
||
var detailsHeight = displayInvoice(doc, invoice, layout.headerRight, layout.accountTop-10, layout);
|
||
layout.headerTop = Math.max(layout.headerTop, detailsHeight + 50);
|
||
layout.tableTop = Math.max(layout.tableTop, detailsHeight + 150);
|
||
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontSize(7);
|
||
doc.setFontType("normal");
|
||
displayClient(doc, invoice, layout.headerRight, layout.headerTop, layout);
|
||
|
||
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontType('bold');
|
||
|
||
doc.setLineWidth(0.3);
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
setDocHexDraw(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setDrawColor(63,60,60);
|
||
doc.setFillColor(63,60,60);
|
||
}
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = layout.tableTop - layout.tablePadding;
|
||
var width = layout.marginRight - (2 * layout.tablePadding);
|
||
var height = 20;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
SetPdfColor('Black',doc);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
|
||
var height1 = displayNotesAndTerms(doc, layout, invoice, y);
|
||
var height2 = displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
y += Math.max(height1, height2);
|
||
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = y - layout.tablePadding;
|
||
var width = layout.marginRight - (2 * layout.tablePadding);
|
||
var height = 20;
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
setDocHexDraw(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setDrawColor(63,60,60);
|
||
doc.setFillColor(63,60,60);
|
||
}
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontType('bold');
|
||
SetPdfColor('White', doc);
|
||
doc.setFontSize(12);
|
||
|
||
var label = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var labelX = layout.unitCostRight-(doc.getStringUnitWidth(label) * doc.internal.getFontSize());
|
||
doc.text(labelX, y+2, label);
|
||
|
||
|
||
doc.setFontType('normal');
|
||
var amount = formatMoney(invoice.balance_amount , currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var amountX = layout.lineTotalRight - (doc.getStringUnitWidth(amount) * doc.internal.getFontSize());
|
||
doc.text(amountX, y+2, amount);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
function Report3AddHeader (invoice, layout, doc)
|
||
{
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setDrawColor(242,101,34);
|
||
doc.setFillColor(242,101,34);
|
||
}
|
||
|
||
var x1 =0;
|
||
var y1 = 0;
|
||
var w2 = 595;
|
||
var h2 = Math.max(110, getInvoiceDetailsHeight(invoice, layout) + 30);
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
SetPdfColor('White',doc);
|
||
|
||
//second column
|
||
doc.setFontType('bold');
|
||
var MaxWidth=594;
|
||
var LineOne= invoice.account.name;
|
||
var AlignLine = MaxWidth-30- (doc.getStringUnitWidth(LineOne) * doc.internal.getFontSize());
|
||
if (LineOne) {
|
||
doc.setFontSize('30');
|
||
doc.setFontType('bold');
|
||
doc.text(40, 50, LineOne);
|
||
}
|
||
}
|
||
|
||
|
||
function Report1AddNewPage(invoice,account,doc)
|
||
{
|
||
doc.addPage();
|
||
if (logoImages.imageLogo1)
|
||
{
|
||
pageHeight=820;
|
||
y=pageHeight-logoImages.imageLogoHeight1;
|
||
var left = 20;//headerRight - invoice.imageLogoWidth1;
|
||
doc.addImage(logoImages.imageLogo1, 'JPEG', left, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);
|
||
|
||
}
|
||
|
||
GlobalY = 40;
|
||
return GlobalY;
|
||
}
|
||
|
||
function displayAccount(doc, invoice, x, y, layout) {
|
||
var account = invoice.account;
|
||
|
||
if (!account) {
|
||
return;
|
||
}
|
||
|
||
var data = [
|
||
account.name,
|
||
account.work_email,
|
||
account.work_phone
|
||
];
|
||
|
||
displayGrid(doc, invoice, data, x, y, layout, true);
|
||
|
||
data = [
|
||
concatStrings(account.address1, account.address2),
|
||
concatStrings(account.city, account.state, account.postal_code),
|
||
account.country ? account.country.name : false
|
||
];
|
||
|
||
var nameWidth = doc.getStringUnitWidth(account.name) * doc.internal.getFontSize() * 1.1;
|
||
var emailWidth = doc.getStringUnitWidth(account.work_email) * doc.internal.getFontSize() * 1.1;
|
||
width = Math.max(emailWidth, nameWidth, 120);
|
||
|
||
x += width;
|
||
|
||
displayGrid(doc, invoice, data, x, y, layout);
|
||
}
|
||
|
||
|
||
function displayClient(doc, invoice, x, y, layout) {
|
||
var client = invoice.client;
|
||
if (!client) {
|
||
return;
|
||
}
|
||
var data = [
|
||
getClientDisplayName(client),
|
||
concatStrings(client.address1, client.address2),
|
||
concatStrings(client.city, client.state, client.postal_code),
|
||
client.country ? client.country.name : false,
|
||
client.contacts[0].email
|
||
];
|
||
|
||
return displayGrid(doc, invoice, data, x, y, layout, true);
|
||
}
|
||
|
||
function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
|
||
if (!invoice) {
|
||
return;
|
||
}
|
||
|
||
var data = getInvoiceDetails(invoice);
|
||
return displayGrid(doc, invoice, data, x, y, layout, true, rightAlignX);
|
||
}
|
||
|
||
function getInvoiceDetails(invoice) {
|
||
return [
|
||
{'invoice_number': invoice.invoice_number},
|
||
{'po_number': invoice.po_number},
|
||
{'invoice_date': invoice.invoice_date},
|
||
{'due_date': invoice.due_date},
|
||
{'custom_label1': invoice.account.custom_value1},
|
||
{'custom_label2': invoice.account.custom_value2},
|
||
{'custom_client_label1': invoice.client.custom_value1},
|
||
{'custom_client_label2': invoice.client.custom_value2},
|
||
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)},
|
||
];
|
||
}
|
||
|
||
function getInvoiceDetailsHeight(invoice, layout) {
|
||
var data = getInvoiceDetails(invoice);
|
||
var count = 0;
|
||
for (var key in data) {
|
||
if (!data.hasOwnProperty(key)) {
|
||
continue;
|
||
}
|
||
var obj = data[key];
|
||
for (var subKey in obj) {
|
||
if (!obj.hasOwnProperty(subKey)) {
|
||
continue;
|
||
}
|
||
if (obj[subKey]) {
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
return count * layout.rowHeight;
|
||
}
|
||
|
||
function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
||
{
|
||
if (!invoice) {
|
||
return;
|
||
}
|
||
|
||
//var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
|
||
var data = [
|
||
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
||
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
||
{'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
||
{'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
||
];
|
||
|
||
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
|
||
}
|
||
|
||
function concatStrings() {
|
||
var concatStr = '';
|
||
var data = [];
|
||
for (var i=0; i<arguments.length; i++) {
|
||
var string = arguments[i];
|
||
if (string) {
|
||
data.push(string);
|
||
}
|
||
}
|
||
for (var i=0; i<data.length; i++) {
|
||
concatStr += data[i];
|
||
if (i == 0 && data.length > 1) {
|
||
concatStr += ', ';
|
||
} else if (i < data.length -1) {
|
||
concatStr += ' ';
|
||
}
|
||
}
|
||
return data.length ? concatStr : false;
|
||
}
|
||
|
||
function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, rightAlignTitleX) {
|
||
var numLines = 0;
|
||
var origY = y;
|
||
for (var i=0; i<data.length; i++) {
|
||
doc.setFontType('normal');
|
||
|
||
if (invoice.invoice_design_id == 1 && i > 0 && origY === layout.accountTop) {
|
||
SetPdfColor('GrayText',doc);
|
||
}
|
||
|
||
var row = data[i];
|
||
if (!row) {
|
||
continue;
|
||
}
|
||
|
||
if (hasheader && i === 0 && !rightAlignTitleX) {
|
||
doc.setFontType('bold');
|
||
}
|
||
|
||
if (typeof row === 'object') {
|
||
for (var key in row) {
|
||
if (row.hasOwnProperty(key)) {
|
||
var value = row[key] ? row[key] + '' : false;
|
||
}
|
||
}
|
||
if (!value) {
|
||
continue;
|
||
}
|
||
|
||
var marginLeft;
|
||
if (rightAlignX) {
|
||
marginLeft = rightAlignX - (doc.getStringUnitWidth(value) * doc.internal.getFontSize());
|
||
} else {
|
||
marginLeft = x + 80;
|
||
}
|
||
doc.text(marginLeft, y, value);
|
||
|
||
doc.setFontType('normal');
|
||
if (invoice.is_quote) {
|
||
if (key == 'invoice_number') {
|
||
key = 'quote_number';
|
||
} else if (key == 'invoice_date') {
|
||
key = 'quote_date';
|
||
} else if (key == 'balance_due') {
|
||
key = 'total';
|
||
}
|
||
}
|
||
|
||
if (key.substring(0, 6) === 'custom') {
|
||
key = invoice.account[key];
|
||
} else {
|
||
key = invoiceLabels[key];
|
||
}
|
||
|
||
if (rightAlignTitleX) {
|
||
marginLeft = rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize());
|
||
} else {
|
||
marginLeft = x;
|
||
}
|
||
|
||
doc.text(marginLeft, y, key);
|
||
} else {
|
||
doc.text(x, y, row);
|
||
}
|
||
|
||
numLines++;
|
||
y += layout.rowHeight;
|
||
}
|
||
|
||
return numLines * layout.rowHeight;
|
||
}
|
||
|
||
function displayNotesAndTerms(doc, layout, invoice, y)
|
||
{
|
||
doc.setFontType("normal");
|
||
var origY = y;
|
||
|
||
if (invoice.public_notes) {
|
||
doc.text(layout.marginLeft, y, invoice.public_notes);
|
||
y += 16 + (doc.splitTextToSize(invoice.public_notes, 300).length * doc.internal.getFontSize());
|
||
}
|
||
|
||
if (invoice.terms) {
|
||
doc.setFontType("bold");
|
||
doc.text(layout.marginLeft, y, invoiceLabels.terms);
|
||
y += 16;
|
||
doc.setFontType("normal");
|
||
doc.text(layout.marginLeft, y, invoice.terms);
|
||
y += 16 + (doc.splitTextToSize(invoice.terms, 300).length * doc.internal.getFontSize());
|
||
}
|
||
|
||
return y - origY;
|
||
}
|
||
|
||
function calculateAmounts(invoice) {
|
||
var total = 0;
|
||
var hasTaxes = false;
|
||
|
||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||
var item = invoice.invoice_items[i];
|
||
var tax = 0;
|
||
if (item.tax && parseFloat(item.tax.rate)) {
|
||
tax = parseFloat(item.tax.rate);
|
||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||
tax = parseFloat(item.tax_rate);
|
||
}
|
||
|
||
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||
if (tax) {
|
||
lineTotal += roundToTwo(lineTotal * tax / 100);
|
||
}
|
||
if (lineTotal) {
|
||
total += lineTotal;
|
||
}
|
||
|
||
if ((item.tax && item.tax.rate > 0) || (item.tax_rate && parseFloat(item.tax_rate) > 0)) {
|
||
hasTaxes = true;
|
||
}
|
||
}
|
||
|
||
invoice.subtotal_amount = total;
|
||
|
||
if (invoice.discount > 0) {
|
||
|
||
var discount = roundToTwo(total * (invoice.discount/100));
|
||
total -= discount;
|
||
}
|
||
|
||
var tax = 0;
|
||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||
tax = parseFloat(invoice.tax.rate);
|
||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||
tax = parseFloat(invoice.tax_rate);
|
||
}
|
||
|
||
if (tax) {
|
||
var tax = roundToTwo(total * (tax/100));
|
||
total = parseFloat(total) + parseFloat(tax);
|
||
}
|
||
|
||
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
|
||
invoice.tax_amount = tax;
|
||
invoice.discount_amount = discount;
|
||
invoice.has_taxes = hasTaxes;
|
||
|
||
return invoice;
|
||
}
|
||
|
||
function getInvoiceTaxRate(invoice) {
|
||
var tax = 0;
|
||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||
tax = parseFloat(invoice.tax.rate);
|
||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||
tax = parseFloat(invoice.tax_rate);
|
||
}
|
||
return tax;
|
||
}
|
||
|
||
function displayInvoiceHeader(doc, invoice, layout) {
|
||
|
||
var costX = layout.unitCostRight - (doc.getStringUnitWidth(invoiceLabels.unit_cost) * doc.internal.getFontSize());
|
||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(invoiceLabels.quantity) * doc.internal.getFontSize());
|
||
var taxX = layout.taxRight - (doc.getStringUnitWidth(invoiceLabels.tax) * doc.internal.getFontSize());
|
||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(invoiceLabels.line_total) * doc.internal.getFontSize());
|
||
|
||
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
|
||
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
|
||
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
|
||
doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
|
||
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
|
||
|
||
if (invoice.has_taxes)
|
||
{
|
||
doc.text(taxX, layout.tableTop, invoiceLabels.tax);
|
||
}
|
||
|
||
}
|
||
|
||
function displayInvoiceItems(doc, invoice, layout) {
|
||
doc.setFontType("normal");
|
||
|
||
var line = 1;
|
||
var total = 0;
|
||
var shownItem = false;
|
||
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
|
||
var tableTop = layout.tableTop;
|
||
|
||
doc.setFontSize(8);
|
||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||
var item = invoice.invoice_items[i];
|
||
var numLines = doc.splitTextToSize(item.notes, 200).length + 2;
|
||
//console.log('num lines %s', numLines);
|
||
|
||
var y = tableTop + (line * layout.tableRowHeight) + (2 * layout.tablePadding);
|
||
var top = y - layout.tablePadding;
|
||
var newTop = top + (numLines * layout.tableRowHeight);
|
||
|
||
if (newTop > 770) {
|
||
line = 0;
|
||
tableTop = layout.accountTop + layout.tablePadding;
|
||
y = tableTop;
|
||
top = y - layout.tablePadding;
|
||
newTop = top + (numLines * layout.tableRowHeight);
|
||
doc.addPage();
|
||
}
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var width = layout.marginRight + layout.tablePadding;
|
||
|
||
var cost = formatMoney(item.cost, currencyId, true);
|
||
var qty = NINJA.parseFloat(item.qty) ? NINJA.parseFloat(item.qty) + '' : '';
|
||
var notes = item.notes;
|
||
var productKey = item.product_key;
|
||
var tax = 0;
|
||
if (item.tax && parseFloat(item.tax.rate)) {
|
||
tax = parseFloat(item.tax.rate);
|
||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||
tax = parseFloat(item.tax_rate);
|
||
}
|
||
|
||
// show at most one blank line
|
||
if (shownItem && (!cost || cost == '0.00') && !qty && !notes && !productKey) {
|
||
continue;
|
||
}
|
||
shownItem = true;
|
||
|
||
// process date variables
|
||
if (invoice.is_recurring) {
|
||
notes = processVariables(notes);
|
||
productKey = processVariables(productKey);
|
||
}
|
||
|
||
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||
if (tax) {
|
||
lineTotal += lineTotal * tax / 100;
|
||
}
|
||
if (lineTotal) {
|
||
total += lineTotal;
|
||
}
|
||
lineTotal = formatMoney(lineTotal, currencyId, true);
|
||
|
||
var costX = layout.unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize());
|
||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
||
var taxX = layout.taxRight - (doc.getStringUnitWidth(tax+'%') * doc.internal.getFontSize());
|
||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
|
||
//if (i==0) y -= 4;
|
||
|
||
line += numLines;
|
||
|
||
|
||
if (invoice.invoice_design_id == 1) {
|
||
if (i%2 == 0) {
|
||
doc.setDrawColor(255,255,255);
|
||
doc.setFillColor(246,246,246);
|
||
doc.rect(left, top, width-left, newTop-top, 'FD');
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(200,200,200);
|
||
doc.line(left, top, width, top);
|
||
doc.line(left, newTop, width, newTop);
|
||
}
|
||
} else if (invoice.invoice_design_id == 2) {
|
||
if (i%2 == 0) {
|
||
left = 0;
|
||
width = 1000;
|
||
|
||
doc.setDrawColor(255,255,255);
|
||
doc.setFillColor(235,235,235);
|
||
doc.rect(left, top, width-left, newTop-top, 'FD');
|
||
|
||
}
|
||
} else {
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(150,150,150);
|
||
doc.line(left, newTop, width, newTop);
|
||
}
|
||
|
||
y += 4;
|
||
|
||
if (invoice.invoice_design_id == 1) {
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
} else if (invoice.invoice_design_id == 2) {
|
||
SetPdfColor('SomeGreen', doc, 'primary');
|
||
} else if (invoice.invoice_design_id == 3) {
|
||
doc.setFontType('bold');
|
||
} else {
|
||
SetPdfColor('Black', doc);
|
||
}
|
||
doc.text(layout.marginLeft, y+2, productKey);
|
||
|
||
SetPdfColor('Black', doc);
|
||
doc.setFontType('normal');
|
||
|
||
doc.text(layout.descriptionLeft, y+2, notes);
|
||
doc.text(costX, y+2, cost);
|
||
doc.text(qtyX, y+2, qty);
|
||
doc.text(totalX, y+2, lineTotal);
|
||
|
||
if (tax) {
|
||
doc.text(taxX, y+2, tax+'%');
|
||
}
|
||
}
|
||
|
||
y = tableTop + (line * layout.tableRowHeight) + (3 * layout.tablePadding);
|
||
var cutoff = 700;
|
||
if (invoice.terms) {
|
||
cutoff -= 50;
|
||
}
|
||
if (invoice.public_notes) {
|
||
cutoff -= 50;
|
||
}
|
||
|
||
if (y > cutoff) {
|
||
doc.addPage();
|
||
return layout.marginLeft;
|
||
}
|
||
|
||
return y;
|
||
}
|
||
|
||
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript
|
||
function objectEquals(x, y) {
|
||
// if both are function
|
||
if (x instanceof Function) {
|
||
if (y instanceof Function) {
|
||
return x.toString() === y.toString();
|
||
}
|
||
return false;
|
||
}
|
||
if (x === null || x === undefined || y === null || y === undefined) { return x === y; }
|
||
if (x === y || x.valueOf() === y.valueOf()) { return true; }
|
||
|
||
// if one of them is date, they must had equal valueOf
|
||
if (x instanceof Date) { return false; }
|
||
if (y instanceof Date) { return false; }
|
||
|
||
// if they are not function or strictly equal, they both need to be Objects
|
||
if (!(x instanceof Object)) { return false; }
|
||
if (!(y instanceof Object)) { return false; }
|
||
|
||
var p = Object.keys(x);
|
||
return Object.keys(y).every(function (i) { return p.indexOf(i) !== -1; }) ?
|
||
p.every(function (i) { return objectEquals(x[i], y[i]); }) : false;
|
||
}
|
||
|
||
|
||
|
||
/*\
|
||
|*|
|
||
|*| Base64 / binary data / UTF-8 strings utilities
|
||
|*|
|
||
|*| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
|
||
|*|
|
||
\*/
|
||
|
||
/* Array of bytes to base64 string decoding */
|
||
|
||
function b64ToUint6 (nChr) {
|
||
|
||
return nChr > 64 && nChr < 91 ?
|
||
nChr - 65
|
||
: nChr > 96 && nChr < 123 ?
|
||
nChr - 71
|
||
: nChr > 47 && nChr < 58 ?
|
||
nChr + 4
|
||
: nChr === 43 ?
|
||
62
|
||
: nChr === 47 ?
|
||
63
|
||
:
|
||
0;
|
||
|
||
}
|
||
|
||
function base64DecToArr (sBase64, nBlocksSize) {
|
||
|
||
var
|
||
sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
|
||
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
|
||
|
||
for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
|
||
nMod4 = nInIdx & 3;
|
||
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
|
||
if (nMod4 === 3 || nInLen - nInIdx === 1) {
|
||
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
|
||
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
|
||
}
|
||
nUint24 = 0;
|
||
|
||
}
|
||
}
|
||
|
||
return taBytes;
|
||
}
|
||
|
||
/* Base64 string to array encoding */
|
||
|
||
function uint6ToB64 (nUint6) {
|
||
|
||
return nUint6 < 26 ?
|
||
nUint6 + 65
|
||
: nUint6 < 52 ?
|
||
nUint6 + 71
|
||
: nUint6 < 62 ?
|
||
nUint6 - 4
|
||
: nUint6 === 62 ?
|
||
43
|
||
: nUint6 === 63 ?
|
||
47
|
||
:
|
||
65;
|
||
|
||
}
|
||
|
||
function base64EncArr (aBytes) {
|
||
|
||
var nMod3 = 2, sB64Enc = "";
|
||
|
||
for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
|
||
nMod3 = nIdx % 3;
|
||
if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
|
||
nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
|
||
if (nMod3 === 2 || aBytes.length - nIdx === 1) {
|
||
sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
|
||
nUint24 = 0;
|
||
}
|
||
}
|
||
|
||
return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? '' : nMod3 === 1 ? '=' : '==');
|
||
|
||
}
|
||
|
||
/* UTF-8 array to DOMString and vice versa */
|
||
|
||
function UTF8ArrToStr (aBytes) {
|
||
|
||
var sView = "";
|
||
|
||
for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {
|
||
nPart = aBytes[nIdx];
|
||
sView += String.fromCharCode(
|
||
nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */
|
||
/* (nPart - 252 << 32) is not possible in ECMAScript! So...: */
|
||
(nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
|
||
: nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */
|
||
(nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
|
||
: nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */
|
||
(nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
|
||
: nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */
|
||
(nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
|
||
: nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */
|
||
(nPart - 192 << 6) + aBytes[++nIdx] - 128
|
||
: /* nPart < 127 ? */ /* one byte */
|
||
nPart
|
||
);
|
||
}
|
||
|
||
return sView;
|
||
|
||
}
|
||
|
||
function strToUTF8Arr (sDOMStr) {
|
||
|
||
var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;
|
||
|
||
/* mapping... */
|
||
|
||
for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {
|
||
nChr = sDOMStr.charCodeAt(nMapIdx);
|
||
nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;
|
||
}
|
||
|
||
aBytes = new Uint8Array(nArrLen);
|
||
|
||
/* transcription... */
|
||
|
||
for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {
|
||
nChr = sDOMStr.charCodeAt(nChrIdx);
|
||
if (nChr < 128) {
|
||
/* one byte */
|
||
aBytes[nIdx++] = nChr;
|
||
} else if (nChr < 0x800) {
|
||
/* two bytes */
|
||
aBytes[nIdx++] = 192 + (nChr >>> 6);
|
||
aBytes[nIdx++] = 128 + (nChr & 63);
|
||
} else if (nChr < 0x10000) {
|
||
/* three bytes */
|
||
aBytes[nIdx++] = 224 + (nChr >>> 12);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr & 63);
|
||
} else if (nChr < 0x200000) {
|
||
/* four bytes */
|
||
aBytes[nIdx++] = 240 + (nChr >>> 18);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr & 63);
|
||
} else if (nChr < 0x4000000) {
|
||
/* five bytes */
|
||
aBytes[nIdx++] = 248 + (nChr >>> 24);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr & 63);
|
||
} else /* if (nChr <= 0x7fffffff) */ {
|
||
/* six bytes */
|
||
aBytes[nIdx++] = 252 + /* (nChr >>> 32) is not possible in ECMAScript! So...: */ (nChr / 1073741824);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
|
||
aBytes[nIdx++] = 128 + (nChr & 63);
|
||
}
|
||
}
|
||
|
||
return aBytes;
|
||
|
||
}
|
||
|
||
|
||
|
||
function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
|
||
function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
|
||
function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
|
||
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
|
||
function setDocHexColor(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setTextColor(r, g, b);
|
||
}
|
||
function setDocHexFill(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setFillColor(r, g, b);
|
||
}
|
||
function setDocHexDraw(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setDrawColor(r, g, b);
|
||
}
|
||
|
||
function openUrl(url, track) {
|
||
trackUrl(track ? track : url);
|
||
window.open(url, '_blank');
|
||
}
|
||
|
||
function toggleDatePicker(field) {
|
||
$('#'+field).datepicker('show');
|
||
}
|
||
|
||
function roundToTwo(num, toString) {
|
||
var val = +(Math.round(num + "e+2") + "e-2");
|
||
return toString ? val.toFixed(2) : val;
|
||
}
|
||
|
||
|