diff -Nru falkon-3.0.0/autotests/autotests.h falkon-3.0.1/autotests/autotests.h --- falkon-3.0.0/autotests/autotests.h 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/autotests.h 2018-05-08 14:18:50.000000000 +0000 @@ -23,7 +23,7 @@ #define FALKONTEST_MAIN(Test) \ int main(int argc, char **argv) \ { \ - QzTools::removeDir(QDir::tempPath() + QSL("/Falkon-test")); \ + QzTools::removeRecursively(QDir::tempPath() + QSL("/Falkon-test")); \ MainApplication::setTestModeEnabled(true); \ MainApplication app(argc, argv); \ QTEST_DISABLE_KEYPAD_NAVIGATION; \ diff -Nru falkon-3.0.0/autotests/CMakeLists.txt falkon-3.0.1/autotests/CMakeLists.txt --- falkon-3.0.0/autotests/CMakeLists.txt 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/CMakeLists.txt 2018-05-08 14:18:50.000000000 +0000 @@ -31,6 +31,7 @@ ) set(falkon_autotests_SRCS passwordbackendtest.cpp) +include_directories(${OPENSSL_INCLUDE_DIR}) falkon_tests( databasepasswordbackendtest databaseencryptedpasswordbackendtest diff -Nru falkon-3.0.0/autotests/locationbartest.cpp falkon-3.0.1/autotests/locationbartest.cpp --- falkon-3.0.0/autotests/locationbartest.cpp 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/locationbartest.cpp 2018-05-08 14:18:50.000000000 +0000 @@ -214,4 +214,17 @@ QCOMPARE(action.type, LocationBar::LoadAction::Invalid); } +void LocationBarTest::loadAction_kdebug392445() +{ + // %20 in url will make it incorrectly treat as web search + + qzSettings->searchFromAddressBar = true; + + LocationBar::LoadAction action; + + action = LocationBar::loadAction("http://www.example.com/my%20beautiful%20page"); + QCOMPARE(action.type, LocationBar::LoadAction::Url); + QCOMPARE(action.loadRequest.url(), QUrl("http://www.example.com/my%20beautiful%20page")); +} + FALKONTEST_MAIN(LocationBarTest) diff -Nru falkon-3.0.0/autotests/locationbartest.h falkon-3.0.1/autotests/locationbartest.h --- falkon-3.0.0/autotests/locationbartest.h 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/locationbartest.h 2018-05-08 14:18:50.000000000 +0000 @@ -34,4 +34,5 @@ void loadAction_kdebug389491(); void loadActionSpecialSchemesTest(); void loadAction_issue2578(); + void loadAction_kdebug392445(); }; diff -Nru falkon-3.0.0/autotests/qztoolstest.cpp falkon-3.0.1/autotests/qztoolstest.cpp --- falkon-3.0.0/autotests/qztoolstest.cpp 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/qztoolstest.cpp 2018-05-08 14:18:50.000000000 +0000 @@ -271,6 +271,111 @@ } } +static void createTestDirectoryStructure(const QString &path) +{ + QDir().mkdir(path); + QDir dir(path); + dir.mkdir("dir1"); + dir.mkdir("dir2"); + dir.mkdir("dir3"); + dir.cd("dir1"); + dir.mkdir("dir1_1"); + dir.mkdir("dir1_2"); + dir.mkdir("dir1_3"); + dir.cdUp(); + dir.cd("dir3"); + dir.mkdir("dir3_1"); + QFile file(path + "/dir1/dir1_2/file1.txt"); + file.open(QFile::WriteOnly); + file.write("test"); + file.close(); +} + +void QzToolsTest::copyRecursivelyTest() +{ + const QString testDir = createPath("copyRecursivelyTest"); + createTestDirectoryStructure(testDir); + + QVERIFY(!QFileInfo(testDir + "-copy").exists()); + + // Copy to non-existant target + QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), true); + + QCOMPARE(QFileInfo(testDir + "-copy").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir1").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir2").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir3").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_1").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_2").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_3").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir3/dir3_1").isDir(), true); + QCOMPARE(QFileInfo(testDir + "-copy/dir1/dir1_2/file1.txt").isFile(), true); + + QFile file(testDir + "-copy/dir1/dir1_2/file1.txt"); + file.open(QFile::ReadOnly); + QCOMPARE(file.readAll(), QByteArray("test")); + file.close(); + + // Copy to target that already exists + QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), false); + + // Cleanup + QCOMPARE(QzTools::removeRecursively(testDir), true); + QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true); +} + +void QzToolsTest::removeRecursivelyTest() +{ + const QString testDir = createPath("removeRecursivelyTest"); + createTestDirectoryStructure(testDir); + + QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy"), true); + QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true); + QCOMPARE(QFileInfo(testDir + "-copy").exists(), false); + + // Remove non-existant path returns success + QCOMPARE(QzTools::removeRecursively(testDir + "-copy"), true); + + QCOMPARE(QzTools::copyRecursively(testDir, testDir + "-copy2"), true); + + QFile dir(testDir + "-copy2"); + dir.setPermissions(dir.permissions() & ~(QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther)); + + QCOMPARE(QzTools::removeRecursively(testDir + "-copy2"), false); + + dir.setPermissions(dir.permissions() | QFile::WriteOwner); + + QCOMPARE(QzTools::removeRecursively(testDir + "-copy2"), true); + + // Cleanup + QCOMPARE(QzTools::removeRecursively(testDir), true); +} + +void QzToolsTest::dontFollowSymlinksTest() +{ + const QString testDir = createPath("removeRecursivelyTest"); + createTestDirectoryStructure(testDir); + + QDir().mkpath(testDir + "/subdir"); + QFile::link(testDir, testDir + "/subdir/link"); + + QVERIFY(QzTools::removeRecursively(testDir + "/subdir")); + + QVERIFY(!QFile::exists(testDir + "/subdir")); + QVERIFY(QFile::exists(testDir)); + + QDir().mkpath(testDir + "/subdir/normalfolder"); + QFile::link("..", testDir + "/subdir/link"); + + QVERIFY(QzTools::copyRecursively(testDir + "/subdir", testDir + "/subdir2")); + + QCOMPARE(QFile::exists(testDir + "/subdir2/link"), true); + QCOMPARE(QFile::exists(testDir + "/subdir2/normalfolder"), true); + + // Cleanup + QCOMPARE(QzTools::removeRecursively(testDir), true); +} + QString QzToolsTest::createPath(const char *file) const { return m_tmpPath + QL1S("/") + file; diff -Nru falkon-3.0.0/autotests/qztoolstest.h falkon-3.0.1/autotests/qztoolstest.h --- falkon-3.0.0/autotests/qztoolstest.h 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/qztoolstest.h 2018-05-08 14:18:50.000000000 +0000 @@ -41,6 +41,9 @@ void escapeSqlGlobString(); void ensureUniqueFilename(); + void copyRecursivelyTest(); + void removeRecursivelyTest(); + void dontFollowSymlinksTest(); private: QString createPath(const char *file) const; diff -Nru falkon-3.0.0/autotests/webviewtest.cpp falkon-3.0.1/autotests/webviewtest.cpp --- falkon-3.0.0/autotests/webviewtest.cpp 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/autotests/webviewtest.cpp 2018-05-08 14:18:50.000000000 +0000 @@ -82,7 +82,7 @@ view.setPage(page2); // WebPage: Workaround for broken load started/finished signals in QtWebEngine 5.10 - const int loadFinishedEmitCount = qstrncmp(qVersion(), "5.10.", 5) == 0 ? 2 : 1; + const int loadFinishedEmitCount = qstrncmp(qVersion(), "5.11.", 5) == 0 ? 1 : 2; QTRY_COMPARE(loadFinishedSpy.count(), loadFinishedEmitCount); QCOMPARE(loadStartedSpy.count(), 0); diff -Nru falkon-3.0.0/CHANGELOG falkon-3.0.1/CHANGELOG --- falkon-3.0.0/CHANGELOG 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/CHANGELOG 2018-05-08 14:18:50.000000000 +0000 @@ -1,3 +1,21 @@ +Version 3.0.1 + * released 8 May 2018 + * added profile migration from QupZilla + * fix incorrectly completing form data on some sites (BUG 391327) + * fix showing incorrect state of back and forward buttons (BUG 391331) + * fix loading urls containing %20 from location bar (BUG 392445) + * fix save page action for downloading text files (BUG 391300) + * fix download manager trying to closing not restored tabs (BUG 392565) + * fix updating location bar site icon after using paste and go action (BUG 392747) + * fix various issues with QtWebEngine 5.11 (BUG 392885, 393398) + * fix speed dial sometimes loading with no pages (BUG 391875) + * fix leaving html fullscreen after closing tab (BUG 393797) + * fix saving speed dial settings when there are no configured pages + * fix restoring nested crashed sessions + * fix setting minimum height of bookmarks toolbar + * VerticalTabs: fix preserving expanded state of times inside collapsed parent (BUG 393567) + * VerticalTabs: don't force open sidebar when opening new window (BUG 393629) + Version 3.0.0 * released 27 February 2018 * first Falkon release diff -Nru falkon-3.0.0/cmake/build-po-files.cmake falkon-3.0.1/cmake/build-po-files.cmake --- falkon-3.0.0/cmake/build-po-files.cmake 2018-02-27 13:56:58.000000000 +0000 +++ falkon-3.0.1/cmake/build-po-files.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -# Copyright (c) 2017 Aleix Pol Gonzalez -# Copyright (c) 2017 Harald Sitter -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. - -file(GLOB_RECURSE pofiles RELATIVE "${PO_DIR}" "${PO_DIR}/**.po") - -foreach(pofile IN LISTS pofiles) - if (NOT pofile MATCHES "_qt.po") - get_filename_component(name ${pofile} NAME_WE) - get_filename_component(langdir ${pofile} DIRECTORY) - set(dest ${COPY_TO}/${langdir}/LC_MESSAGES) - file(MAKE_DIRECTORY ${dest}) - - message(STATUS "building... ${pofile} to ${name}.mo" ) - execute_process( - COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${dest}/${name}.mo ${PO_DIR}/${pofile} - RESULT_VARIABLE code - ) - if(code) - message(FATAL_ERROR "failed at generating ${name}.mo") - endif() - endif() -endforeach() diff -Nru falkon-3.0.0/CMakeLists.txt falkon-3.0.1/CMakeLists.txt --- falkon-3.0.0/CMakeLists.txt 2018-02-27 13:57:27.000000000 +0000 +++ falkon-3.0.1/CMakeLists.txt 2018-05-08 14:19:16.000000000 +0000 @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1) # Project name and version -project(Falkon VERSION 3.0.0) +project(Falkon VERSION 3.0.1) # Find ECM, with nice error handling in case of failure include(FeatureSummary) @@ -36,7 +36,9 @@ else() set(PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${FALKON_INSTALL_PLUGINDIR}") endif() -set(FALKON_PLUGIN_PATH "${PLUGIN_PATH}" CACHE PATH "Default plugin search path") +if (NOT WIN32) + set(FALKON_PLUGIN_PATH "${PLUGIN_PATH}" CACHE PATH "Default plugin search path") +endif() # Defines that are always set add_definitions(-DQT_NO_URL_CAST_FROM_STRING -DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_TO_ASCII) @@ -53,7 +55,7 @@ if (UNIX AND NOT APPLE AND NOT NO_X11) add_definitions(-DQZ_WS_X11) - find_package(XCB COMPONENTS XCB) + find_package(XCB REQUIRED COMPONENTS XCB UTIL) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS X11Extras) endif() if (WIN32) @@ -83,6 +85,14 @@ add_definitions(-D_WIN32_WINNT=${ver}) endif() +# Mandatory: OpenSSL +find_package(OpenSSL REQUIRED) + +# KF5I18n: Mandatory with downloaded translations (only for ki18n_install) +if (EXISTS "${CMAKE_SOURCE_DIR}/po") + find_package(KF5I18n REQUIRED) +endif() + # Optional: GnomeKeyring find_package(PkgConfig) if (PKG_CONFIG_FOUND) @@ -101,9 +111,9 @@ find_package(PySide2 "2.0.0") find_package(Shiboken2 "2.0.0") find_package(PythonLibs "3.0") -set_package_properties(PySide2 PROPERTIES DESCRIPTION "Python plugins" TYPE OPTIONAL) -set_package_properties(Shiboken2 PROPERTIES DESCRIPTION "Python plugins" TYPE OPTIONAL) -set_package_properties(PythonLibs PROPERTIES DESCRIPTION "Python plugins" TYPE OPTIONAL) +set_package_properties(PySide2 PROPERTIES DESCRIPTION "Python plugins (experimental)" TYPE OPTIONAL) +set_package_properties(Shiboken2 PROPERTIES DESCRIPTION "Python plugins (experimental)" TYPE OPTIONAL) +set_package_properties(PythonLibs PROPERTIES DESCRIPTION "Python plugins (experimental)" TYPE OPTIONAL) if (PySide2_FOUND AND Shiboken2_FOUND AND PythonLibs_FOUND) set(ENABLE_PYTHON_PLUGINS TRUE) endif() @@ -160,6 +170,9 @@ add_subdirectory(tests/benchmarks) endif() +# Tell releaseme that po is already taken care of +# SKIP_PO_INSTALL + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) -ecm_install_po_files_as_qm(po) +ecm_install_po_files_as_qm(poqm) diff -Nru falkon-3.0.0/debian/changelog falkon-3.0.1/debian/changelog --- falkon-3.0.0/debian/changelog 2018-03-17 01:10:24.000000000 +0000 +++ falkon-3.0.1/debian/changelog 2018-05-29 22:27:49.000000000 +0000 @@ -1,3 +1,13 @@ +falkon (3.0.1-0ubuntu0.1) bionic; urgency=medium + + * New upstream bugfix release (LP: #1770318). + * Update the watch file for the new upstream location. + * Remove reverse-applicable add-source-minified-js.patch. + * Remove unneeded install file. + * Add build dependency on libkf5i18n-dev for translations. + + -- Simon Quigley Tue, 29 May 2018 17:27:49 -0500 + falkon (3.0.0-0ubuntu3) bionic; urgency=medium * Make the Conflicts/Replaces on falkon versioned. diff -Nru falkon-3.0.0/debian/control falkon-3.0.1/debian/control --- falkon-3.0.0/debian/control 2018-03-17 01:07:42.000000000 +0000 +++ falkon-3.0.1/debian/control 2018-05-29 22:19:38.000000000 +0000 @@ -8,6 +8,7 @@ extra-cmake-modules (>= 5.27.0), libjs-jquery, libjs-jquery-ui, + libkf5i18n-dev, libkf5wallet-dev, libqt5x11extras5-dev, libssl-dev, diff -Nru falkon-3.0.0/debian/falkon.install falkon-3.0.1/debian/falkon.install --- falkon-3.0.0/debian/falkon.install 2018-03-17 01:07:03.000000000 +0000 +++ falkon-3.0.1/debian/falkon.install 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/ diff -Nru falkon-3.0.0/debian/patches/add-source-minified-js.patch falkon-3.0.1/debian/patches/add-source-minified-js.patch --- falkon-3.0.0/debian/patches/add-source-minified-js.patch 2018-03-17 01:07:03.000000000 +0000 +++ falkon-3.0.1/debian/patches/add-source-minified-js.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29742 +0,0 @@ -From fb88da17d6de1c2efa5f23e2393b9ea13d661597 Mon Sep 17 00:00:00 2001 -From: Jonathan Riddell -Date: Wed, 28 Feb 2018 14:59:33 +0000 -Subject: add source alongside minified javascript for freedom - ---- - src/lib/data/html/jquery-1.12.4.js | 11008 +++++++++++++++++++ - src/lib/data/html/jquery-ui-1.12.1.js | 18706 ++++++++++++++++++++++++++++++++ - 2 files changed, 29714 insertions(+) - create mode 100644 src/lib/data/html/jquery-1.12.4.js - create mode 100644 src/lib/data/html/jquery-ui-1.12.1.js - -diff --git a/src/lib/data/html/jquery-1.12.4.js b/src/lib/data/html/jquery-1.12.4.js -new file mode 100644 -index 0000000..7fc60fc ---- /dev/null -+++ b/src/lib/data/html/jquery-1.12.4.js -@@ -0,0 +1,11008 @@ -+/*! -+ * jQuery JavaScript Library v1.12.4 -+ * http://jquery.com/ -+ * -+ * Includes Sizzle.js -+ * http://sizzlejs.com/ -+ * -+ * Copyright jQuery Foundation and other contributors -+ * Released under the MIT license -+ * http://jquery.org/license -+ * -+ * Date: 2016-05-20T17:17Z -+ */ -+ -+(function( global, factory ) { -+ -+ if ( typeof module === "object" && typeof module.exports === "object" ) { -+ // For CommonJS and CommonJS-like environments where a proper `window` -+ // is present, execute the factory and get jQuery. -+ // For environments that do not 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 ) { -+ -+// Support: Firefox 18+ -+// Can't be in strict mode, several libs including ASP.NET trace -+// the stack via arguments.caller.callee and Firefox dies if -+// you try to trace through "use strict" call chains. (#13335) -+//"use strict"; -+var deletedIds = []; -+ -+var document = window.document; -+ -+var slice = deletedIds.slice; -+ -+var concat = deletedIds.concat; -+ -+var push = deletedIds.push; -+ -+var indexOf = deletedIds.indexOf; -+ -+var class2type = {}; -+ -+var toString = class2type.toString; -+ -+var hasOwn = class2type.hasOwnProperty; -+ -+var support = {}; -+ -+ -+ -+var -+ version = "1.12.4", -+ -+ // Define a local copy of jQuery -+ jQuery = function( selector, context ) { -+ -+ // The jQuery object is actually just the init constructor 'enhanced' -+ // Need init if jQuery is called (just allow error to be thrown if not included) -+ return new jQuery.fn.init( selector, context ); -+ }, -+ -+ // Support: Android<4.1, IE<9 -+ // Make sure we trim BOM and NBSP -+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, -+ -+ // Matches dashed string for camelizing -+ rmsPrefix = /^-ms-/, -+ rdashAlpha = /-([\da-z])/gi, -+ -+ // Used by jQuery.camelCase as callback to replace() -+ fcamelCase = function( all, letter ) { -+ return letter.toUpperCase(); -+ }; -+ -+jQuery.fn = jQuery.prototype = { -+ -+ // The current version of jQuery being used -+ jquery: version, -+ -+ constructor: jQuery, -+ -+ // Start with an empty selector -+ selector: "", -+ -+ // The default length of a jQuery object is 0 -+ length: 0, -+ -+ toArray: function() { -+ return slice.call( this ); -+ }, -+ -+ // Get the Nth element in the matched element set OR -+ // Get the whole matched element set as a clean array -+ get: function( num ) { -+ return num != null ? -+ -+ // Return just the one element from the set -+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) : -+ -+ // Return all the elements in a clean array -+ slice.call( this ); -+ }, -+ -+ // Take an array of elements and push it onto the stack -+ // (returning the new matched element set) -+ pushStack: function( elems ) { -+ -+ // Build a new jQuery matched element set -+ var ret = jQuery.merge( this.constructor(), elems ); -+ -+ // Add the old object onto the stack (as a reference) -+ ret.prevObject = this; -+ ret.context = this.context; -+ -+ // Return the newly-formed element set -+ return ret; -+ }, -+ -+ // Execute a callback for every element in the matched set. -+ 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: deletedIds.sort, -+ splice: deletedIds.splice -+}; -+ -+jQuery.extend = jQuery.fn.extend = function() { -+ var src, copyIsArray, copy, name, options, clone, -+ target = arguments[ 0 ] || {}, -+ i = 1, -+ length = arguments.length, -+ deep = false; -+ -+ // Handle a deep copy situation -+ if ( typeof target === "boolean" ) { -+ deep = target; -+ -+ // skip the boolean and the target -+ target = arguments[ i ] || {}; -+ i++; -+ } -+ -+ // Handle case when target is a string or something (possible in deep copy) -+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { -+ target = {}; -+ } -+ -+ // extend jQuery itself if only one argument is passed -+ if ( i === length ) { -+ target = this; -+ i--; -+ } -+ -+ for ( ; i < length; i++ ) { -+ -+ // Only deal with non-null/undefined values -+ if ( ( options = arguments[ i ] ) != null ) { -+ -+ // Extend the base object -+ for ( name in options ) { -+ src = target[ name ]; -+ copy = options[ name ]; -+ -+ // Prevent never-ending loop -+ if ( target === copy ) { -+ continue; -+ } -+ -+ // Recurse if we're merging plain objects or arrays -+ if ( deep && copy && ( jQuery.isPlainObject( copy ) || -+ ( copyIsArray = jQuery.isArray( copy ) ) ) ) { -+ -+ if ( copyIsArray ) { -+ copyIsArray = false; -+ clone = src && jQuery.isArray( src ) ? src : []; -+ -+ } else { -+ clone = src && jQuery.isPlainObject( src ) ? src : {}; -+ } -+ -+ // Never move original objects, clone them -+ target[ name ] = jQuery.extend( deep, clone, copy ); -+ -+ // Don't bring in undefined values -+ } else if ( copy !== undefined ) { -+ target[ name ] = copy; -+ } -+ } -+ } -+ } -+ -+ // Return the modified object -+ return target; -+}; -+ -+jQuery.extend( { -+ -+ // Unique for each copy of jQuery on the page -+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), -+ -+ // Assume jQuery is ready without the ready module -+ isReady: true, -+ -+ error: function( msg ) { -+ throw new Error( msg ); -+ }, -+ -+ noop: function() {}, -+ -+ // See test/unit/core.js for details concerning isFunction. -+ // Since version 1.3, DOM methods and functions like alert -+ // aren't supported. They return false on IE (#2968). -+ isFunction: function( obj ) { -+ return jQuery.type( obj ) === "function"; -+ }, -+ -+ isArray: Array.isArray || function( obj ) { -+ return jQuery.type( obj ) === "array"; -+ }, -+ -+ isWindow: function( obj ) { -+ /* jshint eqeqeq: false */ -+ return obj != null && obj == obj.window; -+ }, -+ -+ isNumeric: function( obj ) { -+ -+ // parseFloat NaNs numeric-cast false positives (null|true|false|"") -+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...") -+ // subtraction forces infinities to NaN -+ // adding 1 corrects loss of precision from parseFloat (#15100) -+ var realStringObj = obj && obj.toString(); -+ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; -+ }, -+ -+ isEmptyObject: function( obj ) { -+ var name; -+ for ( name in obj ) { -+ return false; -+ } -+ return true; -+ }, -+ -+ isPlainObject: function( obj ) { -+ var key; -+ -+ // Must be an Object. -+ // Because of IE, we also have to check the presence of the constructor property. -+ // Make sure that DOM nodes and window objects don't pass through, as well -+ if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { -+ return false; -+ } -+ -+ try { -+ -+ // Not own constructor property must be Object -+ if ( obj.constructor && -+ !hasOwn.call( obj, "constructor" ) && -+ !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { -+ return false; -+ } -+ } catch ( e ) { -+ -+ // IE8,9 Will throw exceptions on certain host objects #9897 -+ return false; -+ } -+ -+ // Support: IE<9 -+ // Handle iteration over inherited properties before own properties. -+ if ( !support.ownFirst ) { -+ for ( key in obj ) { -+ return hasOwn.call( obj, key ); -+ } -+ } -+ -+ // Own properties are enumerated firstly, so to speed up, -+ // if last one is own, then all properties are own. -+ for ( key in obj ) {} -+ -+ return key === undefined || hasOwn.call( obj, key ); -+ }, -+ -+ type: function( obj ) { -+ if ( obj == null ) { -+ return obj + ""; -+ } -+ return typeof obj === "object" || typeof obj === "function" ? -+ class2type[ toString.call( obj ) ] || "object" : -+ typeof obj; -+ }, -+ -+ // Workarounds based on findings by Jim Driscoll -+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context -+ globalEval: function( data ) { -+ if ( data && jQuery.trim( data ) ) { -+ -+ // We use execScript on Internet Explorer -+ // We use an anonymous function so that context is window -+ // rather than jQuery in Firefox -+ ( window.execScript || function( data ) { -+ window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation -+ } )( data ); -+ } -+ }, -+ -+ // Convert dashed to camelCase; used by the css and data modules -+ // Microsoft forgot to hump their vendor prefix (#9572) -+ camelCase: function( string ) { -+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -+ }, -+ -+ nodeName: function( elem, name ) { -+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); -+ }, -+ -+ 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.1, IE<9 -+ trim: function( text ) { -+ return text == null ? -+ "" : -+ ( text + "" ).replace( rtrim, "" ); -+ }, -+ -+ // results is for internal usage only -+ makeArray: function( arr, results ) { -+ var ret = results || []; -+ -+ if ( arr != null ) { -+ if ( isArrayLike( Object( arr ) ) ) { -+ jQuery.merge( ret, -+ typeof arr === "string" ? -+ [ arr ] : arr -+ ); -+ } else { -+ push.call( ret, arr ); -+ } -+ } -+ -+ return ret; -+ }, -+ -+ inArray: function( elem, arr, i ) { -+ var len; -+ -+ if ( arr ) { -+ if ( indexOf ) { -+ return indexOf.call( arr, elem, i ); -+ } -+ -+ len = arr.length; -+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; -+ -+ for ( ; i < len; i++ ) { -+ -+ // Skip accessing in sparse arrays -+ if ( i in arr && arr[ i ] === elem ) { -+ return i; -+ } -+ } -+ } -+ -+ return -1; -+ }, -+ -+ merge: function( first, second ) { -+ var len = +second.length, -+ j = 0, -+ i = first.length; -+ -+ while ( j < len ) { -+ first[ i++ ] = second[ j++ ]; -+ } -+ -+ // Support: IE<9 -+ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) -+ if ( len !== len ) { -+ while ( second[ j ] !== undefined ) { -+ first[ i++ ] = second[ j++ ]; -+ } -+ } -+ -+ first.length = i; -+ -+ return first; -+ }, -+ -+ grep: function( elems, callback, invert ) { -+ var callbackInverse, -+ matches = [], -+ i = 0, -+ length = elems.length, -+ callbackExpect = !invert; -+ -+ // Go through the array, only saving the items -+ // that pass the validator function -+ for ( ; i < length; i++ ) { -+ callbackInverse = !callback( elems[ i ], i ); -+ if ( callbackInverse !== callbackExpect ) { -+ matches.push( elems[ i ] ); -+ } -+ } -+ -+ return matches; -+ }, -+ -+ // arg is for internal usage only -+ map: function( elems, callback, arg ) { -+ var 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 args, proxy, tmp; -+ -+ if ( typeof context === "string" ) { -+ tmp = fn[ context ]; -+ context = fn; -+ fn = tmp; -+ } -+ -+ // Quick check to determine if target is callable, in the spec -+ // this throws a TypeError, but we will just return undefined. -+ if ( !jQuery.isFunction( fn ) ) { -+ return undefined; -+ } -+ -+ // Simulated bind -+ args = slice.call( arguments, 2 ); -+ proxy = function() { -+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); -+ }; -+ -+ // Set the guid of unique handler to the same of original handler, so it can be removed -+ proxy.guid = fn.guid = fn.guid || jQuery.guid++; -+ -+ return proxy; -+ }, -+ -+ now: function() { -+ return +( new Date() ); -+ }, -+ -+ // jQuery.support is not used in Core but other projects attach their -+ // properties to it so it needs to exist. -+ support: support -+} ); -+ -+// JSHint would error on this code due to the Symbol not being defined in ES5. -+// Defining this global in .jshintrc would create a danger of using the global -+// unguarded in another place, it seems safer to just disable JSHint for these -+// three lines. -+/* jshint ignore: start */ -+if ( typeof Symbol === "function" ) { -+ jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; -+} -+/* jshint ignore: end */ -+ -+// 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: iOS 8.2 (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.2.1 -+ * http://sizzlejs.com/ -+ * -+ * Copyright jQuery Foundation and other contributors -+ * Released under the MIT license -+ * http://jquery.org/license -+ * -+ * Date: 2015-10-17 -+ */ -+(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 -+ -+ // 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-]|[^\\x00-\\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 = /[+~]/, -+ 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 m, i, elem, nid, nidselect, 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( rescape, "\\$&" ); -+ } else { -+ context.setAttribute( "id", (nid = expando) ); -+ } -+ -+ // Prefix every selector in the list -+ groups = tokenize( selector ); -+ i = groups.length; -+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; -+ while ( i-- ) { -+ groups[i] = nidselect + " " + 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 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 = 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 && -+ ( ~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; -+ -+ // 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 ( (parent = document.defaultView) && parent.top !== parent ) { -+ // Support: IE 11 -+ if ( parent.addEventListener ) { -+ parent.addEventListener( "unload", unloadHandler, false ); -+ -+ // Support: IE 9 - 10 only -+ } else if ( parent.attachEvent ) { -+ parent.attachEvent( "onunload", unloadHandler ); -+ } -+ } -+ -+ /* 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( document.createComment("") ); -+ return !div.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 programatically-set names, -+ // so use a roundabout getElementsByName test -+ support.getById = assert(function( div ) { -+ docElem.appendChild( div ).id = expando; -+ return !document.getElementsByName || !document.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 ); -+ return m ? [ 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 ( 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 http://bugs.jquery.com/ticket/13378 -+ rbuggyQSA = []; -+ -+ if ( (support.qsa = rnative.test( document.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 = "" + -+ ""; -+ -+ // 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.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ -+ 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 = document.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 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.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": function( elem ) { -+ return elem.disabled === false; -+ }, -+ -+ "disabled": function( elem ) { -+ return elem.disabled === true; -+ }, -+ -+ "checked": function( elem ) { -+ // In CSS3, :checked should return both checked and selected elements -+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked -+ var nodeName = elem.nodeName.toLowerCase(); -+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); -+ }, -+ -+ "selected": function( elem ) { -+ // Accessing this property makes selected-by-default -+ // options in Safari work properly -+ if ( elem.parentNode ) { -+ elem.parentNode.selectedIndex; -+ } -+ -+ return elem.selected === true; -+ }, -+ -+ // Contents -+ "empty": function( elem ) { -+ // http://www.w3.org/TR/selectors/#empty-pseudo -+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), -+ // but not by others (comment: 8; processing instruction: 7; etc.) -+ // nodeType < 6 works because attributes (2) do not appear as children -+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { -+ if ( elem.nodeType < 6 ) { -+ return false; -+ } -+ } -+ return true; -+ }, -+ -+ "parent": function( elem ) { -+ return !Expr.pseudos["empty"]( elem ); -+ }, -+ -+ // Element/input types -+ "header": function( elem ) { -+ return rheader.test( elem.nodeName ); -+ }, -+ -+ "input": function( elem ) { -+ return rinputs.test( elem.nodeName ); -+ }, -+ -+ "button": function( elem ) { -+ var name = elem.nodeName.toLowerCase(); -+ return name === "input" && elem.type === "button" || name === "button"; -+ }, -+ -+ "text": function( elem ) { -+ var attr; -+ return elem.nodeName.toLowerCase() === "input" && -+ elem.type === "text" && -+ -+ // Support: IE<8 -+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" -+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); -+ }, -+ -+ // Position-in-collection -+ "first": createPositionalPseudo(function() { -+ return [ 0 ]; -+ }), -+ -+ "last": createPositionalPseudo(function( matchIndexes, length ) { -+ return [ length - 1 ]; -+ }), -+ -+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { -+ return [ argument < 0 ? argument + length : argument ]; -+ }), -+ -+ "even": createPositionalPseudo(function( matchIndexes, length ) { -+ var i = 0; -+ for ( ; i < length; i += 2 ) { -+ matchIndexes.push( i ); -+ } -+ return matchIndexes; -+ }), -+ -+ "odd": createPositionalPseudo(function( matchIndexes, length ) { -+ var i = 1; -+ for ( ; i < length; i += 2 ) { -+ matchIndexes.push( i ); -+ } -+ return matchIndexes; -+ }), -+ -+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { -+ var i = argument < 0 ? argument + length : argument; -+ for ( ; --i >= 0; ) { -+ matchIndexes.push( i ); -+ } -+ return matchIndexes; -+ }), -+ -+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { -+ var i = argument < 0 ? argument + length : argument; -+ for ( ; ++i < length; ) { -+ matchIndexes.push( i ); -+ } -+ return matchIndexes; -+ }) -+ } -+}; -+ -+Expr.pseudos["nth"] = Expr.pseudos["eq"]; -+ -+// Add button/input type pseudos -+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { -+ Expr.pseudos[ i ] = createInputPseudo( i ); -+} -+for ( i in { submit: true, reset: true } ) { -+ Expr.pseudos[ i ] = createButtonPseudo( i ); -+} -+ -+// Easy API for creating new setFilters -+function setFilters() {} -+setFilters.prototype = Expr.filters = Expr.pseudos; -+Expr.setFilters = new setFilters(); -+ -+tokenize = Sizzle.tokenize = function( selector, parseOnly ) { -+ var matched, match, tokens, type, -+ soFar, groups, preFilters, -+ cached = tokenCache[ selector + " " ]; -+ -+ if ( cached ) { -+ return parseOnly ? 0 : cached.slice( 0 ); -+ } -+ -+ soFar = selector; -+ groups = []; -+ preFilters = Expr.preFilter; -+ -+ while ( soFar ) { -+ -+ // Comma and first run -+ if ( !matched || (match = rcomma.exec( soFar )) ) { -+ if ( match ) { -+ // Don't consume trailing commas as valid -+ soFar = soFar.slice( match[0].length ) || soFar; -+ } -+ groups.push( (tokens = []) ); -+ } -+ -+ matched = false; -+ -+ // Combinators -+ if ( (match = rcombinators.exec( soFar )) ) { -+ matched = match.shift(); -+ tokens.push({ -+ value: matched, -+ // Cast descendant combinators to space -+ type: match[0].replace( rtrim, " " ) -+ }); -+ soFar = soFar.slice( matched.length ); -+ } -+ -+ // Filters -+ for ( type in Expr.filter ) { -+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || -+ (match = preFilters[ type ]( match ))) ) { -+ matched = match.shift(); -+ tokens.push({ -+ value: matched, -+ type: type, -+ matches: match -+ }); -+ soFar = soFar.slice( matched.length ); -+ } -+ } -+ -+ if ( !matched ) { -+ break; -+ } -+ } -+ -+ // Return the length of the invalid excess -+ // if we're just parsing -+ // Otherwise, throw an error or return tokens -+ return parseOnly ? -+ soFar.length : -+ soFar ? -+ Sizzle.error( selector ) : -+ // Cache the tokens -+ tokenCache( selector, groups ).slice( 0 ); -+}; -+ -+function toSelector( tokens ) { -+ var i = 0, -+ len = tokens.length, -+ selector = ""; -+ for ( ; i < len; i++ ) { -+ selector += tokens[i].value; -+ } -+ return selector; -+} -+ -+function addCombinator( matcher, combinator, base ) { -+ var dir = combinator.dir, -+ checkNonElements = base && dir === "parentNode", -+ doneName = done++; -+ -+ return combinator.first ? -+ // Check against closest ancestor/preceding element -+ function( elem, context, xml ) { -+ while ( (elem = elem[ dir ]) ) { -+ if ( elem.nodeType === 1 || checkNonElements ) { -+ return matcher( elem, context, xml ); -+ } -+ } -+ } : -+ -+ // Check against all ancestor/preceding elements -+ function( elem, context, xml ) { -+ var oldCache, 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 ( (oldCache = uniqueCache[ 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 -+ uniqueCache[ 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 || 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" && -+ 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, -+ !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( div1 ) { -+ // Should return 1, but returns 4 (following) -+ return div1.compareDocumentPosition( document.createElement("div") ) & 1; -+}); -+ -+// Support: IE<8 -+// Prevent attribute/property "interpolation" -+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -+if ( !assert(function( div ) { -+ div.innerHTML = ""; -+ 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 = ""; -+ div.firstChild.setAttribute( "value", "" ); -+ return div.firstChild.getAttribute( "value" ) === ""; -+}) ) { -+ addHandle( "value", function( elem, name, isXML ) { -+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { -+ return elem.defaultValue; -+ } -+ }); -+} -+ -+// Support: IE<9 -+// Use getAttributeNode to fetch booleans when getAttribute lies -+if ( !assert(function( div ) { -+ return div.getAttribute("disabled") == null; -+}) ) { -+ addHandle( booleans, function( elem, name, isXML ) { -+ var val; -+ if ( !isXML ) { -+ return elem[ name ] === true ? name.toLowerCase() : -+ (val = elem.getAttributeNode( name )) && val.specified ? -+ val.value : -+ null; -+ } -+ }); -+} -+ -+return Sizzle; -+ -+})( window ); -+ -+ -+ -+jQuery.find = Sizzle; -+jQuery.expr = Sizzle.selectors; -+jQuery.expr[ ":" ] = jQuery.expr.pseudos; -+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -+jQuery.text = Sizzle.getText; -+jQuery.isXMLDoc = Sizzle.isXML; -+jQuery.contains = Sizzle.contains; -+ -+ -+ -+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; -+ -+var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); -+ -+ -+ -+var risSimple = /^.[^:#\[\.,]*$/; -+ -+// Implement the identical functionality for filter and not -+function winnow( elements, qualifier, not ) { -+ if ( jQuery.isFunction( qualifier ) ) { -+ return jQuery.grep( elements, function( elem, i ) { -+ /* jshint -W018 */ -+ return !!qualifier.call( elem, i, elem ) !== not; -+ } ); -+ -+ } -+ -+ if ( qualifier.nodeType ) { -+ return jQuery.grep( elements, function( elem ) { -+ return ( elem === qualifier ) !== not; -+ } ); -+ -+ } -+ -+ if ( typeof qualifier === "string" ) { -+ if ( risSimple.test( qualifier ) ) { -+ return jQuery.filter( qualifier, elements, not ); -+ } -+ -+ qualifier = jQuery.filter( qualifier, elements ); -+ } -+ -+ return jQuery.grep( elements, function( elem ) { -+ return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; -+ } ); -+} -+ -+jQuery.filter = function( expr, elems, not ) { -+ var elem = elems[ 0 ]; -+ -+ if ( not ) { -+ expr = ":not(" + expr + ")"; -+ } -+ -+ return elems.length === 1 && elem.nodeType === 1 ? -+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : -+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { -+ return elem.nodeType === 1; -+ } ) ); -+}; -+ -+jQuery.fn.extend( { -+ find: function( selector ) { -+ var i, -+ ret = [], -+ self = this, -+ len = self.length; -+ -+ if ( typeof selector !== "string" ) { -+ return this.pushStack( jQuery( selector ).filter( function() { -+ for ( i = 0; i < len; i++ ) { -+ if ( jQuery.contains( self[ i ], this ) ) { -+ return true; -+ } -+ } -+ } ) ); -+ } -+ -+ for ( i = 0; i < len; i++ ) { -+ jQuery.find( selector, self[ i ], ret ); -+ } -+ -+ // Needed because $( selector, context ) becomes $( context ).find( selector ) -+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); -+ ret.selector = this.selector ? this.selector + " " + selector : selector; -+ return ret; -+ }, -+ filter: function( selector ) { -+ return this.pushStack( winnow( this, selector || [], false ) ); -+ }, -+ not: function( selector ) { -+ return this.pushStack( winnow( this, selector || [], true ) ); -+ }, -+ is: function( selector ) { -+ return !!winnow( -+ this, -+ -+ // If this is a positional/relative selector, check membership in the returned set -+ // so $("p:first").is("p:last") won't return true for a doc with two "p". -+ typeof selector === "string" && rneedsContext.test( selector ) ? -+ jQuery( selector ) : -+ selector || [], -+ false -+ ).length; -+ } -+} ); -+ -+ -+// Initialize a jQuery object -+ -+ -+// A central reference to the root jQuery(document) -+var rootjQuery, -+ -+ // 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 <) -+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, -+ -+ init = jQuery.fn.init = function( selector, context, root ) { -+ var match, elem; -+ -+ // HANDLE: $(""), $(null), $(undefined), $(false) -+ if ( !selector ) { -+ return this; -+ } -+ -+ // 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.charAt( 0 ) === "<" && -+ selector.charAt( selector.length - 1 ) === ">" && -+ selector.length >= 3 ) { -+ -+ // Assume that strings that start and end with <> are HTML and skip the regex check -+ match = [ null, selector, null ]; -+ -+ } else { -+ match = rquickExpr.exec( selector ); -+ } -+ -+ // Match html or make sure no context is specified for #id -+ if ( match && ( match[ 1 ] || !context ) ) { -+ -+ // HANDLE: $(html) -> $(array) -+ if ( match[ 1 ] ) { -+ context = context instanceof jQuery ? context[ 0 ] : context; -+ -+ // scripts is true for back-compat -+ // Intentionally let the error be thrown if parseHTML is not present -+ jQuery.merge( this, jQuery.parseHTML( -+ match[ 1 ], -+ context && context.nodeType ? context.ownerDocument || context : document, -+ true -+ ) ); -+ -+ // HANDLE: $(html, props) -+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { -+ for ( match in context ) { -+ -+ // Properties of context are called as methods if possible -+ if ( jQuery.isFunction( this[ match ] ) ) { -+ this[ match ]( context[ match ] ); -+ -+ // ...and otherwise set as attributes -+ } else { -+ this.attr( match, context[ match ] ); -+ } -+ } -+ } -+ -+ return this; -+ -+ // HANDLE: $(#id) -+ } else { -+ elem = document.getElementById( match[ 2 ] ); -+ -+ // Check parentNode to catch when Blackberry 4.6 returns -+ // nodes that are no longer in the document #6963 -+ if ( elem && elem.parentNode ) { -+ -+ // Handle the case where IE and Opera return items -+ // by name instead of ID -+ if ( elem.id !== match[ 2 ] ) { -+ return rootjQuery.find( selector ); -+ } -+ -+ // Otherwise, we inject the element directly into the jQuery object -+ this.length = 1; -+ this[ 0 ] = elem; -+ } -+ -+ this.context = document; -+ this.selector = selector; -+ return this; -+ } -+ -+ // HANDLE: $(expr, $(...)) -+ } else if ( !context || context.jquery ) { -+ return ( context || 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.context = this[ 0 ] = selector; -+ this.length = 1; -+ return this; -+ -+ // HANDLE: $(function) -+ // Shortcut for document ready -+ } else if ( jQuery.isFunction( selector ) ) { -+ return typeof root.ready !== "undefined" ? -+ root.ready( selector ) : -+ -+ // Execute immediately if ready is not present -+ selector( jQuery ); -+ } -+ -+ if ( selector.selector !== undefined ) { -+ this.selector = selector.selector; -+ this.context = selector.context; -+ } -+ -+ return jQuery.makeArray( selector, this ); -+ }; -+ -+// Give the init function the jQuery prototype for later instantiation -+init.prototype = jQuery.fn; -+ -+// Initialize central reference -+rootjQuery = jQuery( document ); -+ -+ -+var rparentsprev = /^(?:parents|prev(?:Until|All))/, -+ -+ // methods guaranteed to produce a unique set when starting from a unique set -+ guaranteedUnique = { -+ children: true, -+ contents: true, -+ next: true, -+ prev: true -+ }; -+ -+jQuery.fn.extend( { -+ has: function( target ) { -+ var i, -+ targets = jQuery( target, this ), -+ len = targets.length; -+ -+ return this.filter( function() { -+ for ( i = 0; i < len; i++ ) { -+ if ( jQuery.contains( this, targets[ i ] ) ) { -+ return true; -+ } -+ } -+ } ); -+ }, -+ -+ closest: function( selectors, context ) { -+ var cur, -+ i = 0, -+ l = this.length, -+ matched = [], -+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? -+ jQuery( selectors, context || this.context ) : -+ 0; -+ -+ for ( ; i < l; i++ ) { -+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { -+ -+ // Always skip document fragments -+ if ( cur.nodeType < 11 && ( pos ? -+ pos.index( cur ) > -1 : -+ -+ // Don't pass non-elements to Sizzle -+ cur.nodeType === 1 && -+ jQuery.find.matchesSelector( cur, selectors ) ) ) { -+ -+ matched.push( cur ); -+ break; -+ } -+ } -+ } -+ -+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); -+ }, -+ -+ // Determine the position of an element within -+ // the matched set of elements -+ index: function( elem ) { -+ -+ // No argument, return index in parent -+ if ( !elem ) { -+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; -+ } -+ -+ // index in selector -+ if ( typeof elem === "string" ) { -+ return jQuery.inArray( this[ 0 ], jQuery( elem ) ); -+ } -+ -+ // Locate the position of the desired element -+ return jQuery.inArray( -+ -+ // If it receives a jQuery object, the first element is used -+ elem.jquery ? elem[ 0 ] : elem, this ); -+ }, -+ -+ add: function( selector, context ) { -+ return this.pushStack( -+ jQuery.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 ) { -+ do { -+ cur = cur[ dir ]; -+ } while ( cur && cur.nodeType !== 1 ); -+ -+ return cur; -+} -+ -+jQuery.each( { -+ parent: function( elem ) { -+ var parent = elem.parentNode; -+ return parent && parent.nodeType !== 11 ? parent : null; -+ }, -+ parents: function( elem ) { -+ return 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 ) { -+ return jQuery.nodeName( elem, "iframe" ) ? -+ elem.contentDocument || elem.contentWindow.document : -+ jQuery.merge( [], elem.childNodes ); -+ } -+}, function( name, fn ) { -+ jQuery.fn[ name ] = function( until, selector ) { -+ var ret = jQuery.map( this, fn, until ); -+ -+ if ( name.slice( -5 ) !== "Until" ) { -+ selector = until; -+ } -+ -+ if ( selector && typeof selector === "string" ) { -+ ret = jQuery.filter( selector, ret ); -+ } -+ -+ if ( this.length > 1 ) { -+ -+ // Remove duplicates -+ if ( !guaranteedUnique[ name ] ) { -+ ret = jQuery.uniqueSort( ret ); -+ } -+ -+ // Reverse order for parents* and prev-derivatives -+ if ( rparentsprev.test( name ) ) { -+ ret = ret.reverse(); -+ } -+ } -+ -+ return this.pushStack( ret ); -+ }; -+} ); -+var rnotwhite = ( /\S+/g ); -+ -+ -+ -+// Convert String-formatted options into Object-formatted ones -+function createOptions( options ) { -+ var object = {}; -+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { -+ object[ flag ] = true; -+ } ); -+ return object; -+} -+ -+/* -+ * Create a callback list using the following parameters: -+ * -+ * options: an optional list of space-separated options that will change how -+ * the callback list behaves or a more traditional option object -+ * -+ * By default a callback list will act like an event callback list and can be -+ * "fired" multiple times. -+ * -+ * Possible options: -+ * -+ * once: will ensure the callback list can only be fired once (like a Deferred) -+ * -+ * memory: will keep track of previous values and will call any callback added -+ * after the list has been fired right away with the latest "memorized" -+ * values (like a Deferred) -+ * -+ * unique: will ensure a callback can only be added once (no duplicate in the list) -+ * -+ * stopOnFalse: interrupt callings when a callback returns false -+ * -+ */ -+jQuery.Callbacks = function( options ) { -+ -+ // Convert options from String-formatted to Object-formatted if needed -+ // (we check in cache first) -+ options = typeof options === "string" ? -+ 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 = 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 = true; -+ if ( !memory ) { -+ self.disable(); -+ } -+ 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; -+}; -+ -+ -+jQuery.extend( { -+ -+ Deferred: function( func ) { -+ var tuples = [ -+ -+ // action, add listener, listener list, final state -+ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], -+ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], -+ [ "notify", "progress", jQuery.Callbacks( "memory" ) ] -+ ], -+ state = "pending", -+ promise = { -+ state: function() { -+ return state; -+ }, -+ always: function() { -+ deferred.done( arguments ).fail( arguments ); -+ return this; -+ }, -+ then: function( /* fnDone, fnFail, fnProgress */ ) { -+ var fns = arguments; -+ return jQuery.Deferred( function( newDefer ) { -+ jQuery.each( tuples, function( i, tuple ) { -+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; -+ -+ // deferred[ done | fail | progress ] for forwarding actions to newDefer -+ deferred[ tuple[ 1 ] ]( function() { -+ var returned = fn && fn.apply( this, arguments ); -+ if ( returned && jQuery.isFunction( returned.promise ) ) { -+ returned.promise() -+ .progress( newDefer.notify ) -+ .done( newDefer.resolve ) -+ .fail( newDefer.reject ); -+ } else { -+ newDefer[ tuple[ 0 ] + "With" ]( -+ this === promise ? newDefer.promise() : this, -+ fn ? [ returned ] : arguments -+ ); -+ } -+ } ); -+ } ); -+ fns = null; -+ } ).promise(); -+ }, -+ -+ // Get a promise for this deferred -+ // If obj is provided, the promise aspect is added to the object -+ promise: function( obj ) { -+ return obj != null ? jQuery.extend( obj, promise ) : promise; -+ } -+ }, -+ deferred = {}; -+ -+ // Keep pipe for back-compat -+ promise.pipe = promise.then; -+ -+ // Add list-specific methods -+ jQuery.each( tuples, function( i, tuple ) { -+ var list = tuple[ 2 ], -+ stateString = tuple[ 3 ]; -+ -+ // promise[ done | fail | progress ] = list.add -+ promise[ tuple[ 1 ] ] = list.add; -+ -+ // Handle state -+ if ( stateString ) { -+ list.add( function() { -+ -+ // state = [ resolved | rejected ] -+ state = stateString; -+ -+ // [ reject_list | resolve_list ].disable; progress_list.lock -+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); -+ } -+ -+ // deferred[ resolve | reject | notify ] -+ deferred[ tuple[ 0 ] ] = function() { -+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); -+ return this; -+ }; -+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith; -+ } ); -+ -+ // Make the deferred a promise -+ promise.promise( deferred ); -+ -+ // Call given func if any -+ if ( func ) { -+ func.call( deferred, deferred ); -+ } -+ -+ // All done! -+ return deferred; -+ }, -+ -+ // Deferred helper -+ when: function( subordinate /* , ..., subordinateN */ ) { -+ var i = 0, -+ resolveValues = slice.call( arguments ), -+ length = resolveValues.length, -+ -+ // the count of uncompleted subordinates -+ remaining = length !== 1 || -+ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, -+ -+ // the master Deferred. -+ // If resolveValues consist of only a single Deferred, just use that. -+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(), -+ -+ // Update function for both resolve and progress values -+ updateFunc = function( i, contexts, values ) { -+ return function( value ) { -+ contexts[ i ] = this; -+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; -+ if ( values === progressValues ) { -+ deferred.notifyWith( contexts, values ); -+ -+ } else if ( !( --remaining ) ) { -+ deferred.resolveWith( contexts, values ); -+ } -+ }; -+ }, -+ -+ progressValues, progressContexts, resolveContexts; -+ -+ // add listeners to Deferred subordinates; treat others as resolved -+ if ( length > 1 ) { -+ progressValues = new Array( length ); -+ progressContexts = new Array( length ); -+ resolveContexts = new Array( length ); -+ for ( ; i < length; i++ ) { -+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { -+ resolveValues[ i ].promise() -+ .progress( updateFunc( i, progressContexts, progressValues ) ) -+ .done( updateFunc( i, resolveContexts, resolveValues ) ) -+ .fail( deferred.reject ); -+ } else { -+ --remaining; -+ } -+ } -+ } -+ -+ // if we're not waiting on anything, resolve the master -+ if ( !remaining ) { -+ deferred.resolveWith( resolveContexts, resolveValues ); -+ } -+ -+ return deferred.promise(); -+ } -+} ); -+ -+ -+// The deferred used on DOM ready -+var readyList; -+ -+jQuery.fn.ready = function( fn ) { -+ -+ // Add the callback -+ jQuery.ready.promise().done( fn ); -+ -+ return this; -+}; -+ -+jQuery.extend( { -+ -+ // Is the DOM ready to be used? Set to true once it occurs. -+ isReady: false, -+ -+ // A counter to track how many items to wait for before -+ // the ready event fires. See #6781 -+ readyWait: 1, -+ -+ // Hold (or release) the ready event -+ holdReady: function( hold ) { -+ if ( hold ) { -+ jQuery.readyWait++; -+ } else { -+ jQuery.ready( true ); -+ } -+ }, -+ -+ // Handle when the DOM is ready -+ ready: function( wait ) { -+ -+ // Abort if there are pending holds or we're already ready -+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { -+ return; -+ } -+ -+ // Remember that the DOM is ready -+ jQuery.isReady = true; -+ -+ // If a normal DOM Ready event fired, decrement, and wait if need be -+ if ( wait !== true && --jQuery.readyWait > 0 ) { -+ return; -+ } -+ -+ // If there are functions bound, to execute -+ readyList.resolveWith( document, [ jQuery ] ); -+ -+ // Trigger any bound ready events -+ if ( jQuery.fn.triggerHandler ) { -+ jQuery( document ).triggerHandler( "ready" ); -+ jQuery( document ).off( "ready" ); -+ } -+ } -+} ); -+ -+/** -+ * Clean-up method for dom ready events -+ */ -+function detach() { -+ if ( document.addEventListener ) { -+ document.removeEventListener( "DOMContentLoaded", completed ); -+ window.removeEventListener( "load", completed ); -+ -+ } else { -+ document.detachEvent( "onreadystatechange", completed ); -+ window.detachEvent( "onload", completed ); -+ } -+} -+ -+/** -+ * The ready event handler and self cleanup method -+ */ -+function completed() { -+ -+ // readyState === "complete" is good enough for us to call the dom ready in oldIE -+ if ( document.addEventListener || -+ window.event.type === "load" || -+ document.readyState === "complete" ) { -+ -+ detach(); -+ jQuery.ready(); -+ } -+} -+ -+jQuery.ready.promise = function( obj ) { -+ if ( !readyList ) { -+ -+ readyList = jQuery.Deferred(); -+ -+ // Catch cases where $(document).ready() is called -+ // after the browser event has already occurred. -+ // Support: IE6-10 -+ // 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 ); -+ -+ // Standards-based browsers support DOMContentLoaded -+ } else if ( document.addEventListener ) { -+ -+ // Use the handy event callback -+ document.addEventListener( "DOMContentLoaded", completed ); -+ -+ // A fallback to window.onload, that will always work -+ window.addEventListener( "load", completed ); -+ -+ // If IE event model is used -+ } else { -+ -+ // Ensure firing before onload, maybe late but safe also for iframes -+ document.attachEvent( "onreadystatechange", completed ); -+ -+ // A fallback to window.onload, that will always work -+ window.attachEvent( "onload", completed ); -+ -+ // If IE and not a frame -+ // continually check to see if the document is ready -+ var top = false; -+ -+ try { -+ top = window.frameElement == null && document.documentElement; -+ } catch ( e ) {} -+ -+ if ( top && top.doScroll ) { -+ ( function doScrollCheck() { -+ if ( !jQuery.isReady ) { -+ -+ try { -+ -+ // Use the trick by Diego Perini -+ // http://javascript.nwbox.com/IEContentLoaded/ -+ top.doScroll( "left" ); -+ } catch ( e ) { -+ return window.setTimeout( doScrollCheck, 50 ); -+ } -+ -+ // detach all dom ready events -+ detach(); -+ -+ // and execute any waiting functions -+ jQuery.ready(); -+ } -+ } )(); -+ } -+ } -+ } -+ return readyList.promise( obj ); -+}; -+ -+// Kick off the DOM ready check even if the user does not -+jQuery.ready.promise(); -+ -+ -+ -+ -+// Support: IE<9 -+// Iteration over object's inherited properties before its own -+var i; -+for ( i in jQuery( support ) ) { -+ break; -+} -+support.ownFirst = i === "0"; -+ -+// Note: most support tests are defined in their respective modules. -+// false until the test is run -+support.inlineBlockNeedsLayout = false; -+ -+// Execute ASAP in case we need to set body.style.zoom -+jQuery( function() { -+ -+ // Minified: var a,b,c,d -+ var val, div, body, container; -+ -+ body = document.getElementsByTagName( "body" )[ 0 ]; -+ if ( !body || !body.style ) { -+ -+ // Return for frameset docs that don't have a body -+ return; -+ } -+ -+ // Setup -+ div = document.createElement( "div" ); -+ container = document.createElement( "div" ); -+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; -+ body.appendChild( container ).appendChild( div ); -+ -+ if ( typeof div.style.zoom !== "undefined" ) { -+ -+ // Support: IE<8 -+ // Check if natively block-level elements act like inline-block -+ // elements when setting their display to 'inline' and giving -+ // them layout -+ div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; -+ -+ support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; -+ if ( val ) { -+ -+ // Prevent IE 6 from affecting layout for positioned elements #11048 -+ // Prevent IE from shrinking the body in IE 7 mode #12869 -+ // Support: IE<8 -+ body.style.zoom = 1; -+ } -+ } -+ -+ body.removeChild( container ); -+} ); -+ -+ -+( function() { -+ var div = document.createElement( "div" ); -+ -+ // Support: IE<9 -+ support.deleteExpando = true; -+ try { -+ delete div.test; -+ } catch ( e ) { -+ support.deleteExpando = false; -+ } -+ -+ // Null elements to avoid leaks in IE. -+ div = null; -+} )(); -+var acceptData = function( elem ) { -+ var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], -+ nodeType = +elem.nodeType || 1; -+ -+ // Do not set data on non-element DOM nodes because it will not be cleared (#8335). -+ return nodeType !== 1 && nodeType !== 9 ? -+ false : -+ -+ // Nodes accept data unless otherwise specified; rejection can be conditional -+ !noData || noData !== true && elem.getAttribute( "classid" ) === noData; -+}; -+ -+ -+ -+ -+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, -+ rmultiDash = /([A-Z])/g; -+ -+function dataAttr( elem, key, data ) { -+ -+ // If nothing was found internally, try to fetch any -+ // data from the HTML5 data-* attribute -+ if ( data === undefined && elem.nodeType === 1 ) { -+ -+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); -+ -+ data = elem.getAttribute( name ); -+ -+ if ( typeof data === "string" ) { -+ try { -+ data = data === "true" ? true : -+ data === "false" ? false : -+ data === "null" ? null : -+ -+ // Only convert to a number if it doesn't change the string -+ +data + "" === data ? +data : -+ rbrace.test( data ) ? jQuery.parseJSON( data ) : -+ data; -+ } catch ( e ) {} -+ -+ // Make sure we set the data so it isn't changed later -+ jQuery.data( elem, key, data ); -+ -+ } else { -+ data = undefined; -+ } -+ } -+ -+ return data; -+} -+ -+// checks a cache object for emptiness -+function isEmptyDataObject( obj ) { -+ var name; -+ for ( name in obj ) { -+ -+ // if the public data object is empty, the private is still empty -+ if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { -+ continue; -+ } -+ if ( name !== "toJSON" ) { -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+function internalData( elem, name, data, pvt /* Internal Use Only */ ) { -+ if ( !acceptData( elem ) ) { -+ return; -+ } -+ -+ var ret, thisCache, -+ internalKey = jQuery.expando, -+ -+ // We have to handle DOM nodes and JS objects differently because IE6-7 -+ // can't GC object references properly across the DOM-JS boundary -+ isNode = elem.nodeType, -+ -+ // Only DOM nodes need the global jQuery cache; JS object data is -+ // attached directly to the object so GC can occur automatically -+ cache = isNode ? jQuery.cache : elem, -+ -+ // Only defining an ID for JS objects if its cache already exists allows -+ // the code to shortcut on the same path as a DOM node with no cache -+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; -+ -+ // Avoid doing any more work than we need to when trying to get data on an -+ // object that has no data at all -+ if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && -+ data === undefined && typeof name === "string" ) { -+ return; -+ } -+ -+ if ( !id ) { -+ -+ // Only DOM nodes need a new unique ID for each element since their data -+ // ends up in the global cache -+ if ( isNode ) { -+ id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; -+ } else { -+ id = internalKey; -+ } -+ } -+ -+ if ( !cache[ id ] ) { -+ -+ // Avoid exposing jQuery metadata on plain JS objects when the object -+ // is serialized using JSON.stringify -+ cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; -+ } -+ -+ // An object can be passed to jQuery.data instead of a key/value pair; this gets -+ // shallow copied over onto the existing cache -+ if ( typeof name === "object" || typeof name === "function" ) { -+ if ( pvt ) { -+ cache[ id ] = jQuery.extend( cache[ id ], name ); -+ } else { -+ cache[ id ].data = jQuery.extend( cache[ id ].data, name ); -+ } -+ } -+ -+ thisCache = cache[ id ]; -+ -+ // jQuery data() is stored in a separate object inside the object's internal data -+ // cache in order to avoid key collisions between internal data and user-defined -+ // data. -+ if ( !pvt ) { -+ if ( !thisCache.data ) { -+ thisCache.data = {}; -+ } -+ -+ thisCache = thisCache.data; -+ } -+ -+ if ( data !== undefined ) { -+ thisCache[ jQuery.camelCase( name ) ] = data; -+ } -+ -+ // Check for both converted-to-camel and non-converted data property names -+ // If a data property was specified -+ if ( typeof name === "string" ) { -+ -+ // First Try to find as-is property data -+ ret = thisCache[ name ]; -+ -+ // Test for null|undefined property data -+ if ( ret == null ) { -+ -+ // Try to find the camelCased property -+ ret = thisCache[ jQuery.camelCase( name ) ]; -+ } -+ } else { -+ ret = thisCache; -+ } -+ -+ return ret; -+} -+ -+function internalRemoveData( elem, name, pvt ) { -+ if ( !acceptData( elem ) ) { -+ return; -+ } -+ -+ var thisCache, i, -+ isNode = elem.nodeType, -+ -+ // See jQuery.data for more information -+ cache = isNode ? jQuery.cache : elem, -+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando; -+ -+ // If there is already no cache entry for this object, there is no -+ // purpose in continuing -+ if ( !cache[ id ] ) { -+ return; -+ } -+ -+ if ( name ) { -+ -+ thisCache = pvt ? cache[ id ] : cache[ id ].data; -+ -+ if ( thisCache ) { -+ -+ // Support array or space separated string names for data keys -+ if ( !jQuery.isArray( name ) ) { -+ -+ // try the string as a key before any manipulation -+ if ( name in thisCache ) { -+ name = [ name ]; -+ } else { -+ -+ // split the camel cased version by spaces unless a key with the spaces exists -+ name = jQuery.camelCase( name ); -+ if ( name in thisCache ) { -+ name = [ name ]; -+ } else { -+ name = name.split( " " ); -+ } -+ } -+ } else { -+ -+ // If "name" is an array of keys... -+ // When data is initially created, via ("key", "val") signature, -+ // keys will be converted to camelCase. -+ // Since there is no way to tell _how_ a key was added, remove -+ // both plain key and camelCase key. #12786 -+ // This will only penalize the array argument path. -+ name = name.concat( jQuery.map( name, jQuery.camelCase ) ); -+ } -+ -+ i = name.length; -+ while ( i-- ) { -+ delete thisCache[ name[ i ] ]; -+ } -+ -+ // If there is no data left in the cache, we want to continue -+ // and let the cache object itself get destroyed -+ if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { -+ return; -+ } -+ } -+ } -+ -+ // See jQuery.data for more information -+ if ( !pvt ) { -+ delete cache[ id ].data; -+ -+ // Don't destroy the parent cache unless the internal data object -+ // had been the only thing left in it -+ if ( !isEmptyDataObject( cache[ id ] ) ) { -+ return; -+ } -+ } -+ -+ // Destroy the cache -+ if ( isNode ) { -+ jQuery.cleanData( [ elem ], true ); -+ -+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) -+ /* jshint eqeqeq: false */ -+ } else if ( support.deleteExpando || cache != cache.window ) { -+ /* jshint eqeqeq: true */ -+ delete cache[ id ]; -+ -+ // When all else fails, undefined -+ } else { -+ cache[ id ] = undefined; -+ } -+} -+ -+jQuery.extend( { -+ cache: {}, -+ -+ // The following elements (space-suffixed to avoid Object.prototype collisions) -+ // throw uncatchable exceptions if you attempt to set expando properties -+ noData: { -+ "applet ": true, -+ "embed ": true, -+ -+ // ...but Flash objects (which have this classid) *can* handle expandos -+ "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" -+ }, -+ -+ hasData: function( elem ) { -+ elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; -+ return !!elem && !isEmptyDataObject( elem ); -+ }, -+ -+ data: function( elem, name, data ) { -+ return internalData( elem, name, data ); -+ }, -+ -+ removeData: function( elem, name ) { -+ return internalRemoveData( elem, name ); -+ }, -+ -+ // For internal use only. -+ _data: function( elem, name, data ) { -+ return internalData( elem, name, data, true ); -+ }, -+ -+ _removeData: function( elem, name ) { -+ return internalRemoveData( elem, name, true ); -+ } -+} ); -+ -+jQuery.fn.extend( { -+ data: function( key, value ) { -+ var i, name, data, -+ elem = this[ 0 ], -+ attrs = elem && elem.attributes; -+ -+ // Special expections of .data basically thwart jQuery.access, -+ // so implement the relevant behavior ourselves -+ -+ // Gets all values -+ if ( key === undefined ) { -+ if ( this.length ) { -+ data = jQuery.data( elem ); -+ -+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { -+ i = attrs.length; -+ while ( i-- ) { -+ -+ // Support: IE11+ -+ // The attrs elements can be null (#14894) -+ if ( attrs[ i ] ) { -+ name = attrs[ i ].name; -+ if ( name.indexOf( "data-" ) === 0 ) { -+ name = jQuery.camelCase( name.slice( 5 ) ); -+ dataAttr( elem, name, data[ name ] ); -+ } -+ } -+ } -+ jQuery._data( elem, "parsedAttrs", true ); -+ } -+ } -+ -+ return data; -+ } -+ -+ // Sets multiple values -+ if ( typeof key === "object" ) { -+ return this.each( function() { -+ jQuery.data( this, key ); -+ } ); -+ } -+ -+ return arguments.length > 1 ? -+ -+ // Sets one value -+ this.each( function() { -+ jQuery.data( this, key, value ); -+ } ) : -+ -+ // Gets one value -+ // Try to fetch any internally stored data first -+ elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; -+ }, -+ -+ removeData: function( key ) { -+ return this.each( function() { -+ jQuery.removeData( this, key ); -+ } ); -+ } -+} ); -+ -+ -+jQuery.extend( { -+ queue: function( elem, type, data ) { -+ var queue; -+ -+ if ( elem ) { -+ type = ( type || "fx" ) + "queue"; -+ queue = jQuery._data( elem, type ); -+ -+ // Speed up dequeue by getting out quickly if this is just a lookup -+ if ( data ) { -+ if ( !queue || jQuery.isArray( data ) ) { -+ queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); -+ } else { -+ queue.push( data ); -+ } -+ } -+ return queue || []; -+ } -+ }, -+ -+ dequeue: function( elem, type ) { -+ type = type || "fx"; -+ -+ var queue = jQuery.queue( elem, type ), -+ startLength = queue.length, -+ fn = queue.shift(), -+ hooks = jQuery._queueHooks( elem, type ), -+ next = function() { -+ jQuery.dequeue( elem, type ); -+ }; -+ -+ // If the fx queue is dequeued, always remove the progress sentinel -+ if ( fn === "inprogress" ) { -+ fn = queue.shift(); -+ startLength--; -+ } -+ -+ if ( fn ) { -+ -+ // Add a progress sentinel to prevent the fx queue from being -+ // automatically dequeued -+ if ( type === "fx" ) { -+ queue.unshift( "inprogress" ); -+ } -+ -+ // clear up the last queue stop function -+ delete hooks.stop; -+ fn.call( elem, next, hooks ); -+ } -+ -+ if ( !startLength && hooks ) { -+ hooks.empty.fire(); -+ } -+ }, -+ -+ // not intended for public consumption - generates a queueHooks object, -+ // or returns the current one -+ _queueHooks: function( elem, type ) { -+ var key = type + "queueHooks"; -+ return jQuery._data( elem, key ) || jQuery._data( elem, key, { -+ empty: jQuery.Callbacks( "once memory" ).add( function() { -+ jQuery._removeData( elem, type + "queue" ); -+ jQuery._removeData( elem, key ); -+ } ) -+ } ); -+ } -+} ); -+ -+jQuery.fn.extend( { -+ queue: function( type, data ) { -+ var setter = 2; -+ -+ if ( typeof type !== "string" ) { -+ data = type; -+ type = "fx"; -+ setter--; -+ } -+ -+ if ( arguments.length < setter ) { -+ return jQuery.queue( this[ 0 ], type ); -+ } -+ -+ return data === undefined ? -+ this : -+ this.each( function() { -+ var queue = jQuery.queue( this, type, data ); -+ -+ // ensure a hooks for this queue -+ jQuery._queueHooks( this, type ); -+ -+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { -+ jQuery.dequeue( this, type ); -+ } -+ } ); -+ }, -+ dequeue: function( type ) { -+ return this.each( function() { -+ jQuery.dequeue( this, type ); -+ } ); -+ }, -+ clearQueue: function( type ) { -+ return this.queue( type || "fx", [] ); -+ }, -+ -+ // Get a promise resolved when queues of a certain type -+ // are emptied (fx is the type by default) -+ promise: function( type, obj ) { -+ var tmp, -+ count = 1, -+ defer = jQuery.Deferred(), -+ elements = this, -+ i = this.length, -+ resolve = function() { -+ if ( !( --count ) ) { -+ defer.resolveWith( elements, [ elements ] ); -+ } -+ }; -+ -+ if ( typeof type !== "string" ) { -+ obj = type; -+ type = undefined; -+ } -+ type = type || "fx"; -+ -+ while ( i-- ) { -+ tmp = jQuery._data( elements[ i ], type + "queueHooks" ); -+ if ( tmp && tmp.empty ) { -+ count++; -+ tmp.empty.add( resolve ); -+ } -+ } -+ resolve(); -+ return defer.promise( obj ); -+ } -+} ); -+ -+ -+( function() { -+ var shrinkWrapBlocksVal; -+ -+ support.shrinkWrapBlocks = function() { -+ if ( shrinkWrapBlocksVal != null ) { -+ return shrinkWrapBlocksVal; -+ } -+ -+ // Will be changed later if needed. -+ shrinkWrapBlocksVal = false; -+ -+ // Minified: var b,c,d -+ var div, body, container; -+ -+ body = document.getElementsByTagName( "body" )[ 0 ]; -+ if ( !body || !body.style ) { -+ -+ // Test fired too early or in an unsupported environment, exit. -+ return; -+ } -+ -+ // Setup -+ div = document.createElement( "div" ); -+ container = document.createElement( "div" ); -+ container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; -+ body.appendChild( container ).appendChild( div ); -+ -+ // Support: IE6 -+ // Check if elements with layout shrink-wrap their children -+ if ( typeof div.style.zoom !== "undefined" ) { -+ -+ // Reset CSS: box-sizing; display; margin; border -+ div.style.cssText = -+ -+ // Support: Firefox<29, Android 2.3 -+ // Vendor-prefix box-sizing -+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + -+ "box-sizing:content-box;display:block;margin:0;border:0;" + -+ "padding:1px;width:1px;zoom:1"; -+ div.appendChild( document.createElement( "div" ) ).style.width = "5px"; -+ shrinkWrapBlocksVal = div.offsetWidth !== 3; -+ } -+ -+ body.removeChild( container ); -+ -+ return shrinkWrapBlocksVal; -+ }; -+ -+} )(); -+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; -+ -+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); -+ -+ -+var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; -+ -+var isHidden = function( elem, el ) { -+ -+ // isHidden might be called from jQuery#filter function; -+ // in that case, element will be second argument -+ elem = el || elem; -+ return jQuery.css( elem, "display" ) === "none" || -+ !jQuery.contains( elem.ownerDocument, elem ); -+ }; -+ -+ -+ -+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; -+} -+ -+ -+// 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, -+ length = 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 < length; i++ ) { -+ fn( -+ elems[ i ], -+ key, -+ raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) -+ ); -+ } -+ } -+ } -+ -+ return chainable ? -+ elems : -+ -+ // Gets -+ bulk ? -+ fn.call( elems ) : -+ length ? fn( elems[ 0 ], key ) : emptyGet; -+}; -+var rcheckableType = ( /^(?:checkbox|radio)$/i ); -+ -+var rtagName = ( /<([\w:-]+)/ ); -+ -+var rscriptType = ( /^$|\/(?:java|ecma)script/i ); -+ -+var rleadingWhitespace = ( /^\s+/ ); -+ -+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + -+ "details|dialog|figcaption|figure|footer|header|hgroup|main|" + -+ "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; -+ -+ -+ -+function createSafeFragment( document ) { -+ var list = nodeNames.split( "|" ), -+ safeFrag = document.createDocumentFragment(); -+ -+ if ( safeFrag.createElement ) { -+ while ( list.length ) { -+ safeFrag.createElement( -+ list.pop() -+ ); -+ } -+ } -+ return safeFrag; -+} -+ -+ -+( function() { -+ var div = document.createElement( "div" ), -+ fragment = document.createDocumentFragment(), -+ input = document.createElement( "input" ); -+ -+ // Setup -+ div.innerHTML = "
a"; -+ -+ // IE strips leading whitespace when .innerHTML is used -+ support.leadingWhitespace = div.firstChild.nodeType === 3; -+ -+ // Make sure that tbody elements aren't automatically inserted -+ // IE will insert them into empty tables -+ support.tbody = !div.getElementsByTagName( "tbody" ).length; -+ -+ // Make sure that link elements get serialized correctly by innerHTML -+ // This requires a wrapper element in IE -+ support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; -+ -+ // Makes sure cloning an html5 element does not cause problems -+ // Where outerHTML is undefined, this still works -+ support.html5Clone = -+ document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; -+ -+ // Check if a disconnected checkbox will retain its checked -+ // value of true after appended to the DOM (IE6/7) -+ input.type = "checkbox"; -+ input.checked = true; -+ fragment.appendChild( input ); -+ support.appendChecked = input.checked; -+ -+ // Make sure textarea (and checkbox) defaultValue is properly cloned -+ // Support: IE6-IE11+ -+ div.innerHTML = ""; -+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -+ -+ // #11217 - WebKit loses check when the name is after the checked attribute -+ fragment.appendChild( div ); -+ -+ // Support: Windows Web Apps (WWA) -+ // `name` and `type` must use .setAttribute for WWA (#14901) -+ input = document.createElement( "input" ); -+ input.setAttribute( "type", "radio" ); -+ input.setAttribute( "checked", "checked" ); -+ input.setAttribute( "name", "t" ); -+ -+ div.appendChild( input ); -+ -+ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 -+ // old WebKit doesn't clone checked state correctly in fragments -+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; -+ -+ // Support: IE<9 -+ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ -+ support.noCloneEvent = !!div.addEventListener; -+ -+ // Support: IE<9 -+ // Since attributes and properties are the same in IE, -+ // cleanData must set properties to undefined rather than use removeAttribute -+ div[ jQuery.expando ] = 1; -+ support.attributes = !div.getAttribute( jQuery.expando ); -+} )(); -+ -+ -+// We have to close these tags to support XHTML (#13200) -+var wrapMap = { -+ option: [ 1, "" ], -+ legend: [ 1, "
", "
" ], -+ area: [ 1, "", "" ], -+ -+ // Support: IE8 -+ param: [ 1, "", "" ], -+ thead: [ 1, "", "
" ], -+ tr: [ 2, "", "
" ], -+ col: [ 2, "", "
" ], -+ td: [ 3, "", "
" ], -+ -+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, -+ // unless wrapped in a div with non-breaking characters in front of it. -+ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] -+}; -+ -+// Support: IE8-IE9 -+wrapMap.optgroup = wrapMap.option; -+ -+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -+wrapMap.th = wrapMap.td; -+ -+ -+function getAll( context, tag ) { -+ var elems, elem, -+ i = 0, -+ found = typeof context.getElementsByTagName !== "undefined" ? -+ context.getElementsByTagName( tag || "*" ) : -+ typeof context.querySelectorAll !== "undefined" ? -+ context.querySelectorAll( tag || "*" ) : -+ undefined; -+ -+ if ( !found ) { -+ for ( found = [], elems = context.childNodes || context; -+ ( elem = elems[ i ] ) != null; -+ i++ -+ ) { -+ if ( !tag || jQuery.nodeName( elem, tag ) ) { -+ found.push( elem ); -+ } else { -+ jQuery.merge( found, getAll( elem, tag ) ); -+ } -+ } -+ } -+ -+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ? -+ jQuery.merge( [ context ], found ) : -+ found; -+} -+ -+ -+// Mark scripts as having already been evaluated -+function setGlobalEval( elems, refElements ) { -+ var elem, -+ i = 0; -+ for ( ; ( elem = elems[ i ] ) != null; i++ ) { -+ jQuery._data( -+ elem, -+ "globalEval", -+ !refElements || jQuery._data( refElements[ i ], "globalEval" ) -+ ); -+ } -+} -+ -+ -+var rhtml = /<|&#?\w+;/, -+ rtbody = / from table fragments -+ if ( !support.tbody ) { -+ -+ // String was a , *may* have spurious -+ elem = tag === "table" && !rtbody.test( elem ) ? -+ tmp.firstChild : -+ -+ // String was a bare or -+ wrap[ 1 ] === "
" && !rtbody.test( elem ) ? -+ tmp : -+ 0; -+ -+ j = elem && elem.childNodes.length; -+ while ( j-- ) { -+ if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && -+ !tbody.childNodes.length ) { -+ -+ elem.removeChild( tbody ); -+ } -+ } -+ } -+ -+ jQuery.merge( nodes, tmp.childNodes ); -+ -+ // Fix #12392 for WebKit and IE > 9 -+ tmp.textContent = ""; -+ -+ // Fix #12392 for oldIE -+ while ( tmp.firstChild ) { -+ tmp.removeChild( tmp.firstChild ); -+ } -+ -+ // Remember the top-level container for proper cleanup -+ tmp = safe.lastChild; -+ } -+ } -+ } -+ -+ // Fix #11356: Clear elements from fragment -+ if ( tmp ) { -+ safe.removeChild( tmp ); -+ } -+ -+ // Reset defaultChecked for any radios and checkboxes -+ // about to be appended to the DOM in IE 6/7 (#8060) -+ if ( !support.appendChecked ) { -+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); -+ } -+ -+ i = 0; -+ while ( ( elem = nodes[ i++ ] ) ) { -+ -+ // 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( safe.appendChild( elem ), "script" ); -+ -+ // Preserve script evaluation history -+ if ( contains ) { -+ setGlobalEval( tmp ); -+ } -+ -+ // Capture executables -+ if ( scripts ) { -+ j = 0; -+ while ( ( elem = tmp[ j++ ] ) ) { -+ if ( rscriptType.test( elem.type || "" ) ) { -+ scripts.push( elem ); -+ } -+ } -+ } -+ } -+ -+ tmp = null; -+ -+ return safe; -+} -+ -+ -+( function() { -+ var i, eventName, -+ div = document.createElement( "div" ); -+ -+ // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) -+ for ( i in { submit: true, change: true, focusin: true } ) { -+ eventName = "on" + i; -+ -+ if ( !( support[ i ] = eventName in window ) ) { -+ -+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) -+ div.setAttribute( eventName, "t" ); -+ support[ i ] = div.attributes[ eventName ].expando === false; -+ } -+ } -+ -+ // Null elements to avoid leaks in IE. -+ div = null; -+} )(); -+ -+ -+var rformElems = /^(?:input|select|textarea)$/i, -+ rkeyEvent = /^key/, -+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, -+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, -+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/; -+ -+function returnTrue() { -+ return true; -+} -+ -+function returnFalse() { -+ return false; -+} -+ -+// Support: IE9 -+// 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 tmp, events, t, handleObjIn, -+ special, eventHandle, handleObj, -+ handlers, type, namespaces, origType, -+ elemData = jQuery._data( elem ); -+ -+ // Don't attach events to noData or text/comment nodes (but allow plain objects) -+ if ( !elemData ) { -+ return; -+ } -+ -+ // Caller can pass in an object of custom data in lieu of the handler -+ if ( handler.handler ) { -+ handleObjIn = handler; -+ handler = handleObjIn.handler; -+ selector = handleObjIn.selector; -+ } -+ -+ // Make sure that the handler has a unique ID, used to find/remove it later -+ if ( !handler.guid ) { -+ handler.guid = jQuery.guid++; -+ } -+ -+ // Init the element's event structure and main handler, if this is the first -+ if ( !( events = elemData.events ) ) { -+ events = elemData.events = {}; -+ } -+ if ( !( eventHandle = elemData.handle ) ) { -+ eventHandle = elemData.handle = function( e ) { -+ -+ // Discard the second event of a jQuery.event.trigger() and -+ // when an event is called after a page has unloaded -+ return typeof jQuery !== "undefined" && -+ ( !e || jQuery.event.triggered !== e.type ) ? -+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : -+ undefined; -+ }; -+ -+ // Add elem as a property of the handle fn to prevent a memory leak -+ // with IE non-native events -+ eventHandle.elem = elem; -+ } -+ -+ // Handle multiple events separated by a space -+ types = ( types || "" ).match( rnotwhite ) || [ "" ]; -+ t = types.length; -+ while ( t-- ) { -+ tmp = rtypenamespace.exec( types[ t ] ) || []; -+ type = origType = tmp[ 1 ]; -+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); -+ -+ // There *must* be a type, no attaching namespace-only handlers -+ if ( !type ) { -+ continue; -+ } -+ -+ // If event changes its type, use the special event handlers for the changed type -+ special = jQuery.event.special[ type ] || {}; -+ -+ // If selector defined, determine special event api type, otherwise given type -+ type = ( selector ? special.delegateType : special.bindType ) || type; -+ -+ // Update special based on newly reset type -+ special = jQuery.event.special[ type ] || {}; -+ -+ // handleObj is passed to all event handlers -+ handleObj = jQuery.extend( { -+ type: type, -+ origType: origType, -+ data: data, -+ handler: handler, -+ guid: handler.guid, -+ selector: selector, -+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ), -+ namespace: namespaces.join( "." ) -+ }, handleObjIn ); -+ -+ // Init the event handler queue if we're the first -+ if ( !( handlers = events[ type ] ) ) { -+ handlers = events[ type ] = []; -+ handlers.delegateCount = 0; -+ -+ // Only use addEventListener/attachEvent if the special events handler returns false -+ if ( !special.setup || -+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) { -+ -+ // Bind the global event handler to the element -+ if ( elem.addEventListener ) { -+ elem.addEventListener( type, eventHandle, false ); -+ -+ } else if ( elem.attachEvent ) { -+ elem.attachEvent( "on" + type, eventHandle ); -+ } -+ } -+ } -+ -+ if ( special.add ) { -+ special.add.call( elem, handleObj ); -+ -+ if ( !handleObj.handler.guid ) { -+ handleObj.handler.guid = handler.guid; -+ } -+ } -+ -+ // Add to the element's handler list, delegates in front -+ if ( selector ) { -+ handlers.splice( handlers.delegateCount++, 0, handleObj ); -+ } else { -+ handlers.push( handleObj ); -+ } -+ -+ // Keep track of which events have ever been used, for event optimization -+ jQuery.event.global[ type ] = true; -+ } -+ -+ // Nullify elem to prevent memory leaks in IE -+ elem = null; -+ }, -+ -+ // Detach an event or set of events from an element -+ remove: function( elem, types, handler, selector, mappedTypes ) { -+ var j, handleObj, tmp, -+ origCount, t, events, -+ special, handlers, type, -+ namespaces, origType, -+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ); -+ -+ if ( !elemData || !( events = elemData.events ) ) { -+ return; -+ } -+ -+ // Once for each type.namespace in types; type may be omitted -+ types = ( types || "" ).match( rnotwhite ) || [ "" ]; -+ t = types.length; -+ while ( t-- ) { -+ tmp = rtypenamespace.exec( types[ t ] ) || []; -+ type = origType = tmp[ 1 ]; -+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); -+ -+ // Unbind all events (on this namespace, if provided) for the element -+ if ( !type ) { -+ for ( type in events ) { -+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); -+ } -+ continue; -+ } -+ -+ special = jQuery.event.special[ type ] || {}; -+ type = ( selector ? special.delegateType : special.bindType ) || type; -+ handlers = events[ type ] || []; -+ tmp = tmp[ 2 ] && -+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); -+ -+ // Remove matching events -+ origCount = j = handlers.length; -+ while ( j-- ) { -+ handleObj = handlers[ j ]; -+ -+ if ( ( mappedTypes || origType === handleObj.origType ) && -+ ( !handler || handler.guid === handleObj.guid ) && -+ ( !tmp || tmp.test( handleObj.namespace ) ) && -+ ( !selector || selector === handleObj.selector || -+ selector === "**" && handleObj.selector ) ) { -+ handlers.splice( j, 1 ); -+ -+ if ( handleObj.selector ) { -+ handlers.delegateCount--; -+ } -+ if ( special.remove ) { -+ special.remove.call( elem, handleObj ); -+ } -+ } -+ } -+ -+ // Remove generic event handler if we removed something and no more handlers exist -+ // (avoids potential for endless recursion during removal of special event handlers) -+ if ( origCount && !handlers.length ) { -+ if ( !special.teardown || -+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) { -+ -+ jQuery.removeEvent( elem, type, elemData.handle ); -+ } -+ -+ delete events[ type ]; -+ } -+ } -+ -+ // Remove the expando if it's no longer used -+ if ( jQuery.isEmptyObject( events ) ) { -+ delete elemData.handle; -+ -+ // removeData also checks for emptiness and clears the expando if empty -+ // so use it instead of delete -+ jQuery._removeData( elem, "events" ); -+ } -+ }, -+ -+ trigger: function( event, data, elem, onlyHandlers ) { -+ var handle, ontype, cur, -+ bubbleType, special, tmp, i, -+ eventPath = [ elem || document ], -+ type = hasOwn.call( event, "type" ) ? event.type : event, -+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; -+ -+ cur = tmp = elem = elem || document; -+ -+ // Don't do events on text and comment nodes -+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) { -+ return; -+ } -+ -+ // focus/blur morphs to focusin/out; ensure we're not firing them right now -+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { -+ return; -+ } -+ -+ if ( type.indexOf( "." ) > -1 ) { -+ -+ // Namespaced trigger; create a regexp to match event type in handle() -+ namespaces = type.split( "." ); -+ type = namespaces.shift(); -+ namespaces.sort(); -+ } -+ ontype = type.indexOf( ":" ) < 0 && "on" + type; -+ -+ // Caller can pass in a jQuery.Event object, Object, or just an event type string -+ event = event[ jQuery.expando ] ? -+ event : -+ new jQuery.Event( type, typeof event === "object" && event ); -+ -+ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) -+ event.isTrigger = onlyHandlers ? 2 : 3; -+ event.namespace = namespaces.join( "." ); -+ event.rnamespace = event.namespace ? -+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : -+ null; -+ -+ // Clean up the event in case it is being reused -+ event.result = undefined; -+ if ( !event.target ) { -+ event.target = elem; -+ } -+ -+ // Clone any incoming data and prepend the event, creating the handler arg list -+ data = data == null ? -+ [ event ] : -+ jQuery.makeArray( data, [ event ] ); -+ -+ // Allow special events to draw outside the lines -+ special = jQuery.event.special[ type ] || {}; -+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { -+ return; -+ } -+ -+ // Determine event propagation path in advance, per W3C events spec (#9951) -+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) -+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { -+ -+ bubbleType = special.delegateType || type; -+ if ( !rfocusMorph.test( bubbleType + type ) ) { -+ cur = cur.parentNode; -+ } -+ for ( ; cur; cur = cur.parentNode ) { -+ eventPath.push( cur ); -+ tmp = cur; -+ } -+ -+ // Only add window if we got to document (e.g., not plain obj or detached DOM) -+ if ( tmp === ( elem.ownerDocument || document ) ) { -+ eventPath.push( tmp.defaultView || tmp.parentWindow || window ); -+ } -+ } -+ -+ // Fire handlers on the event path -+ i = 0; -+ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { -+ -+ event.type = i > 1 ? -+ bubbleType : -+ special.bindType || type; -+ -+ // jQuery handler -+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && -+ jQuery._data( cur, "handle" ); -+ -+ if ( handle ) { -+ handle.apply( cur, data ); -+ } -+ -+ // Native handler -+ handle = ontype && cur[ ontype ]; -+ if ( handle && handle.apply && acceptData( cur ) ) { -+ event.result = handle.apply( cur, data ); -+ if ( event.result === false ) { -+ event.preventDefault(); -+ } -+ } -+ } -+ event.type = type; -+ -+ // If nobody prevented the default action, do it now -+ if ( !onlyHandlers && !event.isDefaultPrevented() ) { -+ -+ if ( -+ ( !special._default || -+ special._default.apply( eventPath.pop(), data ) === false -+ ) && acceptData( elem ) -+ ) { -+ -+ // Call a native DOM method on the target with the same name name as the event. -+ // Can't use an .isFunction() check here because IE6/7 fails that test. -+ // Don't do default actions on window, that's where global variables be (#6170) -+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { -+ -+ // Don't re-trigger an onFOO event when we call its FOO() method -+ tmp = elem[ ontype ]; -+ -+ if ( tmp ) { -+ elem[ ontype ] = null; -+ } -+ -+ // Prevent re-triggering of the same event, since we already bubbled it above -+ jQuery.event.triggered = type; -+ try { -+ elem[ type ](); -+ } catch ( e ) { -+ -+ // IE<9 dies on focus/blur to hidden element (#1486,#12518) -+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode -+ } -+ jQuery.event.triggered = undefined; -+ -+ if ( tmp ) { -+ elem[ ontype ] = tmp; -+ } -+ } -+ } -+ } -+ -+ return event.result; -+ }, -+ -+ dispatch: function( event ) { -+ -+ // Make a writable jQuery.Event from the native event object -+ event = jQuery.event.fix( event ); -+ -+ var i, j, ret, matched, handleObj, -+ handlerQueue = [], -+ args = slice.call( arguments ), -+ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], -+ special = jQuery.event.special[ event.type ] || {}; -+ -+ // Use the fix-ed jQuery.Event rather than the (read-only) native event -+ args[ 0 ] = event; -+ event.delegateTarget = this; -+ -+ // Call the preDispatch hook for the mapped type, and let it bail if desired -+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { -+ return; -+ } -+ -+ // Determine handlers -+ handlerQueue = jQuery.event.handlers.call( this, event, handlers ); -+ -+ // Run delegates first; they may want to stop propagation beneath us -+ i = 0; -+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { -+ event.currentTarget = matched.elem; -+ -+ j = 0; -+ while ( ( handleObj = matched.handlers[ j++ ] ) && -+ !event.isImmediatePropagationStopped() ) { -+ -+ // Triggered event must either 1) have no namespace, or 2) have namespace(s) -+ // a subset or equal to those in the bound event (both can have no namespace). -+ if ( !event.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, matches, sel, handleObj, -+ handlerQueue = [], -+ delegateCount = handlers.delegateCount, -+ cur = event.target; -+ -+ // Support (at least): Chrome, IE9 -+ // Find delegate handlers -+ // Black-hole SVG instance trees (#13180) -+ // -+ // Support: Firefox<=42+ -+ // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) -+ if ( delegateCount && cur.nodeType && -+ ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { -+ -+ /* jshint eqeqeq: false */ -+ for ( ; cur != this; cur = cur.parentNode || this ) { -+ /* jshint eqeqeq: true */ -+ -+ // Don't check non-elements (#13208) -+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) -+ if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { -+ matches = []; -+ for ( i = 0; i < delegateCount; i++ ) { -+ handleObj = handlers[ i ]; -+ -+ // Don't conflict with Object.prototype properties (#13203) -+ sel = handleObj.selector + " "; -+ -+ if ( matches[ sel ] === undefined ) { -+ matches[ sel ] = handleObj.needsContext ? -+ jQuery( sel, this ).index( cur ) > -1 : -+ jQuery.find( sel, this, null, [ cur ] ).length; -+ } -+ if ( matches[ sel ] ) { -+ matches.push( handleObj ); -+ } -+ } -+ if ( matches.length ) { -+ handlerQueue.push( { elem: cur, handlers: matches } ); -+ } -+ } -+ } -+ } -+ -+ // Add the remaining (directly-bound) handlers -+ if ( delegateCount < handlers.length ) { -+ handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); -+ } -+ -+ return handlerQueue; -+ }, -+ -+ fix: function( event ) { -+ if ( event[ jQuery.expando ] ) { -+ return event; -+ } -+ -+ // Create a writable copy of the event object and normalize some properties -+ var i, prop, copy, -+ type = event.type, -+ originalEvent = event, -+ fixHook = this.fixHooks[ type ]; -+ -+ if ( !fixHook ) { -+ this.fixHooks[ type ] = fixHook = -+ rmouseEvent.test( type ) ? this.mouseHooks : -+ rkeyEvent.test( type ) ? this.keyHooks : -+ {}; -+ } -+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; -+ -+ event = new jQuery.Event( originalEvent ); -+ -+ i = copy.length; -+ while ( i-- ) { -+ prop = copy[ i ]; -+ event[ prop ] = originalEvent[ prop ]; -+ } -+ -+ // Support: IE<9 -+ // Fix target property (#1925) -+ if ( !event.target ) { -+ event.target = originalEvent.srcElement || document; -+ } -+ -+ // Support: Safari 6-8+ -+ // Target should not be a text node (#504, #13143) -+ if ( event.target.nodeType === 3 ) { -+ event.target = event.target.parentNode; -+ } -+ -+ // Support: IE<9 -+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) -+ event.metaKey = !!event.metaKey; -+ -+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; -+ }, -+ -+ // Includes some event props shared by KeyEvent and MouseEvent -+ props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + -+ "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), -+ -+ fixHooks: {}, -+ -+ keyHooks: { -+ props: "char charCode key keyCode".split( " " ), -+ filter: function( event, original ) { -+ -+ // Add which for key events -+ if ( event.which == null ) { -+ event.which = original.charCode != null ? original.charCode : original.keyCode; -+ } -+ -+ return event; -+ } -+ }, -+ -+ mouseHooks: { -+ props: ( "button buttons clientX clientY fromElement offsetX offsetY " + -+ "pageX pageY screenX screenY toElement" ).split( " " ), -+ filter: function( event, original ) { -+ var body, eventDoc, doc, -+ button = original.button, -+ fromElement = original.fromElement; -+ -+ // Calculate pageX/Y if missing and clientX/Y available -+ if ( event.pageX == null && original.clientX != null ) { -+ eventDoc = event.target.ownerDocument || document; -+ doc = eventDoc.documentElement; -+ body = eventDoc.body; -+ -+ event.pageX = original.clientX + -+ ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - -+ ( doc && doc.clientLeft || body && body.clientLeft || 0 ); -+ event.pageY = original.clientY + -+ ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - -+ ( doc && doc.clientTop || body && body.clientTop || 0 ); -+ } -+ -+ // Add relatedTarget, if necessary -+ if ( !event.relatedTarget && fromElement ) { -+ event.relatedTarget = fromElement === event.target ? -+ original.toElement : -+ fromElement; -+ } -+ -+ // Add which for click: 1 === left; 2 === middle; 3 === right -+ // Note: button is not normalized, so don't use it -+ if ( !event.which && button !== undefined ) { -+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); -+ } -+ -+ return event; -+ } -+ }, -+ -+ special: { -+ load: { -+ -+ // Prevent triggered image.load events from bubbling to window.load -+ noBubble: true -+ }, -+ focus: { -+ -+ // Fire native event if possible so blur/focus sequence is correct -+ trigger: function() { -+ if ( this !== safeActiveElement() && this.focus ) { -+ try { -+ this.focus(); -+ return false; -+ } catch ( e ) { -+ -+ // Support: IE<9 -+ // If we error on focus to hidden element (#1486, #12518), -+ // let .trigger() run the handlers -+ } -+ } -+ }, -+ delegateType: "focusin" -+ }, -+ blur: { -+ trigger: function() { -+ if ( this === safeActiveElement() && this.blur ) { -+ this.blur(); -+ return false; -+ } -+ }, -+ delegateType: "focusout" -+ }, -+ click: { -+ -+ // For checkbox, fire native event so checked state will be right -+ trigger: function() { -+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { -+ this.click(); -+ return false; -+ } -+ }, -+ -+ // For cross-browser consistency, don't fire native .click() on links -+ _default: function( event ) { -+ return jQuery.nodeName( event.target, "a" ); -+ } -+ }, -+ -+ beforeunload: { -+ postDispatch: function( event ) { -+ -+ // Support: Firefox 20+ -+ // Firefox doesn't alert if the returnValue field is not set. -+ if ( event.result !== undefined && event.originalEvent ) { -+ event.originalEvent.returnValue = event.result; -+ } -+ } -+ } -+ }, -+ -+ // Piggyback on a donor event to simulate a different one -+ simulate: function( type, elem, event ) { -+ var e = jQuery.extend( -+ new jQuery.Event(), -+ event, -+ { -+ type: type, -+ isSimulated: true -+ -+ // Previously, `originalEvent: {}` was set here, so stopPropagation call -+ // would not be triggered on donor event, since in our own -+ // jQuery.event.stopPropagation function we had a check for existence of -+ // originalEvent.stopPropagation method, so, consequently it would be a noop. -+ // -+ // Guard for simulated events was moved to jQuery.event.stopPropagation function -+ // since `originalEvent` should point to the original event for the -+ // constancy with other events and for more focused logic -+ } -+ ); -+ -+ jQuery.event.trigger( e, null, elem ); -+ -+ if ( e.isDefaultPrevented() ) { -+ event.preventDefault(); -+ } -+ } -+}; -+ -+jQuery.removeEvent = document.removeEventListener ? -+ function( elem, type, handle ) { -+ -+ // This "if" is needed for plain objects -+ if ( elem.removeEventListener ) { -+ elem.removeEventListener( type, handle ); -+ } -+ } : -+ function( elem, type, handle ) { -+ var name = "on" + type; -+ -+ if ( elem.detachEvent ) { -+ -+ // #8545, #7054, preventing memory leaks for custom events in IE6-8 -+ // detachEvent needed property on element, by name of that event, -+ // to properly expose it to GC -+ if ( typeof elem[ name ] === "undefined" ) { -+ elem[ name ] = null; -+ } -+ -+ elem.detachEvent( name, handle ); -+ } -+ }; -+ -+jQuery.Event = function( src, props ) { -+ -+ // Allow instantiation without the 'new' keyword -+ if ( !( this instanceof jQuery.Event ) ) { -+ return new jQuery.Event( src, props ); -+ } -+ -+ // Event object -+ if ( src && src.type ) { -+ this.originalEvent = src; -+ this.type = src.type; -+ -+ // Events bubbling up the document may have been marked as prevented -+ // by a handler lower down the tree; reflect the correct value. -+ this.isDefaultPrevented = src.defaultPrevented || -+ src.defaultPrevented === undefined && -+ -+ // Support: IE < 9, Android < 4.0 -+ src.returnValue === false ? -+ returnTrue : -+ returnFalse; -+ -+ // Event type -+ } else { -+ this.type = src; -+ } -+ -+ // Put explicitly provided properties onto the event object -+ if ( props ) { -+ jQuery.extend( this, props ); -+ } -+ -+ // Create a timestamp if incoming event doesn't have one -+ this.timeStamp = src && src.timeStamp || jQuery.now(); -+ -+ // Mark it as fixed -+ this[ jQuery.expando ] = true; -+}; -+ -+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -+jQuery.Event.prototype = { -+ constructor: jQuery.Event, -+ isDefaultPrevented: returnFalse, -+ isPropagationStopped: returnFalse, -+ isImmediatePropagationStopped: returnFalse, -+ -+ preventDefault: function() { -+ var e = this.originalEvent; -+ -+ this.isDefaultPrevented = returnTrue; -+ if ( !e ) { -+ return; -+ } -+ -+ // If preventDefault exists, run it on the original event -+ if ( e.preventDefault ) { -+ e.preventDefault(); -+ -+ // Support: IE -+ // Otherwise set the returnValue property of the original event to false -+ } else { -+ e.returnValue = false; -+ } -+ }, -+ stopPropagation: function() { -+ var e = this.originalEvent; -+ -+ this.isPropagationStopped = returnTrue; -+ -+ if ( !e || this.isSimulated ) { -+ return; -+ } -+ -+ // If stopPropagation exists, run it on the original event -+ if ( e.stopPropagation ) { -+ e.stopPropagation(); -+ } -+ -+ // Support: IE -+ // Set the cancelBubble property of the original event to true -+ e.cancelBubble = true; -+ }, -+ stopImmediatePropagation: function() { -+ var e = this.originalEvent; -+ -+ this.isImmediatePropagationStopped = returnTrue; -+ -+ if ( e && e.stopImmediatePropagation ) { -+ e.stopImmediatePropagation(); -+ } -+ -+ this.stopPropagation(); -+ } -+}; -+ -+// Create mouseenter/leave events using mouseover/out and event-time checks -+// 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://code.google.com/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; -+ } -+ }; -+} ); -+ -+// IE submit delegation -+if ( !support.submit ) { -+ -+ jQuery.event.special.submit = { -+ setup: function() { -+ -+ // Only need this for delegated form submit events -+ if ( jQuery.nodeName( this, "form" ) ) { -+ return false; -+ } -+ -+ // Lazy-add a submit handler when a descendant form may potentially be submitted -+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) { -+ -+ // Node name check avoids a VML-related crash in IE (#9807) -+ var elem = e.target, -+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? -+ -+ // Support: IE <=8 -+ // We use jQuery.prop instead of elem.form -+ // to allow fixing the IE8 delegated submit issue (gh-2332) -+ // by 3rd party polyfills/workarounds. -+ jQuery.prop( elem, "form" ) : -+ undefined; -+ -+ if ( form && !jQuery._data( form, "submit" ) ) { -+ jQuery.event.add( form, "submit._submit", function( event ) { -+ event._submitBubble = true; -+ } ); -+ jQuery._data( form, "submit", true ); -+ } -+ } ); -+ -+ // return undefined since we don't need an event listener -+ }, -+ -+ postDispatch: function( event ) { -+ -+ // If form was submitted by the user, bubble the event up the tree -+ if ( event._submitBubble ) { -+ delete event._submitBubble; -+ if ( this.parentNode && !event.isTrigger ) { -+ jQuery.event.simulate( "submit", this.parentNode, event ); -+ } -+ } -+ }, -+ -+ teardown: function() { -+ -+ // Only need this for delegated form submit events -+ if ( jQuery.nodeName( this, "form" ) ) { -+ return false; -+ } -+ -+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above -+ jQuery.event.remove( this, "._submit" ); -+ } -+ }; -+} -+ -+// IE change delegation and checkbox/radio fix -+if ( !support.change ) { -+ -+ jQuery.event.special.change = { -+ -+ setup: function() { -+ -+ if ( rformElems.test( this.nodeName ) ) { -+ -+ // IE doesn't fire change on a check/radio until blur; trigger it on click -+ // after a propertychange. Eat the blur-change in special.change.handle. -+ // This still fires onchange a second time for check/radio after blur. -+ if ( this.type === "checkbox" || this.type === "radio" ) { -+ jQuery.event.add( this, "propertychange._change", function( event ) { -+ if ( event.originalEvent.propertyName === "checked" ) { -+ this._justChanged = true; -+ } -+ } ); -+ jQuery.event.add( this, "click._change", function( event ) { -+ if ( this._justChanged && !event.isTrigger ) { -+ this._justChanged = false; -+ } -+ -+ // Allow triggered, simulated change events (#11500) -+ jQuery.event.simulate( "change", this, event ); -+ } ); -+ } -+ return false; -+ } -+ -+ // Delegated event; lazy-add a change handler on descendant inputs -+ jQuery.event.add( this, "beforeactivate._change", function( e ) { -+ var elem = e.target; -+ -+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { -+ jQuery.event.add( elem, "change._change", function( event ) { -+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { -+ jQuery.event.simulate( "change", this.parentNode, event ); -+ } -+ } ); -+ jQuery._data( elem, "change", true ); -+ } -+ } ); -+ }, -+ -+ handle: function( event ) { -+ var elem = event.target; -+ -+ // Swallow native change events from checkbox/radio, we already triggered them above -+ if ( this !== elem || event.isSimulated || event.isTrigger || -+ ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { -+ -+ return event.handleObj.handler.apply( this, arguments ); -+ } -+ }, -+ -+ teardown: function() { -+ jQuery.event.remove( this, "._change" ); -+ -+ return !rformElems.test( this.nodeName ); -+ } -+ }; -+} -+ -+// Support: Firefox -+// Firefox doesn't have focus(in | out) events -+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -+// -+// Support: Chrome, Safari -+// focus(in | out) events fire after focus & blur events, -+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -+// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 -+if ( !support.focusin ) { -+ jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { -+ -+ // Attach a single capturing handler on the document while someone wants focusin/focusout -+ var handler = function( event ) { -+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); -+ }; -+ -+ jQuery.event.special[ fix ] = { -+ setup: function() { -+ var doc = this.ownerDocument || this, -+ attaches = jQuery._data( doc, fix ); -+ -+ if ( !attaches ) { -+ doc.addEventListener( orig, handler, true ); -+ } -+ jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); -+ }, -+ teardown: function() { -+ var doc = this.ownerDocument || this, -+ attaches = jQuery._data( doc, fix ) - 1; -+ -+ if ( !attaches ) { -+ doc.removeEventListener( orig, handler, true ); -+ jQuery._removeData( doc, fix ); -+ } else { -+ jQuery._data( doc, fix, attaches ); -+ } -+ } -+ }; -+ } ); -+} -+ -+jQuery.fn.extend( { -+ -+ on: function( types, selector, data, fn ) { -+ 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 ); -+ } ); -+ }, -+ -+ trigger: function( type, data ) { -+ return this.each( function() { -+ jQuery.event.trigger( type, data, this ); -+ } ); -+ }, -+ triggerHandler: function( type, data ) { -+ var elem = this[ 0 ]; -+ if ( elem ) { -+ return jQuery.event.trigger( type, data, elem, true ); -+ } -+ } -+} ); -+ -+ -+var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, -+ rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), -+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, -+ -+ // Support: IE 10-11, Edge 10240+ -+ // In IE/Edge using regex groups here causes severe slowdowns. -+ // See https://connect.microsoft.com/IE/feedback/details/1736512/ -+ rnoInnerhtml = /\s*$/g, -+ safeFragment = createSafeFragment( document ), -+ fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); -+ -+// Support: IE<8 -+// Manipulating tables requires a tbody -+function manipulationTarget( elem, content ) { -+ return jQuery.nodeName( elem, "table" ) && -+ jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? -+ -+ elem.getElementsByTagName( "tbody" )[ 0 ] || -+ elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : -+ elem; -+} -+ -+// Replace/restore the type attribute of script elements for safe DOM manipulation -+function disableScript( elem ) { -+ elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; -+ return elem; -+} -+function restoreScript( elem ) { -+ var match = rscriptTypeMasked.exec( elem.type ); -+ if ( match ) { -+ elem.type = match[ 1 ]; -+ } else { -+ elem.removeAttribute( "type" ); -+ } -+ return elem; -+} -+ -+function cloneCopyEvent( src, dest ) { -+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { -+ return; -+ } -+ -+ var type, i, l, -+ oldData = jQuery._data( src ), -+ curData = jQuery._data( dest, oldData ), -+ events = oldData.events; -+ -+ if ( events ) { -+ delete curData.handle; -+ curData.events = {}; -+ -+ for ( type in events ) { -+ for ( i = 0, l = events[ type ].length; i < l; i++ ) { -+ jQuery.event.add( dest, type, events[ type ][ i ] ); -+ } -+ } -+ } -+ -+ // make the cloned public data object a copy from the original -+ if ( curData.data ) { -+ curData.data = jQuery.extend( {}, curData.data ); -+ } -+} -+ -+function fixCloneNodeIssues( src, dest ) { -+ var nodeName, e, data; -+ -+ // We do not need to do anything for non-Elements -+ if ( dest.nodeType !== 1 ) { -+ return; -+ } -+ -+ nodeName = dest.nodeName.toLowerCase(); -+ -+ // IE6-8 copies events bound via attachEvent when using cloneNode. -+ if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { -+ data = jQuery._data( dest ); -+ -+ for ( e in data.events ) { -+ jQuery.removeEvent( dest, e, data.handle ); -+ } -+ -+ // Event data gets referenced instead of copied if the expando gets copied too -+ dest.removeAttribute( jQuery.expando ); -+ } -+ -+ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text -+ if ( nodeName === "script" && dest.text !== src.text ) { -+ disableScript( dest ).text = src.text; -+ restoreScript( dest ); -+ -+ // IE6-10 improperly clones children of object elements using classid. -+ // IE10 throws NoModificationAllowedError if parent is null, #12132. -+ } else if ( nodeName === "object" ) { -+ if ( dest.parentNode ) { -+ dest.outerHTML = src.outerHTML; -+ } -+ -+ // This path appears unavoidable for IE9. When cloning an object -+ // element in IE9, the outerHTML strategy above is not sufficient. -+ // If the src has innerHTML and the destination does not, -+ // copy the src.innerHTML into the dest.innerHTML. #10324 -+ if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { -+ dest.innerHTML = src.innerHTML; -+ } -+ -+ } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { -+ -+ // IE6-8 fails to persist the checked state of a cloned checkbox -+ // or radio button. Worse, IE6-7 fail to give the cloned element -+ // a checked appearance if the defaultChecked value isn't also set -+ -+ dest.defaultChecked = dest.checked = src.checked; -+ -+ // IE6-7 get confused and end up setting the value of a cloned -+ // checkbox/radio button to an empty string instead of "on" -+ if ( dest.value !== src.value ) { -+ dest.value = src.value; -+ } -+ -+ // IE6-8 fails to return the selected option to the default selected -+ // state when cloning options -+ } else if ( nodeName === "option" ) { -+ dest.defaultSelected = dest.selected = src.defaultSelected; -+ -+ // IE6-8 fails to set the defaultValue to the correct value when -+ // cloning other types of input fields -+ } else if ( nodeName === "input" || nodeName === "textarea" ) { -+ dest.defaultValue = src.defaultValue; -+ } -+} -+ -+function domManip( collection, args, callback, ignored ) { -+ -+ // Flatten any nested arrays -+ args = concat.apply( [], args ); -+ -+ var first, node, hasScripts, -+ scripts, doc, fragment, -+ i = 0, -+ l = collection.length, -+ iNoClone = l - 1, -+ value = args[ 0 ], -+ isFunction = jQuery.isFunction( value ); -+ -+ // We can't cloneNode fragments that contain checked, in WebKit -+ if ( isFunction || -+ ( l > 1 && typeof value === "string" && -+ !support.checkClone && rchecked.test( value ) ) ) { -+ return collection.each( function( index ) { -+ var self = collection.eq( index ); -+ if ( isFunction ) { -+ args[ 0 ] = value.call( this, index, self.html() ); -+ } -+ domManip( self, args, callback, ignored ); -+ } ); -+ } -+ -+ if ( l ) { -+ fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); -+ first = fragment.firstChild; -+ -+ if ( fragment.childNodes.length === 1 ) { -+ fragment = first; -+ } -+ -+ // Require either new content or an interest in ignored elements to invoke the callback -+ if ( first || ignored ) { -+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); -+ hasScripts = scripts.length; -+ -+ // Use the original fragment for the last item -+ // instead of the first because it can end up -+ // being emptied incorrectly in certain situations (#8070). -+ for ( ; i < l; i++ ) { -+ node = fragment; -+ -+ if ( i !== iNoClone ) { -+ node = jQuery.clone( node, true, true ); -+ -+ // Keep references to cloned scripts for later restoration -+ if ( hasScripts ) { -+ -+ // Support: Android<4.1, PhantomJS<2 -+ // push.apply(_, arraylike) throws on ancient WebKit -+ jQuery.merge( scripts, getAll( node, "script" ) ); -+ } -+ } -+ -+ callback.call( collection[ i ], node, i ); -+ } -+ -+ if ( hasScripts ) { -+ doc = scripts[ scripts.length - 1 ].ownerDocument; -+ -+ // Reenable scripts -+ jQuery.map( scripts, restoreScript ); -+ -+ // Evaluate executable scripts on first document insertion -+ for ( i = 0; i < hasScripts; i++ ) { -+ node = scripts[ i ]; -+ if ( rscriptType.test( node.type || "" ) && -+ !jQuery._data( node, "globalEval" ) && -+ jQuery.contains( doc, node ) ) { -+ -+ if ( node.src ) { -+ -+ // Optional AJAX dependency, but won't run scripts if not present -+ if ( jQuery._evalUrl ) { -+ jQuery._evalUrl( node.src ); -+ } -+ } else { -+ jQuery.globalEval( -+ ( node.text || node.textContent || node.innerHTML || "" ) -+ .replace( rcleanScript, "" ) -+ ); -+ } -+ } -+ } -+ } -+ -+ // Fix #11809: Avoid leaking memory -+ fragment = first = null; -+ } -+ } -+ -+ return collection; -+} -+ -+function remove( elem, selector, keepData ) { -+ var node, -+ elems = selector ? jQuery.filter( selector, elem ) : elem, -+ i = 0; -+ -+ for ( ; ( node = elems[ i ] ) != null; i++ ) { -+ -+ if ( !keepData && node.nodeType === 1 ) { -+ jQuery.cleanData( getAll( node ) ); -+ } -+ -+ if ( node.parentNode ) { -+ if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { -+ setGlobalEval( getAll( node, "script" ) ); -+ } -+ node.parentNode.removeChild( node ); -+ } -+ } -+ -+ return elem; -+} -+ -+jQuery.extend( { -+ htmlPrefilter: function( html ) { -+ return html.replace( rxhtmlTag, "<$1>" ); -+ }, -+ -+ clone: function( elem, dataAndEvents, deepDataAndEvents ) { -+ var destElements, node, clone, i, srcElements, -+ inPage = jQuery.contains( elem.ownerDocument, elem ); -+ -+ if ( support.html5Clone || jQuery.isXMLDoc( elem ) || -+ !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { -+ -+ clone = elem.cloneNode( true ); -+ -+ // IE<=8 does not properly clone detached, unknown element nodes -+ } else { -+ fragmentDiv.innerHTML = elem.outerHTML; -+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); -+ } -+ -+ if ( ( !support.noCloneEvent || !support.noCloneChecked ) && -+ ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { -+ -+ // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 -+ destElements = getAll( clone ); -+ srcElements = getAll( elem ); -+ -+ // Fix all IE cloning issues -+ for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { -+ -+ // Ensure that the destination node is not null; Fixes #9587 -+ if ( destElements[ i ] ) { -+ fixCloneNodeIssues( node, destElements[ i ] ); -+ } -+ } -+ } -+ -+ // Copy the events from the original to the clone -+ if ( dataAndEvents ) { -+ if ( deepDataAndEvents ) { -+ srcElements = srcElements || getAll( elem ); -+ destElements = destElements || getAll( clone ); -+ -+ for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { -+ cloneCopyEvent( node, destElements[ i ] ); -+ } -+ } else { -+ cloneCopyEvent( elem, clone ); -+ } -+ } -+ -+ // Preserve script evaluation history -+ destElements = getAll( clone, "script" ); -+ if ( destElements.length > 0 ) { -+ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); -+ } -+ -+ destElements = srcElements = node = null; -+ -+ // Return the cloned set -+ return clone; -+ }, -+ -+ cleanData: function( elems, /* internal */ forceAcceptData ) { -+ var elem, type, id, data, -+ i = 0, -+ internalKey = jQuery.expando, -+ cache = jQuery.cache, -+ attributes = support.attributes, -+ special = jQuery.event.special; -+ -+ for ( ; ( elem = elems[ i ] ) != null; i++ ) { -+ if ( forceAcceptData || acceptData( elem ) ) { -+ -+ id = elem[ internalKey ]; -+ data = id && cache[ id ]; -+ -+ if ( data ) { -+ if ( data.events ) { -+ for ( type in data.events ) { -+ if ( special[ type ] ) { -+ jQuery.event.remove( elem, type ); -+ -+ // This is a shortcut to avoid jQuery.event.remove's overhead -+ } else { -+ jQuery.removeEvent( elem, type, data.handle ); -+ } -+ } -+ } -+ -+ // Remove cache only if it was not already removed by jQuery.event.remove -+ if ( cache[ id ] ) { -+ -+ delete cache[ id ]; -+ -+ // Support: IE<9 -+ // IE does not allow us to delete expando properties from nodes -+ // IE creates expando attributes along with the property -+ // IE does not have a removeAttribute function on Document nodes -+ if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { -+ elem.removeAttribute( internalKey ); -+ -+ // Webkit & Blink performance suffers when deleting properties -+ // from DOM nodes, so set to undefined instead -+ // https://code.google.com/p/chromium/issues/detail?id=378607 -+ } else { -+ elem[ internalKey ] = undefined; -+ } -+ -+ deletedIds.push( id ); -+ } -+ } -+ } -+ } -+ } -+} ); -+ -+jQuery.fn.extend( { -+ -+ // Keep domManip exposed until 3.0 (gh-2225) -+ domManip: domManip, -+ -+ detach: function( selector ) { -+ return remove( this, selector, true ); -+ }, -+ -+ remove: function( selector ) { -+ return remove( this, selector ); -+ }, -+ -+ text: function( value ) { -+ return access( this, function( value ) { -+ return value === undefined ? -+ jQuery.text( this ) : -+ this.empty().append( -+ ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) -+ ); -+ }, null, value, arguments.length ); -+ }, -+ -+ append: function() { -+ return domManip( this, arguments, function( elem ) { -+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { -+ var target = manipulationTarget( this, elem ); -+ target.appendChild( elem ); -+ } -+ } ); -+ }, -+ -+ prepend: function() { -+ return domManip( this, arguments, function( elem ) { -+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { -+ var target = manipulationTarget( this, elem ); -+ target.insertBefore( elem, target.firstChild ); -+ } -+ } ); -+ }, -+ -+ before: function() { -+ return domManip( this, arguments, function( elem ) { -+ if ( this.parentNode ) { -+ this.parentNode.insertBefore( elem, this ); -+ } -+ } ); -+ }, -+ -+ after: function() { -+ return domManip( this, arguments, function( elem ) { -+ if ( this.parentNode ) { -+ this.parentNode.insertBefore( elem, this.nextSibling ); -+ } -+ } ); -+ }, -+ -+ empty: function() { -+ var elem, -+ i = 0; -+ -+ for ( ; ( elem = this[ i ] ) != null; i++ ) { -+ -+ // Remove element nodes and prevent memory leaks -+ if ( elem.nodeType === 1 ) { -+ jQuery.cleanData( getAll( elem, false ) ); -+ } -+ -+ // Remove any remaining nodes -+ while ( elem.firstChild ) { -+ elem.removeChild( elem.firstChild ); -+ } -+ -+ // If this is a select, ensure that it displays empty (#12336) -+ // Support: IE<9 -+ if ( elem.options && jQuery.nodeName( elem, "select" ) ) { -+ elem.options.length = 0; -+ } -+ } -+ -+ return this; -+ }, -+ -+ clone: function( dataAndEvents, deepDataAndEvents ) { -+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents; -+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; -+ -+ return this.map( function() { -+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); -+ } ); -+ }, -+ -+ html: function( value ) { -+ return access( this, function( value ) { -+ var elem = this[ 0 ] || {}, -+ i = 0, -+ l = this.length; -+ -+ if ( value === undefined ) { -+ return elem.nodeType === 1 ? -+ elem.innerHTML.replace( rinlinejQuery, "" ) : -+ undefined; -+ } -+ -+ // See if we can take a shortcut and just use innerHTML -+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) && -+ ( support.htmlSerialize || !rnoshimcache.test( value ) ) && -+ ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && -+ !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { -+ -+ value = jQuery.htmlPrefilter( value ); -+ -+ try { -+ for ( ; i < l; i++ ) { -+ -+ // Remove element nodes and prevent memory leaks -+ elem = this[ i ] || {}; -+ if ( elem.nodeType === 1 ) { -+ jQuery.cleanData( getAll( elem, false ) ); -+ elem.innerHTML = value; -+ } -+ } -+ -+ elem = 0; -+ -+ // If using innerHTML throws an exception, use the fallback method -+ } catch ( e ) {} -+ } -+ -+ if ( elem ) { -+ this.empty().append( value ); -+ } -+ }, null, value, arguments.length ); -+ }, -+ -+ replaceWith: function() { -+ var ignored = []; -+ -+ // Make the changes, replacing each non-ignored context element with the new content -+ return domManip( this, arguments, function( elem ) { -+ var parent = this.parentNode; -+ -+ if ( jQuery.inArray( this, ignored ) < 0 ) { -+ jQuery.cleanData( getAll( this ) ); -+ if ( parent ) { -+ parent.replaceChild( elem, this ); -+ } -+ } -+ -+ // Force callback invocation -+ }, ignored ); -+ } -+} ); -+ -+jQuery.each( { -+ appendTo: "append", -+ prependTo: "prepend", -+ insertBefore: "before", -+ insertAfter: "after", -+ replaceAll: "replaceWith" -+}, function( name, original ) { -+ jQuery.fn[ name ] = function( selector ) { -+ var elems, -+ i = 0, -+ ret = [], -+ insert = jQuery( selector ), -+ last = insert.length - 1; -+ -+ for ( ; i <= last; i++ ) { -+ elems = i === last ? this : this.clone( true ); -+ jQuery( insert[ i ] )[ original ]( elems ); -+ -+ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() -+ push.apply( ret, elems.get() ); -+ } -+ -+ return this.pushStack( ret ); -+ }; -+} ); -+ -+ -+var iframe, -+ elemdisplay = { -+ -+ // Support: Firefox -+ // We have to pre-define these values for FF (#10227) -+ HTML: "block", -+ BODY: "block" -+ }; -+ -+/** -+ * Retrieve the actual display of a element -+ * @param {String} name nodeName of the element -+ * @param {Object} doc Document object -+ */ -+ -+// Called only from within defaultDisplay -+function actualDisplay( name, doc ) { -+ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), -+ -+ display = jQuery.css( elem[ 0 ], "display" ); -+ -+ // We don't have any data stored on the element, -+ // so use "detach" method as fast way to get rid of the element -+ elem.detach(); -+ -+ return display; -+} -+ -+/** -+ * Try to determine the default display value of an element -+ * @param {String} nodeName -+ */ -+function defaultDisplay( nodeName ) { -+ var doc = document, -+ display = elemdisplay[ nodeName ]; -+ -+ if ( !display ) { -+ display = actualDisplay( nodeName, doc ); -+ -+ // If the simple way fails, read from inside an iframe -+ if ( display === "none" || !display ) { -+ -+ // Use the already-created iframe if possible -+ iframe = ( iframe || jQuery( "