html >
< html lang= "en" >
< head >
< meta charset= "UTF-8" >
< title > Titletitle >
< style >
#user
{
width : 80 px ;
}
#msg
{
width : 450 px ;
}
style >
< script src= "js/jquery-3.2.1.js" > script >
head >
< body >
< textarea rows= "30" cols= "80" id= "chatArea" readonly > textarea >< br >
< input id= "user" type= "text" > :
< input id= "msg" type= "text" >
< button > 发送button >
< script >
$ ("button" ).click (function () {
var msg ={name :$ ("#user" ).val (),msg :$ ("#msg" ).val ()};
if (msg .name .trim ().length ===0 || msg .msg .trim ().length ===0 ) return ;
sendMsg (msg );
$ ("#msg" ).val ("" );
});
setInterval (sendMsg ,20 );
function sendMsg (msg) {
$ .post ("http://192.168.27.78:3002" ,msg,function (res) {
res=JSON .parse (decodeURIComponent (res));
var str ="" ;
for (var i =0 ;i length ;i ++){
str +=res[i ].name +":" +res[i ].msg +" \n " ;
}
$ ("#chatArea" ).val (str );
})
}
script >
body >
html >
服务器 nodejs
var http =require ("http" );
var querystring =require ("querystring" );
var chatList =[];
var server =http .createServer(function (req,res){
var msg ="" ;
req.on ("data" ,function (data) {
msg +=data;
});
req.on ("end" ,function () {
if (msg ){
var s =querystring .parse (msg );
chatList .push (s );
if (chatList .length >100 ){
chatList .shift ();
}
}
res.writeHead(200 ,{"Content-Type" :"text/plain" ,"Access-Control-Allow-Origin" :"*" });
res.write (encodeURIComponent (JSON .stringify (chatList )));
res.end ();
})
});
server .listen(3002 ,"192.168.27.78" ,function (){
console .log ("开始监听..." );
});
jquery-3.2.1.js
/*!
* jQuery JavaScript Library v3.2.1
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2017-03-20T18:59Z
*/
( function ( global, factory ) {
"use strict" ;
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 have a `window` with a `document`
// (such as Node.js), expose a 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 ) {
// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
// enough that all such attempts are guarded in a try block.
"use strict" ;
var arr = [];
var document = window.document ;
var getProto = Object.getPrototypeOf ;
var slice = arr .slice ;
var concat = arr .concat ;
var push = arr .push ;
var indexOf = arr .indexOf ;
var class2type = {};
var toString = class2type .toString ;
var hasOwn = class2type .hasOwnProperty ;
var fnToString = hasOwn .toString ;
var ObjectFunctionString = fnToString .call ( Object );
var support = {};
function DOMEval ( code, doc ) {
doc = doc || document ;
var script = doc.createElement ( "script" );
script .text = code;
doc.head .appendChild ( script ).parentNode .removeChild ( script );
}
/* global Symbol */
// Defining this global in .eslintrc.json would create a danger of using the global
// unguarded in another place, it seems safer to define global only for this module
var
version = "3.2.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.0 only
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g ,
// Matches dashed string for camelizing
rmsPrefix = /^-ms-/ ,
rdashAlpha = /-([a-z])/g ,
// 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 ,
// 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 all the elements in a clean array
if ( num == null ) {
return slice .call ( this );
}
// Return just the one element from the set
return num < 0 ? this [ num + this .length ] : this [ num ];
},
// 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 ;
// Return the newly-formed element set
return ret ;
},
// Execute a callback for every element in the matched set.
each : function ( callback ) {
return jQuery .each ( this , callback );
},
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 ();
},
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push : push ,
sort : arr .sort ,
splice : arr .splice
};
jQuery .extend = jQuery .fn .extend = function () {
var options , name , src , copy , copyIsArray , 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 = Array.isArray ( copy ) ) ) ) {
if ( copyIsArray ) {
copyIsArray = false ;
clone = src && Array.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 () {},
isFunction : function ( obj ) {
return jQuery .type ( obj ) === "function" ;
},
isWindow : function ( obj ) {
return obj != null && obj === obj.window ;
},
isNumeric : function ( obj ) {
// As of jQuery 3.0, isNumeric is limited to
// strings and numbers (primitives or objects)
// that can be coerced to finite numbers (gh-2662)
var type = jQuery .type ( obj );
return ( type === "number" || type === "string" ) &&
// parseFloat NaNs numeric-cast false positives ("")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
!isNaN ( obj - parseFloat ( obj ) );
},
isPlainObject : function ( obj ) {
var proto , Ctor ;
// Detect obvious negatives
// Use toString instead of jQuery.type to catch host objects
if ( !obj || toString .call ( obj ) !== "[object Object]" ) {
return false ;
}
proto = getProto ( obj );
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if ( !proto ) {
return true ;
}
// Objects with prototype are plain iff they were constructed by a global Object function
Ctor = hasOwn .call ( proto , "constructor" ) && proto .constructor ;
return typeof Ctor === "function" && fnToString .call ( Ctor ) === ObjectFunctionString ;
},
isEmptyObject : function ( obj ) {
/* eslint-disable no-unused-vars */
// See https://github.com/eslint/eslint/issues/6125
var name ;
for ( name in obj ) {
return false ;
}
return true ;
},
type : function ( obj ) {
if ( obj == null ) {
return obj + "" ;
}
// Support: Android <=2.3 only (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type [ toString .call ( obj ) ] || "object" :
typeof obj;
},
// Evaluates a script in a global context
globalEval : function ( code ) {
DOMEval ( code );
},
// Convert dashed to camelCase; used by the css and data modules
// Support: IE <=9 - 11, Edge 12 - 13
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase : function ( string ) {
return string.replace ( rmsPrefix , "ms-" ).replace ( rdashAlpha , fcamelCase );
},
each : function ( obj, callback ) {
var length , i = 0 ;
if ( isArrayLike ( obj ) ) {
length = obj.length ;
for ( ; i < length ; i ++ ) {
if ( callback.call ( obj[ i ], i , obj[ i ] ) === false ) {
break ;
}
}
} else {
for ( i in obj ) {
if ( callback.call ( obj[ i ], i , obj[ i ] ) === false ) {
break ;
}
}
}
return obj;
},
// Support: Android <=4.0 only
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 ) {
return arr == null ? -1 : indexOf .call ( arr, elem, i );
},
// Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
merge : function ( first, second ) {
var len = +second.length ,
j = 0 ,
i = first.length ;
for ( ; j < len ; j ++ ) {
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 length , value ,
i = 0 ,
ret = [];
// Go through the array, translating each of the items to their new values
if ( isArrayLike ( elems ) ) {
length = elems.length ;
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 tmp , args , proxy ;
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 : Date.now ,
// jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support : support
} );
if ( typeof Symbol === "function" ) {
jQuery .fn [ Symbol .iterator ] = arr [ Symbol .iterator ];
}
// Populate the class2type map
jQuery .each ( "Boolean Number String Function Array Date RegExp Object Error Symbol" .split ( " " ),
function ( i, name ) {
class2type [ "[object " + name + "]" ] = name.toLowerCase ();
} );
function isArrayLike ( obj ) {
// Support: real iOS 8.2 only (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = !!obj && "length" in obj && obj.length ,
type = jQuery .type ( obj );
if ( type === "function" || jQuery .isWindow ( obj ) ) {
return false ;
}
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}
var Sizzle =
/*!
* Sizzle CSS Selector Engine v2.3.3
* https://sizzlejs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2016-08-08
*/
(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" + 1 * 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 ;
},
// Instance methods
hasOwn = ({}).hasOwnProperty ,
arr = [],
pop = arr .pop ,
push_native = arr .push ,
push = arr .push ,
slice = arr .slice ,
// Use a stripped-down indexOf as it's faster than native
// https://jsperf.com/thor-indexof-vs-for/5
indexOf = function ( list, elem ) {
var i = 0 ,
len = list.length ;
for ( ; i < len ; i ++ ) {
if ( list[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
// http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[ \\ x20 \\ t \\ r \\ n \\ f]" ,
// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
identifier = "(?: \\\\ .|[ \\ w-]|[^ \0 - \\ xa0])+" ,
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
attributes = " \\ [" + whitespace + "*(" + identifier + ")(?:" + whitespace +
// Operator (capture 2)
"*([*^$|!~]?=)" + whitespace +
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
"*(?:'((?: \\\\ .|[^ \\\\ '])*)'| \" ((?: \\\\ .|[^ \\\\\" ])*) \" |(" + identifier + "))|)" + whitespace +
"* \\ ]" ,
pseudos = ":(" + identifier + ")(?: \\ ((" +
// 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
rwhitespace = new RegExp( whitespace + "+" , "g" ),
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( "^#(" + identifier + ")" ),
"CLASS" : new RegExp( "^ \\ .(" + identifier + ")" ),
"TAG" : new RegExp( "^(" + identifier + "|[*])" ),
"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 = /[+~]/ ,
// 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 );
},
// CSS string/identifier serialization
// https://drafts.csswg.org/cssom/#common-serializing-idioms
rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g ,
fcssescape = function ( ch, asCodePoint ) {
if ( asCodePoint ) {
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
if ( ch === " \0 " ) {
return " \uFFFD " ;
}
// Control characters and (dependent upon position) numbers get escaped as code points
return ch.slice ( 0 , -1 ) + " \\ " + ch.charCodeAt ( ch.length - 1 ).toString ( 16 ) + " " ;
}
// Other potentially-special ASCII characters get backslash-escaped
return " \\ " + ch;
},
// Used for iframes
// See setDocument()
// Removing the function wrapper causes a "Permission Denied"
// error in IE
unloadHandler = function () {
setDocument ();
},
disabledAncestor = addCombinator (
function ( elem ) {
return elem.disabled === true && ("form" in elem || "label" in elem);
},
{ dir : "parentNode" , next : "legend" }
);
// 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 m , i , elem , nid , match , groups , newSelector ,
newContext = context && context.ownerDocument ,
// nodeType defaults to 9, since context defaults to document
nodeType = context ? context.nodeType : 9 ;
results = results || [];
// Return early from calls with invalid selector or context
if ( typeof selector !== "string" || !selector ||
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
return results;
}
// Try to shortcut find operations (as opposed to filters) in HTML documents
if ( !seed ) {
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
setDocument ( context );
}
context = context || document ;
if ( documentIsHTML ) {
// If the selector is sufficiently simple, try using a "get*By*" DOM method
// (excepting DocumentFragment context, where the methods don't exist)
if ( nodeType !== 11 && (match = rquickExpr .exec ( selector )) ) {
// ID selector
if ( (m = match [1 ]) ) {
// Document context
if ( nodeType === 9 ) {
if ( (elem = context.getElementById ( m )) ) {
// Support: IE, Opera, Webkit
// TODO: identify versions
// getElementById can match elements by name instead of ID
if ( elem .id === m ) {
results.push ( elem );
return results;
}
} else {
return results;
}
// Element context
} else {
// Support: IE, Opera, Webkit
// TODO: identify versions
// getElementById can match elements by name instead of ID
if ( newContext && (elem = newContext .getElementById ( m )) &&
contains ( context, elem ) &&
elem .id === m ) {
results.push ( elem );
return results;
}
}
// Type selector
} else if ( match [2 ] ) {
push .apply ( results, context.getElementsByTagName ( selector ) );
return results;
// Class selector
} else if ( (m = match [3 ]) && support .getElementsByClassName &&
context.getElementsByClassName ) {
push .apply ( results, context.getElementsByClassName ( m ) );
return results;
}
}
// Take advantage of querySelectorAll
if ( support .qsa &&
!compilerCache [ selector + " " ] &&
(!rbuggyQSA || !rbuggyQSA .test ( selector )) ) {
if ( nodeType !== 1 ) {
newContext = context;
newSelector = selector;
// qSA looks outside Element context, which is not what we want
// Thanks to Andrew Dupont for this workaround technique
// Support: IE <=8
// Exclude object elements
} else if ( context.nodeName .toLowerCase () !== "object" ) {
// Capture the context ID, setting it first if necessary
if ( (nid = context.getAttribute ( "id" )) ) {
nid = nid .replace ( rcssescape , fcssescape );
} else {
context.setAttribute ( "id" , (nid = expando ) );
}
// Prefix every selector in the list
groups = tokenize ( selector );
i = groups .length ;
while ( i -- ) {
groups [i ] = "#" + nid + " " + toSelector ( groups [i ] );
}
newSelector = groups .join ( "," );
// Expand context for sibling selectors
newContext = rsibling .test ( selector ) && testContext ( context.parentNode ) ||
context;
}
if ( newSelector ) {
try {
push .apply ( results,
newContext .querySelectorAll ( newSelector )
);
return results;
} catch ( qsaError ) {
} finally {
if ( nid === expando ) {
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 element and returns a boolean result
*/
function assert ( fn ) {
var el = document .createElement ("fieldset" );
try {
return !!fn( el );
} catch (e) {
return false ;
} finally {
// Remove from its parent by default
if ( el .parentNode ) {
el .parentNode .removeChild ( el );
}
// release memory in IE
el = 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 = arr .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 &&
a.sourceIndex - b.sourceIndex ;
// 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 :enabled/:disabled
* @param {Boolean} disabled true for :disabled; false for :enabled
*/
function createDisabledPseudo ( disabled ) {
// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
return function ( elem ) {
// Only certain elements can match :enabled or :disabled
// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
if ( "form" in elem ) {
// Check for inherited disabledness on relevant non-disabled elements:
// * listed form-associated elements in a disabled fieldset
// https://html.spec.whatwg.org/multipage/forms.html#category-listed
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
// * option elements in a disabled optgroup
// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
// All such elements have a "form" property.
if ( elem.parentNode && elem.disabled === false ) {
// Option elements defer to a parent optgroup if present
if ( "label" in elem ) {
if ( "label" in elem.parentNode ) {
return elem.parentNode .disabled === disabled;
} else {
return elem.disabled === disabled;
}
}
// Support: IE 6 - 11
// Use the isDisabled shortcut property to check for disabled fieldset ancestors
return elem.isDisabled === disabled ||
// Where there is no isDisabled, check manually
/* jshint -W018 */
elem.isDisabled !== !disabled &&
disabledAncestor ( elem ) === disabled;
}
return elem.disabled === disabled;
// Try to winnow out elements that can't be disabled before trusting the disabled property.
// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
// even exist on them, let alone have a boolean value.
} else if ( "label" in elem ) {
return elem.disabled === disabled;
}
// Remaining elements are neither :enabled nor :disabled
return false ;
};
}
/**
* 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 !== "undefined" && 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 , subWindow ,
doc = node ? node.ownerDocument || node : preferredDoc ;
// Return early if doc is invalid or already selected
if ( doc === document || doc .nodeType !== 9 || !doc .documentElement ) {
return document ;
}
// Update global variables
document = doc ;
docElem = document .documentElement ;
documentIsHTML = !isXML ( document );
// Support: IE 9-11, Edge
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
if ( preferredDoc !== document &&
(subWindow = document .defaultView ) && subWindow .top !== subWindow ) {
// Support: IE 11, Edge
if ( subWindow .addEventListener ) {
subWindow .addEventListener ( "unload" , unloadHandler , false );
// Support: IE 9 - 10 only
} else if ( subWindow .attachEvent ) {
subWindow .attachEvent ( "onunload" , unloadHandler );
}
}
/* Attributes
---------------------------------------------------------------------- */
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support .attributes = assert (function ( el ) {
el.className = "i" ;
return !el.getAttribute ("className" );
});
/* getElement(s)By*
---------------------------------------------------------------------- */
// Check if getElementsByTagName("*") returns only elements
support .getElementsByTagName = assert (function ( el ) {
el.appendChild ( document .createComment ("" ) );
return !el.getElementsByTagName ("*" ).length ;
});
// Support: IE<9
support .getElementsByClassName = rnative .test ( document .getElementsByClassName );
// Support: IE<10
// Check if getElementById returns elements by name
// The broken getElementById methods don't pick up programmatically-set names,
// so use a roundabout getElementsByName test
support .getById = assert (function ( el ) {
docElem .appendChild ( el ).id = expando ;
return !document .getElementsByName || !document .getElementsByName ( expando ).length ;
});
// ID filter and find
if ( support .getById ) {
Expr .filter ["ID" ] = function ( id ) {
var attrId = id.replace ( runescape , funescape );
return function ( elem ) {
return elem.getAttribute ("id" ) === attrId ;
};
};
Expr .find ["ID" ] = function ( id, context ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var elem = context.getElementById ( id );
return elem ? [ elem ] : [];
}
};
} else {
Expr .filter ["ID" ] = function ( id ) {
var attrId = id.replace ( runescape , funescape );
return function ( elem ) {
var node = typeof elem.getAttributeNode !== "undefined" &&
elem.getAttributeNode ("id" );
return node && node .value === attrId ;
};
};
// Support: IE 6 - 7 only
// getElementById is not reliable as a find shortcut
Expr .find ["ID" ] = function ( id, context ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var node , i , elems ,
elem = context.getElementById ( id );
if ( elem ) {
// Verify the id attribute
node = elem .getAttributeNode ("id" );
if ( node && node .value === id ) {
return [ elem ];
}
// Fall back on getElementsByName
elems = context.getElementsByName ( id );
i = 0 ;
while ( (elem = elems [i ++]) ) {
node = elem .getAttributeNode ("id" );
if ( node && node .value === id ) {
return [ elem ];
}
}
}
return [];
}
};
}
// Tag
Expr .find ["TAG" ] = support .getElementsByTagName ?
function ( tag, context ) {
if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName ( tag );
// DocumentFragment nodes don't have gEBTN
} else if ( support .qsa ) {
return context.querySelectorAll ( tag );
}
} :
function ( tag, context ) {
var elem ,
tmp = [],
i = 0 ,
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
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 !== "undefined" && 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 https://bugs.jquery.com/ticket/13378
rbuggyQSA = [];
if ( (support .qsa = rnative .test ( document .querySelectorAll )) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini
assert (function ( el ) {
// 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
// https://bugs.jquery.com/ticket/12359
docElem .appendChild ( el ).innerHTML = " " +
"" +
" " ;
// 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
// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( el.querySelectorAll ("[msallowcapture^='']" ).length ) {
rbuggyQSA .push ( "[*^$]=" + whitespace + "*(?:''| \"\" )" );
}
// Support: IE8
// Boolean attributes and "value" are not treated correctly
if ( !el.querySelectorAll ("[selected]" ).length ) {
rbuggyQSA .push ( " \\ [" + whitespace + "*(?:value|" + booleans + ")" );
}
// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
if ( !el.querySelectorAll ( "[id~=" + expando + "-]" ).length ) {
rbuggyQSA .push ("~=" );
}
// 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 ( !el.querySelectorAll (":checked" ).length ) {
rbuggyQSA .push (":checked" );
}
// Support: Safari 8+, iOS 8+
// https://bugs.webkit.org/show_bug.cgi?id=136851
// In-page `selector#id sibling-combinator selector` fails
if ( !el.querySelectorAll ( "a#" + expando + "+*" ).length ) {
rbuggyQSA .push (".#.+[+~]" );
}
});
assert (function ( el ) {
el.innerHTML = " " +
" " ;
// Support: Windows 8 Native Apps
// The type and name attributes are restricted during .innerHTML assignment
var input = document .createElement ("input" );
input .setAttribute ( "type" , "hidden" );
el.appendChild ( input ).setAttribute ( "name" , "D" );
// Support: IE8
// Enforce case-sensitivity of name attribute
if ( el.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 ( el.querySelectorAll (":enabled" ).length !== 2 ) {
rbuggyQSA .push ( ":enabled" , ":disabled" );
}
// Support: IE9-11+
// IE's :disabled selector does not pick up the children of disabled fieldsets
docElem .appendChild ( el ).disabled = true ;
if ( el.querySelectorAll (":disabled" ).length !== 2 ) {
rbuggyQSA .push ( ":enabled" , ":disabled" );
}
// Opera 10-11 does not throw on post-comma invalid pseudos
el.querySelectorAll ("*,:x" );
rbuggyQSA .push (",.*:" );
});
}
if ( (support .matchesSelector = rnative .test ( (matches = docElem .matches ||
docElem .webkitMatchesSelector ||
docElem .mozMatchesSelector ||
docElem .oMatchesSelector ||
docElem .msMatchesSelector) )) ) {
assert (function ( el ) {
// Check to see if it's possible to do matchesSelector
// on a disconnected node (IE 9)
support .disconnectedMatch = matches .call ( el, "*" );
// This should fail with an exception
// Gecko does not error, returns false instead
matches .call ( el, "[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 self-exclusive
// 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 === document || a.ownerDocument === preferredDoc && contains (preferredDoc , a) ) {
return -1 ;
}
if ( b === document || b.ownerDocument === preferredDoc && contains (preferredDoc , b) ) {
return 1 ;
}
// Maintain original order
return sortInput ?
( indexOf ( sortInput , a ) - indexOf ( 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 === document ? -1 :
b === document ? 1 :
aup ? -1 :
bup ? 1 :
sortInput ?
( indexOf ( sortInput , a ) - indexOf ( 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 document ;
};
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 &&
!compilerCache [ expr + " " ] &&
( !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 .escape = function ( sel ) {
return (sel + "" ).replace ( rcssescape , fcssescape );
};
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 !== "undefined" && 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 .replace ( rwhitespace , " " ) + " " ).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 , uniqueCache , outerCache , node , nodeIndex , start ,
dir = simple !== forward ? "nextSibling" : "previousSibling" ,
parent = elem.parentNode ,
name = ofType && elem.nodeName .toLowerCase (),
useCache = !xml && !ofType ,
diff = false ;
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
// ...in a gzip-friendly way
node = parent ;
outerCache = node [ expando ] || (node [ expando ] = {});
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache [ node .uniqueID ] ||
(outerCache [ node .uniqueID ] = {});
cache = uniqueCache [ type ] || [];
nodeIndex = cache [ 0 ] === dirruns && cache [ 1 ];
diff = nodeIndex && 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 ) {
uniqueCache [ type ] = [ dirruns , nodeIndex , diff ];
break ;
}
}
} else {
// Use previously-cached element index if available
if ( useCache ) {
// ...in a gzip-friendly way
node = elem;
outerCache = node [ expando ] || (node [ expando ] = {});
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache [ node .uniqueID ] ||
(outerCache [ node .uniqueID ] = {});
cache = uniqueCache [ type ] || [];
nodeIndex = cache [ 0 ] === dirruns && cache [ 1 ];
diff = nodeIndex ;
}
// xml :nth-child(...)
// or :nth-last-child(...) or :nth(-last)?-of-type(...)
if ( diff === false ) {
// 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 ) {
outerCache = node [ expando ] || (node [ expando ] = {});
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache [ node .uniqueID ] ||
(outerCache [ node .uniqueID ] = {});
uniqueCache [ 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 ( 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 );
// Don't keep the element (issue #299)
input [0 ] = null ;
return !results .pop ();
};
}),
"has" : markFunction (function ( selector ) {
return function ( elem ) {
return Sizzle ( selector, elem ).length > 0 ;
};
}),
"contains" : markFunction (function ( text ) {
text = text.replace ( runescape , funescape );
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" : createDisabledPseudo ( false ),
"disabled" : createDisabledPseudo ( 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 ,
skip = combinator.next ,
key = skip || dir ,
checkNonElements = base && key === "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 );
}
}
return false ;
} :
// Check against all ancestor/preceding elements
function ( elem, context, xml ) {
var oldCache , uniqueCache , outerCache ,
newCache = [ dirruns , doneName ];
// We can't set arbitrary data on XML nodes, so they don't benefit from combinator 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 ] = {});
// Support: IE <9 only
// Defend against cloned attroperties (jQuery gh-1709)
uniqueCache = outerCache [ elem.uniqueID ] || (outerCache [ elem.uniqueID ] = {});
if ( skip && skip === elem.nodeName .toLowerCase () ) {
elem = elem[ dir ] || elem;
} else if ( (oldCache = uniqueCache [ key ]) &&
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
uniqueCache [ key ] = newCache ;
// A match means we're done; a fail means we have to keep checking
if ( (newCache [ 2 ] = matcher( elem, context, xml )) ) {
return true ;
}
}
}
}
}
return false ;
};
}
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 ( 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 ( checkContext , elem ) > -1 ;
}, implicitRelative , true ),
matchers = [ function ( elem, context, xml ) {
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ?
matchContext ( elem, context, xml ) :
matchAnyContext ( elem, context, xml ) );
// Avoid hanging onto element (issue #299)
checkContext = null ;
return ret ;
} ];
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 || outermost;
}
// Add elements passing elementMatchers directly to results
// Support: IE<9, Safari
// Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
for ( ; i !== len && (elem = elems [i ]) != null ; i ++ ) {
if ( byElement && elem ) {
j = 0 ;
if ( !context && elem .ownerDocument !== document ) {
setDocument ( elem );
xml = !documentIsHTML ;
}
while ( (matcher = elementMatchers[j ++]) ) {
if ( matcher ( elem , context || document , 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 );
}
}
}
// `i` is now the count of elements visited above, and adding it to `matchedCount`
// makes the latter nonnegative.
matchedCount += i ;
// Apply set filters to unmatched elements
// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
// no element matchers and no seed.
// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
// case, which will result in a "00" `matchedCount` that differs from `i` but is also
// numerically zero.
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 only one selector in the list and no seed
// (the latter of which guarantees us context)
if ( match .length === 1 ) {
// Reduce context if the leading compound selector is an ID
tokens = match [0 ] = match [0 ].slice ( 0 );
if ( tokens .length > 2 && (token = tokens [0 ]).type === "ID" &&
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,
!context || 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-35+
// 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 ( el ) {
// Should return 1, but returns 4 (following)
return el.compareDocumentPosition ( document .createElement ("fieldset" ) ) & 1 ;
});
// Support: IE<8
// Prevent attribute/property "interpolation"
// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !assert (function ( el ) {
el.innerHTML = " " ;
return el.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 ( el ) {
el.innerHTML = " " ;
el.firstChild .setAttribute ( "value" , "" );
return el.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 ( el ) {
return el.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 ;
// Deprecated
jQuery .expr [ ":" ] = jQuery .expr .pseudos ;
jQuery .uniqueSort = jQuery .unique = Sizzle .uniqueSort ;
jQuery .text = Sizzle .getText ;
jQuery .isXMLDoc = Sizzle .isXML ;
jQuery .contains = Sizzle .contains ;
jQuery .escapeSelector = Sizzle .escape ;
var dir = function ( elem, dir, until ) {
var matched = [],
truncate = until !== undefined ;
while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
if ( elem.nodeType === 1 ) {
if ( truncate && jQuery ( elem ).is ( until ) ) {
break ;
}
matched .push ( elem );
}
}
return matched ;
};
var siblings = function ( n, elem ) {
var matched = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
matched .push ( n );
}
}
return matched ;
};
var rneedsContext = jQuery .expr .match .needsContext ;
function nodeName ( elem, name ) {
return elem.nodeName && elem.nodeName .toLowerCase () === name.toLowerCase ();
};
var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
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 ) {
return !!qualifier.call ( elem, i, elem ) !== not;
} );
}
// Single element
if ( qualifier.nodeType ) {
return jQuery .grep ( elements, function ( elem ) {
return ( elem === qualifier ) !== not;
} );
}
// Arraylike of elements (jQuery, arguments, Array)
if ( typeof qualifier !== "string" ) {
return jQuery .grep ( elements, function ( elem ) {
return ( indexOf .call ( qualifier, elem ) > -1 ) !== not;
} );
}
// Simple selector that can be filtered directly, removing non-Elements
if ( risSimple .test ( qualifier ) ) {
return jQuery .filter ( qualifier, elements, not );
}
// Complex selector, compare the two sets, removing non-Elements
qualifier = jQuery .filter ( qualifier, elements );
return jQuery .grep ( elements, function ( elem ) {
return ( indexOf .call ( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1 ;
} );
}
jQuery .filter = function ( expr, elems, not ) {
var elem = elems[ 0 ];
if ( not ) {
expr = ":not(" + expr + ")" ;
}
if ( elems.length === 1 && elem .nodeType === 1 ) {
return jQuery .find .matchesSelector ( elem , expr ) ? [ elem ] : [];
}
return jQuery .find .matches ( expr, jQuery .grep ( elems, function ( elem ) {
return elem.nodeType === 1 ;
} ) );
};
jQuery .fn .extend ( {
find : function ( selector ) {
var i , ret ,
len = this .length ,
self = this ;
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 ;
}
}
} ) );
}
ret = this .pushStack ( [] );
for ( i = 0 ; i < len ; i ++ ) {
jQuery .find ( selector, self [ i ], ret );
}
return len > 1 ? jQuery .uniqueSort ( ret ) : 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 ,
// A simple way to check for HTML strings
// Prioritize #id over to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with <)
// Shortcut simple #id case for speed
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/ ,
init = jQuery .fn .init = function ( selector, context, root ) {
var match , elem ;
// HANDLE: $(""), $(null), $(undefined), $(false)
if ( !selector ) {
return this ;
}
// Method init() accepts an alternate rootjQuery
// so migrate can support jQuery.sub (gh-2101)
root = root || rootjQuery ;
// Handle HTML strings
if ( typeof selector === "string" ) {
if ( selector[ 0 ] === "<" &&
selector[ 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;
// Option to run 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 ] );
if ( elem ) {
// Inject the element directly into the jQuery object
this [ 0 ] = elem ;
this .length = 1 ;
}
return this ;
}
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
return ( context || root ).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 [ 0 ] = selector;
this .length = 1 ;
return this ;
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery .isFunction ( selector ) ) {
return root.ready !== undefined ?
root.ready ( selector ) :
// Execute immediately if ready is not present
selector( jQuery );
}
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 .fn .extend ( {
has : function ( target ) {
var targets = jQuery ( target, this ),
l = targets .length ;
return this .filter ( function () {
var i = 0 ;
for ( ; i < l ; i ++ ) {
if ( jQuery .contains ( this , targets [ i ] ) ) {
return true ;
}
}
} );
},
closest : function ( selectors, context ) {
var cur ,
i = 0 ,
l = this .length ,
matched = [],
targets = typeof selectors !== "string" && jQuery ( selectors );
// Positional selectors never match, since there's no _selection_ context
if ( !rneedsContext .test ( selectors ) ) {
for ( ; i < l ; i ++ ) {
for ( cur = this [ i ]; cur && cur !== context; cur = cur .parentNode ) {
// Always skip document fragments
if ( cur .nodeType < 11 && ( targets ?
targets .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 .uniqueSort ( matched ) : matched );
},
// Determine the position of an element within the set
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 indexOf .call ( jQuery ( elem ), this [ 0 ] );
}
// Locate the position of the desired element
return indexOf .call ( this ,
// If it receives a jQuery object, the first element is used
elem.jquery ? elem[ 0 ] : elem
);
},
add : function ( selector, context ) {
return this .pushStack (
jQuery .uniqueSort (
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 ) {
while ( ( cur = cur[ dir ] ) && 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 dir ( elem, "parentNode" );
},
parentsUntil : function ( elem, i, until ) {
return dir ( elem, "parentNode" , until );
},
next : function ( elem ) {
return sibling ( elem, "nextSibling" );
},
prev : function ( elem ) {
return sibling ( elem, "previousSibling" );
},
nextAll : function ( elem ) {
return dir ( elem, "nextSibling" );
},
prevAll : function ( elem ) {
return dir ( elem, "previousSibling" );
},
nextUntil : function ( elem, i, until ) {
return dir ( elem, "nextSibling" , until );
},
prevUntil : function ( elem, i, until ) {
return dir ( elem, "previousSibling" , until );
},
siblings : function ( elem ) {
return siblings ( ( elem.parentNode || {} ).firstChild , elem );
},
children : function ( elem ) {
return siblings ( elem.firstChild );
},
contents : function ( elem ) {
if ( nodeName ( elem, "iframe" ) ) {
return elem.contentDocument ;
}
// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
// Treat the template element as a regular one in browsers that
// don't support it.
if ( nodeName ( elem, "template" ) ) {
elem = elem.content || elem;
}
return jQuery .merge ( [], elem.childNodes );
}
}, function ( name, fn ) {
jQuery .fn [ name ] = function ( until, selector ) {
var matched = jQuery .map ( this , fn, until );
if ( name.slice ( -5 ) !== "Until" ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
matched = jQuery .filter ( selector, matched );
}
if ( this .length > 1 ) {
// Remove duplicates
if ( !guaranteedUnique [ name ] ) {
jQuery .uniqueSort ( matched );
}
// Reverse order for parents* and prev-derivatives
if ( rparentsprev .test ( name ) ) {
matched .reverse ();
}
}
return this .pushStack ( matched );
};
} );
var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
// Convert String-formatted options into Object-formatted ones
function createOptions ( options ) {
var object = {};
jQuery .each ( options.match ( rnothtmlwhite ) || [], 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" ?
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 ,
// Flag to prevent firing
locked ,
// Actual callback list
list = [],
// Queue of execution data for repeatable lists
queue = [],
// Index of currently firing callback (modified by add/remove as needed)
firingIndex = -1 ,
// Fire callbacks
fire = function () {
// Enforce single-firing
locked = locked || options.once;
// Execute callbacks for all pending executions,
// respecting firingIndex overrides and runtime changes
fired = firing = true ;
for ( ; queue .length ; firingIndex = -1 ) {
memory = queue .shift ();
while ( ++firingIndex < list .length ) {
// Run callback and check for early termination
if ( list [ firingIndex ].apply ( memory [ 0 ], memory [ 1 ] ) === false &&
options.stopOnFalse ) {
// Jump to end and forget the data so .add doesn't re-fire
firingIndex = list .length ;
memory = false ;
}
}
}
// Forget the data if we're done with it
if ( !options.memory ) {
memory = false ;
}
firing = false ;
// Clean up if we're done firing for good
if ( locked ) {
// Keep an empty list if we have data for future add calls
if ( memory ) {
list = [];
// Otherwise, this object is spent
} else {
list = "" ;
}
}
},
// Actual Callbacks object
self = {
// Add a callback or a collection of callbacks to the list
add : function () {
if ( list ) {
// If we have memory from a past run, we should fire after adding
if ( memory && !firing ) {
firingIndex = list .length - 1 ;
queue .push ( memory );
}
( function add( args ) {
jQuery .each ( args, function ( _, arg ) {
if ( jQuery .isFunction ( arg ) ) {
if ( !options.unique || !self .has ( arg ) ) {
list .push ( arg );
}
} else if ( arg && arg.length && jQuery .type ( arg ) !== "string" ) {
// Inspect recursively
add ( arg );
}
} );
} )( arguments );
if ( memory && !firing ) {
fire ();
}
}
return this ;
},
// Remove a callback from the list
remove : function () {
jQuery .each ( arguments , function ( _, arg ) {
var index ;
while ( ( index = jQuery .inArray ( arg, list , index ) ) > -1 ) {
list .splice ( index , 1 );
// Handle firing indexes
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 .length > 0 ;
},
// Remove all callbacks from the list
empty : function () {
if ( list ) {
list = [];
}
return this ;
},
// Disable .fire and .add
// Abort any current/pending executions
// Clear all callbacks and values
disable : function () {
locked = queue = [];
list = memory = "" ;
return this ;
},
disabled : function () {
return !list ;
},
// Disable .fire
// Also disable .add unless we have memory (since it would have no effect)
// Abort any pending executions
lock : function () {
locked = queue = [];
if ( !memory && !firing ) {
list = memory = "" ;
}
return this ;
},
locked : function () {
return !!locked ;
},
// Call all callbacks with the given context and arguments
fireWith : function ( context, args ) {
if ( !locked ) {
args = args || [];
args = [ context, args.slice ? args.slice () : args ];
queue .push ( args );
if ( !firing ) {
fire ();
}
}
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 ;
};
function Identity ( v ) {
return v;
}
function Thrower ( ex ) {
throw ex;
}
function adoptValue ( value, resolve, reject, noValue ) {
var method ;
try {
// Check for promise aspect first to privilege synchronous behavior
if ( value && jQuery .isFunction ( ( method = value.promise ) ) ) {
method .call ( value ).done ( resolve ).fail ( reject );
// Other thenables
} else if ( value && jQuery .isFunction ( ( method = value.then ) ) ) {
method .call ( value, resolve, reject );
// Other non-thenables
} else {
// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
// * false: [ value ].slice( 0 ) => resolve( value )
// * true: [ value ].slice( 1 ) => resolve()
resolve.apply ( undefined , [ value ].slice ( noValue ) );
}
// For Promises/A+, convert exceptions into rejections
// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
// Deferred#then to conditionally suppress rejection.
} catch ( value ) {
// Support: Android 4.0 only
// Strict mode functions invoked without .call/.apply get global-object context
reject.apply ( undefined , [ value ] );
}
}
jQuery .extend ( {
Deferred : function ( func ) {
var tuples = [
// action, add listener, callbacks,
// ... .then handlers, argument index, [final state]
[ "notify" , "progress" , jQuery .Callbacks ( "memory" ),
jQuery .Callbacks ( "memory" ), 2 ],
[ "resolve" , "done" , jQuery .Callbacks ( "once memory" ),
jQuery .Callbacks ( "once memory" ), 0 , "resolved" ],
[ "reject" , "fail" , jQuery .Callbacks ( "once memory" ),
jQuery .Callbacks ( "once memory" ), 1 , "rejected" ]
],
state = "pending" ,
promise = {
state : function () {
return state ;
},
always : function () {
deferred .done ( arguments ).fail ( arguments );
return this ;
},
"catch" : function ( fn ) {
return promise .then ( null , fn );
},
// Keep pipe for back-compat
pipe : function ( /* fnDone, fnFail, fnProgress */ ) {
var fns = arguments ;
return jQuery .Deferred ( function ( newDefer ) {
jQuery .each ( tuples , function ( i, tuple ) {
// Map tuples (progress, done, fail) to arguments (done, fail, progress)
var fn = jQuery .isFunction ( fns [ tuple[ 4 ] ] ) && fns [ tuple[ 4 ] ];
// deferred.progress(function() { bind to newDefer or newDefer.notify })
// deferred.done(function() { bind to newDefer or newDefer.resolve })
// deferred.fail(function() { bind to newDefer or newDefer.reject })
deferred [ tuple[ 1 ] ]( function () {
var returned = fn && fn .apply ( this , arguments );
if ( returned && jQuery .isFunction ( returned .promise ) ) {
returned .promise ()
.progress ( newDefer.notify )
.done ( newDefer.resolve )
.fail ( newDefer.reject );
} else {
newDefer[ tuple[ 0 ] + "With" ](
this ,
fn ? [ returned ] : arguments
);
}
} );
} );
fns = null ;
} ).promise ();
},
then : function ( onFulfilled, onRejected, onProgress ) {
var maxDepth = 0 ;
function resolve ( depth, deferred, handler, special ) {
return function () {
var that = this ,
args = arguments ,
mightThrow = function () {
var returned , then ;
// Support: Promises/A+ section 2.3.3.3.3
// https://promisesaplus.com/#point-59
// Ignore double-resolution attempts
if ( depth < maxDepth ) {
return ;
}
returned = handler.apply ( that , args );
// Support: Promises/A+ section 2.3.1
// https://promisesaplus.com/#point-48
if ( returned === deferred.promise () ) {
throw new TypeError ( "Thenable self-resolution" );
}
// Support: Promises/A+ sections 2.3.3.1, 3.5
// https://promisesaplus.com/#point-54
// https://promisesaplus.com/#point-75
// Retrieve `then` only once
then = returned &&
// Support: Promises/A+ section 2.3.4
// https://promisesaplus.com/#point-64
// Only check objects and functions for thenability
( typeof returned === "object" ||
typeof returned === "function" ) &&
returned .then ;
// Handle a returned thenable
if ( jQuery .isFunction ( then ) ) {
// Special processors (notify) just wait for resolution
if ( special ) {
then .call (
returned ,
resolve ( maxDepth , deferred, Identity , special ),
resolve ( maxDepth , deferred, Thrower , special )
);
// Normal processors (resolve) also hook into progress
} else {
// ...and disregard older resolution values
maxDepth ++;
then .call (
returned ,
resolve ( maxDepth , deferred, Identity , special ),
resolve ( maxDepth , deferred, Thrower , special ),
resolve ( maxDepth , deferred, Identity ,
deferred.notifyWith )
);
}
// Handle all other returned values
} else {
// Only substitute handlers pass on context
// and multiple values (non-spec behavior)
if ( handler !== Identity ) {
that = undefined ;
args = [ returned ];
}
// Process the value(s)
// Default process is resolve
( special || deferred.resolveWith )( that , args );
}
},
// Only normal processors (resolve) catch and reject exceptions
process = special ?
mightThrow :
function () {
try {
mightThrow ();
} catch ( e ) {
if ( jQuery .Deferred .exceptionHook ) {
jQuery .Deferred .exceptionHook ( e,
process .stackTrace );
}
// Support: Promises/A+ section 2.3.3.3.4.1
// https://promisesaplus.com/#point-61
// Ignore post-resolution exceptions
if ( depth + 1 >= maxDepth ) {
// Only substitute handlers pass on context
// and multiple values (non-spec behavior)
if ( handler !== Thrower ) {
that = undefined ;
args = [ e ];
}
deferred.rejectWith ( that , args );
}
}
};
// Support: Promises/A+ section 2.3.3.3.1
// https://promisesaplus.com/#point-57
// Re-resolve promises immediately to dodge false rejection from
// subsequent errors
if ( depth ) {
process ();
} else {
// Call an optional hook to record the stack, in case of exception
// since it's otherwise lost when execution goes async
if ( jQuery .Deferred .getStackHook ) {
process .stackTrace = jQuery .Deferred .getStackHook();
}
window.setTimeout ( process );
}
};
}
return jQuery .Deferred ( function ( newDefer ) {
// progress_handlers.add( ... )
tuples [ 0 ][ 3 ].add (
resolve (
0 ,
newDefer,
jQuery .isFunction ( onProgress ) ?
onProgress :
Identity ,
newDefer.notifyWith
)
);
// fulfilled_handlers.add( ... )
tuples [ 1 ][ 3 ].add (
resolve (
0 ,
newDefer,
jQuery .isFunction ( onFulfilled ) ?
onFulfilled :
Identity
)
);
// rejected_handlers.add( ... )
tuples [ 2 ][ 3 ].add (
resolve (
0 ,
newDefer,
jQuery .isFunction ( onRejected ) ?
onRejected :
Thrower
)
);
} ).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 = {};
// Add list-specific methods
jQuery .each ( tuples , function ( i, tuple ) {
var list = tuple[ 2 ],
stateString = tuple[ 5 ];
// promise.progress = list.add
// promise.done = list.add
// promise.fail = list.add
promise [ tuple[ 1 ] ] = list .add ;
// Handle state
if ( stateString ) {
list .add (
function () {
// state = "resolved" (i.e., fulfilled)
// state = "rejected"
state = stateString ;
},
// rejected_callbacks.disable
// fulfilled_callbacks.disable
tuples [ 3 - i ][ 2 ].disable ,
// progress_callbacks.lock
tuples [ 0 ][ 2 ].lock
);
}
// progress_handlers.fire
// fulfilled_handlers.fire
// rejected_handlers.fire
list .add ( tuple[ 3 ].fire );
// deferred.notify = function() { deferred.notifyWith(...) }
// deferred.resolve = function() { deferred.resolveWith(...) }
// deferred.reject = function() { deferred.rejectWith(...) }
deferred [ tuple[ 0 ] ] = function () {
deferred [ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this , arguments );
return this ;
};
// deferred.notifyWith = list.fireWith
// deferred.resolveWith = list.fireWith
// deferred.rejectWith = list.fireWith
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 ( singleValue ) {
var
// count of uncompleted subordinates
remaining = arguments .length ,
// count of unprocessed arguments
i = remaining ,
// subordinate fulfillment data
resolveContexts = Array( i ),
resolveValues = slice .call ( arguments ),
// the master Deferred
master = jQuery .Deferred (),
// subordinate callback factory
updateFunc = function ( i ) {
return function ( value ) {
resolveContexts [ i ] = this ;
resolveValues [ i ] = arguments .length > 1 ? slice .call ( arguments ) : value;
if ( !( --remaining ) ) {
master .resolveWith ( resolveContexts , resolveValues );
}
};
};
// Single- and empty arguments are adopted like Promise.resolve
if ( remaining <= 1 ) {
adoptValue ( singleValue, master .done ( updateFunc ( i ) ).resolve , master .reject ,
!remaining );
// Use .then() to unwrap secondary thenables (cf. gh-3000)
if ( master .state () === "pending" ||
jQuery .isFunction ( resolveValues [ i ] && resolveValues [ i ].then ) ) {
return master .then ();
}
}
// Multiple arguments are aggregated like Promise.all array elements
while ( i -- ) {
adoptValue ( resolveValues [ i ], updateFunc ( i ), master .reject );
}
return master .promise ();
}
} );
// These usually indicate a programmer mistake during development,
// warn about them ASAP rather than swallowing them by default.
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/ ;
jQuery .Deferred .exceptionHook = function ( error, stack ) {
// Support: IE 8 - 9 only
// Console exists when dev tools are open, which can happen at any time
if ( window.console && window.console .warn && error && rerrorNames .test ( error.name ) ) {
window.console .warn ( "jQuery.Deferred exception: " + error.message , error.stack , stack );
}
};
jQuery .readyException = function ( error ) {
window.setTimeout ( function () {
throw error;
} );
};
// The deferred used on DOM ready
var readyList = jQuery .Deferred ();
jQuery .fn .ready = function ( fn ) {
readyList
.then ( fn )
// Wrap jQuery.readyException in a function so that the lookup
// happens at the time of error handling instead of callback
// registration.
.catch ( function ( error ) {
jQuery .readyException ( error );
} );
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 ,
// 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 ;
}
// 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 ] );
}
} );
jQuery .ready .then = readyList .then ;
// The ready event handler and self cleanup method
function completed () {
document .removeEventListener ( "DOMContentLoaded" , completed );
window.removeEventListener ( "load" , completed );
jQuery .ready ();
}
// Catch cases where $(document).ready() is called
// after the browser event has already occurred.
// Support: IE <=9 - 10 only
// Older IE sometimes signals "interactive" too soon
if ( document .readyState === "complete" ||
( document .readyState !== "loading" && !document .documentElement .doScroll ) ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
window.setTimeout ( jQuery .ready );
} else {
// Use the handy event callback
document .addEventListener ( "DOMContentLoaded" , completed );
// A fallback to window.onload, that will always work
window.addEventListener ( "load" , completed );
}
// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function ( elems, fn, key, value, chainable, emptyGet, raw ) {
var i = 0 ,
len = elems.length ,
bulk = key == null ;
// Sets many values
if ( jQuery .type ( key ) === "object" ) {
chainable = true ;
for ( i in key ) {
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 < len ; i ++ ) {
fn(
elems[ i ], key, raw ?
value :
value.call ( elems[ i ], i , fn( elems[ i ], key ) )
);
}
}
}
if ( chainable ) {
return elems;
}
// Gets
if ( bulk ) {
return fn.call ( elems );
}
return len ? fn( elems[ 0 ], key ) : emptyGet;
};
var acceptData = function ( owner ) {
// Accepts only:
// - Node
// - Node.ELEMENT_NODE
// - Node.DOCUMENT_NODE
// - Object
// - Any
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};
function Data () {
this .expando = jQuery .expando + Data .uid ++;
}
Data .uid = 1 ;
Data .prototype = {
cache : function ( owner ) {
// Check if the owner object already has a cache
var value = owner[ this .expando ];
// If not, create one
if ( !value ) {
value = {};
// We can accept data for non-element nodes in modern browsers,
// but we should not, see #8335.
// Always return an empty object.
if ( acceptData ( owner ) ) {
// If it is a node unlikely to be stringify-ed or looped over
// use plain assignment
if ( owner.nodeType ) {
owner[ this .expando ] = value ;
// Otherwise secure it in a non-enumerable property
// configurable must be true to allow the property to be
// deleted when data is removed
} else {
Object.defineProperty ( owner, this .expando , {
value : value ,
configurable : true
} );
}
}
}
return value ;
},
set : function ( owner, data, value ) {
var prop ,
cache = this .cache ( owner );
// Handle: [ owner, key, value ] args
// Always use camelCase key (gh-2257)
if ( typeof data === "string" ) {
cache [ jQuery .camelCase ( data ) ] = value;
// Handle: [ owner, { properties } ] args
} else {
// Copy the properties one-by-one to the cache object
for ( prop in data ) {
cache [ jQuery .camelCase ( prop ) ] = data[ prop ];
}
}
return cache ;
},
get : function ( owner, key ) {
return key === undefined ?
this .cache ( owner ) :
// Always use camelCase key (gh-2257)
owner[ this .expando ] && owner[ this .expando ][ jQuery .camelCase ( key ) ];
},
access : function ( owner, key, value ) {
// In cases where either:
//
// 1. No key was specified
// 2. A string key was specified, but no value provided
//
// Take the "read" path and allow the get method to determine
// which value to return, respectively either:
//
// 1. The entire cache object
// 2. The data stored at the key
//
if ( key === undefined ||
( ( key && typeof key === "string" ) && value === undefined ) ) {
return this .get ( owner, key );
}
// When the key is not a string, or both a key and value
// are specified, set or extend (existing objects) with either:
//
// 1. An object of properties
// 2. A key and value
//
this .set ( owner, key, value );
// Since the "set" path can have two possible entry points
// return the expected data based on which path was taken[*]
return value !== undefined ? value : key;
},
remove : function ( owner, key ) {
var i ,
cache = owner[ this .expando ];
if ( cache === undefined ) {
return ;
}
if ( key !== undefined ) {
// Support array or space separated string of keys
if ( Array.isArray ( key ) ) {
// If key is an array of keys...
// We always set camelCase keys, so remove that.
key = key.map ( jQuery .camelCase );
} else {
key = jQuery .camelCase ( key );
// If a key with the spaces exists, use it.
// Otherwise, create an array by matching non-whitespace
key = key in cache ?
[ key ] :
( key.match ( rnothtmlwhite ) || [] );
}
i = key.length ;
while ( i -- ) {
delete cache [ key[ i ] ];
}
}
// Remove the expando if there's no more data
if ( key === undefined || jQuery .isEmptyObject ( cache ) ) {
// Support: Chrome <=35 - 45
// Webkit & Blink performance suffers when deleting properties
// from DOM nodes, so set to undefined instead
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
if ( owner.nodeType ) {
owner[ this .expando ] = undefined ;
} else {
delete owner[ this .expando ];
}
}
},
hasData : function ( owner ) {
var cache = owner[ this .expando ];
return cache !== undefined && !jQuery .isEmptyObject ( cache );
}
};
var dataPriv = new Data ();
var dataUser = new Data ();
// Implementation Summary
//
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
// 2. Improve the module's maintainability by reducing the storage
// paths to a single mechanism.
// 3. Use the same single mechanism to support "private" and "user" data.
// 4. _Never_ expose "private" data to user code ( TODO: Drop _data, _removeData)
// 5. Avoid exposing implementation details on user objects (eg. expando properties)
// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/ ,
rmultiDash = /[A-Z]/g ;
function getData ( data ) {
if ( data === "true" ) {
return true ;
}
if ( data === "false" ) {
return false ;
}
if ( data === "null" ) {
return null ;
}
// Only convert to a number if it doesn't change the string
if ( data === +data + "" ) {
return +data;
}
if ( rbrace .test ( data ) ) {
return JSON .parse ( data );
}
return data;
}
function dataAttr ( elem, key, data ) {
var name ;
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) {
name = "data-" + key.replace ( rmultiDash , "-$&" ).toLowerCase ();
data = elem.getAttribute ( name );
if ( typeof data === "string" ) {
try {
data = getData ( data );
} catch ( e ) {}
// Make sure we set the data so it isn't changed later
dataUser .set ( elem, key, data );
} else {
data = undefined ;
}
}
return data;
}
jQuery .extend ( {
hasData : function ( elem ) {
return dataUser .hasData ( elem ) || dataPriv .hasData ( elem );
},
data : function ( elem, name, data ) {
return dataUser .access ( elem, name, data );
},
removeData : function ( elem, name ) {
dataUser .remove ( elem, name );
},
// TODO: Now that all calls to _data and _removeData have been replaced
// with direct calls to dataPriv methods, these can be deprecated.
_data : function ( elem, name, data ) {
return dataPriv .access ( elem, name, data );
},
_removeData : function ( elem, name ) {
dataPriv .remove ( elem, name );
}
} );
jQuery .fn .extend ( {
data : function ( key, value ) {
var i , name , data ,
elem = this [ 0 ],
attrs = elem && elem .attributes ;
// Gets all values
if ( key === undefined ) {
if ( this .length ) {
data = dataUser .get ( elem );
if ( elem .nodeType === 1 && !dataPriv .get ( elem , "hasDataAttrs" ) ) {
i = attrs .length ;
while ( i -- ) {
// Support: IE 11 only
// 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 ] );
}
}
}
dataPriv .set ( elem , "hasDataAttrs" , true );
}
}
return data ;
}
// Sets multiple values
if ( typeof key === "object" ) {
return this .each ( function () {
dataUser .set ( this , key );
} );
}
return access ( this , function ( value ) {
var data ;
// The calling jQuery object (element matches) is not empty
// (and therefore has an element appears at this[ 0 ]) and the
// `value` parameter was not undefined. An empty jQuery object
// will result in `undefined` for elem = this[ 0 ] which will
// throw an exception if an attempt to read a data cache is made.
if ( elem && value === undefined ) {
// Attempt to get data from the cache
// The key will always be camelCased in Data
data = dataUser .get ( elem , key );
if ( data !== undefined ) {
return data ;
}
// Attempt to "discover" the data in
// HTML5 custom data-* attrs
data = dataAttr ( elem , key );
if ( data !== undefined ) {
return data ;
}
// We tried really hard, but the data doesn't exist.
return ;
}
// Set the data...
this .each ( function () {
// We always store the camelCased key
dataUser .set ( this , key, value );
} );
}, null , value, arguments .length > 1 , null , true );
},
removeData : function ( key ) {
return this .each ( function () {
dataUser .remove ( this , key );
} );
}
} );
jQuery .extend ( {
queue : function ( elem, type, data ) {
var queue ;
if ( elem ) {
type = ( type || "fx" ) + "queue" ;
queue = dataPriv .get ( elem, type );
// Speed up dequeue by getting out quickly if this is just a lookup
if ( data ) {
if ( !queue || Array.isArray ( data ) ) {
queue = dataPriv .access ( 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 public - generate a queueHooks object, or return the current one
_queueHooks : function ( elem, type ) {
var key = type + "queueHooks" ;
return dataPriv .get ( elem, key ) || dataPriv .access ( elem, key , {
empty : jQuery .Callbacks ( "once memory" ).add ( function () {
dataPriv .remove ( elem, [ type + "queue" , 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 = dataPriv .get ( 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 rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$" , "i" );
var cssExpand = [ "Top" , "Right" , "Bottom" , "Left" ];
var isHiddenWithinTree = function ( elem, el ) {
// isHiddenWithinTree might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
// Inline style trumps all
return elem.style .display === "none" ||
elem.style .display === "" &&
// Otherwise, check computed style
// Support: Firefox <=43 - 45
// Disconnected elements can have computed display: none, so first confirm that elem is
// in the document.
jQuery .contains ( elem.ownerDocument , elem ) &&
jQuery .css ( elem, "display" ) === "none" ;
};
var 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 ;
};
function adjustCSS ( elem, prop, valueParts, tween ) {
var adjusted ,
scale = 1 ,
maxIterations = 20 ,
currentValue = tween ?
function () {
return tween.cur ();
} :
function () {
return jQuery .css ( elem, prop, "" );
},
initial = currentValue (),
unit = valueParts && valueParts[ 3 ] || ( jQuery .cssNumber [ prop ] ? "" : "px" ),
// Starting value computation is required for potential unit mismatches
initialInUnit = ( jQuery .cssNumber [ prop ] || unit !== "px" && +initial ) &&
rcssNum .exec ( jQuery .css ( elem, prop ) );
if ( initialInUnit && initialInUnit [ 3 ] !== unit ) {
// Trust units reported by jQuery.css
unit = unit || initialInUnit [ 3 ];
// Make sure we update the tween properties later on
valueParts = valueParts || [];
// Iteratively approximate from a nonzero starting point
initialInUnit = +initial || 1 ;
do {
// If previous iteration zeroed out, double until we get *something*.
// Use string for doubling so we don't accidentally see scale as unchanged below
scale = scale || ".5" ;
// Adjust and apply
initialInUnit = initialInUnit / scale ;
jQuery .style ( elem, prop, initialInUnit + unit );
// Update scale, tolerating zero or NaN from tween.cur()
// Break the loop if scale is unchanged or perfect, or if we've just had enough.
} while (
scale !== ( scale = currentValue () / initial ) && scale !== 1 && --maxIterations
);
}
if ( valueParts ) {
initialInUnit = +initialInUnit || +initial || 0 ;
// Apply relative offset (+=/-=) if specified
adjusted = valueParts[ 1 ] ?
initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+valueParts[ 2 ];
if ( tween ) {
tween.unit = unit ;
tween.start = initialInUnit ;
tween.end = adjusted ;
}
}
return adjusted ;
}
var defaultDisplayMap = {};
function getDefaultDisplay ( elem ) {
var temp ,
doc = elem.ownerDocument ,
nodeName = elem.nodeName ,
display = defaultDisplayMap [ nodeName ];
if ( display ) {
return display ;
}
temp = doc .body .appendChild ( doc .createElement ( nodeName ) );
display = jQuery .css ( temp , "display" );
temp .parentNode .removeChild ( temp );
if ( display === "none" ) {
display = "block" ;
}
defaultDisplayMap [ nodeName ] = display ;
return display ;
}
function showHide ( elements, show ) {
var display , elem ,
values = [],
index = 0 ,
length = elements.length ;
// Determine new display value for elements that need to change
for ( ; index < length ; index ++ ) {
elem = elements[ index ];
if ( !elem .style ) {
continue ;
}
display = elem .style .display ;
if ( show ) {
// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
// check is required in this first loop unless we have a nonempty display value (either
// inline or about-to-be-restored)
if ( display === "none" ) {
values [ index ] = dataPriv .get ( elem , "display" ) || null ;
if ( !values [ index ] ) {
elem .style .display = "" ;
}
}
if ( elem .style .display === "" && isHiddenWithinTree ( elem ) ) {
values [ index ] = getDefaultDisplay ( elem );
}
} else {
if ( display !== "none" ) {
values [ index ] = "none" ;
// Remember what we're overwriting
dataPriv .set ( elem , "display" , display );
}
}
}
// Set the display of the elements in a second loop to avoid constant reflow
for ( index = 0 ; index < length ; index ++ ) {
if ( values [ index ] != null ) {
elements[ index ].style .display = values [ index ];
}
}
return elements;
}
jQuery .fn .extend ( {
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 ( isHiddenWithinTree ( this ) ) {
jQuery ( this ).show ();
} else {
jQuery ( this ).hide ();
}
} );
}
} );
var rcheckableType = ( /^(?:checkbox|radio)$/i );
var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
var rscriptType = ( /^$|\/(?:java|ecma)script/i );
// We have to close these tags to support XHTML (#13200)
var wrapMap = {
// Support: IE <=9 only
option : [ 1 , "" , "" ],
// XHTML parsers do not magically insert elements in the
// same way that tag soup parsers do. So we cannot shorten
// this by omitting or other required elements.
thead : [ 1 , "" ],
col : [ 2 , "" ],
tr : [ 2 , "" ],
td : [ 3 , "" ],
_default : [ 0 , "" , "" ]
};
// Support: IE <=9 only
wrapMap .optgroup = wrapMap .option ;
wrapMap .tbody = wrapMap .tfoot = wrapMap .colgroup = wrapMap .caption = wrapMap .thead ;
wrapMap .th = wrapMap .td ;
function getAll ( context, tag ) {
// Support: IE <=9 - 11 only
// Use typeof to avoid zero-argument method invocation on host objects (#15151)
var ret ;
if ( typeof context.getElementsByTagName !== "undefined" ) {
ret = context.getElementsByTagName ( tag || "*" );
} else if ( typeof context.querySelectorAll !== "undefined" ) {
ret = context.querySelectorAll ( tag || "*" );
} else {
ret = [];
}
if ( tag === undefined || tag && nodeName ( context, tag ) ) {
return jQuery .merge ( [ context ], ret );
}
return ret ;
}
// Mark scripts as having already been evaluated
function setGlobalEval ( elems, refElements ) {
var i = 0 ,
l = elems.length ;
for ( ; i < l ; i ++ ) {
dataPriv .set (
elems[ i ],
"globalEval" ,
!refElements || dataPriv .get ( refElements[ i ], "globalEval" )
);
}
}
var rhtml = /<|?\w+;/ ;
function buildFragment ( elems, context, scripts, selection, ignored ) {
var elem , tmp , tag , wrap , contains , j ,
fragment = context.createDocumentFragment (),
nodes = [],
i = 0 ,
l = elems.length ;
for ( ; i < l ; i ++ ) {
elem = elems[ i ];
if ( elem || elem === 0 ) {
// Add nodes directly
if ( jQuery .type ( elem ) === "object" ) {
// Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
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 || fragment .appendChild ( context.createElement ( "div" ) );
// Deserialize a standard representation
tag = ( rtagName .exec ( elem ) || [ "" , "" ] )[ 1 ].toLowerCase ();
wrap = wrapMap [ tag ] || wrapMap ._default ;
tmp .innerHTML = wrap [ 1 ] + jQuery .htmlPrefilter ( elem ) + wrap [ 2 ];
// Descend through wrappers to the right content
j = wrap [ 0 ];
while ( j -- ) {
tmp = tmp .lastChild ;
}
// Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery .merge ( nodes , tmp .childNodes );
// Remember the top-level container
tmp = fragment .firstChild ;
// Ensure the created nodes are orphaned (#12392)
tmp .textContent = "" ;
}
}
}
// Remove wrapper from fragment
fragment .textContent = "" ;
i = 0 ;
while ( ( elem = nodes [ i ++ ] ) ) {
// Skip elements already in the context collection (trac-4087)
if ( selection && jQuery .inArray ( elem , selection ) > -1 ) {
if ( ignored ) {
ignored.push ( elem );
}
continue ;
}
contains = jQuery .contains ( elem .ownerDocument , elem );
// Append to fragment
tmp = getAll ( fragment .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 );
}
}
}
}
return fragment ;
}
( function () {
var fragment = document .createDocumentFragment (),
div = fragment .appendChild ( document .createElement ( "div" ) ),
input = document .createElement ( "input" );
// Support: Android 4.0 - 4.3 only
// Check state lost if the name is set (#11217)
// Support: Windows Web Apps (WWA)
// `name` and `type` must use .setAttribute for WWA (#14901)
input .setAttribute ( "type" , "radio" );
input .setAttribute ( "checked" , "checked" );
input .setAttribute ( "name" , "t" );
div .appendChild ( input );
// Support: Android <=4.1 only
// Older WebKit doesn't clone checked state correctly in fragments
support .checkClone = div .cloneNode ( true ).cloneNode ( true ).lastChild .checked ;
// Support: IE <=11 only
// Make sure textarea (and checkbox) defaultValue is properly cloned
div .innerHTML = "" ;
support .noCloneChecked = !!div .cloneNode ( true ).lastChild .defaultValue ;
} )();
var documentElement = document .documentElement ;
var
rkeyEvent = /^key/ ,
rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/ ,
rtypenamespace = /^([^.]*)(?:\.(.+)|)/ ;
function returnTrue () {
return true ;
}
function returnFalse () {
return false ;
}
// Support: IE <=9 only
// See #13393 for more info
function safeActiveElement () {
try {
return document .activeElement ;
} catch ( err ) { }
}
function on ( elem, types, selector, data, fn, one ) {
var origFn , type ;
// 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 ) {
on ( elem, type , selector, data, types[ type ], one );
}
return elem;
}
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 elem;
}
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 elem.each ( function () {
jQuery .event .add ( this , types, fn, data, selector );
} );
}
/*
* 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 handleObjIn , eventHandle , tmp ,
events , t , handleObj ,
special , handlers , type , namespaces , origType ,
elemData = dataPriv .get ( 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 ;
}
// Ensure that invalid selectors throw exceptions at attach time
// Evaluate against documentElement in case elem is a non-element node (e.g., document)
if ( selector ) {
jQuery .find .matchesSelector ( documentElement , 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 !== "undefined" && jQuery .event .triggered !== e.type ?
jQuery .event .dispatch .apply ( elem, arguments ) : undefined ;
};
}
// Handle multiple events separated by a space
types = ( types || "" ).match ( rnothtmlwhite ) || [ "" ];
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 if the special events handler returns false
if ( !special .setup ||
special .setup .call ( elem, data, namespaces , eventHandle ) === false ) {
if ( elem.addEventListener ) {
elem.addEventListener ( 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 ;
}
},
// Detach an event or set of events from an element
remove : function ( elem, types, handler, selector, mappedTypes ) {
var j , origCount , tmp ,
events , t , handleObj ,
special , handlers , type , namespaces , origType ,
elemData = dataPriv .hasData ( elem ) && dataPriv .get ( elem );
if ( !elemData || !( events = elemData .events ) ) {
return ;
}
// Once for each type.namespace in types; type may be omitted
types = ( types || "" ).match ( rnothtmlwhite ) || [ "" ];
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 data and the expando if it's no longer used
if ( jQuery .isEmptyObject ( events ) ) {
dataPriv .remove ( elem, "handle events" );
}
},
dispatch : function ( nativeEvent ) {
// Make a writable jQuery.Event from the native event object
var event = jQuery .event .fix ( nativeEvent );
var i , j , ret , matched , handleObj , handlerQueue ,
args = new Array( arguments .length ),
handlers = ( dataPriv .get ( 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 ;
for ( i = 1 ; i < arguments .length ; i ++ ) {
args [ i ] = arguments [ i ];
}
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 .rnamespace || event .rnamespace .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 i , handleObj , sel , matchedHandlers , matchedSelectors ,
handlerQueue = [],
delegateCount = handlers.delegateCount ,
cur = event.target ;
// Find delegate handlers
if ( delegateCount &&
// Support: IE <=9
// Black-hole SVG instance trees (trac-13180)
cur .nodeType &&
// Support: Firefox <=42
// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
// Support: IE 11 only
// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
!( event.type === "click" && event.button >= 1 ) ) {
for ( ; cur !== this ; cur = cur .parentNode || this ) {
// Don't check non-elements (#13208)
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
if ( cur .nodeType === 1 && !( event.type === "click" && cur .disabled === true ) ) {
matchedHandlers = [];
matchedSelectors = {};
for ( i = 0 ; i < delegateCount ; i ++ ) {
handleObj = handlers[ i ];
// Don't conflict with Object.prototype properties (#13203)
sel = handleObj .selector + " " ;
if ( matchedSelectors [ sel ] === undefined ) {
matchedSelectors [ sel ] = handleObj .needsContext ?
jQuery ( sel , this ).index ( cur ) > -1 :
jQuery .find ( sel , this , null , [ cur ] ).length ;
}
if ( matchedSelectors [ sel ] ) {
matchedHandlers .push ( handleObj );
}
}
if ( matchedHandlers .length ) {
handlerQueue .push ( { elem : cur , handlers : matchedHandlers } );
}
}
}
}
// Add the remaining (directly-bound) handlers
cur = this ;
if ( delegateCount < handlers.length ) {
handlerQueue .push ( { elem : cur , handlers : handlers.slice ( delegateCount ) } );
}
return handlerQueue ;
},
addProp : function ( name, hook ) {
Object.defineProperty ( jQuery .Event .prototype , name, {
enumerable : true ,
configurable : true ,
get : jQuery .isFunction ( hook ) ?
function () {
if ( this .originalEvent ) {
return hook( this .originalEvent );
}
} :
function () {
if ( this .originalEvent ) {
return this .originalEvent [ name ];
}
},
set : function ( value ) {
Object.defineProperty ( this , name, {
enumerable : true ,
configurable : true ,
writable : true ,
value : value
} );
}
} );
},
fix : function ( originalEvent ) {
return originalEvent[ jQuery .expando ] ?
originalEvent :
new jQuery .Event ( originalEvent );
},
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 ) {
this .focus ();
return false ;
}
},
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 ( this .type === "checkbox" && this .click && nodeName ( this , "input" ) ) {
this .click ();
return false ;
}
},
// For cross-browser consistency, don't fire native .click() on links
_default : function ( event ) {
return 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 ;
}
}
}
}
};
jQuery .removeEvent = function ( elem, type, handle ) {
// This "if" is needed for plain objects
if ( elem.removeEventListener ) {
elem.removeEventListener ( type, 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: Android <=2.3 only
src.returnValue === false ?
returnTrue :
returnFalse ;
// Create target properties
// Support: Safari <=6 - 7 only
// Target should not be a text node (#504, #13143)
this .target = ( src.target && src.target .nodeType === 3 ) ?
src.target .parentNode :
src.target ;
this .currentTarget = src.currentTarget ;
this .relatedTarget = src.relatedTarget ;
// 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
// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery .Event .prototype = {
constructor : jQuery .Event ,
isDefaultPrevented : returnFalse ,
isPropagationStopped : returnFalse ,
isImmediatePropagationStopped : returnFalse ,
isSimulated : false ,
preventDefault : function () {
var e = this .originalEvent ;
this .isDefaultPrevented = returnTrue ;
if ( e && !this .isSimulated ) {
e .preventDefault ();
}
},
stopPropagation : function () {
var e = this .originalEvent ;
this .isPropagationStopped = returnTrue ;
if ( e && !this .isSimulated ) {
e .stopPropagation ();
}
},
stopImmediatePropagation : function () {
var e = this .originalEvent ;
this .isImmediatePropagationStopped = returnTrue ;
if ( e && !this .isSimulated ) {
e .stopImmediatePropagation ();
}
this .stopPropagation ();
}
};
// Includes all common event props including KeyEvent and MouseEvent specific props
jQuery .each ( {
altKey : true ,
bubbles : true ,
cancelable : true ,
changedTouches : true ,
ctrlKey : true ,
detail : true ,
eventPhase : true ,
metaKey : true ,
pageX : true ,
pageY : true ,
shiftKey : true ,
view : true ,
"char" : true ,
charCode : true ,
key : true ,
keyCode : true ,
button : true ,
buttons : true ,
clientX : true ,
clientY : true ,
offsetX : true ,
offsetY : true ,
pointerId : true ,
pointerType : true ,
screenX : true ,
screenY : true ,
targetTouches : true ,
toElement : true ,
touches : true ,
which : function ( event ) {
var button = event.button ;
// Add which for key events
if ( event.which == null && rkeyEvent .test ( event.type ) ) {
return event.charCode != null ? event.charCode : event.keyCode ;
}
// Add which for click: 1 === left; 2 === middle; 3 === right
if ( !event.which && button !== undefined && rmouseEvent .test ( event.type ) ) {
if ( button & 1 ) {
return 1 ;
}
if ( button & 2 ) {
return 3 ;
}
if ( button & 4 ) {
return 2 ;
}
return 0 ;
}
return event.which ;
}
}, jQuery .event .addProp );
// Create mouseenter/leave events using mouseover/out and event-time checks
// so that event delegation works in jQuery.
// Do the same for pointerenter/pointerleave and pointerover/pointerout
//
// Support: Safari 7 only
// Safari sends mouseenter too often; see:
// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
// for the description of the bug (it existed in older Chrome versions as well).
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 mouseenter/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 ;
}
};
} );
jQuery .fn .extend ( {
on : function ( types, selector, data, fn ) {
return on ( this , types, selector, data, fn );
},
one : function ( types, selector, data, fn ) {
return on ( this , 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 );
} );
}
} );
var
/* eslint-disable max-len */
// See https://github.com/eslint/eslint/issues/3229
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi ,
/* eslint-enable */
// Support: IE <=10 - 11, Edge 12 - 13
// In IE/Edge using regex groups here causes severe slowdowns.
// See https://connect.microsoft.com/IE/feedback/details/1736512/
rnoInnerhtml = /
你可能感兴趣的:(jQuery AJAX nodejs 简陋聊天室通信)
Java 网络编程(二)—— TCP流套接字编程
熵减玩家
JavaSE 进阶 网络 java tcp
TCP和UDP的区别在传输层,TCP协议是有连接的,可靠传输,面向字节流,全双工而UDP协议是无连接的,不可靠传输,面向数据报,全双工有连接和无连接的区别是在进行网络通信的时候,通信双方有没有保存对端的地址信息,即假设A和B进行通信,A保存了B的地址信息,B也保存了A的地址信息,此时双方都知道和谁建立了连接,这就是有连接的通信,在之前的UDP数据报套接字编程中就提到过UDP是无连接的,所以在发送数
探索高效串口通信:C++跨平台串口库serial
郎锴钦
探索高效串口通信:C++跨平台串口库serial【下载地址】C跨平台串口库serial本仓库提供了一个C++跨平台串口库`serial`的资源文件。该库基于[wjwwood/serial](https://github.com/wjwwood/serial/tree/boostless)项目进行修改,删除了不必要的文件,使得该库无需`catkin`,只需`cmake`即可使用项目地址:https:
【Python】serial库的介绍及用法
"啦啦啦"
python python 网络 linux
目录1、应用场景2、serial-三方库1、应用场景serial库,也被称为pySerial,主要用于串行通信,它在以下几个场景中被广泛应用:嵌入式系统通信:许多嵌入式系统(如Arduino、RaspberryPi等)都使用串行通信进行数据传输。pySerial可以帮助Python程序与这些设备进行通信。硬件设备控制:许多硬件设备(如机器人、传感器、GPS模块等)都使用串行接口进行控制。pySer
Microi 吾码与 JavaScript:前端低代码平台的强大组合
小周不想卷
javascript
目录一、引言二、Microi吾码概述三、JavaScript在Microi吾码前端开发中的应用(一)前端V8引擎与JavaScript(二)接口引擎与JavaScript四、JavaScript在Microi吾码后端开发中的协同(一)与C#后端框架的交互(二)利用gRPC实现跨语言通信五、Microi吾码中JavaScript与数据库的交互六、Microi吾码中JavaScript在表单与模板引擎
开年「荣誉三重奏」,融云斩获技术、产品、出海三项大奖!
程序员
开年接连喜获大奖,融云服务再获认可——登榜CSDN“2024中国开发者影响力年度评选”、荣获InfoQ“2024年度优秀出海服务商”、人人都是产品经理“2024年度评选-产品技术创新突破奖”。2024年是AI应用元年,也是出海持续深化的一年。面对AI和出海这两大变量,开发者群体在国内应用市场增长空间狭小的现实下有了更趁手的工具和广阔的发力方向。融云作为以“一切为了开发者”为发展宗旨的通信云服务商,
stm32+w5500实现web服务_【NodeJS】简单静态WEB服务器实现
weixin_39711441
说明利用HTTP模块URl模块Path模块Fs模块创建在项目文件夹下,创建文件夹static,下面创建index.html//引入http模块var http=require('http');//fs模块var fs=require('fs');http.createServer(function(req,res){ //http://localhost:8001/news.html/new
android wifi 流程图_实现双wifi的方法及Android终端与流程
weixin_39719427
android wifi 流程图
本发明涉及无线通信技术领域,尤其涉及一种实现双wifi的方法及Android终端。背景技术:在楼宇对讲产品中,楼宇对讲的家庭设备,如平板,需要连接到楼宇对讲的局域网络,以实现与楼宇内的相关设备进行对讲等。然而楼宇对讲所在的局域网络通常为内网,加上现有的基于Android系统的平板仅支持一路wifi热点连接功能,导致已连接了内网的平板无法再同时连接公网,即互联网,进而也就无法在通过平板使用需要连接公
vue3开发:项目添加mitt
项目中遇到一个场景:类似于app.vue页面获取某一个页面组件的数据,因为进入那个组件是通过router-view进入,不是通过组件注入到app.vue,所以使用常规的组件通信获取不到数据,我使用了mitt实现了这个功能。Vue2中我们使用EventBus来实现跨组件之间的一些通信,它依赖于Vue自带的on/on/on/emit/$off等方法,而Vue3中移除了这些相关方法,这意味着EventB
STM32 FreeRTOS 事件标志组
雁过留声花欲落
STM32 FreeRTOS stm32 嵌入式硬件 单片机
目录事件标志组简介基本概念1、事件位(事件标志)2、事件组事件组和事件位数据类型事件标志组和信号量的区别事件标志组相关API函数介绍事件标志组简介基本概念当在嵌入式系统中运行多个任务时,这些任务可能需要相互通信,协调其操作。FreeRTOS中的事件标志组(EventFlagsGroup)提供了一种轻量级的机制,用于在任务之间传递信息和同步操作。事件标志组就像是一个共享的标志牌集合,每个标志位都代表
操作系统之输入输出管理
DKPT
# 操作系统 开发语言 学习 c语言 笔记 算法
操作系统中的输入输出(I/O)管理主要涉及I/O设备的分配、控制以及数据的传输。以下是对操作系统中I/O管理的详细解释:一、I/O设备I/O设备是计算机中用于数据输入和输出的外部设备,如键盘、鼠标、显示器、打印机等。这些设备按照不同的分类标准可以分为多种类型,如按使用特性分为人机交互类设备、存储设备和网络通信设备;按传输速率分为低速设备、中速设备和高速设备;按信息交换的单位分为块设备和字符设备等。
基于STM32 + W5500的以太网功能开发与时间同步方案
嵇英芹
基于STM32+W5500的以太网功能开发与时间同步方案STM32W5500移植NTP更新时间.rar项目地址:https://gitcode.com/open-source-toolkit/60355概述本项目展示了如何在STM32微控制器上集成W5500以太网控制器,实现了网络通信的基础,特别地,通过移植Ethernet相关驱动文件,结合NTP协议,实现了精确的RTC(实时时钟)对时功能。此外
SOA(面向服务架构)全面解析
Hello.Reader
java 架构 java 微服务
1.引言什么是SOA(面向服务架构)SOA(Service-OrientedArchitecture,面向服务架构)是一种将应用程序功能以“服务”的形式进行模块化设计的架构风格。这些服务是独立的功能模块,它们通过定义明确的接口进行通信,并可以跨不同的平台和技术栈相互协作。在SOA中,每个服务通常代表一个独立的业务功能(如客户管理、订单处理等),能够被其他服务独立地调用和复用。SOA的目标是通过服务
【gin】gin中使用protbuf消息传输go案例
{⌐■_■}
gin golang 开发语言
在Gin中使用Protobuf进行高效消息传输Protobuf(ProtocolBuffers)是一种高效的二进制序列化协议,广泛用于高性能场景的数据传输。相比JSON,Protobuf具有更小的体积和更快的解析速度,非常适合服务间通信或前后端交互。为什么选择Protobuf?特性JSONProtobuf体积大小较大(文本格式)较小(二进制格式)解析速度较慢较快跨语言支持较弱强(支持多种语言)定义
使用npm创建three.js项目
ShawnWeasley
npm javascript arcgis 前端 node.js
1.安装Node.js和npm首先,需要在您的计算机上安装Node.js和npm。Node.js是一个JavaScript运行环境,而npm是一个JavaScript包管理器。npm会随Node.js一起安装,因此只需要安装Node.js即可。从Node.js的官方网站(https://nodejs.org)下载并安装适合您操作系统的版本。2.创建一个新的项目在您希望创建项目的目录下,手动创建一个
linux中网卡配置,两张网卡,分别用于内网和外网的通信
橘橘子~
Linux linux
环境:centos7、VMware一、一张网卡实现内网通信(不能访问外网):1.首先查看已有的网卡:[root@localhost~]#ipaddr我的默认网卡是ens332.VMware右下角打开设置第一张网卡ens33:3.选择VMnet14.打开真机的网络连接查看网段,我的为112网段:5.配置网卡文件:<
水位监测系统|远程水位监测|水位自动监测
Susie酱
科技 自动驾驶 物联网
计讯物联水位监测系统,远程自动化全方位实时监控。监测点部署包括:目标因子采集传感器及仪器仪表、无线采集通信终端-水利RTU、数据实时采集自动上报,管理人员可通过监控中心平台远程监控,动态掌握监测点水位信息,数据分析处理,为政策规划提供决策依据,异常数据告警提示避免水生态灾害。远程水位自动监测系统组成感知层:水位计、雨量计、流量计、工业摄像头、(水质检测仪)网络传输层:计讯物联水利RTU遥测终端应用
周末了,写个转码经历流水账
程序员
一直没有好好的介绍过自己,这里写一篇文章来介绍下自己。我是普通学校出身,硕士期间自学Java,秋招最终斩获12个offer,包含中大厂、初创公司、国企等各类型公司。自学路上遇到不少问题,但最终结果还是满意的,最终是在北京某互联网厂从事一线开发。本科阶段(接触编程)我是非科班出身,本科学的不是计算机,本科的专业是通信工程;虽然不是计算机专业,但也被认为是计算机相关的专业。课程基本都是和电子、电路原理
电脑有两张网卡,如何实现同时访问外网和内网?
IT运维大本营
电脑 外网 内网 网卡
要是想让一台电脑用两张网卡,既能访问外网又能访问内网,那可以通过设置网络路由还有网卡的IP地址来达成。检查一下网卡的连接得保证电脑的两张网卡分别连到外网和内网的网络设备上,像路由器或者交换机啥的。给网卡配上不一样的IP地址分别给每张网卡设置IP地址,让它们对应的网络能正常通信:内网网卡:把它设置成内网网段的IP地址(像192.168.x.x或者其他内网地址)。外网网卡:可以设置成外网路由器分配的I
Java 多线程编程:并发控制与线程安全
m0_72547478
java 开发语言
摘要:本文聚焦于Java多线程编程中的并发控制和线程安全问题。详细阐述了多线程编程的基本概念,包括线程的创建、启动与生命周期。深入探讨了在多线程环境下如何通过synchronized关键字、Lock接口等机制实现并发控制,确保共享资源的线程安全。同时,介绍了线程间的通信方式以及常见的线程池技术,为Java开发者在处理多线程任务时提供全面的理论与实践指导。一、引言随着计算机硬件性能的不断提升,多线程
计算机网络的五层协议
青茶360
计算机网络 计算机网络
计算机网络的五层协议计算机网络的五层协议模型包括物理层、数据链路层、网络层、传输层和应用层,每一层都有其特定的功能和相关的协议。1物理层:负责传输原始的比特流,通过线路(有线或无线)将数据转换为电信号或光信号进行传输。物理层的主要功能是确保比特流的透明传输,屏蔽具体传输介质和物理设备的差异。数据链路层:负责在相邻节点之间建立可靠的通信,将物理层接收到的比特流组装成帧,并添加必要的控制
keystone 存储 android,KeyStone存储器架构
贺仙
keystone 存储 android
序言随着全球范围内的海量数据对无线和有线网络的强大冲击,运营商面临着严峻的挑战,他们需要不断推出既能满足当前需求也能满足未来需求的网络。因此,通信基础局端设备制造商在致力于降低每比特成本和功耗的同时,也在不断寻求能够满足当前及至未来需求的核心技术。TI最新推出的新型KeyStone多内核SoC架构能够游刃有余地满足这些挑战。本文引用地址:http://www.eepw.com.cn/article
UART中的奇偶校验和粘性奇偶校验(stick parity)
马志高
接口与协议 IC验证
1.UART传输UART传输分为起始位,数据位(从低到高),奇偶校验位,停止位,我们这里详细介绍一下奇偶校验位。2.奇偶校验位奇偶校验是一种常见的校验位方法,用于检测数据传输中的错误。奇校验:数据位的1的个数加上附加位的1的个数为奇数偶校验:数据位的1的个数加上附加位的1的个数为偶数举个例子,假设我们有一个UART串口通信系统,每个数据帧包含8位数据和1位奇偶校验位。我们选择奇校验。数据帧1:数据
433M无线收发模块详解
无线通信技术在现代社会中扮演着至关重要的角色,它让我们能够实现便捷的远程控制、智能家居、自动化以及各种物联网应用。无线通信技术包括WiFi、蓝牙、NFC、Zigbee、5G等等。本次我要给大家介绍无线通信技术之一的433M,从基本概念到工作原理再到实际应用。我们将逐步剖析433M模块背后的技术细节。无论您是初学者还是有一定经验的开发者,这篇文章都将为您提供全面的指导和启发,帮助您更好地了解和应用4
Node与Java后台对比
旭氏美术馆
Nodejs 服务端 并发编程 多线程 node.js java
高并发场景下的对比:nodejs具有单线程、非阻塞IO、事件循环/驱动的特点,所以在高并发场景下,线程占用cup处理资源,cup不用等待IO的处理过程,而是不停的的发起异步请求,在异步处理结束后继续下一步异步任务。所以不会出现线程阻塞。如图1所示。优势:cpu利用率较高,因为cpu不用等待IO,而时一直在发起异步请求。不足:单个线程崩溃后,所以任务都无法进行,而多线程并发场景下,某个线程崩溃,不影
【架构-38】如何选择通信协议和数据格式
W Y
架构 websocket restful xml json tcp/ip
一、通信协议选择不同的协议适用于不同的应用场景,关键在于数据传输的需求,如:实时性、带宽、可靠性等。下面是几种常见通信协议的适用场景:WebSocket适用场景:实时、双向数据传输、低延迟、持久连接特点:WebSocket协议允许建立一个持久的全双工(双向)连接,数据可以在客户端和服务器之间实时双向传输。它特别适合用于实时系统,如工业仿真软件中的状态更新、机器人路径跟踪、实时数据流、传感器数据和A
HDLC&PPP原理与配置
星空予蓝
网络 网络协议 网络
HDLC:高级数据链路控制协议PPP:点对点协议串行链路的数据传输方式:普遍用于广域网1.异步传输:以字节为单位传输数据,效率低,采用额外的起始位和停止位标记每个字节的开始与结束,每个字节有额外开销2.同步传输:以帧为单位,在通信时同步时钟来进行通信,DCE提供用于DCE和DTE数据传输的时钟信号,DTE通常使用DCE产生的时钟信号,效率高DCE:运营商-------------DTE:客户端HD
【网络协议】【http】【https】TLS解决了HTTP存在的问题-加密通信+摘要,数字签名+CA证书
钟离墨笺
网络协议 网络协议 http https
【网络协议】【http】【https】TLS解决了HTTP存在的问题-加密通信+摘要数字签名+CA证书ps:TLS前期发送的密码套件里面主要就是约定:密钥交换算法,签名算法,对称加密算法,摘要算法1加密通信一般选择非对称加密交换密钥对称加密进行后续通信解决了信息泄露问题1.1密钥交换算法(非对称加密)RAS,ECDHE公钥加密私钥解密的方式RAS通过三个随机数(客户端随机数+服务端随机数+客户端随
Netty处理字符格式的报错class java.lang.String cannot be cast to class io.netty.buffer.ByteBuf
kkoneone11
java 开发语言
问题背景:由于第一次处理和打印机进行通信的业务,转化格式为ByteBuf的时候报错:classjava.lang.Stringcannotbecasttoclassio.netty.buffer.ByteBuf分析:根据报错大概意思是String类型不能转化成ByteBuf,但是我印象中也没做什么操作,所以大概是在初始化Handler的时候出现了点错误,因此去看代码发现初始化里编解码是不仅有二进制
【国际学术会议推荐】IEEE Xplore、EI、CPCI、CNKI、EI Compendex、Scopus、Google scholar检索,方向涉及人文地理、城乡规划、遥感、通信、航天、能源、环境
努力学习的大大
学术会议推荐 能源 通信 人工智能 遥感 环境
【国际学术会议推荐】IEEEXplore、EI、CPCI、CNKI、EICompendex、Scopus、Googlescholar检索,方向涉及人文地理、城乡规划、遥感、通信、航天、能源、环境【国际学术会议推荐】IEEEXplore、EI、CPCI、CNKI、EICompendex、Scopus、Googlescholar检索,方向涉及人文地理、城乡规划、遥感、通信、航天、能源、环境文章目录【国
19. C语言 共用体(Union)详解
涛ing
C语言基础 c语言 java 算法 linux c++ visual studio vscode
本章目录前言1.什么是共用体?共用体与结构体的区别2.定义共用体示例:定义共用体变量3.共用体的内存布局和对齐规则内存大小计算字节对齐内存对齐原则4.访问共用体成员示例:基本访问5.共用体的实际应用场景场景1:节省内存场景2:网络通信数据包解析场景3:判断系统是大端还是小端6.高效使用共用体的技巧总结前言在C语言中,共用体(union)是一种特殊的复合数据类型,与结构体(struct)类似,但具备
java解析APK
3213213333332132
java apk linux 解析APK
解析apk有两种方法
1、结合安卓提供apktool工具,用java执行cmd解析命令获取apk信息
2、利用相关jar包里的集成方法解析apk
这里只给出第二种方法,因为第一种方法在linux服务器下会出现不在控制范围之内的结果。
public class ApkUtil
{
/**
* 日志对象
*/
private static Logger
nginx自定义ip访问N种方法
ronin47
nginx 禁止ip访问
因业务需要,禁止一部分内网访问接口, 由于前端架了F5,直接用deny或allow是不行的,这是因为直接获取的前端F5的地址。
所以开始思考有哪些主案可以实现这样的需求,目前可实施的是三种:
一:把ip段放在redis里,写一段lua
二:利用geo传递变量,写一段
mysql timestamp类型字段的CURRENT_TIMESTAMP与ON UPDATE CURRENT_TIMESTAMP属性
dcj3sjt126com
mysql
timestamp有两个属性,分别是CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP两种,使用情况分别如下:
1.
CURRENT_TIMESTAMP
当要向数据库执行insert操作时,如果有个timestamp字段属性设为
CURRENT_TIMESTAMP,则无论这
struts2+spring+hibernate分页显示
171815164
Hibernate
分页显示一直是web开发中一大烦琐的难题,传统的网页设计只在一个JSP或者ASP页面中书写所有关于数据库操作的代码,那样做分页可能简单一点,但当把网站分层开发后,分页就比较困难了,下面是我做Spring+Hibernate+Struts2项目时设计的分页代码,与大家分享交流。
1、DAO层接口的设计,在MemberDao接口中定义了如下两个方法:
public in
构建自己的Wrapper应用
g21121
rap
我们已经了解Wrapper的目录结构,下面可是正式利用Wrapper来包装我们自己的应用,这里假设Wrapper的安装目录为:/usr/local/wrapper。
首先,创建项目应用
&nb
[简单]工作记录_多线程相关
53873039oycg
多线程
最近遇到多线程的问题,原来使用异步请求多个接口(n*3次请求) 方案一 使用多线程一次返回数据,最开始是使用5个线程,一个线程顺序请求3个接口,超时终止返回 缺点 测试发现必须3个接
调试jdk中的源码,查看jdk局部变量
程序员是怎么炼成的
jdk 源码
转自:http://www.douban.com/note/211369821/
学习jdk源码时使用--
学习java最好的办法就是看jdk源代码,面对浩瀚的jdk(光源码就有40M多,比一个大型网站的源码都多)从何入手呢,要是能单步调试跟进到jdk源码里并且能查看其中的局部变量最好了。
可惜的是sun提供的jdk并不能查看运行中的局部变量
Oracle RAC Failover 详解
aijuans
oracle
Oracle RAC 同时具备HA(High Availiablity) 和LB(LoadBalance). 而其高可用性的基础就是Failover(故障转移). 它指集群中任何一个节点的故障都不会影响用户的使用,连接到故障节点的用户会被自动转移到健康节点,从用户感受而言, 是感觉不到这种切换。
Oracle 10g RAC 的Failover 可以分为3种:
1. Client-Si
form表单提交数据编码方式及tomcat的接受编码方式
antonyup_2006
JavaScript tomcat 浏览器 互联网 servlet
原帖地址:http://www.iteye.com/topic/266705
form有2中方法把数据提交给服务器,get和post,分别说下吧。
(一)get提交
1.首先说下客户端(浏览器)的form表单用get方法是如何将数据编码后提交给服务器端的吧。
对于get方法来说,都是把数据串联在请求的url后面作为参数,如:http://localhost:
JS初学者必知的基础
百合不是茶
js函数 js入门基础
JavaScript是网页的交互语言,实现网页的各种效果,
JavaScript 是世界上最流行的脚本语言。
JavaScript 是属于 web 的语言,它适用于 PC、笔记本电脑、平板电脑和移动电话。
JavaScript 被设计为向 HTML 页面增加交互性。
许多 HTML 开发者都不是程序员,但是 JavaScript 却拥有非常简单的语法。几乎每个人都有能力将小的
iBatis的分页分析与详解
bijian1013
java ibatis
分页是操作数据库型系统常遇到的问题。分页实现方法很多,但效率的差异就很大了。iBatis是通过什么方式来实现这个分页的了。查看它的实现部分,发现返回的PaginatedList实际上是个接口,实现这个接口的是PaginatedDataList类的对象,查看PaginatedDataList类发现,每次翻页的时候最
精通Oracle10编程SQL(15)使用对象类型
bijian1013
oracle 数据库 plsql
/*
*使用对象类型
*/
--建立和使用简单对象类型
--对象类型包括对象类型规范和对象类型体两部分。
--建立和使用不包含任何方法的对象类型
CREATE OR REPLACE TYPE person_typ1 as OBJECT(
name varchar2(10),gender varchar2(4),birthdate date
);
drop type p
【Linux命令二】文本处理命令awk
bit1129
linux命令
awk是Linux用来进行文本处理的命令,在日常工作中,广泛应用于日志分析。awk是一门解释型编程语言,包含变量,数组,循环控制结构,条件控制结构等。它的语法采用类C语言的语法。
awk命令用来做什么?
1.awk适用于具有一定结构的文本行,对其中的列进行提取信息
2.awk可以把当前正在处理的文本行提交给Linux的其它命令处理,然后把直接结构返回给awk
3.awk实际工
JAVA(ssh2框架)+Flex实现权限控制方案分析
白糖_
java
目前项目使用的是Struts2+Hibernate+Spring的架构模式,目前已经有一套针对SSH2的权限系统,运行良好。但是项目有了新需求:在目前系统的基础上使用Flex逐步取代JSP,在取代JSP过程中可能存在Flex与JSP并存的情况,所以权限系统需要进行修改。
【SSH2权限系统的实现机制】
权限控制分为页面和后台两块:不同类型用户的帐号分配的访问权限是不同的,用户使
angular.forEach
boyitech
AngularJS AngularJS API angular.forEach
angular.forEach 描述: 循环对obj对象的每个元素调用iterator, obj对象可以是一个Object或一个Array. Iterator函数调用方法: iterator(value, key, obj), 其中obj是被迭代对象,key是obj的property key或者是数组的index,value就是相应的值啦. (此函数不能够迭代继承的属性.)
java-谷歌面试题-给定一个排序数组,如何构造一个二叉排序树
bylijinnan
二叉排序树
import java.util.LinkedList;
public class CreateBSTfromSortedArray {
/**
* 题目:给定一个排序数组,如何构造一个二叉排序树
* 递归
*/
public static void main(String[] args) {
int[] data = { 1, 2, 3, 4,
action执行2次
Chen.H
JavaScript jsp XHTML css Webwork
xwork 写道 <action name="userTypeAction"
class="com.ekangcount.website.system.view.action.UserTypeAction">
<result name="ssss" type="dispatcher">
[时空与能量]逆转时空需要消耗大量能源
comsci
能源
无论如何,人类始终都想摆脱时间和空间的限制....但是受到质量与能量关系的限制,我们人类在目前和今后很长一段时间内,都无法获得大量廉价的能源来进行时空跨越.....
在进行时空穿梭的实验中,消耗超大规模的能源是必然
oracle的正则表达式(regular expression)详细介绍
daizj
oracle 正则表达式
正则表达式是很多编程语言中都有的。可惜oracle8i、oracle9i中一直迟迟不肯加入,好在oracle10g中终于增加了期盼已久的正则表达式功能。你可以在oracle10g中使用正则表达式肆意地匹配你想匹配的任何字符串了。
正则表达式中常用到的元数据(metacharacter)如下:
^ 匹配字符串的开头位置。
$ 匹配支付传的结尾位置。
*
报表工具与报表性能的关系
datamachine
报表工具 birt 报表性能 润乾报表
在选择报表工具时,性能一直是用户关心的指标,但是,报表工具的性能和整个报表系统的性能有多大关系呢?
要回答这个问题,首先要分析一下报表的处理过程包含哪些环节,哪些环节容易出现性能瓶颈,如何优化这些环节。
一、报表处理的一般过程分析
1、用户选择报表输入参数后,报表引擎会根据报表模板和输入参数来解析报表,并将数据计算和读取请求以SQL的方式发送给数据库。
2、
初一上学期难记忆单词背诵第一课
dcj3sjt126com
word english
what 什么
your 你
name 名字
my 我的
am 是
one 一
two 二
three 三
four 四
five 五
class 班级,课
six 六
seven 七
eight 八
nince 九
ten 十
zero 零
how 怎样
old 老的
eleven 十一
twelve 十二
thirteen
我学过和准备学的各种技术
dcj3sjt126com
技术
语言VB https://msdn.microsoft.com/zh-cn/library/2x7h1hfk.aspxJava http://docs.oracle.com/javase/8/C# https://msdn.microsoft.com/library/vstudioPHP http://php.net/manual/en/Html
struts2中token防止重复提交表单
蕃薯耀
重复提交表单 struts2中token
struts2中token防止重复提交表单
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2015年7月12日 11:52:32 星期日
ht
线性查找二维数组
hao3100590
二维数组
1.算法描述
有序(行有序,列有序,且每行从左至右递增,列从上至下递增)二维数组查找,要求复杂度O(n)
2.使用到的相关知识:
结构体定义和使用,二维数组传递(http://blog.csdn.net/yzhhmhm/article/details/2045816)
3.使用数组名传递
这个的不便之处很明显,一旦确定就是不能设置列值
//使
spring security 3中推荐使用BCrypt算法加密密码
jackyrong
Spring Security
spring security 3中推荐使用BCrypt算法加密密码了,以前使用的是md5,
Md5PasswordEncoder 和 ShaPasswordEncoder,现在不推荐了,推荐用bcrpt
Bcrpt中的salt可以是随机的,比如:
int i = 0;
while (i < 10) {
String password = "1234
学习编程并不难,做到以下几点即可!
lampcy
java html 编程语言
不论你是想自己设计游戏,还是开发iPhone或安卓手机上的应用,还是仅仅为了娱乐,学习编程语言都是一条必经之路。编程语言种类繁多,用途各 异,然而一旦掌握其中之一,其他的也就迎刃而解。作为初学者,你可能要先从Java或HTML开始学,一旦掌握了一门编程语言,你就发挥无穷的想象,开发 各种神奇的软件啦。
1、确定目标
学习编程语言既充满乐趣,又充满挑战。有些花费多年时间学习一门编程语言的大学生到
架构师之mysql----------------用group+inner join,left join ,right join 查重复数据(替代in)
nannan408
right join
1.前言。
如题。
2.代码
(1)单表查重复数据,根据a分组
SELECT m.a,m.b, INNER JOIN (select a,b,COUNT(*) AS rank FROM test.`A` A GROUP BY a HAVING rank>1 )k ON m.a=k.a
(2)多表查询 ,
使用改为le
jQuery选择器小结 VS 节点查找(附css的一些东西)
Everyday都不同
jquery css name选择器 追加元素 查找节点
最近做前端页面,频繁用到一些jQuery的选择器,所以特意来总结一下:
测试页面:
<html>
<head>
<script src="jquery-1.7.2.min.js"></script>
<script>
/*$(function() {
$(documen
关于EXT
tntxia
ext
ExtJS是一个很不错的Ajax框架,可以用来开发带有华丽外观的富客户端应用,使得我们的b/s应用更加具有活力及生命力。ExtJS是一个用 javascript编写,与后台技术无关的前端ajax框架。因此,可以把ExtJS用在.Net、Java、Php等各种开发语言开发的应用中。
ExtJs最开始基于YUI技术,由开发人员Jack
一个MIT计算机博士对数学的思考
xjnine
Math
在过去的一年中,我一直在数学的海洋中游荡,research进展不多,对于数学世界的阅历算是有了一些长进。为什么要深入数学的世界?作为计算机的学生,我没有任何企图要成为一个数学家。我学习数学的目的,是要想爬上巨人的肩膀,希望站在更高的高度,能把我自己研究的东西看得更深广一些。说起来,我在刚来这个学校的时候,并没有预料到我将会有一个深入数学的旅程。我的导师最初希望我去做的题目,是对appe