From 335b2c0380bed2fc27d4d73adce4c576a262aed2 Mon Sep 17 00:00:00 2001 From: lzh <52725224+Yourdaylight@users.noreply.github.com> Date: Tue, 4 Aug 2020 10:48:15 +0800 Subject: [PATCH] update studentmanagement --- 2016-course-DB-master/Lib/.idea/Lib.iml | 32 + .../Lib/.idea/dataSources.local.xml | 13 + .../Lib/.idea/dataSources.xml | 16 + .../c4e431f8-0777-4d22-ab99-4a988603b107.xml | 782 ++ 2016-course-DB-master/Lib/.idea/misc.xml | 7 + 2016-course-DB-master/Lib/.idea/modules.xml | 8 + 2016-course-DB-master/Lib/.idea/vcs.xml | 6 + 2016-course-DB-master/Lib/.idea/workspace.xml | 353 + 2016-course-DB-master/Lib/Lib/__init__.py | 0 2016-course-DB-master/Lib/Lib/settings.py | 116 + 2016-course-DB-master/Lib/Lib/urls.py | 23 + 2016-course-DB-master/Lib/Lib/wsgi.py | 14 + 2016-course-DB-master/Lib/db.sqlite3 | Bin 0 -> 80896 bytes 2016-course-DB-master/Lib/main/__init__.py | 0 2016-course-DB-master/Lib/main/admin.py | 12 + .../Lib/main/migrations/0001_initial.py | 127 + .../Lib/main/migrations/__init__.py | 0 2016-course-DB-master/Lib/main/models.py | 58 + .../Lib/main/static/css/indexStaff.css | 209 + .../Lib/main/static/css/library.css | 169 + .../Lib/main/static/css/login.css | 54 + .../Lib/main/static/css/logout.css | 14 + .../Lib/main/static/css/regist.css | 54 + .../Lib/main/static/css/userDetail.css | 107 + .../Lib/main/static/scripts/csrf.js | 36 + .../Lib/main/static/scripts/indexStaff.js | 182 + .../Lib/main/static/scripts/jquery.js | 10074 ++++++++++++++++ .../Lib/main/static/scripts/library.js | 20 + .../Lib/main/static/scripts/userDetail.js | 0 .../Lib/main/templates/indexStaff.html | 139 + .../Lib/main/templates/library.html | 88 + .../Lib/main/templates/login.html | 32 + .../Lib/main/templates/logout.html | 18 + .../Lib/main/templates/regist.html | 37 + .../Lib/main/templates/userDetail.html | 72 + 2016-course-DB-master/Lib/main/tests.py | 3 + 2016-course-DB-master/Lib/main/views.py | 451 + 2016-course-DB-master/Lib/manage.py | 10 + ChatSystem聊天系统/.idea/workspace.xml | 460 + StudentSystem-master/.gitignore | 3 + StudentSystem-master/README.md | 12 + StudentSystem-master/StudentSystem/.gitignore | 5 + .../StudentSystem/StudentSystem/__init__.py | 0 .../StudentSystem/StudentSystem/settings.py | 131 + .../StudentSystem/StudentSystem/urls.py | 25 + .../StudentSystem/StudentSystem/wsgi.py | 16 + StudentSystem-master/StudentSystem/manage.py | 15 + .../studentManagement/__init__.py | 0 .../StudentSystem/studentManagement/admin.py | 31 + .../StudentSystem/studentManagement/apps.py | 5 + .../migrations/0001_initial.py | 52 + .../studentManagement/migrations/__init__.py | 0 .../StudentSystem/studentManagement/models.py | 34 + .../StudentSystem/studentManagement/tests.py | 3 + .../StudentSystem/studentManagement/urls.py | 15 + .../templates/studentManage/add.html | 29 + .../templates/studentManage/delete.html | 18 + .../templates/studentManage/index.html | 22 + .../templates/studentManage/login.html | 16 + .../templates/studentManage/select.html | 33 + .../templates/studentManage/update.html | 23 + 61 files changed, 14284 insertions(+) create mode 100644 2016-course-DB-master/Lib/.idea/Lib.iml create mode 100644 2016-course-DB-master/Lib/.idea/dataSources.local.xml create mode 100644 2016-course-DB-master/Lib/.idea/dataSources.xml create mode 100644 2016-course-DB-master/Lib/.idea/dataSources/c4e431f8-0777-4d22-ab99-4a988603b107.xml create mode 100644 2016-course-DB-master/Lib/.idea/misc.xml create mode 100644 2016-course-DB-master/Lib/.idea/modules.xml create mode 100644 2016-course-DB-master/Lib/.idea/vcs.xml create mode 100644 2016-course-DB-master/Lib/.idea/workspace.xml create mode 100644 2016-course-DB-master/Lib/Lib/__init__.py create mode 100644 2016-course-DB-master/Lib/Lib/settings.py create mode 100644 2016-course-DB-master/Lib/Lib/urls.py create mode 100644 2016-course-DB-master/Lib/Lib/wsgi.py create mode 100644 2016-course-DB-master/Lib/db.sqlite3 create mode 100644 2016-course-DB-master/Lib/main/__init__.py create mode 100644 2016-course-DB-master/Lib/main/admin.py create mode 100644 2016-course-DB-master/Lib/main/migrations/0001_initial.py create mode 100644 2016-course-DB-master/Lib/main/migrations/__init__.py create mode 100644 2016-course-DB-master/Lib/main/models.py create mode 100644 2016-course-DB-master/Lib/main/static/css/indexStaff.css create mode 100644 2016-course-DB-master/Lib/main/static/css/library.css create mode 100644 2016-course-DB-master/Lib/main/static/css/login.css create mode 100644 2016-course-DB-master/Lib/main/static/css/logout.css create mode 100644 2016-course-DB-master/Lib/main/static/css/regist.css create mode 100644 2016-course-DB-master/Lib/main/static/css/userDetail.css create mode 100644 2016-course-DB-master/Lib/main/static/scripts/csrf.js create mode 100644 2016-course-DB-master/Lib/main/static/scripts/indexStaff.js create mode 100644 2016-course-DB-master/Lib/main/static/scripts/jquery.js create mode 100644 2016-course-DB-master/Lib/main/static/scripts/library.js create mode 100644 2016-course-DB-master/Lib/main/static/scripts/userDetail.js create mode 100644 2016-course-DB-master/Lib/main/templates/indexStaff.html create mode 100644 2016-course-DB-master/Lib/main/templates/library.html create mode 100644 2016-course-DB-master/Lib/main/templates/login.html create mode 100644 2016-course-DB-master/Lib/main/templates/logout.html create mode 100644 2016-course-DB-master/Lib/main/templates/regist.html create mode 100644 2016-course-DB-master/Lib/main/templates/userDetail.html create mode 100644 2016-course-DB-master/Lib/main/tests.py create mode 100644 2016-course-DB-master/Lib/main/views.py create mode 100644 2016-course-DB-master/Lib/manage.py create mode 100644 ChatSystem聊天系统/.idea/workspace.xml create mode 100644 StudentSystem-master/.gitignore create mode 100644 StudentSystem-master/README.md create mode 100644 StudentSystem-master/StudentSystem/.gitignore create mode 100644 StudentSystem-master/StudentSystem/StudentSystem/__init__.py create mode 100644 StudentSystem-master/StudentSystem/StudentSystem/settings.py create mode 100644 StudentSystem-master/StudentSystem/StudentSystem/urls.py create mode 100644 StudentSystem-master/StudentSystem/StudentSystem/wsgi.py create mode 100644 StudentSystem-master/StudentSystem/manage.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/__init__.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/admin.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/apps.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/migrations/0001_initial.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/migrations/__init__.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/models.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/tests.py create mode 100644 StudentSystem-master/StudentSystem/studentManagement/urls.py create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/add.html create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/delete.html create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/index.html create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/login.html create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/select.html create mode 100644 StudentSystem-master/StudentSystem/templates/studentManage/update.html diff --git a/2016-course-DB-master/Lib/.idea/Lib.iml b/2016-course-DB-master/Lib/.idea/Lib.iml new file mode 100644 index 0000000..c416296 --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/Lib.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/dataSources.local.xml b/2016-course-DB-master/Lib/.idea/dataSources.local.xml new file mode 100644 index 0000000..09430b7 --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/dataSources.local.xml @@ -0,0 +1,13 @@ + + + + + + " + + + false + *:@ + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/dataSources.xml b/2016-course-DB-master/Lib/.idea/dataSources.xml new file mode 100644 index 0000000..f3fc86d --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/dataSources.xml @@ -0,0 +1,16 @@ + + + + + sqlite.xerial + true + true + $PROJECT_DIR$/Lib/settings.py + org.sqlite.JDBC + jdbc:sqlite:E:\study\项目\Django-Projects\2016-course-DB-master\Lib\db.sqlite3 + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/dataSources/c4e431f8-0777-4d22-ab99-4a988603b107.xml b/2016-course-DB-master/Lib/.idea/dataSources/c4e431f8-0777-4d22-ab99-4a988603b107.xml new file mode 100644 index 0000000..8cfd954 --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/dataSources/c4e431f8-0777-4d22-ab99-4a988603b107.xml @@ -0,0 +1,782 @@ + + + + + 3.25.1 + + + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 1 + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(80)|0s + 1 + + + 1 + name + + 1 + + + id + 1 + + + name + sqlite_autoindex_auth_group_1 + + + 1 + integer|0s + 1 + 1 + + + 2 + integer|0s + 1 + + + 3 + integer|0s + 1 + + + 1 + group_id +permission_id + + 1 + + + group_id + + + + permission_id + + + + id + 1 + + + group_id +permission_id + sqlite_autoindex_auth_group_permissions_1 + + + group_id + auth_group + id + + + permission_id + auth_permission + id + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(50)|0s + 1 + + + 3 + integer|0s + 1 + + + 4 + varchar(100)|0s + 1 + + + 1 + content_type_id +codename + + 1 + + + content_type_id + + + + id + 1 + + + content_type_id +codename + sqlite_autoindex_auth_permission_1 + + + content_type_id + django_content_type + id + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(128)|0s + 1 + + + 3 + datetime|0s + 1 + + + 4 + bool|0s + 1 + + + 5 + varchar(30)|0s + 1 + + + 6 + varchar(30)|0s + 1 + + + 7 + varchar(30)|0s + 1 + + + 8 + varchar(75)|0s + 1 + + + 9 + bool|0s + 1 + + + 10 + bool|0s + 1 + + + 11 + datetime|0s + 1 + + + 1 + username + + 1 + + + id + 1 + + + username + sqlite_autoindex_auth_user_1 + + + 1 + integer|0s + 1 + 1 + + + 2 + integer|0s + 1 + + + 3 + integer|0s + 1 + + + 1 + user_id +group_id + + 1 + + + user_id + + + + group_id + + + + id + 1 + + + user_id +group_id + sqlite_autoindex_auth_user_groups_1 + + + user_id + auth_user + id + + + group_id + auth_group + id + + + 1 + integer|0s + 1 + 1 + + + 2 + integer|0s + 1 + + + 3 + integer|0s + 1 + + + 1 + user_id +permission_id + + 1 + + + user_id + + + + permission_id + + + + id + 1 + + + user_id +permission_id + sqlite_autoindex_auth_user_user_permissions_1 + + + user_id + auth_user + id + + + permission_id + auth_permission + id + + + 1 + integer|0s + 1 + 1 + + + 2 + datetime|0s + 1 + + + 3 + text|0s + + + 4 + varchar(200)|0s + 1 + + + 5 + smallint unsigned|0s + 1 + + + 6 + text|0s + 1 + + + 7 + integer|0s + + + 8 + integer|0s + 1 + + + content_type_id + + + + user_id + + + + id + 1 + + + content_type_id + django_content_type + id + + + user_id + auth_user + id + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(100)|0s + 1 + + + 3 + varchar(100)|0s + 1 + + + 4 + varchar(100)|0s + 1 + + + 1 + app_label +model + + 1 + + + id + 1 + + + app_label +model + sqlite_autoindex_django_content_type_1 + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(255)|0s + 1 + + + 3 + varchar(255)|0s + 1 + + + 4 + datetime|0s + 1 + + + id + 1 + + + 1 + varchar(40)|0s + 1 + + + 2 + text|0s + 1 + + + 3 + datetime|0s + 1 + + + 1 + session_key + + 1 + + + expire_date + + + + session_key + 1 + sqlite_autoindex_django_session_1 + + + 1 + integer|0s + 1 + 1 + + + 2 + integer|0s + 1 + + + 3 + varchar(40)|0s + 1 + + + 4 + integer|0s + 1 + + + bookId_id + + + + staffId_id + + + + id + 1 + + + bookId_id + main_book + bookId + + + staffId_id + main_staffinfo + id + + + 1 + varchar(40)|0s + 1 + + + 2 + varchar(40)|0s + 1 + + + 3 + varchar(40)|0s + 1 + + + 4 + varchar(50)|0s + 1 + + + 5 + text|0s + 1 + + + 6 + integer|0s + 1 + + + 7 + integer|0s + 1 + + + 1 + bookId + + 1 + + + bookType_id + + + + bookId + 1 + sqlite_autoindex_main_book_1 + + + bookType_id + main_booktype + TypeNum + + + 1 + integer|0s + 1 + 1 + + + 2 + integer|0s + 1 + + + 3 + varchar(40)|0s + 1 + + + bookId_id + + + + id + 1 + + + bookId_id + main_book + bookId + + + 1 + integer|0s + 1 + + + 2 + varchar(20)|0s + 1 + + + TypeNum + 1 + + + 1 + integer|0s + 1 + + + 2 + bool|0s + 1 + + + 3 + varchar(40)|0s + 1 + + + 4 + integer|0s + 1 + + + 5 + integer|0s + 1 + + + bookId_id + + + + staffId_id + + + + userId_id + + + + borrowItemId + 1 + + + bookId_id + main_book + bookId + + + staffId_id + main_staffinfo + id + + + userId_id + main_userinfo + id + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(30)|0s + 1 + + + 3 + integer|0s + 1 + + + staffId_id + + + + id + 1 + + + staffId_id + auth_user + id + + + 1 + integer|0s + 1 + 1 + + + 2 + varchar(25)|0s + 1 + + + 3 + bool|0s + 1 + + + 4 + integer|0s + 1 + + + 5 + varchar(12)|0s + + + 6 + date|0s + 1 + + + 7 + integer|0s + 1 + + + userId_id + + + + id + 1 + + + userId_id + auth_user + id + + + 1 + text|0s + + + 2 + text|0s + + + 3 + text|0s + + + 4 + int|0s + + + 5 + text|0s + + + 1 + + + 2 + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/misc.xml b/2016-course-DB-master/Lib/.idea/misc.xml new file mode 100644 index 0000000..8656114 --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/modules.xml b/2016-course-DB-master/Lib/.idea/modules.xml new file mode 100644 index 0000000..9244eec --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/vcs.xml b/2016-course-DB-master/Lib/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/.idea/workspace.xml b/2016-course-DB-master/Lib/.idea/workspace.xml new file mode 100644 index 0000000..f90352f --- /dev/null +++ b/2016-course-DB-master/Lib/.idea/workspace.xml @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + back + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1594695714059 + + + 1594695714059 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/Lib/__init__.py b/2016-course-DB-master/Lib/Lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2016-course-DB-master/Lib/Lib/settings.py b/2016-course-DB-master/Lib/Lib/settings.py new file mode 100644 index 0000000..6448c00 --- /dev/null +++ b/2016-course-DB-master/Lib/Lib/settings.py @@ -0,0 +1,116 @@ +""" +Django settings for Lib project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.7/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '3^y=5xuy(%igotz@mkpl$xn&7c*nrxt=*am#lpf_(@!iw1c+g%' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEMPLATE_DEBUG = True + +ALLOWED_HOSTS = [] +CONTEXT_PROCESSORS = [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', +] +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': {'context_processors': CONTEXT_PROCESSORS, }, + }, + { + 'BACKEND': 'django.template.backends.jinja2.Jinja2' + , + 'DIRS': [ + os.path.join(BASE_DIR, 'templates'), + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': CONTEXT_PROCESSORS, + 'environment': '存放路径.env.environment' + }, + }, +] +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + "main", +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + +ROOT_URLCONF = 'Lib.urls' + +WSGI_APPLICATION = 'Lib.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.7/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + +# Internationalization +# https://docs.djangoproject.com/en/1.7/topics/i18n/ + +LANGUAGE_CODE = 'zh_Hans' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.7/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR,"collected_static") +STATICFILES_DIRS = ( + os.path.join(BASE_DIR,"common_static"), + 'path/to/others/static/', +) + +SESSION_SAVE_EVERY_REQUEST = True +SESSION_EXPIRE_AT_BROWSER_CLOSE = True \ No newline at end of file diff --git a/2016-course-DB-master/Lib/Lib/urls.py b/2016-course-DB-master/Lib/Lib/urls.py new file mode 100644 index 0000000..5483246 --- /dev/null +++ b/2016-course-DB-master/Lib/Lib/urls.py @@ -0,0 +1,23 @@ +from django.conf.urls import include, url +from django.contrib import admin +import main.views +urlpatterns = [ + + url(r'^admin/', admin.site.urls), + url(r'^loginView/',main.views.loginView,name="loginView"), + url(r'^registView/',main.views.registView,name="registView"), + url(r'^logoutView/',main.views.logoutView,name="logoutView"), + url(r'^userBorrowedBook/',main.views.userBorrowedBook,name="userBorrowedBook"), + url(r'^staffAddBookNum/',main.views.staffAddBookNum,name="staffAddBookNum"), + url(r'^staffCreateBook/',main.views.staffCreateBook,name="staffCreateBook"), + url(r'^viewBook/',main.views.viewBook,name="viewBook"), + url(r'^main/',main.views.main,name="main"), + url(r'^regist/',main.views.regist,name="regist"), + url(r'^login/',main.views.login,name="login"), + url(r'^staffBorrowUserBook/',main.views.staffBorrowUserBook,name="staffBorrowUserBook"), + url(r'^staffReturnUserBook/',main.views.staffReturnUserBook,name="staffReturnUserBook"), + url(r'^staffChangeBookInfo/',main.views.staffChangeBookInfo,name="staffChangeBookInfo"), + url(r'^getTypeOptions/',main.views.getTypeOptions,name="getTypeOptions"), + url(r'^staffViewUser/',main.views.staffViewUser,name='staffViewUser'), + url(r'^staffViewUserDetail/',main.views.staffViewUserDetail,name="staffViewUserDetail"), +] diff --git a/2016-course-DB-master/Lib/Lib/wsgi.py b/2016-course-DB-master/Lib/Lib/wsgi.py new file mode 100644 index 0000000..50196b1 --- /dev/null +++ b/2016-course-DB-master/Lib/Lib/wsgi.py @@ -0,0 +1,14 @@ +""" +WSGI config for Lib project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Lib.settings") + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() diff --git a/2016-course-DB-master/Lib/db.sqlite3 b/2016-course-DB-master/Lib/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..0c24d0872807910d93cc34974399c387d0687614 GIT binary patch literal 80896 zcmeHw31D1Fb>OdG-L2cQ$CfqnF=|_uWg)B8|Ns7dXz(zyB-^qr$+9KeQUcmmAL?#( zORetKNeCkifgwyF1Qtj#$pC?bb0EVt+?y<$WwXhKKn?=AfU!NWY&O}=5|$jh@4f%~ z_wP%Z!*iRn9@?~7s+tvr-LKGR zFy^11U6>9m%x6OLnd!`0GE~CL+JAYlZ+y@`-go-qp#5kGh@p`xBv~_GN!65b>u@NKR*` z5f4KB$>en0KNE_V2T3dhw+NmX85)}y1jKSFL9$w$&Q9?S!lweKm=K*0hE~&yaj2hZ z|59dwzNbqRae8__v@$J~3$X#+{|^5D0I9pV^c1LTdGgdfRb^`)>nevdpdXn|hEj=W zIvrh@pOy+dssKI9pw-qqsgz5iROw0;*>*{^HFtHfNh+sKzI14DDKsAl6@2o%@)ZQ0 zz(#NqVs>s!va05u9=7Q>(=HL6P5CoWnzW8u&O^*gH`^+6;ZLhgLR-nTH(6ElnxwhG z0xew%I48To={OFKy%n5;E#NdYfwQ|2oSHgts%;J6TE%}8_cf;KLmAr>D@q6Nz#a|U)E51^^Tinh5hCRX_WI^_F)-3!`_#NT>!u^6@xCf&g zX|W33tgYWaZ-@NtNE$oPrUpK;bh6)R6}mJKm=cFzt$|S0+B*T+n+*tyraGHNXOmS>Sr>+x(zoLfSY^rtzdQFCpr(v8P*ZLQ+P2p!^sshwjv8Dx zTLe0OhgFbRrzvZlk=XQ%_0Qvb3^+aCES#RJ{%PNB5CW;01;Q-#_ntF%>ImdO_58D-Z7?S=wc#8bW)5G_e|uYy|2K&568QJ{SNO;H zLp;SNxQ`#__2S=&eX&Dl;-vh%; zQ&SU$WPK07r~(KOFfxOzKfWJ?G3DUlgZiMIedx~1+zre+$s(2rgY!iU1`Li6I45qfG&Si-!~EAs6oYZhsM=>ae2^846}Cf`_BLi3 z63oMcl~T-(43=G%re>PnYZDwQN&Y|}-eGAz%<{TF!~WkP{0;X1Kj**0Kf>S6e}>1Q z|DWL=-p==m|0+H%{#Ws{;`_w6h(9BS#Y)4Ojci11YPqT;FFR)b>V3$}g zJH{G?e}d#*D8FV4>tPN094c3*9h$#BVaoX*-)CW+tN|xTInVYc3+rO_dLr3Ia7^>n zlgRqE-C<$vtR54{dL5-S>-6Y)i#eis>alfC`yLBxV|5r=_i5d4Vco1&k83opyEJb- zw&8tvuZ4B6T8wY_9iohC3<^+NJg9l<@%09JfO0o4-CD@Uyi~hW^D#wi-eqBjnXww% zPgE&fcr|IhrfAsW_YtkC5Z!Di*h`2NET8VsJhP?MWOaK86C0IP^Vxl;g-NW$8mLhV z(Bqpr(=I~GifNd9p}#{dn3pm2nvb3U)@vP=+JZ6hvzAJdw=k*Ey!1HKC94}Ptd(($ zMBi1^2#ePkHqBp;n&abEqC>&b!9ryyTqSVLS5G3#>!JTc|gm>`Tn zLwl|GfcQt^Iq1CXadv0(sZ&owH}@h_mZVM;s!~AD5|4&JV;J;jLYZhHWT^f+Z@+4( zqVyz1X=mqcQvPi^Y*ncJd);1A)gk{gt+NY03)Gthp-)RmXV$}|PN?~MV||bzUG{WI zo%H3wGlQ20NBRe^Y^BTY1Z8mm=$4;ZftK3PF&E})j@;Qv{huugY>|Cj>=#%0CxDCh zzEIfr3lEPAb++bdA1bM(23zxBYdLi_H74W@x~>~vQSEAZhKlly-PKjiM~<+Kxm*J$ zZbBK-TW!AfITvsnTC~^HqU~A}>r`rN&1a8nNeIGArv$y%ZF*~~nteX@y1IgLn7V5^ zhq~FfzFhgtKu@cz8k*bo%p6*JF4!S+e0uw?O$p>8_?9FRSijk_x88#}=nt zXOasmlIj_99=kqyx^I0bG8T@XzIN&K1vwJyA9DvXbJvrrV`{$~30}N9HntWWTDm-U zO0%_=!Q9&JboYX}wd!(6Xb0^SBw2B(Zb|kiZdF#j%Dsz=j=(}fVCCa%bku05HkU^= z zbX37CT(&zsy)I9$tUA1k8&S=K(ix>Jrlq26bXd2=^vd~#P~3fCaKb$vIF_07UR)WO zk=7?e@pD&ZhOS>(z7m)`+coZ*92h^p5|`!vxye=W}Axh3(#pCe#yjkK&+4h&k2%D|T;q`$K-nsEIrXhB?eES<1J{MHoDb;s=(042m zi;ua0dZRtk;OVi9bI^TBQI{6NYs+)X*HWRO^J~jPXPoot#mRtym;|(P^{PM%pTi{~ zVoY*5-IAoZiYhjbeA;FP+2_FRd?U5U|Eu_KbFlpR-|+Zr{(aa9^e2^Zu|k0g1zwO8 zsO2pz9rVLr9lmP(v9^XcGvq(Aw%1nsP-+MmcOOVR3n7X1{ID@rz(|GSzpo0ySH&gq z1N_VE&B9UmXZl^)V{4x6+fuzldMX&|PJccv_00q(7ZrSxAAAfU!qd_U3KK zjQi6WG_sD)moOv%rA{ zK+{#zR%TEB&Qe4aTTn5Q5aJJHqRX&Tx)6UfotTcnj^)yJ6i-8SdfOY!Q{NO$4erS) z2en$IjpwKvG_-kOb6l_s-K_D?sqRW>1hcuDlk4n!MWe0xO854iQ|ngdE~)w4QIY?d zhPujYg#tT_0u}k+4y*7=aVr!sQ2_aW6TdF-AM?NGPw>Bm6M4SIzsmmue~f>ee}KQ6 zzl;AOe}LZy`+<@?!v7tBR(=%Dgjyr01QsUG!|WHPCavt)8AuwmN$5v(?gbudRlj9kyzE9=BD|v)yK+=P{d= zo^3V@J&)QrJ&)K#dfJiyQ~xj9-wQ{EZ30@Vo_95A&%^t)=b^pY z^WYuY^S~bM*|J-E-r1->S7z+bS@x~ z-;}XS@`R-sDNx|QU$2Xyk%7VMaFSvE{+Q`(tfThPk)lwnp2E!}of|ECtC}zP*v8#C zG&FHn4w>|{Gvrfzepi_CD++Edfm9KYk%kGkA|OOj^8`6v=f++8G~5Qa!p*CAlo`pR z9Z6V};+;~Q;g+KbHo49Xp{c6*72Ry(NDe`2M}$UtI^^{@C4bOGWHSY{lt9W9 zY{WC6V+uwh(I=vS{J(?m7x+*3Kk~nW6~K4-U-CbLHNfw~c_3ecRluXLC-^sE9q=o# zGx*K064-?O!OO4~h{0)ruj1GFWquL%3f~Log}Jx`4iY=c4?%L3UxflMVhUI}V+|eT z9w)aQ-TGtXwvl@j-MS;>+R1H2xArb_50iTc-I{~s9w4^`-Re8ZZ6Zf&?jsk@ z>0-=w2f2I5-Hoobk=$M6HlS;%C%2B=T6B30xz*%Wp)1h*ybPp}>or0-F8r zvLGxAKVk0|uL}Pn{P@`~(gxeF2|n9O3qJGY#U|0^fo%kz*?8pzpC;+>iRP;2D}8KZ zr~n7bFDI!jC59~oIaCg>Lcp@3*+RfPA?=3aP7T$G?NH4MqH_}C!h{b$X;iam6%w;B zMMO16E)s0t-_b(m-LGe)H7Y#bzVQ1l9jE+ToQ%`(F@utJw_9D|gr>=G(-0ouR@wr4 zVI~#|WJvXs39V-6QYcW~=-#PN66~_G*4?ldEzi1JPdps=&mOg>6aIJ{414WM^Xcd; zm^_;;x%DIX5^zSLe-<#&veNIMg6s+vDmgV4-ce4%Ufgj-V3;O^m5hN)pMOhS4mt zF-iX4#5bRU{Qub>9V$6gD6n%VfO2?FS^!R308Ux}PFes?S^!R308Ux}PFes?S^!R3 z08Ux}PFet7Mhn163&2SWz)1_hNejS5oc~k*FR$+_&K>fdk`v0BO|C_1*@2CFXME!ps_5Z!p|2s$vc$~C=?W6?+GeF3t zjr#vl>ikv;@udO$oYuy)M<^r0x4f39?$| zsK$u-)uTm((s>OV)g8#1>y4>Kb1*4 z7Qm-snPh^8)Vp~pWbo7rFP?nhQSdMg`Q|&`aO1&uuqxIqmIs$y4i9bqm!A08J8ypU zK?G-|z@gWk83$+J3^@0Cz$UQ~w%gMc)++K96edKz{^^of(S0&d)u0pPiZjD5)liVJ19q86| zlY5ffE_5v~L${`rd`^%{_CIyU$-kX^j*;6&ZW;TZIp zi1XJI=eH2&uOiN0MfN{cz#3rhk8oaqzdz+&+CTACPqjO3TyCw}s6L>{^du5e70P%F z+tR{-)_j3fVXzTT6GIgSqaed964C7{51Q>N3*#6^I{?SW*#mHWoIz-Ff~PuKy;R|mFEQf(jQBqz z{?Ca2Gvfb@_&+25&xrps;{S~JKO_Fni2pO<|BU!QBmU2b|1;wMjQBqz{?Ca2Gvfb@ z_&+25&xrps;{S~JKO_Fni2pO<|BU!QBmU2b|1;wMjQBqz{?Ca2Gvfb@_&+25&xrps z;{S~JKO_Fni2pO<|BU!QBmU2b|HIrKsYLvr5&vhz{~7UrM*N=<|7XPi8S#Hc{GSp3 zhh;RTK>VMP{V%hV583}R;{S~JKO_Fn4pJ!be@6VD5&vhz|Ji;DCH~Kd|1;wMjQBqz z{?Ca2Gvfb@_&+25&xrps;{S~JKO_Fni2pO<|BU!QBmU2b{}HS9Gyd_@*8e}r+XDnUfL`L%suZt6ffp48aK0eWEI=gwFB1P3Xht9s{}+k>i^Ttn z_x}jA{ugNd5Brs%>{k9=58hZLy7Gl2G3C8Y`v0fHBqP628Z)G9m$ zXpbOCRd@^#yg2C`phl~Y&H-u^ymSswqu`-)fEooiodeV;xab_9MvFq{05w`<8-oNI zEfV&B&f)&=|HFR(kIJt?feHm)Iuxi8xzM7S64Wqw)yxEHK;_qR*dsTBs2ius;SApPl?uLE=KaTfbek!noedB|6-TFH(9n@8f zLwY5ZT4uEgC_@M?PxU05^i-W2*N#>-cXqN(lLm~;MxtQwLYW$0oh4K_M&Q#@;!x~- zy_oq#Z@``)bX`uNwkl7LQ*6V%d9ICW<#nUET0upmQLyaC%Sx0h8}_t{g^}}1CFh?W zjsRCetHmdTV?ZAo#21zoNP%IOA`A0ct!EWmk_;yJU=*(dTn^1f)0uI@yx(kej|n_I zQl{FgnmwSkZ6Y1E(G)><2j>rkBqbn)&7LQ8g6hX9nS%^?O<8OX$|>MTTm9=2VGzz^MWj}k$FHC z*vQ-<3v6Vt2mn_BT_8yQK^F+R0J{H!@&75nU*%V!K!pM?Z3;BPvi}I93BWYkBg3t3 zDF1)C!2cXL|66z%UMs%}1u7KSk^-FvVK>c@6V=tiVSHifaL^BbX;v?JJZ_ijlYEj4 z`(QlXPPtq5)OA!<3lxPe>5`^hY@ej4UN7tw@i<+%t1N2|+X%4nhz_W*Mz{!5a>Lb_ zaOGr8hnSy^Tp}F=w05w3K&dpKllK4B@h{>0KYQ+{rUm>8Xav8sB@rrt6$(@+@Vruh z=JPb?mub!~(VSnRIln}6eu?J%vT4q*fc_um|DgZR&i}2#hXmn6?5Ox!@&EDrged$g z@q31%k-K|r&7+;=ZYndxBh%CKp%s(WHGM09j%B%{s@Vsk$CjL!1m!#^ zL&;=)9VLV$*)Su9Nk)k^X9sh3qXcXhGX&E=$PGYhHI!b&s~%36MBKcx~9 zwj8h~_(9kqh>8~Vh0?DAk!Hl7z8uOdrRW|#Fa*!LB#;c?pNaAJQ;|C6%b&0yaM(ol z;E5+AYs;&eZ2Zoj?a~f0*ABqeTS1nXh6t^|zpF&W=7?;>GF5FZRI38q&Ooxa*Phh! z*Uq6S$j1<*75MjToqtwjS2lmM{OxDEw<17ZyUrEDxitdWSY;6~wQjWkVf-h+|4VfF zidTgK6$-pWDS&o_JZJxB?EiU*7PnHY3I%o~1+bsjkwtJVSp?V6jvy=9|BBTA_4R*= z`#*Lh!77EWP~b&E0optGjQ9VQ=>OVjV3l2fFOqgpL33wPpmhJ&_WwM&{lBRHtK&a| z`~UC+ps&HLUys2FJMV_uz8(PY%CAC!3I(1e3e?uwzy=?7^C_?ouU3DT;k`zGm*Blx zdk0e;v9`*1XSFudyH$V3xE9kp*WWRH(d5tccSs-4{}cI-u!KW+{vTTro_Lmu`@AN* zQE#hhY;SAb7-r0K>kIFA;$v^U@#cqb{o?CaS8u%GbGP33z^(Uv>E=g2bo19Adi?Vn z=J03Z{a$g!TGQCl*0P~8=DzjNo1XZs4Kp4OfAagk_RE_0?RD+q#xaXVhu1LXdi=3B z+L?yVPawSEn z?wLK>&b&8*f>N&Ala480lcqD9J7}nL3i8g)aYq#%fA_i-QsNhU>iS*NX?Su;J^oAe zG(0c_Kw9AjDmqK9$ST2nhlD{a+~Au)hxBLjfR|62cj}9 z`$MYF>vkKtWzQ!xH>W&EQyW14tfD_#sLsv33LW2PJ^@j0EaqmbmZ*7Cn<{z5#+LVx zlsS=6r@3xAk=^8EJ_a#w*Ox(uY`MUC1kEo@wgkn-Bt_Lm&}cD(sh|Nzr)K~AhXQc> zAMqc874RSO|HwbfKVEVKsCZT=P@%x{O@UgF8Cda*FMJUtmV2u{U`2s~)yHb~!`mJJ zQ&{z0%@Yn&Z_?htZ=d!ivj)Cbu(F2*-pt=59v1%$UMs&B4h4S3tL+Wd?Bn$FiqmkJ z6y9wW45_ZL-!12R`|^#$@&k=H8n?_3M5Yj0O-56p>7YLoI@-D6c57RvJ80IF51s$z z$!DASftYX>>ABEa=~I6TOdqrGfQi5OXkRm$c0?BM`7*Wuci!#U%Gfj?xoIi?+Y7aC zc|PW-X;qsSH|M58`otsO5K;F$mS4~2Ig9~sniHAkFs3;}C(8e-`8Tn}59jXxfZ4!b z@oy%US7k+3-Leu`TT3p*Q|^Rw*`uyT1Abp58DAM5pOB`;$JVA|0d;g>c5P%l7#kkg z^oZ8s`(M*H6PTItg}vSd&$@p(vl^RQae8MKVu`RzPK7e5_|(9dGMqRQ9f|cRQ?W^9 zBsRP*``uVW` z?3s0c|B!nq7H~}^Ce|PwdFtB4`tZQu+SK^)>d3W0d1PQt9f<{;Q`bh~!-)xLbUYFn z9SA~tgVBrq=fjiNuR8r_d{RKZx^`WT&ke;ER*U`5M<(S=d?qm#9gUu!^C!+MP08M+ zN!hm)Ja;}h8C40di-|1U<@Jkm((=^VtLd@CnV4U`x-`{)-k06&;dJSDdZ=!P$Bp-I zYhRgsqLNUyhHApN@^J zKNoE-+h(3g+Zsye`Udppi+Ih)1+<+%-v!ROHgET!KFlKC8I{1F?BAehE`^lXIA`~VA_)opF*H?ETJrU*Cn?!yEeb*S)5hZg3C_T zSA(j*&m#ZMBQrGLn(RZ=hfAadv?VS z#{Ua5tMY2lGvi)gT=n`FmlKMLKuTiK>vSi*&cK4Qth(b1@?2y+9CIe!@Ev8&eqNqa z=N4kKl4r)%ML@EuDABb*AQN7fBgvJBb43oS9{0LWUGmK=W$rvk-{IRF0MysHTbfujD5no$GsNZh%o zuC6S2-2o-C7*DMv7c+}KHF*$$l9`2>XksSgoA<1w6~DCX4=l`i0_*cq+_#ijceWtV z%zQZRo?TxIuY}_vH9Qya#TO&~R4N$;N-PByn-R#fGQT*R@g!5qLeLk4=u*_RmU1tz z%_oBM{zYFC0?Faol_l50Y)o31$@pjEQf%3o@P|BJHR_#-#OL=SP};Y?luRdQ!ZU$@ zYjH)DGhS!J8&A74LB*T#I~x%wWG=S6s7AcuWuH49o0sKae0F6$cm#pM zbBTy|Wj5swC&R(z*`PBh&&WylS}d9h#*?e7bqKWG;8TS_E8f|anSfuJUrx!%&{|+U zu^62Vhh_q^%bEGL*|j|gv>gMmAkcRFRYaiK@S3{17+ZC&ug=Mf-pG>VUUjd>VxdG} ze$6@KtI_)Zw*>wjko~`ohxl*s4t|DLi{BT2A8zsaus9<2hzW5w`v>+3_I9{|=PFxb z9(Jeje}!+s(D4HP-NpOxDl*uDsdP(<-KqA<&R$t|s7}0~>z-V&)a`WJop2eKj5n3J z-FW@dsp4RQ(C>b_J1-a#_x3{iitKRG^;I4{7`AQV_D{Rh)vLl)TV99a#*59=!eF&m zg4>^b4j*0ZrQ`(zYH%%-r&ob%s(grAPhPNUhdZX=9xtcU;ql@%Q(bw%6kCPZUI&~a z1Hn>Wuw<72HMp_M2{(4(MOq!^V9AG6gV>O`s$lH)ykIYt8?MB1!!2nzfoaPNhH`s= z;B>1OCEl7B?8WQH6t&l-z?D}R`$%4}YL|eb3X(;2V~rgw5$x)P8`mVd(XAyf*ky++ z&=f42!|lWi+?q=U!|idBj0J1T3zjgpcE6ZH*K6&~3wC0`R7f1I0#h+|V?i)rj`ym0 zA#W_$9&@nMgOeA<3+X$29t^I_3wGNj1uk#Hd&X3{O0Fs|Sc?s<1#gZ+vee`S)11;g zGqMy1!!>folv70cUkmVm{%!to{&W15yoWRKd*YYHUxnR(uN3cwp8q%O5%wSpvX`@F z;fKQS2=5o}7yLM75QHNwR-v1<_50`Tu)eUP+|>?eCDp*kG=9Ll{Z6aUrGW%P@lYm2 zP}SNy0oj`k2<^6H4MM*;8Iw5x(u{U?*qlvuHj7RWYN)IW!%XShQ8-;?$^^eVLF%D{ znljQrO}Qax8wgE$Si3n#4KAB40v*4@DoCu;l(oKSwdon_pU3wYaC*L3I6YVW)4tmv z1X42#gjwqEJ&ji3ZYG&>)bBnbjV9W+zj@Dq~qB_vir_0;9o&kLvtu|ov z95fg`3;H-zWfeMDYql;m0L+BmPTH)3hxM39n!C$f)U(R@oU|IydVaYuQO`8zbKGK7 zJQ6b(AY%5p&rWU-T`y^TVb&gk%Z=8UjskelcPHG~ncs$UpnCpU&^9pcF}2|w9A=&c z!v4RDeOf#J;|+X@cf)Od-w_`Z-v;;hof7x48xUCey}&5Y-C-4cd5u=v9BM~xY=hop za{EQQj~n26t2Kk`%_axl(QXBkG#b~i*_vUo>Er-Aj~R_oZ@1WQK@SyPsMnD|5B%RBVISo}IYXZXg?4!Z%UXKVoK`Rag2TJw0B z0R=DFo7=kX!rtF)8Y@VYMg^|bvo%y~U55=|J!2EFp0xqoeh5d3j_ep^g2e0%u#SU9 zVf0cPELYE7=eixB3DB!h&)fjiv(^Ez|8wE8AY5h-iobU|nt4V3mzCvI+K46eg}b?Vxr z3Yr9YbYRRmGCn3vt`E5;sx0f(~GP z7^J%+`ug3!{m z!t0r%aSM1EBwL8NOM`bI{I2rwAdPa9&_>nZReebKQFT z2W~#_nV|tFz=?W{(3lqiZj+aLL2v_7A%(;~lEmuRiMle7Aik1Shw4FrAV4;-(OQJ; zW~acUJ$sxS-B6EmDi25&Q4l3v$@s(JA(*Y(7iMCiKt{az=zDHH^u`+>edoGvt4E6nrSm$xBtXqt zxwC54Uxn~3%vXrHCZChsNIr#T$dY*DGmmOG+M{W0)@%oCEv(z7B~py7yVnJRRl-(J zgh3OsmcbEZtxyAQY7&xG#S*J$CoKryTv%fum38+zT_D!QdXNboQt#%aka2=c4+Onl z5Qd_ZSJn>gXH~3QEDtWZ93B!-O4`Bx2+qobgB;i8#^&$T4*v&mt^Z#WVCUbv`5f=# z%^>&x6)`6EiZ$#n*az7f8-kmJzAro`JRn?q((8ksCB z;&sf?j%b&PAc3gW;Uui}jUE!OVLivnWdIFYb+}M03r%0&AAuRPmB~Pp>tl0;ZfJr( zS{@#{xrf@FYJxwq1w4qj@qjX?+XQbf2k$1CHw{xB6MX9y@GuDau*6;y{9RkX%MOWT z>b@L&&tZTsRb$YGU6R8`tx|I4A~+6}%mAuOMwz}$EtC;@50Q0)WNltb|#)63hF1;d}C z2_xnAi)|0DkEe3I9T-xfb4 zu8Bh;V}HyZVhQFI{uTQEYXM}NpW=a>+w)0AdNoje;TWsnAo#==Klb?NKYimf@4xkd zH>r@l#|@G8bmh^6A^{r#-HkR{NzNx8dC#p!-g)z(&)xdsTW@{-A&A(oVmSv(Mg(Gd zXhiqL{LB7yAQeq!zW?EO-TK^bL9RDG_m(Ff`4S`uiTGTY2=d2VlhJYq6^YB?qEX75 zT!VY)=Wjgxxm)kK@8-Y%Wk>^}Dhfu;ugq*z#p&?M*qZY;8bYLQ86&ln$PYAh66m>* zMEZU}%tI=d2aIvhgcOZ7?5m34mz@wmzK-(w0#{QdB#1t~%7AB2H^7$~Z$N7Y%>@k40A4Z;Xgw#(MS$@@22C7A zFpaQ1U1cIbe}gLWso38n(-3~)Wmtrw5k$rg3NtlH#u2A@s!@6b>F>nE4uY;c*S3fQ zf^H8hFK?b>nz*1`4sN@_VF-wHqFfQc{t4!qG-gUBuGP~~E&_By)!~zo3rVI?xnTYO zOWSnvClS2q*+Xlw?JON&-HiP7;Pb!uQp86KEhn;HO{zZk6bV}X^afsxqcwP9HE z2jf#`2c4tWCSYB^l`Ym(6yVo}stB z8~@f@ABMjhZ+Yv@pMQsOhJdkmK8-&Ke|GjpAQbLAJlk6YY4R9(|J*w%XgFk@S; z8O%j~_!n=|-&SjkmqOSzabtH)&7Q8du8lqz{0i4%CX&EPrL;x_4=QG{Il7Y z$EtK~HZi7}7r9%I$FvkS$9OK^yUG5qQ5X~8+^>253b6h8Bk_&mCH52cpV%AOFkCVG zZQ&gd{N#WAXA0Ima<>!AOwo{&1Q4_^&a%*Q>z@9>f<&Zl1ymO#Dsh64n1ngm#bmie zTm!fkDzQWd(@j`mdOX@%$V_iom-hB!tP(N-j0Nfd83ibkT-bz)?5OcgR5e+5JW3C5^t zfl3R16(YgH-;IK+ytZ6G=%Jwf#xFfc#+rBsD6UvRpmPrvql7>QQiWnj3N5;&g24c2 zH*g9gmJsM*M9Cq8-W1C3+-gLHRD3VTLY1mL5K4MMRfLrA74syBs@$#7qevKp@=Ua@ z#^&NR9|r}Ix_dEF35gCwQdEaT(m#)Oh!cR1`?NfYX%0dL04G`gQ>J;Z7g8g$^UM*{ZBKk#kSk*v2*rfmA1t&)?$W@`lhFaD7W2SnjOFX*Y*aOjQ=-1 z2Z?gqZB^Rw`v0O`6*&LjC7eP1-@{=2+ax|NenO0j?d;p^P0T5LS9mJ~Zu=V=#}TMK zC+yUiKGYEI!f?1`lvGQKnFSRv6GP-VdPN(|47sT(DdJ@`n3dqa75(J^x8|N z=Y-8hSnhm=RxYK}BbZW4>6AbPZRT?2(l|G~1vXAlW}pTZr1!ZK3CpF_a}iQ9YYvPS z0(-0^2VSWMDlUDBseqY8&xP_4KquzaG>^J!Q-%or=Mh(v?B0|EXs;!j1L}$cr5u|5 zL*)~ZQKO9o-fj-tbFL)nG@FJ^JTlE^B(s|Mtd^@Wi_uWmA}9{fL?Ur=T2t)*wd{ie z|1C5_mN^5K80V|6Vv~WqHQD1LsWxL5#aU!%W5%&Ipf?L%zR@)@f zH;IWfvR7o+GT9ERfSwHI)zrh?ZW9iso7HgP(!lzzmq`Mau3*FCqAiMBC((bcOi}Q( z0>HvcOPFnn(tou~B2H~5CGBS1ZvA{>LMu$cC;M#vT~cL@dj|F+oww9{C;-BC6>-u|cPbd60<2T^XjlY(|S|Cfu7 zE!p&R5#^L^PHWof{9i6QE~cRW--fYo)6+wBvEA`nJAM8ygR(9EWS>osM3md^RIZ(F z#imite5%o=N74HKHs`+W_>mLVocV`M(fpr1DB$jY*#F-I|LFIV4Qrog#VgG&%d`G@ zII%M{pLDtXax|nwqOwbwU3JRk&i_=YF4Ef^)VJfu;-YiGHa!)}J(*qX#V4w5dOXzT zwmU&`2lszC2M-RqD>|x<_&;kD#NUH6zVJxUo&9_DJ=S3u`QX&!Ef4f8J@N(TCSm8o zR1D6J9iK{!tWU_p>sR5tfytGTYs1dbfutuqcIs65GYL06r>GTgccSW!Z^dM$WInEO z({s1RbGA8Vb_cIHwf;|(({{XSyO^>6+k_JWzaoB4>|n1Ez5yR4ej6uh8-$IHKGxFE z(8E|?a%L_VmZ#GZKO7K#OhVQ4vBfFZndHI>Xj_Jy$F5JF?pq&m!P9EabpMUn1-!?pglrmiBphd1$M|wvPXdp zUaD8QcX81XSV#!^rYgC+IL<~#jfQG-c~n!rwaMkl!Lhmc!053lsVgZfzN?``S9o>& z!ugfui)WJkA=!D=6LE)AvXq*iSUR0il8Q@5RqB?tBLzVHraHU|s?r49->sCzv{aOh z4(qm&UM%pP4)?dsk|+w<|rGxxl#R~R8mS+|LMz-E1}?pYk~Q|?6IlS zvE*F;gfuailII81iKX-2<#WE-v++cD%m2{kwxcX?Bd0-Ycb!kWWYBV?~A*Vk*HrD zznr>uVKI{ES{T0`NM1aMDCwsfj2ShBjvY>-JVr(2Q~S5d|0kq>$oC`G}N#z*Q%?Ej2U z2=G_=RVYxQ!0n*G#)(v@FLguczHfWqInf623HeY&|>?ok~ek#;3Z+uJ|IUD;K6t zUa#(z%gL=<3ASndF&)RAe!EZ45^M;N{x6(%Cbuon%%mq=SC=E9(C=Se1$M{{fP5 BJ8=L2 literal 0 HcmV?d00001 diff --git a/2016-course-DB-master/Lib/main/__init__.py b/2016-course-DB-master/Lib/main/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2016-course-DB-master/Lib/main/admin.py b/2016-course-DB-master/Lib/main/admin.py new file mode 100644 index 0000000..5a3ac01 --- /dev/null +++ b/2016-course-DB-master/Lib/main/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin + +# Register your models here. +from .models import Book,BookType,BookNum,AddItem,BorrowItem,UserInfo,StaffInfo + +admin.site.register(Book) +admin.site.register(BookType) +admin.site.register(BookNum) +admin.site.register(AddItem) +admin.site.register(BorrowItem) +admin.site.register(UserInfo) +admin.site.register(StaffInfo) \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/migrations/0001_initial.py b/2016-course-DB-master/Lib/main/migrations/0001_initial.py new file mode 100644 index 0000000..faafb39 --- /dev/null +++ b/2016-course-DB-master/Lib/main/migrations/0001_initial.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='AddItem', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('addNum', models.IntegerField()), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Book', + fields=[ + ('bookId', models.CharField(max_length=40, serialize=False, primary_key=True)), + ('bookName', models.CharField(max_length=40)), + ('bookPublisher', models.CharField(max_length=40)), + ('bookAuthor', models.CharField(max_length=50)), + ('bookIntroduction', models.TextField()), + ('bookPrice', models.IntegerField()), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='BookNum', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('bookNum', models.IntegerField()), + ('bookId', models.ForeignKey(to='main.Book')), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='BookType', + fields=[ + ('TypeNum', models.IntegerField(serialize=False, primary_key=True)), + ('TypeName', models.CharField(max_length=20)), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='BorrowItem', + fields=[ + ('borrowItemId', models.IntegerField(serialize=False, primary_key=True)), + ('hasReturned', models.BooleanField(default=False)), + ('bookId', models.ForeignKey(to='main.Book')), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='StaffInfo', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('staffName', models.CharField(max_length=30)), + ('staffId', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='UserInfo', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('userName', models.CharField(max_length=25)), + ('userSex', models.BooleanField(default=True)), + ('userAge', models.IntegerField()), + ('userPhoneNum', models.CharField(max_length=12, null=True, blank=True)), + ('userRegistTime', models.DateField(auto_now_add=True)), + ('userId', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ], + options={ + }, + bases=(models.Model,), + ), + migrations.AddField( + model_name='borrowitem', + name='staffId', + field=models.ForeignKey(to='main.StaffInfo'), + preserve_default=True, + ), + migrations.AddField( + model_name='borrowitem', + name='userId', + field=models.ForeignKey(to='main.UserInfo'), + preserve_default=True, + ), + migrations.AddField( + model_name='book', + name='bookType', + field=models.ForeignKey(to='main.BookType'), + preserve_default=True, + ), + migrations.AddField( + model_name='additem', + name='bookId', + field=models.ForeignKey(to='main.Book'), + preserve_default=True, + ), + migrations.AddField( + model_name='additem', + name='staffId', + field=models.ForeignKey(to='main.StaffInfo'), + preserve_default=True, + ), + ] diff --git a/2016-course-DB-master/Lib/main/migrations/__init__.py b/2016-course-DB-master/Lib/main/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2016-course-DB-master/Lib/main/models.py b/2016-course-DB-master/Lib/main/models.py new file mode 100644 index 0000000..1b4312d --- /dev/null +++ b/2016-course-DB-master/Lib/main/models.py @@ -0,0 +1,58 @@ +from django.db import models +from django.contrib.auth.models import User as authModel + +# Create your models here. +class BookType(models.Model): + TypeNum = models.IntegerField(primary_key=True) + TypeName = models.CharField(max_length=20) + def __unicode__(self): + return '%s' % (self.TypeName) + +class Book(models.Model): + bookId = models.CharField(max_length = 40,primary_key= True) + bookName = models.CharField(max_length=40) + bookType = models.ForeignKey(BookType,on_delete=models.CASCADE) + bookPublisher = models.CharField(max_length=40) + bookAuthor = models.CharField(max_length=50) + bookIntroduction = models.TextField() + bookPrice = models.IntegerField() + def __unicode__(self): + return '%s' % (self.bookName) + +class BookNum(models.Model): + bookId = models.ForeignKey(Book,on_delete=models.CASCADE) + bookNum = models.IntegerField() + def __unicode__(self): + return '%s' % (self.bookId.bookName) + +class StaffInfo(models.Model): + staffId = models.ForeignKey(authModel,on_delete=models.CASCADE) + staffName = models.CharField(max_length = 30) + def __unicode__(self): + return '%s' % (self.staffName) + +class AddItem(models.Model): + bookId = models.ForeignKey(Book,on_delete=models.CASCADE) + staffId = models.ForeignKey(StaffInfo,on_delete=models.CASCADE) + addNum = models.IntegerField() + def __unicode__(self): + return '%s' % (self.bookId.bookName) + +class UserInfo(models.Model): + userId = models.ForeignKey(authModel,on_delete=models.CASCADE) + userName = models.CharField(max_length=25) + userSex = models.BooleanField(default = True) + userAge = models.IntegerField() + userPhoneNum = models.CharField(max_length=12,null=True,blank=True) + userRegistTime = models.DateField(auto_now_add=True) + def __unicode__(self): + return '%s' % (self.userName) + +class BorrowItem(models.Model): + borrowItemId = models.IntegerField(primary_key = True) + bookId = models.ForeignKey(Book,on_delete=models.CASCADE) + staffId = models.ForeignKey(StaffInfo,on_delete=models.CASCADE) + userId = models.ForeignKey(UserInfo,on_delete=models.CASCADE) + hasReturned = models.BooleanField(default = False) + def __unicode__(self): + return '%s' % (self.borrowItemId) \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/indexStaff.css b/2016-course-DB-master/Lib/main/static/css/indexStaff.css new file mode 100644 index 0000000..a715a34 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/indexStaff.css @@ -0,0 +1,209 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; + position: relative; + margin:0px; + background-color: #092B40; +} +button{ + font-family: 'Microsoft YaHei',sans-serif; + cursor: pointer; +} +.fail{ + color:red; +} +.success{ + color:green; +} +.hid{ + visibility: hidden; +} +.fontBlue{ + color:#092B40; +} +.fontOrange{ + color:#FF7F00; +} +.fontWhite{ + color:#EBEBEB; +} +.backBlue{ + background-color:#092B40; +} +.backOrange{ + background-color: #FF7F00; +} +.backWhite{ + background-color: #EBEBEB; +} +.nav{ + width: 100%; + height:50px; + line-height: 50px; + font-size: 19px; + position:fixed; + background-color: rgba(135,135,135,0.5); + margin: 0px; + top:0px; + left:0px; + padding-left: 400px; + z-index: 100; +} +.bookLib{ + display: inline-block; + margin:0px; + padding:0px; + height:50px; + padding:0px 10px; + line-height: 50px; + text-decoration: none; + color:white; +} +.bookLib:hover{ + background-color: #EEEEE0; + color:#4D4D4D; +} +.container{ + width:1200px; + padding:50px; + margin:0px auto; + overflow: hidden; + position: relative; +} +.fullPage{ + background-color: #EBEBEB; + width:100%; + height:600px; + margin-bottom: 20px; + overflow: hidden; +} +.two{ + width:540px; + margin:10px; + float: left; + overflow: hidden; + height:550px; + padding: 30px 0px 0px 30px; +} +.one{ + width:1120px; + margin:10px; + float: left; + overflow: hidden; + height:550px; + padding: 30px 0px 0px 30px; +} +.line{ + margin: 10px 0px; + font-size: 20px; +} +.line>span{ + display:inline-block; + width: 120px; +} +.line>input{ + border: solid 2px #092B40; + padding: 3px 8px; +} +.line>select{ + border: solid 2px #092B40; + margin-left: 0px; + padding: 3px 8px; + width:189px; +} +.line>select:focus{ + border: solid 2px #092B40; + margin-left: 0px; + padding: 3px 8px; + width:189px; + outline: none +} +.Btn{ + outline: none; + background-color: #EBEBEB; + border: solid 2px #092B40; + padding: 5px 8px; + font-size: 18px; +} +.Btn:hover{ + background-color: #092B40; + border: solid 2px #FF7F00; + color:#EBEBEB; +} +h1{ + margin: 0px; +} +input{ + outline: none; + +} +.currentUser{ + position:fixed; + top:300px; + left:100px; + padding: 20px 20px 10px 20px; + background-color: #EBEBEB; +} +.currentUser>div>a{ + width: 50px; + text-align: center; + display:block; + margin:5px auto; + text-decoration:none; + padding:5px 8px; + background-color:#092B40; + color:#EBEBEB; +} +.container{ + width:1200px; + padding:50px; + margin:0px auto; + overflow: hidden; + position: relative; +} +.templateUserContainer{ + padding:15px 30px; +} +.userItem{ + margin-top: 20px; + display: block; + text-decoration: none; + color:black; + padding: 10px 30px; + background-color: rgba(9,43,64,0.3); +} +.userItem:hover{ + background-color: #092B40; + color:#EBEBEB; + border-style: none none none solid; + border-width: 5px; + border-color: #FF7F00; +} +.pageList{ + margin-top: 30px; + padding-left: 30px; +} +.pageBtn{ + outline: none; + border: none; + background-color:#EBEBEB; + text-align: center; + min-width: 15px; + padding: 0px 10px; + margin-right: 2px; + line-height: 30px; + height:30px; + font-size: 15px; + display: inline-block; + color:#092B40; + text-decoration: none; +} +.pageBtn:hover{ + color: #EBEBEB; + background-color: #092B40; + border-radius: 3px; +} +.active{ + color: #EBEBEB !important; + background-color: #092B40 !important; + border-radius: 3px !important ; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/library.css b/2016-course-DB-master/Lib/main/static/css/library.css new file mode 100644 index 0000000..a14b728 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/library.css @@ -0,0 +1,169 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; + position: relative; + margin:0px; + background-color: #092B40; +} +.fail{ + color:red; +} +.success{ + color:green; +} +.hid{ + visibility: hidden; +} +.chosen{ + visibility: visible !important; +} +.nav{ + width: 100%; + height:50px; + line-height: 50px; + font-size: 19px; + position:fixed; + background-color: rgba(135,135,135,0.5); + margin: 0px; + top:0px; + left:0px; + padding-left: 400px; + z-index: 100; +} +.currentUser{ + position:fixed; + top:300px; + left:100px; + padding: 20px 20px 10px 20px; + background-color: #EBEBEB; +} +.currentUser>div>a{ + width: 50px; + text-align: center; + display:block; + margin:5px auto; + text-decoration:none; + padding:5px 8px; + background-color:#092B40; + color:#EBEBEB; +} +.container{ + width:1200px; + padding:50px; + margin:0px auto; + overflow: hidden; + position: relative; +} +.bookLib{ + display: inline-block; + margin:0px; + padding:0px; + height:50px; + padding:0px 10px; + line-height: 50px; + text-decoration: none; + color:white; +} +.bookLib:hover{ + background-color: #EEEEE0; + color:#4D4D4D; +} +.searchArea{ + margin-top: 30px; + float:right; +} +.searchArea>button{ + border:solid 4px #FF7F00; + border-radius: 5px; + background-color: #6495ED; + color:white; + padding:5px 10px; + font-size: 1.3em; + color: white; + background-color: #092B40; + cursor: pointer; +} +.searchArea>input{ + border:solid 3px #FF7F00; + border-radius: 10px; + height:33px; + padding: 2px 10px; + line-height: 33px; + font-size: 1.3em; + margin-right: 5px; + outline: none; + color: white; + background-color: #092B40; +} +.bookList{ + clear: both; + position: relative; + top:20px; + width: 1010px; + margin:0px auto; + z-index: 10; +} +.bookName{ + font-size: 20px; +} +.bookType,.bookPublisher,.bookAuthor,.bookPrice,.bookNum{ + font-size: 17px; +} +.intro{ + font-size: 15px; + color:gray; +} +.book{ + width:1010px; + height:120px; + margin-bottom: 10px; + cursor: pointer; +} +.hover{ + background-color: #FF7F00; + width:10px; + float:left; + height:120px; +} +.bookMain{ + float: left; + width:980px; + padding-left:20px; + background-color: #EBEBEB; +} +.bookDetail{ + width:800px; + background-color:#D9D9D9; + margin:-10px auto 0px auto; +} +.pageListBox{ + left:10px; + top: 20px; + position: relative; + width: 1010px; + margin:10px auto; + color:#EBEBEB; +} +.pageBtn{ + text-align: center; + min-width: 15px; + padding: 0px 10px; + margin-right: 2px; + line-height: 30px; + height:30px; + font-size: 15px; + display: inline-block; + border: solid 2px #EBEBEB; + border-radius: 5px; + color:#EBEBEB; + text-decoration: none; +} +.pageBtn:hover{ + color: #092B40; + background-color: #EBEBEB; + border: solid 2px #FF7F00; +} +.active{ + color: #092B40 !important ; + background-color: #EBEBEB !important ; + border: solid 2px #FF7F00 !important ; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/login.css b/2016-course-DB-master/Lib/main/static/css/login.css new file mode 100644 index 0000000..f2e1ea2 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/login.css @@ -0,0 +1,54 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; +} +.fail{ + color:red; +} +.success{ + color:green; +} +.container{ + width:400px; + margin:300px auto; +} +.inputArea{ + color:#aaa; + width:388px; + display: inline-block; + border:solid 1px #ddd; + border-radius: 2px; + font-size: 14px; + outline: none; + padding: 10px 0px 10px 10px; + margin:15px 0px 15px 0px; +} +.btn{ + height: 38px; + width:184px; + outline: none; + margin-top: 10px; + float:left; + font-size: 14px; + display: inline-block; + text-align: center; + text-decoration: none; + line-height:38px; +} +.loginBtn{ + border: 1px solid #0381AA; + background-color: #00A7DE; + color:white; + cursor:pointer; +} +.loginBtn:hover{ + background-color: #00a1d6;\ +} +.registBtn{ + margin-left: 28px; + color: #555; + border: 1px solid #ccc; +} +.registBtn:hover{ + background-color: gray; + color:white; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/logout.css b/2016-course-DB-master/Lib/main/static/css/logout.css new file mode 100644 index 0000000..f4fb7b8 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/logout.css @@ -0,0 +1,14 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; + position: relative; + margin:0px; + background-color: #092B40; +} +.container{ + width:1200px; + padding:50px; + margin:400px auto; + overflow: hidden; + color:#EBEBEB; + text-align: center; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/regist.css b/2016-course-DB-master/Lib/main/static/css/regist.css new file mode 100644 index 0000000..01864a4 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/regist.css @@ -0,0 +1,54 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; +} +.fail{ + color:red; +} +.success{ + color:green; +} +.container{ + width:400px; + margin:100px auto; +} +.inputArea{ + color:#aaa; + width:388px; + display: inline-block; + border:solid 1px #ddd; + border-radius: 2px; + font-size: 14px; + outline: none; + padding: 10px 0px 10px 10px; + margin:15px 0px 15px 0px; +} +.btn{ + height: 38px; + width:184px; + outline: none; + margin-top: 10px; + float:left; + font-size: 14px; + display: inline-block; + text-align: center; + text-decoration: none; + line-height:38px; +} +.registBtn{ + border: 1px solid #0381AA; + background-color: #00A7DE; + color:white; + cursor:pointer; +} +.registBtn:hover{ + background-color: #00a1d6;\ +} +.backBtn{ + margin-left: 28px; + color: #555; + border: 1px solid #ccc; +} +.backBtn:hover{ + background-color: gray; + color:white; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/css/userDetail.css b/2016-course-DB-master/Lib/main/static/css/userDetail.css new file mode 100644 index 0000000..c5ce20c --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/css/userDetail.css @@ -0,0 +1,107 @@ +body{ + font-family: 'Microsoft YaHei',sans-serif; + position: relative; + margin:0px; + background-color: #092B40; +} +button{ + font-family: 'Microsoft YaHei',sans-serif; + cursor: pointer; +} +.fail{ + color:red; +} +.success{ + color:green; +} +.hid{ + visibility: hidden; +} +.fontBlue{ + color:#092B40; +} +.fontOrange{ + color:#FF7F00; +} +.fontWhite{ + color:#EBEBEB; +} +.backBlue{ + background-color:#092B40; +} +.backOrange{ + background-color: #FF7F00; +} +.backWhite{ + background-color: #EBEBEB; +} +.nav{ + width: 100%; + height:50px; + line-height: 50px; + font-size: 19px; + position:fixed; + background-color: rgba(135,135,135,0.5); + margin: 0px; + top:0px; + left:0px; + padding-left: 400px; + z-index: 100; +} +.bookLib{ + display: inline-block; + margin:0px; + padding:0px; + height:50px; + padding:0px 10px; + line-height: 50px; + text-decoration: none; + color:white; +} +.bookLib:hover{ + background-color: #EEEEE0; + color:#4D4D4D; +} +.currentUser{ + position:fixed; + top:300px; + left:100px; + padding: 20px 20px 10px 20px; + background-color: #EBEBEB; +} +.currentUser>div>a{ + width: 50px; + text-align: center; + display:block; + margin:5px auto; + text-decoration:none; + padding:5px 8px; + background-color:#092B40; + color:#EBEBEB; +} +.container{ + width:1200px; + padding:50px; + margin:0px auto; + overflow: hidden; + position: relative; +} +.userInfoContainer{ + padding: 50px; +} +.infoItem{ + height:30px; + line-height: 30px; + display: block; +} +.infoBefore{ + text-align: center; + display: inline-block; + width: 90px; +} +.borrowTable{ + width: 1000px; +} +.borrowTable td{ + text-align: center; +} \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/scripts/csrf.js b/2016-course-DB-master/Lib/main/static/scripts/csrf.js new file mode 100644 index 0000000..a9a8a3e --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/scripts/csrf.js @@ -0,0 +1,36 @@ +jQuery(document).ajaxSend(function(event, xhr, settings) { + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + function sameOrigin(url) { + // url could be relative or scheme relative or absolute + var host = document.location.host; // host + port + var protocol = document.location.protocol; + var sr_origin = '//' + host; + var origin = protocol + sr_origin; + // Allow absolute or scheme relative URLs to same origin + return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || + (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || + // or any other URL that isn't scheme relative or absolute i.e relative. + !(/^(\/\/|http:|https:).*/.test(url)); + } + function safeMethod(method) { + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); + } + + if (!safeMethod(settings.type) && sameOrigin(settings.url)) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + } +}); \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/scripts/indexStaff.js b/2016-course-DB-master/Lib/main/static/scripts/indexStaff.js new file mode 100644 index 0000000..62608a2 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/scripts/indexStaff.js @@ -0,0 +1,182 @@ +function initUserScan(userName,Page){ + $('#startPage').val(Page); + var userHtml = '',pageHtml = ''; + var username = userName; + var offset = $('#offset').val(),startPage = Page; + $.get('/staffViewUser', + {'username':username, + 'offset':offset, + 'startPage':startPage}, + function(data) { + //console.log(data); + for(var i=0;i'+ + ''+userItem.userid+' '+userItem.username+'' + +''+userItem.userage+'' + +''; + } + $('.templateUserContainer').html(userHtml); + + if(startPage!=1){pageHtml = '<<';} + for(var i=0;i'+pageItem+''; + else pageHtml += ''+pageItem+''; + } + if(startPage != data.pageList[data.pageList.length-1]) pageHtml += '>>'; + $('.pageList').html(pageHtml); + $('.pageBtn').click(function(event) { + //var targetPage = $(this).text(); + //startPage = $('#startPage').val(targetPage); + if($(this).hasClass('next')){ + targetPage = parseInt($('#startPage').val())+1; + } + else if($(this).hasClass('prev')){ + targetPage = parseInt($('#startPage').val())-1; + } + else{ + targetPage = $(this).text(); + } + initUserScan($('#changeUserName').val(),targetPage); + }); + }); +} +initUserScan('',1); +$(document).ready(function(){ + var typeOptions = []; + $.get('/getTypeOptions', function(data) { + typeOptions = data; + //console.log(typeOptions); + }); + $('.changeUserBtnCheck').click(function(event) { + initUserScan($('#changeUserName').val(),1); + }); + $('.returnBtnCheck').click(function(event) { + var bookid=$('#returnBookid').val(); + var userid=$('#returnUserid').val(); + $.get('/staffReturnUserBook',{"bookid":bookid,"userid":userid},function(data) { + $('.returnBookMsg').removeClass('success').removeClass('fail').text(""); + bookid=$('#returnBookid').val(""); + userid=$('#returnUserid').val(""); + if(data.end){ + $('.returnBookMsg').addClass('success').text("还书成功!"); + } + else{ + $('.returnBookMsg').addClass('fail').text("还书失败!请重新操作"); + } + }); + }); + $('.borrowBtnCheck').click(function(event) { + var bookid=$('#borrowBookid').val(); + var userid=$('#borrowUserid').val(); + console.log(bookid+userid); + $.get('/staffBorrowUserBook',{"bookid":bookid,"userid":userid},function(data) { + $('.borrowBookMsg').removeClass('success').removeClass('fail').text(""); + $('#borrowBookid').val(""); + $('#borrowUserid').val(""); + if(data.end){ + $('.borrowBookMsg').addClass('success').text("借书成功!"); + } + else{ + $('.borrowBookMsg').addClass('fail').text("借书失败!请重新操作"); + } + }); + }); + $('.createBtnCheck').click(function(event){ + var bookid = $('#createBookId').val(); + var bookname = $('#createBookName').val(); + var booktype = $('#createBookType').val(); + var bookpub = $('#createBookPub').val(); + var bookauthor = $('#createBookAuthor').val(); + var bookintro = $('#createBookIntro').val(); + var bookprice = $('#createBookPrice').val(); + var booknum = $('#createBookNum').val(); + $.get('/staffCreateBook', + {"bookid":bookid, + "bookname":bookname, + "booktype":booktype, + "bookpublisher":bookpub, + "bookauthor":bookauthor, + "bookintroduction":bookintro, + "bookprice":bookprice, + "booknum":booknum},function(data) { + console.log(data); + }); + }); + $('.addBtnCheck').click(function(event) { + var bookid = $('#addBookId').val(); + var addnum = $('#addBookNum').val(); + $.get('/staffAddBookNum',{"bookid":bookid,"addBookNum":addnum},function(data) { + console.log(data); + }); + }); + $('.changeBookBtnCheck').click(function(event) { + var template =''; + var bookid = $('#changeBookId').val(); + $.get('/viewBook',{"mode":"Detail","startPage":0,"offset":10,"bookLikeName":bookid},function(data) { + optionTemplate = ''; + for(var i=0;i'+option.optionName+'' + } + else optionTemplate+=''+option.optionName+'' + } + console.log(data); + template+= ''+ + ''+ + '图书名称:'+ + ''+ + ''+ + '图书类型:'+ + ''+ + optionTemplate+ + ''+ + ''+ + ''+ + '作者:'+ + ''+ + ''+ + '出版社:'+ + ''+ + ''+ + '简介:'+ + ''+ + ''+ + '价格:'+ + ''+ + ''+ + '库存:'+ + ''; + $('.templateBookContainer').html(template); + $('.changeBookBtnSubmit').removeClass('hid'); + }); + }); + $('.changeBookBtnSubmit').click(function(event) { + var bookid = $('.changeBookId').val(); + var bookname = $('.changeBookName').val(); + var booktype = $('.changeBookType').val(); + var bookauthor = $('.changeBookAuthor').val(); + var bookpublisher = $('.changeBookPublisher').val(); + var bookintro = $('.changeBookIntro').val(); + var bookprice = $('.changeBookPrice').val(); + var booknum = $('.changeBookNum').val(); + $.get('/staffChangeBookInfo', + {"bookid":bookid, + "bookname":bookname, + "booktype":booktype, + "bookauthor":bookauthor, + "bookpublisher":bookpublisher, + "bookintroduction":bookintro, + "bookprice":bookprice, + "booknum":booknum}, + function(data) { + console.log(data); + }); + }); +}); + \ No newline at end of file diff --git a/2016-course-DB-master/Lib/main/static/scripts/jquery.js b/2016-course-DB-master/Lib/main/static/scripts/jquery.js new file mode 100644 index 0000000..f2fc274 --- /dev/null +++ b/2016-course-DB-master/Lib/main/static/scripts/jquery.js @@ -0,0 +1,10074 @@ +/*eslint-disable no-unused-vars*/ +/*! + * jQuery JavaScript Library v3.1.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2016-07-07T21:44Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.1.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return 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; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = 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() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + 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.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.0 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-01-04 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + // Known :disabled false positives: + // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) + // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Check form elements and option elements for explicit disabling + return "label" in elem && elem.disabled === disabled || + "form" in elem && elem.disabled === disabled || + + // Check non-disabled form elements for fieldset[disabled] ancestors + "form" in elem && elem.disabled === false && ( + // Support: IE6-11+ + // Ancestry is covered for us + elem.isDisabled === disabled || + + // Otherwise, assume any non- under fieldset[disabled] is disabled + /* jshint -W018 */ + elem.isDisabled !== !disabled && + ("label" in elem || !disabledAncestor( elem )) !== disabled + ); + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID 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 https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +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( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + + } + + 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 ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; + } ); +} + +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, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var 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 = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + resolve.call( undefined, value ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.call( undefined, value ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( jQuery.isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // 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 ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ jQuery.camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ jQuery.camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( jQuery.camelCase ); + } else { + key = jQuery.camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnotwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = 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 ) ? JSON.parse( data ) : + data; + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ), + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "", "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "" ], + col: [ 2, "", "" ], + tr: [ 2, "", "" ], + td: [ 3, "", "" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = "x"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( 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 if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( 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 data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support: IE <=9 + // 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 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && ( 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; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: jQuery.isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + 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; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + return ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = / + + + + {% if is_staff %} + 管理员中心 + {% else %} + 用户中心 + {% endif %} + 图书库 + + + + {{currentUser.userId}} + {% if is_staff %} + 管理员 + {% else %} + 用户 + {% endif %} + + {{currentUser.userName}} + 登出 + + + + + + + + + 借 + + bookId : + + + userId : + + 借阅 + + + + 还 + + bookId : + + + userId : + + 还书 + + + + + + 添加图书数量 + + 图书编号 : + + + 数量 : + + 添加 + + + 添加图书类别 + + 图书编号 : + + + 书名 : + + + 类型 : + + {% for typeItem in typeList %} + {{typeItem.typeInfo}} + {% endfor %} + + + + 出版社 : + + + 作者 : + + + 简介 : + + + 价格 : + + + 数量 : + + 添加 + + + + + + + + Check + + 更改图书信息 + + + Change + + + + + + + + + + Check + + 浏览用户信息 + + + + + + + + + + +