/*!

* Sizzle CSS Selector Engine v2.2.0-pre
* http://sizzlejs.com/
*
* Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-12-16
*/

(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;
},

// General-purpose constants
MAX_NEGATIVE = 1 << 31,

// Instance methods
hasOwn = ({}).hasOwnProperty,
arr = [],
pop = arr.pop,
push_native = arr.push,
push = arr.push,
slice = arr.slice,
// Use a stripped-down indexOf as it's faster than native
// http://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

// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",
// http://www.w3.org/TR/css3-syntax/#characters
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",

// Loosely modeled on CSS identifier characters
// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
identifier = characterEncoding.replace( "w", "w#" ),

// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
        // Operator (capture 2)
        "*([*^$|!~]?=)" + whitespace +
        // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
        "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
        "*\\]",

pseudos = ":(" + characterEncoding + ")(?:\\((" +
        // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
        // 1. quoted (capture 3; capture 4 or capture 5)
        "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
        // 2. simple (capture 6)
        "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
        // 3. anything else (capture 2)
        ".*" +
        ")\\)|)",

// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
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( "^#(" + characterEncoding + ")" ),
        "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
        "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
        "ATTR": new RegExp( "^" + attributes ),
        "PSEUDO": new RegExp( "^" + pseudos ),
        "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
                "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
                "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
        "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
        // For use in libraries implementing .is()
        // We use this for POS matching in `select`
        "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
                whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
},

rinputs = /^(?:input|select|textarea|button)$/i,
rheader = /^h\d$/i,

rnative = /^[^{]+\{\s*\[native \w/,

// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

rsibling = /[+~]/,
rescape = /'|\\/g,

// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
funescape = function( _, escaped, escapedWhitespace ) {
        var high = "0x" + escaped - 0x10000;
        // NaN means non-codepoint
        // Support: Firefox<24
        // Workaround erroneous numeric interpretation of +"0x"
        return high !== high || escapedWhitespace ?
                escaped :
                high < 0 ?
                        // BMP codepoint
                        String.fromCharCode( high + 0x10000 ) :
                        // Supplemental Plane codepoint (surrogate pair)
                        String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
},

// Used for iframes
// See setDocument()
// Removing the function wrapper causes a "Permission Denied"
// error in IE
unloadHandler = function() {
        setDocument();
};

// Optimize for push.apply( _, NodeList ) try {

push.apply(
        (arr = slice.call( preferredDoc.childNodes )),
        preferredDoc.childNodes
);
// Support: Android<4.0
// Detect silently failing push.apply
arr[ preferredDoc.childNodes.length ].nodeType;

} catch ( e ) {

push = { apply: arr.length ?

        // Leverage slice if possible
        function( target, els ) {
                push_native.apply( target, slice.call(els) );
        } :

        // Support: IE<9
        // Otherwise append directly
        function( target, els ) {
                var j = target.length,
                        i = 0;
                // Can't trust NodeList.length
                while ( (target[j++] = els[i++]) ) {}
                target.length = j - 1;
        }
};

}

function Sizzle( selector, context, results, seed ) {

var match, elem, m, nodeType,
        // QSA vars
        i, groups, old, nid, newContext, newSelector;

if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
        setDocument( context );
}

context = context || document;
results = results || [];
nodeType = context.nodeType;

if ( typeof selector !== "string" || !selector ||
        nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

        return results;
}

if ( !seed && documentIsHTML ) {

        // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
        if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
                // Speed-up: Sizzle("#ID")
                if ( (m = match[1]) ) {
                        if ( nodeType === 9 ) {
                                elem = context.getElementById( m );
                                // Check parentNode to catch when Blackberry 4.6 returns
                                // nodes that are no longer in the document (jQuery #6963)
                                if ( elem && elem.parentNode ) {
                                        // Handle the case where IE, Opera, and Webkit return items
                                        // by name instead of ID
                                        if ( elem.id === m ) {
                                                results.push( elem );
                                                return results;
                                        }
                                } else {
                                        return results;
                                }
                        } else {
                                // Context is not a document
                                if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
                                        contains( context, elem ) && elem.id === m ) {
                                        results.push( elem );
                                        return results;
                                }
                        }

                // Speed-up: Sizzle("TAG")
                } else if ( match[2] ) {
                        push.apply( results, context.getElementsByTagName( selector ) );
                        return results;

                // Speed-up: Sizzle(".CLASS")
                } else if ( (m = match[3]) && support.getElementsByClassName ) {
                        push.apply( results, context.getElementsByClassName( m ) );
                        return results;
                }
        }

        // QSA path
        if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
                nid = old = expando;
                newContext = context;
                newSelector = nodeType !== 1 && selector;

                // qSA works strangely on Element-rooted queries
                // We can work around this by specifying an extra ID on the root
                // and working up from there (Thanks to Andrew Dupont for the technique)
                // IE 8 doesn't work on object elements
                if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
                        groups = tokenize( selector );

                        if ( (old = context.getAttribute("id")) ) {
                                nid = old.replace( rescape, "\\$&" );
                        } else {
                                context.setAttribute( "id", nid );
                        }
                        nid = "[id='" + nid + "'] ";

                        i = groups.length;
                        while ( i-- ) {
                                groups[i] = nid + toSelector( groups[i] );
                        }
                        newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
                        newSelector = groups.join(",");
                }

                if ( newSelector ) {
                        try {
                                push.apply( results,
                                        newContext.querySelectorAll( newSelector )
                                );
                                return results;
                        } catch(qsaError) {
                        } finally {
                                if ( !old ) {
                                        context.removeAttribute("id");
                                }
                        }
                }
        }
}

// All others
return select( selector.replace( rtrim, "$1" ), context, results, seed );

}

/**

* Create key-value caches of limited size
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
*      property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
*      deleting the oldest entry
*/

function createCache() {

var keys = [];

function cache( key, value ) {
        // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
        if ( keys.push( key + " " ) > Expr.cacheLength ) {
                // Only keep the most recent entries
                delete cache[ keys.shift() ];
        }
        return (cache[ key + " " ] = value);
}
return cache;

}

/**

* Mark a function for special use by Sizzle
* @param {Function} fn The function to mark
*/

function markFunction( fn ) {

fn[ expando ] = true;
return fn;

}

/**

* Support testing using an element
* @param {Function} fn Passed the created div and expects a boolean result
*/

function assert( fn ) {

var div = document.createElement("div");

try {
        return !!fn( div );
} catch (e) {
        return false;
} finally {
        // Remove from its parent by default
        if ( div.parentNode ) {
                div.parentNode.removeChild( div );
        }
        // release memory in IE
        div = null;
}

}

/**

* Adds the same handler for all of the specified attrs
* @param {String} attrs Pipe-separated list of attributes
* @param {Function} handler The method that will be applied
*/

function addHandle( attrs, handler ) {

var arr = attrs.split("|"),
        i = attrs.length;

while ( i-- ) {
        Expr.attrHandle[ arr[i] ] = handler;
}

}

/**

* Checks document order of two siblings
* @param {Element} a
* @param {Element} b
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
*/

function siblingCheck( a, b ) {

var cur = b && a,
        diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
                ( ~b.sourceIndex || MAX_NEGATIVE ) -
                ( ~a.sourceIndex || MAX_NEGATIVE );

// Use IE sourceIndex if available on both nodes
if ( diff ) {
        return diff;
}

// Check if b follows a
if ( cur ) {
        while ( (cur = cur.nextSibling) ) {
                if ( cur === b ) {
                        return -1;
                }
        }
}

return a ? 1 : -1;

}

/**

* Returns a function to use in pseudos for input types
* @param {String} type
*/

function createInputPseudo( type ) {

return function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return name === "input" && elem.type === type;
};

}

/**

* Returns a function to use in pseudos for buttons
* @param {String} type
*/

function createButtonPseudo( type ) {

return function( elem ) {
        var name = elem.nodeName.toLowerCase();
        return (name === "input" || name === "button") && elem.type === type;
};

}

/**

* Returns a function to use in pseudos for positionals
* @param {Function} fn
*/

function createPositionalPseudo( fn ) {

return markFunction(function( argument ) {
        argument = +argument;
        return markFunction(function( seed, matches ) {
                var j,
                        matchIndexes = fn( [], seed.length, argument ),
                        i = matchIndexes.length;

                // Match elements found at the specified indexes
                while ( i-- ) {
                        if ( seed[ (j = matchIndexes[i]) ] ) {
                                seed[j] = !(matches[j] = seed[j]);
                        }
                }
        });
});

}

/**

* Checks a node for validity as a Sizzle context
* @param {Element|Object=} context
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/

function testContext( context ) {

return context && typeof context.getElementsByTagName !== "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, parent,
        doc = node ? node.ownerDocument || node : preferredDoc;

// If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
        return document;
}

// Set our document
document = doc;
docElem = doc.documentElement;
parent = doc.defaultView;

// Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
// IE6-8 do not support the defaultView property so parent will be undefined
if ( parent && parent !== parent.top ) {
        // IE11 does not have attachEvent, so all must suffer
        if ( parent.addEventListener ) {
                parent.addEventListener( "unload", unloadHandler, false );
        } else if ( parent.attachEvent ) {
                parent.attachEvent( "onunload", unloadHandler );
        }
}

/* Support tests
---------------------------------------------------------------------- */
documentIsHTML = !isXML( doc );

/* Attributes
---------------------------------------------------------------------- */

// Support: IE<8
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support.attributes = assert(function( div ) {
        div.className = "i";
        return !div.getAttribute("className");
});

/* getElement(s)By*
---------------------------------------------------------------------- */

// Check if getElementsByTagName("*") returns only elements
support.getElementsByTagName = assert(function( div ) {
        div.appendChild( doc.createComment("") );
        return !div.getElementsByTagName("*").length;
});

// Support: IE<9
support.getElementsByClassName = rnative.test( doc.getElementsByClassName );

// Support: IE<10
// Check if getElementById returns elements by name
// The broken getElementById methods don't pick up programatically-set names,
// so use a roundabout getElementsByName test
support.getById = assert(function( div ) {
        docElem.appendChild( div ).id = expando;
        return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
});

// ID find and filter
if ( support.getById ) {
        Expr.find["ID"] = function( id, context ) {
                if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
                        var m = context.getElementById( id );
                        // Check parentNode to catch when Blackberry 4.6 returns
                        // nodes that are no longer in the document #6963
                        return m && m.parentNode ? [ m ] : [];
                }
        };
        Expr.filter["ID"] = function( id ) {
                var attrId = id.replace( runescape, funescape );
                return function( elem ) {
                        return elem.getAttribute("id") === attrId;
                };
        };
} else {
        // Support: IE6/7
        // getElementById is not reliable as a find shortcut
        delete Expr.find["ID"];

        Expr.filter["ID"] =  function( id ) {
                var attrId = id.replace( runescape, funescape );
                return function( elem ) {
                        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
                        return node && node.value === attrId;
                };
        };
}

// 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 ( documentIsHTML ) {
                return context.getElementsByClassName( className );
        }
};

/* QSA/matchesSelector
---------------------------------------------------------------------- */

// QSA and matchesSelector support

// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
rbuggyMatches = [];

// qSa(:focus) reports false when true (Chrome 21)
// We allow this because of a bug in IE8/9 that throws an error
// whenever `document.activeElement` is accessed on an iframe
// So, we allow :focus to pass through QSA all the time to avoid the IE error
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [];

if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
        // Build QSA regex
        // Regex strategy adopted from Diego Perini
        assert(function( div ) {
                // Select is set to empty string on purpose
                // This is to test IE's treatment of not explicitly
                // setting a boolean content attribute,
                // since its presence should be enough
                // http://bugs.jquery.com/ticket/12359
                docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
                        "<select id='" + expando + "-\f]' msallowcapture=''>" +
                        "<option selected=''></option></select>";

                // Support: IE8, Opera 11-12.16
                // Nothing should be selected when empty strings follow ^= or $= or *=
                // The test attribute must be unknown in Opera but "safe" for WinRT
                // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
                if ( div.querySelectorAll("[msallowcapture^='']").length ) {
                        rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
                }

                // Support: IE8
                // Boolean attributes and "value" are not treated correctly
                if ( !div.querySelectorAll("[selected]").length ) {
                        rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
                }

                // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
                if ( !div.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 ( !div.querySelectorAll(":checked").length ) {
                        rbuggyQSA.push(":checked");
                }

                // Support: Safari 8+, iOS 8+
                // https://bugs.webkit.org/show_bug.cgi?id=136851
                // In-page `selector#id sibing-combinator selector` fails
                if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
                        rbuggyQSA.push(".#.+[+~]");
                }
        });

        assert(function( div ) {
                // Support: Windows 8 Native Apps
                // The type and name attributes are restricted during .innerHTML assignment
                var input = doc.createElement("input");
                input.setAttribute( "type", "hidden" );
                div.appendChild( input ).setAttribute( "name", "D" );

                // Support: IE8
                // Enforce case-sensitivity of name attribute
                if ( div.querySelectorAll("[name=d]").length ) {
                        rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
                }

                // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
                // IE8 throws error here and will not see later tests
                if ( !div.querySelectorAll(":enabled").length ) {
                        rbuggyQSA.push( ":enabled", ":disabled" );
                }

                // Opera 10-11 does not throw on post-comma invalid pseudos
                div.querySelectorAll("*,:x");
                rbuggyQSA.push(",.*:");
        });
}

if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
        docElem.webkitMatchesSelector ||
        docElem.mozMatchesSelector ||
        docElem.oMatchesSelector ||
        docElem.msMatchesSelector) )) ) {

        assert(function( div ) {
                // Check to see if it's possible to do matchesSelector
                // on a disconnected node (IE 9)
                support.disconnectedMatch = matches.call( div, "div" );

                // This should fail with an exception
                // Gecko does not error, returns false instead
                matches.call( div, "[s!='']:x" );
                rbuggyMatches.push( "!=", pseudos );
        });
}

rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );

/* Contains
---------------------------------------------------------------------- */
hasCompare = rnative.test( docElem.compareDocumentPosition );

// Element contains another
// Purposefully does not implement inclusive descendent
// As in, an element does not contain itself
contains = hasCompare || rnative.test( docElem.contains ) ?
        function( a, b ) {
                var adown = a.nodeType === 9 ? a.documentElement : a,
                        bup = b && b.parentNode;
                return a === bup || !!( bup && bup.nodeType === 1 && (
                        adown.contains ?
                                adown.contains( bup ) :
                                a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
                ));
        } :
        function( a, b ) {
                if ( b ) {
                        while ( (b = b.parentNode) ) {
                                if ( b === a ) {
                                        return true;
                                }
                        }
                }
                return false;
        };

/* Sorting
---------------------------------------------------------------------- */

// Document order sorting
sortOrder = hasCompare ?
function( a, b ) {

        // Flag for duplicate removal
        if ( a === b ) {
                hasDuplicate = true;
                return 0;
        }

        // Sort on method existence if only one input has compareDocumentPosition
        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
        if ( compare ) {
                return compare;
        }

        // Calculate position if both inputs belong to the same document
        compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
                a.compareDocumentPosition( b ) :

                // Otherwise we know they are disconnected
                1;

        // Disconnected nodes
        if ( compare & 1 ||
                (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {

                // Choose the first element that is related to our preferred document
                if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
                        return -1;
                }
                if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
                        return 1;
                }

                // Maintain original order
                return sortInput ?
                        ( indexOf( 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 === doc ? -1 :
                        b === doc ? 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 doc;

};

Sizzle.matches = function( expr, elements ) {

return Sizzle( expr, null, null, elements );

};

Sizzle.matchesSelector = function( elem, expr ) {

// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
        setDocument( elem );
}

// Make sure that attribute selectors are quoted
expr = expr.replace( rattributeQuotes, "='$1']" );

if ( support.matchesSelector && documentIsHTML &&
        ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
        ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {

        try {
                var ret = matches.call( elem, expr );

                // IE 9's matchesSelector returns false on disconnected nodes
                if ( ret || support.disconnectedMatch ||
                                // As well, disconnected nodes are said to be in a document
                                // fragment in IE 9
                                elem.document && elem.document.nodeType !== 11 ) {
                        return ret;
                }
        } catch (e) {}
}

return Sizzle( expr, document, null, [ elem ] ).length > 0;

};

Sizzle.contains = function( context, elem ) {

// Set document vars if needed
if ( ( context.ownerDocument || context ) !== document ) {
        setDocument( context );
}
return contains( context, elem );

};

Sizzle.attr = function( elem, name ) {

// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
        setDocument( elem );
}

var fn = Expr.attrHandle[ name.toLowerCase() ],
        // Don't get fooled by Object.prototype properties (jQuery #13807)
        val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
                fn( elem, name, !documentIsHTML ) :
                undefined;

return val !== undefined ?
        val :
        support.attributes || !documentIsHTML ?
                elem.getAttribute( name ) :
                (val = elem.getAttributeNode(name)) && val.specified ?
                        val.value :
                        null;

};

Sizzle.error = function( msg ) {

throw new Error( "Syntax error, unrecognized expression: " + msg );

};

/**

* Document sorting and removing duplicates
* @param {ArrayLike} results
*/

Sizzle.uniqueSort = function( results ) {

var elem,
        duplicates = [],
        j = 0,
        i = 0;

// Unless we *know* we can detect duplicates, assume their presence
hasDuplicate = !support.detectDuplicates;
sortInput = !support.sortStable && results.slice( 0 );
results.sort( sortOrder );

if ( hasDuplicate ) {
        while ( (elem = results[i++]) ) {
                if ( elem === results[ i ] ) {
                        j = duplicates.push( i );
                }
        }
        while ( j-- ) {
                results.splice( duplicates[ j ], 1 );
        }
}

// Clear input after sorting to release objects
// See https://github.com/jquery/sizzle/pull/225
sortInput = null;

return results;

};

/**

* Utility function for retrieving the text value of an array of DOM nodes
* @param {Array|Element} elem
*/

getText = Sizzle.getText = function( elem ) {

var node,
        ret = "",
        i = 0,
        nodeType = elem.nodeType;

if ( !nodeType ) {
        // If no nodeType, this is expected to be an array
        while ( (node = elem[i++]) ) {
                // Do not traverse comment nodes
                ret += getText( node );
        }
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
        // Use textContent for elements
        // innerText usage removed for consistency of new lines (jQuery #11153)
        if ( typeof elem.textContent === "string" ) {
                return elem.textContent;
        } else {
                // Traverse its children
                for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                        ret += getText( elem );
                }
        }
} else if ( nodeType === 3 || nodeType === 4 ) {
        return elem.nodeValue;
}
// Do not include comment or processing instruction nodes

return ret;

};

Expr = Sizzle.selectors = {

// Can be adjusted by the user
cacheLength: 50,

createPseudo: markFunction,

match: matchExpr,

attrHandle: {},

find: {},

relative: {
        ">": { dir: "parentNode", first: true },
        " ": { dir: "parentNode" },
        "+": { dir: "previousSibling", first: true },
        "~": { dir: "previousSibling" }
},

preFilter: {
        "ATTR": function( match ) {
                match[1] = match[1].replace( runescape, funescape );

                // Move the given value to match[3] whether quoted or unquoted
                match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );

                if ( match[2] === "~=" ) {
                        match[3] = " " + match[3] + " ";
                }

                return match.slice( 0, 4 );
        },

        "CHILD": function( match ) {
                /* matches from matchExpr["CHILD"]
                        1 type (only|nth|...)
                        2 what (child|of-type)
                        3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
                        4 xn-component of xn+y argument ([+-]?\d*n|)
                        5 sign of xn-component
                        6 x of xn-component
                        7 sign of y-component
                        8 y of y-component
                */
                match[1] = match[1].toLowerCase();

                if ( match[1].slice( 0, 3 ) === "nth" ) {
                        // nth-* requires argument
                        if ( !match[3] ) {
                                Sizzle.error( match[0] );
                        }

                        // numeric x and y parameters for Expr.filter.CHILD
                        // remember that false/true cast respectively to 0/1
                        match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
                        match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );

                // other types prohibit arguments
                } else if ( match[3] ) {
                        Sizzle.error( match[0] );
                }

                return match;
        },

        "PSEUDO": function( match ) {
                var excess,
                        unquoted = !match[6] && match[2];

                if ( matchExpr["CHILD"].test( match[0] ) ) {
                        return null;
                }

                // Accept quoted arguments as-is
                if ( match[3] ) {
                        match[2] = match[4] || match[5] || "";

                // Strip excess characters from unquoted arguments
                } else if ( unquoted && rpseudo.test( unquoted ) &&
                        // Get excess from tokenize (recursively)
                        (excess = tokenize( unquoted, true )) &&
                        // advance to the next closing parenthesis
                        (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {

                        // excess is a negative index
                        match[0] = match[0].slice( 0, excess );
                        match[2] = unquoted.slice( 0, excess );
                }

                // Return only captures needed by the pseudo filter method (type and argument)
                return match.slice( 0, 3 );
        }
},

filter: {

        "TAG": function( nodeNameSelector ) {
                var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
                return nodeNameSelector === "*" ?
                        function() { return true; } :
                        function( elem ) {
                                return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
                        };
        },

        "CLASS": function( className ) {
                var pattern = classCache[ className + " " ];

                return pattern ||
                        (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
                        classCache( className, function( elem ) {
                                return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "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, outerCache, node, diff, nodeIndex, start,
                                        dir = simple !== forward ? "nextSibling" : "previousSibling",
                                        parent = elem.parentNode,
                                        name = ofType && elem.nodeName.toLowerCase(),
                                        useCache = !xml && !ofType;

                                if ( parent ) {

                                        // :(first|last|only)-(child|of-type)
                                        if ( simple ) {
                                                while ( dir ) {
                                                        node = elem;
                                                        while ( (node = node[ dir ]) ) {
                                                                if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
                                                                        return false;
                                                                }
                                                        }
                                                        // Reverse direction for :only-* (if we haven't yet done so)
                                                        start = dir = type === "only" && !start && "nextSibling";
                                                }
                                                return true;
                                        }

                                        start = [ forward ? parent.firstChild : parent.lastChild ];

                                        // non-xml :nth-child(...) stores cache data on `parent`
                                        if ( forward && useCache ) {
                                                // Seek `elem` from a previously-cached index
                                                outerCache = parent[ expando ] || (parent[ expando ] = {});
                                                cache = outerCache[ type ] || [];
                                                nodeIndex = cache[0] === dirruns && cache[1];
                                                diff = cache[0] === dirruns && cache[2];
                                                node = nodeIndex && parent.childNodes[ nodeIndex ];

                                                while ( (node = ++nodeIndex && node && node[ dir ] ||

                                                        // Fallback to seeking `elem` from the start
                                                        (diff = nodeIndex = 0) || start.pop()) ) {

                                                        // When found, cache indexes on `parent` and break
                                                        if ( node.nodeType === 1 && ++diff && node === elem ) {
                                                                outerCache[ type ] = [ dirruns, nodeIndex, diff ];
                                                                break;
                                                        }
                                                }

                                        // Use previously-cached element index if available
                                        } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
                                                diff = cache[1];

                                        // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
                                        } else {
                                                // Use the same loop as above to seek `elem` from the start
                                                while ( (node = ++nodeIndex && node && node[ dir ] ||
                                                        (diff = nodeIndex = 0) || start.pop()) ) {

                                                        if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
                                                                // Cache the index of each encountered element
                                                                if ( useCache ) {
                                                                        (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
                                                                }

                                                                if ( node === elem ) {
                                                                        break;
                                                                }
                                                        }
                                                }
                                        }

                                        // Incorporate the offset, then check against cycle size
                                        diff -= last;
                                        return diff === first || ( diff % first === 0 && diff / first >= 0 );
                                }
                        };
        },

        "PSEUDO": function( pseudo, argument ) {
                // pseudo-class names are case-insensitive
                // http://www.w3.org/TR/selectors/#pseudo-classes
                // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
                // Remember that setFilters inherits from pseudos
                var args,
                        fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
                                Sizzle.error( "unsupported pseudo: " + pseudo );

                // The user may use createPseudo to indicate that
                // arguments are needed to create the filter function
                // just as Sizzle does
                if ( fn[ expando ] ) {
                        return fn( argument );
                }

                // But maintain support for old signatures
                if ( fn.length > 1 ) {
                        args = [ pseudo, pseudo, "", argument ];
                        return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
                                markFunction(function( seed, matches ) {
                                        var idx,
                                                matched = fn( seed, argument ),
                                                i = matched.length;
                                        while ( i-- ) {
                                                idx = indexOf( 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": function( elem ) {
                return elem.disabled === false;
        },

        "disabled": function( elem ) {
                return elem.disabled === true;
        },

        "checked": function( elem ) {
                // In CSS3, :checked should return both checked and selected elements
                // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
                var nodeName = elem.nodeName.toLowerCase();
                return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
        },

        "selected": function( elem ) {
                // Accessing this property makes selected-by-default
                // options in Safari work properly
                if ( elem.parentNode ) {
                        elem.parentNode.selectedIndex;
                }

                return elem.selected === true;
        },

        // Contents
        "empty": function( elem ) {
                // http://www.w3.org/TR/selectors/#empty-pseudo
                // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
                //   but not by others (comment: 8; processing instruction: 7; etc.)
                // nodeType < 6 works because attributes (2) do not appear as children
                for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
                        if ( elem.nodeType < 6 ) {
                                return false;
                        }
                }
                return true;
        },

        "parent": function( elem ) {
                return !Expr.pseudos["empty"]( elem );
        },

        // Element/input types
        "header": function( elem ) {
                return rheader.test( elem.nodeName );
        },

        "input": function( elem ) {
                return rinputs.test( elem.nodeName );
        },

        "button": function( elem ) {
                var name = elem.nodeName.toLowerCase();
                return name === "input" && elem.type === "button" || name === "button";
        },

        "text": function( elem ) {
                var attr;
                return elem.nodeName.toLowerCase() === "input" &&
                        elem.type === "text" &&

                        // Support: IE<8
                        // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
                        ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
        },

        // Position-in-collection
        "first": createPositionalPseudo(function() {
                return [ 0 ];
        }),

        "last": createPositionalPseudo(function( matchIndexes, length ) {
                return [ length - 1 ];
        }),

        "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
                return [ argument < 0 ? argument + length : argument ];
        }),

        "even": createPositionalPseudo(function( matchIndexes, length ) {
                var i = 0;
                for ( ; i < length; i += 2 ) {
                        matchIndexes.push( i );
                }
                return matchIndexes;
        }),

        "odd": createPositionalPseudo(function( matchIndexes, length ) {
                var i = 1;
                for ( ; i < length; i += 2 ) {
                        matchIndexes.push( i );
                }
                return matchIndexes;
        }),

        "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                var i = argument < 0 ? argument + length : argument;
                for ( ; --i >= 0; ) {
                        matchIndexes.push( i );
                }
                return matchIndexes;
        }),

        "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
                var i = argument < 0 ? argument + length : argument;
                for ( ; ++i < length; ) {
                        matchIndexes.push( i );
                }
                return matchIndexes;
        })
}

};

Expr.pseudos = Expr.pseudos;

// Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {

Expr.pseudos[ i ] = createInputPseudo( i );

} for ( i in { submit: true, reset: true } ) {

Expr.pseudos[ i ] = createButtonPseudo( i );

}

// Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters();

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {

var matched, match, tokens, type,
        soFar, groups, preFilters,
        cached = tokenCache[ selector + " " ];

if ( cached ) {
        return parseOnly ? 0 : cached.slice( 0 );
}

soFar = selector;
groups = [];
preFilters = Expr.preFilter;

while ( soFar ) {

        // Comma and first run
        if ( !matched || (match = rcomma.exec( soFar )) ) {
                if ( match ) {
                        // Don't consume trailing commas as valid
                        soFar = soFar.slice( match[0].length ) || soFar;
                }
                groups.push( (tokens = []) );
        }

        matched = false;

        // Combinators
        if ( (match = rcombinators.exec( soFar )) ) {
                matched = match.shift();
                tokens.push({
                        value: matched,
                        // Cast descendant combinators to space
                        type: match[0].replace( rtrim, " " )
                });
                soFar = soFar.slice( matched.length );
        }

        // Filters
        for ( type in Expr.filter ) {
                if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
                        (match = preFilters[ type ]( match ))) ) {
                        matched = match.shift();
                        tokens.push({
                                value: matched,
                                type: type,
                                matches: match
                        });
                        soFar = soFar.slice( matched.length );
                }
        }

        if ( !matched ) {
                break;
        }
}

// Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
return parseOnly ?
        soFar.length :
        soFar ?
                Sizzle.error( selector ) :
                // Cache the tokens
                tokenCache( selector, groups ).slice( 0 );

};

function toSelector( tokens ) {

var i = 0,
        len = tokens.length,
        selector = "";
for ( ; i < len; i++ ) {
        selector += tokens[i].value;
}
return selector;

}

function addCombinator( matcher, combinator, base ) {

var dir = combinator.dir,
        checkNonElements = base && dir === "parentNode",
        doneName = done++;

return combinator.first ?
        // Check against closest ancestor/preceding element
        function( elem, context, xml ) {
                while ( (elem = elem[ dir ]) ) {
                        if ( elem.nodeType === 1 || checkNonElements ) {
                                return matcher( elem, context, xml );
                        }
                }
        } :

        // Check against all ancestor/preceding elements
        function( elem, context, xml ) {
                var oldCache, outerCache,
                        newCache = [ dirruns, doneName ];

                // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
                if ( xml ) {
                        while ( (elem = elem[ dir ]) ) {
                                if ( elem.nodeType === 1 || checkNonElements ) {
                                        if ( matcher( elem, context, xml ) ) {
                                                return true;
                                        }
                                }
                        }
                } else {
                        while ( (elem = elem[ dir ]) ) {
                                if ( elem.nodeType === 1 || checkNonElements ) {
                                        outerCache = elem[ expando ] || (elem[ expando ] = {});
                                        if ( (oldCache = outerCache[ dir ]) &&
                                                oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {

                                                // Assign to newCache so results back-propagate to previous elements
                                                return (newCache[ 2 ] = oldCache[ 2 ]);
                                        } else {
                                                // Reuse newcache so results back-propagate to previous elements
                                                outerCache[ dir ] = newCache;

                                                // A match means we're done; a fail means we have to keep checking
                                                if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
                                                        return true;
                                                }
                                        }
                                }
                        }
                }
        };

}

function elementMatcher( matchers ) {

return matchers.length > 1 ?
        function( elem, context, xml ) {
                var i = matchers.length;
                while ( i-- ) {
                        if ( !matchers[i]( elem, context, xml ) ) {
                                return false;
                        }
                }
                return true;
        } :
        matchers[0];

}

function multipleContexts( selector, contexts, results ) {

var i = 0,
        len = contexts.length;
for ( ; i < len; i++ ) {
        Sizzle( selector, contexts[i], results );
}
return results;

}

function condense( unmatched, map, filter, context, xml ) {

var elem,
        newUnmatched = [],
        i = 0,
        len = unmatched.length,
        mapped = map != null;

for ( ; i < len; i++ ) {
        if ( (elem = unmatched[i]) ) {
                if ( !filter || filter( elem, context, xml ) ) {
                        newUnmatched.push( elem );
                        if ( mapped ) {
                                map.push( i );
                        }
                }
        }
}

return newUnmatched;

}

function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {

if ( postFilter && !postFilter[ expando ] ) {
        postFilter = setMatcher( postFilter );
}
if ( postFinder && !postFinder[ expando ] ) {
        postFinder = setMatcher( postFinder, postSelector );
}
return markFunction(function( seed, results, context, xml ) {
        var temp, i, elem,
                preMap = [],
                postMap = [],
                preexisting = results.length,

                // Get initial elements from seed or context
                elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),

                // Prefilter to get matcher input, preserving a map for seed-results synchronization
                matcherIn = preFilter && ( seed || !selector ) ?
                        condense( elems, preMap, preFilter, context, xml ) :
                        elems,

                matcherOut = matcher ?
                        // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
                        postFinder || ( seed ? preFilter : preexisting || postFilter ) ?

                                // ...intermediate processing is necessary
                                [] :

                                // ...otherwise use results directly
                                results :
                        matcherIn;

        // Find primary matches
        if ( matcher ) {
                matcher( matcherIn, matcherOut, context, xml );
        }

        // Apply postFilter
        if ( postFilter ) {
                temp = condense( matcherOut, postMap );
                postFilter( temp, [], context, xml );

                // Un-match failing elements by moving them back to matcherIn
                i = temp.length;
                while ( i-- ) {
                        if ( (elem = temp[i]) ) {
                                matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
                        }
                }
        }

        if ( seed ) {
                if ( postFinder || preFilter ) {
                        if ( postFinder ) {
                                // Get the final matcherOut by condensing this intermediate into postFinder contexts
                                temp = [];
                                i = matcherOut.length;
                                while ( i-- ) {
                                        if ( (elem = matcherOut[i]) ) {
                                                // Restore matcherIn since elem is not yet a final match
                                                temp.push( (matcherIn[i] = elem) );
                                        }
                                }
                                postFinder( null, (matcherOut = []), temp, xml );
                        }

                        // Move matched elements from seed to results to keep them synchronized
                        i = matcherOut.length;
                        while ( i-- ) {
                                if ( (elem = matcherOut[i]) &&
                                        (temp = postFinder ? indexOf( 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;
                }

                // Add elements passing elementMatchers directly to results
                // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
                // Support: IE<9, Safari
                // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
                for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
                        if ( byElement && elem ) {
                                j = 0;
                                while ( (matcher = elementMatchers[j++]) ) {
                                        if ( matcher( elem, context, xml ) ) {
                                                results.push( elem );
                                                break;
                                        }
                                }
                                if ( outermost ) {
                                        dirruns = dirrunsUnique;
                                }
                        }

                        // Track unmatched elements for set filters
                        if ( bySet ) {
                                // They will have gone through all possible matchers
                                if ( (elem = !matcher && elem) ) {
                                        matchedCount--;
                                }

                                // Lengthen the array for every element, matched or not
                                if ( seed ) {
                                        unmatched.push( elem );
                                }
                        }
                }

                // Apply set filters to unmatched elements
                matchedCount += i;
                if ( bySet && i !== matchedCount ) {
                        j = 0;
                        while ( (matcher = setMatchers[j++]) ) {
                                matcher( unmatched, setMatched, context, xml );
                        }

                        if ( seed ) {
                                // Reintegrate element matches to eliminate the need for sorting
                                if ( matchedCount > 0 ) {
                                        while ( i-- ) {
                                                if ( !(unmatched[i] || setMatched[i]) ) {
                                                        setMatched[i] = pop.call( results );
                                                }
                                        }
                                }

                                // Discard index placeholder values to get only actual matches
                                setMatched = condense( setMatched );
                        }

                        // Add matches to results
                        push.apply( results, setMatched );

                        // Seedless set matches succeeding multiple successful matchers stipulate sorting
                        if ( outermost && !seed && setMatched.length > 0 &&
                                ( matchedCount + setMatchers.length ) > 1 ) {

                                Sizzle.uniqueSort( results );
                        }
                }

                // Override manipulation of globals by nested matchers
                if ( outermost ) {
                        dirruns = dirrunsUnique;
                        outermostContext = contextBackup;
                }

                return unmatched;
        };

return bySet ?
        markFunction( superMatcher ) :
        superMatcher;

}

compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {

var i,
        setMatchers = [],
        elementMatchers = [],
        cached = compilerCache[ selector + " " ];

if ( !cached ) {
        // Generate a function of recursive functions that can be used to check each element
        if ( !match ) {
                match = tokenize( selector );
        }
        i = match.length;
        while ( i-- ) {
                cached = matcherFromTokens( match[i] );
                if ( cached[ expando ] ) {
                        setMatchers.push( cached );
                } else {
                        elementMatchers.push( cached );
                }
        }

        // Cache the compiled function
        cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );

        // Save selector and tokenization
        cached.selector = selector;
}
return cached;

};

/**

* A low-level selection function that works with Sizzle's compiled
*  selector functions
* @param {String|Function} selector A selector or a pre-compiled
*  selector function built with Sizzle.compile
* @param {Element} context
* @param {Array} [results]
* @param {Array} [seed] A set of elements to match against
*/

select = Sizzle.select = function( selector, context, results, seed ) {

var i, tokens, token, type, find,
        compiled = typeof selector === "function" && selector,
        match = !seed && tokenize( (selector = compiled.selector || selector) );

results = results || [];

// Try to minimize operations if there is no seed and only one group
if ( match.length === 1 ) {

        // Take a shortcut and set the context if the root selector is an ID
        tokens = match[0] = match[0].slice( 0 );
        if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
                        support.getById && context.nodeType === 9 && documentIsHTML &&
                        Expr.relative[ tokens[1].type ] ) {

                context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
                if ( !context ) {
                        return results;

                // Precompiled matchers will still verify ancestry, so step up a level
                } else if ( compiled ) {
                        context = context.parentNode;
                }

                selector = selector.slice( tokens.shift().value.length );
        }

        // Fetch a seed set for right-to-left matching
        i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
        while ( i-- ) {
                token = tokens[i];

                // Abort if we hit a combinator
                if ( Expr.relative[ (type = token.type) ] ) {
                        break;
                }
                if ( (find = Expr.find[ type ]) ) {
                        // Search, expanding context for leading sibling combinators
                        if ( (seed = find(
                                token.matches[0].replace( runescape, funescape ),
                                rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
                        )) ) {

                                // If seed is empty or no tokens remain, we can return early
                                tokens.splice( i, 1 );
                                selector = seed.length && toSelector( tokens );
                                if ( !selector ) {
                                        push.apply( results, seed );
                                        return results;
                                }

                                break;
                        }
                }
        }
}

// Compile and execute a filtering function if one is not provided
// Provide `match` to avoid retokenization if we modified the selector above
( compiled || compile( selector, match ) )(
        seed,
        context,
        !documentIsHTML,
        results,
        rsibling.test( selector ) && testContext( context.parentNode ) || context
);
return results;

};

// One-time assignments

// Sort stability support.sortStable = expando.split(“”).sort( sortOrder ).join(“”) === expando;

// Support: Chrome 14-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( div1 ) {

// Should return 1, but returns 4 (following)
return div1.compareDocumentPosition( document.createElement("div") ) & 1;

});

// Support: IE<8 // Prevent attribute/property “interpolation” // msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert(function( div ) {

div.innerHTML = "<a href='#'></a>";
return div.firstChild.getAttribute("href") === "#" ;

}) ) {

addHandle( "type|href|height|width", function( elem, name, isXML ) {
        if ( !isXML ) {
                return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
        }
});

}

// Support: IE<9 // Use defaultValue in place of getAttribute(“value”) if ( !support.attributes || !assert(function( div ) {

div.innerHTML = "<input/>";
div.firstChild.setAttribute( "value", "" );
return div.firstChild.getAttribute( "value" ) === "";

}) ) {

addHandle( "value", function( elem, name, isXML ) {
        if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
                return elem.defaultValue;
        }
});

}

// Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert(function( div ) {

return div.getAttribute("disabled") == null;

}) ) {

addHandle( booleans, function( elem, name, isXML ) {
        var val;
        if ( !isXML ) {
                return elem[ name ] === true ? name.toLowerCase() :
                                (val = elem.getAttributeNode( name )) && val.specified ?
                                val.value :
                        null;
        }
});

}

// EXPOSE if ( typeof define === “function” && define.amd ) {

define(function() { return Sizzle; });

// Sizzle requires that there be a global window in Common-JS like environments } else if ( typeof module !== “undefined” && module.exports ) {

module.exports = Sizzle;

} else {

window.Sizzle = Sizzle;

} // EXPOSE

})( window );