diff --git a/.gitignore b/.gitignore
index 5666883d..5ae79525 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ config.rb
!/usr/plugins/HelloWorld
/usr/themes/
!/usr/themes/default
+node_modules/
diff --git a/admin/css/grid.css b/admin/css/grid.css
index 6303d21f..c0c8f250 100644
--- a/admin/css/grid.css
+++ b/admin/css/grid.css
@@ -1,748 +1,211 @@
-/*
- * Bento Grid System
- * Source: https://github.com/fenbox/bento
- * Version: 1.2.8
- * Update: 2013.11.25
- */
-/* line 23, ../scss/grid.scss */
-.container, .row [class*="col-"] {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box; }
-
-/* line 31, ../scss/grid.scss */
-.container {
- margin-left: auto;
- margin-right: auto;
- padding-left: 10px;
- padding-right: 10px; }
-
-/* line 40, ../scss/grid.scss */
-.row {
- margin-right: -10px;
- margin-left: -10px; }
-
-/* line 46, ../scss/grid.scss */
-.row [class*="col-"] {
- float: left;
- min-height: 1px;
- padding-right: 10px;
- padding-left: 10px; }
-
-/* line 54, ../scss/grid.scss */
-.row [class*="-push-"],
-.row [class*="-pull-"] {
- position: relative; }
-
-/*
- * Mobile and up
- */
-/* line 65, ../scss/grid.scss */
-.col-mb-1 {
- width: 8.33333%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-2 {
- width: 16.66667%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-3 {
- width: 25%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-4 {
- width: 33.33333%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-5 {
- width: 41.66667%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-6 {
- width: 50%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-7 {
- width: 58.33333%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-8 {
- width: 66.66667%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-9 {
- width: 75%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-10 {
- width: 83.33333%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-11 {
- width: 91.66667%; }
-
-/* line 65, ../scss/grid.scss */
-.col-mb-12 {
- width: 100%; }
-
-/*
- * Tablet and up
- */
-@media (min-width: 768px) {
- /* line 76, ../scss/grid.scss */
- .container {
- max-width: 728px; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-1 {
- width: 8.33333%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-2 {
- width: 16.66667%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-3 {
- width: 25%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-4 {
- width: 33.33333%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-5 {
- width: 41.66667%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-6 {
- width: 50%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-7 {
- width: 58.33333%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-8 {
- width: 66.66667%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-9 {
- width: 75%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-10 {
- width: 83.33333%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-11 {
- width: 91.66667%; }
-
- /* line 82, ../scss/grid.scss */
- .col-tb-12 {
- width: 100%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-0 {
- margin-left: 0%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-1 {
- margin-left: 8.33333%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-2 {
- margin-left: 16.66667%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-3 {
- margin-left: 25%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-4 {
- margin-left: 33.33333%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-5 {
- margin-left: 41.66667%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-6 {
- margin-left: 50%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-7 {
- margin-left: 58.33333%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-8 {
- margin-left: 66.66667%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-9 {
- margin-left: 75%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-10 {
- margin-left: 83.33333%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-11 {
- margin-left: 91.66667%; }
-
- /* line 89, ../scss/grid.scss */
- .col-tb-offset-12 {
- margin-left: 100%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-0 {
- right: 0%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-1 {
- right: 8.33333%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-2 {
- right: 16.66667%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-3 {
- right: 25%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-4 {
- right: 33.33333%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-5 {
- right: 41.66667%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-6 {
- right: 50%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-7 {
- right: 58.33333%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-8 {
- right: 66.66667%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-9 {
- right: 75%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-10 {
- right: 83.33333%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-11 {
- right: 91.66667%; }
-
- /* line 96, ../scss/grid.scss */
- .col-tb-pull-12 {
- right: 100%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-0 {
- left: 0%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-1 {
- left: 8.33333%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-2 {
- left: 16.66667%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-3 {
- left: 25%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-4 {
- left: 33.33333%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-5 {
- left: 41.66667%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-6 {
- left: 50%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-7 {
- left: 58.33333%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-8 {
- left: 66.66667%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-9 {
- left: 75%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-10 {
- left: 83.33333%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-11 {
- left: 91.66667%; }
-
- /* line 103, ../scss/grid.scss */
- .col-tb-push-12 {
- left: 100%; } }
-/*
- * Desktop and up
- */
-@media (min-width: 992px) {
- /* line 115, ../scss/grid.scss */
- .container {
- max-width: 952px; }
-
- /* line 121, ../scss/grid.scss */
- .col-1 {
- width: 8.33333%; }
-
- /* line 121, ../scss/grid.scss */
- .col-2 {
- width: 16.66667%; }
-
- /* line 121, ../scss/grid.scss */
- .col-3 {
- width: 25%; }
-
- /* line 121, ../scss/grid.scss */
- .col-4 {
- width: 33.33333%; }
-
- /* line 121, ../scss/grid.scss */
- .col-5 {
- width: 41.66667%; }
-
- /* line 121, ../scss/grid.scss */
- .col-6 {
- width: 50%; }
-
- /* line 121, ../scss/grid.scss */
- .col-7 {
- width: 58.33333%; }
-
- /* line 121, ../scss/grid.scss */
- .col-8 {
- width: 66.66667%; }
-
- /* line 121, ../scss/grid.scss */
- .col-9 {
- width: 75%; }
-
- /* line 121, ../scss/grid.scss */
- .col-10 {
- width: 83.33333%; }
-
- /* line 121, ../scss/grid.scss */
- .col-11 {
- width: 91.66667%; }
-
- /* line 121, ../scss/grid.scss */
- .col-12 {
- width: 100%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-0 {
- margin-left: 0%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-1 {
- margin-left: 8.33333%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-2 {
- margin-left: 16.66667%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-3 {
- margin-left: 25%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-4 {
- margin-left: 33.33333%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-5 {
- margin-left: 41.66667%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-6 {
- margin-left: 50%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-7 {
- margin-left: 58.33333%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-8 {
- margin-left: 66.66667%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-9 {
- margin-left: 75%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-10 {
- margin-left: 83.33333%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-11 {
- margin-left: 91.66667%; }
-
- /* line 128, ../scss/grid.scss */
- .col-offset-12 {
- margin-left: 100%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-0 {
- right: 0%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-1 {
- right: 8.33333%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-2 {
- right: 16.66667%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-3 {
- right: 25%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-4 {
- right: 33.33333%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-5 {
- right: 41.66667%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-6 {
- right: 50%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-7 {
- right: 58.33333%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-8 {
- right: 66.66667%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-9 {
- right: 75%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-10 {
- right: 83.33333%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-11 {
- right: 91.66667%; }
-
- /* line 135, ../scss/grid.scss */
- .col-pull-12 {
- right: 100%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-0 {
- left: 0%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-1 {
- left: 8.33333%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-2 {
- left: 16.66667%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-3 {
- left: 25%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-4 {
- left: 33.33333%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-5 {
- left: 41.66667%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-6 {
- left: 50%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-7 {
- left: 58.33333%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-8 {
- left: 66.66667%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-9 {
- left: 75%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-10 {
- left: 83.33333%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-11 {
- left: 91.66667%; }
-
- /* line 142, ../scss/grid.scss */
- .col-push-12 {
- left: 100%; } }
-/*
- * Widescreen and up
- */
-@media (min-width: 1200px) {
- /* line 154, ../scss/grid.scss */
- .container {
- max-width: 1160px; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-1 {
- width: 8.33333%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-2 {
- width: 16.66667%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-3 {
- width: 25%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-4 {
- width: 33.33333%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-5 {
- width: 41.66667%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-6 {
- width: 50%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-7 {
- width: 58.33333%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-8 {
- width: 66.66667%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-9 {
- width: 75%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-10 {
- width: 83.33333%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-11 {
- width: 91.66667%; }
-
- /* line 160, ../scss/grid.scss */
- .col-wd-12 {
- width: 100%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-0 {
- margin-left: 0%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-1 {
- margin-left: 8.33333%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-2 {
- margin-left: 16.66667%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-3 {
- margin-left: 25%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-4 {
- margin-left: 33.33333%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-5 {
- margin-left: 41.66667%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-6 {
- margin-left: 50%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-7 {
- margin-left: 58.33333%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-8 {
- margin-left: 66.66667%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-9 {
- margin-left: 75%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-10 {
- margin-left: 83.33333%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-11 {
- margin-left: 91.66667%; }
-
- /* line 167, ../scss/grid.scss */
- .col-wd-offset-12 {
- margin-left: 100%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-0 {
- right: 0%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-1 {
- right: 8.33333%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-2 {
- right: 16.66667%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-3 {
- right: 25%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-4 {
- right: 33.33333%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-5 {
- right: 41.66667%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-6 {
- right: 50%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-7 {
- right: 58.33333%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-8 {
- right: 66.66667%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-9 {
- right: 75%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-10 {
- right: 83.33333%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-11 {
- right: 91.66667%; }
-
- /* line 174, ../scss/grid.scss */
- .col-wd-pull-12 {
- right: 100%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-0 {
- left: 0%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-1 {
- left: 8.33333%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-2 {
- left: 16.66667%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-3 {
- left: 25%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-4 {
- left: 33.33333%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-5 {
- left: 41.66667%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-6 {
- left: 50%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-7 {
- left: 58.33333%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-8 {
- left: 66.66667%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-9 {
- left: 75%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-10 {
- left: 83.33333%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-11 {
- left: 91.66667%; }
-
- /* line 181, ../scss/grid.scss */
- .col-wd-push-12 {
- left: 100%; } }
-/*
- * Responsive kit
- */
-@media (max-width: 767px) {
- /* line 194, ../scss/grid.scss */
- .kit-hidden-mb {
- display: none; } }
-@media (max-width: 991px) {
- /* line 201, ../scss/grid.scss */
- .kit-hidden-tb {
- display: none; } }
-@media (max-width: 1199px) {
- /* line 208, ../scss/grid.scss */
- .kit-hidden {
- display: none; } }
-/*
- * Clearfix
- */
-/* line 217, ../scss/grid.scss */
-.clearfix, .row {
- zoom: 1; }
- /* line 219, ../scss/grid.scss */
- .clearfix:before, .row:before, .clearfix:after, .row:after {
- content: " ";
- display: table; }
- /* line 223, ../scss/grid.scss */
- .clearfix:after, .row:after {
- clear: both; }
+/* Bento Grid System Source: https://github.com/fenbox/bento Version: 1.2.8 Update: 2013.11.25 */
+.container, .row [class*="col-"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
+
+.container { margin-left: auto; margin-right: auto; padding-left: 10px; padding-right: 10px; }
+
+.row { margin-right: -10px; margin-left: -10px; }
+
+.row [class*="col-"] { float: left; min-height: 1px; padding-right: 10px; padding-left: 10px; }
+
+.row [class*="-push-"], .row [class*="-pull-"] { position: relative; }
+
+/* Mobile and up */
+.col-mb-1 { width: 8.33333%; }
+
+.col-mb-2 { width: 16.66667%; }
+
+.col-mb-3 { width: 25%; }
+
+.col-mb-4 { width: 33.33333%; }
+
+.col-mb-5 { width: 41.66667%; }
+
+.col-mb-6 { width: 50%; }
+
+.col-mb-7 { width: 58.33333%; }
+
+.col-mb-8 { width: 66.66667%; }
+
+.col-mb-9 { width: 75%; }
+
+.col-mb-10 { width: 83.33333%; }
+
+.col-mb-11 { width: 91.66667%; }
+
+.col-mb-12 { width: 100%; }
+
+/* Tablet and up */
+@media (min-width: 768px) { .container { max-width: 728px; }
+ .col-tb-1 { width: 8.33333%; }
+ .col-tb-2 { width: 16.66667%; }
+ .col-tb-3 { width: 25%; }
+ .col-tb-4 { width: 33.33333%; }
+ .col-tb-5 { width: 41.66667%; }
+ .col-tb-6 { width: 50%; }
+ .col-tb-7 { width: 58.33333%; }
+ .col-tb-8 { width: 66.66667%; }
+ .col-tb-9 { width: 75%; }
+ .col-tb-10 { width: 83.33333%; }
+ .col-tb-11 { width: 91.66667%; }
+ .col-tb-12 { width: 100%; }
+ .col-tb-offset-0 { margin-left: 0%; }
+ .col-tb-offset-1 { margin-left: 8.33333%; }
+ .col-tb-offset-2 { margin-left: 16.66667%; }
+ .col-tb-offset-3 { margin-left: 25%; }
+ .col-tb-offset-4 { margin-left: 33.33333%; }
+ .col-tb-offset-5 { margin-left: 41.66667%; }
+ .col-tb-offset-6 { margin-left: 50%; }
+ .col-tb-offset-7 { margin-left: 58.33333%; }
+ .col-tb-offset-8 { margin-left: 66.66667%; }
+ .col-tb-offset-9 { margin-left: 75%; }
+ .col-tb-offset-10 { margin-left: 83.33333%; }
+ .col-tb-offset-11 { margin-left: 91.66667%; }
+ .col-tb-offset-12 { margin-left: 100%; }
+ .col-tb-pull-0 { right: 0%; }
+ .col-tb-pull-1 { right: 8.33333%; }
+ .col-tb-pull-2 { right: 16.66667%; }
+ .col-tb-pull-3 { right: 25%; }
+ .col-tb-pull-4 { right: 33.33333%; }
+ .col-tb-pull-5 { right: 41.66667%; }
+ .col-tb-pull-6 { right: 50%; }
+ .col-tb-pull-7 { right: 58.33333%; }
+ .col-tb-pull-8 { right: 66.66667%; }
+ .col-tb-pull-9 { right: 75%; }
+ .col-tb-pull-10 { right: 83.33333%; }
+ .col-tb-pull-11 { right: 91.66667%; }
+ .col-tb-pull-12 { right: 100%; }
+ .col-tb-push-0 { left: 0%; }
+ .col-tb-push-1 { left: 8.33333%; }
+ .col-tb-push-2 { left: 16.66667%; }
+ .col-tb-push-3 { left: 25%; }
+ .col-tb-push-4 { left: 33.33333%; }
+ .col-tb-push-5 { left: 41.66667%; }
+ .col-tb-push-6 { left: 50%; }
+ .col-tb-push-7 { left: 58.33333%; }
+ .col-tb-push-8 { left: 66.66667%; }
+ .col-tb-push-9 { left: 75%; }
+ .col-tb-push-10 { left: 83.33333%; }
+ .col-tb-push-11 { left: 91.66667%; }
+ .col-tb-push-12 { left: 100%; } }
+
+/* Desktop and up */
+@media (min-width: 992px) { .container { max-width: 952px; }
+ .col-1 { width: 8.33333%; }
+ .col-2 { width: 16.66667%; }
+ .col-3 { width: 25%; }
+ .col-4 { width: 33.33333%; }
+ .col-5 { width: 41.66667%; }
+ .col-6 { width: 50%; }
+ .col-7 { width: 58.33333%; }
+ .col-8 { width: 66.66667%; }
+ .col-9 { width: 75%; }
+ .col-10 { width: 83.33333%; }
+ .col-11 { width: 91.66667%; }
+ .col-12 { width: 100%; }
+ .col-offset-0 { margin-left: 0%; }
+ .col-offset-1 { margin-left: 8.33333%; }
+ .col-offset-2 { margin-left: 16.66667%; }
+ .col-offset-3 { margin-left: 25%; }
+ .col-offset-4 { margin-left: 33.33333%; }
+ .col-offset-5 { margin-left: 41.66667%; }
+ .col-offset-6 { margin-left: 50%; }
+ .col-offset-7 { margin-left: 58.33333%; }
+ .col-offset-8 { margin-left: 66.66667%; }
+ .col-offset-9 { margin-left: 75%; }
+ .col-offset-10 { margin-left: 83.33333%; }
+ .col-offset-11 { margin-left: 91.66667%; }
+ .col-offset-12 { margin-left: 100%; }
+ .col-pull-0 { right: 0%; }
+ .col-pull-1 { right: 8.33333%; }
+ .col-pull-2 { right: 16.66667%; }
+ .col-pull-3 { right: 25%; }
+ .col-pull-4 { right: 33.33333%; }
+ .col-pull-5 { right: 41.66667%; }
+ .col-pull-6 { right: 50%; }
+ .col-pull-7 { right: 58.33333%; }
+ .col-pull-8 { right: 66.66667%; }
+ .col-pull-9 { right: 75%; }
+ .col-pull-10 { right: 83.33333%; }
+ .col-pull-11 { right: 91.66667%; }
+ .col-pull-12 { right: 100%; }
+ .col-push-0 { left: 0%; }
+ .col-push-1 { left: 8.33333%; }
+ .col-push-2 { left: 16.66667%; }
+ .col-push-3 { left: 25%; }
+ .col-push-4 { left: 33.33333%; }
+ .col-push-5 { left: 41.66667%; }
+ .col-push-6 { left: 50%; }
+ .col-push-7 { left: 58.33333%; }
+ .col-push-8 { left: 66.66667%; }
+ .col-push-9 { left: 75%; }
+ .col-push-10 { left: 83.33333%; }
+ .col-push-11 { left: 91.66667%; }
+ .col-push-12 { left: 100%; } }
+
+/* Widescreen and up */
+@media (min-width: 1200px) { .container { max-width: 1160px; }
+ .col-wd-1 { width: 8.33333%; }
+ .col-wd-2 { width: 16.66667%; }
+ .col-wd-3 { width: 25%; }
+ .col-wd-4 { width: 33.33333%; }
+ .col-wd-5 { width: 41.66667%; }
+ .col-wd-6 { width: 50%; }
+ .col-wd-7 { width: 58.33333%; }
+ .col-wd-8 { width: 66.66667%; }
+ .col-wd-9 { width: 75%; }
+ .col-wd-10 { width: 83.33333%; }
+ .col-wd-11 { width: 91.66667%; }
+ .col-wd-12 { width: 100%; }
+ .col-wd-offset-0 { margin-left: 0%; }
+ .col-wd-offset-1 { margin-left: 8.33333%; }
+ .col-wd-offset-2 { margin-left: 16.66667%; }
+ .col-wd-offset-3 { margin-left: 25%; }
+ .col-wd-offset-4 { margin-left: 33.33333%; }
+ .col-wd-offset-5 { margin-left: 41.66667%; }
+ .col-wd-offset-6 { margin-left: 50%; }
+ .col-wd-offset-7 { margin-left: 58.33333%; }
+ .col-wd-offset-8 { margin-left: 66.66667%; }
+ .col-wd-offset-9 { margin-left: 75%; }
+ .col-wd-offset-10 { margin-left: 83.33333%; }
+ .col-wd-offset-11 { margin-left: 91.66667%; }
+ .col-wd-offset-12 { margin-left: 100%; }
+ .col-wd-pull-0 { right: 0%; }
+ .col-wd-pull-1 { right: 8.33333%; }
+ .col-wd-pull-2 { right: 16.66667%; }
+ .col-wd-pull-3 { right: 25%; }
+ .col-wd-pull-4 { right: 33.33333%; }
+ .col-wd-pull-5 { right: 41.66667%; }
+ .col-wd-pull-6 { right: 50%; }
+ .col-wd-pull-7 { right: 58.33333%; }
+ .col-wd-pull-8 { right: 66.66667%; }
+ .col-wd-pull-9 { right: 75%; }
+ .col-wd-pull-10 { right: 83.33333%; }
+ .col-wd-pull-11 { right: 91.66667%; }
+ .col-wd-pull-12 { right: 100%; }
+ .col-wd-push-0 { left: 0%; }
+ .col-wd-push-1 { left: 8.33333%; }
+ .col-wd-push-2 { left: 16.66667%; }
+ .col-wd-push-3 { left: 25%; }
+ .col-wd-push-4 { left: 33.33333%; }
+ .col-wd-push-5 { left: 41.66667%; }
+ .col-wd-push-6 { left: 50%; }
+ .col-wd-push-7 { left: 58.33333%; }
+ .col-wd-push-8 { left: 66.66667%; }
+ .col-wd-push-9 { left: 75%; }
+ .col-wd-push-10 { left: 83.33333%; }
+ .col-wd-push-11 { left: 91.66667%; }
+ .col-wd-push-12 { left: 100%; } }
+
+/* Responsive kit */
+@media (max-width: 767px) { .kit-hidden-mb { display: none; } }
+
+@media (max-width: 991px) { .kit-hidden-tb { display: none; } }
+
+@media (max-width: 1199px) { .kit-hidden { display: none; } }
+
+/* Clearfix */
+.clearfix, .row { zoom: 1; }
+
+.clearfix:before, .row:before, .clearfix:after, .row:after { content: " "; display: table; }
+
+.clearfix:after, .row:after { clear: both; }
diff --git a/admin/css/style.css b/admin/css/style.css
index 45f1ba4e..22b56e59 100644
--- a/admin/css/style.css
+++ b/admin/css/style.css
@@ -1,2178 +1,837 @@
@charset "UTF-8";
/* vim: set et sw=2 ts=2 sts=2 fdm=marker ff=unix fenc=utf8 */
-/**
-* Typecho 后台样式
-*
-* @author Typecho Team
-* @since 2008-09-26
-* @update 2013-11-02
-* @link http://www.typecho.org/
-* @version 0.9
-*/
-/**
-* Typecho 全局样式
-*/
-/* line 18, ../scss/style.scss */
-html {
- height: 100%; }
+/** Typecho 后台样式 @author Typecho Team @since 2008-09-26 @update 2013-11-02 @link http://www.typecho.org/ @version 0.9 */
+/** Typecho 全局样式 */
+html { height: 100%; }
-/* line 22, ../scss/style.scss */
-body {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- background: #F6F6F3;
- color: #444;
- font-size: 87.5%;
- line-height: 1.5; }
+body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; background: #F6F6F3; color: #444; font-size: 87.5%; line-height: 1.5; }
-/* line 30, ../scss/style.scss */
-a {
- color: #467B96;
- text-decoration: none; }
- /* line 33, ../scss/style.scss */
- a:hover {
- color: #499BC3;
- text-decoration: underline; }
+a { color: #467B96; text-decoration: none; }
-/* line 39, ../scss/style.scss */
-code, pre, .mono {
- font-family: Menlo, Monaco, Consolas, "Courier New", monospace; }
+a:hover { color: #499BC3; text-decoration: underline; }
-/* line 43, ../scss/style.scss */
-.p {
- margin: 1em 0; }
+code, pre, .mono { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; }
-/* line 45, ../scss/style.scss */
-.body-100 {
- height: 100%; }
+.p { margin: 1em 0; }
-/* line 49, ../scss/style.scss */
-a.balloon-button {
- display: inline-block;
- padding: 0 6px;
- min-width: 12px;
- height: 18px;
- line-height: 18px;
- background: #D8E7EE;
- font-size: .85714em;
- text-align: center;
- text-decoration: none;
- /** 修正ie中文不对齐 */
- zoom: 1;
- -moz-border-radius: 30px;
- -webkit-border-radius: 30px;
- border-radius: 30px;
- white-space: nowrap; }
+.body-100 { height: 100%; }
-/* line 69, ../scss/style.scss */
-a.button:hover, a.balloon-button:hover {
- background-color: #A5CADC;
- color: #FFF;
- text-decoration: none; }
+a.balloon-button { display: inline-block; padding: 0 6px; min-width: 12px; height: 18px; line-height: 18px; background: #D8E7EE; font-size: .85714em; text-align: center; text-decoration: none; /** 修正ie中文不对齐 */ zoom: 1; -moz-border-radius: 30px; -webkit-border-radius: 30px; border-radius: 30px; white-space: nowrap; }
-/**
-* Forms
-*/
-/* line 5, ../scss/_forms.scss */
-input[type=text], input[type=password], input[type=email],
-textarea {
- background: #FFF;
- border: 1px solid #D9D9D6;
- padding: 7px;
- border-radius: 2px;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box; }
+a.button:hover, a.balloon-button:hover { background-color: #A5CADC; color: #FFF; text-decoration: none; }
-/* line 18, ../scss/_forms.scss */
-textarea {
- resize: vertical;
- line-height: 1.5; }
+/** Forms */
+input[type=text], input[type=password], input[type=email], textarea { background: #FFF; border: 1px solid #D9D9D6; padding: 7px; border-radius: 2px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
-/* line 23, ../scss/_forms.scss */
-input[type="radio"], input[type="checkbox"] {
- margin-right: 3px; }
+textarea { resize: vertical; line-height: 1.5; }
-/* line 26, ../scss/_forms.scss */
-input.text-s, textarea.text-s {
- padding: 5px; }
-/* line 27, ../scss/_forms.scss */
-input.text-l, textarea.text-l {
- padding: 10px;
- font-size: 1.14286em; }
+input[type="radio"], input[type="checkbox"] { margin-right: 3px; }
-/* line 33, ../scss/_forms.scss */
-.w-10 {
- width: 10%; }
+input.text-s, textarea.text-s { padding: 5px; }
-/* line 34, ../scss/_forms.scss */
-.w-20 {
- width: 20%; }
+input.text-l, textarea.text-l { padding: 10px; font-size: 1.14286em; }
-/* line 35, ../scss/_forms.scss */
-.w-30 {
- width: 30%; }
+.w-10 { width: 10%; }
-/* line 36, ../scss/_forms.scss */
-.w-40 {
- width: 40%; }
+.w-20 { width: 20%; }
-/* line 37, ../scss/_forms.scss */
-.w-50 {
- width: 50%; }
+.w-30 { width: 30%; }
-/* line 38, ../scss/_forms.scss */
-.w-60 {
- width: 60%; }
+.w-40 { width: 40%; }
-/* line 39, ../scss/_forms.scss */
-.w-70 {
- width: 70%; }
+.w-50 { width: 50%; }
-/* line 40, ../scss/_forms.scss */
-.w-80 {
- width: 80%; }
+.w-60 { width: 60%; }
-/* line 41, ../scss/_forms.scss */
-.w-90 {
- width: 90%; }
+.w-70 { width: 70%; }
-/* line 42, ../scss/_forms.scss */
-.w-100 {
- width: 100%; }
+.w-80 { width: 80%; }
-/* line 44, ../scss/_forms.scss */
-select {
- border: 1px solid #CCC;
- height: 28px; }
+.w-90 { width: 90%; }
-/**
-* Buttons
-*/
-/* line 28, ../scss/_buttons.scss */
-.btn, #ui-datepicker-div .ui-datepicker-current,
-#ui-datepicker-div .ui-datepicker-close {
- border: none;
- background-color: #E9E9E6;
- cursor: pointer;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
- display: inline-block;
- padding: 0 12px;
- height: 32px;
- color: #666;
- vertical-align: middle;
- zoom: 1; }
- /* line 15, ../scss/_buttons.scss */
- .btn:hover, #ui-datepicker-div .ui-datepicker-current:hover,
- #ui-datepicker-div .ui-datepicker-close:hover {
- -moz-transition-duration: 0.4s;
- -o-transition-duration: 0.4s;
- -webkit-transition-duration: 0.4s;
- transition-duration: 0.4s;
- background-color: #dbdbd6; }
- /* line 19, ../scss/_buttons.scss */
- .btn:active, #ui-datepicker-div .ui-datepicker-current:active,
- #ui-datepicker-div .ui-datepicker-close:active, .btn.active, #ui-datepicker-div .active.ui-datepicker-current,
- #ui-datepicker-div .active.ui-datepicker-close {
- background-color: #d6d6d0; }
- /* line 22, ../scss/_buttons.scss */
- .btn:disabled, #ui-datepicker-div .ui-datepicker-current:disabled,
- #ui-datepicker-div .ui-datepicker-close:disabled {
- background-color: #f7f7f6;
- cursor: default; }
- /* line 38, ../scss/_buttons.scss */
- .btn:disabled, #ui-datepicker-div .ui-datepicker-current:disabled,
- #ui-datepicker-div .ui-datepicker-close:disabled {
- color: #999; }
+.w-100 { width: 100%; }
-/* line 43, ../scss/_buttons.scss */
-.btn-xs, #ui-datepicker-div .ui-datepicker-current,
-#ui-datepicker-div .ui-datepicker-close {
- padding: 0 10px;
- height: 25px;
- font-size: 13px; }
+select { border: 1px solid #CCC; height: 28px; }
-/* line 48, ../scss/_buttons.scss */
-.btn-s {
- height: 28px; }
+/** Buttons */
+.btn, #ui-datepicker-div .ui-datepicker-current, #ui-datepicker-div .ui-datepicker-close { border: none; background-color: #E9E9E6; cursor: pointer; border-radius: 2px; display: inline-block; padding: 0 12px; height: 32px; color: #666; vertical-align: middle; zoom: 1; }
-/* line 49, ../scss/_buttons.scss */
-.btn-l {
- height: 40px;
- font-size: 1.14286em;
- font-weight: bold; }
+.btn:hover, #ui-datepicker-div .ui-datepicker-current:hover, #ui-datepicker-div .ui-datepicker-close:hover { transition-duration: .4s; background-color: #dbdbd6; }
-/* line 55, ../scss/_buttons.scss */
-.primary {
- border: none;
- background-color: #467B96;
- cursor: pointer;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
- color: #FFF; }
- /* line 15, ../scss/_buttons.scss */
- .primary:hover {
- -moz-transition-duration: 0.4s;
- -o-transition-duration: 0.4s;
- -webkit-transition-duration: 0.4s;
- transition-duration: 0.4s;
- background-color: #3c6a81; }
- /* line 19, ../scss/_buttons.scss */
- .primary:active, .primary.active {
- background-color: #39647a; }
- /* line 22, ../scss/_buttons.scss */
- .primary:disabled {
- background-color: #508cab;
- cursor: default; }
+.btn:active, #ui-datepicker-div .ui-datepicker-current:active, #ui-datepicker-div .ui-datepicker-close:active, .btn.active, #ui-datepicker-div .active.ui-datepicker-current, #ui-datepicker-div .active.ui-datepicker-close { background-color: #d6d6d0; }
-/* line 60, ../scss/_buttons.scss */
-.btn-group {
- display: inline-block; }
+.btn:disabled, #ui-datepicker-div .ui-datepicker-current:disabled, #ui-datepicker-div .ui-datepicker-close:disabled { background-color: #f7f7f6; cursor: default; }
-/* line 64, ../scss/_buttons.scss */
-.btn-warn {
- border: none;
- background-color: #B94A48;
- cursor: pointer;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
- color: #FFF; }
- /* line 15, ../scss/_buttons.scss */
- .btn-warn:hover {
- -moz-transition-duration: 0.4s;
- -o-transition-duration: 0.4s;
- -webkit-transition-duration: 0.4s;
- transition-duration: 0.4s;
- background-color: #a4403f; }
- /* line 19, ../scss/_buttons.scss */
- .btn-warn:active, .btn-warn.active {
- background-color: #9c3e3c; }
- /* line 22, ../scss/_buttons.scss */
- .btn-warn:disabled {
- background-color: #c1605e;
- cursor: default; }
+.btn:disabled, #ui-datepicker-div .ui-datepicker-current:disabled, #ui-datepicker-div .ui-datepicker-close:disabled { color: #999; }
-/* line 69, ../scss/_buttons.scss */
-.btn-link,
-.btn-link:hover,
-.btn-link:focus,
-.btn-link:active,
-.btn-link.active {
- background-color: transparent; }
+.btn-xs, #ui-datepicker-div .ui-datepicker-current, #ui-datepicker-div .ui-datepicker-close { padding: 0 10px; height: 25px; font-size: 13px; }
+
+.btn-s { height: 28px; }
+
+.btn-l { height: 40px; font-size: 1.14286em; font-weight: bold; }
+
+.primary { border: none; background-color: #467B96; cursor: pointer; border-radius: 2px; color: #FFF; }
+
+.primary:hover { transition-duration: .4s; background-color: #3c6a81; }
+
+.primary:active, .primary.active { background-color: #39647a; }
+
+.primary:disabled { background-color: #508cab; cursor: default; }
+
+.btn-group { display: inline-block; }
+
+.btn-warn { border: none; background-color: #B94A48; cursor: pointer; border-radius: 2px; color: #FFF; }
+
+.btn-warn:hover { transition-duration: .4s; background-color: #a4403f; }
+
+.btn-warn:active, .btn-warn.active { background-color: #9c3e3c; }
+
+.btn-warn:disabled { background-color: #c1605e; cursor: default; }
+
+.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active, .btn-link.active { background-color: transparent; }
/* 下拉菜单 */
-/* line 78, ../scss/_buttons.scss */
-.btn-drop {
- position: relative; }
+.btn-drop { position: relative; }
-/* line 81, ../scss/_buttons.scss */
-.dropdown-toggle {
- padding-right: 8px; }
+.dropdown-toggle { padding-right: 8px; }
-/* line 84, ../scss/_buttons.scss */
-.dropdown-menu {
- list-style: none;
- position: absolute;
- z-index: 2;
- left: 0;
- margin: 0;
- padding: 0;
- border: 1px solid #D9D9D6;
- background: #FFF;
- text-align: left;
- min-width: 108px;
- display: none; }
- /* line 97, ../scss/_buttons.scss */
- .dropdown-menu li {
- white-space: nowrap; }
- /* line 99, ../scss/_buttons.scss */
- .dropdown-menu li.multiline {
- padding: 5px 12px 12px; }
- /* line 104, ../scss/_buttons.scss */
- .dropdown-menu a {
- display: block;
- padding: 5px 12px;
- color: #666; }
- /* line 108, ../scss/_buttons.scss */
- .dropdown-menu a:hover {
- background: #F6F6F3;
- text-decoration: none !important; }
+.dropdown-menu { list-style: none; position: absolute; z-index: 2; left: 0; margin: 0; padding: 0; border: 1px solid #D9D9D6; background: #FFF; text-align: left; min-width: 108px; display: none; }
-/**
-* 提示信息框
-*/
-/* line 6, ../scss/_messages.scss */
-.message {
- padding: 8px 10px;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px; }
+.dropdown-menu li { white-space: nowrap; }
-/* line 11, ../scss/_messages.scss */
-.message a {
- font-weight: bold;
- text-decoration: underline; }
+.dropdown-menu li.multiline { padding: 5px 12px 12px; }
-/* line 16, ../scss/_messages.scss */
-.error {
- background: #FBE3E4;
- color: #8A1F11; }
+.dropdown-menu a { display: block; padding: 5px 12px; color: #666; }
-/* line 20, ../scss/_messages.scss */
-.error a {
- color: #8A1F11; }
+.dropdown-menu a:hover { background: #F6F6F3; text-decoration: none !important; }
-/* line 22, ../scss/_messages.scss */
-.notice {
- background: #FFF6BF;
- color: #8A6D3B; }
+/** 提示信息框 */
+.message { padding: 8px 10px; border-radius: 2px; }
-/* line 26, ../scss/_messages.scss */
-.notice a {
- color: #8A6D3B; }
+.message a { font-weight: bold; text-decoration: underline; }
-/* line 28, ../scss/_messages.scss */
-.success {
- background: #E6EFC2;
- color: #264409; }
+.error { background: #FBE3E4; color: #8A1F11; }
-/* line 32, ../scss/_messages.scss */
-.success a {
- color: #264409; }
+.error a { color: #8A1F11; }
-/* line 36, ../scss/_messages.scss */
-.balloon {
- display: inline-block;
- padding: 0 4px;
- min-width: 10px;
- height: 14px;
- line-height: 14px;
- background: #B9B9B6;
- vertical-align: text-top;
- text-align: center;
- font-size: 12px;
- color: #FFF;
- -moz-border-radius: 20px;
- -webkit-border-radius: 20px;
- border-radius: 20px; }
+.notice { background: #FFF6BF; color: #8A6D3B; }
-/**
-* 后台分页
-*/
-/* line 5, ../scss/_pagenavi.scss */
-.typecho-pager {
- list-style: none;
- float: right;
- margin: 0;
- padding: 0;
- line-height: 1;
- text-align: center;
- zoom: 1; }
+.notice a { color: #8A6D3B; }
-/* line 15, ../scss/_pagenavi.scss */
-.typecho-pager li {
- display: inline-block;
- margin: 0 3px;
- height: 28px;
- line-height: 28px; }
+.success { background: #E6EFC2; color: #264409; }
-/* line 22, ../scss/_pagenavi.scss */
-.typecho-pager a {
- display: block;
- padding: 0 10px;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px; }
+.success a { color: #264409; }
-/* line 28, ../scss/_pagenavi.scss */
-.typecho-pager a:hover {
- text-decoration: none;
- background: #E9E9E6; }
+.balloon { display: inline-block; padding: 0 4px; min-width: 10px; height: 14px; line-height: 14px; background: #B9B9B6; vertical-align: text-top; text-align: center; font-size: 12px; color: #FFF; border-radius: 20px; }
-/* line 33, ../scss/_pagenavi.scss */
-.typecho-pager li.current a {
- background: #E9E9E6;
- color: #444; }
+/** 后台分页 */
+.typecho-pager { list-style: none; float: right; margin: 0; padding: 0; line-height: 1; text-align: center; zoom: 1; }
-/**
-* 后台头部导航
-*/
-/* line 4, ../scss/_header.scss */
-.typecho-head-nav {
- padding: 0 10px;
- background: #292D33; }
+.typecho-pager li { display: inline-block; margin: 0 3px; height: 28px; line-height: 28px; }
-/* line 9, ../scss/_header.scss */
-.typecho-head-nav a {
- color: #BBB; }
+.typecho-pager a { display: block; padding: 0 10px; border-radius: 2px; }
-/* line 12, ../scss/_header.scss */
-.typecho-head-nav a:hover,
-.typecho-head-nav a:focus {
- color: #FFF;
- text-decoration: none; }
+.typecho-pager a:hover { text-decoration: none; background: #E9E9E6; }
-/* line 18, ../scss/_header.scss */
-#typecho-nav-list {
- float: left; }
- /* line 20, ../scss/_header.scss */
- #typecho-nav-list ul {
- list-style: none;
- margin: 0;
- padding: 0; }
+.typecho-pager li.current a { background: #E9E9E6; color: #444; }
-/* line 27, ../scss/_header.scss */
-#typecho-nav-list ul:first-child {
- border-left: 1px solid #383D45; }
+/** 后台头部导航 */
+.typecho-head-nav { padding: 0 10px; background: #292D33; }
-/* line 31, ../scss/_header.scss */
-#typecho-nav-list .root {
- position: relative;
- float: left; }
+.typecho-head-nav a { color: #BBB; }
-/* line 36, ../scss/_header.scss */
-#typecho-nav-list .parent a {
- display: block;
- float: left;
- padding: 0 20px;
- border-right: 1px solid #383D45;
- height: 36px;
- line-height: 36px;
- color: #BBB; }
+.typecho-head-nav a:hover, .typecho-head-nav a:focus { color: #FFF; text-decoration: none; }
-/* line 46, ../scss/_header.scss */
-#typecho-nav-list .parent a:hover,
-#typecho-nav-list .focus .parent a,
-#typecho-nav-list .root:hover .parent a {
- background: #202328;
- color: #FFF;
- text-decoration: none; }
+#typecho-nav-list { float: left; }
-/* line 54, ../scss/_header.scss */
-#typecho-nav-list .focus .parent a {
- font-weight: bold; }
+#typecho-nav-list ul { list-style: none; margin: 0; padding: 0; }
-/* line 58, ../scss/_header.scss */
-#typecho-nav-list .child {
- position: absolute;
- top: 36px;
- display: none;
- margin: 0;
- min-width: 160px;
- max-width: 240px;
- background: #202328;
- z-index: 250; }
+#typecho-nav-list ul:first-child { border-left: 1px solid #383D45; }
-/* line 69, ../scss/_header.scss */
-#typecho-nav-list .root:hover .child {
- display: block; }
+#typecho-nav-list .root { position: relative; float: left; }
-/* line 73, ../scss/_header.scss */
-#typecho-nav-list .child li a {
- color: #BBB;
- display: block;
- padding: 0 20px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- height: 36px;
- line-height: 36px; }
+#typecho-nav-list .parent a { display: block; float: left; padding: 0 20px; border-right: 1px solid #383D45; height: 36px; line-height: 36px; color: #BBB; }
-/* line 84, ../scss/_header.scss */
-#typecho-nav-list .child li a:hover,
-#typecho-nav-list .child li a:focus {
- background: #292D33;
- color: #FFF; }
+#typecho-nav-list .parent a:hover, #typecho-nav-list .focus .parent a, #typecho-nav-list .root:hover .parent a { background: #202328; color: #FFF; text-decoration: none; }
-/* line 89, ../scss/_header.scss */
-#typecho-nav-list .child li.focus a {
- color: #6DA1BB;
- font-weight: bold; }
+#typecho-nav-list .focus .parent a { font-weight: bold; }
-/* line 94, ../scss/_header.scss */
-.typecho-head-nav .operate {
- float: right; }
+#typecho-nav-list .child { position: absolute; top: 36px; display: none; margin: 0; min-width: 160px; max-width: 240px; background: #202328; z-index: 250; }
-/* line 97, ../scss/_header.scss */
-.typecho-head-nav .operate a {
- display: inline-block;
- margin-left: -1px;
- padding: 0 20px;
- border: 1px solid #383D45;
- border-width: 0 1px;
- line-height: 36px;
- color: #BBB; }
+#typecho-nav-list .root:hover .child { display: block; }
-/* line 106, ../scss/_header.scss */
-.typecho-head-nav .operate a:hover {
- background-color: #202328;
- color: #FFF; }
+#typecho-nav-list .child li a { color: #BBB; display: block; padding: 0 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; height: 36px; line-height: 36px; }
-/**
-* 注脚
-*/
-/* line 4, ../scss/_footer.scss */
-.typecho-foot {
- padding: 4em 0 3em;
- color: #999;
- line-height: 1.8;
- text-align: center; }
- /* line 10, ../scss/_footer.scss */
- .typecho-foot .copyright p {
- margin: 10px 0 0; }
- /* line 13, ../scss/_footer.scss */
- .typecho-foot .resource {
- color: #CCC; }
- /* line 16, ../scss/_footer.scss */
- .typecho-foot .resource a {
- margin: 0 3px;
- color: #999; }
+#typecho-nav-list .child li a:hover, #typecho-nav-list .child li a:focus { background: #292D33; color: #FFF; }
+
+#typecho-nav-list .child li.focus a { color: #6DA1BB; font-weight: bold; }
+
+.typecho-head-nav .operate { float: right; }
+
+.typecho-head-nav .operate a { display: inline-block; margin-left: -1px; padding: 0 20px; border: 1px solid #383D45; border-width: 0 1px; line-height: 36px; color: #BBB; }
+
+.typecho-head-nav .operate a:hover { background-color: #202328; color: #FFF; }
+
+/** 注脚 */
+.typecho-foot { padding: 4em 0 3em; color: #999; line-height: 1.8; text-align: center; }
+
+.typecho-foot .copyright p { margin: 10px 0 0; }
+
+.typecho-foot .resource { color: #CCC; }
+
+.typecho-foot .resource a { margin: 0 3px; color: #999; }
/* 低版本浏览器升级提示 */
-/* line 85, ../scss/style.scss */
-.browsehappy {
- border: none;
- text-align: center; }
+.browsehappy { border: none; text-align: center; }
/** 顶部消息样式 by 70 */
-/* line 91, ../scss/style.scss */
-.popup {
- display: none;
- position: absolute;
- top: 0;
- left: 0;
- margin: 0;
- padding: 8px 0;
- border: none;
- width: 100%;
- z-index: 10;
- text-align: center;
- -moz-border-radius: 0;
- -webkit-border-radius: 0;
- border-radius: 0; }
+.popup { display: none; position: absolute; top: 0; left: 0; margin: 0; padding: 8px 0; border: none; width: 100%; z-index: 10; text-align: center; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }
-/* line 108, ../scss/style.scss */
-.popup ul {
- list-style: none;
- margin: 0;
- padding: 0;
- text-align: center; }
+.popup ul { list-style: none; margin: 0; padding: 0; text-align: center; }
-/* line 115, ../scss/style.scss */
-.popup ul li {
- display: inline-block;
- margin-right: 10px; }
+.popup ul li { display: inline-block; margin-right: 10px; }
-/**
-* logo 的样式
-*/
-/**
-* 载入状态
-*/
-/* line 129, ../scss/style.scss */
-.loading {
- padding-left: 20px !important;
- background: transparent url(../img/ajax-loader.gif) no-repeat left center; }
+/** logo 的样式 */
+/** 载入状态 */
+.loading { padding-left: 20px !important; background: transparent url(../img/ajax-loader.gif) no-repeat left center; }
-/**
-* 典型配置选项
-*/
-/* line 138, ../scss/style.scss */
-.typecho-option {
- list-style: none;
- margin: 1em 0;
- padding: 0; }
+/** 典型配置选项 */
+.typecho-option { list-style: none; margin: 1em 0; padding: 0; }
-/* line 147, ../scss/style.scss */
-.typecho-option-submit li {
- border-bottom: none; }
+.typecho-option-submit li { border-bottom: none; }
-/* line 151, ../scss/style.scss */
-.typecho-option label.typecho-label {
- display: block;
- margin-bottom: .5em;
- font-weight: bold; }
+.typecho-option label.typecho-label { display: block; margin-bottom: .5em; font-weight: bold; }
-/* line 156, ../scss/style.scss */
-.typecho-option label.required:after {
- content: " *";
- color: #B94A48; }
+.typecho-option label.required:after { content: " *"; color: #B94A48; }
-/* line 162, ../scss/style.scss */
-.typecho-option span {
- margin-right: 15px; }
+.typecho-option span { margin-right: 15px; }
-/* line 163, ../scss/style.scss */
-.typecho-option .description {
- margin: .5em 0 0;
- color: #999;
- font-size: .92857em; }
+.typecho-option .description { margin: .5em 0 0; color: #999; font-size: .92857em; }
-/* line 169, ../scss/style.scss */
-.typecho-option input.file {
- width: 100%;
- margin: .7em 0; }
+.typecho-option input.file { width: 100%; margin: .7em 0; }
-/* line 174, ../scss/style.scss */
-.front-archive {
- padding-left: 1.5em; }
+.front-archive { padding-left: 1.5em; }
-/* line 178, ../scss/style.scss */
-.profile-avatar {
- border: 1px dashed #D9D9D6;
- max-width: 100%; }
+.profile-avatar { border: 1px dashed #D9D9D6; max-width: 100%; }
/** 增加配置面板内部的错误样式 by 70 */
-/**
-* 安装样式
-*
-* @author mingcheng
-* @date 2008-09-06
-*/
-/**
-* 安装向导
-*/
-/* line 196, ../scss/style.scss */
-.typecho-install {
- padding-bottom: 2em; }
+/** 安装样式 @author mingcheng @date 2008-09-06 */
+/** 安装向导 */
+.typecho-install { padding-bottom: 2em; }
-/* line 199, ../scss/style.scss */
-.typecho-install-patch {
- margin-bottom: 2em;
- padding: 2em 0;
- background-color: #292D33;
- color: #FFF;
- text-align: center; }
+.typecho-install-patch { margin-bottom: 2em; padding: 2em 0; background-color: #292D33; color: #FFF; text-align: center; }
-/* line 207, ../scss/style.scss */
-.typecho-install-patch ol {
- list-style: none;
- margin: 3em 0 1em;
- padding: 0;
- color: #999; }
+.typecho-install-patch ol { list-style: none; margin: 3em 0 1em; padding: 0; color: #999; }
-/* line 213, ../scss/style.scss */
-.typecho-install-patch li {
- display: inline-block;
- margin: 0 .8em; }
+.typecho-install-patch li { display: inline-block; margin: 0 .8em; }
-/* line 217, ../scss/style.scss */
-.typecho-install-patch span {
- display: inline-block;
- margin-right: 5px;
- width: 20px;
- height: 20px;
- line-height: 20px;
- border: 2px solid #999;
- text-align: center;
- border-radius: 2em; }
+.typecho-install-patch span { display: inline-block; margin-right: 5px; width: 20px; height: 20px; line-height: 20px; border: 2px solid #999; text-align: center; border-radius: 2em; }
-/* line 227, ../scss/style.scss */
-.typecho-install-patch li.current {
- color: #FFF;
- font-weight: bold; }
+.typecho-install-patch li.current { color: #FFF; font-weight: bold; }
-/* line 231, ../scss/style.scss */
-.typecho-install-patch li.current span {
- border-color: #FFF; }
+.typecho-install-patch li.current span { border-color: #FFF; }
-/**
-* 安装主体内容
-*/
-/* line 240, ../scss/style.scss */
-.typecho-install .typecho-install-body input {
- width: 100%; }
+/** 安装主体内容 */
+.typecho-install .typecho-install-body input { width: 100%; }
-/* line 243, ../scss/style.scss */
-.typecho-install-body .typecho-option li {
- margin: 1em 0; }
+.typecho-install-body .typecho-option li { margin: 1em 0; }
-/**
-* 欢迎界面
-*/
-/* line 252, ../scss/style.scss */
-#typecho-welcome {
- margin: 1em 0;
- padding: 1em 2em;
- background-color: #E9E9E6; }
+/** 欢迎界面 */
+#typecho-welcome { margin: 1em 0; padding: 1em 2em; background-color: #E9E9E6; }
-/* line 258, ../scss/style.scss */
-.welcome-board {
- color: #999;
- font-size: 1.15em; }
- /* line 261, ../scss/style.scss */
- .welcome-board em {
- color: #444;
- font-size: 2em;
- font-style: normal;
- font-family: Georgia, serif; }
+.welcome-board { color: #999; font-size: 1.15em; }
-/* line 269, ../scss/style.scss */
-#start-link {
- margin-bottom: 25px;
- padding: 0 0 35px;
- border-bottom: 1px solid #ECECEC; }
- /* line 273, ../scss/style.scss */
- #start-link li {
- float: left;
- margin-right: 1.5em; }
- /* line 277, ../scss/style.scss */
- #start-link .balloon {
- margin-top: 2px; }
+.welcome-board em { color: #444; font-size: 2em; font-style: normal; font-family: Georgia, serif; }
-/* line 283, ../scss/style.scss */
-.latest-link li {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis; }
-/* line 288, ../scss/style.scss */
-.latest-link span {
- display: inline-block;
- margin-right: 4px;
- padding-right: 8px;
- border-right: 1px solid #ECECEC;
- width: 37px;
- text-align: right;
- color: #999; }
+#start-link { margin-bottom: 25px; padding: 0 0 35px; border-bottom: 1px solid #ECECEC; }
-/* line 299, ../scss/style.scss */
-.update-check {
- font-size: 14px; }
+#start-link li { float: left; margin-right: 1.5em; }
-/**
-* 登录框
-*/
-/* line 306, ../scss/style.scss */
-.typecho-login-wrap {
- display: table;
- margin: 0 auto;
- height: 100%; }
+#start-link .balloon { margin-top: 2px; }
-/* line 311, ../scss/style.scss */
-.typecho-login {
- display: table-cell;
- padding: 30px 0 100px;
- width: 280px;
- text-align: center;
- vertical-align: middle; }
- /* line 317, ../scss/style.scss */
- .typecho-login h1 {
- margin: 0 0 1em; }
+.latest-link li { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-/* line 322, ../scss/style.scss */
-.typecho-login .more-link {
- margin-top: 2em;
- color: #CCC; }
+.latest-link span { display: inline-block; margin-right: 4px; padding-right: 8px; border-right: 1px solid #ECECEC; width: 37px; text-align: right; color: #999; }
-/* line 326, ../scss/style.scss */
-.typecho-login .more-link a {
- margin: 0 3px; }
+.update-check { font-size: 14px; }
-/**
-* 标题
-*/
-/* line 333, ../scss/style.scss */
-.typecho-page-title h2 {
- margin: 25px 0 10px;
- font-size: 1.28571em; }
+/** 登录框 */
+.typecho-login-wrap { display: table; margin: 0 auto; height: 100%; }
-/* line 337, ../scss/style.scss */
-.typecho-page-title h2 a {
- margin-left: 10px;
- padding: 3px 8px;
- background: #E9E9E6;
- font-size: .8em;
- border-radius: 2px; }
+.typecho-login { display: table-cell; padding: 30px 0 100px; width: 280px; text-align: center; vertical-align: middle; }
-/* line 345, ../scss/style.scss */
-.typecho-page-title h2 a:hover {
- text-decoration: none; }
+.typecho-login h1 { margin: 0 0 1em; }
-/**
-* 后台页面主体
-*/
-/**
-* 主页主体
-*/
-/* line 359, ../scss/style.scss */
-.typecho-dashboard ul {
- list-style: none;
- padding: 0; }
+.typecho-login .more-link { margin-top: 2em; color: #CCC; }
-/* line 363, ../scss/style.scss */
-.typecho-dashboard li {
- margin-bottom: 5px; }
+.typecho-login .more-link a { margin: 0 3px; }
-/**
-* 标签页
-*/
-/* line 371, ../scss/style.scss */
-.typecho-option-tabs {
- list-style: none;
- margin: 1em 0 0;
- padding: 0;
- font-size: 13px;
- text-align: center; }
- /* line 377, ../scss/style.scss */
- .typecho-option-tabs.fix-tabs {
- margin-bottom: 1em; }
+/** 标题 */
+.typecho-page-title h2 { margin: 25px 0 10px; font-size: 1.28571em; }
-/* line 382, ../scss/style.scss */
-.typecho-option-tabs a {
- display: block;
- margin-right: -1px;
- border: 1px solid #D9D9D6;
- padding: 0 15px;
- height: 26px;
- line-height: 26px;
- color: #666;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box; }
+.typecho-page-title h2 a { margin-left: 10px; padding: 3px 8px; background: #E9E9E6; font-size: .8em; border-radius: 2px; }
-/* line 393, ../scss/style.scss */
-.typecho-option-tabs a:hover {
- background-color: #E9E9E6;
- color: #666;
- text-decoration: none; }
+.typecho-page-title h2 a:hover { text-decoration: none; }
-/* line 399, ../scss/style.scss */
-.typecho-option-tabs li {
- float: left; }
- /* line 401, ../scss/style.scss */
- .typecho-option-tabs li:first-child a {
- -moz-border-radius: 2px 0 0 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px 0 0 2px; }
- /* line 404, ../scss/style.scss */
- .typecho-option-tabs li:last-child a {
- -moz-border-radius: 0 2px 2px 0;
- -webkit-border-radius: 0;
- border-radius: 0 2px 2px 0; }
+/** 后台页面主体 */
+/** 主页主体 */
+.typecho-dashboard ul { list-style: none; padding: 0; }
-/* line 409, ../scss/style.scss */
-.typecho-option-tabs.right {
- float: right; }
+.typecho-dashboard li { margin-bottom: 5px; }
-/* line 413, ../scss/style.scss */
-.typecho-option-tabs li.current a,
-.typecho-option-tabs li.active a {
- background-color: #E9E9E6; }
+/** 标签页 */
+.typecho-option-tabs { list-style: none; margin: 1em 0 0; padding: 0; font-size: 13px; text-align: center; }
-/**
-* 表格列表页
-*/
-/**
-* 列表页选项
-*/
-/* line 429, ../scss/style.scss */
-.typecho-list-operate {
- margin: 1em 0; }
+.typecho-option-tabs.fix-tabs { margin-bottom: 1em; }
-/* line 433, ../scss/style.scss */
-.typecho-list-operate input,
-.typecho-list-operate button,
-.typecho-list-operate select {
- vertical-align: bottom; }
+.typecho-option-tabs a { display: block; margin-right: -1px; border: 1px solid #D9D9D6; padding: 0 15px; height: 26px; line-height: 26px; color: #666; box-sizing: border-box; }
-/* line 439, ../scss/style.scss */
-.typecho-list-operate input[type="checkbox"] {
- vertical-align: text-top; }
+.typecho-option-tabs a:hover { background-color: #E9E9E6; color: #666; text-decoration: none; }
-/* line 443, ../scss/style.scss */
-.typecho-list-operate .operate {
- float: left; }
+.typecho-option-tabs li { float: left; }
-/* line 447, ../scss/style.scss */
-.typecho-list-operate .search {
- float: right; }
+.typecho-option-tabs li:first-child a { border-radius: 2px 0 0 2px; }
-/* line 451, ../scss/style.scss */
-.typecho-list-operate span.operate-delete, a.operate-delete,
-.typecho-list-operate span.operate-button-delete, a.operate-button-delete {
- color: #B94A48; }
+.typecho-option-tabs li:last-child a { border-radius: 0 2px 2px 0; }
-/* line 456, ../scss/style.scss */
-a.operate-edit {
- color: #007700; }
+.typecho-option-tabs.right { float: right; }
-/* line 460, ../scss/style.scss */
-a.operate-reply {
- color: #545c30; }
+.typecho-option-tabs li.current a, .typecho-option-tabs li.active a { background-color: #E9E9E6; }
-/* line 464, ../scss/style.scss */
-.typecho-list-operate a:hover {
- text-decoration: none; }
+/** 表格列表页 */
+/** 列表页选项 */
+.typecho-list-operate { margin: 1em 0; }
-/**
-* 列表表格
-*/
+.typecho-list-operate input, .typecho-list-operate button, .typecho-list-operate select { vertical-align: bottom; }
+
+.typecho-list-operate input[type="checkbox"] { vertical-align: text-top; }
+
+.typecho-list-operate .operate { float: left; }
+
+.typecho-list-operate .search { float: right; }
+
+.typecho-list-operate span.operate-delete, a.operate-delete, .typecho-list-operate span.operate-button-delete, a.operate-button-delete { color: #B94A48; }
+
+a.operate-edit { color: #007700; }
+
+a.operate-reply { color: #545c30; }
+
+.typecho-list-operate a:hover { text-decoration: none; }
+
+/** 列表表格 */
/** 增加表格标题 by 70 */
-/* line 472, ../scss/style.scss */
-.typecho-list-table-title {
- margin: 1em 0;
- color: #999;
- text-align: center; }
-
-/* line 477, ../scss/style.scss */
-.typecho-table-wrap {
- padding: 30px;
- background: #FFF; }
-
-/* line 481, ../scss/style.scss */
-.typecho-list-table {
- width: 100%;
- border-collapse: collapse; }
-
-/* line 486, ../scss/style.scss */
-.typecho-list-table.deactivate {
- color: #999; }
-
-/* line 490, ../scss/style.scss */
-.typecho-list-table .right {
- text-align: right; }
-
-/* line 494, ../scss/style.scss */
-.typecho-list-table th {
- padding: 0 10px 10px;
- border-bottom: 2px solid #F0F0EC;
- text-align: left; }
-
-/* line 500, ../scss/style.scss */
-.typecho-list-table td {
- padding: 10px;
- border-top: 1px solid #F0F0EC;
- word-break: break-all; }
-
-/* line 505, ../scss/style.scss */
-.typecho-list-table .status {
- margin-left: 5px;
- color: #999;
- font-size: .92857em;
- font-style: normal; }
-
-/* line 511, ../scss/style.scss */
-.typecho-list-table tbody tr:hover td {
- background-color: #F6F6F3; }
-
-/* line 515, ../scss/style.scss */
-.typecho-list-table tbody tr.checked td {
- background-color: #FFF9E8; }
-
-/* line 519, ../scss/style.scss */
-.warning {
- color: #B94A48; }
-
-/* line 524, ../scss/style.scss */
-.typecho-list-table tr td .hidden-by-mouse {
- filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
- opacity: 0; }
-
-/* line 528, ../scss/style.scss */
-.typecho-list-table tr:hover td .hidden-by-mouse {
- filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
- opacity: 1; }
-
-/**
-* 评论管理
-*/
-/* line 537, ../scss/style.scss */
-.comment-reply-content {
- position: relative;
- margin: 1em 0;
- padding: 0 1em;
- border: 1px solid transparent;
- background-color: #F0F0EC; }
-
-/* line 544, ../scss/style.scss */
-.comment-reply-content:after {
- position: absolute;
- right: 1em;
- border: 8px solid #F0F0EC;
- border-color: #F0F0EC #F0F0EC transparent transparent;
- content: " "; }
-
-/* line 552, ../scss/style.scss */
-.comment-meta span,
-.comment-date {
- font-size: .92857em;
- color: #999; }
-
-/* line 558, ../scss/style.scss */
-.comment-action a, .comment-action span {
- margin-right: 4px; }
-
-/* line 560, ../scss/style.scss */
-.comment-edit label {
- display: block; }
-
-/* line 564, ../scss/style.scss */
-.comment-content img {
- max-width: 100%; }
-
-/**
-* 评论回复
-*/
-/* line 572, ../scss/style.scss */
-#typecho-respond {
- padding: 10px;
- display: none; }
-
-/**
-* 模板列表
-*/
-/* line 590, ../scss/style.scss */
-.typecho-theme-list img {
- margin: 1em 0;
- max-width: 100%;
- max-height: 240px; }
-
-/* line 596, ../scss/style.scss */
-.typecho-theme-list cite {
- font-style: normal;
- color: #999; }
-
-/* line 601, ../scss/style.scss */
-.typecho-theme-list tbody tr.current td {
- background-color: #FFF9E8; }
-
-/**
-* 后台配置项
-*/
-/* line 610, ../scss/style.scss */
-.typecho-page-main .typecho-option input.text {
- width: 100%; }
-
-/* line 614, ../scss/style.scss */
-.typecho-page-main .typecho-option input.num {
- width: 40px; }
-
-/* line 618, ../scss/style.scss */
-.typecho-page-main .typecho-option textarea {
- width: 100%;
- height: 100px; }
-
-/* line 623, ../scss/style.scss */
-.typecho-page-main .typecho-option .multiline {
- display: block;
- margin: .3em 0; }
- /* line 626, ../scss/style.scss */
- .typecho-page-main .typecho-option .multiline.hidden {
- display: none; }
-
-/**
-* 编辑模板
-*/
-/* line 635, ../scss/style.scss */
-.typecho-select-theme {
- height: 25px;
- line-height: 25px;
- margin: 15px 0px; }
-
-/* line 641, ../scss/style.scss */
-.typecho-select-theme h5 {
- color: #E47E00;
- font-weight: bold;
- float: left;
- font-size: 14px;
- width: 120px;
- margin-right: 10px; }
-
-/* line 650, ../scss/style.scss */
-.typecho-select-theme select {
- width: 150px; }
-
-/**
-* 编辑模板(编辑详情)
-*/
-/* line 658, ../scss/style.scss */
-.typecho-edit-theme ul {
- list-style: none;
- margin: 0;
- padding: 0; }
-
-/* line 664, ../scss/style.scss */
-.typecho-edit-theme li {
- padding: 3px 10px; }
-
-/* line 668, ../scss/style.scss */
-.typecho-edit-theme .current {
- background-color: #E6E6E3; }
-
-/* line 671, ../scss/style.scss */
-.typecho-edit-theme .current a {
- color: #444; }
-
-/* line 675, ../scss/style.scss */
-.typecho-edit-theme textarea {
- font-size: .92857em;
- line-height: 1.2;
- height: 500px; }
-
-/**
-* 编写页面
-*/
-/* line 685, ../scss/style.scss */
-.typecho-post-area .edit-draft-notice {
- color: #999;
- font-size: .92857em; }
-
-/* line 689, ../scss/style.scss */
-.typecho-post-area .edit-draft-notice a {
- color: #B94A48; }
-
-/* line 691, ../scss/style.scss */
-.typecho-post-area .typecho-label {
- display: block;
- margin: 1em 0 -0.5em;
- font-weight: bold; }
-
-/* line 697, ../scss/style.scss */
-.typecho-post-area #auto-save-message {
- display: block;
- margin-top: 0.5em;
- color: #999;
- font-size: .92857em; }
-
-/* line 704, ../scss/style.scss */
-.typecho-post-area .submit .right button {
- margin-left: 5px; }
-
-/* line 708, ../scss/style.scss */
-.typecho-post-area .right {
- float: right;
- padding-left: 24px; }
-
-/* line 713, ../scss/style.scss */
-.typecho-post-area .left {
- float: left; }
-
-/* line 720, ../scss/style.scss */
-.typecho-post-area .out-date {
- border: 1px solid #D3DBB3;
- padding: 3px;
- background: #fff; }
-
-/* line 726, ../scss/style.scss */
-.typecho-post-area input.title {
- font-size: 1.17em;
- font-weight: bold; }
-
-/* line 730, ../scss/style.scss */
-.typecho-post-area .url-slug {
- margin-top: -0.5em;
- color: #AAA;
- font-size: .92857em;
- word-break: break-word; }
-
-/* line 736, ../scss/style.scss */
-.typecho-post-area #slug {
- padding: 2px;
- border: none;
- background: #FFFBCC;
- color: #666; }
-
-/* line 743, ../scss/style.scss */
-.typecho-post-area #text {
- resize: none; }
-
-/* line 747, ../scss/style.scss */
-#advance-panel {
- display: none; }
-
-/* line 751, ../scss/style.scss */
-#custom-field {
- margin: 1em 0;
- padding: 10px 15px;
- background: #FFF; }
- /* line 756, ../scss/style.scss */
- #custom-field.fold table, #custom-field.fold .description {
- display: none; }
- /* line 759, ../scss/style.scss */
- #custom-field .description {
- margin-top: 10px;
- text-align: right; }
- /* line 762, ../scss/style.scss */
- #custom-field .description button {
- float: left; }
- /* line 767, ../scss/style.scss */
- #custom-field p.description {
- text-align: left; }
- /* line 771, ../scss/style.scss */
- #custom-field .typecho-label {
- margin: 0; }
- /* line 773, ../scss/style.scss */
- #custom-field .typecho-label a {
- display: block;
- color: #444; }
- /* line 776, ../scss/style.scss */
- #custom-field .typecho-label a:hover {
- color: #467B96;
- text-decoration: none; }
- /* line 782, ../scss/style.scss */
- #custom-field table {
- margin-top: 10px; }
- /* line 785, ../scss/style.scss */
- #custom-field td {
- padding: 10px 5px;
- font-size: .92857em;
- border-bottom: 1px solid #F0F0EC;
- vertical-align: top; }
- /* line 790, ../scss/style.scss */
- #custom-field td label {
- font-size: 1em;
- font-weight: normal; }
- /* line 795, ../scss/style.scss */
- #custom-field select {
- height: 27px; }
-
-/* line 798, ../scss/style.scss */
-.typecho-post-area .is-draft {
- background: #FFF1A8; }
-
-/* line 802, ../scss/style.scss */
-.typecho-post-option .description {
- margin-top: -0.5em;
- color: #999;
- font-size: .92857em; }
-
-/* line 808, ../scss/style.scss */
-.category-option ul {
- list-style: none;
- border: 1px solid #D9D9D6;
- padding: 6px 12px;
- max-height: 240px;
- overflow: auto;
- background-color: #FFF;
- border-radius: 2px; }
-
-/* line 817, ../scss/style.scss */
-.category-option li {
- margin: 3px 0; }
-
-/* line 821, ../scss/style.scss */
-.visibility-option ul,
-.allow-option ul {
- list-style: none;
- padding: 0; }
-
-/**
-* 标签列表
-*/
-/* line 832, ../scss/style.scss */
-.typecho-page-main ul.tag-list {
- list-style: none;
- margin: 0;
- padding: 20px;
- background-color: #FFF; }
-
-/* line 839, ../scss/style.scss */
-.typecho-page-main ul.tag-list li {
- display: inline-block;
- margin: 0 0 5px 0;
- padding: 5px 5px 5px 10px;
- cursor: pointer; }
-
-/* line 845, ../scss/style.scss */
-.typecho-page-main ul.tag-list li:hover {
- background-color: #E9E9E6; }
-
-/* line 849, ../scss/style.scss */
-.typecho-page-main ul.tag-list li input {
- display: none; }
-
-/* line 854, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.checked {
- background-color: #FFFBCC; }
-
-/* line 858, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.size-5 {
- font-size: 1em; }
-
-/* line 859, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.size-10 {
- font-size: 1.2em; }
-
-/* line 860, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.size-20 {
- font-size: 1.4em; }
-
-/* line 861, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.size-30 {
- font-size: 1.6em; }
-
-/* line 862, ../scss/style.scss */
-.typecho-page-main ul.tag-list li.size-0 {
- font-size: 1.8em; }
-
-/* line 864, ../scss/style.scss */
-.typecho-page-main .tag-edit-link {
- visibility: hidden; }
-
-/* line 865, ../scss/style.scss */
-.typecho-page-main li:hover .tag-edit-link {
- visibility: visible; }
-
-/* line 867, ../scss/style.scss */
-.typecho-attachment-photo {
- border: 1px solid #E6E6E3;
- max-width: 100%; }
-
-/*
-* Upload
-*/
-/* line 876, ../scss/style.scss */
-#upload-panel {
- border: 1px dashed #D9D9D6;
- background-color: #FFF;
- color: #999;
- font-size: .92857em; }
- /* line 881, ../scss/style.scss */
- #upload-panel.drag {
- background-color: #FFFBCC; }
-
-/* line 886, ../scss/style.scss */
-.upload-area {
- padding: 15px;
- text-align: center; }
-
-/* line 891, ../scss/style.scss */
-#file-list {
- list-style: none;
- margin: 0 10px;
- padding: 0;
- max-height: 450px;
- overflow: auto;
- word-break: break-all; }
- /* line 898, ../scss/style.scss */
- #file-list li,
- #file-list .insert {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis; }
- /* line 904, ../scss/style.scss */
- #file-list li {
- padding: 8px 0;
- border-top: 1px dashed #D9D9D6; }
- /* line 908, ../scss/style.scss */
- #file-list .insert {
- display: block;
- max-width: 100%; }
- /* line 912, ../scss/style.scss */
- #file-list .file {
- margin-left: 5px; }
- /* line 915, ../scss/style.scss */
- #file-list .info {
- text-transform: uppercase; }
-
-/* line 920, ../scss/style.scss */
-#btn-fullscreen-upload {
- visibility: hidden; }
-
-/**
-* 附件管理
-*/
-/* line 928, ../scss/style.scss */
-.edit-media button {
- margin-right: 6px; }
+.typecho-list-table-title { margin: 1em 0; color: #999; text-align: center; }
+
+.typecho-table-wrap { padding: 30px; background: #FFF; }
+
+.typecho-list-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
+
+.typecho-list-table.deactivate { color: #999; }
+
+.typecho-list-table .right { text-align: right; }
+
+.typecho-list-table th { padding: 0 10px 10px; border-bottom: 2px solid #F0F0EC; text-align: left; }
+
+.typecho-list-table td { padding: 10px; border-top: 1px solid #F0F0EC; word-break: break-all; }
+
+.typecho-list-table td pre { overflow: auto; }
+
+.typecho-list-table .status { margin-left: 5px; color: #999; font-size: .92857em; font-style: normal; }
+
+.typecho-list-table tbody tr:hover td { background-color: #F6F6F3; }
+
+.typecho-list-table tbody tr.checked td { background-color: #FFF9E8; }
+
+.typecho-list-table tr td .hidden-by-mouse { opacity: 0; }
+
+.typecho-list-table tr:hover td .hidden-by-mouse { opacity: 1; }
+
+.warning { color: #B94A48; }
+
+/** 评论管理 */
+.comment-reply-content { position: relative; margin: 1em 0; padding: 0 1em; border: 1px solid transparent; background-color: #F0F0EC; }
+
+.comment-reply-content:after { position: absolute; right: 1em; border: 8px solid #F0F0EC; border-color: #F0F0EC #F0F0EC transparent transparent; content: " "; }
+
+.comment-meta span, .comment-date { font-size: .92857em; color: #999; }
+
+.comment-action a, .comment-action span { margin-right: 4px; }
+
+.comment-edit label { display: block; }
+
+.comment-content img { max-width: 100%; }
+
+/** 评论回复 */
+#typecho-respond { padding: 10px; display: none; }
+
+/** 模板列表 */
+.typecho-theme-list img { margin: 1em 0; max-width: 100%; max-height: 240px; }
+
+.typecho-theme-list cite { font-style: normal; color: #999; }
+
+.typecho-theme-list tbody tr.current td { background-color: #FFF9E8; }
+
+/** 后台配置项 */
+.typecho-page-main .typecho-option input.text { width: 100%; }
+
+.typecho-page-main .typecho-option input.num { width: 40px; }
+
+.typecho-page-main .typecho-option textarea { width: 100%; height: 100px; }
+
+.typecho-page-main .typecho-option .multiline { display: block; margin: .3em 0; }
+
+.typecho-page-main .typecho-option .multiline.hidden { display: none; }
+
+/** 编辑模板 */
+.typecho-select-theme { height: 25px; line-height: 25px; margin: 15px 0px; }
+
+.typecho-select-theme h5 { color: #E47E00; font-weight: bold; float: left; font-size: 14px; width: 120px; margin-right: 10px; }
+
+.typecho-select-theme select { width: 150px; }
+
+/** 编辑模板(编辑详情) */
+.typecho-edit-theme ul { list-style: none; margin: 0; padding: 0; }
+
+.typecho-edit-theme li { padding: 3px 10px; }
+
+.typecho-edit-theme .current { background-color: #E6E6E3; }
+
+.typecho-edit-theme .current a { color: #444; }
+
+.typecho-edit-theme textarea { font-size: .92857em; line-height: 1.2; height: 500px; }
+
+/** 编写页面 */
+.typecho-post-area .edit-draft-notice { color: #999; font-size: .92857em; }
+
+.typecho-post-area .edit-draft-notice a { color: #B94A48; }
+
+.typecho-post-area .typecho-label { display: block; margin: 1em 0 -0.5em; font-weight: bold; }
+
+.typecho-post-area #auto-save-message { display: block; margin-top: 0.5em; color: #999; font-size: .92857em; }
+
+.typecho-post-area .submit .right button { margin-left: 5px; }
+
+.typecho-post-area .right { float: right; padding-left: 24px; }
+
+.typecho-post-area .left { float: left; }
+
+.typecho-post-area .out-date { border: 1px solid #D3DBB3; padding: 3px; background: #fff; }
+
+.typecho-post-area input.title { font-size: 1.17em; font-weight: bold; }
+
+.typecho-post-area .url-slug { margin-top: -0.5em; color: #AAA; font-size: .92857em; word-break: break-word; }
+
+.typecho-post-area #slug { padding: 2px; border: none; background: #FFFBCC; color: #666; }
+
+.typecho-post-area #text { resize: none; }
+
+#advance-panel { display: none; }
+
+#custom-field { margin: 1em 0; padding: 10px 15px; background: #FFF; }
+
+#custom-field.fold table, #custom-field.fold .description { display: none; }
+
+#custom-field .description { margin-top: 10px; text-align: right; }
+
+#custom-field .description button { float: left; }
+
+#custom-field p.description { text-align: left; }
+
+#custom-field .typecho-label { margin: 0; }
+
+#custom-field .typecho-label a { display: block; color: #444; }
+
+#custom-field .typecho-label a:hover { color: #467B96; text-decoration: none; }
+
+#custom-field table { margin-top: 10px; }
+
+#custom-field td { padding: 10px 5px; font-size: .92857em; border-bottom: 1px solid #F0F0EC; vertical-align: top; }
+
+#custom-field td label { font-size: 1em; font-weight: normal; }
+
+#custom-field select { height: 27px; }
+
+.typecho-post-area .is-draft { background: #FFF1A8; }
+
+.typecho-post-option .description { margin-top: -0.5em; color: #999; font-size: .92857em; }
+
+.category-option ul { list-style: none; border: 1px solid #D9D9D6; padding: 6px 12px; max-height: 240px; overflow: auto; background-color: #FFF; border-radius: 2px; }
+
+.category-option li { margin: 3px 0; }
+
+.visibility-option ul, .allow-option ul { list-style: none; padding: 0; }
+
+/** 标签列表 */
+.typecho-page-main ul.tag-list { list-style: none; margin: 0; padding: 20px; background-color: #FFF; }
+
+.typecho-page-main ul.tag-list li { display: inline-block; margin: 0 0 5px 0; padding: 5px 5px 5px 10px; cursor: pointer; }
+
+.typecho-page-main ul.tag-list li:hover { background-color: #E9E9E6; }
+
+.typecho-page-main ul.tag-list li input { display: none; }
+
+.typecho-page-main ul.tag-list li.checked { background-color: #FFFBCC; }
+
+.typecho-page-main ul.tag-list li.size-5 { font-size: 1em; }
+
+.typecho-page-main ul.tag-list li.size-10 { font-size: 1.2em; }
+
+.typecho-page-main ul.tag-list li.size-20 { font-size: 1.4em; }
+
+.typecho-page-main ul.tag-list li.size-30 { font-size: 1.6em; }
+
+.typecho-page-main ul.tag-list li.size-0 { font-size: 1.8em; }
+
+.typecho-page-main .tag-edit-link { visibility: hidden; }
+
+.typecho-page-main li:hover .tag-edit-link { visibility: visible; }
+
+.typecho-attachment-photo { border: 1px solid #E6E6E3; max-width: 100%; }
+
+/* Upload */
+#upload-panel { border: 1px dashed #D9D9D6; background-color: #FFF; color: #999; font-size: .92857em; }
+
+#upload-panel.drag { background-color: #FFFBCC; }
+
+.upload-area { padding: 15px; text-align: center; }
+
+#file-list { list-style: none; margin: 0 10px; padding: 0; max-height: 450px; overflow: auto; word-break: break-all; }
+
+#file-list li, #file-list .insert { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
+
+#file-list li { padding: 8px 0; border-top: 1px dashed #D9D9D6; }
+
+#file-list .insert { display: block; max-width: 100%; }
+
+#file-list .file { margin-left: 5px; }
+
+#file-list .info { text-transform: uppercase; }
+
+#btn-fullscreen-upload { visibility: hidden; }
+
+/** 附件管理 */
+.edit-media button { margin-right: 6px; }
/* 拖动调整 textarea 大小 */
-/* line 931, ../scss/style.scss */
-.resize {
- display: block;
- margin: 2px auto 0;
- padding: 2px 0;
- border: 1px solid #D9D9D6;
- border-width: 1px 0;
- width: 60px;
- cursor: row-resize; }
- /* line 939, ../scss/style.scss */
- .resize i {
- display: block;
- height: 1px;
- background-color: #D9D9D6; }
+.resize { display: block; margin: 2px auto 0; padding: 2px 0; border: 1px solid #D9D9D6; border-width: 1px 0; width: 60px; cursor: row-resize; }
+
+.resize i { display: block; height: 1px; background-color: #D9D9D6; }
/* 拖动排序 */
-/* line 947, ../scss/style.scss */
-.tDnD_whileDrag {
- background-color: #FFFBCC; }
+.tDnD_whileDrag { background-color: #FFFBCC; }
-/**
-* 导入扩展样式
-*/
-/**
- * icons
- */
-/* line 29, ../scss/_icons.scss */
-.i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow, .i-upload, .i-upload-active {
- display: inline-block;
- vertical-align: text-bottom;
- text-indent: -9999em;
- background-image: url('../img/icons-s0c4f1c5ae6.png');
- background-repeat: no-repeat; }
- /* line 35, ../scss/_icons.scss */
- .i-edit:hover, .i-delete:hover, .i-exlink:hover, .mime-office:hover, .mime-text:hover, .mime-image:hover, .mime-html:hover, .mime-archive:hover, .mime-application:hover, .mime-audio:hover, .mime-script:hover, .mime-video:hover, .mime-unknow:hover, .i-upload:hover, .i-upload-active:hover {
- filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=75);
- opacity: 0.75; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 29, ../scss/_icons.scss */
- .i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow, .i-upload, .i-upload-active {
- -moz-background-size: auto 256px;
- -o-background-size: auto 256px;
- -webkit-background-size: auto 256px;
- background-size: auto 256px;
- background-image: url('../img/icons-2x-s481937020b.png'); } }
+/** 导入扩展样式 */
+/** icons */
+.icons-sprite, .icons-icon-delete, .icons-icon-edit, .icons-icon-exlink, .icons-icon-upload-active, .icons-icon-upload, .icons-mime-application, .icons-mime-archive, .icons-mime-audio, .icons-mime-html, .icons-mime-image, .icons-mime-office, .icons-mime-script, .icons-mime-text, .icons-mime-unknow, .icons-mime-video, .i-edit, .i-delete, .i-upload, .i-upload-active, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow { background-image: url("../img/icons.png?_=01c3ae1"); background-repeat: no-repeat; }
-/* line 47, ../scss/_icons.scss */
-.i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow {
- width: 16px;
- height: 16px; }
+.icons-icon-delete { background-position: 0 -16px; width: 16px; height: 16px; }
-/* line 53, ../scss/_icons.scss */
-.i-upload, .i-upload-active {
- width: 24px;
- height: 24px; }
+.icons-icon-edit { background-position: 0 -112px; width: 16px; height: 16px; }
-/* line 59, ../scss/_icons.scss */
-.i-edit {
- background-position: 0 -16px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 59, ../scss/_icons.scss */
- .i-edit {
- background-position: 0 -16px; } }
+.icons-icon-exlink { background-position: 0 -32px; width: 16px; height: 16px; }
-/* line 63, ../scss/_icons.scss */
-.i-delete {
- background-position: 0 0; }
+.icons-icon-upload-active { background-position: 0 -232px; width: 24px; height: 24px; }
-/* line 71, ../scss/_icons.scss */
-.i-upload {
- background-position: 0 -72px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 71, ../scss/_icons.scss */
- .i-upload {
- background-position: 0 -72px; } }
+.icons-icon-upload { background-position: 0 -208px; width: 24px; height: 24px; }
-/* line 76, ../scss/_icons.scss */
-.i-upload-active {
- background-position: 0 -48px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 76, ../scss/_icons.scss */
- .i-upload-active {
- background-position: 0 -48px; } }
+.icons-icon-upload:active, .icons-icon-upload.icon-upload-active { background-position: 0 -232px; }
-/* line 82, ../scss/_icons.scss */
-.i-caret-up, .i-caret-down, .i-caret-left, .i-caret-right {
- display: inline-block;
- border-style: solid;
- border-color: transparent transparent #BBB transparent;
- border-width: 3px 4px 5px; }
+.icons-mime-application { background-position: 0 -80px; width: 16px; height: 16px; }
-/* line 88, ../scss/_icons.scss */
-.i-caret-down {
- border-color: #BBB transparent transparent transparent;
- border-width: 5px 4px 3px; }
+.icons-mime-archive { background-position: 0 -96px; width: 16px; height: 16px; }
-/* line 92, ../scss/_icons.scss */
-.i-caret-left {
- border-color: transparent #BBB transparent transparent;
- border-width: 4px 5px 4px 3px; }
+.icons-mime-audio { background-position: 0 0; width: 16px; height: 16px; }
-/* line 96, ../scss/_icons.scss */
-.i-caret-right {
- border-color: transparent transparent transparent #BBB;
- border-width: 4px 3px 4px 5px; }
+.icons-mime-html { background-position: 0 -128px; width: 16px; height: 16px; }
-/* line 101, ../scss/_icons.scss */
-.i-exlink {
- background-position: 0 -32px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 101, ../scss/_icons.scss */
- .i-exlink {
- background-position: 0 -32px; } }
+.icons-mime-image { background-position: 0 -144px; width: 16px; height: 16px; }
+
+.icons-mime-office { background-position: 0 -160px; width: 16px; height: 16px; }
+
+.icons-mime-script { background-position: 0 -176px; width: 16px; height: 16px; }
+
+.icons-mime-text { background-position: 0 -64px; width: 16px; height: 16px; }
+
+.icons-mime-unknow { background-position: 0 -48px; width: 16px; height: 16px; }
+
+.icons-mime-video { background-position: 0 -192px; width: 16px; height: 16px; }
+
+@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .icons-sprite, .icons-icon-delete, .icons-icon-edit, .icons-icon-exlink, .icons-icon-upload-active, .icons-icon-upload, .icons-mime-application, .icons-mime-archive, .icons-mime-audio, .icons-mime-html, .icons-mime-image, .icons-mime-office, .icons-mime-script, .icons-mime-text, .icons-mime-unknow, .icons-mime-video { background-image: url("../img/icons-2x.png?_=dffe302"); background-repeat: no-repeat; }
+ .icons-icon-delete { background-position: 0 -32px; }
+ .icons-icon-edit { background-position: 0 -224px; }
+ .icons-icon-exlink { background-position: 0 -64px; }
+ .icons-icon-upload-active { background-position: 0 -464px; }
+ .icons-icon-upload { background-position: 0 -416px; }
+ .icons-icon-upload:active, .icons-icon-upload.icon-upload-active { background-position: 0 -464px; }
+ .icons-mime-application { background-position: 0 -160px; }
+ .icons-mime-archive { background-position: 0 -192px; }
+ .icons-mime-audio { background-position: 0 0; }
+ .icons-mime-html { background-position: 0 -256px; }
+ .icons-mime-image { background-position: 0 -288px; }
+ .icons-mime-office { background-position: 0 -320px; }
+ .icons-mime-script { background-position: 0 -352px; }
+ .icons-mime-text { background-position: 0 -128px; }
+ .icons-mime-unknow { background-position: 0 -96px; }
+ .icons-mime-video { background-position: 0 -384px; } }
+
+/* @mixin sprite-background($name) { // background-image: sprite-url($sprites); // background-position: sprite-position($sprites, $name); @include icons-sprite($name); // background-repeat: no-repeat; // display: block; // height: image-height(sprite-file($sprites, $name)); // width: image-width(sprite-file($sprites, $name)); @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { @include icons-2x-sprite($name); // Workaround for https://gist.github.com/2140082 //@if (sprite-position($sprites, $name) != sprite-position($sprites-retina, $name)) { // $ypos: round(nth(sprite-position($sprites-retina, $name), 2) / 2); // background-position: 0 $ypos; //} // Hard coded width of the normal sprite image. There must be a smarter way to do this. // @include background-size(auto 256px); // background-image: sprite-url($sprites-retina); } } */
+.i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow, .i-upload, .i-upload-active { display: inline-block; vertical-align: text-bottom; text-indent: -9999em; }
+
+.i-edit:hover, .i-delete:hover, .i-exlink:hover, .mime-office:hover, .mime-text:hover, .mime-image:hover, .mime-html:hover, .mime-archive:hover, .mime-application:hover, .mime-audio:hover, .mime-script:hover, .mime-video:hover, .mime-unknow:hover, .i-upload:hover, .i-upload-active:hover { opacity: 0.75; }
+
+@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { .i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow, .i-upload, .i-upload-active { background-size: auto 256px; } }
+
+.i-edit, .i-delete, .i-exlink, .mime-office, .mime-text, .mime-image, .mime-html, .mime-archive, .mime-application, .mime-audio, .mime-script, .mime-video, .mime-unknow { width: 16px; height: 16px; }
+
+.i-upload, .i-upload-active { width: 24px; height: 24px; }
+
+.i-edit { background-position: 0 -112px; }
+
+.i-delete { background-position: 0 -16px; }
+
+.i-upload { background-position: 0 -208px; }
+
+.i-upload:active, .i-upload.icon-upload-active { background-position: 0 -232px; }
+
+.i-upload-active { background-position: 0 -232px; }
+
+.i-caret-up, .i-caret-down, .i-caret-left, .i-caret-right { display: inline-block; border-style: solid; border-color: transparent transparent #BBB transparent; border-width: 3px 4px 5px; }
+
+.i-caret-down { border-color: #BBB transparent transparent transparent; border-width: 5px 4px 3px; }
+
+.i-caret-left { border-color: transparent #BBB transparent transparent; border-width: 4px 5px 4px 3px; }
+
+.i-caret-right { border-color: transparent transparent transparent #BBB; border-width: 4px 3px 4px 5px; }
+
+.i-exlink { background-position: 0 -32px; }
/* 文件类型图标 */
-/* line 109, ../scss/_icons.scss */
-.mime-office {
- background-position: 0 -176px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 109, ../scss/_icons.scss */
- .mime-office {
- background-position: 0 -176px; } }
+.mime-office { background-position: 0 -160px; }
-/* line 114, ../scss/_icons.scss */
-.mime-text {
- background-position: 0 -208px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 114, ../scss/_icons.scss */
- .mime-text {
- background-position: 0 -208px; } }
+.mime-text { background-position: 0 -64px; }
-/* line 119, ../scss/_icons.scss */
-.mime-image {
- background-position: 0 -160px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 119, ../scss/_icons.scss */
- .mime-image {
- background-position: 0 -160px; } }
+.mime-image { background-position: 0 -144px; }
-/* line 124, ../scss/_icons.scss */
-.mime-html {
- background-position: 0 -144px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 124, ../scss/_icons.scss */
- .mime-html {
- background-position: 0 -144px; } }
+.mime-html { background-position: 0 -128px; }
-/* line 129, ../scss/_icons.scss */
-.mime-archive {
- background-position: 0 -112px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 129, ../scss/_icons.scss */
- .mime-archive {
- background-position: 0 -112px; } }
+.mime-archive { background-position: 0 -96px; }
-/* line 134, ../scss/_icons.scss */
-.mime-application {
- background-position: 0 -96px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 134, ../scss/_icons.scss */
- .mime-application {
- background-position: 0 -96px; } }
+.mime-application { background-position: 0 -80px; }
-/* line 139, ../scss/_icons.scss */
-.mime-audio {
- background-position: 0 -128px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 139, ../scss/_icons.scss */
- .mime-audio {
- background-position: 0 -128px; } }
+.mime-audio { background-position: 0 0; }
-/* line 144, ../scss/_icons.scss */
-.mime-script {
- background-position: 0 -192px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 144, ../scss/_icons.scss */
- .mime-script {
- background-position: 0 -192px; } }
+.mime-script { background-position: 0 -176px; }
-/* line 149, ../scss/_icons.scss */
-.mime-video {
- background-position: 0 -240px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 149, ../scss/_icons.scss */
- .mime-video {
- background-position: 0 -240px; } }
+.mime-video { background-position: 0 -192px; }
-/* line 154, ../scss/_icons.scss */
-.mime-unknow {
- background-position: 0 -224px; }
- @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 154, ../scss/_icons.scss */
- .mime-unknow {
- background-position: 0 -224px; } }
+.mime-unknow { background-position: 0 -48px; }
/* Logo 图标 */
-/* line 161, ../scss/_icons.scss */
-.i-logo, .i-logo-s {
- width: 169px;
- height: 40px;
- display: inline-block;
- background: url("../img/typecho-logo.svg") no-repeat;
- text-indent: -9999em;
- -moz-background-size: auto 40px;
- -o-background-size: auto 40px;
- -webkit-background-size: auto 40px;
- background-size: auto 40px;
- filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=15);
- opacity: 0.15; }
- /* line 169, ../scss/_icons.scss */
- .i-logo:hover, .i-logo-s:hover {
- filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=20);
- opacity: 0.2; }
+.i-logo, .i-logo-s { width: 169px; height: 40px; display: inline-block; background: url("../img/typecho-logo.svg") no-repeat; text-indent: -9999em; background-size: auto 40px; opacity: .15; }
-/* line 173, ../scss/_icons.scss */
-.i-logo-s {
- width: 26px;
- height: 26px;
- -moz-background-size: auto 26px;
- -o-background-size: auto 26px;
- -webkit-background-size: auto 26px;
- background-size: auto 26px; }
+.i-logo:hover, .i-logo-s:hover { opacity: .2; }
-/*
-* Editor
-*/
-/* line 4, ../scss/components/_editor.scss */
-.editor {
- margin-bottom: -0.5em; }
+.i-logo-s { width: 26px; height: 26px; background-size: auto 26px; }
-/* line 8, ../scss/components/_editor.scss */
-.wmd-button-row {
- list-style: none;
- margin: 0;
- padding: 0;
- height: 26px;
- line-height: 1; }
- /* line 15, ../scss/components/_editor.scss */
- .wmd-button-row li {
- display: inline-block;
- margin-right: 4px;
- padding: 3px;
- cursor: pointer;
- vertical-align: middle;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px; }
- /* line 22, ../scss/components/_editor.scss */
- .wmd-button-row li:hover {
- background-color: #E9E9E6; }
- /* line 25, ../scss/components/_editor.scss */
- .wmd-button-row li.wmd-spacer {
- height: 20px;
- margin: 0 10px 0 6px;
- padding: 0;
- width: 1px;
- background: #E9E9E6;
- cursor: default; }
+/* Editor */
+.editor { margin-bottom: -0.5em; }
-/* line 36, ../scss/components/_editor.scss */
-#wmd-button-row span {
- display: block;
- width: 20px;
- height: 20px;
- background: transparent url(../img/editor.png) no-repeat; }
+.wmd-button-row { list-style: none; margin: 0; padding: 0; height: 26px; line-height: 1; }
-/* line 43, ../scss/components/_editor.scss */
-#btn-cancel-preview {
- display: none; }
+.wmd-button-row li { display: inline-block; margin-right: 4px; padding: 3px; cursor: pointer; vertical-align: middle; border-radius: 2px; }
-@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- /* line 48, ../scss/components/_editor.scss */
- #wmd-button-row span {
- background-image: url(../img/editor@2x.png);
- -moz-background-size: 320px auto;
- -o-background-size: 320px auto;
- -webkit-background-size: 320px auto;
- background-size: 320px auto; } }
-/* line 55, ../scss/components/_editor.scss */
-.wmd-edittab {
- float: right;
- margin-top: 3px;
- font-size: .92857em; }
- /* line 59, ../scss/components/_editor.scss */
- .wmd-edittab a {
- display: inline-block;
- padding: 0 8px;
- margin-left: 5px;
- height: 20px;
- line-height: 20px; }
- /* line 65, ../scss/components/_editor.scss */
- .wmd-edittab a:hover {
- text-decoration: none; }
- /* line 68, ../scss/components/_editor.scss */
- .wmd-edittab a.active {
- background: #E9E9E6;
- color: #999; }
+.wmd-button-row li:hover { background-color: #E9E9E6; }
-/* line 76, ../scss/components/_editor.scss */
-.wmd-hidetab {
- display: none; }
+.wmd-button-row li.wmd-spacer { height: 20px; margin: 0 10px 0 6px; padding: 0; width: 1px; background: #E9E9E6; cursor: default; }
-/* line 80, ../scss/components/_editor.scss */
-.wmd-visualhide {
- visibility: hidden; }
+#wmd-button-row span { display: block; width: 20px; height: 20px; background: transparent url(../img/editor.png) no-repeat; }
+
+#btn-cancel-preview { display: none; }
+
+@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { #wmd-button-row span { background-image: url(../img/editor@2x.png); background-size: 320px auto; } }
+
+.wmd-edittab { float: right; margin-top: 3px; font-size: .92857em; }
+
+.wmd-edittab a { display: inline-block; padding: 0 8px; margin-left: 5px; height: 20px; line-height: 20px; }
+
+.wmd-edittab a:hover { text-decoration: none; }
+
+.wmd-edittab a.active { background: #E9E9E6; color: #999; }
+
+.wmd-hidetab { display: none; }
+
+.wmd-visualhide { visibility: hidden; }
/* 对话框 */
-/* line 85, ../scss/components/_editor.scss */
-.wmd-prompt-background {
- background-color: #000; }
+.wmd-prompt-background { background-color: #000; }
-/* line 88, ../scss/components/_editor.scss */
-.wmd-prompt-dialog {
- position: fixed;
- z-index: 1001;
- top: 50%;
- left: 50%;
- margin-top: -95px;
- margin-left: -200px;
- padding: 20px;
- width: 360px;
- background: #F6F6F3; }
- /* line 99, ../scss/components/_editor.scss */
- .wmd-prompt-dialog p {
- margin: 0 0 5px; }
- /* line 100, ../scss/components/_editor.scss */
- .wmd-prompt-dialog form {
- margin-top: 10px; }
- /* line 101, ../scss/components/_editor.scss */
- .wmd-prompt-dialog input[type="text"] {
- margin-bottom: 10px;
- width: 100%; }
- /* line 105, ../scss/components/_editor.scss */
- .wmd-prompt-dialog button {
- margin-right: 10px; }
+.wmd-prompt-dialog { position: fixed; z-index: 1001; top: 50%; left: 50%; margin-top: -95px; margin-left: -200px; padding: 20px; width: 360px; background: #F6F6F3; }
+
+.wmd-prompt-dialog p { margin: 0 0 5px; }
+
+.wmd-prompt-dialog form { margin-top: 10px; }
+
+.wmd-prompt-dialog input[type="text"] { margin-bottom: 10px; width: 100%; }
+
+.wmd-prompt-dialog button { margin-right: 10px; }
/* 预览 */
-/* line 109, ../scss/components/_editor.scss */
-#wmd-preview {
- background: #FFF;
- margin: 1em 0;
- padding: 0 15px;
- word-wrap: break-word;
- overflow: auto;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px; }
- /* line 116, ../scss/components/_editor.scss */
- #wmd-preview img {
- max-width: 100%; }
- /* line 117, ../scss/components/_editor.scss */
- #wmd-preview code, #wmd-preview pre {
- padding: 2px 4px;
- background: #DDD;
- font-size: 14px; }
- /* line 122, ../scss/components/_editor.scss */
- #wmd-preview code {
- color: #C13; }
- /* line 123, ../scss/components/_editor.scss */
- #wmd-preview pre {
- padding: 1em; }
- /* line 125, ../scss/components/_editor.scss */
- #wmd-preview pre code {
- padding: 0;
- color: #444;
- white-space: pre-wrap;}
- /* line 130, ../scss/components/_editor.scss */
- #wmd-preview blockquote {
- margin: 1em 1.5em;
- padding-left: 1.5em;
- border-left: 4px solid #E9E9E6;
- color: #777; }
- /* line 136, ../scss/components/_editor.scss */
- #wmd-preview hr {
- margin: 2em auto;
- width: 100px;
- border: 1px solid #E9E9E6;
- border-width: 2px 0 0 0; }
- /* line 142, ../scss/components/_editor.scss */
- #wmd-preview .summary:after {
- display: block;
- margin: 2em 0;
- background: #FFF9E8;
- color: #cf9900;
- font-size: .85714em;
- text-align: center;
- content: "- more -"; }
- /* line 152, ../scss/components/_editor.scss */
- #wmd-preview table {
- width: 100%; }
- /* line 156, ../scss/components/_editor.scss */
- #wmd-preview table th, #wmd-preview table td {
- border: 1px solid #DDD;
- padding: 5px 8px;
- word-break: break-all; }
- /* line 162, ../scss/components/_editor.scss */
- #wmd-preview table th {
- background: #EEE; }
- /* line 165, ../scss/components/_editor.scss */
- #wmd-preview span.line {
- display: inline;
- height: 1px;
- line-height: 1px;
- position: absolute; }
- /* line 172, ../scss/components/_editor.scss */
- #wmd-preview .focus, #wmd-preview .focus * {
- background-color: rgba(255, 230, 0, 0.5) !important; }
+#wmd-preview { background: #FFF; margin: 1em 0; padding: 0 15px; word-wrap: break-word; overflow: auto; border-radius: 2px; }
+
+#wmd-preview img { max-width: 100%; }
+
+#wmd-preview code, #wmd-preview pre { padding: 2px 4px; background: #DDD; font-size: 14px; }
+
+#wmd-preview code { color: #C13; }
+
+#wmd-preview pre { padding: 1em; }
+
+#wmd-preview pre code { padding: 0; color: #444; }
+
+#wmd-preview blockquote { margin: 1em 1.5em; padding-left: 1.5em; border-left: 4px solid #E9E9E6; color: #777; }
+
+#wmd-preview hr { margin: 2em auto; width: 100px; border: 1px solid #E9E9E6; border-width: 2px 0 0 0; }
+
+#wmd-preview .summary:after { display: block; margin: 2em 0; background: #FFF9E8; color: #cf9900; font-size: .85714em; text-align: center; content: "- more -"; }
+
+#wmd-preview table { width: 100%; }
+
+#wmd-preview table th, #wmd-preview table td { border: 1px solid #DDD; padding: 5px 8px; word-break: break-all; }
+
+#wmd-preview table th { background: #EEE; }
+
+#wmd-preview span.line { display: inline; height: 1px; line-height: 1px; position: absolute; }
+
+#wmd-preview .focus, #wmd-preview .focus * { background-color: rgba(255, 230, 0, 0.5) !important; }
/* 上传面板动画效果 */
-@keyframes fullscreen-upload {
- 0% {
- right: -280px; }
- 100% {
- right: -1px; } }
-@-moz-keyframes fullscreen-upload {
- 0% {
- right: -280px; }
- 100% {
- right: -1px; } }
-@-webkit-keyframes fullscreen-upload {
- 0% {
- right: -280px; }
- 100% {
- right: -1px; } }
-@-o-keyframes fullscreen-upload {
- 0% {
- right: -280px; }
- 100% {
- right: -1px; } }
+@keyframes fullscreen-upload { 0% { right: -280px; }
+ 100% { right: -1px; } }
+
+@-moz-keyframes fullscreen-upload { 0% { right: -280px; }
+ 100% { right: -1px; } }
+
+@-webkit-keyframes fullscreen-upload { 0% { right: -280px; }
+ 100% { right: -1px; } }
+
+@-o-keyframes fullscreen-upload { 0% { right: -280px; }
+ 100% { right: -1px; } }
+
/* 编辑器全屏 */
-/* line 200, ../scss/components/_editor.scss */
-.fullscreen #wmd-button-bar, .fullscreen #text, .fullscreen #wmd-preview, .fullscreen .submit {
- position: absolute;
- top: 0;
- width: 50%;
- background: #FFF;
- z-index: 999;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- -moz-border-radius: 0;
- -webkit-border-radius: 0;
- border-radius: 0; }
-/* line 210, ../scss/components/_editor.scss */
-.fullscreen #wmd-button-bar {
- left: 0;
- padding: 13px 20px;
- border-bottom: 1px solid #F3F3F0;
- z-index: 1000; }
-/* line 216, ../scss/components/_editor.scss */
-.fullscreen #text {
- top: 53px;
- left: 0;
- padding: 20px;
- border: none;
- outline: none; }
-/* line 223, ../scss/components/_editor.scss */
-.fullscreen #wmd-preview {
- top: 53px;
- right: 0;
- margin: 0;
- padding: 5px 20px;
- border: none;
- border-left: 1px solid #F3F3F0;
- background: #F6F6F3;
- overflow: auto; }
-/* line 233, ../scss/components/_editor.scss */
-.fullscreen .submit {
- right: 0;
- margin: 0;
- padding: 10px 20px;
- border-bottom: 1px solid #F3F3F0; }
-/* line 239, ../scss/components/_editor.scss */
-.fullscreen #upload-panel {
- -webkit-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.225);
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.225);
- border-style: solid; }
-/* line 246, ../scss/components/_editor.scss */
-.fullscreen #tab-files {
- position: absolute;
- top: 52px;
- right: -1px;
- width: 280px;
- z-index: 1001;
- animation: fullscreen-upload 0.5s;
- -moz-animation: fullscreen-upload 0.5s;
- -webkit-animation: fullscreen-upload 0.5s;
- -o-animation: fullscreen-upload 0.5s; }
-/* line 259, ../scss/components/_editor.scss */
-.fullscreen .wmd-edittab,
-.fullscreen .typecho-post-option,
-.fullscreen .title,
-.fullscreen .url-slug,
-.fullscreen .typecho-page-title,
-.fullscreen .typecho-head-nav,
-.fullscreen .message {
- display: none; }
-/* line 266, ../scss/components/_editor.scss */
-.fullscreen .wmd-hidetab {
- display: block; }
-/* line 267, ../scss/components/_editor.scss */
-.fullscreen .wmd-visualhide,
-.fullscreen #btn-fullscreen-upload {
- visibility: visible; }
+.fullscreen #wmd-button-bar, .fullscreen #text, .fullscreen #wmd-preview, .fullscreen .submit { position: absolute; top: 0; width: 50%; background: #FFF; z-index: 999; box-sizing: border-box; border-radius: 0; }
-/* line 274, ../scss/components/_editor.scss */
-.preview .submit {
- width: 100%;
- background: #FFFFDD; }
-/* line 275, ../scss/components/_editor.scss */
-.preview #wmd-button-bar, .preview #wmd-preview, .preview #text, .preview #upload-panel, .preview #tab-files, .preview #btn-preview, .preview #btn-fullscreen-upload, .preview #auto-save-message {
- display: none; }
-/* line 276, ../scss/components/_editor.scss */
-.preview .preview-frame {
- width: 100%;
- border: 0;
- padding: 0;
- margin: 0;
- background: #fff;
- z-index: 999;
- position: absolute;
- top: 53px;
- left: 0; }
-/* line 279, ../scss/components/_editor.scss */
-.preview .preview-loading {
- background-image: url(../img/ajax-loader.gif);
- background-position: center;
- background-repeat: no-repeat; }
-/* line 280, ../scss/components/_editor.scss */
-.preview #btn-cancel-preview {
- display: inline-block; }
+.fullscreen #wmd-button-bar { left: 0; padding: 13px 20px; border-bottom: 1px solid #F3F3F0; z-index: 1000; }
-/**
-* Jquery Timepicker
-*/
-/* line 5, ../scss/components/_timepicker.scss */
-#ui-datepicker-div {
- display: none;
- margin-top: -1px;
- padding: 10px;
- border: 1px solid #D9D9D6;
- background: #FFF; }
+.fullscreen #text { top: 53px; left: 0; padding: 20px; border: none; outline: none; }
-/* line 12, ../scss/components/_timepicker.scss */
-.ui-timepicker-div .ui-widget-header {
- margin-bottom: 8px; }
+.fullscreen #wmd-preview { top: 53px; right: 0; margin: 0; padding: 5px 20px; border: none; border-left: 1px solid #F3F3F0; background: #F6F6F3; overflow: auto; }
-/* line 13, ../scss/components/_timepicker.scss */
-.ui-timepicker-div dl {
- text-align: left; }
+.fullscreen .submit { right: 0; margin: 0; padding: 10px 20px; border-bottom: 1px solid #F3F3F0; }
-/* line 14, ../scss/components/_timepicker.scss */
-.ui-timepicker-div dl dt {
- float: left;
- clear: left; }
+.fullscreen #upload-panel { -webkit-box-shadow: 0 4px 16px rgba(0, 0, 0, 0.225); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.225); border-style: solid; }
-/* line 15, ../scss/components/_timepicker.scss */
-.ui-timepicker-div dl dd {
- margin: 0 0 10px 40%; }
+.fullscreen #tab-files { position: absolute; top: 52px; right: -1px; width: 280px; z-index: 1001; animation: fullscreen-upload 0.5s; -moz-animation: fullscreen-upload 0.5s; -webkit-animation: fullscreen-upload 0.5s; -o-animation: fullscreen-upload 0.5s; }
-/* line 16, ../scss/components/_timepicker.scss */
-.ui-tpicker-grid-label {
- background: none;
- border: none;
- margin: 0;
- padding: 0; }
+.fullscreen .wmd-edittab, .fullscreen .typecho-post-option, .fullscreen .title, .fullscreen .url-slug, .fullscreen .typecho-page-title, .fullscreen .typecho-head-nav, .fullscreen .message { display: none; }
-/* line 18, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-header {
- margin-bottom: 10px;
- padding-bottom: 10px;
- border-bottom: 1px solid #EEE; }
+.fullscreen .wmd-hidetab { display: block; }
-/* line 23, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-prev {
- float: left;
- cursor: pointer; }
+.fullscreen .wmd-visualhide, .fullscreen #btn-fullscreen-upload { visibility: visible; }
-/* line 24, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-next {
- float: right;
- cursor: pointer; }
+.preview .submit { width: 100%; background: #FFFFDD; }
-/* line 25, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-title {
- font-weight: bold;
- text-align: center; }
+.preview #wmd-button-bar, .preview #wmd-preview, .preview #text, .preview #upload-panel, .preview #tab-files, .preview #btn-preview, .preview #btn-fullscreen-upload, .preview #auto-save-message { display: none; }
-/* line 29, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-calendar th {
- line-height: 24px; }
+.preview .preview-frame { width: 100%; border: 0; padding: 0; margin: 0; background: #fff; z-index: 999; position: absolute; top: 53px; left: 0; }
-/* line 30, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-calendar a {
- display: block;
- width: 30px;
- background-color: #F3F3F0;
- line-height: 24px;
- text-align: center; }
+.preview .preview-loading { background-image: url(../img/ajax-loader.gif); background-position: center; background-repeat: no-repeat; }
-/* line 37, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-calendar a:hover {
- background-color: #E9E9E6;
- text-decoration: none; }
+.preview #btn-cancel-preview { display: inline-block; }
-/* line 41, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-today a {
- background-color: #E9E9E6;
- color: #444; }
+/** Jquery Timepicker */
+#ui-datepicker-div { display: none; margin-top: -1px; padding: 10px; border: 1px solid #D9D9D6; background: #FFF; }
-/* line 45, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-current-day a {
- background-color: #467B96 !important;
- color: #FFF; }
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
-/* line 49, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-timepicker-div {
- margin-top: 20px;
- border-top: 1px solid #EEE; }
+.ui-timepicker-div dl { text-align: left; }
-/* line 53, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-slider {
- position: relative;
- margin-top: 18px;
- border: 1px solid #E9E9E6;
- background-color: #F6F6F3;
- height: 4px; }
+.ui-timepicker-div dl dt { float: left; clear: left; }
-/* line 60, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-slider .ui-slider-handle {
- position: absolute;
- top: -7px;
- margin-left: -5px;
- z-index: 2;
- width: 10px;
- height: 16px;
- background-color: #467B96; }
+.ui-timepicker-div dl dd { margin: 0 0 10px 40%; }
-/* line 70, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-buttonpane {
- padding-top: 10px;
- border-top: 1px solid #EEE; }
+.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
-/* line 74, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-current,
-#ui-datepicker-div .ui-datepicker-close {
- float: left; }
+#ui-datepicker-div .ui-datepicker-header { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #EEE; }
-/* line 80, ../scss/components/_timepicker.scss */
-#ui-datepicker-div .ui-datepicker-close {
- float: right; }
+#ui-datepicker-div .ui-datepicker-prev { float: left; cursor: pointer; }
-/* line 84, ../scss/components/_timepicker.scss */
-.ui-effects-transfer {
- border: 2px dotted #ccc; }
+#ui-datepicker-div .ui-datepicker-next { float: right; cursor: pointer; }
-/**
-* Jquery Tokeninput
-*/
-/* line 5, ../scss/components/_tokeninput.scss */
-ul.token-input-list {
- list-style: none;
- margin: 0;
- padding: 0 4px;
- min-height: 32px;
- border: 1px solid #D9D9D6;
- cursor: text;
- z-index: 999;
- background-color: #FFF;
- clear: left;
- border-radius: 2px;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box; }
- /* line 22, ../scss/components/_tokeninput.scss */
- ul.token-input-list li {
- margin: 4px 0; }
+#ui-datepicker-div .ui-datepicker-title { font-weight: bold; text-align: center; }
-/* line 28, ../scss/components/_tokeninput.scss */
-ul.token-input-list li input {
- padding: 0;
- border: 0;
- width: 100%;
- -webkit-appearance: caret; }
+#ui-datepicker-div .ui-datepicker-calendar th { line-height: 24px; }
-/* line 35, ../scss/components/_tokeninput.scss */
-li.token-input-token {
- padding: 0 6px;
- height: 27px;
- line-height: 27px;
- background-color: #F3F3F0;
- cursor: default;
- font-size: .92857em;
- text-align: right;
- white-space: nowrap; }
- /* line 44, ../scss/components/_tokeninput.scss */
- li.token-input-token p {
- float: left;
- display: inline;
- margin: 0; }
- /* line 49, ../scss/components/_tokeninput.scss */
- li.token-input-token span {
- color: #BBB;
- font-weight: bold;
- cursor: pointer; }
+#ui-datepicker-div .ui-datepicker-calendar a { display: block; width: 30px; background-color: #F3F3F0; line-height: 24px; text-align: center; }
-/* line 58, ../scss/components/_tokeninput.scss */
-li.token-input-selected-token {
- background-color: #E9E9E6; }
+#ui-datepicker-div .ui-datepicker-calendar a:hover { background-color: #E9E9E6; text-decoration: none; }
-/* line 62, ../scss/components/_tokeninput.scss */
-li.token-input-input-token {
- padding: 0 4px; }
+#ui-datepicker-div .ui-datepicker-today a { background-color: #E9E9E6; color: #444; }
-/* line 66, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown {
- position: absolute;
- background-color: #FFF;
- overflow: hidden;
- border: 1px solid #D9D9D6;
- border-top-width: 0;
- cursor: default;
- z-index: 1;
- font-size: .92857em; }
+#ui-datepicker-div .ui-datepicker-current-day a { background-color: #467B96 !important; color: #FFF; }
-/* line 77, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown p {
- margin: 0;
- padding: 5px 10px;
- color: #777;
- font-weight: bold; }
+#ui-datepicker-div .ui-timepicker-div { margin-top: 20px; border-top: 1px solid #EEE; }
-/* line 84, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown ul {
- list-style: none;
- margin: 0;
- padding: 0; }
+#ui-datepicker-div .ui-slider { position: relative; margin-top: 18px; border: 1px solid #E9E9E6; background-color: #F6F6F3; height: 4px; }
-/* line 90, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown ul li {
- padding: 4px 10px;
- background-color: #FFF; }
+#ui-datepicker-div .ui-slider .ui-slider-handle { position: absolute; top: -7px; margin-left: -5px; z-index: 2; width: 10px; height: 16px; background-color: #467B96; }
-/* line 95, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown ul li.token-input-dropdown-item {
- background-color: #FFF; }
+#ui-datepicker-div .ui-datepicker-buttonpane { padding-top: 10px; border-top: 1px solid #EEE; }
-/* line 99, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown ul li em {
- font-style: normal; }
+#ui-datepicker-div .ui-datepicker-current, #ui-datepicker-div .ui-datepicker-close { float: left; }
-/* line 103, ../scss/components/_tokeninput.scss */
-div.token-input-dropdown ul li.token-input-selected-dropdown-item {
- background-color: #467B96;
- color: #FFF; }
+#ui-datepicker-div .ui-datepicker-close { float: right; }
-/*
-* Hide from both screenreaders and browsers: h5bp.com/u
-*/
-/* line 5, ../scss/_hidden.scss */
-.hidden {
- display: none; }
+.ui-effects-transfer { border: 2px dotted #ccc; }
-/*
-* Hide only visually, but have it available for screenreaders: h5bp.com/v
-*/
-/* line 15, ../scss/_hidden.scss */
-.sr-only {
- border: 0;
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px; }
+/** Jquery Tokeninput */
+ul.token-input-list { list-style: none; margin: 0; padding: 0 4px; min-height: 32px; border: 1px solid #D9D9D6; cursor: text; z-index: 999; background-color: #FFF; clear: left; border-radius: 2px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
-/*
-* Extends the .sr-only class to allow the element to be focusable
-* when navigated to via the keyboard: h5bp.com/p
-*/
-/* line 30, ../scss/_hidden.scss */
-.sr-only.focusable:active,
-.sr-only.focusable:focus {
- clip: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- position: static;
- width: auto; }
+ul.token-input-list li { margin: 4px 0; }
-/*
-* Hide visually and from screenreaders, but maintain layout
-*/
-/* line 44, ../scss/_hidden.scss */
-.invisible {
- visibility: hidden; }
+ul.token-input-list li input { padding: 0; border: 0; width: 100%; -webkit-appearance: caret; }
+
+li.token-input-token { padding: 0 6px; height: 27px; line-height: 27px; background-color: #F3F3F0; cursor: default; font-size: .92857em; text-align: right; white-space: nowrap; }
+
+li.token-input-token p { float: left; display: inline; margin: 0; }
+
+li.token-input-token span { color: #BBB; font-weight: bold; cursor: pointer; }
+
+li.token-input-selected-token { background-color: #E9E9E6; }
+
+li.token-input-input-token { padding: 0 4px; }
+
+div.token-input-dropdown { position: absolute; background-color: #FFF; overflow: hidden; border: 1px solid #D9D9D6; border-top-width: 0; cursor: default; z-index: 1; font-size: .92857em; }
+
+div.token-input-dropdown p { margin: 0; padding: 5px 10px; color: #777; font-weight: bold; }
+
+div.token-input-dropdown ul { list-style: none; margin: 0; padding: 0; }
+
+div.token-input-dropdown ul li { padding: 4px 10px; background-color: #FFF; }
+
+div.token-input-dropdown ul li.token-input-dropdown-item { background-color: #FFF; }
+
+div.token-input-dropdown ul li em { font-style: normal; }
+
+div.token-input-dropdown ul li.token-input-selected-dropdown-item { background-color: #467B96; color: #FFF; }
+
+/* Hide from both screenreaders and browsers: h5bp.com/u */
+.hidden { display: none; }
+
+/* Hide only visually, but have it available for screenreaders: h5bp.com/v */
+.sr-only { border: 0; height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+
+/* Extends the .sr-only class to allow the element to be focusable when navigated to via the keyboard: h5bp.com/p */
+.sr-only.focusable:active, .sr-only.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
+
+/* Hide visually and from screenreaders, but maintain layout */
+.invisible { visibility: hidden; }
diff --git a/admin/img/icons-2x-s481937020b.png b/admin/img/icons-2x-s481937020b.png
deleted file mode 100644
index f887f62a..00000000
Binary files a/admin/img/icons-2x-s481937020b.png and /dev/null differ
diff --git a/admin/img/icons-2x.png b/admin/img/icons-2x.png
new file mode 100644
index 00000000..642f712f
Binary files /dev/null and b/admin/img/icons-2x.png differ
diff --git a/admin/img/icons-s0c4f1c5ae6.png b/admin/img/icons-s0c4f1c5ae6.png
deleted file mode 100644
index b82a6daa..00000000
Binary files a/admin/img/icons-s0c4f1c5ae6.png and /dev/null differ
diff --git a/admin/img/icons.png b/admin/img/icons.png
new file mode 100644
index 00000000..12038ecd
Binary files /dev/null and b/admin/img/icons.png differ
diff --git a/admin/js/html5shiv.js b/admin/js/html5shiv.js
index d074da78..1ba2909d 100644
--- a/admin/js/html5shiv.js
+++ b/admin/js/html5shiv.js
@@ -1,301 +1 @@
-/**
-* @preserve HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
-*/
-;(function(window, document) {
-/*jshint evil:true */
- /** version */
- var version = '3.7.0';
-
- /** Preset options */
- var options = window.html5 || {};
-
- /** Used to skip problem elements */
- var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
-
- /** Not all elements can be cloned in IE **/
- var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
-
- /** Detect whether the browser supports default html5 styles */
- var supportsHtml5Styles;
-
- /** Name of the expando, to work with multiple documents or to re-shiv one document */
- var expando = '_html5shiv';
-
- /** The id for the the documents expando */
- var expanID = 0;
-
- /** Cached data for each document */
- var expandoData = {};
-
- /** Detect whether the browser supports unknown elements */
- var supportsUnknownElements;
-
- (function() {
- try {
- var a = document.createElement('a');
- a.innerHTML = ' ' + (this.markLine(start, end)) + (htmlspecialchars(lines.join("\n"))) + '' + (htmlspecialchars(matches[3])) + '
');
- };
- })(this));
- text = text.replace(/(^|[^\\])(\$+)(.+?)\2/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return matches[1] + _this.makeHolder(matches[2] + (htmlspecialchars(matches[3])) + matches[2]);
- };
- })(this));
- text = text.replace(/\\(.)/g, (function(_this) {
- return function() {
- var escaped, matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- escaped = htmlspecialchars(matches[1]);
- escaped = escaped.replace(/\$/g, '$');
- return _this.makeHolder(escaped);
- };
- })(this));
- text = text.replace(/<(https?:\/\/.+)>/ig, (function(_this) {
- return function() {
- var link, matches, url;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- url = _this.cleanUrl(matches[1]);
- link = _this.call('parseLink', matches[1]);
- return _this.makeHolder("" + link + "");
- };
- })(this));
- text = text.replace(/<(\/?)([a-z0-9-]+)(\s+[^>]*)?>/ig, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- if (_this.html || (('|' + _this.commonWhiteList + '|' + whiteList + '|').indexOf('|' + matches[2].toLowerCase() + '|')) >= 0) {
- return _this.makeHolder(matches[0]);
- } else {
- return htmlspecialchars(matches[0]);
- }
- };
- })(this));
- if (this.html) {
- text = text.replace(//g, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return _this.makeHolder(matches[0]);
- };
- })(this));
- }
- text = str_replace(['<', '>'], ['<', '>'], text);
- text = text.replace(/\[\^((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) {
- return function() {
- var id, matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- id = _this.footnotes.indexOf(matches[1]);
- if (id < 0) {
- id = _this.footnotes.length + 1;
- _this.footnotes.push(_this.parseInline(matches[1], '', false));
- }
- return _this.makeHolder("" + id + "");
- };
- })(this));
- text = text.replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g, (function(_this) {
- return function() {
- var escaped, matches, url;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- escaped = htmlspecialchars(_this.escapeBracket(matches[1]));
- url = _this.escapeBracket(matches[2]);
- url = _this.cleanUrl(url);
- return _this.makeHolder("");
- };
- })(this));
- text = text.replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) {
- return function() {
- var escaped, matches, result;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- escaped = htmlspecialchars(_this.escapeBracket(matches[1]));
- result = _this.definitions[matches[2]] != null ? "" : escaped;
- return _this.makeHolder(result);
- };
- })(this));
- text = text.replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g, (function(_this) {
- return function() {
- var escaped, matches, url;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- escaped = _this.parseInline(_this.escapeBracket(matches[1]), '', false, false);
- url = _this.escapeBracket(matches[2]);
- url = _this.cleanUrl(url);
- return _this.makeHolder("" + escaped + "");
- };
- })(this));
- text = text.replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) {
- return function() {
- var escaped, matches, result;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- escaped = _this.parseInline(_this.escapeBracket(matches[1]), '', false, false);
- result = _this.definitions[matches[2]] != null ? "" + escaped + "" : escaped;
- return _this.makeHolder(result);
- };
- })(this));
- text = this.parseInlineCallback(text);
- text = text.replace(/<([_a-z0-9-\.\+]+@[^@]+\.[a-z]{2,})>/ig, '$1');
- if (enableAutoLink) {
- regex = new RegExp("(^|[^\"])((https?):[" + pL + "_0-9-\\./%#!@\\?\\+=~\\|\\,&\\(\\)]+)($|[^\"])", 'ig');
- text = text.replace(regex, (function(_this) {
- return function() {
- var link, matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- link = _this.call('parseLink', matches[2]);
- return matches[1] + "" + link + "" + matches[4];
- };
- })(this));
- }
- text = this.call('afterParseInlineBeforeRelease', text);
- text = this.releaseHolder(text, clearHolders);
- text = this.call('afterParseInline', text);
- return text;
- };
-
- Parser.prototype.parseInlineCallback = function(text) {
- text = text.replace(/(\*{3})((?:.|\r)+?)\1/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return '' + (_this.parseInlineCallback(matches[2])) + '';
- };
- })(this));
- text = text.replace(/(\*{2})((?:.|\r)+?)\1/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return '' + (_this.parseInlineCallback(matches[2])) + '';
- };
- })(this));
- text = text.replace(/(\*)((?:.|\r)+?)\1/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return '' + (_this.parseInlineCallback(matches[2])) + '';
- };
- })(this));
- text = text.replace(/(\s+|^)(_{3})((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4];
- };
- })(this));
- text = text.replace(/(\s+|^)(_{2})((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4];
- };
- })(this));
- text = text.replace(/(\s+|^)(_)((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4];
- };
- })(this));
- text = text.replace(/(~{2})((?:.|\r)+?)\1/mg, (function(_this) {
- return function() {
- var matches;
- matches = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return '' + (_this.parseInlineCallback(matches[2])) + '';
- };
- })(this));
- return text;
- };
-
- Parser.prototype.parseBlock = function(text, lines) {
- var block, j, key, l, len, len1, line, name, parser, pass, ref, ref1, state;
- ref = text.split("\n");
- for (j = 0, len = ref.length; j < len; j++) {
- line = ref[j];
- lines.push(line);
- }
- this.blocks = [];
- this.current = 'normal';
- this.pos = -1;
- state = {
- special: (array_keys(this.specialWhiteList)).join('|'),
- empty: 0,
- html: false
- };
- for (key = l = 0, len1 = lines.length; l < len1; key = ++l) {
- line = lines[key];
- block = this.getBlock();
- if (block != null) {
- block = block.slice(0);
- }
- if (this.current !== 'normal') {
- pass = this.parsers[this.current](block, key, line, state, lines);
- if (!pass) {
- continue;
- }
- }
- ref1 = this.parsers;
- for (name in ref1) {
- parser = ref1[name];
- if (name !== this.current) {
- pass = parser(block, key, line, state, lines);
- if (!pass) {
- break;
- }
- }
- }
- }
- return this.optimizeBlocks(this.blocks, lines);
- };
-
- Parser.prototype.parseBlockList = function(block, key, line, state) {
- var matches, space;
- if (!!(matches = line.match(/^(\s*)((?:[0-9]+\.)|\-|\+|\*)\s+/i))) {
- space = matches[1].length;
- state.empty = 0;
- if (this.isBlock('list')) {
- this.setBlock(key, space);
- } else {
- this.startBlock('list', key, space);
- }
- return false;
- } else if ((this.isBlock('list')) && !line.match(/^\s*\[((?:[^\]]|\\\]|\\\[)+?)\]:\s*(.+)$/)) {
- if ((state.empty <= 1) && !!(matches = line.match(/^(\s+)/)) && matches[1].length > block[3]) {
- state.empty = 0;
- this.setBlock(key);
- return false;
- } else if ((line.match(/^\s*$/)) && state.empty === 0) {
- state.empty += 1;
- this.setBlock(key);
- return false;
- }
- }
- return true;
- };
-
- Parser.prototype.parseBlockCode = function(block, key, line) {
- var isAfterList, matches, space;
- if (!!(matches = line.match(/^(\s*)(~{3,}|`{3,})([^`~]*)$/i))) {
- if (this.isBlock('code')) {
- isAfterList = block[3][2];
- if (isAfterList) {
- this.combineBlock().setBlock(key);
- } else {
- (this.setBlock(key)).endBlock();
- }
- } else {
- isAfterList = false;
- if (this.isBlock('list')) {
- space = block[3];
- isAfterList = (space > 0 && matches[1].length >= space) || matches[1].length > space;
- }
- this.startBlock('code', key, [matches[1], matches[3], isAfterList]);
- }
- return false;
- } else if (this.isBlock('code')) {
- this.setBlock(key);
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockShtml = function(block, key, line, state) {
- var matches;
- if (this.html) {
- if (!!(matches = line.match(/^(\s*)!!!(\s*)$/))) {
- if (this.isBlock('shtml')) {
- this.setBlock(key).endBlock();
- } else {
- this.startBlock('shtml', key);
- }
- return false;
- } else if (this.isBlock('shtml')) {
- this.setBlock(key);
- return false;
- }
- }
- return true;
- };
-
- Parser.prototype.parseBlockAhtml = function(block, key, line, state) {
- var htmlTagAllRegExp, htmlTagRegExp, lastMatch, m, matches;
- if (this.html) {
- htmlTagRegExp = new RegExp("^\\s*<(" + this.blockHtmlTags + ")(\\s+[^>]*)?>", 'i');
- if (matches = line.match(htmlTagRegExp)) {
- if (this.isBlock('ahtml')) {
- this.setBlock(key);
- return false;
- } else if (matches[2] === void 0 || matches[2] !== '/') {
- this.startBlock('ahtml', key);
- htmlTagAllRegExp = new RegExp("\\s*<(" + this.blockHtmlTags + ")(\\s+[^>]*)?>", 'ig');
- while (true) {
- m = htmlTagAllRegExp.exec(line);
- if (!m) {
- break;
- }
- lastMatch = m[1];
- }
- if (0 <= line.indexOf("" + lastMatch + ">")) {
- this.endBlock();
- } else {
- state.html = lastMatch;
- }
- return false;
- }
- } else if (!!state.html && 0 <= line.indexOf("" + state.html + ">")) {
- this.setBlock(key).endBlock();
- state.html = false;
- return false;
- } else if (this.isBlock('ahtml')) {
- this.setBlock(key);
- return false;
- } else if (!!(matches = line.match(/^\s*\s*$/))) {
- this.startBlock('ahtml', key).endBlock();
- return false;
- }
- }
- return true;
- };
-
- Parser.prototype.parseBlockMath = function(block, key, line) {
- var matches;
- if (!!(matches = line.match(/^(\s*)\$\$(\s*)$/))) {
- if (this.isBlock('math')) {
- this.setBlock(key).endBlock();
- } else {
- this.startBlock('math', key);
- }
- return false;
- } else if (this.isBlock('math')) {
- this.setBlock(key);
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockPre = function(block, key, line, state) {
- if (!!(line.match(/^ {4}/))) {
- if (this.isBlock('pre')) {
- this.setBlock(key);
- } else {
- this.startBlock('pre', key);
- }
- return false;
- } else if ((this.isBlock('pre')) && line.match(/^\s*$/)) {
- this.setBlock(key);
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockHtml = function(block, key, line, state) {
- var matches, tag;
- if (!!(matches = line.match(new RegExp("^\\s*<(" + state.special + ")(\\s+[^>]*)?>", 'i')))) {
- tag = matches[1].toLowerCase();
- if (!(this.isBlock('html', tag)) && !(this.isBlock('pre'))) {
- this.startBlock('html', key, tag);
- }
- return false;
- } else if (!!(matches = line.match(new RegExp("(" + state.special + ")>\\s*$", 'i')))) {
- tag = matches[1].toLowerCase();
- if (this.isBlock('html', tag)) {
- this.setBlock(key).endBlock();
- }
- return false;
- } else if (this.isBlock('html')) {
- this.setBlock(key);
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockFootnote = function(block, key, line) {
- var matches, space;
- if (!!(matches = line.match(/^\[\^((?:[^\]]|\\\]|\\\[)+?)\]:/))) {
- space = matches[0].length - 1;
- this.startBlock('footnote', key, [space, matches[1]]);
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockDefinition = function(block, key, line) {
- var matches;
- if (!!(matches = line.match(/^\s*\[((?:[^\]]|\\\]|\\\[)+?)\]:\s*(.+)$/))) {
- this.definitions[matches[1]] = this.cleanUrl(matches[2]);
- this.startBlock('definition', key).endBlock();
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockQuote = function(block, key, line) {
- var matches;
- if (!!(matches = line.match(/^(\s*)>/))) {
- if ((this.isBlock('list')) && matches[1].length > 0) {
- this.setBlock(key);
- } else if (this.isBlock('quote')) {
- this.setBlock(key);
- } else {
- this.startBlock('quote', key);
- }
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockTable = function(block, key, line, state, lines) {
- var align, aligns, head, j, len, matches, row, rows;
- if (!!(matches = line.match(/^((?:(?:(?:\||\+)(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:[ :]*\-+[ :]*)(?:\||\+)(?:[ :]*\-+[ :]*))|(?:(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:\||\+)(?:[ :]*\-+[ :]*)))+)$/))) {
- if (this.isBlock('table')) {
- block[3][0].push(block[3][2]);
- block[3][2] += 1;
- this.setBlock(key, block[3]);
- } else {
- head = 0;
- if ((block == null) || block[0] !== 'normal' || lines[block[2]].match(/^\s*$/)) {
- this.startBlock('table', key);
- } else {
- head = 1;
- this.backBlock(1, 'table');
- }
- if (matches[1][0] === '|') {
- matches[1] = matches[1].substring(1);
- if (matches[1][matches[1].length - 1] === '|') {
- matches[1] = matches[1].substring(0, matches[1].length - 1);
- }
- }
- rows = matches[1].split(/\+|\|/);
- aligns = [];
- for (j = 0, len = rows.length; j < len; j++) {
- row = rows[j];
- align = 'none';
- if (!!(matches = row.match(/^\s*(:?)\-+(:?)\s*$/))) {
- if (!!matches[1] && !!matches[2]) {
- align = 'center';
- } else if (!!matches[1]) {
- align = 'left';
- } else if (!!matches[2]) {
- align = 'right';
- }
- }
- aligns.push(align);
- }
- this.setBlock(key, [[head], aligns, head + 1]);
- }
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockSh = function(block, key, line) {
- var matches, num;
- if (!!(matches = line.match(/^(#+)(.*)$/))) {
- num = Math.min(matches[1].length, 6);
- this.startBlock('sh', key, num).endBlock();
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockMh = function(block, key, line, state, lines) {
- var matches;
- if (!!(matches = line.match(/^\s*((=|-){2,})\s*$/)) && ((block != null) && block[0] === 'normal' && !lines[block[2]].match(/^\s*$/))) {
- if (this.isBlock('normal')) {
- this.backBlock(1, 'mh', matches[1][0] === '=' ? 1 : 2).setBlock(key).endBlock();
- } else {
- this.startBlock('normal', key);
- }
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockShr = function(block, key, line) {
- if (!!(line.match(/^(\* *){3,}\s*$/))) {
- this.startBlock('hr', key).endBlock();
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockDhr = function(block, key, line) {
- if (!!(line.match(/^(- *){3,}\s*$/))) {
- this.startBlock('hr', key).endBlock();
- return false;
- }
- return true;
- };
-
- Parser.prototype.parseBlockDefault = function(block, key, line, state) {
- var matches;
- if (this.isBlock('footnote')) {
- matches = line.match(/^(\s*)/);
- if (matches[1].length >= block[3][0]) {
- this.setBlock(key);
- } else {
- this.startBlock('normal', key);
- }
- } else if (this.isBlock('table')) {
- if (0 <= line.indexOf('|')) {
- block[3][2] += 1;
- this.setBlock(key, block[3]);
- } else {
- this.startBlock('normal', key);
- }
- } else if (this.isBlock('quote')) {
- if (!line.match(/^(\s*)$/)) {
- this.setBlock(key);
- } else {
- this.startBlock('normal', key);
- }
- } else {
- if ((block == null) || block[0] !== 'normal') {
- this.startBlock('normal', key);
- } else {
- this.setBlock(key);
- }
- }
- return true;
- };
-
- Parser.prototype.optimizeBlocks = function(_blocks, _lines) {
- var block, blocks, from, isEmpty, key, lines, moved, nextBlock, prevBlock, to, type, types;
- blocks = _blocks.slice(0);
- lines = _lines.slice(0);
- blocks = this.call('beforeOptimizeBlocks', blocks, lines);
- key = 0;
- while (blocks[key] != null) {
- moved = false;
- block = blocks[key];
- prevBlock = blocks[key - 1] != null ? blocks[key - 1] : null;
- nextBlock = blocks[key + 1] != null ? blocks[key + 1] : null;
- type = block[0], from = block[1], to = block[2];
- if ('pre' === type) {
- isEmpty = (lines.slice(block[1], block[2] + 1)).reduce(function(result, line) {
- return (line.match(/^\s*$/)) && result;
- }, true);
- if (isEmpty) {
- block[0] = type = 'normal';
- }
- }
- if ('normal' === type) {
- types = ['list', 'quote'];
- if (from === to && (lines[from].match(/^\s*$/)) && (prevBlock != null) && (nextBlock != null)) {
- if (prevBlock[0] === nextBlock[0] && (types.indexOf(prevBlock[0])) >= 0) {
- blocks[key - 1] = [prevBlock[0], prevBlock[1], nextBlock[2], null];
- blocks.splice(key, 2);
- moved = true;
- }
- }
- }
- if (!moved) {
- key += 1;
- }
- }
- return this.call('afterOptimizeBlocks', blocks, lines);
- };
-
- Parser.prototype.parseCode = function(lines, parts, start) {
- var blank, count, isEmpty, lang, rel, str;
- blank = parts[0], lang = parts[1];
- lang = trim(lang);
- count = blank.length;
- if (!lang.match(/^[_a-z0-9-\+\#\:\.]+$/i)) {
- lang = null;
- } else {
- parts = lang.split(':');
- if (parts.length > 1) {
- lang = parts[0], rel = parts[1];
- lang = trim(lang);
- rel = trim(rel);
- }
- }
- isEmpty = true;
- lines = lines.slice(1, -1).map(function(line) {
- line = line.replace(new RegExp("/^[ ]{" + count + "}/"), '');
- if (isEmpty && !line.match(/^\s*$/)) {
- isEmpty = false;
- }
- return htmlspecialchars(line);
- });
- str = (this.markLines(lines, start + 1)).join("\n");
- if (isEmpty) {
- return '';
- } else {
- return '
';
- }
- };
-
- Parser.prototype.parsePre = function(lines, value, start) {
- var str;
- lines = lines.map(function(line) {
- return htmlspecialchars(line.substring(4));
- });
- str = (this.markLines(lines, start)).join("\n");
- if (str.match(/^\s*$/)) {
- return '';
- } else {
- return '' + str + '
';
- }
- };
-
- Parser.prototype.parseAhtml = function(lines, value, start) {
- return trim((this.markLines(lines, start)).join("\n"));
- };
-
- Parser.prototype.parseShtml = function(lines, value, start) {
- return trim((this.markLines(lines.slice(1, -1), start + 1)).join("\n"));
- };
-
- Parser.prototype.parseMath = function(lines, value, start, end) {
- return '' + str + '
' + (this.parse(str, true, start)) + '
';
- }
- };
-
- Parser.prototype.parseList = function(lines, value, start) {
- var found, html, j, key, l, lastType, leftLines, leftStart, len, len1, line, matches, minSpace, row, rows, secondFound, secondMinSpace, space, text, type;
- html = '';
- minSpace = 99999;
- secondMinSpace = 99999;
- found = false;
- secondFound = false;
- rows = [];
- for (key = j = 0, len = lines.length; j < len; key = ++j) {
- line = lines[key];
- if (matches = line.match(/^(\s*)((?:[0-9]+\.?)|\-|\+|\*)(\s+)(.*)$/i)) {
- space = matches[1].length;
- type = 0 <= '+-*'.indexOf(matches[2]) ? 'ul' : 'ol';
- minSpace = Math.min(space, minSpace);
- found = true;
- if (space > 0) {
- secondMinSpace = Math.min(space, secondMinSpace);
- secondFound = true;
- }
- rows.push([space, type, line, matches[4]]);
- } else {
- rows.push(line);
- if (!!(matches = line.match(/^(\s*)/))) {
- space = matches[1].length;
- if (space > 0) {
- secondMinSpace = Math.min(space, secondMinSpace);
- secondFound = true;
- }
- }
- }
- }
- minSpace = found ? minSpace : 0;
- secondMinSpace = secondFound ? secondMinSpace : minSpace;
- lastType = '';
- leftLines = [];
- leftStart = 0;
- for (key = l = 0, len1 = rows.length; l < len1; key = ++l) {
- row = rows[key];
- if (row instanceof Array) {
- space = row[0], type = row[1], line = row[2], text = row[3];
- if (space !== minSpace) {
- leftLines.push(line.replace(new RegExp("^\\s{" + secondMinSpace + "}"), ''));
- } else {
- if (leftLines.length > 0) {
- html += '';
- body = head ? null : true;
- output = false;
- for (key = j = 0, len = lines.length; j < len; key = ++j) {
- line = lines[key];
- if (0 <= ignores.indexOf(key)) {
- if (head && output) {
- head = false;
- body = true;
- }
- continue;
- }
- line = trim(line);
- output = true;
- if (line[0] === '|') {
- line = line.substring(1);
- if (line[line.length - 1] === '|') {
- line = line.substring(0, line.length - 1);
- }
- }
- rows = line.split('|').map(function(row) {
- if (row.match(/^\s*$/)) {
- return ' ';
- } else {
- return trim(row);
- }
- });
- columns = {};
- last = -1;
- for (l = 0, len1 = rows.length; l < len1; l++) {
- row = rows[l];
- if (row.length > 0) {
- last += 1;
- columns[last] = [(columns[last] != null ? columns[last][0] + 1 : 1), row];
- } else if (columns[last] != null) {
- columns[last][0] += 1;
- } else {
- columns[0] = [1, row];
- }
- }
- if (head) {
- html += '';
- } else if (body) {
- html += '';
- }
- html += '
';
- };
-
- Parser.prototype.parseHr = function(lines, value, start) {
- if (this.line) {
- return '';
- for (key in columns) {
- column = columns[key];
- num = column[0], text = column[1];
- tag = head ? 'th' : 'td';
- html += "<" + tag;
- if (num > 1) {
- html += " colspan=\"" + num + "\"";
- }
- if ((aligns[key] != null) && aligns[key] !== 'none') {
- html += " align=\"" + aligns[key] + "\"";
- }
- html += '>' + (this.parseInline(text)) + ("" + tag + ">");
- }
- html += ' ';
- if (head) {
- html += '';
- } else if (body) {
- body = false;
- }
- }
- if (body !== null) {
- html += '';
- }
- return html += '
';
- } else {
- return '
';
- }
- };
-
- Parser.prototype.parseNormal = function(lines, inline, start) {
- var key, str;
- if (inline == null) {
- inline = false;
- }
- key = 0;
- lines = lines.map((function(_this) {
- return function(line) {
- line = _this.parseInline(line);
- if (!line.match(/^\s*$/)) {
- line = (_this.markLine(start + key)) + line;
- }
- key += 1;
- return line;
- };
- })(this));
- str = trim(lines.join("\n"));
- str = str.replace(/(\n\s*){2,}/g, '
');
- str = str.replace(/\n/g, '
');
- if (str.match(/^\s*$/)) {
- return '';
- } else {
- if (inline) {
- return str;
- } else {
- return "
" + str + "
"; - } - } - }; - - Parser.prototype.parseFootnote = function(lines, value) { - var index, note, space; - space = value[0], note = value[1]; - index = this.footnotes.indexOf(note); - if (index >= 0) { - lines = lines.slice(0); - lines[0] = lines[0].replace(/^\[\^((?:[^\]]|\]|\[)+?)\]:/, ''); - this.footnotes[index] = lines; - } - return ''; - }; - - Parser.prototype.parseDefinition = function() { - return ''; - }; - - Parser.prototype.parseHtml = function(lines, type, start) { - lines = lines.map((function(_this) { - return function(line) { - return _this.parseInline(line, _this.specialWhiteList[type] != null ? _this.specialWhiteList[type] : ''); - }; - })(this)); - return (this.markLines(lines, start)).join("\n"); - }; - - Parser.prototype.cleanUrl = function(url) { - var matches, regexUrl, regexWord; - regexUrl = new RegExp("^\\s*((http|https|ftp|mailto):[" + pL + "_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&\\(\\)]+)", 'i'); - regexWord = new RegExp("^\\s*([" + pL + "_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&]+)", 'i'); - if (!!(matches = url.match(regexUrl))) { - return matches[1]; - } else if (!!(matches = url.match(regexWord))) { - return matches[1]; - } else { - return '#'; - } - }; - - Parser.prototype.escapeBracket = function(str) { - return str_replace(['\\[', '\\]', '\\(', '\\)'], ['[', ']', '(', ')'], str); - }; - - Parser.prototype.startBlock = function(type, start, value) { - if (value == null) { - value = null; - } - this.pos += 1; - this.current = type; - this.blocks.push([type, start, start, value]); - return this; - }; - - Parser.prototype.endBlock = function() { - this.current = 'normal'; - return this; - }; - - Parser.prototype.isBlock = function(type, value) { - if (value == null) { - value = null; - } - return this.current === type && (null === value ? true : this.blocks[this.pos][3] === value); - }; - - Parser.prototype.getBlock = function() { - if (this.blocks[this.pos] != null) { - return this.blocks[this.pos]; - } else { - return null; - } - }; - - Parser.prototype.setBlock = function(to, value) { - if (to == null) { - to = null; - } - if (value == null) { - value = null; - } - if (to !== null) { - this.blocks[this.pos][2] = to; - } - if (value !== null) { - this.blocks[this.pos][3] = value; - } - return this; - }; - - Parser.prototype.backBlock = function(step, type, value) { - var item, last; - if (value == null) { - value = null; - } - if (this.pos < 0) { - return this.startBlock(type, 0, value); - } - last = this.blocks[this.pos][2]; - this.blocks[this.pos][2] = last - step; - item = [type, last - step + 1, last, value]; - if (this.blocks[this.pos][1] <= this.blocks[this.pos][2]) { - this.pos += 1; - this.blocks.push(item); - } else { - this.blocks[this.pos] = item; - } - this.current = type; - return this; - }; - - Parser.prototype.combineBlock = function() { - var current, prev; - if (this.pos < 1) { - return this; - } - prev = this.blocks[this.pos - 1].slice(0); - current = this.blocks[this.pos].slice(0); - prev[2] = current[2]; - this.blocks[this.pos - 1] = prev; - this.current = prev[0]; - this.blocks = this.blocks.slice(0, -1); - this.pos -= 1; - return this; - }; - - return Parser; - - })(); - - if (typeof module !== "undefined" && module !== null) { - module.exports = Parser; - } else if (typeof window !== "undefined" && window !== null) { - window.HyperDown = Parser; - } - -}).call(this); +(function(){var t,k,n,d,B,c,b,x,g,y=[].slice;function e(){this.commonWhiteList="kbd|b|i|strong|em|sup|sub|br|code|del|a|hr|small",this.blockHtmlTags="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|svg|script|noscript",this.specialWhiteList={table:"table|tbody|thead|tfoot|tr|td|th"},this.hooks={},this.html=!1,this.line=!1,this.blockParsers=[["code",10],["shtml",20],["pre",30],["ahtml",40],["shr",50],["list",60],["math",70],["html",80],["footnote",90],["definition",100],["quote",110],["table",120],["sh",130],["mh",140],["dhr",150],["default",9999]],this.parsers={}}g=function(t){return t.charAt(0).toUpperCase()+t.substring(1)},c=function(t){return t.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},B="A-Za-zªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԧԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠࢢ-ࢬऄ-हऽॐक़-ॡॱ-ॷॹ-ॿঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-ళవ-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤜᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚗꚠ-ꛥꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞓꞠ-Ɦꟸ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꪀ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ",b=function(t,e,r){var n,s,l,i,o,a;if(t instanceof Array)if(e instanceof Array)for(n=s=0,i=t.length;s/g,">").replace(/"/g,""")},x=function(t,e){var r,n,s,l,i;if(null==e&&(e=null),null==e)return t.replace(/^\s*/,"").replace(/\s*$/,"");for(i="",n=s=0,l=e.length-1;0<=l?s<=l:l<=s;n=0<=l?++s:--s)r=e[n],i+=r=c(r);return i="["+i+"]*",t.replace(new RegExp("^"+i),"").replace(new RegExp(i+"$"),"")},k=function(t){var e,r,n,s=[];if(t instanceof Array)for(r=e=0,n=t.length;e"+d(t[3])+"
")}))).replace(/(^|[^\\])(\$+)(.+?)\2/gm,(i=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return t[1]+i.makeHolder(t[2]+d(t[3])+t[2])}))).replace(/\\(.)/g,(o=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=d(t[1]);return e=e.replace(/\$/g,"$"),o.makeHolder(e)}))).replace(/<(https?:\/\/.+)>/gi,(a=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=a.cleanUrl(t[1]),r=a.call("parseLink",t[1]);return a.makeHolder(''+r+"")}))).replace(/<(\/?)([a-z0-9-]+)(\s+[^>]*)?>/gi,(c=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return c.html||0<=("|"+c.commonWhiteList+"|"+e+"|").indexOf("|"+t[2].toLowerCase()+"|")?c.makeHolder(t[0]):d(t[0])})),this.html&&(t=t.replace(//g,(h=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return h.makeHolder(t[0])}))),t=(t=(t=(t=(t=(t=b(["<",">"],["<",">"],t)).replace(/\[\^((?:[^\]]|\\\]|\\\[)+?)\]/g,(p=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=p.footnotes.indexOf(t[1]);return e<0&&(e=p.footnotes.length+1,p.footnotes.push(p.parseInline(t[1],"",!1))),p.makeHolder(''+e+"")}))).replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g,(u=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=d(u.escapeBracket(t[1])),r=u.escapeBracket(t[2]);return r=u.cleanUrl(r),u.makeHolder('')}))).replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g,(f=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=d(f.escapeBracket(t[1])),r=null!=f.definitions[t[2]]?'':e;return f.makeHolder(r)}))).replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g,(k=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=k.parseInline(k.escapeBracket(t[1]),"",!1,!1),r=k.escapeBracket(t[2]);return r=k.cleanUrl(r),k.makeHolder(''+e+"")}))).replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g,(m=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=m.parseInline(m.escapeBracket(t[1]),"",!1,!1),r=null!=m.definitions[t[2]]?''+e+"":e;return m.makeHolder(r)})),t=(t=this.parseInlineCallback(t)).replace(/<([_a-z0-9-\.\+]+@[^@]+\.[a-z]{2,})>/gi,'$1'),n&&(s=new RegExp('(^|[^"])((https?):['+B+'_0-9-\\./%#!@\\?\\+=~\\|\\,&\\(\\)]+)($|[^"])',"ig"),t=t.replace(s,(g=this,function(){var t=1<=arguments.length?y.call(arguments,0):[],e=g.call("parseLink",t[2]);return t[1]+''+e+""+t[4]}))),t=this.call("afterParseInlineBeforeRelease",t),t=this.releaseHolder(t,r),t=this.call("afterParseInline",t)},e.prototype.parseInlineCallback=function(t){var e,r,n,s,l,i,o;return t=(t=(t=(t=(t=(t=(t=t.replace(/(\*{3})((?:.|\r)+?)\1/gm,(e=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return""+e.parseInlineCallback(t[2])+""}))).replace(/(\*{2})((?:.|\r)+?)\1/gm,(r=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return""+r.parseInlineCallback(t[2])+""}))).replace(/(\*)((?:.|\r)+?)\1/gm,(n=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return""+n.parseInlineCallback(t[2])+""}))).replace(/(\s+|^)(_{3})((?:.|\r)+?)\2(\s+|$)/gm,(s=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return t[1]+""+s.parseInlineCallback(t[3])+""+t[4]}))).replace(/(\s+|^)(_{2})((?:.|\r)+?)\2(\s+|$)/gm,(l=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return t[1]+""+l.parseInlineCallback(t[3])+""+t[4]}))).replace(/(\s+|^)(_)((?:.|\r)+?)\2(\s+|$)/gm,(i=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return t[1]+""+i.parseInlineCallback(t[3])+""+t[4]}))).replace(/(~{2})((?:.|\r)+?)\1/gm,(o=this,function(){var t=1<=arguments.length?y.call(arguments,0):[];return""+i+"
"},e.prototype.parsePre=function(t,e,r){var n;return t=t.map(function(t){return d(t.substring(4))}),(n=this.markLines(t,r).join("\n")).match(/^\s*$/)?"":""+n+"
"},e.prototype.parseAhtml=function(t,e,r){return x(this.markLines(t,r).join("\n"))},e.prototype.parseShtml=function(t,e,r){return x(this.markLines(t.slice(1,-1),r+1).join("\n"))},e.prototype.parseMath=function(t,e,r,n){return""+this.markLine(r,n)+d(t.join("\n"))+"
"},e.prototype.parseSh=function(t,e,r,n){var s=this.markLine(r,n)+this.parseInline(x(t[0],"# "));return s.match(/^\s*$/)?"":""+this.parse(n,!0,r)+""},e.prototype.parseList=function(t,e,r){for(var n,s,l,i,o,a,c,h,p,u,f,k,m="",g=99999,d=99999,B=!1,b=!1,y=[],v=n=0,$=t.length;n<$;v=++n)(h=(c=t[v]).match(/^(\s*)((?:[0-9]+\.?)|\-|\+|\*)(\s+)(.*)$/i))?(u=h[1].length,k=0<="+-*".indexOf(h[2])?"ul":"ol",g=Math.min(u,g),B=!0,0"+this.parse(i.join("\n"),!0,r+o)+""),l!==k&&(l&&(m+=""+l+">"),m+="<"+k+">"),o=v,i=[f],l=k)):i.push(p.replace(new RegExp("^\\s{"+d+"}"),""));return 0
")).replace(/\n/g,"
")).match(/^\s*$/)?"":e?s:"
"+s+"
"},e.prototype.parseFootnote=function(t,e){e[0];var r=e[1],n=this.footnotes.indexOf(r);return 0<=n&&((t=t.slice(0))[0]=t[0].replace(/^\[\^((?:[^\]]|\]|\[)+?)\]:/,""),this.footnotes[n]=t),""},e.prototype.parseDefinition=function(){return""},e.prototype.parseHtml=function(t,e,r){var n;return t=t.map((n=this,function(t){return n.parseInline(t,null!=n.specialWhiteList[e]?n.specialWhiteList[e]:"")})),this.markLines(t,r).join("\n")},e.prototype.cleanUrl=function(t){var e,r=new RegExp("^\\s*((http|https|ftp|mailto):["+B+"_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&\\(\\)]+)","i"),n=new RegExp("^\\s*(["+B+"_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&]+)","i");return(e=t.match(r))||(e=t.match(n))?e[1]:"#"},e.prototype.escapeBracket=function(t){return b(["\\[","\\]","\\(","\\)"],["[","]","(",")"],t)},e.prototype.startBlock=function(t,e,r){return null==r&&(r=null),this.pos+=1,this.current=t,this.blocks.push([t,e,e,r]),this},e.prototype.endBlock=function(){return this.current="normal",this},e.prototype.isBlock=function(t,e){return null==e&&(e=null),this.current===t&&(null===e||this.blocks[this.pos][3]===e)},e.prototype.getBlock=function(){return null!=this.blocks[this.pos]?this.blocks[this.pos]:null},e.prototype.setBlock=function(t,e){return null==t&&(t=null),null==e&&(e=null),null!==t&&(this.blocks[this.pos][2]=t),null!==e&&(this.blocks[this.pos][3]=e),this},e.prototype.backBlock=function(t,e,r){var n,s;return null==r&&(r=null),this.pos<0?this.startBlock(e,0,r):(s=this.blocks[this.pos][2],this.blocks[this.pos][2]=s-t,n=[e,s-t+1,s,r],this.blocks[this.pos][1]<=this.blocks[this.pos][2]?(this.pos+=1,this.blocks.push(n)):this.blocks[this.pos]=n,this.current=e,this)},e.prototype.combineBlock=function(){var t,e;return this.pos<1||(e=this.blocks[this.pos-1].slice(0),t=this.blocks[this.pos].slice(0),e[2]=t[2],this.blocks[this.pos-1]=e,this.current=e[0],this.blocks=this.blocks.slice(0,-1),--this.pos),this},t=e,"undefined"!=typeof module&&null!==module?module.exports=t:"undefined"!=typeof window&&null!==window&&(window.HyperDown=t)}).call(this); \ No newline at end of file diff --git a/admin/js/jquery-ui.js b/admin/js/jquery-ui.js index 5e24f394..79d41e4e 100644 --- a/admin/js/jquery-ui.js +++ b/admin/js/jquery-ui.js @@ -1,4980 +1 @@ -/*! jQuery UI - v1.10.3 - 2013-10-16 -* http://jqueryui.com -* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.datepicker.js, jquery.ui.slider.js, jquery.ui.effect.js, jquery.ui.effect-highlight.js -* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ - -(function( $, undefined ) { - -var uuid = 0, - runiqueId = /^ui-id-\d+$/; - -// $.ui might exist from components with no dependencies, e.g., $.ui.position -$.ui = $.ui || {}; - -$.extend( $.ui, { - version: "1.10.3", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - scrollParent: function() { - var scrollParent; - if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { - scrollParent = this.parents().filter(function() { - return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } else { - scrollParent = this.parents().filter(function() { - return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } - - return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - //" + this._get(inst, "weekHeader") + " | " : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "" + dayNamesMin[day] + " | "; - } - calender += thead + "
---|---|
" + - this._get(inst, "calculateWeek")(printDate) + " | "); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += "" + // actions - (otherMonth && !showOtherMonths ? " " : // display for other months - (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + " | "; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + "
" )[ 0 ], - - // colors = jQuery.Color.names - colors, - - // local aliases of functions called often - each = jQuery.each; - -// determine rgba support immediately -supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; -support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; - -// define cache name and alpha properties -// for rgba and hsla spaces -each( spaces, function( spaceName, space ) { - space.cache = "_" + spaceName; - space.props.alpha = { - idx: 3, - type: "percent", - def: 1 - }; -}); - -function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; - - if ( value == null ) { - return (allowEmpty || !prop.def) ? null : prop.def; - } - - // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); - - // IE will pass in empty strings as value for alpha, - // which will hit this case - if ( isNaN( value ) ) { - return prop.def; - } - - if ( type.mod ) { - // we add mod before modding to make sure that negatives values - // get converted properly: -10 -> 350 - return (value + type.mod) % type.mod; - } - - // for now all property types without mod have min and max - return 0 > value ? 0 : type.max < value ? type.max : value; -} - -function stringParse( string ) { - var inst = color(), - rgba = inst._rgba = []; - - string = string.toLowerCase(); - - each( stringParsers, function( i, parser ) { - var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), - spaceName = parser.space || "rgba"; - - if ( values ) { - parsed = inst[ spaceName ]( values ); - - // if this was an rgba parse the assignment might happen twice - // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; - rgba = inst._rgba = parsed._rgba; - - // exit each( stringParsers ) here because we matched - return false; - } - }); - - // Found a stringParser that handled it - if ( rgba.length ) { - - // if this came from a parsed string, force "transparent" when alpha is 0 - // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( rgba.join() === "0,0,0,0" ) { - jQuery.extend( rgba, colors.transparent ); - } - return inst; - } - - // named colors - return colors[ string ]; -} - -color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; - return this; - } - if ( red.jquery || red.nodeType ) { - red = jQuery( red ).css( green ); - green = undefined; - } - - var inst = this, - type = jQuery.type( red ), - rgba = this._rgba = []; - - // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; - type = "array"; - } - - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); - } - - if ( type === "array" ) { - each( spaces.rgba.props, function( key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); - }); - return this; - } - - if ( type === "object" ) { - if ( red instanceof color ) { - each( spaces, function( spaceName, space ) { - if ( red[ space.cache ] ) { - inst[ space.cache ] = red[ space.cache ].slice(); - } - }); - } else { - each( spaces, function( spaceName, space ) { - var cache = space.cache; - each( space.props, function( key, prop ) { - - // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { - - // if the value was null, we don't need to copy it - // if the key was alpha, we don't need to copy it either - if ( key === "alpha" || red[ key ] == null ) { - return; - } - inst[ cache ] = space.to( inst._rgba ); - } - - // this is the only case where we allow nulls for ALL properties. - // call clamp with alwaysAllowEmpty - inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); - }); - - // everything defined but alpha? - if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { - // use the default of 1 - inst[ cache ][ 3 ] = 1; - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); - } - } - }); - } - return this; - } - }, - is: function( compare ) { - var is = color( compare ), - same = true, - inst = this; - - each( spaces, function( _, space ) { - var localCache, - isCache = is[ space.cache ]; - if (isCache) { - localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; - each( space.props, function( _, prop ) { - if ( isCache[ prop.idx ] != null ) { - same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); - return same; - } - }); - } - return same; - }); - return same; - }, - _space: function() { - var used = [], - inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); - } - }); - return used.pop(); - }, - transition: function( other, distance ) { - var end = color( other ), - spaceName = end._space(), - space = spaces[ spaceName ], - startColor = this.alpha() === 0 ? color( "transparent" ) : this, - start = startColor[ space.cache ] || space.to( startColor._rgba ), - result = start.slice(); - - end = end[ space.cache ]; - each( space.props, function( key, prop ) { - var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; - - // if null, don't override start value - if ( endValue === null ) { - return; - } - // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; - } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { - startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { - startValue -= type.mod; - } - } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); - } - }); - return this[ spaceName ]( result ); - }, - blend: function( opaque ) { - // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { - return this; - } - - var rgb = this._rgba.slice(), - a = rgb.pop(), - blend = color( opaque )._rgba; - - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; - })); - }, - toRgbaString: function() { - var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - return v == null ? ( i > 2 ? 1 : 0 ) : v; - }); - - if ( rgba[ 3 ] === 1 ) { - rgba.pop(); - prefix = "rgb("; - } - - return prefix + rgba.join() + ")"; - }, - toHslaString: function() { - var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { - v = i > 2 ? 1 : 0; - } - - // catch 1 and 2 - if ( i && i < 3 ) { - v = Math.round( v * 100 ) + "%"; - } - return v; - }); - - if ( hsla[ 3 ] === 1 ) { - hsla.pop(); - prefix = "hsl("; - } - return prefix + hsla.join() + ")"; - }, - toHexString: function( includeAlpha ) { - var rgba = this._rgba.slice(), - alpha = rgba.pop(); - - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); - } - - return "#" + jQuery.map( rgba, function( v ) { - - // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); - return v.length === 1 ? "0" + v : v; - }).join(""); - }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); - } -}); -color.fn.parse.prototype = color.fn; - -// hsla conversions adapted from: -// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - -function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { - return p + (q - p) * h * 6; - } - if ( h * 2 < 1) { - return q; - } - if ( h * 3 < 2 ) { - return p + (q - p) * ((2/3) - h) * 6; - } - return p; -} - -spaces.hsla.to = function ( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; - } - var r = rgba[ 0 ] / 255, - g = rgba[ 1 ] / 255, - b = rgba[ 2 ] / 255, - a = rgba[ 3 ], - max = Math.max( r, g, b ), - min = Math.min( r, g, b ), - diff = max - min, - add = max + min, - l = add * 0.5, - h, s; - - if ( min === max ) { - h = 0; - } else if ( r === max ) { - h = ( 60 * ( g - b ) / diff ) + 360; - } else if ( g === max ) { - h = ( 60 * ( b - r ) / diff ) + 120; - } else { - h = ( 60 * ( r - g ) / diff ) + 240; - } - - // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% - // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) - if ( diff === 0 ) { - s = 0; - } else if ( l <= 0.5 ) { - s = diff / add; - } else { - s = diff / ( 2 - add ); - } - return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; -}; - -spaces.hsla.from = function ( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; - } - var h = hsla[ 0 ] / 360, - s = hsla[ 1 ], - l = hsla[ 2 ], - a = hsla[ 3 ], - q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, - p = 2 * l - q; - - return [ - Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), - Math.round( hue2rgb( p, q, h ) * 255 ), - Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), - a - ]; -}; - - -each( spaces, function( spaceName, space ) { - var props = space.props, - cache = space.cache, - to = space.to, - from = space.from; - - // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { - - // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); - } - if ( value === undefined ) { - return this[ cache ].slice(); - } - - var ret, - type = jQuery.type( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); - - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; - } - local[ prop.idx ] = clamp( val, prop ); - }); - - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; - return ret; - } else { - return color( local ); - } - }; - - // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { - // alpha is included in more than one space - if ( color.fn[ key ] ) { - return; - } - color.fn[ key ] = function( value ) { - var vtype = jQuery.type( value ), - fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), - local = this[ fn ](), - cur = local[ prop.idx ], - match; - - if ( vtype === "undefined" ) { - return cur; - } - - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = jQuery.type( value ); - } - if ( value == null && prop.empty ) { - return this; - } - if ( vtype === "string" ) { - match = rplusequals.exec( value ); - if ( match ) { - value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); - } - } - local[ prop.idx ] = value; - return this[ fn ]( local ); - }; - }); -}); - -// add cssHook and .fx.step function for each named hook. -// accept a space separated string of properties -color.hook = function( hook ) { - var hooks = hook.split( " " ); - each( hooks, function( i, hook ) { - jQuery.cssHooks[ hook ] = { - set: function( elem, value ) { - var parsed, curElem, - backgroundColor = ""; - - if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { - curElem = hook === "backgroundColor" ? elem.parentNode : elem; - while ( - (backgroundColor === "" || backgroundColor === "transparent") && - curElem && curElem.style - ) { - try { - backgroundColor = jQuery.css( curElem, "backgroundColor" ); - curElem = curElem.parentNode; - } catch ( e ) { - } - } - - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? - backgroundColor : - "_default" ); - } - - value = value.toRgbaString(); - } - try { - elem.style[ hook ] = value; - } catch( e ) { - // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' - } - } - }; - jQuery.fx.step[ hook ] = function( fx ) { - if ( !fx.colorInit ) { - fx.start = color( fx.elem, hook ); - fx.end = color( fx.end ); - fx.colorInit = true; - } - jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); - }; - }); - -}; - -color.hook( stepHooks ); - -jQuery.cssHooks.borderColor = { - expand: function( value ) { - var expanded = {}; - - each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { - expanded[ "border" + part + "Color" ] = value; - }); - return expanded; - } -}; - -// Basic color names only. -// Usage of any of the other color names requires adding yourself or including -// jquery.color.svg-names.js. -colors = jQuery.Color.names = { - // 4.1. Basic color keywords - aqua: "#00ffff", - black: "#000000", - blue: "#0000ff", - fuchsia: "#ff00ff", - gray: "#808080", - green: "#008000", - lime: "#00ff00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - purple: "#800080", - red: "#ff0000", - silver: "#c0c0c0", - teal: "#008080", - white: "#ffffff", - yellow: "#ffff00", - - // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], - - _default: "#ffffff" -}; - -})( jQuery ); - - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -(function() { - -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; - } - }; -}); - -function getElementStyles( elem ) { - var key, len, - style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : - elem.currentStyle, - styles = {}; - - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - styles[ $.camelCase( key ) ] = style[ key ]; - } - } - // support: Opera, IE <9 - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - styles[ key ] = style[ key ]; - } - } - } - - return styles; -} - - -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; - - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } - } - } - } - - return diff; -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); - - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; - - // map the animated objects to store the original styles. - allAnimations = allAnimations.map(function() { - var el = $( this ); - return { - el: el, - start: getElementStyles( this ) - }; - }); - - // apply class change - applyClassChange = function() { - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - }); - }; - applyClassChange(); - - // map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map(function() { - this.end = getElementStyles( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - }); - - // apply original class - animated.attr( "class", baseClass ); - - // map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map(function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = $.extend({}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - }); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - }); - - // once all animations have completed: - $.when.apply( $, allAnimations.get() ).done(function() { - - // set the final class - applyClassChange(); - - // for each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function(key) { - el.css( key, "" ); - }); - }); - - // this is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - }); - }); -}; - -$.fn.extend({ - addClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.addClass ), - - removeClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return arguments.length > 1 ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.removeClass ), - - toggleClass: (function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { - // without speed parameter - return orig.apply( this, arguments ); - } else { - return $.effects.animateClass.call( this, - (force ? { add: classNames } : { remove: classNames }), - speed, easing, callback ); - } - } else { - // without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }; - })( $.fn.toggleClass ), - - switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -(function() { - -$.extend( $.effects, { - version: "1.10.3", - - // Saves a set of properties in a data storage - save: function( element, set ) { - for( var i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i; - for( i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - // support: jQuery 1.6.2 - // http://bugs.jquery.com/ticket/9917 - // jQuery 1.6.2 incorrectly returns undefined for any falsy value. - // We can't differentiate between "" and 0 here, so we just assume - // empty string since it's likely to be a more common value... - if ( val === undefined ) { - val = ""; - } - element.css( set[ i ], val ); - } - } - }, - - setMode: function( el, mode ) { - if (mode === "toggle") { - mode = el.is( ":hidden" ) ? "show" : "hide"; - } - return mode; - }, - - // Translates a [top,left] array into a baseline value - // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { - var y, x; - switch ( origin[ 0 ] ) { - case "top": y = 0; break; - case "middle": y = 0.5; break; - case "bottom": y = 1; break; - default: y = origin[ 0 ] / original.height; - } - switch ( origin[ 1 ] ) { - case "left": x = 0; break; - case "center": x = 0.5; break; - case "right": x = 1; break; - default: x = origin[ 1 ] / original.width; - } - return { - x: x, - y: y - }; - }, - - // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { - - // if the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" )) { - return element.parent(); - } - - // wrap the element - var props = { - width: element.outerWidth(true), - height: element.outerHeight(true), - "float": element.css( "float" ) - }, - wrapper = $( "
" ) - .addClass( "ui-effects-wrapper" ) - .css({ - fontSize: "100%", - background: "transparent", - border: "none", - margin: 0, - padding: 0 - }), - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; - - // support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - active.id; - } catch( e ) { - active = document.body; - } - - element.wrap( wrapper ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element - - // transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css({ position: "relative" }); - element.css({ position: "relative" }); - } else { - $.extend( props, { - position: element.css( "position" ), - zIndex: element.css( "z-index" ) - }); - $.each([ "top", "left", "bottom", "right" ], function(i, pos) { - props[ pos ] = element.css( pos ); - if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = "auto"; - } - }); - element.css({ - position: "relative", - top: 0, - left: 0, - right: "auto", - bottom: "auto" - }); - } - element.css(size); - - return wrapper.css( props ).show(); - }, - - removeWrapper: function( element ) { - var active = document.activeElement; - - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - } - - - return element; - }, - - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - }); - return value; - } -}); - -// return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { - - // allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } - - // convert to an object - effect = { effect: effect }; - - // catch (effect, null, ...) - if ( options == null ) { - options = {}; - } - - // catch (effect, callback) - if ( $.isFunction( options ) ) { - callback = options; - speed = null; - options = {}; - } - - // catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } - - // catch (effect, options, callback) - if ( $.isFunction( speed ) ) { - callback = speed; - speed = null; - } - - // add options to effect - if ( options ) { - $.extend( effect, options ); - } - - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; - - effect.complete = callback || options.complete; - - return effect; -} - -function standardAnimationOption( option ) { - // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { - return true; - } - - // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { - return true; - } - - // Complete callback - if ( $.isFunction( option ) ) { - return true; - } - - // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { - return true; - } - - // Didn't match any standard API - return false; -} - -$.fn.extend({ - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - mode = args.mode, - queue = args.queue, - effectMethod = $.effects.effect[ args.effect ]; - - if ( $.fx.off || !effectMethod ) { - // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, args.complete ); - } else { - return this.each( function() { - if ( args.complete ) { - args.complete.call( this ); - } - }); - } - } - - function run( next ) { - var elem = $( this ), - complete = args.complete, - mode = args.mode; - - function done() { - if ( $.isFunction( complete ) ) { - complete.call( elem[0] ); - } - if ( $.isFunction( next ) ) { - next(); - } - } - - // If the element already has the correct final state, delegate to - // the core methods so the internal tracking of "olddisplay" works. - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[0], args, done ); - } - } - - return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); - }, - - show: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }; - })( $.fn.show ), - - hide: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }; - })( $.fn.hide ), - - toggle: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }; - })( $.fn.toggle ), - - // helper functions - cssUnit: function(key) { - var style = this.css( key ), - val = []; - - $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { - if ( style.indexOf( unit ) > 0 ) { - val = [ parseFloat( style ), unit ]; - } - }); - return val; - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ - -(function() { - -// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) - -var baseEasings = {}; - -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -}); - -$.extend( baseEasings, { - Sine: function ( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); - }, - Circ: function ( p ) { - return 1 - Math.sqrt( 1 - p * p ); - }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); - }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); - }, - Bounce: function ( p ) { - var pow2, - bounce = 4; - - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -}); - -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -}); - -})(); - -})(jQuery); -(function( $, undefined ) { - -$.effects.effect.highlight = function( o, done ) { - var elem = $( this ), - props = [ "backgroundImage", "backgroundColor", "opacity" ], - mode = $.effects.setMode( elem, o.mode || "show" ), - animation = { - backgroundColor: elem.css( "backgroundColor" ) - }; - - if (mode === "hide") { - animation.opacity = 0; - } - - $.effects.save( elem, props ); - - elem - .show() - .css({ - backgroundImage: "none", - backgroundColor: o.color || "#ffff99" - }) - .animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - elem.hide(); - } - $.effects.restore( elem, props ); - done(); - } - }); -}; - -})(jQuery); +!function(o,u){var e,t,i=0,a=/^ui-id-\d+$/;function s(e,t){var i,a,s,n=e.nodeName.toLowerCase();return"area"===n?(a=(i=e.parentNode).name,!(!e.href||!a||"map"!==i.nodeName.toLowerCase())&&(!!(s=o("img[usemap=#"+a+"]")[0])&&r(s))):(/input|select|textarea|button|object/.test(n)?!e.disabled:"a"===n&&e.href||t)&&r(e)}function r(e){return o.expr.filters.visible(e)&&!o(e).parents().addBack().filter(function(){return"hidden"===o.css(this,"visibility")}).length}o.ui=o.ui||{},o.extend(o.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),o.fn.extend({focus:(e=o.fn.focus,function(t,i){return"number"==typeof t?this.each(function(){var e=this;setTimeout(function(){o(e).focus(),i&&i.call(e)},t)}):e.apply(this,arguments)}),scrollParent:function(){var e=o.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(o.css(this,"position"))&&/(auto|scroll)/.test(o.css(this,"overflow")+o.css(this,"overflow-y")+o.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(o.css(this,"overflow")+o.css(this,"overflow-y")+o.css(this,"overflow-x"))}).eq(0);return/fixed/.test(this.css("position"))||!e.length?o(document):e},zIndex:function(e){if(e!==u)return this.css("zIndex",e);if(this.length)for(var t,i,a=o(this[0]);a.length&&a[0]!==document;){if(("absolute"===(t=a.css("position"))||"relative"===t||"fixed"===t)&&(i=parseInt(a.css("zIndex"),10),!isNaN(i)&&0!==i))return i;a=a.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++i)})},removeUniqueId:function(){return this.each(function(){a.test(this.id)&&o(this).removeAttr("id")})}}),o.extend(o.expr[":"],{data:o.expr.createPseudo?o.expr.createPseudo(function(t){return function(e){return!!o.data(e,t)}}):function(e,t,i){return!!o.data(e,i[3])},focusable:function(e){return s(e,!isNaN(o.attr(e,"tabindex")))},tabbable:function(e){var t=o.attr(e,"tabindex"),i=isNaN(t);return(i||0<=t)&&s(e,!i)}}),o("").outerWidth(1).jquery||o.each(["Width","Height"],function(e,i){var s="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),n={innerWidth:o.fn.innerWidth,innerHeight:o.fn.innerHeight,outerWidth:o.fn.outerWidth,outerHeight:o.fn.outerHeight};function r(e,t,i,a){return o.each(s,function(){t-=parseFloat(o.css(e,"padding"+this))||0,i&&(t-=parseFloat(o.css(e,"border"+this+"Width"))||0),a&&(t-=parseFloat(o.css(e,"margin"+this))||0)}),t}o.fn["inner"+i]=function(e){return e===u?n["inner"+i].call(this):this.each(function(){o(this).css(a,r(this,e)+"px")})},o.fn["outer"+i]=function(e,t){return"number"!=typeof e?n["outer"+i].call(this,e):this.each(function(){o(this).css(a,r(this,e,!0,t)+"px")})}}),o.fn.addBack||(o.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),o("").data("a-b","a").removeData("a-b").data("a-b")&&(o.fn.removeData=(t=o.fn.removeData,function(e){return arguments.length?t.call(this,o.camelCase(e)):t.call(this)})),o.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),o.support.selectstart="onselectstart"in document.createElement("div"),o.fn.extend({disableSelection:function(){return this.bind((o.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),o.extend(o.ui,{plugin:{add:function(e,t,i){var a,s=o.ui[e].prototype;for(a in i)s.plugins[a]=s.plugins[a]||[],s.plugins[a].push([t,i[a]])},call:function(e,t,i){var a,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(a=0;aInsert Hyperlink
http://example.com/ "optional title"
',linkname:null,quote:"BlockquoteCtrl+Q",quoteexample:"Blockquote",code:"Code SampleCtrl+K",codeexample:"enter code here",image:"Image Ctrl+G",imagedescription:"enter image description here",imagedialog:"
Insert Image
http://example.com/images/diagram.jpg \"optional title\"
",imagename:null,olist:"Numbered List
Need free image hosting?Ctrl+O",ulist:"Bulleted List
Ctrl+U",litem:"List item",heading:"Heading
/
Ctrl+H",headingexample:"Heading",more:"More contents \x3c!--more--\x3e Ctrl+M",fullscreen:"FullScreen Ctrl+J",exitFullscreen:"Exit FullScreen Ctrl+E",fullscreenUnsupport:"Sorry, the browser dont support fullscreen api",hr:"Horizontal Rule
Ctrl+R",undo:"Undo - Ctrl+Z",redo:"Redo - Ctrl+Y",redomac:"Redo - Ctrl+Shift+Z",ok:"OK",cancel:"Cancel",help:"Markdown Editing Help"};function t(){}function d(e){this.buttonBar=k.getElementById("wmd-button-bar"+e),this.preview=k.getElementById("wmd-preview"+e),this.input=k.getElementById("text")}function f(t,n){function r(e,t){s!=e&&(s=e,t||g()),T.isIE&&"moving"==s?o=null:a=setTimeout(d,1)}var u,a,o,i=this,c=[],l=0,s="none",d=function(e){o=new S(n,e),a=void 0};this.setCommandMode=function(){s="command",g(),a=setTimeout(d,0)},this.canUndo=function(){return 1k.body.offsetHeight?(e=k.body.scrollWidth,k.body.scrollHeight):(e=k.body.offsetWidth,k.body.offsetHeight);return self.innerHeight?(t=self.innerWidth,n=self.innerHeight):k.documentElement&&k.documentElement.clientHeight?(t=k.documentElement.clientWidth,n=k.documentElement.clientHeight):k.body&&(t=k.body.clientWidth,n=k.body.clientHeight),[Math.max(e,t),Math.max(r,n),t,n]},w.createBackground=function(){var e=k.createElement("div"),t=e.style;e.className="wmd-prompt-background",t.position="absolute",t.top="0",t.zIndex="1000",T.isIE?t.filter="alpha(opacity=50)":t.opacity="0.5";var n=m.getPageSize();return t.height=n[1]+"px",T.isIE?(t.left=k.documentElement.scrollLeft,t.width=k.documentElement.clientWidth):(t.left="0",t.width="100%"),k.body.appendChild(e),e},w.dialog=function(u,t,a,o){function i(e){27===(e.charCode||e.keyCode)&&l(!0)}var c,l=function(e){return v.removeEvent(k.body,"keydown",i),c.parentNode.removeChild(c),t(e),!1};setTimeout(function(){!function(){(c=k.createElement("div")).className="wmd-prompt-dialog",c.setAttribute("role","dialog");var e=k.createElement("div"),t=k.createElement("form");t.style;t.onsubmit=function(){return l(!1)},c.appendChild(t),t.appendChild(e),"function"==typeof u?u.call(this,e):e.innerHTML=u;var n=k.createElement("button");n.type="button",n.className="btn btn-s primary",n.onclick=function(){return l(!1)},n.innerHTML=a;var r=k.createElement("button");r.type="button",r.className="btn btn-s",r.onclick=function(){return l(!0)},r.innerHTML=o,t.appendChild(n),t.appendChild(r),v.addEvent(k.body,"keydown",i),k.body.appendChild(c)}()},0)},w.prompt=function(u,a,n,o,i){var c,l;void 0===a&&(a="");function s(e){27===(e.charCode||e.keyCode)&&d(!0)}var d=function(e){v.removeEvent(k.body,"keydown",s);var t=l.value;return e?t=null:(t=t.replace(/^http:\/\/(https?|ftp):\/\//,"$1://"),/^(?:https?|ftp):\/\//.test(t)||/^[_a-z0-9-]+:/i.test(t)||(t="http://"+t)),c.parentNode.removeChild(c),n(t),!1};setTimeout(function(){!function(){(c=k.createElement("div")).className="wmd-prompt-dialog",c.setAttribute("role","dialog");var e=k.createElement("div");e.innerHTML=u,c.appendChild(e);var t=k.createElement("form");t.style;t.onsubmit=function(){return d(!1)},c.appendChild(t),(l=k.createElement("input")).type="text",l.value=a,t.appendChild(l);var n=k.createElement("button");n.type="button",n.className="btn btn-s primary",n.onclick=function(){return d(!1)},n.innerHTML=o;var r=k.createElement("button");r.type="button",r.className="btn btn-s",r.onclick=function(){return d(!0)},r.innerHTML=i,t.appendChild(n),t.appendChild(r),v.addEvent(k.body,"keydown",s),k.body.appendChild(c)}();var e,t=a.length;void 0!==l.selectionStart?(l.selectionStart=0,l.selectionEnd=t):l.createTextRange&&((e=l.createTextRange()).collapse(!1),e.moveStart("character",-t),e.moveEnd("character",t),e.select()),l.focus()},0)};var e=y.prototype;function C(e,t){this.fullScreenBind=!1,this.hooks=e,this.getString=t,this.isFakeFullScreen=!1}function u(){return document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen||document.msIsFullScreen}e.prefixes="(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)",e.unwrap=function(e){var t=new p("([^\\n])\\n(?!(\\n|"+this.prefixes+"))","g");e.selection=e.selection.replace(t,"$1 $2")},e.wrap=function(e,t){this.unwrap(e);var n=new p("(.{1,"+t+"})( +|$\\n?)","gm"),r=this;e.selection=e.selection.replace(n,function(e,t){return new p("^"+r.prefixes,"").test(e)?e:t+"\n"}),e.selection=e.selection.replace(/\s+$/,"")},e.doBold=function(e,t){return this.doBorI(e,t,2,this.getString("boldexample"))},e.doItalic=function(e,t){return this.doBorI(e,t,1,this.getString("italicexample"))},e.doBorI=function(e,t,n,r){e.trimWhitespace(),e.selection=e.selection.replace(/\n{2,}/g,"\n");var u,a,o=/(\**$)/.exec(e.before)[0],i=/(^\**)/.exec(e.after)[0],c=Math.min(o.length,i.length);n<=c&&(2!=c||1!=n)?(e.before=e.before.replace(p("[*]{"+n+"}$",""),""),e.after=e.after.replace(p("^[*]{"+n+"}",""),"")):!e.selection&&i?(e.after=e.after.replace(/^([*_]*)/,""),e.before=e.before.replace(/(\s?)$/,""),u=p.$1,e.before=e.before+i+u):(e.selection||i||(e.selection=r),a=n<=1?"*":"**",e.before=e.before+a,e.after=a+e.after)},e.stripLinkDefs=function(e,a){return e=e.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm,function(e,t,n,r,u){return a[t]=e.replace(/\s*$/,""),r?(a[t]=e.replace(/["(](.+?)[")]$/,""),r+u):""})},e.addLinkDef=function(e,t){var o=0,i={};e.before=this.stripLinkDefs(e.before,i),e.selection=this.stripLinkDefs(e.selection,i),e.after=this.stripLinkDefs(e.after,i);function c(e){o++,e=e.replace(/^[ ]{0,3}\[(\d+)\]:/," ["+o+"]:"),n+="\n"+e}var n="",l=/(\[)((?:\[[^\]]*\]|[^\[\]])*)(\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g,s=function(e,t,n,r,u,a){return n=n.replace(l,s),i[u]?(c(i[u]),t+n+r+o+a):e};e.before=e.before.replace(l,s),t?c(t):e.selection=e.selection.replace(l,s);var r=o;return e.after=e.after.replace(l,s),e.after&&(e.after=e.after.replace(/\n*$/,"")),e.after||(e.selection=e.selection.replace(/\n*$/,"")),e.after+="\n\n"+n,r},e.doLinkOrImage=function(a,o,i){if(a.trimWhitespace(),a.findTags(/\s*!?\[/,/\][ ]?(?:\n[ ]*)?(\[.*?\])?/),!(1 /g,">"))?t+' "'+n+'"':t}),n=c.addLinkDef(a,t),a.startTag=i?"![":"[",a.endTag="]["+n+"]",a.selection||(i?(r=c.getString("imagename"),a.selection=r||c.getString("imagedescription")):(u=c.getString("linkname"),a.selection=u||c.getString("linkdescription")))),o(),c.hooks.commandExecuted(i?"doImage":"doLink")}var c=this,l=w.createBackground();return i?this.hooks.insertImageDialog(e)||w.prompt(this.getString("imagedialog"),"http://",e,this.getString("ok"),this.getString("cancel")):this.hooks.insertLinkDialog(e)||w.prompt(this.getString("linkdialog"),"http://",e,this.getString("ok"),this.getString("cancel")),!0}a.startTag=a.startTag.replace(/!?\[/,""),a.endTag="",this.addLinkDef(a,null)},e.doAutoindent=function(t,e){var n=this,r=!1;t.before=t.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/,"\n\n"),t.before=t.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/,"\n\n"),t.before=t.before.replace(/(\n|^)[ \t]+\n$/,"\n\n"),t.selection||/^[ \t]*(?:\n|$)/.test(t.after)||(t.after=t.after.replace(/^[^\n]*/,function(e){return t.selection=e,""}),r=!0),/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(t.before)&&n.doList&&n.doList(t),/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(t.before)&&n.doBlockquote&&n.doBlockquote(t),/(\n|^)(\t|[ ]{4,}).*\n$/.test(t.before)&&n.doCode&&n.doCode(t),r&&(t.after=t.selection+t.after,t.selection="")},e.doBlockquote=function(u,e){u.selection=u.selection.replace(/^(\n*)([^\r]+?)(\n*)$/,function(e,t,n,r){return u.before+=t,u.after=r+u.after,n}),u.before=u.before.replace(/(>[ \t]*)$/,function(e,t){return u.selection=t+u.selection,""}),u.selection=u.selection.replace(/^(\s|>)+$/,""),u.selection=u.selection||this.getString("quoteexample");var t="",n="";if(u.before){for(var r=u.before.replace(/\n$/,"").split("\n"),a=!1,o=0;o /.test(c)?(i=!0,!a&&1 /.test(t)||(n+=t,t="")}u.startTag=t,u.before=n,u.after&&(u.after=u.after.replace(/^\n?/,"\n")),u.after=u.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/,function(e){return u.endTag=e,""});function l(e){var n=e?"> ":"";u.startTag&&(u.startTag=u.startTag.replace(/\n((>|\s)*)\n$/,function(e,t){return"\n"+t.replace(/^[ ]{0,3}>?[ \t]*$/gm,n)+"\n"})),u.endTag&&(u.endTag=u.endTag.replace(/^\n((>|\s)*)\n/,function(e,t){return"\n"+t.replace(/^[ ]{0,3}>?[ \t]*$/gm,n)+"\n"}))}/^(?![ ]{0,3}>)/m.test(u.selection)?(this.wrap(u,g-2),u.selection=u.selection.replace(/^/gm,"> "),l(!0),u.skipLines()):(u.selection=u.selection.replace(/^[ ]{0,3}> ?/gm,""),this.unwrap(u),l(!1),!/^(\n|^)[ ]{0,3}>/.test(u.selection)&&u.startTag&&(u.startTag=u.startTag.replace(/\n{0,2}$/,"\n\n")),!/(\n|^)[ ]{0,3}>.*$/.test(u.selection)&&u.endTag&&(u.endTag=u.endTag.replace(/^\n{0,2}/,"\n\n"))),u.selection=this.hooks.postBlockquoteCreation(u.selection),/\n/.test(u.selection)||(u.selection=u.selection.replace(/^(> *)/,function(e,t){return u.startTag+=t,""}))},e.doCode=function(t,e){var n,r,u=/\S[ ]*$/.test(t.before);!/^[ ]*\S/.test(t.after)&&!u||/\n/.test(t.selection)?(t.before=t.before.replace(/[ ]{4}$/,function(e){return t.selection=e+t.selection,""}),r=n=1,/(\n|^)(\t|[ ]{4,}).*\n$/.test(t.before)&&(n=0),/^\n(\t|[ ]{4,})/.test(t.after)&&(r=0),t.skipLines(n,r),t.selection?/^[ ]{0,3}\S/m.test(t.selection)?/\n/.test(t.selection)?t.selection=t.selection.replace(/^/gm," "):t.before+=" ":t.selection=t.selection.replace(/^(?:[ ]{4}|[ ]{0,3}\t)/gm,""):(t.startTag=" ",t.selection=this.getString("codeexample"))):(t.trimWhitespace(),t.findTags(/`/,/`/),t.startTag||t.endTag?t.endTag&&!t.startTag?(t.before+=t.endTag,t.endTag=""):t.startTag=t.endTag="":(t.startTag=t.endTag="`",t.selection||(t.selection=this.getString("codeexample"))))},e.doList=function(e,t,n){function r(){var e;return n?(e=" "+i+". ",i++):e=" "+o+" ",e}function u(e){return void 0===n&&(n=/^\s*\d/.test(e)),e=e.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm,function(e){return r()})}var a=/^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/,o="-",i=1;if(e.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/,null),!e.before||/\n$/.test(e.before)||/^\n/.test(e.startTag)||(e.before+=e.startTag,e.startTag=""),e.startTag){var c=/\d+[.]/.test(e.startTag);if(e.startTag="",e.selection=e.selection.replace(/\n[ ]{4}/g,"\n"),this.unwrap(e),e.skipLines(),c&&(e.after=e.after.replace(a,u)),n==c)return}var l=1;e.before=e.before.replace(/(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/,function(e){return/^\s*([*+-])/.test(e)&&(o=p.$1),l=/[^\n]\n\n[^\n]/.test(e)?1:0,u(e)}),e.selection||(e.selection=this.getString("litem"));var s=r(),d=1;e.after=e.after.replace(a,function(e){return d=/[^\n]\n\n[^\n]/.test(e)?1:0,u(e)}),e.trimWhitespace(!0),e.skipLines(l,d,!0);var f=(e.startTag=s).replace(/./g," ");this.wrap(e,g-f.length),e.selection=e.selection.replace(/\n/g,"\n"+f),this.hooks.commandExecuted("doList")},e.doHeading=function(e,t){if(e.selection=e.selection.replace(/\s+/g," "),e.selection=e.selection.replace(/(^\s+|\s+$)/g,""),!e.selection)return e.startTag="## ",e.selection=this.getString("headingexample"),void(e.endTag=" ##");var n=0;e.findTags(/#+[ ]*/,/[ ]*#+/),/#+/.test(e.startTag)&&(n=p.lastMatch.length),e.startTag=e.endTag="",e.findTags(null,/\s?(-+|=+)/),/=+/.test(e.endTag)&&(n=1),/-+/.test(e.endTag)&&(n=2),e.startTag=e.endTag="",e.skipLines(1,1);var r=0==n?2:n-1;if(0 0 && img.is(':visible'); - } - if (/^(input|select|textarea|button|object)$/.test(nodeName)) { - focusableIfVisible = !element.disabled; - if (focusableIfVisible) { - fieldset = $(element).closest('fieldset')[0]; - if (fieldset) { - focusableIfVisible = !fieldset.disabled; - } - } - } else if ('a' === nodeName) { - focusableIfVisible = element.href || hasTabindex; - } else { - focusableIfVisible = hasTabindex; - } - focusableIfVisible = focusableIfVisible || $(element).is('[contenteditable]'); - return focusableIfVisible && $(element).is(':visible'); - }; - - Paste = (function() { - Paste.prototype._target = null; - - Paste.prototype._container = null; - - Paste.mountNonInputable = function(nonInputable) { - var paste; - paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable); - $(nonInputable).on('click', (function(_this) { - return function(ev) { - if (!(isFocusable(ev.target, false) || window.getSelection().toString())) { - return paste._container.focus(); - } - }; - })(this)); - paste._container.on('focus', (function(_this) { - return function() { - return $(nonInputable).addClass('pastable-focus'); - }; - })(this)); - return paste._container.on('blur', (function(_this) { - return function() { - return $(nonInputable).removeClass('pastable-focus'); - }; - })(this)); - }; - - Paste.mountTextarea = function(textarea) { - var ctlDown, paste, ref, ref1; - if ((typeof DataTransfer !== "undefined" && DataTransfer !== null ? DataTransfer.prototype : void 0) && ((ref = Object.getOwnPropertyDescriptor) != null ? (ref1 = ref.call(Object, DataTransfer.prototype, 'items')) != null ? ref1.get : void 0 : void 0)) { - return this.mountContenteditable(textarea); - } - paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea); - ctlDown = false; - $(textarea).on('keyup', function(ev) { - var ref2; - if ((ref2 = ev.keyCode) === 17 || ref2 === 224) { - ctlDown = false; - } - return null; - }); - $(textarea).on('keydown', function(ev) { - var ref2; - if ((ref2 = ev.keyCode) === 17 || ref2 === 224) { - ctlDown = true; - } - if ((ev.ctrlKey != null) && (ev.metaKey != null)) { - ctlDown = ev.ctrlKey || ev.metaKey; - } - if (ctlDown && ev.keyCode === 86) { - paste._textarea_focus_stolen = true; - paste._container.focus(); - paste._paste_event_fired = false; - setTimeout((function(_this) { - return function() { - if (!paste._paste_event_fired) { - $(textarea).focus(); - return paste._textarea_focus_stolen = false; - } - }; - })(this), 1); - } - return null; - }); - $(textarea).on('paste', (function(_this) { - return function() {}; - })(this)); - $(textarea).on('focus', (function(_this) { - return function() { - if (!paste._textarea_focus_stolen) { - return $(textarea).addClass('pastable-focus'); - } - }; - })(this)); - $(textarea).on('blur', (function(_this) { - return function() { - if (!paste._textarea_focus_stolen) { - return $(textarea).removeClass('pastable-focus'); - } - }; - })(this)); - $(paste._target).on('_pasteCheckContainerDone', (function(_this) { - return function() { - $(textarea).focus(); - return paste._textarea_focus_stolen = false; - }; - })(this)); - return $(paste._target).on('pasteText', (function(_this) { - return function(ev, data) { - var content, curEnd, curStart; - curStart = $(textarea).prop('selectionStart'); - curEnd = $(textarea).prop('selectionEnd'); - content = $(textarea).val(); - $(textarea).val("" + content.slice(0, curStart) + data.text + content.slice(curEnd)); - $(textarea)[0].setSelectionRange(curStart + data.text.length, curStart + data.text.length); - return $(textarea).trigger('change'); - }; - })(this)); - }; - - Paste.mountContenteditable = function(contenteditable) { - var paste; - paste = new Paste(contenteditable, contenteditable); - $(contenteditable).on('focus', (function(_this) { - return function() { - return $(contenteditable).addClass('pastable-focus'); - }; - })(this)); - return $(contenteditable).on('blur', (function(_this) { - return function() { - return $(contenteditable).removeClass('pastable-focus'); - }; - })(this)); - }; - - function Paste(_container, _target) { - this._container = _container; - this._target = _target; - this._container = $(this._container); - this._target = $(this._target).addClass('pastable'); - this._container.on('paste', (function(_this) { - return function(ev) { - var _i, clipboardData, file, fileType, item, j, k, l, len, len1, len2, pastedFilename, reader, ref, ref1, ref2, ref3, ref4, stringIsFilename, text; - _this.originalEvent = (ev.originalEvent !== null ? ev.originalEvent : null); - _this._paste_event_fired = true; - if (((ref = ev.originalEvent) != null ? ref.clipboardData : void 0) != null) { - clipboardData = ev.originalEvent.clipboardData; - if (clipboardData.items) { - pastedFilename = null; - _this.originalEvent.pastedTypes = []; - ref1 = clipboardData.items; - for (j = 0, len = ref1.length; j < len; j++) { - item = ref1[j]; - if (item.type.match(/^text\/(plain|rtf|html)/)) { - _this.originalEvent.pastedTypes.push(item.type); - } - } - ref2 = clipboardData.items; - for (_i = k = 0, len1 = ref2.length; k < len1; _i = ++k) { - item = ref2[_i]; - if (item.type.match(/^image\//)) { - reader = new FileReader(); - reader.onload = function(event) { - return _this._handleImage(event.target.result, _this.originalEvent, pastedFilename); - }; - try { - reader.readAsDataURL(item.getAsFile()); - } catch (error) {} - ev.preventDefault(); - break; - } - if (item.type === 'text/plain') { - if (_i === 0 && clipboardData.items.length > 1 && clipboardData.items[1].type.match(/^image\//)) { - stringIsFilename = true; - fileType = clipboardData.items[1].type; - } - item.getAsString(function(string) { - if (stringIsFilename) { - pastedFilename = string; - return _this._target.trigger('pasteText', { - text: string, - isFilename: true, - fileType: fileType, - originalEvent: _this.originalEvent - }); - } else { - return _this._target.trigger('pasteText', { - text: string, - originalEvent: _this.originalEvent - }); - } - }); - } - if (item.type === 'text/rtf') { - item.getAsString(function(string) { - return _this._target.trigger('pasteTextRich', { - text: string, - originalEvent: _this.originalEvent - }); - }); - } - if (item.type === 'text/html') { - item.getAsString(function(string) { - return _this._target.trigger('pasteTextHtml', { - text: string, - originalEvent: _this.originalEvent - }); - }); - } - } - } else { - if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) { - text = clipboardData.getData('Text'); - setTimeout(function() { - return _this._target.trigger('pasteText', { - text: text, - originalEvent: _this.originalEvent - }); - }, 1); - } - _this._checkImagesInContainer(function(src) { - return _this._handleImage(src, _this.originalEvent); - }); - } - } - if (clipboardData = window.clipboardData) { - if ((ref3 = (text = clipboardData.getData('Text'))) != null ? ref3.length : void 0) { - setTimeout(function() { - _this._target.trigger('pasteText', { - text: text, - originalEvent: _this.originalEvent - }); - return _this._target.trigger('_pasteCheckContainerDone'); - }, 1); - } else { - ref4 = clipboardData.files; - for (l = 0, len2 = ref4.length; l < len2; l++) { - file = ref4[l]; - _this._handleImage(URL.createObjectURL(file), _this.originalEvent); - } - _this._checkImagesInContainer(function(src) {}); - } - } - return null; - }; - })(this)); - } - - Paste.prototype._handleImage = function(src, e, name) { - var loader; - if (src.match(/^webkit\-fake\-url\:\/\//)) { - return this._target.trigger('pasteImageError', { - message: "You are trying to paste an image in Safari, however we are unable to retieve its data." - }); - } - this._target.trigger('pasteImageStart'); - loader = new Image(); - loader.crossOrigin = "anonymous"; - loader.onload = (function(_this) { - return function() { - var blob, canvas, ctx, dataURL; - canvas = document.createElement('canvas'); - canvas.width = loader.width; - canvas.height = loader.height; - ctx = canvas.getContext('2d'); - ctx.drawImage(loader, 0, 0, canvas.width, canvas.height); - dataURL = null; - try { - dataURL = canvas.toDataURL('image/png'); - blob = dataURLtoBlob(dataURL); - } catch (error) {} - if (dataURL) { - _this._target.trigger('pasteImage', { - blob: blob, - dataURL: dataURL, - width: loader.width, - height: loader.height, - originalEvent: e, - name: name - }); - } - return _this._target.trigger('pasteImageEnd'); - }; - })(this); - loader.onerror = (function(_this) { - return function() { - _this._target.trigger('pasteImageError', { - message: "Failed to get image from: " + src, - url: src - }); - return _this._target.trigger('pasteImageEnd'); - }; - })(this); - return loader.src = src; - }; - - Paste.prototype._checkImagesInContainer = function(cb) { - var img, j, len, ref, timespan; - timespan = Math.floor(1000 * Math.random()); - ref = this._container.find('img'); - for (j = 0, len = ref.length; j < len; j++) { - img = ref[j]; - img["_paste_marked_" + timespan] = true; - } - return setTimeout((function(_this) { - return function() { - var k, len1, ref1; - ref1 = _this._container.find('img'); - for (k = 0, len1 = ref1.length; k < len1; k++) { - img = ref1[k]; - if (!img["_paste_marked_" + timespan]) { - cb(img.src); - $(img).remove(); - } - } - return _this._target.trigger('_pasteCheckContainerDone'); - }; - })(this), 1); - }; - - return Paste; - - })(); - -}).call(this); +(function(){var s,a,r,l,n;function o(t,e){var x;this._container=t,this._target=e,this._container=s(this._container),this._target=s(this._target).addClass("pastable"),this._container.on("paste",(x=this,function(t){var e,n,a,r,i,o,l,s,u,g,c,f,p,d,h,_,m,v,b,y;if(x.originalEvent=null!==t.originalEvent?t.originalEvent:null,x._paste_event_fired=!0,null!=(null!=(d=t.originalEvent)?d.clipboardData:void 0))if((n=t.originalEvent.clipboardData).items){for(f=null,x.originalEvent.pastedTypes=[],o=0,u=(h=n.items).length;o 0) { - caps.slice_blob = true; - } - - if (!plupload.isEmptyObj(settings.resize) || settings.multipart === false) { - caps.send_binary_string = true; - } - - if (settings.http_method) { - caps.use_http_method = settings.http_method; - } - - plupload.each(settings, function(value, feature) { - resolve(feature, !!value, true); // strict check - }); - } - - return caps; -} - -/** - * @module plupload - * @static - */ -var plupload = { - /** - * Plupload version will be replaced on build. - * - * @property VERSION - * @for Plupload - * @static - * @final - */ - VERSION : '2.3.6', - - /** - * The state of the queue before it has started and after it has finished - * - * @property STOPPED - * @static - * @final - */ - STOPPED : 1, - - /** - * Upload process is running - * - * @property STARTED - * @static - * @final - */ - STARTED : 2, - - /** - * File is queued for upload - * - * @property QUEUED - * @static - * @final - */ - QUEUED : 1, - - /** - * File is being uploaded - * - * @property UPLOADING - * @static - * @final - */ - UPLOADING : 2, - - /** - * File has failed to be uploaded - * - * @property FAILED - * @static - * @final - */ - FAILED : 4, - - /** - * File has been uploaded successfully - * - * @property DONE - * @static - * @final - */ - DONE : 5, - - // Error constants used by the Error event - - /** - * Generic error for example if an exception is thrown inside Silverlight. - * - * @property GENERIC_ERROR - * @static - * @final - */ - GENERIC_ERROR : -100, - - /** - * HTTP transport error. For example if the server produces a HTTP status other than 200. - * - * @property HTTP_ERROR - * @static - * @final - */ - HTTP_ERROR : -200, - - /** - * Generic I/O error. For example if it wasn't possible to open the file stream on local machine. - * - * @property IO_ERROR - * @static - * @final - */ - IO_ERROR : -300, - - /** - * @property SECURITY_ERROR - * @static - * @final - */ - SECURITY_ERROR : -400, - - /** - * Initialization error. Will be triggered if no runtime was initialized. - * - * @property INIT_ERROR - * @static - * @final - */ - INIT_ERROR : -500, - - /** - * File size error. If the user selects a file that is too large or is empty it will be blocked and - * an error of this type will be triggered. - * - * @property FILE_SIZE_ERROR - * @static - * @final - */ - FILE_SIZE_ERROR : -600, - - /** - * File extension error. If the user selects a file that isn't valid according to the filters setting. - * - * @property FILE_EXTENSION_ERROR - * @static - * @final - */ - FILE_EXTENSION_ERROR : -601, - - /** - * Duplicate file error. If prevent_duplicates is set to true and user selects the same file again. - * - * @property FILE_DUPLICATE_ERROR - * @static - * @final - */ - FILE_DUPLICATE_ERROR : -602, - - /** - * Runtime will try to detect if image is proper one. Otherwise will throw this error. - * - * @property IMAGE_FORMAT_ERROR - * @static - * @final - */ - IMAGE_FORMAT_ERROR : -700, - - /** - * While working on files runtime may run out of memory and will throw this error. - * - * @since 2.1.2 - * @property MEMORY_ERROR - * @static - * @final - */ - MEMORY_ERROR : -701, - - /** - * Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error. - * - * @property IMAGE_DIMENSIONS_ERROR - * @static - * @final - */ - IMAGE_DIMENSIONS_ERROR : -702, - - /** - * Expose whole moxie (#1469). - * - * @property moxie - * @type Object - * @final - */ - moxie: o, - - /** - * Mime type lookup table. - * - * @property mimeTypes - * @type Object - * @final - */ - mimeTypes : u.Mime.mimes, - - /** - * In some cases sniffing is the only way around :( - */ - ua: u.Env, - - /** - * Gets the true type of the built-in object (better version of typeof). - * @credits Angus Croll (http://javascriptweblog.wordpress.com/) - * - * @method typeOf - * @static - * @param {Object} o Object to check. - * @return {String} Object [[Class]] - */ - typeOf: u.Basic.typeOf, - - /** - * Extends the specified object with another object. - * - * @method extend - * @static - * @param {Object} target Object to extend. - * @param {Object..} obj Multiple objects to extend with. - * @return {Object} Same as target, the extended object. - */ - extend : u.Basic.extend, - - /** - * Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers. - * The only way a user would be able to get the same ID is if the two persons at the same exact millisecond manages - * to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique. - * It's more probable for the earth to be hit with an asteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property - * to an user unique key. - * - * @method guid - * @static - * @return {String} Virtually unique id. - */ - guid : u.Basic.guid, - - /** - * Get array of DOM Elements by their ids. - * - * @method get - * @param {String} id Identifier of the DOM Element - * @return {Array} - */ - getAll : function get(ids) { - var els = [], el; - - if (plupload.typeOf(ids) !== 'array') { - ids = [ids]; - } - - var i = ids.length; - while (i--) { - el = plupload.get(ids[i]); - if (el) { - els.push(el); - } - } - - return els.length ? els : null; - }, - - /** - Get DOM element by id - - @method get - @param {String} id Identifier of the DOM Element - @return {Node} - */ - get: u.Dom.get, - - /** - * Executes the callback function for each item in array/object. If you return false in the - * callback it will break the loop. - * - * @method each - * @static - * @param {Object} obj Object to iterate. - * @param {function} callback Callback function to execute for each item. - */ - each : u.Basic.each, - - /** - * Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields. - * - * @method getPos - * @static - * @param {Element} node HTML element or element id to get x, y position from. - * @param {Element} root Optional root element to stop calculations at. - * @return {object} Absolute position of the specified element object with x, y fields. - */ - getPos : u.Dom.getPos, - - /** - * Returns the size of the specified node in pixels. - * - * @method getSize - * @static - * @param {Node} node Node to get the size of. - * @return {Object} Object with a w and h property. - */ - getSize : u.Dom.getSize, - - /** - * Encodes the specified string. - * - * @method xmlEncode - * @static - * @param {String} s String to encode. - * @return {String} Encoded string. - */ - xmlEncode : function(str) { - var xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'}, xmlEncodeRegExp = /[<>&\"\']/g; - - return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) { - return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr; - }) : str; - }, - - /** - * Forces anything into an array. - * - * @method toArray - * @static - * @param {Object} obj Object with length field. - * @return {Array} Array object containing all items. - */ - toArray : u.Basic.toArray, - - /** - * Find an element in array and return its index if present, otherwise return -1. - * - * @method inArray - * @static - * @param {mixed} needle Element to find - * @param {Array} array - * @return {Int} Index of the element, or -1 if not found - */ - inArray : u.Basic.inArray, - - /** - Recieve an array of functions (usually async) to call in sequence, each function - receives a callback as first argument that it should call, when it completes. Finally, - after everything is complete, main callback is called. Passing truthy value to the - callback as a first argument will interrupt the sequence and invoke main callback - immediately. - - @method inSeries - @static - @param {Array} queue Array of functions to call in sequence - @param {Function} cb Main callback that is called in the end, or in case of error - */ - inSeries: u.Basic.inSeries, - - /** - * Extends the language pack object with new items. - * - * @method addI18n - * @static - * @param {Object} pack Language pack items to add. - * @return {Object} Extended language pack object. - */ - addI18n : o.core.I18n.addI18n, - - /** - * Translates the specified string by checking for the english string in the language pack lookup. - * - * @method translate - * @static - * @param {String} str String to look for. - * @return {String} Translated string or the input string if it wasn't found. - */ - translate : o.core.I18n.translate, - - /** - * Pseudo sprintf implementation - simple way to replace tokens with specified values. - * - * @param {String} str String with tokens - * @return {String} String with replaced tokens - */ - sprintf : u.Basic.sprintf, - - /** - * Checks if object is empty. - * - * @method isEmptyObj - * @static - * @param {Object} obj Object to check. - * @return {Boolean} - */ - isEmptyObj : u.Basic.isEmptyObj, - - /** - * Checks if specified DOM element has specified class. - * - * @method hasClass - * @static - * @param {Object} obj DOM element like object to add handler to. - * @param {String} name Class name - */ - hasClass : u.Dom.hasClass, - - /** - * Adds specified className to specified DOM element. - * - * @method addClass - * @static - * @param {Object} obj DOM element like object to add handler to. - * @param {String} name Class name - */ - addClass : u.Dom.addClass, - - /** - * Removes specified className from specified DOM element. - * - * @method removeClass - * @static - * @param {Object} obj DOM element like object to add handler to. - * @param {String} name Class name - */ - removeClass : u.Dom.removeClass, - - /** - * Returns a given computed style of a DOM element. - * - * @method getStyle - * @static - * @param {Object} obj DOM element like object. - * @param {String} name Style you want to get from the DOM element - */ - getStyle : u.Dom.getStyle, - - /** - * Adds an event handler to the specified object and store reference to the handler - * in objects internal Plupload registry (@see removeEvent). - * - * @method addEvent - * @static - * @param {Object} obj DOM element like object to add handler to. - * @param {String} name Name to add event listener to. - * @param {Function} callback Function to call when event occurs. - * @param {String} (optional) key that might be used to add specifity to the event record. - */ - addEvent : u.Events.addEvent, - - /** - * Remove event handler from the specified object. If third argument (callback) - * is not specified remove all events with the specified name. - * - * @method removeEvent - * @static - * @param {Object} obj DOM element to remove event listener(s) from. - * @param {String} name Name of event listener to remove. - * @param {Function|String} (optional) might be a callback or unique key to match. - */ - removeEvent: u.Events.removeEvent, - - /** - * Remove all kind of events from the specified object - * - * @method removeAllEvents - * @static - * @param {Object} obj DOM element to remove event listeners from. - * @param {String} (optional) unique key to match, when removing events. - */ - removeAllEvents: u.Events.removeAllEvents, - - /** - * Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _. - * - * @method cleanName - * @static - * @param {String} s String to clean up. - * @return {String} Cleaned string. - */ - cleanName : function(name) { - var i, lookup; - - // Replace diacritics - lookup = [ - /[\300-\306]/g, 'A', /[\340-\346]/g, 'a', - /\307/g, 'C', /\347/g, 'c', - /[\310-\313]/g, 'E', /[\350-\353]/g, 'e', - /[\314-\317]/g, 'I', /[\354-\357]/g, 'i', - /\321/g, 'N', /\361/g, 'n', - /[\322-\330]/g, 'O', /[\362-\370]/g, 'o', - /[\331-\334]/g, 'U', /[\371-\374]/g, 'u' - ]; - - for (i = 0; i < lookup.length; i += 2) { - name = name.replace(lookup[i], lookup[i + 1]); - } - - // Replace whitespace - name = name.replace(/\s+/g, '_'); - - // Remove anything else - name = name.replace(/[^a-z0-9_\-\.]+/gi, ''); - - return name; - }, - - /** - * Builds a full url out of a base URL and an object with items to append as query string items. - * - * @method buildUrl - * @static - * @param {String} url Base URL to append query string items to. - * @param {Object} items Name/value object to serialize as a querystring. - * @return {String} String with url + serialized query string items. - */ - buildUrl: function(url, items) { - var query = ''; - - plupload.each(items, function(value, name) { - query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value); - }); - - if (query) { - url += (url.indexOf('?') > 0 ? '&' : '?') + query; - } - - return url; - }, - - /** - * Formats the specified number as a size string for example 1024 becomes 1 KB. - * - * @method formatSize - * @static - * @param {Number} size Size to format as string. - * @return {String} Formatted size string. - */ - formatSize : function(size) { - - if (size === undef || /\D/.test(size)) { - return plupload.translate('N/A'); - } - - function round(num, precision) { - return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision); - } - - var boundary = Math.pow(1024, 4); - - // TB - if (size > boundary) { - return round(size / boundary, 1) + " " + plupload.translate('tb'); - } - - // GB - if (size > (boundary/=1024)) { - return round(size / boundary, 1) + " " + plupload.translate('gb'); - } - - // MB - if (size > (boundary/=1024)) { - return round(size / boundary, 1) + " " + plupload.translate('mb'); - } - - // KB - if (size > 1024) { - return Math.round(size / 1024) + " " + plupload.translate('kb'); - } - - return size + " " + plupload.translate('b'); - }, - - - /** - * Parses the specified size string into a byte value. For example 10kb becomes 10240. - * - * @method parseSize - * @static - * @param {String|Number} size String to parse or number to just pass through. - * @return {Number} Size in bytes. - */ - parseSize : u.Basic.parseSizeStr, - - - /** - * A way to predict what runtime will be choosen in the current environment with the - * specified settings. - * - * @method predictRuntime - * @static - * @param {Object|String} config Plupload settings to check - * @param {String} [runtimes] Comma-separated list of runtimes to check against - * @return {String} Type of compatible runtime - */ - predictRuntime : function(config, runtimes) { - var up, runtime; - - up = new plupload.Uploader(config); - runtime = Runtime.thatCan(up.getOption().required_features, runtimes || config.runtimes); - up.destroy(); - return runtime; - }, - - /** - * Registers a filter that will be executed for each file added to the queue. - * If callback returns false, file will not be added. - * - * Callback receives two arguments: a value for the filter as it was specified in settings.filters - * and a file to be filtered. Callback is executed in the context of uploader instance. - * - * @method addFileFilter - * @static - * @param {String} name Name of the filter by which it can be referenced in settings.filters - * @param {String} cb Callback - the actual routine that every added file must pass - */ - addFileFilter: function(name, cb) { - fileFilters[name] = cb; - } -}; - - -plupload.addFileFilter('mime_types', function(filters, file, cb) { - if (filters.length && !filters.regexp.test(file.name)) { - this.trigger('Error', { - code : plupload.FILE_EXTENSION_ERROR, - message : plupload.translate('File extension error.'), - file : file - }); - cb(false); - } else { - cb(true); - } -}); - - -plupload.addFileFilter('max_file_size', function(maxSize, file, cb) { - var undef; - - maxSize = plupload.parseSize(maxSize); - - // Invalid file size - if (file.size !== undef && maxSize && file.size > maxSize) { - this.trigger('Error', { - code : plupload.FILE_SIZE_ERROR, - message : plupload.translate('File size error.'), - file : file - }); - cb(false); - } else { - cb(true); - } -}); - - -plupload.addFileFilter('prevent_duplicates', function(value, file, cb) { - if (value) { - var ii = this.files.length; - while (ii--) { - // Compare by name and size (size might be 0 or undefined, but still equivalent for both) - if (file.name === this.files[ii].name && file.size === this.files[ii].size) { - this.trigger('Error', { - code : plupload.FILE_DUPLICATE_ERROR, - message : plupload.translate('Duplicate file error.'), - file : file - }); - cb(false); - return; - } - } - } - cb(true); -}); - -plupload.addFileFilter('prevent_empty', function(value, file, cb) { - if (value && !file.size && file.size !== undef) { - this.trigger('Error', { - code : plupload.FILE_SIZE_ERROR, - message : plupload.translate('File size error.'), - file : file - }); - cb(false); - } else { - cb(true); - } -}); - - -/** -@class Uploader -@constructor - -@param {Object} settings For detailed information about each option check documentation. - @param {String|DOMElement} settings.browse_button id of the DOM element or DOM element itself to use as file dialog trigger. - @param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled. - @param {String|DOMElement} [settings.container] id of the DOM element or DOM element itself that will be used to wrap uploader structures. Defaults to immediate parent of the `browse_button` element. - @param {String|DOMElement} [settings.drop_element] id of the DOM element or DOM element itself to use as a drop zone for Drag-n-Drop. - @param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message. - @param {Object} [settings.filters={}] Set of file type filters. - @param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`. - @param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR` - @param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`. - @param {Boolean} [settings.filters.prevent_empty=true] Do not let empty files into the queue (IE10 is known to hang for example when trying to upload such). Dispatches `plupload.FILE_SIZE_ERROR`. - @param {String} [settings.flash_swf_url] URL of the Flash swf. - @param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs. - @param {String} [settings.http_method="POST"] HTTP method to use during upload (only PUT or POST allowed). - @param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event. - @param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message. - @param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload. - @param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog. - @param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess. - @param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}` - @param {Number} [settings.resize.width] If image is bigger, it will be resized. - @param {Number} [settings.resize.height] If image is bigger, it will be resized. - @param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100). - @param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally. - @param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails. - @param {String} [settings.silverlight_xap_url] URL of the Silverlight xap. - @param {Boolean} [settings.send_chunk_number=true] Whether to send chunks and chunk numbers, or total and offset bytes. - @param {Boolean} [settings.send_file_name=true] Whether to send file name as additional argument - 'name' (required for chunked uploads and some other cases where file name cannot be sent via normal ways). - @param {String} settings.url URL of the server-side upload handler. - @param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files. - -*/ -plupload.Uploader = function(options) { - /** - Fires when the current RunTime has been initialized. - - @event Init - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires after the init event incase you need to perform actions there. - - @event PostInit - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires when the option is changed in via uploader.setOption(). - - @event OptionChanged - @since 2.1 - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {String} name Name of the option that was changed - @param {Mixed} value New value for the specified option - @param {Mixed} oldValue Previous value of the option - */ - - /** - Fires when the silverlight/flash or other shim needs to move. - - @event Refresh - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires when the overall state is being changed for the upload queue. - - @event StateChanged - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires when browse_button is clicked and browse dialog shows. - - @event Browse - @since 2.1.2 - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires for every filtered file before it is added to the queue. - - @event FileFiltered - @since 2.1 - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file Another file that has to be added to the queue. - */ - - /** - Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance. - - @event QueueChanged - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - - /** - Fires after files were filtered and added to the queue. - - @event FilesAdded - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {Array} files Array of file objects that were added to queue by the user. - */ - - /** - Fires when file is removed from the queue. - - @event FilesRemoved - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {Array} files Array of files that got removed. - */ - - /** - Fires just before a file is uploaded. Can be used to cancel the upload for the specified file - by returning false from the handler. - - @event BeforeUpload - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file File to be uploaded. - */ - - /** - Fires when a file is to be uploaded by the runtime. - - @event UploadFile - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file File to be uploaded. - */ - - /** - Fires while a file is being uploaded. Use this event to update the current file upload progress. - - @event UploadProgress - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file File that is currently being uploaded. - */ - - /** - * Fires just before a chunk is uploaded. This event enables you to override settings - * on the uploader instance before the chunk is uploaded. - * - * @event BeforeChunkUpload - * @param {plupload.Uploader} uploader Uploader instance sending the event. - * @param {plupload.File} file File to be uploaded. - * @param {Object} args POST params to be sent. - * @param {Blob} chunkBlob Current blob. - * @param {offset} offset Current offset. - */ - - /** - Fires when file chunk is uploaded. - - @event ChunkUploaded - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file File that the chunk was uploaded for. - @param {Object} result Object with response properties. - @param {Number} result.offset The amount of bytes the server has received so far, including this chunk. - @param {Number} result.total The size of the file. - @param {String} result.response The response body sent by the server. - @param {Number} result.status The HTTP status code sent by the server. - @param {String} result.responseHeaders All the response headers as a single string. - */ - - /** - Fires when a file is successfully uploaded. - - @event FileUploaded - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {plupload.File} file File that was uploaded. - @param {Object} result Object with response properties. - @param {String} result.response The response body sent by the server. - @param {Number} result.status The HTTP status code sent by the server. - @param {String} result.responseHeaders All the response headers as a single string. - */ - - /** - Fires when all files in a queue are uploaded. - - @event UploadComplete - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {Array} files Array of file objects that was added to queue/selected by the user. - */ - - /** - Fires when a error occurs. - - @event Error - @param {plupload.Uploader} uploader Uploader instance sending the event. - @param {Object} error Contains code, message and sometimes file and other details. - @param {Number} error.code The plupload error code. - @param {String} error.message Description of the error (uses i18n). - */ - - /** - Fires when destroy method is called. - - @event Destroy - @param {plupload.Uploader} uploader Uploader instance sending the event. - */ - var uid = plupload.guid() - , settings - , files = [] - , preferred_caps = {} - , fileInputs = [] - , fileDrops = [] - , startTime - , total - , disabled = false - , xhr - ; - - - // Private methods - function uploadNext() { - var file, count = 0, i; - - if (this.state == plupload.STARTED) { - // Find first QUEUED file - for (i = 0; i < files.length; i++) { - if (!file && files[i].status == plupload.QUEUED) { - file = files[i]; - if (this.trigger("BeforeUpload", file)) { - file.status = plupload.UPLOADING; - this.trigger("UploadFile", file); - } - } else { - count++; - } - } - - // All files are DONE or FAILED - if (count == files.length) { - if (this.state !== plupload.STOPPED) { - this.state = plupload.STOPPED; - this.trigger("StateChanged"); - } - this.trigger("UploadComplete", files); - } - } - } - - - function calcFile(file) { - file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100; - calc(); - } - - - function calc() { - var i, file; - var loaded; - var loadedDuringCurrentSession = 0; - - // Reset stats - total.reset(); - - // Check status, size, loaded etc on all files - for (i = 0; i < files.length; i++) { - file = files[i]; - - if (file.size !== undef) { - // We calculate totals based on original file size - total.size += file.origSize; - - // Since we cannot predict file size after resize, we do opposite and - // interpolate loaded amount to match magnitude of total - loaded = file.loaded * file.origSize / file.size; - - if (!file.completeTimestamp || file.completeTimestamp > startTime) { - loadedDuringCurrentSession += loaded; - } - - total.loaded += loaded; - } else { - total.size = undef; - } - - if (file.status == plupload.DONE) { - total.uploaded++; - } else if (file.status == plupload.FAILED) { - total.failed++; - } else { - total.queued++; - } - } - - // If we couldn't calculate a total file size then use the number of files to calc percent - if (total.size === undef) { - total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0; - } else { - total.bytesPerSec = Math.ceil(loadedDuringCurrentSession / ((+new Date() - startTime || 1) / 1000.0)); - total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0; - } - } - - - function getRUID() { - var ctrl = fileInputs[0] || fileDrops[0]; - if (ctrl) { - return ctrl.getRuntime().uid; - } - return false; - } - - - function bindEventListeners() { - this.bind('FilesAdded FilesRemoved', function(up) { - up.trigger('QueueChanged'); - up.refresh(); - }); - - this.bind('CancelUpload', onCancelUpload); - - this.bind('BeforeUpload', onBeforeUpload); - - this.bind('UploadFile', onUploadFile); - - this.bind('UploadProgress', onUploadProgress); - - this.bind('StateChanged', onStateChanged); - - this.bind('QueueChanged', calc); - - this.bind('Error', onError); - - this.bind('FileUploaded', onFileUploaded); - - this.bind('Destroy', onDestroy); - } - - - function initControls(settings, cb) { - var self = this, inited = 0, queue = []; - - // common settings - var options = { - runtime_order: settings.runtimes, - required_caps: settings.required_features, - preferred_caps: preferred_caps, - swf_url: settings.flash_swf_url, - xap_url: settings.silverlight_xap_url - }; - - // add runtime specific options if any - plupload.each(settings.runtimes.split(/\s*,\s*/), function(runtime) { - if (settings[runtime]) { - options[runtime] = settings[runtime]; - } - }); - - // initialize file pickers - there can be many - if (settings.browse_button) { - plupload.each(settings.browse_button, function(el) { - queue.push(function(cb) { - var fileInput = new o.file.FileInput(plupload.extend({}, options, { - accept: settings.filters.mime_types, - name: settings.file_data_name, - multiple: settings.multi_selection, - container: settings.container, - browse_button: el - })); - - fileInput.onready = function() { - var info = Runtime.getInfo(this.ruid); - - // for backward compatibility - plupload.extend(self.features, { - chunks: info.can('slice_blob'), - multipart: info.can('send_multipart'), - multi_selection: info.can('select_multiple') - }); - - inited++; - fileInputs.push(this); - cb(); - }; - - fileInput.onchange = function() { - self.addFile(this.files); - }; - - fileInput.bind('mouseenter mouseleave mousedown mouseup', function(e) { - if (!disabled) { - if (settings.browse_button_hover) { - if ('mouseenter' === e.type) { - plupload.addClass(el, settings.browse_button_hover); - } else if ('mouseleave' === e.type) { - plupload.removeClass(el, settings.browse_button_hover); - } - } - - if (settings.browse_button_active) { - if ('mousedown' === e.type) { - plupload.addClass(el, settings.browse_button_active); - } else if ('mouseup' === e.type) { - plupload.removeClass(el, settings.browse_button_active); - } - } - } - }); - - fileInput.bind('mousedown', function() { - self.trigger('Browse'); - }); - - fileInput.bind('error runtimeerror', function() { - fileInput = null; - cb(); - }); - - fileInput.init(); - }); - }); - } - - // initialize drop zones - if (settings.drop_element) { - plupload.each(settings.drop_element, function(el) { - queue.push(function(cb) { - var fileDrop = new o.file.FileDrop(plupload.extend({}, options, { - drop_zone: el - })); - - fileDrop.onready = function() { - var info = Runtime.getInfo(this.ruid); - - // for backward compatibility - plupload.extend(self.features, { - chunks: info.can('slice_blob'), - multipart: info.can('send_multipart'), - dragdrop: info.can('drag_and_drop') - }); - - inited++; - fileDrops.push(this); - cb(); - }; - - fileDrop.ondrop = function() { - self.addFile(this.files); - }; - - fileDrop.bind('error runtimeerror', function() { - fileDrop = null; - cb(); - }); - - fileDrop.init(); - }); - }); - } - - - plupload.inSeries(queue, function() { - if (typeof(cb) === 'function') { - cb(inited); - } - }); - } - - - function resizeImage(blob, params, runtimeOptions, cb) { - var img = new o.image.Image(); - - try { - img.onload = function() { - // no manipulation required if... - if (params.width > this.width && - params.height > this.height && - params.quality === undef && - params.preserve_headers && - !params.crop - ) { - this.destroy(); - cb(blob); - } else { - // otherwise downsize - img.downsize(params.width, params.height, params.crop, params.preserve_headers); - } - }; - - img.onresize = function() { - var resizedBlob = this.getAsBlob(blob.type, params.quality); - this.destroy(); - cb(resizedBlob); - }; - - img.bind('error runtimeerror', function() { - this.destroy(); - cb(blob); - }); - - img.load(blob, runtimeOptions); - } catch(ex) { - cb(blob); - } - } - - - function setOption(option, value, init) { - var self = this, reinitRequired = false; - - function _setOption(option, value, init) { - var oldValue = settings[option]; - - switch (option) { - case 'max_file_size': - if (option === 'max_file_size') { - settings.max_file_size = settings.filters.max_file_size = value; - } - break; - - case 'chunk_size': - if (value = plupload.parseSize(value)) { - settings[option] = value; - settings.send_file_name = true; - } - break; - - case 'multipart': - settings[option] = value; - if (!value) { - settings.send_file_name = true; - } - break; - - case 'http_method': - settings[option] = value.toUpperCase() === 'PUT' ? 'PUT' : 'POST'; - break; - - case 'unique_names': - settings[option] = value; - if (value) { - settings.send_file_name = true; - } - break; - - case 'filters': - // for sake of backward compatibility - if (plupload.typeOf(value) === 'array') { - value = { - mime_types: value - }; - } - - if (init) { - plupload.extend(settings.filters, value); - } else { - settings.filters = value; - } - - // if file format filters are being updated, regenerate the matching expressions - if (value.mime_types) { - if (plupload.typeOf(value.mime_types) === 'string') { - value.mime_types = o.core.utils.Mime.mimes2extList(value.mime_types); - } - - value.mime_types.regexp = (function(filters) { - var extensionsRegExp = []; - - plupload.each(filters, function(filter) { - plupload.each(filter.extensions.split(/,/), function(ext) { - if (/^\s*\*\s*$/.test(ext)) { - extensionsRegExp.push('\\.*'); - } else { - extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&')); - } - }); - }); - - return new RegExp('(' + extensionsRegExp.join('|') + ')$', 'i'); - }(value.mime_types)); - - settings.filters.mime_types = value.mime_types; - } - break; - - case 'resize': - if (value) { - settings.resize = plupload.extend({ - preserve_headers: true, - crop: false - }, value); - } else { - settings.resize = false; - } - break; - - case 'prevent_duplicates': - settings.prevent_duplicates = settings.filters.prevent_duplicates = !!value; - break; - - // options that require reinitialisation - case 'container': - case 'browse_button': - case 'drop_element': - value = 'container' === option - ? plupload.get(value) - : plupload.getAll(value) - ; - - case 'runtimes': - case 'multi_selection': - case 'flash_swf_url': - case 'silverlight_xap_url': - settings[option] = value; - if (!init) { - reinitRequired = true; - } - break; - - default: - settings[option] = value; - } - - if (!init) { - self.trigger('OptionChanged', option, value, oldValue); - } - } - - if (typeof(option) === 'object') { - plupload.each(option, function(value, option) { - _setOption(option, value, init); - }); - } else { - _setOption(option, value, init); - } - - if (init) { - // Normalize the list of required capabilities - settings.required_features = normalizeCaps(plupload.extend({}, settings)); - - // Come up with the list of capabilities that can affect default mode in a multi-mode runtimes - preferred_caps = normalizeCaps(plupload.extend({}, settings, { - required_features: true - })); - } else if (reinitRequired) { - self.trigger('Destroy'); - - initControls.call(self, settings, function(inited) { - if (inited) { - self.runtime = Runtime.getInfo(getRUID()).type; - self.trigger('Init', { runtime: self.runtime }); - self.trigger('PostInit'); - } else { - self.trigger('Error', { - code : plupload.INIT_ERROR, - message : plupload.translate('Init error.') - }); - } - }); - } - } - - - // Internal event handlers - function onBeforeUpload(up, file) { - // Generate unique target filenames - if (up.settings.unique_names) { - var matches = file.name.match(/\.([^.]+)$/), ext = "part"; - if (matches) { - ext = matches[1]; - } - file.target_name = file.id + '.' + ext; - } - } - - - function onUploadFile(up, file) { - var url = up.settings.url; - var chunkSize = up.settings.chunk_size; - var retries = up.settings.max_retries; - var features = up.features; - var offset = 0; - var blob; - - var runtimeOptions = { - runtime_order: up.settings.runtimes, - required_caps: up.settings.required_features, - preferred_caps: preferred_caps, - swf_url: up.settings.flash_swf_url, - xap_url: up.settings.silverlight_xap_url - }; - - // make sure we start at a predictable offset - if (file.loaded) { - offset = file.loaded = chunkSize ? chunkSize * Math.floor(file.loaded / chunkSize) : 0; - } - - function handleError() { - if (retries-- > 0) { - delay(uploadNextChunk, 1000); - } else { - file.loaded = offset; // reset all progress - - up.trigger('Error', { - code : plupload.HTTP_ERROR, - message : plupload.translate('HTTP Error.'), - file : file, - response : xhr.responseText, - status : xhr.status, - responseHeaders: xhr.getAllResponseHeaders() - }); - } - } - - function uploadNextChunk() { - var chunkBlob, args = {}, curChunkSize; - - // make sure that file wasn't cancelled and upload is not stopped in general - if (file.status !== plupload.UPLOADING || up.state === plupload.STOPPED) { - return; - } - - // send additional 'name' parameter only if required - if (up.settings.send_file_name) { - args.name = file.target_name || file.name; - } - - if (chunkSize && features.chunks && blob.size > chunkSize) { // blob will be of type string if it was loaded in memory - curChunkSize = Math.min(chunkSize, blob.size - offset); - chunkBlob = blob.slice(offset, offset + curChunkSize); - } else { - curChunkSize = blob.size; - chunkBlob = blob; - } - - // If chunking is enabled add corresponding args, no matter if file is bigger than chunk or smaller - if (chunkSize && features.chunks) { - // Setup query string arguments - if (up.settings.send_chunk_number) { - args.chunk = Math.ceil(offset / chunkSize); - args.chunks = Math.ceil(blob.size / chunkSize); - } else { // keep support for experimental chunk format, just in case - args.offset = offset; - args.total = blob.size; - } - } - - if (up.trigger('BeforeChunkUpload', file, args, chunkBlob, offset)) { - uploadChunk(args, chunkBlob, curChunkSize); - } - } - - function uploadChunk(args, chunkBlob, curChunkSize) { - var formData; - - xhr = new o.xhr.XMLHttpRequest(); - - // Do we have upload progress support - if (xhr.upload) { - xhr.upload.onprogress = function(e) { - file.loaded = Math.min(file.size, offset + e.loaded); - up.trigger('UploadProgress', file); - }; - } - - xhr.onload = function() { - // check if upload made itself through - if (xhr.status < 200 || xhr.status >= 400) { - handleError(); - return; - } - - retries = up.settings.max_retries; // reset the counter - - // Handle chunk response - if (curChunkSize < blob.size) { - chunkBlob.destroy(); - - offset += curChunkSize; - file.loaded = Math.min(offset, blob.size); - - up.trigger('ChunkUploaded', file, { - offset : file.loaded, - total : blob.size, - response : xhr.responseText, - status : xhr.status, - responseHeaders: xhr.getAllResponseHeaders() - }); - - // stock Android browser doesn't fire upload progress events, but in chunking mode we can fake them - if (plupload.ua.browser === 'Android Browser') { - // doesn't harm in general, but is not required anywhere else - up.trigger('UploadProgress', file); - } - } else { - file.loaded = file.size; - } - - chunkBlob = formData = null; // Free memory - - // Check if file is uploaded - if (!offset || offset >= blob.size) { - // If file was modified, destory the copy - if (file.size != file.origSize) { - blob.destroy(); - blob = null; - } - - up.trigger('UploadProgress', file); - - file.status = plupload.DONE; - file.completeTimestamp = +new Date(); - - up.trigger('FileUploaded', file, { - response : xhr.responseText, - status : xhr.status, - responseHeaders: xhr.getAllResponseHeaders() - }); - } else { - // Still chunks left - delay(uploadNextChunk, 1); // run detached, otherwise event handlers interfere - } - }; - - xhr.onerror = function() { - handleError(); - }; - - xhr.onloadend = function() { - this.destroy(); - }; - - // Build multipart request - if (up.settings.multipart && features.multipart) { - xhr.open(up.settings.http_method, url, true); - - // Set custom headers - plupload.each(up.settings.headers, function(value, name) { - xhr.setRequestHeader(name, value); - }); - - formData = new o.xhr.FormData(); - - // Add multipart params - plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) { - formData.append(name, value); - }); - - // Add file and send it - formData.append(up.settings.file_data_name, chunkBlob); - xhr.send(formData, runtimeOptions); - } else { - // if no multipart, send as binary stream - url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params)); - - xhr.open(up.settings.http_method, url, true); - - // Set custom headers - plupload.each(up.settings.headers, function(value, name) { - xhr.setRequestHeader(name, value); - }); - - // do not set Content-Type, if it was defined previously (see #1203) - if (!xhr.hasRequestHeader('Content-Type')) { - xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header - } - - xhr.send(chunkBlob, runtimeOptions); - } - } - - - blob = file.getSource(); - - // Start uploading chunks - if (!plupload.isEmptyObj(up.settings.resize) && plupload.inArray(blob.type, ['image/jpeg', 'image/png']) !== -1) { - // Resize if required - resizeImage(blob, up.settings.resize, runtimeOptions, function(resizedBlob) { - blob = resizedBlob; - file.size = resizedBlob.size; - uploadNextChunk(); - }); - } else { - uploadNextChunk(); - } - } - - - function onUploadProgress(up, file) { - calcFile(file); - } - - - function onStateChanged(up) { - if (up.state == plupload.STARTED) { - // Get start time to calculate bps - startTime = (+new Date()); - } else if (up.state == plupload.STOPPED) { - // Reset currently uploading files - for (var i = up.files.length - 1; i >= 0; i--) { - if (up.files[i].status == plupload.UPLOADING) { - up.files[i].status = plupload.QUEUED; - calc(); - } - } - } - } - - - function onCancelUpload() { - if (xhr) { - xhr.abort(); - } - } - - - function onFileUploaded(up) { - calc(); - - // Upload next file but detach it from the error event - // since other custom listeners might want to stop the queue - delay(function() { - uploadNext.call(up); - }, 1); - } - - - function onError(up, err) { - if (err.code === plupload.INIT_ERROR) { - up.destroy(); - } - // Set failed status if an error occured on a file - else if (err.code === plupload.HTTP_ERROR) { - err.file.status = plupload.FAILED; - err.file.completeTimestamp = +new Date(); - calcFile(err.file); - - // Upload next file but detach it from the error event - // since other custom listeners might want to stop the queue - if (up.state == plupload.STARTED) { // upload in progress - up.trigger('CancelUpload'); - delay(function() { - uploadNext.call(up); - }, 1); - } - } - } - - - function onDestroy(up) { - up.stop(); - - // Purge the queue - plupload.each(files, function(file) { - file.destroy(); - }); - files = []; - - if (fileInputs.length) { - plupload.each(fileInputs, function(fileInput) { - fileInput.destroy(); - }); - fileInputs = []; - } - - if (fileDrops.length) { - plupload.each(fileDrops, function(fileDrop) { - fileDrop.destroy(); - }); - fileDrops = []; - } - - preferred_caps = {}; - disabled = false; - startTime = xhr = null; - total.reset(); - } - - - // Default settings - settings = { - chunk_size: 0, - file_data_name: 'file', - filters: { - mime_types: [], - max_file_size: 0, - prevent_duplicates: false, - prevent_empty: true - }, - flash_swf_url: 'js/Moxie.swf', - http_method: 'POST', - max_retries: 0, - multipart: true, - multi_selection: true, - resize: false, - runtimes: Runtime.order, - send_file_name: true, - send_chunk_number: true, - silverlight_xap_url: 'js/Moxie.xap' - }; - - - setOption.call(this, options, null, true); - - // Inital total state - total = new plupload.QueueProgress(); - - // Add public methods - plupload.extend(this, { - - /** - * Unique id for the Uploader instance. - * - * @property id - * @type String - */ - id : uid, - uid : uid, // mOxie uses this to differentiate between event targets - - /** - * Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED. - * These states are controlled by the stop/start methods. The default value is STOPPED. - * - * @property state - * @type Number - */ - state : plupload.STOPPED, - - /** - * Map of features that are available for the uploader runtime. Features will be filled - * before the init event is called, these features can then be used to alter the UI for the end user. - * Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize. - * - * @property features - * @type Object - */ - features : {}, - - /** - * Current runtime name. - * - * @property runtime - * @type String - */ - runtime : null, - - /** - * Current upload queue, an array of File instances. - * - * @property files - * @type Array - * @see plupload.File - */ - files : files, - - /** - * Object with name/value settings. - * - * @property settings - * @type Object - */ - settings : settings, - - /** - * Total progess information. How many files has been uploaded, total percent etc. - * - * @property total - * @type plupload.QueueProgress - */ - total : total, - - - /** - * Initializes the Uploader instance and adds internal event listeners. - * - * @method init - */ - init : function() { - var self = this, opt, preinitOpt, err; - - preinitOpt = self.getOption('preinit'); - if (typeof(preinitOpt) == "function") { - preinitOpt(self); - } else { - plupload.each(preinitOpt, function(func, name) { - self.bind(name, func); - }); - } - - bindEventListeners.call(self); - - // Check for required options - plupload.each(['container', 'browse_button', 'drop_element'], function(el) { - if (self.getOption(el) === null) { - err = { - code : plupload.INIT_ERROR, - message : plupload.sprintf(plupload.translate("%s specified, but cannot be found."), el) - } - return false; - } - }); - - if (err) { - return self.trigger('Error', err); - } - - - if (!settings.browse_button && !settings.drop_element) { - return self.trigger('Error', { - code : plupload.INIT_ERROR, - message : plupload.translate("You must specify either browse_button or drop_element.") - }); - } - - - initControls.call(self, settings, function(inited) { - var initOpt = self.getOption('init'); - if (typeof(initOpt) == "function") { - initOpt(self); - } else { - plupload.each(initOpt, function(func, name) { - self.bind(name, func); - }); - } - - if (inited) { - self.runtime = Runtime.getInfo(getRUID()).type; - self.trigger('Init', { runtime: self.runtime }); - self.trigger('PostInit'); - } else { - self.trigger('Error', { - code : plupload.INIT_ERROR, - message : plupload.translate('Init error.') - }); - } - }); - }, - - /** - * Set the value for the specified option(s). - * - * @method setOption - * @since 2.1 - * @param {String|Object} option Name of the option to change or the set of key/value pairs - * @param {Mixed} [value] Value for the option (is ignored, if first argument is object) - */ - setOption: function(option, value) { - setOption.call(this, option, value, !this.runtime); // until runtime not set we do not need to reinitialize - }, - - /** - * Get the value for the specified option or the whole configuration, if not specified. - * - * @method getOption - * @since 2.1 - * @param {String} [option] Name of the option to get - * @return {Mixed} Value for the option or the whole set - */ - getOption: function(option) { - if (!option) { - return settings; - } - return settings[option]; - }, - - /** - * Refreshes the upload instance by dispatching out a refresh event to all runtimes. - * This would for example reposition flash/silverlight shims on the page. - * - * @method refresh - */ - refresh : function() { - if (fileInputs.length) { - plupload.each(fileInputs, function(fileInput) { - fileInput.trigger('Refresh'); - }); - } - this.trigger('Refresh'); - }, - - /** - * Starts uploading the queued files. - * - * @method start - */ - start : function() { - if (this.state != plupload.STARTED) { - this.state = plupload.STARTED; - this.trigger('StateChanged'); - - uploadNext.call(this); - } - }, - - /** - * Stops the upload of the queued files. - * - * @method stop - */ - stop : function() { - if (this.state != plupload.STOPPED) { - this.state = plupload.STOPPED; - this.trigger('StateChanged'); - this.trigger('CancelUpload'); - } - }, - - - /** - * Disables/enables browse button on request. - * - * @method disableBrowse - * @param {Boolean} disable Whether to disable or enable (default: true) - */ - disableBrowse : function() { - disabled = arguments[0] !== undef ? arguments[0] : true; - - if (fileInputs.length) { - plupload.each(fileInputs, function(fileInput) { - fileInput.disable(disabled); - }); - } - - this.trigger('DisableBrowse', disabled); - }, - - /** - * Returns the specified file object by id. - * - * @method getFile - * @param {String} id File id to look for. - * @return {plupload.File} File object or undefined if it wasn't found; - */ - getFile : function(id) { - var i; - for (i = files.length - 1; i >= 0; i--) { - if (files[i].id === id) { - return files[i]; - } - } - }, - - /** - * Adds file to the queue programmatically. Can be native file, instance of Plupload.File, - * instance of mOxie.File, input[type="file"] element, or array of these. Fires FilesAdded, - * if any files were added to the queue. Otherwise nothing happens. - * - * @method addFile - * @since 2.0 - * @param {plupload.File|mOxie.File|File|Node|Array} file File or files to add to the queue. - * @param {String} [fileName] If specified, will be used as a name for the file - */ - addFile : function(file, fileName) { - var self = this - , queue = [] - , filesAdded = [] - , ruid - ; - - function filterFile(file, cb) { - var queue = []; - plupload.each(self.settings.filters, function(rule, name) { - if (fileFilters[name]) { - queue.push(function(cb) { - fileFilters[name].call(self, rule, file, function(res) { - cb(!res); - }); - }); - } - }); - plupload.inSeries(queue, cb); - } - - /** - * @method resolveFile - * @private - * @param {moxie.file.File|moxie.file.Blob|plupload.File|File|Blob|input[type="file"]} file - */ - function resolveFile(file) { - var type = plupload.typeOf(file); - - // moxie.file.File - if (file instanceof o.file.File) { - if (!file.ruid && !file.isDetached()) { - if (!ruid) { // weird case - return false; - } - file.ruid = ruid; - file.connectRuntime(ruid); - } - resolveFile(new plupload.File(file)); - } - // moxie.file.Blob - else if (file instanceof o.file.Blob) { - resolveFile(file.getSource()); - file.destroy(); - } - // plupload.File - final step for other branches - else if (file instanceof plupload.File) { - if (fileName) { - file.name = fileName; - } - - queue.push(function(cb) { - // run through the internal and user-defined filters, if any - filterFile(file, function(err) { - if (!err) { - // make files available for the filters by updating the main queue directly - files.push(file); - // collect the files that will be passed to FilesAdded event - filesAdded.push(file); - - self.trigger("FileFiltered", file); - } - delay(cb, 1); // do not build up recursions or eventually we might hit the limits - }); - }); - } - // native File or blob - else if (plupload.inArray(type, ['file', 'blob']) !== -1) { - resolveFile(new o.file.File(null, file)); - } - // input[type="file"] - else if (type === 'node' && plupload.typeOf(file.files) === 'filelist') { - // if we are dealing with input[type="file"] - plupload.each(file.files, resolveFile); - } - // mixed array of any supported types (see above) - else if (type === 'array') { - fileName = null; // should never happen, but unset anyway to avoid funny situations - plupload.each(file, resolveFile); - } - } - - ruid = getRUID(); - - resolveFile(file); - - if (queue.length) { - plupload.inSeries(queue, function() { - // if any files left after filtration, trigger FilesAdded - if (filesAdded.length) { - self.trigger("FilesAdded", filesAdded); - } - }); - } - }, - - /** - * Removes a specific file. - * - * @method removeFile - * @param {plupload.File|String} file File to remove from queue. - */ - removeFile : function(file) { - var id = typeof(file) === 'string' ? file : file.id; - - for (var i = files.length - 1; i >= 0; i--) { - if (files[i].id === id) { - return this.splice(i, 1)[0]; - } - } - }, - - /** - * Removes part of the queue and returns the files removed. This will also trigger the - * FilesRemoved and QueueChanged events. - * - * @method splice - * @param {Number} [start=0] Start index to remove from. - * @param {Number} [length] Number of files to remove (defaults to number of files in the queue). - * @return {Array} Array of files that was removed. - */ - splice : function(start, length) { - // Splice and trigger events - var removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length); - - // if upload is in progress we need to stop it and restart after files are removed - var restartRequired = false; - if (this.state == plupload.STARTED) { // upload in progress - plupload.each(removed, function(file) { - if (file.status === plupload.UPLOADING) { - restartRequired = true; // do not restart, unless file that is being removed is uploading - return false; - } - }); - - if (restartRequired) { - this.stop(); - } - } - - this.trigger("FilesRemoved", removed); - - // Dispose any resources allocated by those files - plupload.each(removed, function(file) { - file.destroy(); - }); - - if (restartRequired) { - this.start(); - } - - return removed; - }, - - /** - Dispatches the specified event name and its arguments to all listeners. - - @method trigger - @param {String} name Event name to fire. - @param {Object..} Multiple arguments to pass along to the listener functions. - */ - - // override the parent method to match Plupload-like event logic - dispatchEvent: function(type) { - var list, args, result; - - type = type.toLowerCase(); - - list = this.hasEventListener(type); - - if (list) { - // sort event list by priority - list.sort(function(a, b) { return b.priority - a.priority; }); - - // first argument should be current plupload.Uploader instance - args = [].slice.call(arguments); - args.shift(); - args.unshift(this); - - for (var i = 0; i < list.length; i++) { - // Fire event, break chain if false is returned - if (list[i].fn.apply(list[i].scope, args) === false) { - return false; - } - } - } - return true; - }, - - /** - Check whether uploader has any listeners to the specified event. - - @method hasEventListener - @param {String} name Event name to check for. - */ - - - /** - Adds an event listener by name. - - @method bind - @param {String} name Event name to listen for. - @param {function} fn Function to call ones the event gets fired. - @param {Object} [scope] Optional scope to execute the specified function in. - @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first - */ - bind: function(name, fn, scope, priority) { - // adapt moxie EventTarget style to Plupload-like - plupload.Uploader.prototype.bind.call(this, name, fn, priority, scope); - }, - - /** - Removes the specified event listener. - - @method unbind - @param {String} name Name of event to remove. - @param {function} fn Function to remove from listener. - */ - - /** - Removes all event listeners. - - @method unbindAll - */ - - - /** - * Destroys Plupload instance and cleans after itself. - * - * @method destroy - */ - destroy : function() { - this.trigger('Destroy'); - settings = total = null; // purge these exclusively - this.unbindAll(); - } - }); -}; - -plupload.Uploader.prototype = o.core.EventTarget.instance; - -/** - * Constructs a new file instance. - * - * @class File - * @constructor - * - * @param {Object} file Object containing file properties - * @param {String} file.name Name of the file. - * @param {Number} file.size File size. - */ -plupload.File = (function() { - var filepool = {}; - - function PluploadFile(file) { - - plupload.extend(this, { - - /** - * File id this is a globally unique id for the specific file. - * - * @property id - * @type String - */ - id: plupload.guid(), - - /** - * File name for example "myfile.gif". - * - * @property name - * @type String - */ - name: file.name || file.fileName, - - /** - * File type, `e.g image/jpeg` - * - * @property type - * @type String - */ - type: file.type || '', - - /** - * Relative path to the file inside a directory - * - * @property relativePath - * @type String - * @default '' - */ - relativePath: file.relativePath || '', - - /** - * File size in bytes (may change after client-side manupilation). - * - * @property size - * @type Number - */ - size: file.fileSize || file.size, - - /** - * Original file size in bytes. - * - * @property origSize - * @type Number - */ - origSize: file.fileSize || file.size, - - /** - * Number of bytes uploaded of the files total size. - * - * @property loaded - * @type Number - */ - loaded: 0, - - /** - * Number of percentage uploaded of the file. - * - * @property percent - * @type Number - */ - percent: 0, - - /** - * Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE. - * - * @property status - * @type Number - * @see plupload - */ - status: plupload.QUEUED, - - /** - * Date of last modification. - * - * @property lastModifiedDate - * @type {String} - */ - lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString(), // Thu Aug 23 2012 19:40:00 GMT+0400 (GET) - - - /** - * Set when file becomes plupload.DONE or plupload.FAILED. Is used to calculate proper plupload.QueueProgress.bytesPerSec. - * @private - * @property completeTimestamp - * @type {Number} - */ - completeTimestamp: 0, - - /** - * Returns native window.File object, when it's available. - * - * @method getNative - * @return {window.File} or null, if plupload.File is of different origin - */ - getNative: function() { - var file = this.getSource().getSource(); - return plupload.inArray(plupload.typeOf(file), ['blob', 'file']) !== -1 ? file : null; - }, - - /** - * Returns mOxie.File - unified wrapper object that can be used across runtimes. - * - * @method getSource - * @return {mOxie.File} or null - */ - getSource: function() { - if (!filepool[this.id]) { - return null; - } - return filepool[this.id]; - }, - - /** - * Destroys plupload.File object. - * - * @method destroy - */ - destroy: function() { - var src = this.getSource(); - if (src) { - src.destroy(); - delete filepool[this.id]; - } - } - }); - - filepool[this.id] = file; - } - - return PluploadFile; -}()); - - -/** - * Constructs a queue progress. - * - * @class QueueProgress - * @constructor - */ - plupload.QueueProgress = function() { - var self = this; // Setup alias for self to reduce code size when it's compressed - - /** - * Total queue file size. - * - * @property size - * @type Number - */ - self.size = 0; - - /** - * Total bytes uploaded. - * - * @property loaded - * @type Number - */ - self.loaded = 0; - - /** - * Number of files uploaded. - * - * @property uploaded - * @type Number - */ - self.uploaded = 0; - - /** - * Number of files failed to upload. - * - * @property failed - * @type Number - */ - self.failed = 0; - - /** - * Number of files yet to be uploaded. - * - * @property queued - * @type Number - */ - self.queued = 0; - - /** - * Total percent of the uploaded bytes. - * - * @property percent - * @type Number - */ - self.percent = 0; - - /** - * Bytes uploaded per second. - * - * @property bytesPerSec - * @type Number - */ - self.bytesPerSec = 0; - - /** - * Resets the progress to its initial values. - * - * @method reset - */ - self.reset = function() { - self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0; - }; -}; - -exports.plupload = plupload; - -}(this, moxie)); - -})); \ No newline at end of file +!function(e){function t(){var e={};return function(e){(function(e,w,T){var D=window.setTimeout;var x={};var t=w.core.utils;var F=w.runtime.Runtime;function P(e){var t=e.required_features,s={};function i(e,t,i){var r={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};if(r[e]){s[r[e]]=t}else if(!i){s[e]=t}}if(typeof t==="string"){U.each(t.split(/\s*,\s*/),function(e){i(e,true)})}else if(typeof t==="object"){U.each(t,function(e,t){i(t,e)})}else if(t===true){if(e.chunk_size&&e.chunk_size>0){s.slice_blob=true}if(!U.isEmptyObj(e.resize)||e.multipart===false){s.send_binary_string=true}if(e.http_method){s.use_http_method=e.http_method}U.each(e,function(e,t){i(t,!!e,true)})}return s}var U={VERSION:"2.3.6",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,moxie:w,mimeTypes:t.Mime.mimes,ua:t.Env,typeOf:t.Basic.typeOf,extend:t.Basic.extend,guid:t.Basic.guid,getAll:function e(t){var i=[],r;if(U.typeOf(t)!=="array"){t=[t]}var s=t.length;while(s--){r=U.get(t[s]);if(r){i.push(r)}}return i.length?i:null},get:t.Dom.get,each:t.Basic.each,getPos:t.Dom.getPos,getSize:t.Dom.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},i=/[<>&\"\']/g;return e?(""+e).replace(i,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.Basic.toArray,inArray:t.Basic.inArray,inSeries:t.Basic.inSeries,addI18n:w.core.I18n.addI18n,translate:w.core.I18n.translate,sprintf:t.Basic.sprintf,isEmptyObj:t.Basic.isEmptyObj,hasClass:t.Dom.hasClass,addClass:t.Dom.addClass,removeClass:t.Dom.removeClass,getStyle:t.Dom.getStyle,addEvent:t.Events.addEvent,removeEvent:t.Events.removeEvent,removeAllEvents:t.Events.removeAllEvents,cleanName:function(e){var t,i;i=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t 0?"&":"?")+i}return e},formatSize:function(e){if(e===T||/\D/.test(e)){return U.translate("N/A")}function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}var i=Math.pow(1024,4);if(e>i){return t(e/i,1)+" "+U.translate("tb")}if(e>(i/=1024)){return t(e/i,1)+" "+U.translate("gb")}if(e>(i/=1024)){return t(e/i,1)+" "+U.translate("mb")}if(e>1024){return Math.round(e/1024)+" "+U.translate("kb")}return e+" "+U.translate("b")},parseSize:t.Basic.parseSizeStr,predictRuntime:function(e,t){var i,r;i=new U.Uploader(e);r=F.thatCan(i.getOption().required_features,t||e.runtimes);i.destroy();return r},addFileFilter:function(e,t){x[e]=t}};U.addFileFilter("mime_types",function(e,t,i){if(e.length&&!e.regexp.test(t.name)){this.trigger("Error",{code:U.FILE_EXTENSION_ERROR,message:U.translate("File extension error."),file:t});i(false)}else{i(true)}});U.addFileFilter("max_file_size",function(e,t,i){var r;e=U.parseSize(e);if(t.size!==r&&e&&t.size>e){this.trigger("Error",{code:U.FILE_SIZE_ERROR,message:U.translate("File size error."),file:t});i(false)}else{i(true)}});U.addFileFilter("prevent_duplicates",function(e,t,i){if(e){var r=this.files.length;while(r--){if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:U.FILE_DUPLICATE_ERROR,message:U.translate("Duplicate file error."),file:t});i(false);return}}}i(true)});U.addFileFilter("prevent_empty",function(e,t,i){if(e&&!t.size&&t.size!==T){this.trigger("Error",{code:U.FILE_SIZE_ERROR,message:U.translate("File size error."),file:t});i(false)}else{i(true)}});U.Uploader=function(e){var t=U.guid(),a,u=[],h={},o=[],l=[],s,n,f=false,m;function i(){var e,t=0,i;if(this.state==U.STARTED){for(i=0;i 0?Math.ceil(e.loaded/e.size*100):100;d()}function d(){var e,t;var i;var r=0;n.reset();for(e=0;e s){r+=i}n.loaded+=i}else{n.size=T}if(t.status==U.DONE){n.uploaded++}else if(t.status==U.FAILED){n.failed++}else{n.queued++}}if(n.size===T){n.percent=u.length>0?Math.ceil(n.uploaded/u.length*100):0}else{n.bytesPerSec=Math.ceil(r/((+new Date-s||1)/1e3));n.percent=n.size>0?Math.ceil(n.loaded/n.size*100):0}}function c(){var e=o[0]||l[0];if(e){return e.getRuntime().uid}return false}function p(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged");e.refresh()});this.bind("CancelUpload",z);this.bind("BeforeUpload",E);this.bind("UploadFile",b);this.bind("UploadProgress",y);this.bind("StateChanged",R);this.bind("QueueChanged",d);this.bind("Error",S);this.bind("FileUploaded",O);this.bind("Destroy",I)}function g(r,e){var s=this,n=0,t=[];var a={runtime_order:r.runtimes,required_caps:r.required_features,preferred_caps:h,swf_url:r.flash_swf_url,xap_url:r.silverlight_xap_url};U.each(r.runtimes.split(/\s*,\s*/),function(e){if(r[e]){a[e]=r[e]}});if(r.browse_button){U.each(r.browse_button,function(i){t.push(function(t){var e=new w.file.FileInput(U.extend({},a,{accept:r.filters.mime_types,name:r.file_data_name,multiple:r.multi_selection,container:r.container,browse_button:i}));e.onready=function(){var e=F.getInfo(this.ruid);U.extend(s.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")});n++;o.push(this);t()};e.onchange=function(){s.addFile(this.files)};e.bind("mouseenter mouseleave mousedown mouseup",function(e){if(!f){if(r.browse_button_hover){if("mouseenter"===e.type){U.addClass(i,r.browse_button_hover)}else if("mouseleave"===e.type){U.removeClass(i,r.browse_button_hover)}}if(r.browse_button_active){if("mousedown"===e.type){U.addClass(i,r.browse_button_active)}else if("mouseup"===e.type){U.removeClass(i,r.browse_button_active)}}}});e.bind("mousedown",function(){s.trigger("Browse")});e.bind("error runtimeerror",function(){e=null;t()});e.init()})})}if(r.drop_element){U.each(r.drop_element,function(i){t.push(function(t){var e=new w.file.FileDrop(U.extend({},a,{drop_zone:i}));e.onready=function(){var e=F.getInfo(this.ruid);U.extend(s.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),dragdrop:e.can("drag_and_drop")});n++;l.push(this);t()};e.ondrop=function(){s.addFile(this.files)};e.bind("error runtimeerror",function(){e=null;t()});e.init()})})}U.inSeries(t,function(){if(typeof e==="function"){e(n)}})}function _(t,i,e,r){var s=new w.image.Image;try{s.onload=function(){if(i.width>this.width&&i.height>this.height&&i.quality===T&&i.preserve_headers&&!i.crop){this.destroy();r(t)}else{s.downsize(i.width,i.height,i.crop,i.preserve_headers)}};s.onresize=function(){var e=this.getAsBlob(t.type,i.quality);this.destroy();r(e)};s.bind("error runtimeerror",function(){this.destroy();r(t)});s.load(t,e)}catch(e){r(t)}}function v(e,t,i){var s=this,n=false;function r(e,t,i){var r=a[e];switch(e){case"max_file_size":if(e==="max_file_size"){a.max_file_size=a.filters.max_file_size=t}break;case"chunk_size":if(t=U.parseSize(t)){a[e]=t;a.send_file_name=true}break;case"multipart":a[e]=t;if(!t){a.send_file_name=true}break;case"http_method":a[e]=t.toUpperCase()==="PUT"?"PUT":"POST";break;case"unique_names":a[e]=t;if(t){a.send_file_name=true}break;case"filters":if(U.typeOf(t)==="array"){t={mime_types:t}}if(i){U.extend(a.filters,t)}else{a.filters=t}if(t.mime_types){if(U.typeOf(t.mime_types)==="string"){t.mime_types=w.core.utils.Mime.mimes2extList(t.mime_types)}t.mime_types.regexp=function(e){var t=[];U.each(e,function(e){U.each(e.extensions.split(/,/),function(e){if(/^\s*\*\s*$/.test(e)){t.push("\\.*")}else{t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))}})});return new RegExp("("+t.join("|")+")$","i")}(t.mime_types);a.filters.mime_types=t.mime_types}break;case"resize":if(t){a.resize=U.extend({preserve_headers:true,crop:false},t)}else{a.resize=false}break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"container":case"browse_button":case"drop_element":t="container"===e?U.get(t):U.getAll(t);case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t;if(!i){n=true}break;default:a[e]=t}if(!i){s.trigger("OptionChanged",e,t,r)}}if(typeof e==="object"){U.each(e,function(e,t){r(t,e,i)})}else{r(e,t,i)}if(i){a.required_features=P(U.extend({},a));h=P(U.extend({},a,{required_features:true}))}else if(n){s.trigger("Destroy");g.call(s,a,function(e){if(e){s.runtime=F.getInfo(c()).type;s.trigger("Init",{runtime:s.runtime});s.trigger("PostInit")}else{s.trigger("Error",{code:U.INIT_ERROR,message:U.translate("Init error.")})}})}}function E(e,t){if(e.settings.unique_names){var i=t.name.match(/\.([^.]+)$/),r="part";if(i){r=i[1]}t.target_name=t.id+"."+r}}function b(s,n){var a=s.settings.url;var r=s.settings.chunk_size;var o=s.settings.max_retries;var l=s.features;var u=0;var f;var d={runtime_order:s.settings.runtimes,required_caps:s.settings.required_features,preferred_caps:h,swf_url:s.settings.flash_swf_url,xap_url:s.settings.silverlight_xap_url};if(n.loaded){u=n.loaded=r?r*Math.floor(n.loaded/r):0}function c(){if(o-- >0){D(p,1e3)}else{n.loaded=u;s.trigger("Error",{code:U.HTTP_ERROR,message:U.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})}}function p(){var e,t={},i;if(n.status!==U.UPLOADING||s.state===U.STOPPED){return}if(s.settings.send_file_name){t.name=n.target_name||n.name}if(r&&l.chunks&&f.size>r){i=Math.min(r,f.size-u);e=f.slice(u,u+i)}else{i=f.size;e=f}if(r&&l.chunks){if(s.settings.send_chunk_number){t.chunk=Math.ceil(u/r);t.chunks=Math.ceil(f.size/r)}else{t.offset=u;t.total=f.size}}if(s.trigger("BeforeChunkUpload",n,t,e,u)){g(t,e,i)}}function g(e,t,i){var r;m=new w.xhr.XMLHttpRequest;if(m.upload){m.upload.onprogress=function(e){n.loaded=Math.min(n.size,u+e.loaded);s.trigger("UploadProgress",n)}}m.onload=function(){if(m.status<200||m.status>=400){c();return}o=s.settings.max_retries;if(i =f.size){if(n.size!=n.origSize){f.destroy();f=null}s.trigger("UploadProgress",n);n.status=U.DONE;n.completeTimestamp=+new Date;s.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})}else{D(p,1)}};m.onerror=function(){c()};m.onloadend=function(){this.destroy()};if(s.settings.multipart&&l.multipart){m.open(s.settings.http_method,a,true);U.each(s.settings.headers,function(e,t){m.setRequestHeader(t,e)});r=new w.xhr.FormData;U.each(U.extend(e,s.settings.multipart_params),function(e,t){r.append(t,e)});r.append(s.settings.file_data_name,t);m.send(r,d)}else{a=U.buildUrl(s.settings.url,U.extend(e,s.settings.multipart_params));m.open(s.settings.http_method,a,true);U.each(s.settings.headers,function(e,t){m.setRequestHeader(t,e)});if(!m.hasRequestHeader("Content-Type")){m.setRequestHeader("Content-Type","application/octet-stream")}m.send(t,d)}}f=n.getSource();if(!U.isEmptyObj(s.settings.resize)&&U.inArray(f.type,["image/jpeg","image/png"])!==-1){_(f,s.settings.resize,d,function(e){f=e;n.size=e.size;p()})}else{p()}}function y(e,t){r(t)}function R(e){if(e.state==U.STARTED){s=+new Date}else if(e.state==U.STOPPED){for(var t=e.files.length-1;t>=0;t--){if(e.files[t].status==U.UPLOADING){e.files[t].status=U.QUEUED;d()}}}}function z(){if(m){m.abort()}}function O(e){d();D(function(){i.call(e)},1)}function S(e,t){if(t.code===U.INIT_ERROR){e.destroy()}else if(t.code===U.HTTP_ERROR){t.file.status=U.FAILED;t.file.completeTimestamp=+new Date;r(t.file);if(e.state==U.STARTED){e.trigger("CancelUpload");D(function(){i.call(e)},1)}}}function I(e){e.stop();U.each(u,function(e){e.destroy()});u=[];if(o.length){U.each(o,function(e){e.destroy()});o=[]}if(l.length){U.each(l,function(e){e.destroy()});l=[]}h={};f=false;s=m=null;n.reset()}a={chunk_size:0,file_data_name:"file",filters:{mime_types:[],max_file_size:0,prevent_duplicates:false,prevent_empty:true},flash_swf_url:"js/Moxie.swf",http_method:"POST",max_retries:0,multipart:true,multi_selection:true,resize:false,runtimes:F.order,send_file_name:true,send_chunk_number:true,silverlight_xap_url:"js/Moxie.xap"};v.call(this,e,null,true);n=new U.QueueProgress;U.extend(this,{id:t,uid:t,state:U.STOPPED,features:{},runtime:null,files:u,settings:a,total:n,init:function(){var i=this,e,t,r;t=i.getOption("preinit");if(typeof t=="function"){t(i)}else{U.each(t,function(e,t){i.bind(t,e)})}p.call(i);U.each(["container","browse_button","drop_element"],function(e){if(i.getOption(e)===null){r={code:U.INIT_ERROR,message:U.sprintf(U.translate("%s specified, but cannot be found."),e)};return false}});if(r){return i.trigger("Error",r)}if(!a.browse_button&&!a.drop_element){return i.trigger("Error",{code:U.INIT_ERROR,message:U.translate("You must specify either browse_button or drop_element.")})}g.call(i,a,function(e){var t=i.getOption("init");if(typeof t=="function"){t(i)}else{U.each(t,function(e,t){i.bind(t,e)})}if(e){i.runtime=F.getInfo(c()).type;i.trigger("Init",{runtime:i.runtime});i.trigger("PostInit")}else{i.trigger("Error",{code:U.INIT_ERROR,message:U.translate("Init error.")})}})},setOption:function(e,t){v.call(this,e,t,!this.runtime)},getOption:function(e){if(!e){return a}return a[e]},refresh:function(){if(o.length){U.each(o,function(e){e.trigger("Refresh")})}this.trigger("Refresh")},start:function(){if(this.state!=U.STARTED){this.state=U.STARTED;this.trigger("StateChanged");i.call(this)}},stop:function(){if(this.state!=U.STOPPED){this.state=U.STOPPED;this.trigger("StateChanged");this.trigger("CancelUpload")}},disableBrowse:function(){f=arguments[0]!==T?arguments[0]:true;if(o.length){U.each(o,function(e){e.disable(f)})}this.trigger("DisableBrowse",f)},getFile:function(e){var t;for(t=u.length-1;t>=0;t--){if(u[t].id===e){return u[t]}}},addFile:function(e,t){var s=this,r=[],n=[],a;function o(r,e){var t=[];U.each(s.settings.filters,function(e,i){if(x[i]){t.push(function(t){x[i].call(s,e,r,function(e){t(!e)})})}});U.inSeries(t,e)}function l(i){var e=U.typeOf(i);if(i instanceof w.file.File){if(!i.ruid&&!i.isDetached()){if(!a){return false}i.ruid=a;i.connectRuntime(a)}l(new U.File(i))}else if(i instanceof w.file.Blob){l(i.getSource());i.destroy()}else if(i instanceof U.File){if(t){i.name=t}r.push(function(t){o(i,function(e){if(!e){u.push(i);n.push(i);s.trigger("FileFiltered",i)}D(t,1)})})}else if(U.inArray(e,["file","blob"])!==-1){l(new w.file.File(null,i))}else if(e==="node"&&U.typeOf(i.files)==="filelist"){U.each(i.files,l)}else if(e==="array"){t=null;U.each(i,l)}}a=c();l(e);if(r.length){U.inSeries(r,function(){if(n.length){s.trigger("FilesAdded",n)}})}},removeFile:function(e){var t=typeof e==="string"?e:e.id;for(var i=u.length-1;i>=0;i--){if(u[i].id===t){return this.splice(i,1)[0]}}},splice:function(e,t){var i=u.splice(e===T?0:e,t===T?u.length:t);var r=false;if(this.state==U.STARTED){U.each(i,function(e){if(e.status===U.UPLOADING){r=true;return false}});if(r){this.stop()}}this.trigger("FilesRemoved",i);U.each(i,function(e){e.destroy()});if(r){this.start()}return i},dispatchEvent:function(e){var t,i,r;e=e.toLowerCase();t=this.hasEventListener(e);if(t){t.sort(function(e,t){return t.priority-e.priority});i=[].slice.call(arguments);i.shift();i.unshift(this);for(var s=0;s #mq-test-1 { width: 42px; }'; - docElem.insertBefore(fakeBody, refNode); - bool = div.offsetWidth === 42; - docElem.removeChild(fakeBody); - return { - matches: bool, - media: q - }; - }; - }(w.document); -})(this); - -(function(w) { - "use strict"; - var respond = {}; - w.respond = respond; - respond.update = function() {}; - var requestQueue = [], xmlHttp = function() { - var xmlhttpmethod = false; - try { - xmlhttpmethod = new w.XMLHttpRequest(); - } catch (e) { - xmlhttpmethod = new w.ActiveXObject("Microsoft.XMLHTTP"); - } - return function() { - return xmlhttpmethod; - }; - }(), ajax = function(url, callback) { - var req = xmlHttp(); - if (!req) { - return; - } - req.open("GET", url, true); - req.onreadystatechange = function() { - if (req.readyState !== 4 || req.status !== 200 && req.status !== 304) { - return; - } - callback(req.responseText); - }; - if (req.readyState === 4) { - return; - } - req.send(null); - }, isUnsupportedMediaQuery = function(query) { - return query.replace(respond.regex.minmaxwh, "").match(respond.regex.other); - }; - respond.ajax = ajax; - respond.queue = requestQueue; - respond.unsupportedmq = isUnsupportedMediaQuery; - respond.regex = { - media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi, - keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi, - comments: /\/\*[^*]*\*+([^/][^*]*\*+)*\//gi, - urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, - findStyles: /@media *([^\{]+)\{([\S\s]+?)$/, - only: /(only\s+)?([a-zA-Z]+)\s?/, - minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/, - maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/, - minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi, - other: /\([^\)]*\)/g - }; - respond.mediaQueriesSupported = w.matchMedia && w.matchMedia("only all") !== null && w.matchMedia("only all").matches; - if (respond.mediaQueriesSupported) { - return; - } - var doc = w.document, docElem = doc.documentElement, mediastyles = [], rules = [], appendedEls = [], parsedSheets = {}, resizeThrottle = 30, head = doc.getElementsByTagName("head")[0] || docElem, base = doc.getElementsByTagName("base")[0], links = head.getElementsByTagName("link"), lastCall, resizeDefer, eminpx, getEmValue = function() { - var ret, div = doc.createElement("div"), body = doc.body, originalHTMLFontSize = docElem.style.fontSize, originalBodyFontSize = body && body.style.fontSize, fakeUsed = false; - div.style.cssText = "position:absolute;font-size:1em;width:1em"; - if (!body) { - body = fakeUsed = doc.createElement("body"); - body.style.background = "none"; - } - docElem.style.fontSize = "100%"; - body.style.fontSize = "100%"; - body.appendChild(div); - if (fakeUsed) { - docElem.insertBefore(body, docElem.firstChild); - } - ret = div.offsetWidth; - if (fakeUsed) { - docElem.removeChild(body); - } else { - body.removeChild(div); - } - docElem.style.fontSize = originalHTMLFontSize; - if (originalBodyFontSize) { - body.style.fontSize = originalBodyFontSize; - } - ret = eminpx = parseFloat(ret); - return ret; - }, applyMedia = function(fromResize) { - var name = "clientWidth", docElemProp = docElem[name], currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[name] || docElemProp, styleBlocks = {}, lastLink = links[links.length - 1], now = new Date().getTime(); - if (fromResize && lastCall && now - lastCall < resizeThrottle) { - w.clearTimeout(resizeDefer); - resizeDefer = w.setTimeout(applyMedia, resizeThrottle); - return; - } else { - lastCall = now; - } - for (var i in mediastyles) { - if (mediastyles.hasOwnProperty(i)) { - var thisstyle = mediastyles[i], min = thisstyle.minw, max = thisstyle.maxw, minnull = min === null, maxnull = max === null, em = "em"; - if (!!min) { - min = parseFloat(min) * (min.indexOf(em) > -1 ? eminpx || getEmValue() : 1); - } - if (!!max) { - max = parseFloat(max) * (max.indexOf(em) > -1 ? eminpx || getEmValue() : 1); - } - if (!thisstyle.hasquery || (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max)) { - if (!styleBlocks[thisstyle.media]) { - styleBlocks[thisstyle.media] = []; - } - styleBlocks[thisstyle.media].push(rules[thisstyle.rules]); - } - } - } - for (var j in appendedEls) { - if (appendedEls.hasOwnProperty(j)) { - if (appendedEls[j] && appendedEls[j].parentNode === head) { - head.removeChild(appendedEls[j]); - } - } - } - appendedEls.length = 0; - for (var k in styleBlocks) { - if (styleBlocks.hasOwnProperty(k)) { - var ss = doc.createElement("style"), css = styleBlocks[k].join("\n"); - ss.type = "text/css"; - ss.media = k; - head.insertBefore(ss, lastLink.nextSibling); - if (ss.styleSheet) { - ss.styleSheet.cssText = css; - } else { - ss.appendChild(doc.createTextNode(css)); - } - appendedEls.push(ss); - } - } - }, translate = function(styles, href, media) { - var qs = styles.replace(respond.regex.comments, "").replace(respond.regex.keyframes, "").match(respond.regex.media), ql = qs && qs.length || 0; - href = href.substring(0, href.lastIndexOf("/")); - var repUrls = function(css) { - return css.replace(respond.regex.urls, "$1" + href + "$2$3"); - }, useMedia = !ql && media; - if (href.length) { - href += "/"; - } - if (useMedia) { - ql = 1; - } - for (var i = 0; i < ql; i++) { - var fullq, thisq, eachq, eql; - if (useMedia) { - fullq = media; - rules.push(repUrls(styles)); - } else { - fullq = qs[i].match(respond.regex.findStyles) && RegExp.$1; - rules.push(RegExp.$2 && repUrls(RegExp.$2)); - } - eachq = fullq.split(","); - eql = eachq.length; - for (var j = 0; j < eql; j++) { - thisq = eachq[j]; - if (isUnsupportedMediaQuery(thisq)) { - continue; - } - mediastyles.push({ - media: thisq.split("(")[0].match(respond.regex.only) && RegExp.$2 || "all", - rules: rules.length - 1, - hasquery: thisq.indexOf("(") > -1, - minw: thisq.match(respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""), - maxw: thisq.match(respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "") - }); - } - } - applyMedia(); - }, makeRequests = function() { - if (requestQueue.length) { - var thisRequest = requestQueue.shift(); - ajax(thisRequest.href, function(styles) { - translate(styles, thisRequest.href, thisRequest.media); - parsedSheets[thisRequest.href] = true; - w.setTimeout(function() { - makeRequests(); - }, 0); - }); - } - }, ripCSS = function() { - for (var i = 0; i < links.length; i++) { - var sheet = links[i], href = sheet.href, media = sheet.media, isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; - if (!!href && isCSS && !parsedSheets[href]) { - if (sheet.styleSheet && sheet.styleSheet.rawCssText) { - translate(sheet.styleSheet.rawCssText, href, media); - parsedSheets[href] = true; - } else { - if (!/^([a-zA-Z:]*\/\/)/.test(href) && !base || href.replace(RegExp.$1, "").split("/")[0] === w.location.host) { - if (href.substring(0, 2) === "//") { - href = w.location.protocol + href; - } - requestQueue.push({ - href: href, - media: media - }); - } - } - } - } - makeRequests(); - }; - ripCSS(); - respond.update = ripCSS; - respond.getEmValue = getEmValue; - function callMedia() { - applyMedia(true); - } - if (w.addEventListener) { - w.addEventListener("resize", callMedia, false); - } else if (w.attachEvent) { - w.attachEvent("onresize", callMedia); - } -})(this); \ No newline at end of file +!function(e){"use strict";var t,n,a,s,i,r;e.matchMedia=e.matchMedia||(t=e.document,a=t.documentElement,s=a.firstElementChild||a.firstChild,i=t.createElement("body"),(r=t.createElement("div")).id="mq-test-1",r.style.cssText="position:absolute;top:-100em",i.style.background="none",i.appendChild(r),function(e){return r.innerHTML='',a.insertBefore(i,s),n=42===r.offsetWidth,a.removeChild(i),{matches:n,media:e}})}(this),function(y){"use strict";var c={};(y.respond=c).update=function(){};function e(e,t){var n=a();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))}function p(e){return e.replace(c.regex.minmaxwh,"").match(c.regex.other)}var x,v,E,w,S,i,T,r,C,b,$,z,M,R,o,l,t,m=[],a=function(){var t=!1;try{t=new y.XMLHttpRequest}catch(e){t=new y.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}();function n(){R(!0)}c.ajax=e,c.queue=m,c.unsupportedmq=p,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=y.matchMedia&&null!==y.matchMedia("only all")&&y.matchMedia("only all").matches,c.mediaQueriesSupported||(x=y.document,v=x.documentElement,E=[],w=[],S=[],i={},T=x.getElementsByTagName("head")[0]||v,r=x.getElementsByTagName("base")[0],C=T.getElementsByTagName("link"),M=function(){var e,t=x.createElement("div"),n=x.body,a=v.style.fontSize,s=n&&n.style.fontSize,i=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||((n=i=x.createElement("body")).style.background="none"),v.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),i&&v.insertBefore(n,v.firstChild),e=t.offsetWidth,i?v.removeChild(n):n.removeChild(t),v.style.fontSize=a,s&&(n.style.fontSize=s),e=z=parseFloat(e)},R=function(e){var t,n,a,s,i,r,o,l="clientWidth",m=v[l],d="CSS1Compat"===x.compatMode&&m||x.body[l]||m,h={},u=C[C.length-1],c=(new Date).getTime();if(e&&b&&c-b<30)return y.clearTimeout($),void($=y.setTimeout(R,30));for(var p in b=c,E){E.hasOwnProperty(p)&&(n=null===(s=(t=E[p]).minw),a=null===(i=t.maxw),s=s&&parseFloat(s)*(-1 0 && typeof timezoneList[0] !== 'object') { - for (; tzi < tzl; tzi++) { - tzv = timezoneList[tzi]; - timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) }; - } - } - tp_inst._defaults.timezoneList = timezoneList; - - // set the default units - tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) : - ((new Date()).getTimezoneOffset() * -1); - tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin : - tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour; - tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin : - tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute; - tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin : - tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second; - tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin : - tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec; - tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin : - tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec; - tp_inst.ampm = ''; - tp_inst.$input = $input; - - if (tp_inst._defaults.altField) { - tp_inst.$altInput = $(tp_inst._defaults.altField).css({ - cursor: 'pointer' - }).focus(function () { - $input.trigger("focus"); - }); - } - - if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { - tp_inst._defaults.minDate = new Date(); - } - if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { - tp_inst._defaults.maxDate = new Date(); - } - - // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. - if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { - tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); - } - if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { - tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); - } - if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { - tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); - } - if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { - tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); - } - tp_inst.$input.bind('focus', function () { - tp_inst._onFocus(); - }); - - return tp_inst; - }, - - /* - * add our sliders to the calendar - */ - _addTimePicker: function (dp_inst) { - var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); - - this.timeDefined = this._parseTime(currDT); - this._limitMinMaxDateTime(dp_inst, false); - this._injectTimePicker(); - }, - - /* - * parse the time string from input value or _setTime - */ - _parseTime: function (timeString, withDate) { - if (!this.inst) { - this.inst = $.datepicker._getInst(this.$input[0]); - } - - if (withDate || !this._defaults.timeOnly) { - var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); - try { - var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); - if (!parseRes.timeObj) { - return false; - } - $.extend(this, parseRes.timeObj); - } catch (err) { - $.timepicker.log("Error parsing the date/time string: " + err + - "\ndate/time string = " + timeString + - "\ntimeFormat = " + this._defaults.timeFormat + - "\ndateFormat = " + dp_dateFormat); - return false; - } - return true; - } else { - var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); - if (!timeObj) { - return false; - } - $.extend(this, timeObj); - return true; - } - }, - - /* - * generate and inject html for timepicker into ui datepicker - */ - _injectTimePicker: function () { - var $dp = this.inst.dpDiv, - o = this.inst.settings, - tp_inst = this, - litem = '', - uitem = '', - show = null, - max = {}, - gridSize = {}, - size = null, - i = 0, - l = 0; - - // Prevent displaying twice - if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { - var noDisplay = ' style="display:none;"', - html = ' '; - var $tp = $(html); - - // if we only want time picker... - if (o.timeOnly === true) { - $tp.prepend(' '); - $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); - } - - // add sliders, adjust grids, add events - for (i = 0, l = tp_inst.units.length; i < l; i++) { - litem = tp_inst.units[i]; - uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); - show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; - - // add the slider - tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]); - - // adjust the grid and add click event - if (show && o[litem + 'Grid'] > 0) { - size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']); - $tp.find('.ui_tpicker_' + litem + ' table').css({ - width: size + "%", - marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"), - marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0', - borderCollapse: 'collapse' - }).find("td").click(function (e) { - var $t = $(this), - h = $t.html(), - n = parseInt(h.replace(/[^0-9]/g), 10), - ap = h.replace(/[^apm]/ig), - f = $t.data('for'); // loses scope, so we use data-for - - if (f === 'hour') { - if (ap.indexOf('p') !== -1 && n < 12) { - n += 12; - } - else { - if (ap.indexOf('a') !== -1 && n === 12) { - n = 0; - } - } - } - - tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n); - - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }).css({ - cursor: 'pointer', - width: (100 / gridSize[litem]) + '%', - textAlign: 'center', - overflow: 'hidden' - }); - } // end if grid > 0 - } // end for loop - - // Add timezone options - this.timezone_select = $tp.find('.ui_tpicker_timezone').append('').find("select"); - $.fn.append.apply(this.timezone_select, - $.map(o.timezoneList, function (val, idx) { - return $("").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val); - })); - if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") { - var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1; - if (local_timezone === this.timezone) { - selectLocalTimezone(tp_inst); - } else { - this.timezone_select.val(this.timezone); - } - } else { - if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") { - this.timezone_select.val(o.timezone); - } else { - selectLocalTimezone(tp_inst); - } - } - this.timezone_select.change(function () { - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }); - // End timezone options - - // inject timepicker into datepicker - var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); - if ($buttonPanel.length) { - $buttonPanel.before($tp); - } else { - $dp.append($tp); - } - - this.$timeObj = $tp.find('.ui_tpicker_time'); - - if (this.inst !== null) { - var timeDefined = this.timeDefined; - this._onTimeChange(); - this.timeDefined = timeDefined; - } - - // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/ - if (this._defaults.addSliderAccess) { - var sliderAccessArgs = this._defaults.sliderAccessArgs, - rtl = this._defaults.isRTL; - sliderAccessArgs.isRTL = rtl; - - setTimeout(function () { // fix for inline mode - if ($tp.find('.ui-slider-access').length === 0) { - $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs); - - // fix any grids since sliders are shorter - var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true); - if (sliderAccessWidth) { - $tp.find('table:visible').each(function () { - var $g = $(this), - oldWidth = $g.outerWidth(), - oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''), - newWidth = oldWidth - sliderAccessWidth, - newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%', - css = { width: newWidth, marginRight: 0, marginLeft: 0 }; - css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft; - $g.css(css); - }); - } - } - }, 10); - } - // end slideAccess integration - - tp_inst._limitMinMaxDateTime(this.inst, true); - } - }, - - /* - * This function tries to limit the ability to go outside the - * min/max date range - */ - _limitMinMaxDateTime: function (dp_inst, adjustSliders) { - var o = this._defaults, - dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); - - if (!this._defaults.showTimepicker) { - return; - } // No time so nothing to check here - - if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) { - var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), - minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); - - if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) { - this.hourMinOriginal = o.hourMin; - this.minuteMinOriginal = o.minuteMin; - this.secondMinOriginal = o.secondMin; - this.millisecMinOriginal = o.millisecMin; - this.microsecMinOriginal = o.microsecMin; - } - - if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) { - this._defaults.hourMin = minDateTime.getHours(); - if (this.hour <= this._defaults.hourMin) { - this.hour = this._defaults.hourMin; - this._defaults.minuteMin = minDateTime.getMinutes(); - if (this.minute <= this._defaults.minuteMin) { - this.minute = this._defaults.minuteMin; - this._defaults.secondMin = minDateTime.getSeconds(); - if (this.second <= this._defaults.secondMin) { - this.second = this._defaults.secondMin; - this._defaults.millisecMin = minDateTime.getMilliseconds(); - if (this.millisec <= this._defaults.millisecMin) { - this.millisec = this._defaults.millisecMin; - this._defaults.microsecMin = minDateTime.getMicroseconds(); - } else { - if (this.microsec < this._defaults.microsecMin) { - this.microsec = this._defaults.microsecMin; - } - this._defaults.microsecMin = this.microsecMinOriginal; - } - } else { - this._defaults.millisecMin = this.millisecMinOriginal; - this._defaults.microsecMin = this.microsecMinOriginal; - } - } else { - this._defaults.secondMin = this.secondMinOriginal; - this._defaults.millisecMin = this.millisecMinOriginal; - this._defaults.microsecMin = this.microsecMinOriginal; - } - } else { - this._defaults.minuteMin = this.minuteMinOriginal; - this._defaults.secondMin = this.secondMinOriginal; - this._defaults.millisecMin = this.millisecMinOriginal; - this._defaults.microsecMin = this.microsecMinOriginal; - } - } else { - this._defaults.hourMin = this.hourMinOriginal; - this._defaults.minuteMin = this.minuteMinOriginal; - this._defaults.secondMin = this.secondMinOriginal; - this._defaults.millisecMin = this.millisecMinOriginal; - this._defaults.microsecMin = this.microsecMinOriginal; - } - } - - if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) { - var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), - maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); - - if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) { - this.hourMaxOriginal = o.hourMax; - this.minuteMaxOriginal = o.minuteMax; - this.secondMaxOriginal = o.secondMax; - this.millisecMaxOriginal = o.millisecMax; - this.microsecMaxOriginal = o.microsecMax; - } - - if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) { - this._defaults.hourMax = maxDateTime.getHours(); - if (this.hour >= this._defaults.hourMax) { - this.hour = this._defaults.hourMax; - this._defaults.minuteMax = maxDateTime.getMinutes(); - if (this.minute >= this._defaults.minuteMax) { - this.minute = this._defaults.minuteMax; - this._defaults.secondMax = maxDateTime.getSeconds(); - if (this.second >= this._defaults.secondMax) { - this.second = this._defaults.secondMax; - this._defaults.millisecMax = maxDateTime.getMilliseconds(); - if (this.millisec >= this._defaults.millisecMax) { - this.millisec = this._defaults.millisecMax; - this._defaults.microsecMax = maxDateTime.getMicroseconds(); - } else { - if (this.microsec > this._defaults.microsecMax) { - this.microsec = this._defaults.microsecMax; - } - this._defaults.microsecMax = this.microsecMaxOriginal; - } - } else { - this._defaults.millisecMax = this.millisecMaxOriginal; - this._defaults.microsecMax = this.microsecMaxOriginal; - } - } else { - this._defaults.secondMax = this.secondMaxOriginal; - this._defaults.millisecMax = this.millisecMaxOriginal; - this._defaults.microsecMax = this.microsecMaxOriginal; - } - } else { - this._defaults.minuteMax = this.minuteMaxOriginal; - this._defaults.secondMax = this.secondMaxOriginal; - this._defaults.millisecMax = this.millisecMaxOriginal; - this._defaults.microsecMax = this.microsecMaxOriginal; - } - } else { - this._defaults.hourMax = this.hourMaxOriginal; - this._defaults.minuteMax = this.minuteMaxOriginal; - this._defaults.secondMax = this.secondMaxOriginal; - this._defaults.millisecMax = this.millisecMaxOriginal; - this._defaults.microsecMax = this.microsecMaxOriginal; - } - } - - if (adjustSliders !== undefined && adjustSliders === true) { - var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10), - minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10), - secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10), - millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10), - microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10); - - if (this.hour_slider) { - this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax }); - this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour)); - } - if (this.minute_slider) { - this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax }); - this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute)); - } - if (this.second_slider) { - this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax }); - this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond)); - } - if (this.millisec_slider) { - this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax }); - this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec)); - } - if (this.microsec_slider) { - this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax }); - this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec)); - } - } - - }, - - /* - * when a slider moves, set the internal time... - * on time change is also called when the time is updated in the text field - */ - _onTimeChange: function () { - if (!this._defaults.showTimepicker) { - return; - } - var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false, - minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false, - second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false, - millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false, - microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false, - timezone = (this.timezone_select) ? this.timezone_select.val() : false, - o = this._defaults, - pickerTimeFormat = o.pickerTimeFormat || o.timeFormat, - pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix; - - if (typeof(hour) === 'object') { - hour = false; - } - if (typeof(minute) === 'object') { - minute = false; - } - if (typeof(second) === 'object') { - second = false; - } - if (typeof(millisec) === 'object') { - millisec = false; - } - if (typeof(microsec) === 'object') { - microsec = false; - } - if (typeof(timezone) === 'object') { - timezone = false; - } - - if (hour !== false) { - hour = parseInt(hour, 10); - } - if (minute !== false) { - minute = parseInt(minute, 10); - } - if (second !== false) { - second = parseInt(second, 10); - } - if (millisec !== false) { - millisec = parseInt(millisec, 10); - } - if (microsec !== false) { - microsec = parseInt(microsec, 10); - } - - var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0]; - - // If the update was done in the input field, the input field should not be updated. - // If the update was done using the sliders, update the input field. - var hasChanged = (hour !== this.hour || minute !== this.minute || second !== this.second || millisec !== this.millisec || microsec !== this.microsec || - (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || (this.timezone !== null && timezone !== this.timezone)); - - if (hasChanged) { - - if (hour !== false) { - this.hour = hour; - } - if (minute !== false) { - this.minute = minute; - } - if (second !== false) { - this.second = second; - } - if (millisec !== false) { - this.millisec = millisec; - } - if (microsec !== false) { - this.microsec = microsec; - } - if (timezone !== false) { - this.timezone = timezone; - } - - if (!this.inst) { - this.inst = $.datepicker._getInst(this.$input[0]); - } - - this._limitMinMaxDateTime(this.inst, true); - } - if (this.support.ampm) { - this.ampm = ampm; - } - - // Updates the time within the timepicker - this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o); - if (this.$timeObj) { - if (pickerTimeFormat === o.timeFormat) { - this.$timeObj.text(this.formattedTime + pickerTimeSuffix); - } - else { - this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix); - } - } - - this.timeDefined = true; - if (hasChanged) { - this._updateDateTime(); - } - }, - - /* - * call custom onSelect. - * bind to sliders slidestop, and grid click. - */ - _onSelectHandler: function () { - var onSelect = this._defaults.onSelect || this.inst.settings.onSelect; - var inputEl = this.$input ? this.$input[0] : null; - if (onSelect && inputEl) { - onSelect.apply(inputEl, [this.formattedDateTime, this]); - } - }, - - /* - * update our input with the new date time.. - */ - _updateDateTime: function (dp_inst) { - dp_inst = this.inst || dp_inst; - var dtTmp = (dp_inst.currentYear > 0? - new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : - new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), - dt = $.datepicker._daylightSavingAdjust(dtTmp), - //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), - //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)), - dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), - formatCfg = $.datepicker._getFormatConfig(dp_inst), - timeAvailable = dt !== null && this.timeDefined; - this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); - var formattedDateTime = this.formattedDate; - - // if a slider was changed but datepicker doesn't have a value yet, set it - if (dp_inst.lastVa === "") { - dp_inst.currentYear = dp_inst.selectedYear; - dp_inst.currentMonth = dp_inst.selectedMonth; - dp_inst.currentDay = dp_inst.selectedDay; - } - - /* - * remove following lines to force every changes in date picker to change the input value - * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. - * If the user manually empty the value in the input field, the date picker will never change selected value. - */ - //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) { - // return; - //} - - if (this._defaults.timeOnly === true) { - formattedDateTime = this.formattedTime; - } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { - formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; - } - - this.formattedDateTime = formattedDateTime; - - if (!this._defaults.showTimepicker) { - this.$input.val(this.formattedDate); - } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) { - this.$altInput.val(this.formattedTime); - this.$input.val(this.formattedDate); - } else if (this.$altInput) { - this.$input.val(formattedDateTime); - var altFormattedDateTime = '', - altSeparator = this._defaults.altSeparator ? this._defaults.altSeparator : this._defaults.separator, - altTimeSuffix = this._defaults.altTimeSuffix ? this._defaults.altTimeSuffix : this._defaults.timeSuffix; - - if (!this._defaults.timeOnly) { - if (this._defaults.altFormat) { - altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg); - } - else { - altFormattedDateTime = this.formattedDate; - } - - if (altFormattedDateTime) { - altFormattedDateTime += altSeparator; - } - } - - if (this._defaults.altTimeFormat) { - altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix; - } - else { - altFormattedDateTime += this.formattedTime + altTimeSuffix; - } - this.$altInput.val(altFormattedDateTime); - } else { - this.$input.val(formattedDateTime); - } - - this.$input.trigger("change"); - }, - - _onFocus: function () { - if (!this.$input.val() && this._defaults.defaultValue) { - this.$input.val(this._defaults.defaultValue); - var inst = $.datepicker._getInst(this.$input.get(0)), - tp_inst = $.datepicker._get(inst, 'timepicker'); - if (tp_inst) { - if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { - try { - $.datepicker._updateDatepicker(inst); - } catch (err) { - $.timepicker.log(err); - } - } - } - } - }, - - /* - * Small abstraction to control types - * We can add more, just be sure to follow the pattern: create, options, value - */ - _controls: { - // slider methods - slider: { - create: function (tp_inst, obj, unit, val, min, max, step) { - var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60 - return obj.prop('slide', null).slider({ - orientation: "horizontal", - value: rtl ? val * -1 : val, - min: rtl ? max * -1 : min, - max: rtl ? min * -1 : max, - step: step, - slide: function (event, ui) { - tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value); - tp_inst._onTimeChange(); - }, - stop: function (event, ui) { - tp_inst._onSelectHandler(); - } - }); - }, - options: function (tp_inst, obj, unit, opts, val) { - if (tp_inst._defaults.isRTL) { - if (typeof(opts) === 'string') { - if (opts === 'min' || opts === 'max') { - if (val !== undefined) { - return obj.slider(opts, val * -1); - } - return Math.abs(obj.slider(opts)); - } - return obj.slider(opts); - } - var min = opts.min, - max = opts.max; - opts.min = opts.max = null; - if (min !== undefined) { - opts.max = min * -1; - } - if (max !== undefined) { - opts.min = max * -1; - } - return obj.slider(opts); - } - if (typeof(opts) === 'string' && val !== undefined) { - return obj.slider(opts, val); - } - return obj.slider(opts); - }, - value: function (tp_inst, obj, unit, val) { - if (tp_inst._defaults.isRTL) { - if (val !== undefined) { - return obj.slider('value', val * -1); - } - return Math.abs(obj.slider('value')); - } - if (val !== undefined) { - return obj.slider('value', val); - } - return obj.slider('value'); - } - }, - // select methods - select: { - create: function (tp_inst, obj, unit, val, min, max, step) { - var sel = ''; - - obj.children('select').remove(); - - $(sel).appendTo(obj).change(function (e) { - tp_inst._onTimeChange(); - tp_inst._onSelectHandler(); - }); - - return obj; - }, - options: function (tp_inst, obj, unit, opts, val) { - var o = {}, - $t = obj.children('select'); - if (typeof(opts) === 'string') { - if (val === undefined) { - return $t.data(opts); - } - o[opts] = val; - } - else { o = opts; } - return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min || $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step')); - }, - value: function (tp_inst, obj, unit, val) { - var $t = obj.children('select'); - if (val !== undefined) { - return $t.val(val); - } - return $t.val(); - } - } - } // end _controls - - }); - - $.fn.extend({ - /* - * shorthand just to use timepicker. - */ - timepicker: function (o) { - o = o || {}; - var tmp_args = Array.prototype.slice.call(arguments); - - if (typeof o === 'object') { - tmp_args[0] = $.extend(o, { - timeOnly: true - }); - } - - return $(this).each(function () { - $.fn.datetimepicker.apply($(this), tmp_args); - }); - }, - - /* - * extend timepicker to datepicker - */ - datetimepicker: function (o) { - o = o || {}; - var tmp_args = arguments; - - if (typeof(o) === 'string') { - if (o === 'getDate') { - return $.fn.datepicker.apply($(this[0]), tmp_args); - } else { - return this.each(function () { - var $t = $(this); - $t.datepicker.apply($t, tmp_args); - }); - } - } else { - return this.each(function () { - var $t = $(this); - $t.datepicker($.timepicker._newInst($t, o)._defaults); - }); - } - } - }); - - /* - * Public Utility to parse date and time - */ - $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { - var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings); - if (parseRes.timeObj) { - var t = parseRes.timeObj; - parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec); - parseRes.date.setMicroseconds(t.microsec); - } - - return parseRes.date; - }; - - /* - * Public utility to parse time - */ - $.datepicker.parseTime = function (timeFormat, timeString, options) { - var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}), - iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1); - - // Strict parse requires the timeString to match the timeFormat exactly - var strictParse = function (f, s, o) { - - // pattern for standard and localized AM/PM markers - var getPatternAmpm = function (amNames, pmNames) { - var markers = []; - if (amNames) { - $.merge(markers, amNames); - } - if (pmNames) { - $.merge(markers, pmNames); - } - markers = $.map(markers, function (val) { - return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&'); - }); - return '(' + markers.join('|') + ')?'; - }; - - // figure out position of time elements.. cause js cant do named captures - var getFormatPositions = function (timeFormat) { - var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g), - orders = { - h: -1, - m: -1, - s: -1, - l: -1, - c: -1, - t: -1, - z: -1 - }; - - if (finds) { - for (var i = 0; i < finds.length; i++) { - if (orders[finds[i].toString().charAt(0)] === -1) { - orders[finds[i].toString().charAt(0)] = i + 1; - } - } - } - return orders; - }; - - var regstr = '^' + f.toString() - .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { - var ml = match.length; - switch (match.charAt(0).toLowerCase()) { - case 'h': - return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; - case 'm': - return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; - case 's': - return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; - case 'l': - return '(\\d?\\d?\\d)'; - case 'c': - return '(\\d?\\d?\\d)'; - case 'z': - return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?'; - case 't': - return getPatternAmpm(o.amNames, o.pmNames); - default: // literal escaped in quotes - return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?'; - } - }) - .replace(/\s/g, '\\s?') + - o.timeSuffix + '$', - order = getFormatPositions(f), - ampm = '', - treg; - - treg = s.match(new RegExp(regstr, 'i')); - - var resTime = { - hour: 0, - minute: 0, - second: 0, - millisec: 0, - microsec: 0 - }; - - if (treg) { - if (order.t !== -1) { - if (treg[order.t] === undefined || treg[order.t].length === 0) { - ampm = ''; - resTime.ampm = ''; - } else { - ampm = $.inArray(treg[order.t].toUpperCase(), o.amNames) !== -1 ? 'AM' : 'PM'; - resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0]; - } - } - - if (order.h !== -1) { - if (ampm === 'AM' && treg[order.h] === '12') { - resTime.hour = 0; // 12am = 0 hour - } else { - if (ampm === 'PM' && treg[order.h] !== '12') { - resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12 - } else { - resTime.hour = Number(treg[order.h]); - } - } - } - - if (order.m !== -1) { - resTime.minute = Number(treg[order.m]); - } - if (order.s !== -1) { - resTime.second = Number(treg[order.s]); - } - if (order.l !== -1) { - resTime.millisec = Number(treg[order.l]); - } - if (order.c !== -1) { - resTime.microsec = Number(treg[order.c]); - } - if (order.z !== -1 && treg[order.z] !== undefined) { - resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]); - } - - - return resTime; - } - return false; - };// end strictParse - - // First try JS Date, if that fails, use strictParse - var looseParse = function (f, s, o) { - try { - var d = new Date('2012-01-01 ' + s); - if (isNaN(d.getTime())) { - d = new Date('2012-01-01T' + s); - if (isNaN(d.getTime())) { - d = new Date('01/01/2012 ' + s); - if (isNaN(d.getTime())) { - throw "Unable to parse time with native Date: " + s; - } - } - } - - return { - hour: d.getHours(), - minute: d.getMinutes(), - second: d.getSeconds(), - millisec: d.getMilliseconds(), - microsec: d.getMicroseconds(), - timezone: d.getTimezoneOffset() * -1 - }; - } - catch (err) { - try { - return strictParse(f, s, o); - } - catch (err2) { - $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f); - } - } - return false; - }; // end looseParse - - if (typeof o.parse === "function") { - return o.parse(timeFormat, timeString, o); - } - if (o.parse === 'loose') { - return looseParse(timeFormat, timeString, o); - } - return strictParse(timeFormat, timeString, o); - }; - - /** - * Public utility to format the time - * @param {string} format format of the time - * @param {Object} time Object not a Date for timezones - * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm - * @returns {string} the formatted time - */ - $.datepicker.formatTime = function (format, time, options) { - options = options || {}; - options = $.extend({}, $.timepicker._defaults, options); - time = $.extend({ - hour: 0, - minute: 0, - second: 0, - millisec: 0, - microsec: 0, - timezone: null - }, time); - - var tmptime = format, - ampmName = options.amNames[0], - hour = parseInt(time.hour, 10); - - if (hour > 11) { - ampmName = options.pmNames[0]; - } - - tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { - switch (match) { - case 'HH': - return ('0' + hour).slice(-2); - case 'H': - return hour; - case 'hh': - return ('0' + convert24to12(hour)).slice(-2); - case 'h': - return convert24to12(hour); - case 'mm': - return ('0' + time.minute).slice(-2); - case 'm': - return time.minute; - case 'ss': - return ('0' + time.second).slice(-2); - case 's': - return time.second; - case 'l': - return ('00' + time.millisec).slice(-3); - case 'c': - return ('00' + time.microsec).slice(-3); - case 'z': - return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false); - case 'Z': - return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true); - case 'T': - return ampmName.charAt(0).toUpperCase(); - case 'TT': - return ampmName.toUpperCase(); - case 't': - return ampmName.charAt(0).toLowerCase(); - case 'tt': - return ampmName.toLowerCase(); - default: - return match.replace(/'/g, ""); - } - }); - - return tmptime; - }; - - /* - * the bad hack :/ override datepicker so it doesn't close on select - // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 - */ - $.datepicker._base_selectDate = $.datepicker._selectDate; - $.datepicker._selectDate = function (id, dateStr) { - var inst = this._getInst($(id)[0]), - tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - tp_inst._limitMinMaxDateTime(inst, true); - inst.inline = inst.stay_open = true; - //This way the onSelect handler called from calendarpicker get the full dateTime - this._base_selectDate(id, dateStr); - inst.inline = inst.stay_open = false; - this._notifyChange(inst); - this._updateDatepicker(inst); - } else { - this._base_selectDate(id, dateStr); - } - }; - - /* - * second bad hack :/ override datepicker so it triggers an event when changing the input field - * and does not redraw the datepicker on every selectDate event - */ - $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; - $.datepicker._updateDatepicker = function (inst) { - - // don't popup the datepicker if there is another instance already opened - var input = inst.input[0]; - if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) { - return; - } - - if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { - - this._base_updateDatepicker(inst); - - // Reload the time control when changing something in the input text field. - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - tp_inst._addTimePicker(inst); - } - } - }; - - /* - * third bad hack :/ override datepicker so it allows spaces and colon in the input field - */ - $.datepicker._base_doKeyPress = $.datepicker._doKeyPress; - $.datepicker._doKeyPress = function (event) { - var inst = $.datepicker._getInst(event.target), - tp_inst = $.datepicker._get(inst, 'timepicker'); - - if (tp_inst) { - if ($.datepicker._get(inst, 'constrainInput')) { - var ampm = tp_inst.support.ampm, - tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone, - dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), - datetimeChars = tp_inst._defaults.timeFormat.toString() - .replace(/[hms]/g, '') - .replace(/TT/g, ampm ? 'APM' : '') - .replace(/Tt/g, ampm ? 'AaPpMm' : '') - .replace(/tT/g, ampm ? 'AaPpMm' : '') - .replace(/T/g, ampm ? 'AP' : '') - .replace(/tt/g, ampm ? 'apm' : '') - .replace(/t/g, ampm ? 'ap' : '') + - " " + tp_inst._defaults.separator + - tp_inst._defaults.timeSuffix + - (tz ? tp_inst._defaults.timezoneList.join('') : '') + - (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + - dateChars, - chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); - return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); - } - } - - return $.datepicker._base_doKeyPress(event); - }; - - /* - * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField - * Update any alternate field to synchronise with the main field. - */ - $.datepicker._base_updateAlternate = $.datepicker._updateAlternate; - $.datepicker._updateAlternate = function (inst) { - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - var altField = tp_inst._defaults.altField; - if (altField) { // update alternate field too - var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat, - date = this._getDate(inst), - formatCfg = $.datepicker._getFormatConfig(inst), - altFormattedDateTime = '', - altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, - altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix, - altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat; - - altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix; - if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) { - if (tp_inst._defaults.altFormat) { - altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime; - } - else { - altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime; - } - } - $(altField).val(altFormattedDateTime); - } - } - else { - $.datepicker._base_updateAlternate(inst); - } - }; - - /* - * Override key up event to sync manual input changes. - */ - $.datepicker._base_doKeyUp = $.datepicker._doKeyUp; - $.datepicker._doKeyUp = function (event) { - var inst = $.datepicker._getInst(event.target), - tp_inst = $.datepicker._get(inst, 'timepicker'); - - if (tp_inst) { - if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { - try { - $.datepicker._updateDatepicker(inst); - } catch (err) { - $.timepicker.log(err); - } - } - } - - return $.datepicker._base_doKeyUp(event); - }; - - /* - * override "Today" button to also grab the time. - */ - $.datepicker._base_gotoToday = $.datepicker._gotoToday; - $.datepicker._gotoToday = function (id) { - var inst = this._getInst($(id)[0]), - $dp = inst.dpDiv; - this._base_gotoToday(id); - var tp_inst = this._get(inst, 'timepicker'); - selectLocalTimezone(tp_inst); - var now = new Date(); - this._setTime(inst, now); - $('.ui-datepicker-today', $dp).click(); - }; - - /* - * Disable & enable the Time in the datetimepicker - */ - $.datepicker._disableTimepickerDatepicker = function (target) { - var inst = this._getInst(target); - if (!inst) { - return; - } - - var tp_inst = this._get(inst, 'timepicker'); - $(target).datepicker('getDate'); // Init selected[Year|Month|Day] - if (tp_inst) { - inst.settings.showTimepicker = false; - tp_inst._defaults.showTimepicker = false; - tp_inst._updateDateTime(inst); - } - }; - - $.datepicker._enableTimepickerDatepicker = function (target) { - var inst = this._getInst(target); - if (!inst) { - return; - } - - var tp_inst = this._get(inst, 'timepicker'); - $(target).datepicker('getDate'); // Init selected[Year|Month|Day] - if (tp_inst) { - inst.settings.showTimepicker = true; - tp_inst._defaults.showTimepicker = true; - tp_inst._addTimePicker(inst); // Could be disabled on page load - tp_inst._updateDateTime(inst); - } - }; - - /* - * Create our own set time function - */ - $.datepicker._setTime = function (inst, date) { - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - var defaults = tp_inst._defaults; - - // calling _setTime with no date sets time to defaults - tp_inst.hour = date ? date.getHours() : defaults.hour; - tp_inst.minute = date ? date.getMinutes() : defaults.minute; - tp_inst.second = date ? date.getSeconds() : defaults.second; - tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec; - tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec; - - //check if within min/max times.. - tp_inst._limitMinMaxDateTime(inst, true); - - tp_inst._onTimeChange(); - tp_inst._updateDateTime(inst); - } - }; - - /* - * Create new public method to set only time, callable as $().datepicker('setTime', date) - */ - $.datepicker._setTimeDatepicker = function (target, date, withDate) { - var inst = this._getInst(target); - if (!inst) { - return; - } - - var tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - this._setDateFromField(inst); - var tp_date; - if (date) { - if (typeof date === "string") { - tp_inst._parseTime(date, withDate); - tp_date = new Date(); - tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); - tp_date.setMicroseconds(tp_inst.microsec); - } else { - tp_date = new Date(date.getTime()); - tp_date.setMicroseconds(date.getMicroseconds()); - } - if (tp_date.toString() === 'Invalid Date') { - tp_date = undefined; - } - this._setTime(inst, tp_date); - } - } - - }; - - /* - * override setDate() to allow setting time too within Date object - */ - $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; - $.datepicker._setDateDatepicker = function (target, date) { - var inst = this._getInst(target); - if (!inst) { - return; - } - - if (typeof(date) === 'string') { - date = new Date(date); - if (!date.getTime()) { - $.timepicker.log("Error creating Date object from string."); - } - } - - var tp_inst = this._get(inst, 'timepicker'); - var tp_date; - if (date instanceof Date) { - tp_date = new Date(date.getTime()); - tp_date.setMicroseconds(date.getMicroseconds()); - } else { - tp_date = date; - } - - // This is important if you are using the timezone option, javascript's Date - // object will only return the timezone offset for the current locale, so we - // adjust it accordingly. If not using timezone option this won't matter.. - // If a timezone is different in tp, keep the timezone as is - if (tp_inst) { - // look out for DST if tz wasn't specified - if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { - tp_inst.timezone = tp_date.getTimezoneOffset() * -1; - } - date = $.timepicker.timezoneAdjust(date, tp_inst.timezone); - tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone); - } - - this._updateDatepicker(inst); - this._base_setDateDatepicker.apply(this, arguments); - this._setTimeDatepicker(target, tp_date, true); - }; - - /* - * override getDate() to allow getting time too within Date object - */ - $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; - $.datepicker._getDateDatepicker = function (target, noDefault) { - var inst = this._getInst(target); - if (!inst) { - return; - } - - var tp_inst = this._get(inst, 'timepicker'); - - if (tp_inst) { - // if it hasn't yet been defined, grab from field - if (inst.lastVal === undefined) { - this._setDateFromField(inst, noDefault); - } - - var date = this._getDate(inst); - if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) { - date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); - date.setMicroseconds(tp_inst.microsec); - - // This is important if you are using the timezone option, javascript's Date - // object will only return the timezone offset for the current locale, so we - // adjust it accordingly. If not using timezone option this won't matter.. - if (tp_inst.timezone != null) { - // look out for DST if tz wasn't specified - if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { - tp_inst.timezone = date.getTimezoneOffset() * -1; - } - date = $.timepicker.timezoneAdjust(date, tp_inst.timezone); - } - } - return date; - } - return this._base_getDateDatepicker(target, noDefault); - }; - - /* - * override parseDate() because UI 1.8.14 throws an error about "Extra characters" - * An option in datapicker to ignore extra format characters would be nicer. - */ - $.datepicker._base_parseDate = $.datepicker.parseDate; - $.datepicker.parseDate = function (format, value, settings) { - var date; - try { - date = this._base_parseDate(format, value, settings); - } catch (err) { - // Hack! The error message ends with a colon, a space, and - // the "extra" characters. We rely on that instead of - // attempting to perfectly reproduce the parsing algorithm. - if (err.indexOf(":") >= 0) { - date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings); - $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format); - } else { - throw err; - } - } - return date; - }; - - /* - * override formatDate to set date with time to the input - */ - $.datepicker._base_formatDate = $.datepicker._formatDate; - $.datepicker._formatDate = function (inst, day, month, year) { - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - tp_inst._updateDateTime(inst); - return tp_inst.$input.val(); - } - return this._base_formatDate(inst); - }; - - /* - * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate - */ - $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; - $.datepicker._optionDatepicker = function (target, name, value) { - var inst = this._getInst(target), - name_clone; - if (!inst) { - return null; - } - - var tp_inst = this._get(inst, 'timepicker'); - if (tp_inst) { - var min = null, - max = null, - onselect = null, - overrides = tp_inst._defaults.evnts, - fns = {}, - prop; - if (typeof name === 'string') { // if min/max was set with the string - if (name === 'minDate' || name === 'minDateTime') { - min = value; - } else if (name === 'maxDate' || name === 'maxDateTime') { - max = value; - } else if (name === 'onSelect') { - onselect = value; - } else if (overrides.hasOwnProperty(name)) { - if (typeof (value) === 'undefined') { - return overrides[name]; - } - fns[name] = value; - name_clone = {}; //empty results in exiting function after overrides updated - } - } else if (typeof name === 'object') { //if min/max was set with the JSON - if (name.minDate) { - min = name.minDate; - } else if (name.minDateTime) { - min = name.minDateTime; - } else if (name.maxDate) { - max = name.maxDate; - } else if (name.maxDateTime) { - max = name.maxDateTime; - } - for (prop in overrides) { - if (overrides.hasOwnProperty(prop) && name[prop]) { - fns[prop] = name[prop]; - } - } - } - for (prop in fns) { - if (fns.hasOwnProperty(prop)) { - overrides[prop] = fns[prop]; - if (!name_clone) { name_clone = $.extend({}, name); } - delete name_clone[prop]; - } - } - if (name_clone && isEmptyObject(name_clone)) { return; } - if (min) { //if min was set - if (min === 0) { - min = new Date(); - } else { - min = new Date(min); - } - tp_inst._defaults.minDate = min; - tp_inst._defaults.minDateTime = min; - } else if (max) { //if max was set - if (max === 0) { - max = new Date(); - } else { - max = new Date(max); - } - tp_inst._defaults.maxDate = max; - tp_inst._defaults.maxDateTime = max; - } else if (onselect) { - tp_inst._defaults.onSelect = onselect; - } - } - if (value === undefined) { - return this._base_optionDatepicker.call($.datepicker, target, name); - } - return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value); - }; - - /* - * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype, - * it will return false for all objects - */ - var isEmptyObject = function (obj) { - var prop; - for (prop in obj) { - if (obj.hasOwnProperty(prop)) { - return false; - } - } - return true; - }; - - /* - * jQuery extend now ignores nulls! - */ - var extendRemove = function (target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] === null || props[name] === undefined) { - target[name] = props[name]; - } - } - return target; - }; - - /* - * Determine by the time format which units are supported - * Returns an object of booleans for each unit - */ - var detectSupport = function (timeFormat) { - var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals - isIn = function (f, t) { // does the format contain the token? - return f.indexOf(t) !== -1 ? true : false; - }; - return { - hour: isIn(tf, 'h'), - minute: isIn(tf, 'm'), - second: isIn(tf, 's'), - millisec: isIn(tf, 'l'), - microsec: isIn(tf, 'c'), - timezone: isIn(tf, 'z'), - ampm: isIn(tf, 't') && isIn(timeFormat, 'h'), - iso8601: isIn(timeFormat, 'Z') - }; - }; - - /* - * Converts 24 hour format into 12 hour - * Returns 12 hour without leading 0 - */ - var convert24to12 = function (hour) { - hour %= 12; - - if (hour === 0) { - hour = 12; - } - - return String(hour); - }; - - var computeEffectiveSetting = function (settings, property) { - return settings && settings[property] ? settings[property] : $.timepicker._defaults[property]; - }; - - /* - * Splits datetime string into date and time substrings. - * Throws exception when date can't be parsed - * Returns {dateString: dateString, timeString: timeString} - */ - var splitDateTime = function (dateTimeString, timeSettings) { - // The idea is to get the number separator occurrences in datetime and the time format requested (since time has - // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split. - var separator = computeEffectiveSetting(timeSettings, 'separator'), - format = computeEffectiveSetting(timeSettings, 'timeFormat'), - timeParts = format.split(separator), // how many occurrences of separator may be in our format? - timePartsLen = timeParts.length, - allParts = dateTimeString.split(separator), - allPartsLen = allParts.length; - - if (allPartsLen > 1) { - return { - dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator), - timeString: allParts.splice(0, timePartsLen).join(separator) - }; - } - - return { - dateString: dateTimeString, - timeString: '' - }; - }; - - /* - * Internal function to parse datetime interval - * Returns: {date: Date, timeObj: Object}, where - * date - parsed date without time (type Date) - * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional - */ - var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { - var date, - parts, - parsedTime; - - parts = splitDateTime(dateTimeString, timeSettings); - date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings); - - if (parts.timeString === '') { - return { - date: date - }; - } - - parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings); - - if (!parsedTime) { - throw 'Wrong time format'; - } - - return { - date: date, - timeObj: parsedTime - }; - }; - - /* - * Internal function to set timezone_select to the local timezone - */ - var selectLocalTimezone = function (tp_inst, date) { - if (tp_inst && tp_inst.timezone_select) { - var now = date || new Date(); - tp_inst.timezone_select.val(-now.getTimezoneOffset()); - } - }; - - /* - * Create a Singleton Instance - */ - $.timepicker = new Timepicker(); - - /** - * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5) - * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned - * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45" - * @return {string} - */ - $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) { - if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) { - return tzMinutes; - } - - var off = tzMinutes, - minutes = off % 60, - hours = (off - minutes) / 60, - iso = iso8601 ? ':' : '', - tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2); - - if (tz === '+00:00') { - return 'Z'; - } - return tz; - }; - - /** - * Get the number in minutes that represents a timezone string - * @param {string} tzString formatted like "+0500", "-1245", "Z" - * @return {number} the offset minutes or the original string if it doesn't match expectations - */ - $.timepicker.timezoneOffsetNumber = function (tzString) { - var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245" - - if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset - return 0; - } - - if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back - return tzString; - } - - return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus - ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes) - parseInt(normalized.substr(3, 2), 10))); // minutes - }; - - /** - * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate) - * @param {Date} date - * @param {string} toTimezone formatted like "+0500", "-1245" - * @return {Date} - */ - $.timepicker.timezoneAdjust = function (date, toTimezone) { - var toTz = $.timepicker.timezoneOffsetNumber(toTimezone); - if (!isNaN(toTz)) { - date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz); - } - return date; - }; - - /** - * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to - * enforce date range limits. - * n.b. The input value must be correctly formatted (reformatting is not supported) - * @param {Element} startTime - * @param {Element} endTime - * @param {Object} options Options for the timepicker() call - * @return {jQuery} - */ - $.timepicker.timeRange = function (startTime, endTime, options) { - return $.timepicker.handleRange('timepicker', startTime, endTime, options); - }; - - /** - * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to - * enforce date range limits. - * @param {Element} startTime - * @param {Element} endTime - * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, - * a boolean value that can be used to reformat the input values to the `dateFormat`. - * @param {string} method Can be used to specify the type of picker to be added - * @return {jQuery} - */ - $.timepicker.datetimeRange = function (startTime, endTime, options) { - $.timepicker.handleRange('datetimepicker', startTime, endTime, options); - }; - - /** - * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to - * enforce date range limits. - * @param {Element} startTime - * @param {Element} endTime - * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, - * a boolean value that can be used to reformat the input values to the `dateFormat`. - * @return {jQuery} - */ - $.timepicker.dateRange = function (startTime, endTime, options) { - $.timepicker.handleRange('datepicker', startTime, endTime, options); - }; - - /** - * Calls `method` on the `startTime` and `endTime` elements, and configures them to - * enforce date range limits. - * @param {string} method Can be used to specify the type of picker to be added - * @param {Element} startTime - * @param {Element} endTime - * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, - * a boolean value that can be used to reformat the input values to the `dateFormat`. - * @return {jQuery} - */ - $.timepicker.handleRange = function (method, startTime, endTime, options) { - options = $.extend({}, { - minInterval: 0, // min allowed interval in milliseconds - maxInterval: 0, // max allowed interval in milliseconds - start: {}, // options for start picker - end: {} // options for end picker - }, options); - - function checkDates(changed, other) { - var startdt = startTime[method]('getDate'), - enddt = endTime[method]('getDate'), - changeddt = changed[method]('getDate'); - - if (startdt !== null) { - var minDate = new Date(startdt.getTime()), - maxDate = new Date(startdt.getTime()); - - minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval); - maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval); - - if (options.minInterval > 0 && minDate > enddt) { // minInterval check - endTime[method]('setDate', minDate); - } - else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check - endTime[method]('setDate', maxDate); - } - else if (startdt > enddt) { - other[method]('setDate', changeddt); - } - } - } - - function selected(changed, other, option) { - if (!changed.val()) { - return; - } - var date = changed[method].call(changed, 'getDate'); - if (date !== null && options.minInterval > 0) { - if (option === 'minDate') { - date.setMilliseconds(date.getMilliseconds() + options.minInterval); - } - if (option === 'maxDate') { - date.setMilliseconds(date.getMilliseconds() - options.minInterval); - } - } - if (date.getTime) { - other[method].call(other, 'option', option, date); - } - } - - $.fn[method].call(startTime, $.extend({ - onClose: function (dateText, inst) { - checkDates($(this), endTime); - }, - onSelect: function (selectedDateTime) { - selected($(this), endTime, 'minDate'); - } - }, options, options.start)); - $.fn[method].call(endTime, $.extend({ - onClose: function (dateText, inst) { - checkDates($(this), startTime); - }, - onSelect: function (selectedDateTime) { - selected($(this), startTime, 'maxDate'); - } - }, options, options.end)); - - checkDates(startTime, endTime); - selected(startTime, endTime, 'minDate'); - selected(endTime, startTime, 'maxDate'); - return $([startTime.get(0), endTime.get(0)]); - }; - - /** - * Log error or data to the console during error or debugging - * @param {Object} err pass any type object to log to the console during error or debugging - * @return {void} - */ - $.timepicker.log = function (err) { - if (window.console) { - window.console.log(err); - } - }; - - /* - * Add util object to allow access to private methods for testability. - */ - $.timepicker._util = { - _extendRemove: extendRemove, - _isEmptyObject: isEmptyObject, - _convert24to12: convert24to12, - _detectSupport: detectSupport, - _selectLocalTimezone: selectLocalTimezone, - _computeEffectiveSetting: computeEffectiveSetting, - _splitDateTime: splitDateTime, - _parseDateTimeInternal: parseDateTimeInternal - }; - - /* - * Microsecond support - */ - if (!Date.prototype.getMicroseconds) { - Date.prototype.microseconds = 0; - Date.prototype.getMicroseconds = function () { return this.microseconds; }; - Date.prototype.setMicroseconds = function (m) { - this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000)); - this.microseconds = m % 1000; - return this; - }; - } - - /* - * Keep up with the version - */ - $.timepicker.version = "1.4"; - -})(jQuery); +!function($){var Timepicker,isEmptyObject,extendRemove,detectSupport,convert24to12,computeEffectiveSetting,splitDateTime,parseDateTimeInternal,selectLocalTimezone;$.ui.timepicker=$.ui.timepicker||{},$.ui.timepicker.version||($.extend($.ui,{timepicker:{version:"1.4"}}),Timepicker=function(){this.regional=[],this.regional[""]={currentText:"Now",closeText:"Done",amNames:["AM","A"],pmNames:["PM","P"],timeFormat:"HH:mm",timeSuffix:"",timeOnlyTitle:"Choose Time",timeText:"Time",hourText:"Hour",minuteText:"Minute",secondText:"Second",millisecText:"Millisecond",microsecText:"Microsecond",timezoneText:"Time Zone",isRTL:!1},this._defaults={showButtonPanel:!0,timeOnly:!1,showHour:null,showMinute:null,showSecond:null,showMillisec:null,showMicrosec:null,showTimezone:null,showTime:!0,stepHour:1,stepMinute:1,stepSecond:1,stepMillisec:1,stepMicrosec:1,hour:0,minute:0,second:0,millisec:0,microsec:0,timezone:null,hourMin:0,minuteMin:0,secondMin:0,millisecMin:0,microsecMin:0,hourMax:23,minuteMax:59,secondMax:59,millisecMax:999,microsecMax:999,minDateTime:null,maxDateTime:null,onSelect:null,hourGrid:0,minuteGrid:0,secondGrid:0,millisecGrid:0,microsecGrid:0,alwaysSetTime:!0,separator:" ",altFieldTimeOnly:!0,altTimeFormat:null,altSeparator:null,altTimeSuffix:null,pickerTimeFormat:null,pickerTimeSuffix:null,showTimepicker:!0,timezoneList:null,addSliderAccess:!1,sliderAccessArgs:null,controlType:"slider",defaultValue:null,parse:"strict"},$.extend(this._defaults,this.regional[""])},$.extend(Timepicker.prototype,{$input:null,$altInput:null,$timeObj:null,inst:null,hour_slider:null,minute_slider:null,second_slider:null,millisec_slider:null,microsec_slider:null,timezone_select:null,hour:0,minute:0,second:0,millisec:0,microsec:0,timezone:null,hourMinOriginal:null,minuteMinOriginal:null,secondMinOriginal:null,millisecMinOriginal:null,microsecMinOriginal:null,hourMaxOriginal:null,minuteMaxOriginal:null,secondMaxOriginal:null,millisecMaxOriginal:null,microsecMaxOriginal:null,ampm:"",formattedDate:"",formattedTime:"",formattedDateTime:"",timezoneList:null,units:["hour","minute","second","millisec","microsec"],support:{},control:null,setDefaults:function(e){return extendRemove(this._defaults,e||{}),this},_newInst:function($input,opts){var tp_inst=new Timepicker,inlineSettings={},fns={},overrides,i;for(var attrName in this._defaults)if(this._defaults.hasOwnProperty(attrName)){var attrValue=$input.attr("time:"+attrName);if(attrValue)try{inlineSettings[attrName]=eval(attrValue)}catch(e){inlineSettings[attrName]=attrValue}}for(i in overrides={beforeShow:function(e,t){if($.isFunction(tp_inst._defaults.evnts.beforeShow))return tp_inst._defaults.evnts.beforeShow.call($input[0],e,t,tp_inst)},onChangeMonthYear:function(e,t,i){tp_inst._updateDateTime(i),$.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)&&tp_inst._defaults.evnts.onChangeMonthYear.call($input[0],e,t,i,tp_inst)},onClose:function(e,t){!0===tp_inst.timeDefined&&""!==$input.val()&&tp_inst._updateDateTime(t),$.isFunction(tp_inst._defaults.evnts.onClose)&&tp_inst._defaults.evnts.onClose.call($input[0],e,t,tp_inst)}},overrides)overrides.hasOwnProperty(i)&&(fns[i]=opts[i]||null);tp_inst._defaults=$.extend({},this._defaults,inlineSettings,opts,overrides,{evnts:fns,timepicker:tp_inst}),tp_inst.amNames=$.map(tp_inst._defaults.amNames,function(e){return e.toUpperCase()}),tp_inst.pmNames=$.map(tp_inst._defaults.pmNames,function(e){return e.toUpperCase()}),tp_inst.support=detectSupport(tp_inst._defaults.timeFormat+(tp_inst._defaults.pickerTimeFormat?tp_inst._defaults.pickerTimeFormat:"")+(tp_inst._defaults.altTimeFormat?tp_inst._defaults.altTimeFormat:"")),"string"==typeof tp_inst._defaults.controlType?("slider"===tp_inst._defaults.controlType&&void 0===$.ui.slider&&(tp_inst._defaults.controlType="select"),tp_inst.control=tp_inst._controls[tp_inst._defaults.controlType]):tp_inst.control=tp_inst._defaults.controlType;var timezoneList=[-720,-660,-600,-570,-540,-480,-420,-360,-300,-270,-240,-210,-180,-120,-60,0,60,120,180,210,240,270,300,330,345,360,390,420,480,525,540,570,600,630,660,690,720,765,780,840];null!==tp_inst._defaults.timezoneList&&(timezoneList=tp_inst._defaults.timezoneList);var tzl=timezoneList.length,tzi=0,tzv=null;if(0' + '
- ' + o.timeText + '
' + - ''; - - // Create the markup - for (i = 0, l = this.units.length; i < l; i++) { - litem = this.units[i]; - uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); - show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; - - // Added by Peter Medeiros: - // - Figure out what the hour/minute/second max should be based on the step values. - // - Example: if stepMinute is 15, then minMax is 45. - max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10); - gridSize[litem] = 0; - - html += '- ' + o[litem + 'Text'] + '
' + - '- '; - - if (show && o[litem + 'Grid'] > 0) { - html += '
'; - } - - // Timezone - var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone; - html += ''; - } - html += '
'; - - if (litem === 'hour') { - for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) { - gridSize[litem]++; - var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o); - html += ' ' + tmph + ' '; - } - } - else { - for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) { - gridSize[litem]++; - html += '' + ((m < 10) ? '0' : '') + m + ' '; - } - } - - html += '- ' + o.timezoneText + '
'; - html += ''; - - // Create the elements from string - html += 'tp_inst._defaults.hourMax?tp_inst._defaults.hourMax:tp_inst._defaults.hour,tp_inst.minute=tp_inst._defaults.minute tp_inst._defaults.minuteMax?tp_inst._defaults.minuteMax:tp_inst._defaults.minute,tp_inst.second=tp_inst._defaults.second tp_inst._defaults.secondMax?tp_inst._defaults.secondMax:tp_inst._defaults.second,tp_inst.millisec=tp_inst._defaults.millisec tp_inst._defaults.millisecMax?tp_inst._defaults.millisecMax:tp_inst._defaults.millisec,tp_inst.microsec=tp_inst._defaults.microsec tp_inst._defaults.microsecMax?tp_inst._defaults.microsecMax:tp_inst._defaults.microsec,tp_inst.ampm="",tp_inst.$input=$input,tp_inst._defaults.altField&&(tp_inst.$altInput=$(tp_inst._defaults.altField).css({cursor:"pointer"}).focus(function(){$input.trigger("focus")})),0!==tp_inst._defaults.minDate&&0!==tp_inst._defaults.minDateTime||(tp_inst._defaults.minDate=new Date),0!==tp_inst._defaults.maxDate&&0!==tp_inst._defaults.maxDateTime||(tp_inst._defaults.maxDate=new Date),void 0!==tp_inst._defaults.minDate&&tp_inst._defaults.minDate instanceof Date&&(tp_inst._defaults.minDateTime=new Date(tp_inst._defaults.minDate.getTime())),void 0!==tp_inst._defaults.minDateTime&&tp_inst._defaults.minDateTime instanceof Date&&(tp_inst._defaults.minDate=new Date(tp_inst._defaults.minDateTime.getTime())),void 0!==tp_inst._defaults.maxDate&&tp_inst._defaults.maxDate instanceof Date&&(tp_inst._defaults.maxDateTime=new Date(tp_inst._defaults.maxDate.getTime())),void 0!==tp_inst._defaults.maxDateTime&&tp_inst._defaults.maxDateTime instanceof Date&&(tp_inst._defaults.maxDate=new Date(tp_inst._defaults.maxDateTime.getTime())),tp_inst.$input.bind("focus",function(){tp_inst._onFocus()}),tp_inst},_addTimePicker:function(e){var t=this.$altInput&&this._defaults.altFieldTimeOnly?this.$input.val()+" "+this.$altInput.val():this.$input.val();this.timeDefined=this._parseTime(t),this._limitMinMaxDateTime(e,!1),this._injectTimePicker()},_parseTime:function(t,e){if(this.inst||(this.inst=$.datepicker._getInst(this.$input[0])),e||!this._defaults.timeOnly){var i=$.datepicker._get(this.inst,"dateFormat");try{var s=parseDateTimeInternal(i,this._defaults.timeFormat,t,$.datepicker._getFormatConfig(this.inst),this._defaults);if(!s.timeObj)return!1;$.extend(this,s.timeObj)}catch(e){return $.timepicker.log("Error parsing the date/time string: "+e+"\ndate/time string = "+t+"\ntimeFormat = "+this._defaults.timeFormat+"\ndateFormat = "+i),!1}return!0}var a=$.datepicker.parseTime(this._defaults.timeFormat,t,this._defaults);return!!a&&($.extend(this,a),!0)},_injectTimePicker:function(){var e=this.inst.dpDiv,t=this.inst.settings,r=this,l="",i="",s=null,a={},n={},o=null,c=0,m=0;if(0===e.find("div.ui-timepicker-div").length&&t.showTimepicker){for(var u=' style="display:none;"',d=' "}d+=""}var f=null!==t.showTimezone?t.showTimezone:this.support.timezone;d+='
- "+t.timeText+'
",c=0,m=this.units.length;c"+t[l+"Text"]+' - ",s&&0
',"hour"===l)for(var p=t[l+"Min"];p<=a[l];p+=parseInt(t[l+"Grid"],10)){n[l]++;var h=$.datepicker.formatTime(this.support.ampm?"hht":"HH",{hour:p},t);d+=' '+h+" "}else for(var _=t[l+"Min"];_<=a[l];_+=parseInt(t[l+"Grid"],10))n[l]++,d+=''+(_<10?"0":"")+_+" ";d+="- "+t.timezoneText+"
",d+='";var g=$(d+="");for(!0===t.timeOnly&&(g.prepend(' "),e.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()),c=0,m=r.units.length;c").find("select"),$.fn.append.apply(this.timezone_select,$.map(t.timezoneList,function(e,t){return $("").val("object"==typeof e?e.value:e).text("object"==typeof e?e.label:e)})),void 0!==this.timezone&&null!==this.timezone&&""!==this.timezone?-1*new Date(this.inst.selectedYear,this.inst.selectedMonth,this.inst.selectedDay,12).getTimezoneOffset()===this.timezone?selectLocalTimezone(r):this.timezone_select.val(this.timezone):void 0!==this.hour&&null!==this.hour&&""!==this.hour?this.timezone_select.val(t.timezone):selectLocalTimezone(r),this.timezone_select.change(function(){r._onTimeChange(),r._onSelectHandler()});var M,k,v,T=e.find(".ui-datepicker-buttonpane");T.length?T.before(g):e.append(g),this.$timeObj=g.find(".ui_tpicker_time"),null!==this.inst&&(M=this.timeDefined,this._onTimeChange(),this.timeDefined=M),this._defaults.addSliderAccess&&(k=this._defaults.sliderAccessArgs,v=this._defaults.isRTL,k.isRTL=v,setTimeout(function(){var r;0===g.find(".ui-slider-access").length&&(g.find(".ui-slider:visible").sliderAccess(k),(r=g.find(".ui-slider-access:eq(0)").outerWidth(!0))&&g.find("table:visible").each(function(){var e=$(this),t=e.outerWidth(),i=e.css(v?"marginRight":"marginLeft").toString().replace("%",""),s=t-r,a=i*s/t+"%",n={width:s,marginRight:0,marginLeft:0};n[v?"marginRight":"marginLeft"]=a,e.css(n)}))},10)),r._limitMinMaxDateTime(this.inst,!0)}},_limitMinMaxDateTime:function(e,t){var i,s,a,n,r,l,o,c,m,u=this._defaults,d=new Date(e.selectedYear,e.selectedMonth,e.selectedDay);this._defaults.showTimepicker&&(null!==$.datepicker._get(e,"minDateTime")&&void 0!==$.datepicker._get(e,"minDateTime")&&d&&(i=$.datepicker._get(e,"minDateTime"),s=new Date(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0,0),null!==this.hourMinOriginal&&null!==this.minuteMinOriginal&&null!==this.secondMinOriginal&&null!==this.millisecMinOriginal&&null!==this.microsecMinOriginal||(this.hourMinOriginal=u.hourMin,this.minuteMinOriginal=u.minuteMin,this.secondMinOriginal=u.secondMin,this.millisecMinOriginal=u.millisecMin,this.microsecMinOriginal=u.microsecMin),e.settings.timeOnly||s.getTime()===d.getTime()?(this._defaults.hourMin=i.getHours(),this.hour<=this._defaults.hourMin?(this.hour=this._defaults.hourMin,this._defaults.minuteMin=i.getMinutes(),this.minute<=this._defaults.minuteMin?(this.minute=this._defaults.minuteMin,this._defaults.secondMin=i.getSeconds(),this.second<=this._defaults.secondMin?(this.second=this._defaults.secondMin,this._defaults.millisecMin=i.getMilliseconds(),this.millisec<=this._defaults.millisecMin?(this.millisec=this._defaults.millisecMin,this._defaults.microsecMin=i.getMicroseconds()):(this.microsec =this._defaults.hourMax?(this.hour=this._defaults.hourMax,this._defaults.minuteMax=a.getMinutes(),this.minute>=this._defaults.minuteMax?(this.minute=this._defaults.minuteMax,this._defaults.secondMax=a.getSeconds(),this.second>=this._defaults.secondMax?(this.second=this._defaults.secondMax,this._defaults.millisecMax=a.getMilliseconds(),this.millisec>=this._defaults.millisecMax?(this.millisec=this._defaults.millisecMax,this._defaults.microsecMax=a.getMicroseconds()):(this.microsec>this._defaults.microsecMax&&(this.microsec=this._defaults.microsecMax),this._defaults.microsecMax=this.microsecMaxOriginal)):(this._defaults.millisecMax=this.millisecMaxOriginal,this._defaults.microsecMax=this.microsecMaxOriginal)):(this._defaults.secondMax=this.secondMaxOriginal,this._defaults.millisecMax=this.millisecMaxOriginal,this._defaults.microsecMax=this.microsecMaxOriginal)):(this._defaults.minuteMax=this.minuteMaxOriginal,this._defaults.secondMax=this.secondMaxOriginal,this._defaults.millisecMax=this.millisecMaxOriginal,this._defaults.microsecMax=this.microsecMaxOriginal)):(this._defaults.hourMax=this.hourMaxOriginal,this._defaults.minuteMax=this.minuteMaxOriginal,this._defaults.secondMax=this.secondMaxOriginal,this._defaults.millisecMax=this.millisecMaxOriginal,this._defaults.microsecMax=this.microsecMaxOriginal)),void 0!==t&&!0===t&&(r=parseInt(this._defaults.hourMax-(this._defaults.hourMax-this._defaults.hourMin)%this._defaults.stepHour,10),l=parseInt(this._defaults.minuteMax-(this._defaults.minuteMax-this._defaults.minuteMin)%this._defaults.stepMinute,10),o=parseInt(this._defaults.secondMax-(this._defaults.secondMax-this._defaults.secondMin)%this._defaults.stepSecond,10),c=parseInt(this._defaults.millisecMax-(this._defaults.millisecMax-this._defaults.millisecMin)%this._defaults.stepMillisec,10),m=parseInt(this._defaults.microsecMax-(this._defaults.microsecMax-this._defaults.microsecMin)%this._defaults.stepMicrosec,10),this.hour_slider&&(this.control.options(this,this.hour_slider,"hour",{min:this._defaults.hourMin,max:r}),this.control.value(this,this.hour_slider,"hour",this.hour-this.hour%this._defaults.stepHour)),this.minute_slider&&(this.control.options(this,this.minute_slider,"minute",{min:this._defaults.minuteMin,max:l}),this.control.value(this,this.minute_slider,"minute",this.minute-this.minute%this._defaults.stepMinute)),this.second_slider&&(this.control.options(this,this.second_slider,"second",{min:this._defaults.secondMin,max:o}),this.control.value(this,this.second_slider,"second",this.second-this.second%this._defaults.stepSecond)),this.millisec_slider&&(this.control.options(this,this.millisec_slider,"millisec",{min:this._defaults.millisecMin,max:c}),this.control.value(this,this.millisec_slider,"millisec",this.millisec-this.millisec%this._defaults.stepMillisec)),this.microsec_slider&&(this.control.options(this,this.microsec_slider,"microsec",{min:this._defaults.microsecMin,max:m}),this.control.value(this,this.microsec_slider,"microsec",this.microsec-this.microsec%this._defaults.stepMicrosec))))},_onTimeChange:function(){var e,t,i,s,a,n,r,l,o,c,m;this._defaults.showTimepicker&&(e=!!this.hour_slider&&this.control.value(this,this.hour_slider,"hour"),t=!!this.minute_slider&&this.control.value(this,this.minute_slider,"minute"),i=!!this.second_slider&&this.control.value(this,this.second_slider,"second"),s=!!this.millisec_slider&&this.control.value(this,this.millisec_slider,"millisec"),a=!!this.microsec_slider&&this.control.value(this,this.microsec_slider,"microsec"),n=!!this.timezone_select&&this.timezone_select.val(),l=(r=this._defaults).pickerTimeFormat||r.timeFormat,o=r.pickerTimeSuffix||r.timeSuffix,"object"==typeof e&&(e=!1),"object"==typeof t&&(t=!1),"object"==typeof i&&(i=!1),"object"==typeof s&&(s=!1),"object"==typeof a&&(a=!1),"object"==typeof n&&(n=!1),!1!==e&&(e=parseInt(e,10)),!1!==t&&(t=parseInt(t,10)),!1!==i&&(i=parseInt(i,10)),!1!==s&&(s=parseInt(s,10)),!1!==a&&(a=parseInt(a,10)),c=r[e<12?"amNames":"pmNames"][0],(m=e!==this.hour||t!==this.minute||i!==this.second||s!==this.millisec||a!==this.microsec||0 ',o=t._defaults.pickerTimeFormat||t._defaults.timeFormat,c=a;c<=n;c+=r)l+='";return l+="",e.children("select").remove(),$(l).appendTo(e).change(function(e){t._onTimeChange(),t._onSelectHandler()}),e},options:function(e,t,i,s,a){var n={},r=t.children("select");if("string"==typeof s){if(void 0===a)return r.data(s);n[s]=a}else n=s;return e.control.create(e,t,r.data("unit"),r.val(),n.min||r.data("min"),n.max||r.data("max"),n.step||r.data("step"))},value:function(e,t,i,s){var a=t.children("select");return void 0!==s?a.val(s):a.val()}}}}),$.fn.extend({timepicker:function(e){e=e||{};var t=Array.prototype.slice.call(arguments);return"object"==typeof e&&(t[0]=$.extend(e,{timeOnly:!0})),$(this).each(function(){$.fn.datetimepicker.apply($(this),t)})},datetimepicker:function(t){var i=arguments;return"string"==typeof(t=t||{})?"getDate"===t?$.fn.datepicker.apply($(this[0]),i):this.each(function(){var e=$(this);e.datepicker.apply(e,i)}):this.each(function(){var e=$(this);e.datepicker($.timepicker._newInst(e,t)._defaults)})}}),$.datepicker.parseDateTime=function(e,t,i,s,a){var n,r=parseDateTimeInternal(e,t,i,s,a);return r.timeObj&&(n=r.timeObj,r.date.setHours(n.hour,n.minute,n.second,n.millisec),r.date.setMicroseconds(n.microsec)),r.date},$.datepicker.parseTime=function(e,t,i){function a(e,t,n){var i="^"+e.toString().replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g,function(e){var t,i,s,a=e.length;switch(e.charAt(0).toLowerCase()){case"h":case"m":case"s":return 1===a?"(\\d?\\d)":"(\\d{"+a+"})";case"l":case"c":return"(\\d?\\d?\\d)";case"z":return"(z|[-+]\\d\\d:?\\d\\d|\\S+)?";case"t":return t=n.amNames,i=n.pmNames,s=[],t&&$.merge(s,t),i&&$.merge(s,i),"("+(s=$.map(s,function(e){return e.replace(/[.*+?|()\[\]{}\\]/g,"\\$&")})).join("|")+")?";default:return"("+e.replace(/\'/g,"").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g,function(e){return"\\"+e})+")?"}}).replace(/\s/g,"\\s?")+n.timeSuffix+"$",s=function(e){var t=e.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),i={h:-1,m:-1,s:-1,l:-1,c:-1,t:-1,z:-1};if(t)for(var s=0;s " + item[this.propertyToSearch]+ "" }, - tokenFormatter: function(item) { return " - " }, - - // Callbacks - onResult: null, - onAdd: null, - onDelete: null, - onReady: null -}; - -// Default classes to use when theming -var DEFAULT_CLASSES = { - tokenList: "token-input-list", - token: "token-input-token", - tokenDelete: "token-input-delete-token", - selectedToken: "token-input-selected-token", - highlightedToken: "token-input-highlighted-token", - dropdown: "token-input-dropdown", - dropdownItem: "token-input-dropdown-item", - dropdownItem2: "token-input-dropdown-item2", - selectedDropdownItem: "token-input-selected-dropdown-item", - inputToken: "token-input-input-token" -}; - -// Input box position "enum" -var POSITION = { - BEFORE: 0, - AFTER: 1, - END: 2 -}; - -// Keys "enum" -var KEY = { - BACKSPACE: 8, - TAB: 9, - ENTER: 13, - ESCAPE: 27, - SPACE: 32, - PAGE_UP: 33, - PAGE_DOWN: 34, - END: 35, - HOME: 36, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - NUMPAD_ENTER: 108, - COMMA: 188 -}; - -// Additional public (exposed) methods -var methods = { - init: function(url_or_data_or_function, options) { - var settings = $.extend({}, DEFAULT_SETTINGS, options || {}); - - return this.each(function () { - $(this).data("tokenInputObject", new $.TokenList(this, url_or_data_or_function, settings)); - }); - }, - clear: function() { - this.data("tokenInputObject").clear(); - return this; - }, - add: function(item) { - this.data("tokenInputObject").add(item); - return this; - }, - remove: function(item) { - this.data("tokenInputObject").remove(item); - return this; - }, - get: function() { - return this.data("tokenInputObject").getTokens(); - } -} - -// Expose the .tokenInput function to jQuery as a plugin -$.fn.tokenInput = function (method) { - // Method calling and initialization logic - if(methods[method]) { - return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); - } else { - return methods.init.apply(this, arguments); - } -}; - -// TokenList class for each input -$.TokenList = function (input, url_or_data, settings) { - // - // Initialization - // - - // Configure the data source - if($.type(url_or_data) === "string" || $.type(url_or_data) === "function") { - // Set the url to query against - settings.url = url_or_data; - - // If the URL is a function, evaluate it here to do our initalization work - var url = computeURL(); - - // Make a smart guess about cross-domain if it wasn't explicitly specified - if(settings.crossDomain === undefined) { - if(url.indexOf("://") === -1) { - settings.crossDomain = false; - } else { - settings.crossDomain = (location.href.split(/\/+/g)[1] !== url.split(/\/+/g)[1]); - } - } - } else if(typeof(url_or_data) === "object") { - // Set the local data to search through - settings.local_data = url_or_data; - } - - // Build class names - if(settings.classes) { - // Use custom class names - settings.classes = $.extend({}, DEFAULT_CLASSES, settings.classes); - } else if(settings.theme) { - // Use theme-suffixed default class names - settings.classes = {}; - $.each(DEFAULT_CLASSES, function(key, value) { - settings.classes[key] = value + "-" + settings.theme; - }); - } else { - settings.classes = DEFAULT_CLASSES; - } - - - // Save the tokens - var saved_tokens = []; - - // Keep track of the number of tokens in the list - var token_count = 0; - - // Basic cache to save on db hits - var cache = new $.TokenList.Cache(); - - // Keep track of the timeout, old vals - var timeout; - var input_val; - - // Create a new text input an attach keyup events - var input_box = $("") - .css({ - outline: "none" - }) - .attr("id", settings.idPrefix + input.id) - .focus(function () { - if (settings.tokenLimit === null || settings.tokenLimit !== token_count) { - show_dropdown_hint(); - } - }) - .blur(function () { - hide_dropdown(); - $(this).val(""); - }) - // .bind("keyup keydown blur update", resize_input) - .keydown(function (event) { - var previous_token; - var next_token; - - switch(event.keyCode) { - case KEY.LEFT: - case KEY.RIGHT: - case KEY.UP: - case KEY.DOWN: - if(!$(this).val()) { - previous_token = input_token.prev(); - next_token = input_token.next(); - - if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) { - // Check if there is a previous/next token and it is selected - if(event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) { - deselect_token($(selected_token), POSITION.BEFORE); - } else { - deselect_token($(selected_token), POSITION.AFTER); - } - } else if((event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) && previous_token.length) { - // We are moving left, select the previous token if it exists - select_token($(previous_token.get(0))); - } else if((event.keyCode === KEY.RIGHT || event.keyCode === KEY.DOWN) && next_token.length) { - // We are moving right, select the next token if it exists - select_token($(next_token.get(0))); - } - } else { - var dropdown_item = null; - - if(event.keyCode === KEY.DOWN || event.keyCode === KEY.RIGHT) { - dropdown_item = $(selected_dropdown_item).next(); - } else { - dropdown_item = $(selected_dropdown_item).prev(); - } - - if(dropdown_item.length) { - select_dropdown_item(dropdown_item); - } - return false; - } - break; - - case KEY.BACKSPACE: - previous_token = input_token.prev(); - - if(!$(this).val().length) { - if(selected_token) { - delete_token($(selected_token)); - hidden_input.change(); - } else if(previous_token.length) { - select_token($(previous_token.get(0))); - } - - return false; - } else if($(this).val().length === 1) { - hide_dropdown(); - } else { - // set a timeout just long enough to let this function finish. - setTimeout(function(){do_search();}, 5); - } - break; - - // case KEY.TAB: - case KEY.ENTER: - case KEY.NUMPAD_ENTER: - case KEY.COMMA: - if(selected_dropdown_item) { - add_token($(selected_dropdown_item).data("tokeninput")); - hidden_input.change(); - return false; - } else { - add_token(null); - return false; - } - - break; - - case KEY.ESCAPE: - hide_dropdown(); - return true; - - default: - if(String.fromCharCode(event.which)) { - // set a timeout just long enough to let this function finish. - setTimeout(function(){do_search();}, 5); - } - break; - } - }); - - // Keep a reference to the original input box - var hidden_input = $(input) - .hide() - .val("") - .focus(function () { - input_box.focus(); - }) - .blur(function () { - input_box.blur(); - }); - - // Keep a reference to the selected token and dropdown item - var selected_token = null; - var selected_token_index = 0; - var selected_dropdown_item = null; - - // The list to store the token items in - var token_list = $("
" + item[this.propertyToSearch] + "
") - .addClass(settings.classes.tokenList) - .click(function (event) { - var li = $(event.target).closest("li"); - if(li && li.get(0) && $.data(li.get(0), "tokeninput")) { - toggle_select_token(li); - } else { - // Deselect selected token - if(selected_token) { - deselect_token($(selected_token), POSITION.END); - } - - // Focus input box - input_box.focus(); - } - }) - .mouseover(function (event) { - var li = $(event.target).closest("li"); - if(li && selected_token !== this) { - li.addClass(settings.classes.highlightedToken); - } - }) - .mouseout(function (event) { - var li = $(event.target).closest("li"); - if(li && selected_token !== this) { - li.removeClass(settings.classes.highlightedToken); - } - }) - .insertBefore(hidden_input); - - // The token holding the input box - var input_token = $("") - .addClass(settings.classes.inputToken) - .appendTo(token_list) - .append(input_box); - - // The list to store the dropdown items in - var dropdown = $("
") - .addClass(settings.classes.dropdown) - .appendTo("body") - .hide(); - - // Magic element to help us resize the text input - var input_resizer = $("") - .insertAfter(input_box) - .css({ - position: "absolute", - top: -9999, - left: -9999, - width: "auto", - fontSize: input_box.css("fontSize"), - fontFamily: input_box.css("fontFamily"), - fontWeight: input_box.css("fontWeight"), - letterSpacing: input_box.css("letterSpacing"), - whiteSpace: "nowrap" - }); - - // Pre-populate list if items exist - hidden_input.val(""); - var li_data = settings.prePopulate || hidden_input.data("pre"); - if(settings.processPrePopulate && $.isFunction(settings.onResult)) { - li_data = settings.onResult.call(hidden_input, li_data); - } - if(li_data && li_data.length) { - $.each(li_data, function (index, value) { - insert_token(value); - checkTokenLimit(); - }); - } - - // Initialization is done - if($.isFunction(settings.onReady)) { - settings.onReady.call(); - } - - // - // Public functions - // - - this.clear = function() { - token_list.children("li").each(function() { - if ($(this).children("input").length === 0) { - delete_token($(this)); - } - }); - } - - this.add = function(item) { - add_token(item); - } - - this.remove = function(item) { - token_list.children("li").each(function() { - if ($(this).children("input").length === 0) { - var currToken = $(this).data("tokeninput"); - var match = true; - for (var prop in item) { - if (item[prop] !== currToken[prop]) { - match = false; - break; - } - } - if (match) { - delete_token($(this)); - } - } - }); - } - - this.getTokens = function() { - return saved_tokens; - } - - // - // Private functions - // - - function checkTokenLimit() { - if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { - input_box.hide(); - hide_dropdown(); - return; - } - } - - function resize_input() { - if(input_val === (input_val = input_box.val())) {return;} - - // Enter new content into resizer and resize input accordingly - var escaped = input_val.replace(/&/g, '&').replace(/\s/g,' ').replace(//g, '>'); - input_resizer.html(escaped); - input_box.width(input_resizer.width() + 30); - } - - function is_printable_character(keycode) { - return ((keycode >= 48 && keycode <= 90) || // 0-1a-z - (keycode >= 96 && keycode <= 111) || // numpad 0-9 + - / * . - (keycode >= 186 && keycode <= 192) || // ; = , - . / ^ - (keycode >= 219 && keycode <= 222)); // ( \ ) ' - } - - // Inner function to a token to the list - function insert_token(item) { - var this_token = settings.tokenFormatter(item); - this_token = $(this_token) - .addClass(settings.classes.token) - .insertBefore(input_token); - - // The 'delete token' button - $("" + settings.deleteText + "") - .addClass(settings.classes.tokenDelete) - .appendTo(this_token) - .click(function () { - delete_token($(this).parent()); - hidden_input.change(); - return false; - }); - - // Store data on the token - var token_data = {"id": item.id}; - token_data[settings.propertyToSearch] = item[settings.propertyToSearch]; - $.data(this_token.get(0), "tokeninput", item); - - // Save this token for duplicate checking - saved_tokens = saved_tokens.slice(0,selected_token_index).concat([token_data]).concat(saved_tokens.slice(selected_token_index)); - selected_token_index++; - - // Update the hidden input - update_hidden_input(saved_tokens, hidden_input); - - token_count += 1; - - // Check the token limit - if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) { - input_box.hide(); - hide_dropdown(); - } - - return this_token; - } - - // Add a token to the token list based on user input - function add_token (item) { - var callback = settings.onAdd; - - // fix null bug - if (!item && input_box.val().length > 0) { - item = { - id : input_box.val() - }; - - item[settings.propertyToSearch] = input_box.val(); - } - - if (!item) { - return false; - } - - // See if the token already exists and select it if we don't want duplicates - if(token_count > 0 && settings.preventDuplicates) { - var found_existing_token = null; - token_list.children().each(function () { - var existing_token = $(this); - var existing_data = $.data(existing_token.get(0), "tokeninput"); - if(existing_data && existing_data.id === item.id) { - found_existing_token = existing_token; - return false; - } - }); - - if(found_existing_token) { - select_token(found_existing_token); - input_token.insertAfter(found_existing_token); - input_box.focus(); - return; - } - } - - // Insert the new tokens - if(settings.tokenLimit == null || token_count < settings.tokenLimit) { - insert_token(item); - checkTokenLimit(); - } - - // Clear input box - input_box.val(""); - - // Don't show the help dropdown, they've got the idea - hide_dropdown(); - - // Execute the onAdd callback if defined - if($.isFunction(callback)) { - callback.call(hidden_input,item); - } - } - - // Select a token in the token list - function select_token (token) { - token.addClass(settings.classes.selectedToken); - selected_token = token.get(0); - - // Hide input box - input_box.val(""); - - // Hide dropdown if it is visible (eg if we clicked to select token) - hide_dropdown(); - } - - // Deselect a token in the token list - function deselect_token (token, position) { - token.removeClass(settings.classes.selectedToken); - selected_token = null; - - if(position === POSITION.BEFORE) { - input_token.insertBefore(token); - selected_token_index--; - } else if(position === POSITION.AFTER) { - input_token.insertAfter(token); - selected_token_index++; - } else { - input_token.appendTo(token_list); - selected_token_index = token_count; - } - - // Show the input box and give it focus again - input_box.focus(); - } - - // Toggle selection of a token in the token list - function toggle_select_token(token) { - var previous_selected_token = selected_token; - - if(selected_token) { - deselect_token($(selected_token), POSITION.END); - } - - if(previous_selected_token === token.get(0)) { - deselect_token(token, POSITION.END); - } else { - select_token(token); - } - } - - // Delete a token from the token list - function delete_token (token) { - // Remove the id from the saved list - var token_data = $.data(token.get(0), "tokeninput"); - var callback = settings.onDelete; - - var index = token.prevAll().length; - if(index > selected_token_index) index--; - - // Delete the token - token.remove(); - selected_token = null; - - // Show the input box and give it focus again - input_box.focus(); - - // Remove this token from the saved list - saved_tokens = saved_tokens.slice(0,index).concat(saved_tokens.slice(index+1)); - if(index < selected_token_index) selected_token_index--; - - // Update the hidden input - update_hidden_input(saved_tokens, hidden_input); - - token_count -= 1; - - if(settings.tokenLimit !== null) { - input_box - .show() - .val("") - .focus(); - } - - // Execute the onDelete callback if defined - if($.isFunction(callback)) { - callback.call(hidden_input,token_data); - } - } - - // Update the hidden input box value - function update_hidden_input(saved_tokens, hidden_input) { - var token_values = $.map(saved_tokens, function (el) { - return el[settings.tokenValue]; - }); - hidden_input.val(token_values.join(settings.tokenDelimiter)); - - } - - // Hide and clear the results dropdown - function hide_dropdown () { - dropdown.hide().empty(); - selected_dropdown_item = null; - } - - function show_dropdown() { - dropdown - .css({ - position: "absolute", - top: $(token_list).offset().top + $(token_list).outerHeight(), - left: $(token_list).offset().left, - zindex: 999 - }) - .show(); - } - - function show_dropdown_searching () { - if(settings.searchingText) { - dropdown.html(" "+settings.searchingText+"
"); - show_dropdown(); - } - } - - function show_dropdown_hint () { - if(settings.hintText) { - dropdown.html(""+settings.hintText+"
"); - show_dropdown(); - } - } - - // Highlight the query part of the search term - function highlight_term(value, term) { - return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); - } - - function find_value_and_highlight_term(template, value, term) { - return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + value + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term)); - } - - // Populate the results dropdown with some results - function populate_dropdown (query, results) { - if(results && results.length) { - dropdown.empty(); - var dropdown_ul = $("") - .appendTo(dropdown) - .mouseover(function (event) { - select_dropdown_item($(event.target).closest("li")); - }) - .mousedown(function (event) { - add_token($(event.target).closest("li").data("tokeninput")); - hidden_input.change(); - return false; - }) - .hide(); - - $.each(results, function(index, value) { - var this_li = settings.resultsFormatter(value); - - this_li = find_value_and_highlight_term(this_li ,value[settings.propertyToSearch], query); - - this_li = $(this_li).appendTo(dropdown_ul); - - if(index % 2) { - this_li.addClass(settings.classes.dropdownItem); - } else { - this_li.addClass(settings.classes.dropdownItem2); - } - - if(index === 0) { - select_dropdown_item(this_li); - } - - $.data(this_li.get(0), "tokeninput", value); - }); - - show_dropdown(); - - if(settings.animateDropdown) { - dropdown_ul.slideDown("fast"); - } else { - dropdown_ul.show(); - } - } else { - if(settings.noResultsText) { - dropdown.html("
"+settings.noResultsText+"
"); - show_dropdown(); - } - } - } - - // Highlight an item in the results dropdown - function select_dropdown_item (item) { - if(item) { - if(selected_dropdown_item) { - deselect_dropdown_item($(selected_dropdown_item)); - } - - item.addClass(settings.classes.selectedDropdownItem); - selected_dropdown_item = item.get(0); - } - } - - // Remove highlighting from an item in the results dropdown - function deselect_dropdown_item (item) { - item.removeClass(settings.classes.selectedDropdownItem); - selected_dropdown_item = null; - } - - // Do a search and show the "searching" dropdown if the input is longer - // than settings.minChars - function do_search() { - var val = input_box.val(), query = val.toLowerCase(); - - if(query && query.length) { - if(selected_token) { - deselect_token($(selected_token), POSITION.AFTER); - } - - if(query.length >= settings.minChars) { - show_dropdown_searching(); - clearTimeout(timeout); - - timeout = setTimeout(function(){ - run_search(query, val); - }, settings.searchDelay); - } else { - hide_dropdown(); - } - } - } - - // Do the actual search - function run_search(query, val) { - var cache_key = val + computeURL(); - var cached_results = cache.get(cache_key); - if(cached_results) { - populate_dropdown(query, cached_results); - } else { - // Are we doing an ajax search or local data search? - if(settings.url) { - var url = computeURL(); - // Extract exisiting get params - var ajax_params = {}; - ajax_params.data = {}; - if(url.indexOf("?") > -1) { - var parts = url.split("?"); - ajax_params.url = parts[0]; - - var param_array = parts[1].split("&"); - $.each(param_array, function (index, value) { - var kv = value.split("="); - ajax_params.data[kv[0]] = kv[1]; - }); - } else { - ajax_params.url = url; - } - - // Prepare the request - ajax_params.data[settings.queryParam] = query; - ajax_params.type = settings.method; - ajax_params.dataType = settings.contentType; - if(settings.crossDomain) { - ajax_params.dataType = "jsonp"; - } - - // Attach the success callback - ajax_params.success = function(results) { - if($.isFunction(settings.onResult)) { - results = settings.onResult.call(hidden_input, results, query, val); - } - cache.add(cache_key, settings.jsonContainer ? results[settings.jsonContainer] : results); - - // only populate the dropdown if the results are associated with the active search query - if(input_box.val().toLowerCase() === query) { - populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results); - } - }; - - // Make the request - $.ajax(ajax_params); - } else if(settings.local_data) { - // Do the search through local data - var results = $.grep(settings.local_data, function (row) { - return row[settings.propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1; - }); - - if($.isFunction(settings.onResult)) { - results = settings.onResult.call(hidden_input, results, query, val); - } - cache.add(cache_key, results); - populate_dropdown(query, results); - } - } - } - - // compute the dynamic URL - function computeURL() { - var url = settings.url; - if(typeof settings.url == 'function') { - url = settings.url.call(); - } - return url; - } -}; - -// Really basic cache for the results -$.TokenList.Cache = function (options) { - var settings = $.extend({ - max_size: 500 - }, options); - - var data = {}; - var size = 0; - - var flush = function () { - data = {}; - size = 0; - }; - - this.add = function (query, results) { - if(size > settings.max_size) { - flush(); - } - - if(!data[query]) { - size += 1; - } - - data[query] = results; - }; - - this.get = function (query) { - return data[query]; - }; -}; -}(jQuery)); +!function(F){var o={method:"GET",contentType:"json",queryParam:"q",searchDelay:300,minChars:1,propertyToSearch:"name",jsonContainer:null,hintText:"Type in a search term",noResultsText:"No results",searchingText:"Searching...",deleteText:"×",animateDropdown:!0,tokenLimit:null,tokenDelimiter:",",preventDuplicates:!1,tokenValue:"id",prePopulate:null,processPrePopulate:!1,idPrefix:"token-input-",resultsFormatter:function(e){return"- "+e[this.propertyToSearch]+"
"},tokenFormatter:function(e){return"- "},onResult:null,onAdd:null,onDelete:null,onReady:null},P={tokenList:"token-input-list",token:"token-input-token",tokenDelete:"token-input-delete-token",selectedToken:"token-input-selected-token",highlightedToken:"token-input-highlighted-token",dropdown:"token-input-dropdown",dropdownItem:"token-input-dropdown-item",dropdownItem2:"token-input-dropdown-item2",selectedDropdownItem:"token-input-selected-dropdown-item",inputToken:"token-input-input-token"},O=0,A=1,z=2,_=8,q=13,B=27,E=37,V=38,W=39,G=40,H=108,N=188,t={init:function(e,t){var n=F.extend({},o,t||{});return this.each(function(){F(this).data("tokenInputObject",new F.TokenList(this,e,n))})},clear:function(){return this.data("tokenInputObject").clear(),this},add:function(e){return this.data("tokenInputObject").add(e),this},remove:function(e){return this.data("tokenInputObject").remove(e),this},get:function(){return this.data("tokenInputObject").getTokens()}};F.fn.tokenInput=function(e){return t[e]?t[e].apply(this,Array.prototype.slice.call(arguments,1)):t.init.apply(this,arguments)},F.TokenList=function(e,t,c){var n;"string"===F.type(t)||"function"===F.type(t)?(c.url=t,n=I(),void 0===c.crossDomain&&(-1===n.indexOf("://")?c.crossDomain=!1:c.crossDomain=location.href.split(/\/+/g)[1]!==n.split(/\/+/g)[1])):"object"==typeof t&&(c.local_data=t),c.classes?c.classes=F.extend({},P,c.classes):c.theme?(c.classes={},F.each(P,function(e,t){c.classes[e]=t+"-"+c.theme})):c.classes=P;var o,i=[],a=0,u=new F.TokenList.Cache,d=F('').css({outline:"none"}).attr("id",c.idPrefix+e.id).focus(function(){null!==c.tokenLimit&&c.tokenLimit===a||c.hintText&&(k.html("
"+e[this.propertyToSearch]+"
"+c.hintText+"
"),L())}).blur(function(){D(),F(this).val("")}).keydown(function(e){var t,n;switch(e.keyCode){case E:case W:case V:case G:if(F(this).val()){var o=null;return(o=e.keyCode===G||e.keyCode===W?F(r).next():F(r).prev()).length&&R(o),!1}t=f.prev(),n=f.next(),t.length&&t.get(0)===s||n.length&&n.get(0)===s?e.keyCode===E||e.keyCode===V?C(F(s),O):C(F(s),A):e.keyCode!==E&&e.keyCode!==V||!t.length?e.keyCode!==W&&e.keyCode!==G||!n.length||y(F(n.get(0))):y(F(t.get(0)));break;case _:if(t=f.prev(),!F(this).val().length)return s?(w(F(s)),p.change()):t.length&&y(F(t.get(0))),!1;1===F(this).val().length?D():setTimeout(function(){S()},5);break;case q:case H:case N:return r?(T(F(r).data("tokeninput")),p.change()):T(null),!1;case B:return D(),!0;default:String.fromCharCode(e.which)&&setTimeout(function(){S()},5)}}),p=F(e).hide().val("").focus(function(){d.focus()}).blur(function(){d.blur()}),s=null,l=0,r=null,h=F("").addClass(c.classes.tokenList).click(function(e){var t=F(e.target).closest("li");t&&t.get(0)&&F.data(t.get(0),"tokeninput")?function(e){var t=s;s&&C(F(s),z);t===e.get(0)?C(e,z):y(e)}(t):(s&&C(F(s),z),d.focus())}).mouseover(function(e){var t=F(e.target).closest("li");t&&s!==this&&t.addClass(c.classes.highlightedToken)}).mouseout(function(e){var t=F(e.target).closest("li");t&&s!==this&&t.removeClass(c.classes.highlightedToken)}).insertBefore(p),f=F("").addClass(c.classes.inputToken).appendTo(h).append(d),k=F("
").addClass(c.classes.dropdown).appendTo("body").hide();F("").insertAfter(d).css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:d.css("fontSize"),fontFamily:d.css("fontFamily"),fontWeight:d.css("fontWeight"),letterSpacing:d.css("letterSpacing"),whiteSpace:"nowrap"});p.val("");var g=c.prePopulate||p.data("pre");function m(){return null!==c.tokenLimit&&a>=c.tokenLimit&&(d.hide(),void D())}function v(e){var t=c.tokenFormatter(e),t=F(t).addClass(c.classes.token).insertBefore(f);F(""+c.deleteText+"").addClass(c.classes.tokenDelete).appendTo(t).click(function(){return w(F(this).parent()),p.change(),!1});var n={id:e.id};return n[c.propertyToSearch]=e[c.propertyToSearch],F.data(t.get(0),"tokeninput",e),i=i.slice(0,l).concat([n]).concat(i.slice(l)),l++,x(i,p),a+=1,null!==c.tokenLimit&&a>=c.tokenLimit&&(d.hide(),D()),t}function T(n){var e=c.onAdd;if(!n&&0 ]*)("+t+")(?![^<>]*>)(?![^&;]+;)","g"),(o=n,t.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+o+")(?![^<>]*>)(?![^&;]+;)","gi"),"$1")));var o}function j(o,e){var i;e&&e.length?(k.empty(),i=F(" ").appendTo(k).mouseover(function(e){R(F(e.target).closest("li"))}).mousedown(function(e){return T(F(e.target).closest("li").data("tokeninput")),p.change(),!1}).hide(),F.each(e,function(e,t){var n=b(n=c.resultsFormatter(t),t[c.propertyToSearch],o);n=F(n).appendTo(i),e%2?n.addClass(c.classes.dropdownItem):n.addClass(c.classes.dropdownItem2),0===e&&R(n),F.data(n.get(0),"tokeninput",t)}),L(),c.animateDropdown?i.slideDown("fast"):i.show()):c.noResultsText&&(k.html("
"+c.noResultsText+"
"),L())}function R(e){e&&(r&&(F(r).removeClass(c.classes.selectedDropdownItem),r=null),e.addClass(c.classes.selectedDropdownItem),r=e.get(0))}function S(){var e=d.val(),t=e.toLowerCase();t&&t.length&&(s&&C(F(s),A),t.length>=c.minChars?(c.searchingText&&(k.html(""+c.searchingText+"
"),L()),clearTimeout(o),o=setTimeout(function(){!function(t,n){var o=n+I(),e=u.get(o);{var i,a,s,l,r;e?j(t,e):c.url?(i=I(),a={data:{}},-1n.max_size&&(o={},i=0),o[e]||(i+=1),o[e]=t},this.get=function(e){return o[e]}}}(jQuery); \ No newline at end of file diff --git a/admin/js/typecho.js b/admin/js/typecho.js index 2bebb9b9..6c2dd3e6 100644 --- a/admin/js/typecho.js +++ b/admin/js/typecho.js @@ -1,1460 +1 @@ -(function (w) { - w.Typecho = { - insertFileToEditor : function (file, url, isImage) {}, - uploadFile: function (file) {}, - editorResize : function (id, url) { - $('#' + id).resizeable({ - minHeight : 100, - afterResize : function (h) { - $.post(url, {size : h}); - } - }) - }, - uploadComplete : function (file) {} - }; -})(window); - -// 虚拟编辑器 -function scrollableEditor(el, preview) { - var styles = el.css(), - lastWidth = el.width(), - lastFocus = null, - merge = [], - rows = [], - previewRows = [], - css = {display: 'block', 'position': 'absolute', 'left': '-99999px', 'top': '-99999px'}, - test = $('').appendTo(document.body), - focused = false; - - for (var k in styles) { - if (k.match(/^(direction|font-family|font-size|font-style|font-weight|letter-spacing|line-height|text-align|vertical-align|white-space|word-wrap|word-break|word-spacing)$/i)) { - css[k] = styles[k]; - } - } - - test.css(css); - test.css('min-height', css['line-height']); - - function reload(input) { - var text = el.val(), - lines = text.split("\n"), - h = 0; - - test.width(el.width()); - rows = []; - - for (var i = 0; i < lines.length; i ++) { - test.text(lines[i]); - h += test.height(); - - rows.push(h); - } - - test.html(''); - reloadPreview(input); - } - - function scroll(inputLine) { - var height = el.height(), - offset = (el.innerHeight() - height) / 2, - scrollTop = el.scrollTop() - offset, - previewScrollTop = preview.scrollTop(), - percent = 0, - scrollPos = 0, - current = null; - - // 自动滚动到当前行 - if (typeof inputLine != 'undefined') { - for (var a = 0; a < previewRows.length; a ++) { - var item = previewRows[a]; - - if (inputLine >= item[0] && inputLine <= item[1]) { - if (a == previewRows.length - 1 || item[2] < previewScrollTop - || previewRows[a + 1][2] > previewScrollTop + preview.height()) { - preview.scrollTop(item[2]); - } - break; - } - } - - return; - } - - for (var i = 0; i < merge.length; i ++) { - current = merge[i]; - - if (scrollTop <= current[2]) { - percent = (scrollTop - current[3]) * current[4] / (current[2] - current[3]) - break; - } - } - - if (!current) { - return; - } - - for (var j = 0; j < previewRows.length; j ++) { - var item = previewRows[j]; - - if (current[0] >= item[0] && current[1] <= item[1]) { - var nextPos = previewRows[j + 1] ? previewRows[j + 1][2] : preview.get(0).scrollHeight; - scrollPos = (i == 0 ? 0 : item[2]) + (nextPos - item[2]) * percent; - - preview.scrollTop(scrollPos); - break; - } - } - } - - function scrollPreview() { - var height = el.height(), - offset = (el.innerHeight() - height) / 2, - previewScrollTop = preview.scrollTop(), - found = false, - current; - - if (previewRows.length <= 0) { - return; - } - - for (var i = 0; i < previewRows.length; i ++) { - var item = previewRows[i]; - - if (previewScrollTop < item[2]) { - found = true; - break; - } - } - - current = found ? previewRows[i > 0 ? i - 1 : 0] : previewRows[previewRows.length - 1]; - - var start = current[0] > 0 ? rows[current[0] - 1] : 0, - end = rows[current[1]], - nextPos = found ? previewRows[i > 0 ? i : 1][2] : preview.get(0).scrollHeight, - percent = (previewScrollTop - current[2]) / (nextPos - current[2]); - - el.scrollTop(start + (end - start) * percent + offset); - } - - function reloadPreview(input) { - var last = 0; - previewRows = []; - merge = []; - - $('.line', preview).each(function () { - var t = $(this), start = t.data('start'), end = t.data('end'), startOriginal = t.data('start-original'), - pos = t.position().top + preview.scrollTop(); - - previewRows.push([start, end, pos, this]); - - if (typeof startOriginal != 'undefined') { - merge.push([start, startOriginal - 1, rows[startOriginal - 1], last, 0]); - merge.push([startOriginal, end, rows[end], rows[startOriginal - 1], 1]); - } else { - merge.push([start, end, rows[end], last, 1]); - } - - last = rows[end]; - }); - - var inputLine = reloadInput(); - - if (input) { - if (inputLine !== null) { - scroll(inputLine); - } - } else { - scroll(); - } - } - - function getFoucsElement(focus) { - var e = $(focus), p = e.parent(); - - if (e.length > 0 && e.prop('tagName').match(/^(hr|tr)$/i)) { - return e; - } else if (p.length > 0 && p.prop('tagName').toLowerCase() == 'div') { - return e.next(); - } - - return p; - } - - function reloadInput() { - var text = el.val(), end = el.getSelection().start, pos = 0, line = 0, current = null; - - if (!focused) { - return current; - } - - // 使用高效算法检测当前行号 - while (true) { - pos = text.indexOf("\n", pos); - - if (pos >= 0 && pos < end) { - line ++; - pos += 1; - } else { - break; - } - } - - for (var i = 0; i < previewRows.length; i ++) { - var item = previewRows[i]; - - if (line >= item[0] && line <= item[1]) { - getFoucsElement(lastFocus).removeClass('focus'); - getFoucsElement(item[3]).addClass('focus'); - lastFocus = item[3]; - current = line; - break; - } - } - - return current; - } - - // 检测宽度 - setInterval(function () { - if (el.width() != lastWidth) { - lastWidth = el.width(); - el.trigger('resize'); - } - }, 150); - - // 检测输入 - el.on('touch keypress click', reloadInput); - el.on('focus', function () { - focused = true; - }).on('blur', function () { - focused = false; - getFoucsElement(lastFocus).removeClass('focus'); - }); - - el.on('resize', reload); - - el.on('DOMMouseScroll mousewheel touchmove', function () { - scroll(); - }); - - preview.on('DOMMouseScroll mousewheel touchmove', function () { - scrollPreview(); - }); - - return reload; -} - -(function ($) { - // 下拉菜单插件 - $.fn.dropdownMenu = function (options) { - this.each(function () { - var menu = this, s = $.extend({ - menuEl : null, - btnEl : null - }, options); - - $(s.btnEl, menu).click(function () { - var t = $(this); - - t.toggleClass('active'); - $(s.menuEl, menu).toggle(); - return false; - }); - }); - }; - - $.fn.resizeable = function (options) { - var s = $.extend({ - minHeight : 100, - afterResize : null - }, options); - - return this.each(function () { - var r = $('').insertAfter(this), - staticOffset, iLastMousePos = 0, iMin = s.minHeight, t = this; - - function startDrag(e) { - textarea = $(e.data.el); - textarea.blur(); - iLastMousePos = mousePosition(e).y; - - staticOffset = textarea.height() - iLastMousePos; - textarea.css('opacity', 0.25); - - $(document).mousemove(performDrag).mouseup(endDrag); - return false; - } - - function performDrag(e) { - var iThisMousePos = mousePosition(e).y, - iMousePos = staticOffset + iThisMousePos; - if (iLastMousePos >= (iThisMousePos)) { - iMousePos -= 5; - } - - iLastMousePos = iThisMousePos; - iMousePos = Math.max(iMin, iMousePos); - textarea.height(iMousePos + 'px'); - - if (iMousePos < iMin) { - endDrag(e); - } - return false; - } - - function endDrag(e) { - var h = textarea.outerHeight(); - $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag); - - textarea.css('opacity', 1); - textarea.focus(); - textarea = null; - - staticOffset = null; - iLastMousePos = 0; - - if (s.afterResize) { - s.afterResize.call(t, h); - } - } - - function mousePosition(e) { - return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop }; - } - - r.bind('mousedown', {el : this}, startDrag); - }); - }; - - // 表格选择插件 - $.fn.tableSelectable = function (options) { - var table = this, s = $.extend({ - checkEl : null, - rowEl : null, - selectAllEl : null, - actionEl : null - }, options); - - function clickRow (t) { - var t = $(t), check = $(s.checkEl, t), checked = check.prop('checked'); - - if (!check.length) { - return; - } - - check.prop('checked', !checked); - - if (checked) { - t.removeClass('checked'); - } else { - t.addClass('checked'); - } - } - - $(s.rowEl, this).each(function () { - $(s.checkEl, this).click(function (e) { - clickRow($(this).parents(s.rowEl)); - }); - }).click(function (e) { - var target = $(e.toElement ? e.toElement : e.target), - tagName = target.prop('tagName').toLowerCase(); - - if ($.inArray(tagName, ['input', 'textarea', 'a', 'button', 'i']) >= 0 - && 'checkbox' != target.attr('type')) { - e.stopPropagation(); - } else { - clickRow(this); - } - }); - - $(s.selectAllEl).click(function () { - var t = $(this), checked = t.prop('checked'); - - if (checked) { - $(s.rowEl, table).each(function () { - var t = $(this), el = $(s.checkEl, this).prop('checked', true); - if (el.length > 0) { - t.addClass('checked'); - } - }); - } else { - $(s.rowEl, table).each(function () { - var t = $(this), el = $(s.checkEl, this).prop('checked', false); - if (el.length > 0) { - t.removeClass('checked'); - } - }); - } - }); - - $(s.actionEl).click(function () { - var t = $(this), lang = t.attr('lang'); - - if (!lang || confirm(lang)) { - table.parents('form').attr('action', t.attr('href')).submit(); - } - - return false; - }); - }; -})($); - - -/** - * TableDnD plug-in for JQuery, allows you to drag and drop table rows - * You can set up various options to control how the system will work - * Copyright © Denis Howlett - * Licensed like jQuery, see http://docs.jquery.com/License. - * - * Configuration options: - * - * onDragStyle - * This is the style that is assigned to the row during drag. There are limitations to the styles that can be - * associated with a row (such as you can't assign a border—well you can, but it won't be - * displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as - * a map (as used in the jQuery css(...) function). - * onDropStyle - * This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations - * to what you can do. Also this replaces the original style, so again consider using onDragClass which - * is simply added and then removed on drop. - * onDragClass - * This class is added for the duration of the drag and then removed when the row is dropped. It is more - * flexible than using onDragStyle since it can be inherited by the row cells and other content. The default - * is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your - * stylesheet. - * onDrop - * Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table - * and the row that was dropped. You can work out the new order of the rows by using - * table.rows. - * onDragStart - * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the - * table and the row which the user has started to drag. - * onAllowDrop - * Pass a function that will be called as a row is over another row. If the function returns true, allow - * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under - * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. - * scrollAmount - * This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the - * window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2, - * FF3 beta) - * - * Other ways to control behaviour: - * - * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows - * that you don't want to be draggable. - * - * Inside the onDrop method you can also call $.tableDnD.serialize() this returns a string of the form - * []= & []= so that you can send this back to the server. The table must have - * an ID as must all the rows. - * - * Known problems: - * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 - * - * Version 0.2: 2008-02-20 First public version - * Version 0.3: 2008-02-07 Added onDragStart option - * Made the scroll amount configurable (default is 5 as before) - * Version 0.4: 2008-03-15 Changed the noDrag/noDrop attributes to nodrag/nodrop classes - * Added onAllowDrop to control dropping - * Fixed a bug which meant that you couldn't set the scroll amount in both directions - * Added serialise method - */ -(function (jQuery) { -jQuery.tableDnD = { - /** Keep hold of the current table being dragged */ - currentTable : null, - /** Keep hold of the current drag object if any */ - dragObject: null, - /** The current mouse offset */ - mouseOffset: null, - /** Remember the old value of Y so that we don't do too much processing */ - oldY: 0, - - /** Actually build the structure */ - build: function(options) { - // Make sure options exists - options = options || {}; - // Set up the defaults if any - - this.each(function() { - // Remember the options - this.tableDnDConfig = { - onDragStyle: options.onDragStyle, - onDropStyle: options.onDropStyle, - // Add in the default class for whileDragging - onDragClass: options.onDragClass ? options.onDragClass : "tDnD_whileDrag", - onDrop: options.onDrop, - onDragStart: options.onDragStart, - scrollAmount: options.scrollAmount ? options.scrollAmount : 5 - }; - // Now make the rows draggable - jQuery.tableDnD.makeDraggable(this); - - // fix chrome border bug - if (0 == $('tfoot', this).length - && 0 < $('thead', this).length) { - var h = $('thead', this), count = $('th', h).length, - f = $(' ').insertAfter(h), - l = $('tr:last', this); - - if (l.parent().prop('tagName').toLowerCase() != 'tfoot') { - var td = $('td', l), dh = td.height(); - td.height(dh - f.outerHeight()); - } - } - }); - - // Now we need to capture the mouse up and mouse move event - // We can use bind so that we don't interfere with other event handlers - jQuery(document) - .bind('mousemove', jQuery.tableDnD.mousemove) - .bind('mouseup', jQuery.tableDnD.mouseup); - - // Don't break the chain - return this; - }, - - /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ - makeDraggable: function(table) { - // Now initialise the rows - var rows = table.rows; //getElementsByTagName("tr") - var config = table.tableDnDConfig; - for (var i=0; i jQuery.tableDnD.oldY; - // update the old value - jQuery.tableDnD.oldY = y; - // update the style to show we're dragging - if (config.onDragClass) { - dragObj.addClass(config.onDragClass); - } else { - dragObj.css(config.onDragStyle); - } - // If we're over a row then move the dragged row to there so that the user sees the - // effect dynamically - var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y); - if (currentRow) { - // TODO worry about what happens when there are multiple TBODIES - if (movingDown && jQuery.tableDnD.dragObject != currentRow) { - jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling); - } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) { - jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow); - } - } - } - - return false; - }, - - /** We're only worried about the y position really, because we can only move rows up and down */ - findDropTargetRow: function(draggedRow, y) { - var rows = jQuery.tableDnD.currentTable.rows; - for (var i=0; i rowY - rowHeight) && (y < (rowY + rowHeight))) { - // that's the row we're over - // If it's the same as the current row, ignore it - if (row == draggedRow) {return null;} - var config = jQuery.tableDnD.currentTable.tableDnDConfig; - if (config.onAllowDrop) { - if (config.onAllowDrop(draggedRow, row)) { - return row; - } else { - return null; - } - } else { - // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) - var nodrop = $(row).hasClass("nodrop"); - if (! nodrop) { - return row; - } else { - return null; - } - } - return row; - } - } - return null; - }, - - mouseup: function(e) { - if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) { - var droppedRow = jQuery.tableDnD.dragObject; - var config = jQuery.tableDnD.currentTable.tableDnDConfig; - // If we have a dragObject, then we need to release it, - // The row will already have been moved to the right place so we just reset stuff - if (config.onDragClass) { - jQuery(droppedRow).removeClass(config.onDragClass); - } else { - jQuery(droppedRow).css(config.onDropStyle); - } - jQuery.tableDnD.dragObject = null; - if (config.onDrop) { - // Call the onDrop method if there is one - config.onDrop(jQuery.tableDnD.currentTable, droppedRow); - } - jQuery.tableDnD.currentTable = null; // let go of the table too - } - }, - - serialize: function() { - if (jQuery.tableDnD.currentTable) { - var result = ""; - var tableId = jQuery.tableDnD.currentTable.id; - var rows = jQuery.tableDnD.currentTable.rows; - for (var i=0; i 0) result += "&"; - result += tableId + '[]=' + rows[i].id; - } - return result; - } else { - return "Error: No Table id set, you need to set an id on your table and every row"; - } - } -} - -jQuery.fn.extend( - { - tableDnD : jQuery.tableDnD.build - } -); -})($); - -/* - Masked Input plugin for jQuery - Copyright (c) 2007-2013 Josh Bush (digitalbush.com) - Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) - Version: 1.3.1 -*/ -(function($) { - function getPasteEvent() { - var el = document.createElement('input'), - name = 'onpaste'; - el.setAttribute(name, ''); - return (typeof el[name] === 'function')?'paste':'input'; -} - -var pasteEventName = getPasteEvent() + ".mask", - ua = navigator.userAgent, - iPhone = /iphone/i.test(ua), - android=/android/i.test(ua), - caretTimeoutId; - -$.mask = { - //Predefined character definitions - definitions: { - '9': "[0-9]", - 'a': "[A-Za-z]", - '*': "[A-Za-z0-9]" - }, - dataName: "rawMaskFn", - placeholder: '_', -}; - -$.fn.extend({ - //Helper Function for Caret positioning - caret: function(begin, end) { - var range; - - if (this.length === 0 || this.is(":hidden")) { - return; - } - - if (typeof begin == 'number') { - end = (typeof end === 'number') ? end : begin; - return this.each(function() { - if (this.setSelectionRange) { - this.setSelectionRange(begin, end); - } else if (this.createTextRange) { - range = this.createTextRange(); - range.collapse(true); - range.moveEnd('character', end); - range.moveStart('character', begin); - range.select(); - } - }); - } else { - if (this[0].setSelectionRange) { - begin = this[0].selectionStart; - end = this[0].selectionEnd; - } else if (document.selection && document.selection.createRange) { - range = document.selection.createRange(); - begin = 0 - range.duplicate().moveStart('character', -100000); - end = begin + range.text.length; - } - return { begin: begin, end: end }; - } - }, - unmask: function() { - return this.trigger("unmask"); - }, - mask: function(mask, settings) { - var input, - defs, - tests, - partialPosition, - firstNonMaskPos, - len; - - if (!mask && this.length > 0) { - input = $(this[0]); - return input.data($.mask.dataName)(); - } - settings = $.extend({ - placeholder: $.mask.placeholder, // Load default placeholder - completed: null - }, settings); - - - defs = $.mask.definitions; - tests = []; - partialPosition = len = mask.length; - firstNonMaskPos = null; - - $.each(mask.split(""), function(i, c) { - if (c == '?') { - len--; - partialPosition = i; - } else if (defs[c]) { - tests.push(new RegExp(defs[c])); - if (firstNonMaskPos === null) { - firstNonMaskPos = tests.length - 1; - } - } else { - tests.push(null); - } - }); - - return this.trigger("unmask").each(function() { - var input = $(this), - buffer = $.map( - mask.split(""), - function(c, i) { - if (c != '?') { - return defs[c] ? settings.placeholder : c; - } - }), - focusText = input.val(); - - function seekNext(pos) { - while (++pos < len && !tests[pos]); - return pos; - } - - function seekPrev(pos) { - while (--pos >= 0 && !tests[pos]); - return pos; - } - - function shiftL(begin,end) { - var i, - j; - - if (begin<0) { - return; - } - - for (i = begin, j = seekNext(end); i < len; i++) { - if (tests[i]) { - if (j < len && tests[i].test(buffer[j])) { - buffer[i] = buffer[j]; - buffer[j] = settings.placeholder; - } else { - break; - } - - j = seekNext(j); - } - } - writeBuffer(); - input.caret(Math.max(firstNonMaskPos, begin)); - } - - function shiftR(pos) { - var i, - c, - j, - t; - - for (i = pos, c = settings.placeholder; i < len; i++) { - if (tests[i]) { - j = seekNext(i); - t = buffer[i]; - buffer[i] = c; - if (j < len && tests[j].test(t)) { - c = t; - } else { - break; - } - } - } - } - - function keydownEvent(e) { - var k = e.which, - pos, - begin, - end; - - //backspace, delete, and escape get special treatment - if (k === 8 || k === 46 || (iPhone && k === 127)) { - pos = input.caret(); - begin = pos.begin; - end = pos.end; - - if (end - begin === 0) { - begin=k!==46?seekPrev(begin):(end=seekNext(begin-1)); - end=k===46?seekNext(end):end; - } - clearBuffer(begin, end); - shiftL(begin, end - 1); - - e.preventDefault(); - } else if (k == 27) {//escape - input.val(focusText); - input.caret(0, checkVal()); - e.preventDefault(); - } - } - - function keypressEvent(e) { - var k = e.which, - pos = input.caret(), - p, - c, - next; - - if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore - return; - } else if (k) { - if (pos.end - pos.begin !== 0){ - clearBuffer(pos.begin, pos.end); - shiftL(pos.begin, pos.end-1); - } - - p = seekNext(pos.begin - 1); - if (p < len) { - c = String.fromCharCode(k); - if (tests[p].test(c)) { - shiftR(p); - - buffer[p] = c; - writeBuffer(); - next = seekNext(p); - - if(android){ - setTimeout($.proxy($.fn.caret,input,next),0); - }else{ - input.caret(next); - } - - if (settings.completed && next >= len) { - settings.completed.call(input); - } - } - } - e.preventDefault(); - } - } - - function clearBuffer(start, end) { - var i; - for (i = start; i < end && i < len; i++) { - if (tests[i]) { - buffer[i] = settings.placeholder; - } - } - } - - function writeBuffer() { input.val(buffer.join('')); } - - function checkVal(allow) { - //try to place characters where they belong - var test = input.val(), - lastMatch = -1, - i, - c; - - for (i = 0, pos = 0; i < len; i++) { - if (tests[i]) { - buffer[i] = settings.placeholder; - while (pos++ < test.length) { - c = test.charAt(pos - 1); - if (tests[i].test(c)) { - buffer[i] = c; - lastMatch = i; - break; - } - } - if (pos > test.length) { - break; - } - } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) { - pos++; - lastMatch = i; - } - } - if (allow) { - writeBuffer(); - } else if (lastMatch + 1 < partialPosition) { - input.val(""); - clearBuffer(0, len); - } else { - writeBuffer(); - input.val(input.val().substring(0, lastMatch + 1)); - } - return (partialPosition ? i : firstNonMaskPos); - } - - input.data($.mask.dataName,function(){ - return $.map(buffer, function(c, i) { - return tests[i]&&c!=settings.placeholder ? c : null; - }).join(''); - }); - - if (!input.attr("readonly")) - input - .one("unmask", function() { - input - .unbind(".mask") - .removeData($.mask.dataName); - }) - .bind("focus.mask", function() { - clearTimeout(caretTimeoutId); - var pos, - moveCaret; - - focusText = input.val(); - pos = checkVal(); - - caretTimeoutId = setTimeout(function(){ - writeBuffer(); - if (pos == mask.length) { - input.caret(0, pos); - } else { - input.caret(pos); - } - }, 10); - }) - .bind("blur.mask", function() { - checkVal(); - if (input.val() != focusText) - input.change(); - }) - .bind("keydown.mask", keydownEvent) - .bind("keypress.mask", keypressEvent) - .bind(pasteEventName, function() { - setTimeout(function() { - var pos=checkVal(true); - input.caret(pos); - if (settings.completed && pos == input.val().length) - settings.completed.call(input); - }, 0); - }); - checkVal(); //Perform initial check for existing values - }); - } -}); - - -})(jQuery); - -/* - * jQuery plugin: fieldSelection - v0.1.1 - last change: 2006-12-16 - * (c) 2006 Alex Brem - http://blog.0xab.cd - */ - -jQuery.fn.extend({ - getSelection: function () { - - var e = this.get(0); - if (!e) { - return null; - } - - return ( - - /* mozilla / dom 3.0 */ - ('selectionStart' in e && function() { - var l = e.selectionEnd - e.selectionStart; - return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; - }) || - - /* other */ - (window.getSelection() && function () { - var selection = window.getSelection(), range = selection.getRangeAt(0); - - return { start: range.startOffset, end: range.endOffset, length: range.endOffset - range.startOffset, text: range.toString()}; - - }) || - - /* exploder */ - (document.selection && function() { - - e.focus(); - - var r = document.selection.createRange(); - if (r === null) { - return { start: 0, end: e.value.length, length: 0 } - } - - var re = e.createTextRange(); - var rc = re.duplicate(); - re.moveToBookmark(r.getBookmark()); - rc.setEndPoint('EndToStart', re); - - return { start: rc.text.length, end: rc.text.length + r.text.length, length: r.text.length, text: r.text }; - }) || - - /* browser not supported */ - function() { return null; } - - )(); - }, - - setSelection: function (start, end) { - var e = this.get(0); - if (!e) { - return; - } - - if (e.setSelectionRange) { - e.focus(); - e.setSelectionRange(start, end); - } else if (e.createTextRange) { - var range = e.createTextRange(); - range.collapse(true); - range.moveEnd('character', end); - range.moveStart('character', start); - range.select(); - } - }, - - replaceSelection: function () { - - var e = this.get(0); - if (!e) { - return null; - } - - var text = arguments[0] || ''; - - return ( - - /* mozilla / dom 3.0 */ - ('selectionStart' in e && function() { - e.value = e.value.substr(0, e.selectionStart) + text + e.value.substr(e.selectionEnd, e.value.length); - return this; - }) || - - /* exploder */ - (document.selection && function() { - e.focus(); - document.selection.createRange().text = text; - return this; - }) || - - /* browser not supported */ - function() { - e.value += text; - return jQuery(e); - } - - )(); - } -}); - -/** - * jQuery Cookie plugin - * - * Copyright (c) 2010 Klaus Hartl (stilbuero.de) - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - */ -jQuery.cookie = function (key, value, options) { - - // key and at least value given, set cookie... - if (arguments.length > 1 && String(value) !== "[object Object]") { - options = jQuery.extend({}, options); - - if (value === null || value === undefined) { - options.expires = -1; - } - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - value = String(value); - - return (document.cookie = [ - encodeURIComponent(key), '=', - options.raw ? value : encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // key and possibly options given, get cookie... - options = value || {}; - var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; - return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; -}; - -/*! - * jQuery.ScrollTo - * Copyright (c) 2007-2012 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com - * Dual licensed under MIT and GPL. - * Date: 4/09/2012 - * - * @projectDescription Easy element scrolling using jQuery. - * http://flesler.blogspot.com/2007/10/jqueryscrollto.html - * @author Ariel Flesler - * @version 1.4.3.1 - * - * @id jQuery.scrollTo - * @id jQuery.fn.scrollTo - * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements. - * The different options for target are: - * - A number position (will be applied to all axes). - * - A string position ('44', '100px', '+=90', etc ) will be applied to all axes - * - A jQuery/DOM element ( logically, child of the element to scroll ) - * - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc ) - * - A hash { top:x, left:y }, x and y can be any kind of number/string like above. - * - A percentage of the container's dimension/s, for example: 50% to go to the middle. - * - The string 'max' for go-to-end. - * @param {Number, Function} duration The OVERALL length of the animation, this argument can be the settings object instead. - * @param {Object,Function} settings Optional set of settings or the onAfter callback. - * @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'. - * @option {Number, Function} duration The OVERALL length of the animation. - * @option {String} easing The easing method for the animation. - * @option {Boolean} margin If true, the margin of the target element will be deducted from the final position. - * @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }. - * @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes. - * @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends. - * @option {Function} onAfter Function to be called after the scrolling ends. - * @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends. - * @return {jQuery} Returns the same jQuery object, for chaining. - * - * @desc Scroll to a fixed position - * @example $('div').scrollTo( 340 ); - * - * @desc Scroll relatively to the actual position - * @example $('div').scrollTo( '+=340px', { axis:'y' } ); - * - * @desc Scroll using a selector (relative to the scrolled element) - * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } ); - * - * @desc Scroll to a DOM element (same for jQuery object) - * @example var second_child = document.getElementById('container').firstChild.nextSibling; - * $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){ - * alert('scrolled!!'); - * }}); - * - * @desc Scroll on both axes, to different values - * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } ); - */ - -;(function( $ ){ - - var $scrollTo = $.scrollTo = function( target, duration, settings ){ - $(window).scrollTo( target, duration, settings ); - }; - - $scrollTo.defaults = { - axis:'xy', - duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1, - limit:true - }; - - // Returns the element that needs to be animated to scroll the window. - // Kept for backwards compatibility (specially for localScroll & serialScroll) - $scrollTo.window = function( scope ){ - return $(window)._scrollable(); - }; - - // Hack, hack, hack :) - // Returns the real elements to scroll (supports window/iframes, documents and regular nodes) - $.fn._scrollable = function(){ - return this.map(function(){ - var elem = this, - isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1; - - if( !isWin ) - return elem; - - var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem; - - return /webkit/i.test(navigator.userAgent) || doc.compatMode == 'BackCompat' ? - doc.body : - doc.documentElement; - }); - }; - - $.fn.scrollTo = function( target, duration, settings ){ - if( typeof duration == 'object' ){ - settings = duration; - duration = 0; - } - if( typeof settings == 'function' ) - settings = { onAfter:settings }; - - if( target == 'max' ) - target = 9e9; - - settings = $.extend( {}, $scrollTo.defaults, settings ); - // Speed is still recognized for backwards compatibility - duration = duration || settings.duration; - // Make sure the settings are given right - settings.queue = settings.queue && settings.axis.length > 1; - - if( settings.queue ) - // Let's keep the overall duration - duration /= 2; - settings.offset = both( settings.offset ); - settings.over = both( settings.over ); - - return this._scrollable().each(function(){ - // Null target yields nothing, just like jQuery does - if (target == null) return; - - var elem = this, - $elem = $(elem), - targ = target, toff, attr = {}, - win = $elem.is('html,body'); - - switch( typeof targ ){ - // A number will pass the regex - case 'number': - case 'string': - if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){ - targ = both( targ ); - // We are done - break; - } - // Relative selector, no break! - targ = $(targ,this); - if (!targ.length) return; - case 'object': - // DOMElement / jQuery - if( targ.is || targ.style ) - // Get the real position of the target - toff = (targ = $(targ)).offset(); - } - $.each( settings.axis.split(''), function( i, axis ){ - var Pos = axis == 'x' ? 'Left' : 'Top', - pos = Pos.toLowerCase(), - key = 'scroll' + Pos, - old = elem[key], - max = $scrollTo.max(elem, axis); - - if( toff ){// jQuery / DOMElement - attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] ); - - // If it's a dom element, reduce the margin - if( settings.margin ){ - attr[key] -= parseInt(targ.css('margin'+Pos)) || 0; - attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0; - } - - attr[key] += settings.offset[pos] || 0; - - if( settings.over[pos] ) - // Scroll to a fraction of its width/height - attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos]; - }else{ - var val = targ[pos]; - // Handle percentage values - attr[key] = val.slice && val.slice(-1) == '%' ? - parseFloat(val) / 100 * max - : val; - } - - // Number or 'number' - if( settings.limit && /^\d+$/.test(attr[key]) ) - // Check the limits - attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max ); - - // Queueing axes - if( !i && settings.queue ){ - // Don't waste time animating, if there's no need. - if( old != attr[key] ) - // Intermediate animation - animate( settings.onAfterFirst ); - // Don't animate this axis again in the next iteration. - delete attr[key]; - } - }); - - animate( settings.onAfter ); - - function animate( callback ){ - $elem.animate( attr, duration, settings.easing, callback && function(){ - callback.call(this, target, settings); - }); - }; - - }).end(); - }; - - // Max scrolling position, works on quirks mode - // It only fails (not too badly) on IE, quirks mode. - $scrollTo.max = function( elem, axis ){ - var Dim = axis == 'x' ? 'Width' : 'Height', - scroll = 'scroll'+Dim; - - if( !$(elem).is('html,body') ) - return elem[scroll] - $(elem)[Dim.toLowerCase()](); - - var size = 'client' + Dim, - html = elem.ownerDocument.documentElement, - body = elem.ownerDocument.body; - - return Math.max( html[scroll], body[scroll] ) - - Math.min( html[size] , body[size] ); - }; - - function both( val ){ - return typeof val == 'object' ? val : { top:val, left:val }; - }; - -})( jQuery ); - -jQuery.fn.css2 = jQuery.fn.css; -jQuery.fn.css = function() { - if (arguments.length) return jQuery.fn.css2.apply(this, arguments); - var attr = ['font-family','font-size','font-weight','font-style','color', 'box-sizing', - 'text-transform','text-decoration','letter-spacing', 'box-shadow', - 'line-height','text-align','vertical-align','direction','background-color', - 'background-image','background-repeat','background-position', - 'background-attachment','opacity','width','height','top','right','bottom', - 'left','margin-top','margin-right','margin-bottom','margin-left', - 'padding-top','padding-right','padding-bottom','padding-left', - 'border-top-width','border-right-width','border-bottom-width', - 'border-left-width','border-top-color','border-right-color', - 'border-bottom-color','border-left-color','border-top-style', - 'border-right-style','border-bottom-style','border-left-style','position', - 'display','visibility','z-index','overflow-x','overflow-y','white-space', - 'clip','float','clear','cursor','list-style-image','list-style-position', - 'list-style-type','marker-offset', 'word-wrap', 'word-break', 'word-spacing']; - var len = attr.length, obj = {}; - for (var i = 0; i < len; i++) - obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]); - return obj; -}; +function scrollableEditor(h,g){var e=h.css(),t=h.width(),l=null,m=[],u=[],p=[],n={display:"block",position:"absolute",left:"-99999px",top:"-99999px"},r=$("").appendTo(document.body),c=!1;for(var o in e)o.match(/^(direction|font-family|font-size|font-style|font-weight|letter-spacing|line-height|text-align|vertical-align|white-space|word-wrap|word-break|word-spacing)$/i)&&(n[o]=e[o]);function a(e){var t=h.val().split("\n"),n=0;r.width(h.width()),u=[];for(var o=0;o =f[0]&&l[1]<=f[1]){var u=p[s+1]?p[s+1][2]:g.get(0).scrollHeight,i=(0==c?0:f[2])+(u-f[2])*a;g.scrollTop(i);break}}}else for(var f,d=0;d =(f=p[d])[0]&&e<=f[1]){(d==p.length-1||f[2] r+g.height())&&g.scrollTop(f[2]);break}}}function s(e){var t=$(e),n=t.parent();return 0 =i[0]&&o<=i[1]){s(l).removeClass("focus"),s(i[3]).addClass("focus"),l=i[3],r=o;break}}return r}return r.css(n),r.css("min-height",n["line-height"]),setInterval(function(){h.width()!=t&&(t=h.width(),h.trigger("resize"))},150),h.on("touch keypress click",f),h.on("focus",function(){c=!0}).on("blur",function(){c=!1,s(l).removeClass("focus")}),h.on("resize",a),h.on("DOMMouseScroll mousewheel touchmove",function(){i()}),g.on("DOMMouseScroll mousewheel touchmove",function(){!function(){var e,t=h.height(),n=(h.innerHeight()-t)/2,o=g.scrollTop(),r=!1;if(!(p.length<=0)){for(var a=0;a ').insertAfter(this),r=0,a=s.minHeight,n=this;function i(e){var t=c(e).y,n=o+t;return t<=r&&(n-=5),r=t,n=Math.max(a,n),textarea.height(n+"px"),n ').insertAfter(e),"tfoot"!=(o=$("tr:last",this)).parent().prop("tagName").toLowerCase()&&(a=(r=$("td",o)).height(),r.height(a-n.outerHeight())))}),c(document).bind("mousemove",c.tableDnD.mousemove).bind("mouseup",c.tableDnD.mouseup),this},makeDraggable:function(t){for(var e=t.rows,n=t.tableDnDConfig,o=0;o c.tableDnD.oldY,c.tableDnD.oldY=i,r.onDragClass?o.addClass(r.onDragClass):o.css(r.onDragStyle),(n=c.tableDnD.findDropTargetRow(o,i))&&(t&&c.tableDnD.dragObject!=n?c.tableDnD.dragObject.parentNode.insertBefore(c.tableDnD.dragObject,n.nextSibling):t||c.tableDnD.dragObject==n||c.tableDnD.dragObject.parentNode.insertBefore(c.tableDnD.dragObject,n))),!1}},findDropTargetRow:function(e,t){for(var n=c.tableDnD.currentTable.rows,o=0;o n.length)break}else l[r]===n.charAt(pos)&&r!==m&&(pos++,o=r);return e?f():o+1 unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i /g, '>').replace(/"/g, '"'); + }; + + trim = function(str, ch) { + var c, i, j, ref, search; + if (ch == null) { + ch = null; + } + if (ch != null) { + search = ''; + for (i = j = 0, ref = ch.length - 1; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) { + c = ch[i]; + c = preg_quote(c); + search += c; + } + search = '[' + search + ']*'; + return str.replace(new RegExp('^' + search), '').replace(new RegExp(search + '$'), ''); + } else { + return str.replace(/^\s*/, '').replace(/\s*$/, ''); + } + }; + + array_keys = function(arr) { + var _, j, k, len, result; + result = []; + if (arr instanceof Array) { + for (k = j = 0, len = arr.length; j < len; k = ++j) { + _ = arr[k]; + result.push(k); + } + } else { + for (k in arr) { + result.push(k); + } + } + return result; + }; + + array_values = function(arr) { + var _, j, len, result, v; + result = []; + if (arr instanceof Array) { + for (j = 0, len = arr.length; j < len; j++) { + v = arr[j]; + result.push(v); + } + } else { + for (_ in arr) { + v = arr[_]; + result.push(v); + } + } + return result; + }; + + function Parser() { + this.commonWhiteList = 'kbd|b|i|strong|em|sup|sub|br|code|del|a|hr|small'; + this.blockHtmlTags = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|svg|script|noscript'; + this.specialWhiteList = { + table: 'table|tbody|thead|tfoot|tr|td|th' + }; + this.hooks = {}; + this.html = false; + this.line = false; + this.blockParsers = [['code', 10], ['shtml', 20], ['pre', 30], ['ahtml', 40], ['shr', 50], ['list', 60], ['math', 70], ['html', 80], ['footnote', 90], ['definition', 100], ['quote', 110], ['table', 120], ['sh', 130], ['mh', 140], ['dhr', 150], ['default', 9999]]; + this.parsers = {}; + } + + Parser.prototype.makeHtml = function(text) { + var html, j, len, name, parser, ref; + this.footnotes = []; + this.definitions = {}; + this.holders = {}; + this.uniqid = (Math.ceil(Math.random() * 10000000)) + (Math.ceil(Math.random() * 10000000)); + this.id = 0; + this.blockParsers.sort(function(a, b) { + if (a[1] < b[1]) { + return -1; + } else { + return 1; + } + }); + ref = this.blockParsers; + for (j = 0, len = ref.length; j < len; j++) { + parser = ref[j]; + name = parser[0]; + if (parser[2] !== void 0) { + this.parsers[name] = parser[2]; + } else { + this.parsers[name] = this['parseBlock' + (ucfirst(name))].bind(this); + } + } + text = this.initText(text); + html = this.parse(text); + html = this.makeFootnotes(html); + html = this.optimizeLines(html); + return this.call('makeHtml', html); + }; + + Parser.prototype.enableHtml = function(html1) { + this.html = html1 != null ? html1 : true; + }; + + Parser.prototype.enableLine = function(line1) { + this.line = line1 != null ? line1 : true; + }; + + Parser.prototype.hook = function(type, cb) { + if (this.hooks[type] == null) { + this.hooks[type] = []; + } + return this.hooks[type].push(cb); + }; + + Parser.prototype.makeHolder = function(str) { + var key; + key = "|\r" + this.uniqid + this.id + "\r|"; + this.id += 1; + this.holders[key] = str; + return key; + }; + + Parser.prototype.initText = function(text) { + return text.replace(/\t/g, ' ').replace(/\r/g, '').replace(/(\u000A|\u000D|\u2028|\u2029)/g, "\n"); + }; + + Parser.prototype.makeFootnotes = function(html) { + var index, val; + if (this.footnotes.length > 0) { + html += ' '; + } + return html; + }; + + Parser.prototype.parse = function(text, inline, offset) { + var block, blocks, end, extract, html, j, len, lines, method, result, start, type, value; + if (inline == null) { + inline = false; + } + if (offset == null) { + offset = 0; + } + lines = []; + blocks = this.parseBlock(text, lines); + html = ''; + if (inline && blocks.length === 1 && blocks[0][0] === 'normal') { + blocks[0][3] = true; + } + for (j = 0, len = blocks.length; j < len; j++) { + block = blocks[j]; + type = block[0], start = block[1], end = block[2], value = block[3]; + extract = lines.slice(start, end + 1); + method = 'parse' + ucfirst(type); + extract = this.call('before' + ucfirst(method), extract, value); + result = this[method](extract, value, start + offset, end + offset); + result = this.call('after' + ucfirst(method), result, value); + html += result; + } + return html; + }; + + Parser.prototype.call = function() { + var args, callback, j, len, ref, type, value; + type = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + value = args[0]; + if (this.hooks[type] == null) { + return value; + } + ref = this.hooks[type]; + for (j = 0, len = ref.length; j < len; j++) { + callback = ref[j]; + value = callback.apply(this, args); + args[0] = value; + } + return value; + }; + + Parser.prototype.releaseHolder = function(text, clearHolders) { + var deep; + if (clearHolders == null) { + clearHolders = true; + } + deep = 0; + while ((text.indexOf("\r")) >= 0 && deep < 10) { + text = str_replace(array_keys(this.holders), array_values(this.holders), text); + deep += 1; + } + if (clearHolders) { + this.holders = {}; + } + return text; + }; + + Parser.prototype.markLine = function(start, end) { + if (end == null) { + end = -1; + } + if (this.line) { + end = end < 0 ? start : end; + return ''; + } + return ''; + }; + + Parser.prototype.markLines = function(lines, start) { + var i; + i = -1; + if (this.line) { + return lines.map((function(_this) { + return function(line) { + i += 1; + return (_this.markLine(start + i)) + line; + }; + })(this)); + } else { + return lines; + } + }; + + Parser.prototype.optimizeLines = function(html) { + var last, regex; + last = 0; + regex = new RegExp("class=\"line\" data\\-start=\"([0-9]+)\" data\\-end=\"([0-9]+)\" (data\\-id=\"" + this.uniqid + "\")", 'g'); + if (this.line) { + return html.replace(regex, function() { + var matches, replace; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + if (last !== parseInt(matches[1])) { + replace = 'class="line" data-start="' + last + '" data-start-original="' + matches[1] + '" data-end="' + matches[2] + '" ' + matches[3]; + } else { + replace = matches[0]; + } + last = 1 + parseInt(matches[2]); + return replace; + }); + } else { + return html; + } + }; + + Parser.prototype.parseInline = function(text, whiteList, clearHolders, enableAutoLink) { + var regex; + if (whiteList == null) { + whiteList = ''; + } + if (clearHolders == null) { + clearHolders = true; + } + if (enableAutoLink == null) { + enableAutoLink = true; + } + text = this.call('beforeParseInline', text); + text = text.replace(/(^|[^\\])(`+)(.+?)\2/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + _this.makeHolder('' + (htmlspecialchars(matches[3])) + '
'); + }; + })(this)); + text = text.replace(/(^|[^\\])(\$+)(.+?)\2/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + _this.makeHolder(matches[2] + (htmlspecialchars(matches[3])) + matches[2]); + }; + })(this)); + text = text.replace(/\\(.)/g, (function(_this) { + return function() { + var escaped, matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + escaped = htmlspecialchars(matches[1]); + escaped = escaped.replace(/\$/g, '$'); + return _this.makeHolder(escaped); + }; + })(this)); + text = text.replace(/<(https?:\/\/.+)>/ig, (function(_this) { + return function() { + var link, matches, url; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + url = _this.cleanUrl(matches[1]); + link = _this.call('parseLink', matches[1]); + return _this.makeHolder("" + link + ""); + }; + })(this)); + text = text.replace(/<(\/?)([a-z0-9-]+)(\s+[^>]*)?>/ig, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + if (_this.html || (('|' + _this.commonWhiteList + '|' + whiteList + '|').indexOf('|' + matches[2].toLowerCase() + '|')) >= 0) { + return _this.makeHolder(matches[0]); + } else { + return htmlspecialchars(matches[0]); + } + }; + })(this)); + if (this.html) { + text = text.replace(//g, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.makeHolder(matches[0]); + }; + })(this)); + } + text = str_replace(['<', '>'], ['<', '>'], text); + text = text.replace(/\[\^((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) { + return function() { + var id, matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + id = _this.footnotes.indexOf(matches[1]); + if (id < 0) { + id = _this.footnotes.length + 1; + _this.footnotes.push(_this.parseInline(matches[1], '', false)); + } + return _this.makeHolder("" + id + ""); + }; + })(this)); + text = text.replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g, (function(_this) { + return function() { + var escaped, matches, url; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + escaped = htmlspecialchars(_this.escapeBracket(matches[1])); + url = _this.escapeBracket(matches[2]); + url = _this.cleanUrl(url); + return _this.makeHolder(""); + }; + })(this)); + text = text.replace(/!\[((?:[^\]]|\\\]|\\\[)*?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) { + return function() { + var escaped, matches, result; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + escaped = htmlspecialchars(_this.escapeBracket(matches[1])); + result = _this.definitions[matches[2]] != null ? "" : escaped; + return _this.makeHolder(result); + }; + })(this)); + text = text.replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\(((?:[^\)]|\\\)|\\\()+?)\)/g, (function(_this) { + return function() { + var escaped, matches, url; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + escaped = _this.parseInline(_this.escapeBracket(matches[1]), '', false, false); + url = _this.escapeBracket(matches[2]); + url = _this.cleanUrl(url); + return _this.makeHolder("" + escaped + ""); + }; + })(this)); + text = text.replace(/\[((?:[^\]]|\\\]|\\\[)+?)\]\[((?:[^\]]|\\\]|\\\[)+?)\]/g, (function(_this) { + return function() { + var escaped, matches, result; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + escaped = _this.parseInline(_this.escapeBracket(matches[1]), '', false, false); + result = _this.definitions[matches[2]] != null ? "" + escaped + "" : escaped; + return _this.makeHolder(result); + }; + })(this)); + text = this.parseInlineCallback(text); + text = text.replace(/<([_a-z0-9-\.\+]+@[^@]+\.[a-z]{2,})>/ig, '$1'); + if (enableAutoLink) { + regex = new RegExp("(^|[^\"])((https?):[" + pL + "_0-9-\\./%#!@\\?\\+=~\\|\\,&\\(\\)]+)($|[^\"])", 'ig'); + text = text.replace(regex, (function(_this) { + return function() { + var link, matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + link = _this.call('parseLink', matches[2]); + return matches[1] + "" + link + "" + matches[4]; + }; + })(this)); + } + text = this.call('afterParseInlineBeforeRelease', text); + text = this.releaseHolder(text, clearHolders); + text = this.call('afterParseInline', text); + return text; + }; + + Parser.prototype.parseInlineCallback = function(text) { + text = text.replace(/(\*{3})((?:.|\r)+?)\1/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return '' + (_this.parseInlineCallback(matches[2])) + ''; + }; + })(this)); + text = text.replace(/(\*{2})((?:.|\r)+?)\1/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return '' + (_this.parseInlineCallback(matches[2])) + ''; + }; + })(this)); + text = text.replace(/(\*)((?:.|\r)+?)\1/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return '' + (_this.parseInlineCallback(matches[2])) + ''; + }; + })(this)); + text = text.replace(/(\s+|^)(_{3})((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4]; + }; + })(this)); + text = text.replace(/(\s+|^)(_{2})((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4]; + }; + })(this)); + text = text.replace(/(\s+|^)(_)((?:.|\r)+?)\2(\s+|$)/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return matches[1] + '' + (_this.parseInlineCallback(matches[3])) + '' + matches[4]; + }; + })(this)); + text = text.replace(/(~{2})((?:.|\r)+?)\1/mg, (function(_this) { + return function() { + var matches; + matches = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return '' + (_this.parseInlineCallback(matches[2])) + ''; + }; + })(this)); + return text; + }; + + Parser.prototype.parseBlock = function(text, lines) { + var block, j, key, l, len, len1, line, name, parser, pass, ref, ref1, state; + ref = text.split("\n"); + for (j = 0, len = ref.length; j < len; j++) { + line = ref[j]; + lines.push(line); + } + this.blocks = []; + this.current = 'normal'; + this.pos = -1; + state = { + special: (array_keys(this.specialWhiteList)).join('|'), + empty: 0, + html: false + }; + for (key = l = 0, len1 = lines.length; l < len1; key = ++l) { + line = lines[key]; + block = this.getBlock(); + if (block != null) { + block = block.slice(0); + } + if (this.current !== 'normal') { + pass = this.parsers[this.current](block, key, line, state, lines); + if (!pass) { + continue; + } + } + ref1 = this.parsers; + for (name in ref1) { + parser = ref1[name]; + if (name !== this.current) { + pass = parser(block, key, line, state, lines); + if (!pass) { + break; + } + } + } + } + return this.optimizeBlocks(this.blocks, lines); + }; + + Parser.prototype.parseBlockList = function(block, key, line, state) { + var matches, space; + if (!!(matches = line.match(/^(\s*)((?:[0-9]+\.)|\-|\+|\*)\s+/i))) { + space = matches[1].length; + state.empty = 0; + if (this.isBlock('list')) { + this.setBlock(key, space); + } else { + this.startBlock('list', key, space); + } + return false; + } else if ((this.isBlock('list')) && !line.match(/^\s*\[((?:[^\]]|\\\]|\\\[)+?)\]:\s*(.+)$/)) { + if ((state.empty <= 1) && !!(matches = line.match(/^(\s+)/)) && matches[1].length > block[3]) { + state.empty = 0; + this.setBlock(key); + return false; + } else if ((line.match(/^\s*$/)) && state.empty === 0) { + state.empty += 1; + this.setBlock(key); + return false; + } + } + return true; + }; + + Parser.prototype.parseBlockCode = function(block, key, line) { + var isAfterList, matches, space; + if (!!(matches = line.match(/^(\s*)(~{3,}|`{3,})([^`~]*)$/i))) { + if (this.isBlock('code')) { + isAfterList = block[3][2]; + if (isAfterList) { + this.combineBlock().setBlock(key); + } else { + (this.setBlock(key)).endBlock(); + } + } else { + isAfterList = false; + if (this.isBlock('list')) { + space = block[3]; + isAfterList = (space > 0 && matches[1].length >= space) || matches[1].length > space; + } + this.startBlock('code', key, [matches[1], matches[3], isAfterList]); + } + return false; + } else if (this.isBlock('code')) { + this.setBlock(key); + return false; + } + return true; + }; + + Parser.prototype.parseBlockShtml = function(block, key, line, state) { + var matches; + if (this.html) { + if (!!(matches = line.match(/^(\s*)!!!(\s*)$/))) { + if (this.isBlock('shtml')) { + this.setBlock(key).endBlock(); + } else { + this.startBlock('shtml', key); + } + return false; + } else if (this.isBlock('shtml')) { + this.setBlock(key); + return false; + } + } + return true; + }; + + Parser.prototype.parseBlockAhtml = function(block, key, line, state) { + var htmlTagAllRegExp, htmlTagRegExp, lastMatch, m, matches; + if (this.html) { + htmlTagRegExp = new RegExp("^\\s*<(" + this.blockHtmlTags + ")(\\s+[^>]*)?>", 'i'); + if (matches = line.match(htmlTagRegExp)) { + if (this.isBlock('ahtml')) { + this.setBlock(key); + return false; + } else if (matches[2] === void 0 || matches[2] !== '/') { + this.startBlock('ahtml', key); + htmlTagAllRegExp = new RegExp("\\s*<(" + this.blockHtmlTags + ")(\\s+[^>]*)?>", 'ig'); + while (true) { + m = htmlTagAllRegExp.exec(line); + if (!m) { + break; + } + lastMatch = m[1]; + } + if (0 <= line.indexOf("" + lastMatch + ">")) { + this.endBlock(); + } else { + state.html = lastMatch; + } + return false; + } + } else if (!!state.html && 0 <= line.indexOf("" + state.html + ">")) { + this.setBlock(key).endBlock(); + state.html = false; + return false; + } else if (this.isBlock('ahtml')) { + this.setBlock(key); + return false; + } else if (!!(matches = line.match(/^\s*\s*$/))) { + this.startBlock('ahtml', key).endBlock(); + return false; + } + } + return true; + }; + + Parser.prototype.parseBlockMath = function(block, key, line) { + var matches; + if (!!(matches = line.match(/^(\s*)\$\$(\s*)$/))) { + if (this.isBlock('math')) { + this.setBlock(key).endBlock(); + } else { + this.startBlock('math', key); + } + return false; + } else if (this.isBlock('math')) { + this.setBlock(key); + return false; + } + return true; + }; + + Parser.prototype.parseBlockPre = function(block, key, line, state) { + if (!!(line.match(/^ {4}/))) { + if (this.isBlock('pre')) { + this.setBlock(key); + } else { + this.startBlock('pre', key); + } + return false; + } else if ((this.isBlock('pre')) && line.match(/^\s*$/)) { + this.setBlock(key); + return false; + } + return true; + }; + + Parser.prototype.parseBlockHtml = function(block, key, line, state) { + var matches, tag; + if (!!(matches = line.match(new RegExp("^\\s*<(" + state.special + ")(\\s+[^>]*)?>", 'i')))) { + tag = matches[1].toLowerCase(); + if (!(this.isBlock('html', tag)) && !(this.isBlock('pre'))) { + this.startBlock('html', key, tag); + } + return false; + } else if (!!(matches = line.match(new RegExp("(" + state.special + ")>\\s*$", 'i')))) { + tag = matches[1].toLowerCase(); + if (this.isBlock('html', tag)) { + this.setBlock(key).endBlock(); + } + return false; + } else if (this.isBlock('html')) { + this.setBlock(key); + return false; + } + return true; + }; + + Parser.prototype.parseBlockFootnote = function(block, key, line) { + var matches, space; + if (!!(matches = line.match(/^\[\^((?:[^\]]|\\\]|\\\[)+?)\]:/))) { + space = matches[0].length - 1; + this.startBlock('footnote', key, [space, matches[1]]); + return false; + } + return true; + }; + + Parser.prototype.parseBlockDefinition = function(block, key, line) { + var matches; + if (!!(matches = line.match(/^\s*\[((?:[^\]]|\\\]|\\\[)+?)\]:\s*(.+)$/))) { + this.definitions[matches[1]] = this.cleanUrl(matches[2]); + this.startBlock('definition', key).endBlock(); + return false; + } + return true; + }; + + Parser.prototype.parseBlockQuote = function(block, key, line) { + var matches; + if (!!(matches = line.match(/^(\s*)>/))) { + if ((this.isBlock('list')) && matches[1].length > 0) { + this.setBlock(key); + } else if (this.isBlock('quote')) { + this.setBlock(key); + } else { + this.startBlock('quote', key); + } + return false; + } + return true; + }; + + Parser.prototype.parseBlockTable = function(block, key, line, state, lines) { + var align, aligns, head, j, len, matches, row, rows; + if (!!(matches = line.match(/^((?:(?:(?:\||\+)(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:[ :]*\-+[ :]*)(?:\||\+)(?:[ :]*\-+[ :]*))|(?:(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:\||\+)(?:[ :]*\-+[ :]*)))+)$/))) { + if (this.isBlock('table')) { + block[3][0].push(block[3][2]); + block[3][2] += 1; + this.setBlock(key, block[3]); + } else { + head = 0; + if ((block == null) || block[0] !== 'normal' || lines[block[2]].match(/^\s*$/)) { + this.startBlock('table', key); + } else { + head = 1; + this.backBlock(1, 'table'); + } + if (matches[1][0] === '|') { + matches[1] = matches[1].substring(1); + if (matches[1][matches[1].length - 1] === '|') { + matches[1] = matches[1].substring(0, matches[1].length - 1); + } + } + rows = matches[1].split(/\+|\|/); + aligns = []; + for (j = 0, len = rows.length; j < len; j++) { + row = rows[j]; + align = 'none'; + if (!!(matches = row.match(/^\s*(:?)\-+(:?)\s*$/))) { + if (!!matches[1] && !!matches[2]) { + align = 'center'; + } else if (!!matches[1]) { + align = 'left'; + } else if (!!matches[2]) { + align = 'right'; + } + } + aligns.push(align); + } + this.setBlock(key, [[head], aligns, head + 1]); + } + return false; + } + return true; + }; + + Parser.prototype.parseBlockSh = function(block, key, line) { + var matches, num; + if (!!(matches = line.match(/^(#+)(.*)$/))) { + num = Math.min(matches[1].length, 6); + this.startBlock('sh', key, num).endBlock(); + return false; + } + return true; + }; + + Parser.prototype.parseBlockMh = function(block, key, line, state, lines) { + var matches; + if (!!(matches = line.match(/^\s*((=|-){2,})\s*$/)) && ((block != null) && block[0] === 'normal' && !lines[block[2]].match(/^\s*$/))) { + if (this.isBlock('normal')) { + this.backBlock(1, 'mh', matches[1][0] === '=' ? 1 : 2).setBlock(key).endBlock(); + } else { + this.startBlock('normal', key); + } + return false; + } + return true; + }; + + Parser.prototype.parseBlockShr = function(block, key, line) { + if (!!(line.match(/^(\* *){3,}\s*$/))) { + this.startBlock('hr', key).endBlock(); + return false; + } + return true; + }; + + Parser.prototype.parseBlockDhr = function(block, key, line) { + if (!!(line.match(/^(- *){3,}\s*$/))) { + this.startBlock('hr', key).endBlock(); + return false; + } + return true; + }; + + Parser.prototype.parseBlockDefault = function(block, key, line, state) { + var matches; + if (this.isBlock('footnote')) { + matches = line.match(/^(\s*)/); + if (matches[1].length >= block[3][0]) { + this.setBlock(key); + } else { + this.startBlock('normal', key); + } + } else if (this.isBlock('table')) { + if (0 <= line.indexOf('|')) { + block[3][2] += 1; + this.setBlock(key, block[3]); + } else { + this.startBlock('normal', key); + } + } else if (this.isBlock('quote')) { + if (!line.match(/^(\s*)$/)) { + this.setBlock(key); + } else { + this.startBlock('normal', key); + } + } else { + if ((block == null) || block[0] !== 'normal') { + this.startBlock('normal', key); + } else { + this.setBlock(key); + } + } + return true; + }; + + Parser.prototype.optimizeBlocks = function(_blocks, _lines) { + var block, blocks, from, isEmpty, key, lines, moved, nextBlock, prevBlock, to, type, types; + blocks = _blocks.slice(0); + lines = _lines.slice(0); + blocks = this.call('beforeOptimizeBlocks', blocks, lines); + key = 0; + while (blocks[key] != null) { + moved = false; + block = blocks[key]; + prevBlock = blocks[key - 1] != null ? blocks[key - 1] : null; + nextBlock = blocks[key + 1] != null ? blocks[key + 1] : null; + type = block[0], from = block[1], to = block[2]; + if ('pre' === type) { + isEmpty = (lines.slice(block[1], block[2] + 1)).reduce(function(result, line) { + return (line.match(/^\s*$/)) && result; + }, true); + if (isEmpty) { + block[0] = type = 'normal'; + } + } + if ('normal' === type) { + types = ['list', 'quote']; + if (from === to && (lines[from].match(/^\s*$/)) && (prevBlock != null) && (nextBlock != null)) { + if (prevBlock[0] === nextBlock[0] && (types.indexOf(prevBlock[0])) >= 0) { + blocks[key - 1] = [prevBlock[0], prevBlock[1], nextBlock[2], null]; + blocks.splice(key, 2); + moved = true; + } + } + } + if (!moved) { + key += 1; + } + } + return this.call('afterOptimizeBlocks', blocks, lines); + }; + + Parser.prototype.parseCode = function(lines, parts, start) { + var blank, count, isEmpty, lang, rel, str; + blank = parts[0], lang = parts[1]; + lang = trim(lang); + count = blank.length; + if (!lang.match(/^[_a-z0-9-\+\#\:\.]+$/i)) { + lang = null; + } else { + parts = lang.split(':'); + if (parts.length > 1) { + lang = parts[0], rel = parts[1]; + lang = trim(lang); + rel = trim(rel); + } + } + isEmpty = true; + lines = lines.slice(1, -1).map(function(line) { + line = line.replace(new RegExp("/^[ ]{" + count + "}/"), ''); + if (isEmpty && !line.match(/^\s*$/)) { + isEmpty = false; + } + return htmlspecialchars(line); + }); + str = (this.markLines(lines, start + 1)).join("\n"); + if (isEmpty) { + return ''; + } else { + return ''; + } + }; + + Parser.prototype.parsePre = function(lines, value, start) { + var str; + lines = lines.map(function(line) { + return htmlspecialchars(line.substring(4)); + }); + str = (this.markLines(lines, start)).join("\n"); + if (str.match(/^\s*$/)) { + return ''; + } else { + return '' + str + '
'; + } + }; + + Parser.prototype.parseAhtml = function(lines, value, start) { + return trim((this.markLines(lines, start)).join("\n")); + }; + + Parser.prototype.parseShtml = function(lines, value, start) { + return trim((this.markLines(lines.slice(1, -1), start + 1)).join("\n")); + }; + + Parser.prototype.parseMath = function(lines, value, start, end) { + return '' + str + '
' + (this.markLine(start, end)) + (htmlspecialchars(lines.join("\n"))) + '
'; + }; + + Parser.prototype.parseSh = function(lines, num, start, end) { + var line; + line = (this.markLine(start, end)) + this.parseInline(trim(lines[0], '# ')); + if (line.match(/^\s*$/)) { + return ''; + } else { + return "" + line + " "; + } + }; + + Parser.prototype.parseMh = function(lines, num, start, end) { + return this.parseSh(lines, num, start, end); + }; + + Parser.prototype.parseQuote = function(lines, value, start) { + var str; + lines = lines.map(function(line) { + return line.replace(/^\s*> ?/, ''); + }); + str = lines.join("\n"); + if (str.match(/^\s*$/)) { + return ''; + } else { + return '' + (this.parse(str, true, start)) + ''; + } + }; + + Parser.prototype.parseList = function(lines, value, start) { + var found, html, j, key, l, lastType, leftLines, leftStart, len, len1, line, matches, minSpace, row, rows, secondFound, secondMinSpace, space, text, type; + html = ''; + minSpace = 99999; + secondMinSpace = 99999; + found = false; + secondFound = false; + rows = []; + for (key = j = 0, len = lines.length; j < len; key = ++j) { + line = lines[key]; + if (matches = line.match(/^(\s*)((?:[0-9]+\.?)|\-|\+|\*)(\s+)(.*)$/i)) { + space = matches[1].length; + type = 0 <= '+-*'.indexOf(matches[2]) ? 'ul' : 'ol'; + minSpace = Math.min(space, minSpace); + found = true; + if (space > 0) { + secondMinSpace = Math.min(space, secondMinSpace); + secondFound = true; + } + rows.push([space, type, line, matches[4]]); + } else { + rows.push(line); + if (!!(matches = line.match(/^(\s*)/))) { + space = matches[1].length; + if (space > 0) { + secondMinSpace = Math.min(space, secondMinSpace); + secondFound = true; + } + } + } + } + minSpace = found ? minSpace : 0; + secondMinSpace = secondFound ? secondMinSpace : minSpace; + lastType = ''; + leftLines = []; + leftStart = 0; + for (key = l = 0, len1 = rows.length; l < len1; key = ++l) { + row = rows[key]; + if (row instanceof Array) { + space = row[0], type = row[1], line = row[2], text = row[3]; + if (space !== minSpace) { + leftLines.push(line.replace(new RegExp("^\\s{" + secondMinSpace + "}"), '')); + } else { + if (leftLines.length > 0) { + html += '- ' + (this.parse(leftLines.join("\n"), true, start + leftStart)) + '
'; + } + if (lastType !== type) { + if (!!lastType) { + html += "" + lastType + ">"; + } + html += "<" + type + ">"; + } + leftStart = key; + leftLines = [text]; + lastType = type; + } + } else { + leftLines.push(row.replace(new RegExp("^\\s{" + secondMinSpace + "}"), '')); + } + } + if (leftLines.length > 0) { + html += '- ' + (this.parse(leftLines.join("\n"), true, start + leftStart)) + ("
" + lastType + ">"); + } + return html; + }; + + Parser.prototype.parseTable = function(lines, value, start) { + var aligns, body, column, columns, head, html, ignores, j, key, l, last, len, len1, line, num, output, row, rows, tag, text; + ignores = value[0], aligns = value[1]; + head = ignores.length > 0 && (ignores.reduce(function(prev, curr) { + return curr + prev; + })) > 0; + html = ''; + body = head ? null : true; + output = false; + for (key = j = 0, len = lines.length; j < len; key = ++j) { + line = lines[key]; + if (0 <= ignores.indexOf(key)) { + if (head && output) { + head = false; + body = true; + } + continue; + } + line = trim(line); + output = true; + if (line[0] === '|') { + line = line.substring(1); + if (line[line.length - 1] === '|') { + line = line.substring(0, line.length - 1); + } + } + rows = line.split('|').map(function(row) { + if (row.match(/^\s*$/)) { + return ' '; + } else { + return trim(row); + } + }); + columns = {}; + last = -1; + for (l = 0, len1 = rows.length; l < len1; l++) { + row = rows[l]; + if (row.length > 0) { + last += 1; + columns[last] = [(columns[last] != null ? columns[last][0] + 1 : 1), row]; + } else if (columns[last] != null) { + columns[last][0] += 1; + } else { + columns[0] = [1, row]; + } + } + if (head) { + html += ''; + } else if (body) { + html += ''; + } + html += '
'; + }; + + Parser.prototype.parseHr = function(lines, value, start) { + if (this.line) { + return ''; + for (key in columns) { + column = columns[key]; + num = column[0], text = column[1]; + tag = head ? 'th' : 'td'; + html += "<" + tag; + if (num > 1) { + html += " colspan=\"" + num + "\""; + } + if ((aligns[key] != null) && aligns[key] !== 'none') { + html += " align=\"" + aligns[key] + "\""; + } + html += '>' + (this.parseInline(text)) + ("" + tag + ">"); + } + html += ' '; + if (head) { + html += ''; + } else if (body) { + body = false; + } + } + if (body !== null) { + html += ''; + } + return html += '
'; + } else { + return '
'; + } + }; + + Parser.prototype.parseNormal = function(lines, inline, start) { + var key, str; + if (inline == null) { + inline = false; + } + key = 0; + lines = lines.map((function(_this) { + return function(line) { + line = _this.parseInline(line); + if (!line.match(/^\s*$/)) { + line = (_this.markLine(start + key)) + line; + } + key += 1; + return line; + }; + })(this)); + str = trim(lines.join("\n")); + str = str.replace(/(\n\s*){2,}/g, ''); + str = str.replace(/\n/g, '
'); + if (str.match(/^\s*$/)) { + return ''; + } else { + if (inline) { + return str; + } else { + return "" + str + "
"; + } + } + }; + + Parser.prototype.parseFootnote = function(lines, value) { + var index, note, space; + space = value[0], note = value[1]; + index = this.footnotes.indexOf(note); + if (index >= 0) { + lines = lines.slice(0); + lines[0] = lines[0].replace(/^\[\^((?:[^\]]|\]|\[)+?)\]:/, ''); + this.footnotes[index] = lines; + } + return ''; + }; + + Parser.prototype.parseDefinition = function() { + return ''; + }; + + Parser.prototype.parseHtml = function(lines, type, start) { + lines = lines.map((function(_this) { + return function(line) { + return _this.parseInline(line, _this.specialWhiteList[type] != null ? _this.specialWhiteList[type] : ''); + }; + })(this)); + return (this.markLines(lines, start)).join("\n"); + }; + + Parser.prototype.cleanUrl = function(url) { + var matches, regexUrl, regexWord; + regexUrl = new RegExp("^\\s*((http|https|ftp|mailto):[" + pL + "_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&\\(\\)]+)", 'i'); + regexWord = new RegExp("^\\s*([" + pL + "_a-z0-9-:\\.\\*/%#!@\\?\\+=~\\|\\,&]+)", 'i'); + if (!!(matches = url.match(regexUrl))) { + return matches[1]; + } else if (!!(matches = url.match(regexWord))) { + return matches[1]; + } else { + return '#'; + } + }; + + Parser.prototype.escapeBracket = function(str) { + return str_replace(['\\[', '\\]', '\\(', '\\)'], ['[', ']', '(', ')'], str); + }; + + Parser.prototype.startBlock = function(type, start, value) { + if (value == null) { + value = null; + } + this.pos += 1; + this.current = type; + this.blocks.push([type, start, start, value]); + return this; + }; + + Parser.prototype.endBlock = function() { + this.current = 'normal'; + return this; + }; + + Parser.prototype.isBlock = function(type, value) { + if (value == null) { + value = null; + } + return this.current === type && (null === value ? true : this.blocks[this.pos][3] === value); + }; + + Parser.prototype.getBlock = function() { + if (this.blocks[this.pos] != null) { + return this.blocks[this.pos]; + } else { + return null; + } + }; + + Parser.prototype.setBlock = function(to, value) { + if (to == null) { + to = null; + } + if (value == null) { + value = null; + } + if (to !== null) { + this.blocks[this.pos][2] = to; + } + if (value !== null) { + this.blocks[this.pos][3] = value; + } + return this; + }; + + Parser.prototype.backBlock = function(step, type, value) { + var item, last; + if (value == null) { + value = null; + } + if (this.pos < 0) { + return this.startBlock(type, 0, value); + } + last = this.blocks[this.pos][2]; + this.blocks[this.pos][2] = last - step; + item = [type, last - step + 1, last, value]; + if (this.blocks[this.pos][1] <= this.blocks[this.pos][2]) { + this.pos += 1; + this.blocks.push(item); + } else { + this.blocks[this.pos] = item; + } + this.current = type; + return this; + }; + + Parser.prototype.combineBlock = function() { + var current, prev; + if (this.pos < 1) { + return this; + } + prev = this.blocks[this.pos - 1].slice(0); + current = this.blocks[this.pos].slice(0); + prev[2] = current[2]; + this.blocks[this.pos - 1] = prev; + this.current = prev[0]; + this.blocks = this.blocks.slice(0, -1); + this.pos -= 1; + return this; + }; + + return Parser; + + })(); + + if (typeof module !== "undefined" && module !== null) { + module.exports = Parser; + } else if (typeof window !== "undefined" && window !== null) { + window.HyperDown = Parser; + } + +}).call(this); diff --git a/admin/src/js/jquery-ui.js b/admin/src/js/jquery-ui.js new file mode 100644 index 00000000..5e24f394 --- /dev/null +++ b/admin/src/js/jquery-ui.js @@ -0,0 +1,4980 @@ +/*! jQuery UI - v1.10.3 - 2013-10-16 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.datepicker.js, jquery.ui.slider.js, jquery.ui.effect.js, jquery.ui.effect-highlight.js +* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ + +(function( $, undefined ) { + +var uuid = 0, + runiqueId = /^ui-id-\d+$/; + +// $.ui might exist from components with no dependencies, e.g., $.ui.position +$.ui = $.ui || {}; + +$.extend( $.ui, { + version: "1.10.3", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + focus: (function( orig ) { + return function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + orig.apply( this, arguments ); + }; + })( $.fn.focus ), + + scrollParent: function() { + var scrollParent; + if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } + + return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //+ value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + }, + + uniqueId: function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + (++uuid); + } + }); + }, + + removeUniqueId: function() { + return this.each(function() { + if ( runiqueId.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap=#" + mapName + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); +} + +function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support: jQuery <1.8 +if ( !$( "" ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) +if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); +} + + + + + +// deprecated +$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + +$.support.selectstart = "onselectstart" in document.createElement( "div" ); +$.fn.extend({ + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } +}); + +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use $.widget() extensions instead. + plugin: { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var i, + set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + // only used by resizable + hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + } +}); + +})( jQuery ); +(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + // accept selectors, DOM elements + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +})( jQuery ); +(function( $, undefined ) { + +var mouseHandled = false; +$( document ).mouseup( function() { + mouseHandled = false; +}); + +$.widget("ui.mouse", { + version: "1.10.3", + options: { + cancel: "input,textarea,button,select,option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind("mousedown."+this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind("click."+this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { + $.removeData(event.target, that.widgetName + ".preventClickEvent"); + event.stopImmediatePropagation(); + return false; + } + }); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.unbind("."+this.widgetName); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return; } + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if (!this.mouseDelayMet) { + this._mouseDelayTimer = setTimeout(function() { + that.mouseDelayMet = true; + }, this.options.delay); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = (this._mouseStart(event) !== false); + if (!this._mouseStarted) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { + $.removeData(event.target, this.widgetName + ".preventClickEvent"); + } + + // these delegates are required to keep context + this._mouseMoveDelegate = function(event) { + return that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + $(document) + .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .bind("mouseup."+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + return this._mouseUp(event); + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + + if (this._mouseStarted) { + this._mouseStarted = false; + + if (event.target === this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + ".preventClickEvent", true); + } + + this._mouseStop(event); + } + + return false; + }, + + _mouseDistanceMet: function(event) { + return (Math.max( + Math.abs(this._mouseDownEvent.pageX - event.pageX), + Math.abs(this._mouseDownEvent.pageY - event.pageY) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function(/* event */) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function(/* event */) {}, + _mouseDrag: function(/* event */) {}, + _mouseStop: function(/* event */) {}, + _mouseCapture: function(/* event */) { return true; } +}); + +})(jQuery); +(function( $, undefined ) { + +$.extend($.ui, { datepicker: { version: "1.10.3" } }); + +var PROP_NAME = "datepicker", + instActive; + +/* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Datepicker() { + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class + this._appendClass = "ui-datepicker-append"; // The name of the append marker class + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[""] = { // Default regional settings + closeText: "Done", // Display text for close link + prevText: "Prev", // Display text for previous month link + nextText: "Next", // Display text for next month link + currentText: "Today", // Display text for current month link + monthNames: ["January","February","March","April","May","June", + "July","August","September","October","November","December"], // Names of months for drop-down and formatting + monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting + dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting + dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting + dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday + weekHeader: "Wk", // Column header for week of the year + dateFormat: "mm/dd/yy", // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: "" // Additional text to append to the year in the month headers + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: "focus", // "focus" for popup on focus, + // "button" for trigger button, or "both" for either + showAnim: "fadeIn", // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: "", // Display text following the input box, e.g. showing the format + buttonText: "...", // Text for trigger button + buttonImage: "", // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: "c-10:c+10", // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: "+10", // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with "+" for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: "fast", // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: "", // Selector for an alternate field to store selected dates into + altFormat: "", // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend(this._defaults, this.regional[""]); + this.dpDiv = bindHover($("")); +} + +$.extend(Datepicker.prototype, { + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: "hasDatepicker", + + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, + + /* Override the default settings for all instances of the date picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + /* Attach the date picker to a jQuery selection. + * @param target element - the target input field or division or span + * @param settings object - the new settings to use for this date picker instance (anonymous) + */ + _attachDatepicker: function(target, settings) { + var nodeName, inline, inst; + nodeName = target.nodeName.toLowerCase(); + inline = (nodeName === "div" || nodeName === "span"); + if (!target.id) { + this.uuid += 1; + target.id = "dp" + this.uuid; + } + inst = this._newInst($(target), inline); + inst.settings = $.extend({}, settings || {}); + if (nodeName === "input") { + this._connectDatepicker(target, inst); + } else if (inline) { + this._inlineDatepicker(target, inst); + } + }, + + /* Create a new instance object. */ + _newInst: function(target, inline) { + var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars + return {id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: (!inline ? this.dpDiv : // presentation div + bindHover($("")))}; + }, + + /* Attach the date picker to an input field. */ + _connectDatepicker: function(target, inst) { + var input = $(target); + inst.append = $([]); + inst.trigger = $([]); + if (input.hasClass(this.markerClassName)) { + return; + } + this._attachments(input, inst); + input.addClass(this.markerClassName).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp); + this._autoSize(inst); + $.data(target, PROP_NAME, inst); + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, + + /* Make attachments based on settings. */ + _attachments: function(input, inst) { + var showOn, buttonText, buttonImage, + appendText = this._get(inst, "appendText"), + isRTL = this._get(inst, "isRTL"); + + if (inst.append) { + inst.append.remove(); + } + if (appendText) { + inst.append = $("" + appendText + ""); + input[isRTL ? "before" : "after"](inst.append); + } + + input.unbind("focus", this._showDatepicker); + + if (inst.trigger) { + inst.trigger.remove(); + } + + showOn = this._get(inst, "showOn"); + if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field + input.focus(this._showDatepicker); + } + if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked + buttonText = this._get(inst, "buttonText"); + buttonImage = this._get(inst, "buttonImage"); + inst.trigger = $(this._get(inst, "buttonImageOnly") ? + $("").addClass(this._triggerClass). + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : + $("").addClass(this._triggerClass). + html(!buttonImage ? buttonText : $("").attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? "before" : "after"](inst.trigger); + inst.trigger.click(function() { + if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { + $.datepicker._hideDatepicker(); + } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } else { + $.datepicker._showDatepicker(input[0]); + } + return false; + }); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, "autoSize") && !inst.inline) { + var findMax, max, maxI, i, + date = new Date(2009, 12 - 1, 20), // Ensure double digits + dateFormat = this._get(inst, "dateFormat"); + + if (dateFormat.match(/[DM]/)) { + findMax = function(names) { + max = 0; + maxI = 0; + for (i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + "monthNames" : "monthNamesShort")))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); + } + inst.input.attr("size", this._formatDate(inst, date).length); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function(target, inst) { + var divSpan = $(target); + if (divSpan.hasClass(this.markerClassName)) { + return; + } + divSpan.addClass(this.markerClassName).append(inst.dpDiv); + $.data(target, PROP_NAME, inst); + this._setDate(inst, this._getDefaultDate(inst), true); + this._updateDatepicker(inst); + this._updateAlternate(inst); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function(input, date, onSelect, settings, pos) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance + + if (!inst) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $(""); + this._dialogInput.keydown(this._doKeyDown); + $("body").append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], PROP_NAME, inst); + } + extendRemove(inst.settings, settings || {}); + date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); + + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); + if (!this._pos) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + } + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass(this._dialogClass); + this._showDatepicker(this._dialogInput[0]); + if ($.blockUI) { + $.blockUI(this.dpDiv); + } + $.data(this._dialogInput[0], PROP_NAME, inst); + return this; + }, + + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function(target) { + var nodeName, + $target = $(target), + inst = $.data(target, PROP_NAME); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData(target, PROP_NAME); + if (nodeName === "input") { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind("focus", this._showDatepicker). + unbind("keydown", this._doKeyDown). + unbind("keypress", this._doKeyPress). + unbind("keyup", this._doKeyUp); + } else if (nodeName === "div" || nodeName === "span") { + $target.removeClass(this.markerClassName).empty(); + } + }, + + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, PROP_NAME); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = false; + inst.trigger.filter("button"). + each(function() { this.disabled = false; }).end(). + filter("img").css({opacity: "1.0", cursor: ""}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().removeClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", false); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + }, + + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function(target) { + var nodeName, inline, + $target = $(target), + inst = $.data(target, PROP_NAME); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if (nodeName === "input") { + target.disabled = true; + inst.trigger.filter("button"). + each(function() { this.disabled = true; }).end(). + filter("img").css({opacity: "0.5", cursor: "default"}); + } else if (nodeName === "div" || nodeName === "span") { + inline = $target.children("." + this._inlineClass); + inline.children().addClass("ui-state-disabled"); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + prop("disabled", true); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value === target ? null : value); }); // delete entry + this._disabledInputs[this._disabledInputs.length] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function(target) { + if (!target) { + return false; + } + for (var i = 0; i < this._disabledInputs.length; i++) { + if (this._disabledInputs[i] === target) { + return true; + } + } + return false; + }, + + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function(target) { + try { + return $.data(target, PROP_NAME); + } + catch (err) { + throw "Missing instance data for this datepicker"; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function(target, name, value) { + var settings, date, minDate, maxDate, + inst = this._getInst(target); + + if (arguments.length === 2 && typeof name === "string") { + return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : + (inst ? (name === "all" ? $.extend({}, inst.settings) : + this._get(inst, name)) : null)); + } + + settings = name || {}; + if (typeof name === "string") { + settings = {}; + settings[name] = value; + } + + if (inst) { + if (this._curInst === inst) { + this._hideDatepicker(); + } + + date = this._getDateDatepicker(target, true); + minDate = this._getMinMaxDate(inst, "min"); + maxDate = this._getMinMaxDate(inst, "max"); + extendRemove(inst.settings, settings); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { + inst.settings.minDate = this._formatDate(inst, minDate); + } + if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { + inst.settings.maxDate = this._formatDate(inst, maxDate); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker(target); + } else { + this._enableDatepicker(target); + } + } + this._attachments($(target), inst); + this._autoSize(inst); + this._setDate(inst, date); + this._updateAlternate(inst); + this._updateDatepicker(inst); + } + }, + + // change method deprecated + _changeDatepicker: function(target, name, value) { + this._optionDatepicker(target, name, value); + }, + + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function(target) { + var inst = this._getInst(target); + if (inst) { + this._updateDatepicker(inst); + } + }, + + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function(target, date) { + var inst = this._getInst(target); + if (inst) { + this._setDate(inst, date); + this._updateDatepicker(inst); + this._updateAlternate(inst); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function(target, noDefault) { + var inst = this._getInst(target); + if (inst && !inst.inline) { + this._setDateFromField(inst, noDefault); + } + return (inst ? this._getDate(inst) : null); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(event) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst(event.target), + handled = true, + isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); + + inst._keyEvent = true; + if ($.datepicker._datepickerShowing) { + switch (event.keyCode) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv); + if (sel[0]) { + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + } + + onSelect = $.datepicker._get(inst, "onSelect"); + if (onSelect) { + dateStr = $.datepicker._formatDate(inst); + + // trigger custom callback + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + } else { + $.datepicker._hideDatepicker(); + } + + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + break; // next month/year on page down/+ ctrl + case 35: if (event.ctrlKey || event.metaKey) { + $.datepicker._clearDate(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if (event.ctrlKey || event.metaKey) { + $.datepicker._gotoToday(event.target); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, "stepBigMonths") : + -$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +left on Mac + break; + case 38: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, -7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); + } + handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right + if (event.originalEvent.altKey) { + $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, "stepBigMonths") : + +$.datepicker._get(inst, "stepMonths")), "M"); + } + // next month/year on alt +right + break; + case 40: if (event.ctrlKey || event.metaKey) { + $.datepicker._adjustDate(event.target, +7, "D"); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home + $.datepicker._showDatepicker(this); + } else { + handled = false; + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function(event) { + var chars, chr, + inst = $.datepicker._getInst(event.target); + + if ($.datepicker._get(inst, "constrainInput")) { + chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); + chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); + return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var date, + inst = $.datepicker._getInst(event.target); + + if (inst.input.val() !== inst.lastVal) { + try { + date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (err) { + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function(input) { + input = input.target || input; + if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger + input = $("input", input.parentNode)[0]; + } + + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here + return; + } + + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; + + inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst !== inst) { + $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } + } + + beforeShow = $.datepicker._get(inst, "beforeShow"); + beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + return; + } + extendRemove(inst.settings, beforeShowSettings); + + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField(inst); + + if ($.datepicker._inDialog) { // hide cursor + input.value = ""; + } + if (!$.datepicker._pos) { // position below input + $.datepicker._pos = $.datepicker._findPos(input); + $.datepicker._pos[1] += input.offsetHeight; // add the height + } + + isFixed = false; + $(input).parents().each(function() { + isFixed |= $(this).css("position") === "fixed"; + return !isFixed; + }); + + offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); + // determine sizing offscreen + inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); + $.datepicker._updateDatepicker(inst); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset(inst, offset, isFixed); + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? + "static" : (isFixed ? "fixed" : "absolute")), display: "none", + left: offset.left + "px", top: offset.top + "px"}); + + if (!inst.inline) { + showAnim = $.datepicker._get(inst, "showAnim"); + duration = $.datepicker._get(inst, "duration"); + inst.dpDiv.zIndex($(input).zIndex()+1); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); + } else { + inst.dpDiv[showAnim || "show"](showAnim ? duration : null); + } + + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function(inst) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + this._attachHandlers(inst); + inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); + + var origyearshtml, + numMonths = this._getNumberOfMonths(inst), + cols = numMonths[1], + width = 17; + + inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); + if (cols > 1) { + inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); + } + inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + + "Class"]("ui-datepicker-multi"); + inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + + "Class"]("ui-datepicker-rtl"); + + if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.focus(); + } + + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } + }, + + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function(inst, offset, isFixed) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), + viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); + + offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); + offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; + offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; + + // now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + var position, + inst = this._getInst(obj), + isRTL = this._get(inst, "isRTL"); + + while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { + obj = obj[isRTL ? "previousSibling" : "nextSibling"]; + } + + position = $(obj).offset(); + return [position.left, position.top]; + }, + + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function(input) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; + + if (!inst || (input && inst !== $.data(input, PROP_NAME))) { + return; + } + + if (this._datepickerShowing) { + showAnim = this._get(inst, "showAnim"); + duration = this._get(inst, "duration"); + postProcess = function() { + $.datepicker._tidyDialog(inst); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); + } else { + inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : + (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); + } + + if (!showAnim) { + postProcess(); + } + this._datepickerShowing = false; + + onClose = this._get(inst, "onClose"); + if (onClose) { + onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); + } + + this._lastInput = null; + if (this._inDialog) { + this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); + if ($.blockUI) { + $.unblockUI(); + $("body").append(this.dpDiv); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!$.datepicker._curInst) { + return; + } + + var $target = $(event.target), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id !== $.datepicker._mainDivId && + $target.parents("#" + $.datepicker._mainDivId).length === 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.closest("." + $.datepicker._triggerClass).length && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var target = $(id), + inst = this._getInst(target[0]); + + if (this._isDisabledDatepicker(target[0])) { + return; + } + this._adjustInstDate(inst, offset + + (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning + period); + this._updateDatepicker(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var date, + target = $(id), + inst = this._getInst(target[0]); + + if (this._get(inst, "gotoCurrent") && inst.currentDay) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var target = $(id), + inst = this._getInst(target[0]); + + inst["selected" + (period === "M" ? "Month" : "Year")] = + inst["draw" + (period === "M" ? "Month" : "Year")] = + parseInt(select.options[select.selectedIndex].value,10); + + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, month, year, td) { + var inst, + target = $(id); + + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + return; + } + + inst = this._getInst(target[0]); + inst.selectedDay = inst.currentDay = $("a", td).html(); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate(id, this._formatDate(inst, + inst.currentDay, inst.currentMonth, inst.currentYear)); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function(id) { + var target = $(id); + this._selectDate(target, ""); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var onSelect, + target = $(id), + inst = this._getInst(target[0]); + + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) { + inst.input.val(dateStr); + } + this._updateAlternate(inst); + + onSelect = this._get(inst, "onSelect"); + if (onSelect) { + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback + } else if (inst.input) { + inst.input.trigger("change"); // fire the change event + } + + if (inst.inline){ + this._updateDatepicker(inst); + } else { + this._hideDatepicker(); + this._lastInput = inst.input[0]; + if (typeof(inst.input[0]) !== "object") { + inst.input.focus(); // restore focus + } + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function(inst) { + var altFormat, date, dateStr, + altField = this._get(inst, "altField"); + + if (altField) { // update alternate field too + altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); + date = this._getDate(inst); + dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + $(altField).each(function() { $(this).val(dateStr); }); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), ""]; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function(date) { + var time, + checkDate = new Date(date.getTime()); + + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + + time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + }, + + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function (format, value, settings) { + if (format == null || value == null) { + throw "Invalid arguments"; + } + + value = (typeof value === "object" ? value.toString() : value + ""); + if (value === "") { + return null; + } + + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, + shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Extract a number from the string value + getNumber = function(match) { + var isDoubled = lookAhead(match), + size = (match === "@" ? 14 : (match === "!" ? 20 : + (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), + digits = new RegExp("^\\d{1," + size + "}"), + num = value.substring(iValue).match(digits); + if (!num) { + throw "Missing number at position " + iValue; + } + iValue += num[0].length; + return parseInt(num[0], 10); + }, + // Extract a name from the string value and convert to an index + getName = function(match, shortNames, longNames) { + var index = -1, + names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; + } + }); + if (index !== -1) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, + // Confirm that a literal character matches the string value + checkLiteral = function() { + if (value.charAt(iValue) !== format.charAt(iFormat)) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + day = getNumber("d"); + break; + case "D": + getName("D", dayNamesShort, dayNames); + break; + case "o": + doy = getNumber("o"); + break; + case "m": + month = getNumber("m"); + break; + case "M": + month = getName("M", monthNamesShort, monthNames); + break; + case "y": + year = getNumber("y"); + break; + case "@": + date = new Date(getNumber("@")); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date((getNumber("!") - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if (lookAhead("'")){ + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + + if (iValue < value.length){ + extra = value.substr(iValue); + if (!/^\s+/.test(extra)) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + + if (year === -1) { + year = new Date().getFullYear(); + } else if (year < 100) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + (year <= shortYearCutoff ? 0 : -100); + } + + if (doy > -1) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth(year, month - 1); + if (day <= dim) { + break; + } + month++; + day -= dim; + } while (true); + } + + date = this._daylightSavingAdjust(new Date(year, month - 1, day)); + if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { + throw "Invalid date"; // E.g. 31/02/00 + } + return date; + }, + + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 + + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function (format, date, settings) { + if (!date) { + return ""; + } + + var iFormat, + dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, + dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, + monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, + monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }, + // Format a number, with leading zero if necessary + formatNumber = function(match, value, len) { + var num = "" + value; + if (lookAhead(match)) { + while (num.length < len) { + num = "0" + num; + } + } + return num; + }, + // Format a name, short or long as requested + formatName = function(match, value, shortNames, longNames) { + return (lookAhead(match) ? longNames[value] : shortNames[value]); + }, + output = "", + literal = false; + + if (date) { + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + output += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": + output += formatNumber("d", date.getDate(), 2); + break; + case "D": + output += formatName("D", date.getDay(), dayNamesShort, dayNames); + break; + case "o": + output += formatNumber("o", + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + break; + case "m": + output += formatNumber("m", date.getMonth() + 1, 2); + break; + case "M": + output += formatName("M", date.getMonth(), monthNamesShort, monthNames); + break; + case "y": + output += (lookAhead("y") ? date.getFullYear() : + (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if (lookAhead("'")) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt(iFormat); + } + } + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function (format) { + var iFormat, + chars = "", + literal = false, + // Check whether a format character is doubled + lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); + if (matches) { + iFormat++; + } + return matches; + }; + + for (iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) { + if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + literal = false; + } else { + chars += format.charAt(iFormat); + } + } else { + switch (format.charAt(iFormat)) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if (lookAhead("'")) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt(iFormat); + } + } + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function(inst, name) { + return inst.settings[name] !== undefined ? + inst.settings[name] : this._defaults[name]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() === inst.lastVal) { + return; + } + + var dateFormat = this._get(inst, "dateFormat"), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate(inst), + date = defaultDate, + settings = this._getFormatConfig(inst); + + try { + date = this.parseDate(dateFormat, dates, settings) || defaultDate; + } catch (event) { + dates = (noDefault ? "" : dates); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = (dates ? date.getDate() : 0); + inst.currentMonth = (dates ? date.getMonth() : 0); + inst.currentYear = (dates ? date.getFullYear() : 0); + this._adjustInstDate(inst); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function(inst) { + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function(inst, date, defaultDate) { + var offsetNumeric = function(offset) { + var date = new Date(); + date.setDate(date.getDate() + offset); + return date; + }, + offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec(offset); + + while (matches) { + switch (matches[2] || "d") { + case "d" : case "D" : + day += parseInt(matches[1],10); break; + case "w" : case "W" : + day += parseInt(matches[1],10) * 7; break; + case "m" : case "M" : + month += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + case "y": case "Y" : + year += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + } + matches = pattern.exec(offset); + } + return new Date(year, month, day); + }, + newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : + (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + + newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + } + return this._daylightSavingAdjust(newDate); + }, + + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function(date) { + if (!date) { + return null; + } + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function(inst, date, noChange) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { + this._notifyChange(inst); + } + this._adjustInstDate(inst); + if (inst.input) { + inst.input.val(clear ? "" : this._formatDate(inst)); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function(inst) { + var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : + this._daylightSavingAdjust(new Date( + inst.currentYear, inst.currentMonth, inst.currentDay))); + return startDate; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, "stepMonths"), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find("[data-handler]").map(function () { + var handler = { + prev: function () { + $.datepicker._adjustDate(id, -stepMonths, "M"); + }, + next: function () { + $.datepicker._adjustDate(id, +stepMonths, "M"); + }, + hide: function () { + $.datepicker._hideDatepicker(); + }, + today: function () { + $.datepicker._gotoToday(id); + }, + selectDay: function () { + $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); + return false; + }, + selectMonth: function () { + $.datepicker._selectMonthYear(id, this, "M"); + return false; + }, + selectYear: function () { + $.datepicker._selectMonthYear(id, this, "Y"); + return false; + } + }; + $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); + }); + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function(inst) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time + isRTL = this._get(inst, "isRTL"), + showButtonPanel = this._get(inst, "showButtonPanel"), + hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), + navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), + numMonths = this._getNumberOfMonths(inst), + showCurrentAtPos = this._get(inst, "showCurrentAtPos"), + stepMonths = this._get(inst, "stepMonths"), + isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), + currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; + + if (drawMonth < 0) { + drawMonth += 12; + drawYear--; + } + if (maxDate) { + maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + drawMonth--; + if (drawMonth < 0) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + + prevText = this._get(inst, "prevText"); + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), + this._getFormatConfig(inst))); + + prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + "" : + (hideIfNoPrevNext ? "" : "")); + + nextText = this._get(inst, "nextText"); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + + next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + "" : + (hideIfNoPrevNext ? "" : "")); + + currentText = this._get(inst, "currentText"); + gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); + currentText = (!navigationAsDateFormat ? currentText : + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); + + controls = (!inst.inline ? "" : ""); + + buttonPanel = (showButtonPanel) ? " " : ""; + + firstDay = parseInt(this._get(inst, "firstDay"),10); + firstDay = (isNaN(firstDay) ? 0 : firstDay); + + showWeek = this._get(inst, "showWeek"); + dayNames = this._get(inst, "dayNames"); + dayNamesMin = this._get(inst, "dayNamesMin"); + monthNames = this._get(inst, "monthNames"); + monthNamesShort = this._get(inst, "monthNamesShort"); + beforeShowDay = this._get(inst, "beforeShowDay"); + showOtherMonths = this._get(inst, "showOtherMonths"); + selectOtherMonths = this._get(inst, "selectOtherMonths"); + defaultDate = this._getDefaultDate(inst); + html = ""; + dow; + for (row = 0; row < numMonths[0]; row++) { + group = ""; + this.maxRows = 4; + for (col = 0; col < numMonths[1]; col++) { + selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + cornerClass = " ui-corner-all"; + calender = ""; + if (isMultiMonth) { + calender += ""; + } + calender += "" + + ((numMonths[0] > 0 && col === numMonths[1]-1) ? "" : "") : ""); + group += calender; + } + html += group; + } + html += buttonPanel; + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { + + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get(inst, "changeMonth"), + changeYear = this._get(inst, "changeYear"), + showMonthAfterYear = this._get(inst, "showMonthAfterYear"), + html = "" + + "
" + (isMultiMonth ? ""; + thead = (showWeek ? " "; + daysInMonth = this._getDaysInMonth(drawYear, drawMonth); + if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + } + leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; + curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); + for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows + calender += "" + this._get(inst, "weekHeader") + " " : ""); + for (dow = 0; dow < 7; dow++) { // days of the week + day = (dow + firstDay) % 7; + thead += "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + + "" + dayNamesMin[day] + " "; + } + calender += thead + ""; + tbody = (!showWeek ? "" : " "; + } + drawMonth++; + if (drawMonth > 11) { + drawMonth = 0; + drawYear++; + } + calender += "" + + this._get(inst, "calculateWeek")(printDate) + " "); + for (dow = 0; dow < 7; dow++) { // create date picker days + daySettings = (beforeShowDay ? + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); + otherMonth = (printDate.getMonth() !== drawMonth); + unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody += "" + // actions + (otherMonth && !showOtherMonths ? " " : // display for other months + (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + " "; // display selectable date + printDate.setDate(printDate.getDate() + 1); + printDate = this._daylightSavingAdjust(printDate); + } + calender += tbody + "", + monthHtml = ""; + + // month selection + if (secondary || !changeMonth) { + monthHtml += "" + monthNames[drawMonth] + ""; + } else { + inMinYear = (minDate && minDate.getFullYear() === drawYear); + inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); + monthHtml += ""; + } + + if (!showMonthAfterYear) { + html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + } + + // year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if (secondary || !changeYear) { + html += "" + drawYear + ""; + } else { + // determine range of years to display + years = this._get(inst, "yearRange").split(":"); + thisYear = new Date().getFullYear(); + determineYear = function(value) { + var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + year = determineYear(years[0]); + endYear = Math.max(year, determineYear(years[1] || "")); + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + inst.yearshtml += ""; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + + html += this._get(inst, "yearSuffix"); + if (showMonthAfterYear) { + html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; + } + html += ""; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function(inst, offset, period) { + var year = inst.drawYear + (period === "Y" ? offset : 0), + month = inst.drawMonth + (period === "M" ? offset : 0), + day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), + date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if (period === "M" || period === "Y") { + this._notifyChange(inst); + } + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + newDate = (minDate && date < minDate ? minDate : date); + return (maxDate && newDate > maxDate ? maxDate : newDate); + }, + + /* Notify change of month/year. */ + _notifyChange: function(inst) { + var onChange = this._get(inst, "onChangeMonthYear"); + if (onChange) { + onChange.apply((inst.input ? inst.input[0] : null), + [inst.selectedYear, inst.selectedMonth + 1, inst]); + } + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function(inst) { + var numMonths = this._get(inst, "numberOfMonths"); + return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + "Date"), null); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(inst, offset, curYear, curMonth) { + var numMonths = this._getNumberOfMonths(inst), + date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + + if (offset < 0) { + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + } + return this._isInRange(inst, date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(inst, date) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate(inst, "min"), + maxDate = this._getMinMaxDate(inst, "max"), + minYear = null, + maxYear = null, + years = this._get(inst, "yearRange"); + if (years){ + yearSplit = years.split(":"); + currentYear = new Date().getFullYear(); + minYear = parseInt(yearSplit[0], 10); + maxYear = parseInt(yearSplit[1], 10); + if ( yearSplit[0].match(/[+\-].*/) ) { + minYear += currentYear; + } + if ( yearSplit[1].match(/[+\-].*/) ) { + maxYear += currentYear; + } + } + + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime()) && + (!minYear || date.getFullYear() >= minYear) && + (!maxYear || date.getFullYear() <= maxYear)); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function(inst) { + var shortYearCutoff = this._get(inst, "shortYearCutoff"); + shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + return {shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), + monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + }, + + /* Format the given date for display. */ + _formatDate: function(inst, day, month, year) { + if (!day) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = (day ? (typeof day === "object" ? day : + this._daylightSavingAdjust(new Date(year, month, day))) : + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + } +}); + +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function bindHover(dpDiv) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.delegate(selector, "mouseout", function() { + $(this).removeClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).removeClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).removeClass("ui-datepicker-next-hover"); + } + }) + .delegate(selector, "mouseover", function(){ + if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); + $(this).addClass("ui-state-hover"); + if (this.className.indexOf("ui-datepicker-prev") !== -1) { + $(this).addClass("ui-datepicker-prev-hover"); + } + if (this.className.indexOf("ui-datepicker-next") !== -1) { + $(this).addClass("ui-datepicker-next-hover"); + } + } + }); +} + +/* jQuery extend now ignores nulls! */ +function extendRemove(target, props) { + $.extend(target, props); + for (var name in props) { + if (props[name] == null) { + target[name] = props[name]; + } + } + return target; +} + +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function(options){ + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if (!$.datepicker.initialized) { + $(document).mousedown($.datepicker._checkExternalClick); + $.datepicker.initialized = true; + } + + /* Append datepicker main container to body if not exist. */ + if ($("#"+$.datepicker._mainDivId).length === 0) { + $("body").append($.datepicker.dpDiv); + } + + var otherArgs = Array.prototype.slice.call(arguments, 1); + if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { + return $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this[0]].concat(otherArgs)); + } + return this.each(function() { + typeof options === "string" ? + $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); +}; + +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.10.3"; + +})(jQuery); +(function( $, undefined ) { + +// number of pages in a slider +// (how many times can you page up/down to go through the whole range) +var numPages = 5; + +$.widget( "ui.slider", $.ui.mouse, { + version: "1.10.3", + widgetEventPrefix: "slide", + + options: { + animate: false, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null, + + // callbacks + change: null, + slide: null, + start: null, + stop: null + }, + + _create: function() { + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + + this.element + .addClass( "ui-slider" + + " ui-slider-" + this.orientation + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all"); + + this._refresh(); + this._setOption( "disabled", this.options.disabled ); + + this._animateOff = false; + }, + + _refresh: function() { + this._createRange(); + this._createHandles(); + this._setupEvents(); + this._refreshValue(); + }, + + _createHandles: function() { + var i, handleCount, + options = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), + handle = "", + handles = []; + + handleCount = ( options.values && options.values.length ) || 1; + + if ( existingHandles.length > handleCount ) { + existingHandles.slice( handleCount ).remove(); + existingHandles = existingHandles.slice( 0, handleCount ); + } + + for ( i = existingHandles.length; i < handleCount; i++ ) { + handles.push( handle ); + } + + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + + this.handle = this.handles.eq( 0 ); + + this.handles.each(function( i ) { + $( this ).data( "ui-slider-handle-index", i ); + }); + }, + + _createRange: function() { + var options = this.options, + classes = ""; + + if ( options.range ) { + if ( options.range === true ) { + if ( !options.values ) { + options.values = [ this._valueMin(), this._valueMin() ]; + } else if ( options.values.length && options.values.length !== 2 ) { + options.values = [ options.values[0], options.values[0] ]; + } else if ( $.isArray( options.values ) ) { + options.values = options.values.slice(0); + } + } + + if ( !this.range || !this.range.length ) { + this.range = $( "" ) + .appendTo( this.element ); + + classes = "ui-slider-range" + + // note: this isn't the most fittingly semantic framework class for this element, + // but worked best visually with a variety of themes + " ui-widget-header ui-corner-all"; + } else { + this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) + // Handle range switching from true to min/max + .css({ + "left": "", + "bottom": "" + }); + } + + this.range.addClass( classes + + ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); + } else { + this.range = $([]); + } + }, + + _setupEvents: function() { + var elements = this.handles.add( this.range ).filter( "a" ); + this._off( elements ); + this._on( elements, this._handleEvents ); + this._hoverable( elements ); + this._focusable( elements ); + }, + + _destroy: function() { + this.handles.remove(); + this.range.remove(); + + this.element + .removeClass( "ui-slider" + + " ui-slider-horizontal" + + " ui-slider-vertical" + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ); + + this._mouseDestroy(); + }, + + _mouseCapture: function( event ) { + var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, + that = this, + o = this.options; + + if ( o.disabled ) { + return false; + } + + this.elementSize = { + width: this.element.outerWidth(), + height: this.element.outerHeight() + }; + this.elementOffset = this.element.offset(); + + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + this.handles.each(function( i ) { + var thisDistance = Math.abs( normValue - that.values(i) ); + if (( distance > thisDistance ) || + ( distance === thisDistance && + (i === that._lastChangedValue || that.values(i) === o.min ))) { + distance = thisDistance; + closestHandle = $( this ); + index = i; + } + }); + + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; + } + this._mouseSliding = true; + + this._handleIndex = index; + + closestHandle + .addClass( "ui-state-active" ) + .focus(); + + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); + this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - + ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + + ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) + }; + + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); + } + this._animateOff = true; + return true; + }, + + _mouseStart: function() { + return true; + }, + + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); + + this._slide( event, this._handleIndex, normValue ); + + return false; + }, + + _mouseStop: function( event ) { + this.handles.removeClass( "ui-state-active" ); + this._mouseSliding = false; + + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); + + this._handleIndex = null; + this._clickOffset = null; + this._animateOff = false; + + return false; + }, + + _detectOrientation: function() { + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + }, + + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; + + if ( this.orientation === "horizontal" ) { + pixelTotal = this.elementSize.width; + pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); + } else { + pixelTotal = this.elementSize.height; + pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); + } + + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; + } + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { + percentMouse = 1 - percentMouse; + } + + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; + + return this._trimAlignValue( valueMouse ); + }, + + _start: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + return this._trigger( "start", event, uiHash ); + }, + + _slide: function( event, index, newVal ) { + var otherVal, + newValues, + allowed; + + if ( this.options.values && this.options.values.length ) { + otherVal = this.values( index ? 0 : 1 ); + + if ( ( this.options.values.length === 2 && this.options.range === true ) && + ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + ) { + newVal = otherVal; + } + + if ( newVal !== this.values( index ) ) { + newValues = this.values(); + newValues[ index ] = newVal; + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal, + values: newValues + } ); + otherVal = this.values( index ? 0 : 1 ); + if ( allowed !== false ) { + this.values( index, newVal, true ); + } + } + } else { + if ( newVal !== this.value() ) { + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal + } ); + if ( allowed !== false ) { + this.value( newVal ); + } + } + } + }, + + _stop: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "stop", event, uiHash ); + }, + + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + //store the last changed value index for reference when handles overlap + this._lastChangedValue = index; + + this._trigger( "change", event, uiHash ); + } + }, + + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); + return; + } + + return this._value(); + }, + + values: function( index, newValue ) { + var vals, + newValues, + i; + + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); + return; + } + + if ( arguments.length ) { + if ( $.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); + } else { + if ( this.options.values && this.options.values.length ) { + return this._values( index ); + } else { + return this.value(); + } + } + } else { + return this._values(); + } + }, + + _setOption: function( key, value ) { + var i, + valsLength = 0; + + if ( key === "range" && this.options.range === true ) { + if ( value === "min" ) { + this.options.value = this._values( 0 ); + this.options.values = null; + } else if ( value === "max" ) { + this.options.value = this._values( this.options.values.length-1 ); + this.options.values = null; + } + } + + if ( $.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "orientation": + this._detectOrientation(); + this.element + .removeClass( "ui-slider-horizontal ui-slider-vertical" ) + .addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + for ( i = 0; i < valsLength; i += 1 ) { + this._change( null, i ); + } + this._animateOff = false; + break; + case "min": + case "max": + this._animateOff = true; + this._refreshValue(); + this._animateOff = false; + break; + case "range": + this._animateOff = true; + this._refresh(); + this._animateOff = false; + break; + } + }, + + //internal value getter + // _value() returns value trimmed by min and max, aligned by step + _value: function() { + var val = this.options.value; + val = this._trimAlignValue( val ); + + return val; + }, + + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; + + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); + + return val; + } else if ( this.options.values && this.options.values.length ) { + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i+= 1) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); + } + + return vals; + } else { + return []; + } + }, + + // returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val <= this._valueMin() ) { + return this._valueMin(); + } + if ( val >= this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = (val - this._valueMin()) % step, + alignValue = val - valModStep; + + if ( Math.abs(valModStep) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); + } + + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed(5) ); + }, + + _valueMin: function() { + return this.options.min; + }, + + _valueMax: function() { + return this.options.max; + }, + + _refreshValue: function() { + var lastValPercent, valPercent, value, valueMin, valueMax, + oRange = this.options.range, + o = this.options, + that = this, + animate = ( !this._animateOff ) ? o.animate : false, + _set = {}; + + if ( this.options.values && this.options.values.length ) { + this.handles.each(function( i ) { + valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; + _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( that.options.range === true ) { + if ( that.orientation === "horizontal" ) { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } else { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + } + lastValPercent = valPercent; + }); + } else { + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + }, + + _handleEvents: { + keydown: function( event ) { + /*jshint maxcomplexity:25*/ + var allowed, curVal, newVal, step, + index = $( event.target ).data( "ui-slider-handle-index" ); + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + event.preventDefault(); + if ( !this._keySliding ) { + this._keySliding = true; + $( event.target ).addClass( "ui-state-active" ); + allowed = this._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = this.options.step; + if ( this.options.values && this.options.values.length ) { + curVal = newVal = this.values( index ); + } else { + curVal = newVal = this.value(); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = this._valueMin(); + break; + case $.ui.keyCode.END: + newVal = this._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === this._valueMax() ) { + return; + } + newVal = this._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === this._valueMin() ) { + return; + } + newVal = this._trimAlignValue( curVal - step ); + break; + } + + this._slide( event, index, newVal ); + }, + click: function( event ) { + event.preventDefault(); + }, + keyup: function( event ) { + var index = $( event.target ).data( "ui-slider-handle-index" ); + + if ( this._keySliding ) { + this._keySliding = false; + this._stop( event, index ); + this._change( event, index ); + $( event.target ).removeClass( "ui-state-active" ); + } + } + } + +}); + +}(jQuery)); +(function($, undefined) { + +var dataSpace = "ui-effects-"; + +$.effects = { + effect: {} +}; + +/*! + * jQuery Color Animations v2.1.2 + * https://github.com/jquery/jquery-color + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: Wed Jan 16 08:47:09 2013 -0600 + */ +(function( jQuery, undefined ) { + + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + + // plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + // a set of RE's that can match strings and generate color tuples. + stringParsers = [{ + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ], + execResult[ 3 ], + execResult[ 4 ] + ]; + } + }, { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, + execResult[ 4 ] + ]; + } + }, { + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ) + ]; + } + }, { + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) + ]; + } + }, { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + space: "hsla", + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] + ]; + } + }], + + // jQuery.Color( ) + color = jQuery.Color = function( color, green, blue, alpha ) { + return new jQuery.Color.fn.parse( color, green, blue, alpha ); + }, + spaces = { + rgba: { + props: { + red: { + idx: 0, + type: "byte" + }, + green: { + idx: 1, + type: "byte" + }, + blue: { + idx: 2, + type: "byte" + } + } + }, + + hsla: { + props: { + hue: { + idx: 0, + type: "degrees" + }, + saturation: { + idx: 1, + type: "percent" + }, + lightness: { + idx: 2, + type: "percent" + } + } + } + }, + propTypes = { + "byte": { + floor: true, + max: 255 + }, + "percent": { + max: 1 + }, + "degrees": { + mod: 360, + floor: true + } + }, + support = color.support = {}, + + // element for support tests + supportElem = jQuery( "" )[ 0 ], + + // colors = jQuery.Color.names + colors, + + // local aliases of functions called often + each = jQuery.each; + +// determine rgba support immediately +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + +// define cache name and alpha properties +// for rgba and hsla spaces +each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 + }; +}); + +function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return (allowEmpty || !prop.def) ? null : prop.def; + } + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; + } + + if ( type.mod ) { + // we add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return (value + type.mod) % type.mod; + } + + // for now all property types without mod have min and max + return 0 > value ? 0 : type.max < value ? type.max : value; +} + +function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; + + string = string.toLowerCase(); + + each( stringParsers, function( i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; + + if ( values ) { + parsed = inst[ spaceName ]( values ); + + // if this was an rgba parse the assignment might happen twice + // oh well.... + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + rgba = inst._rgba = parsed._rgba; + + // exit each( stringParsers ) here because we matched + return false; + } + }); + + // Found a stringParser that handled it + if ( rgba.length ) { + + // if this came from a parsed string, force "transparent" when alpha is 0 + // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) + if ( rgba.join() === "0,0,0,0" ) { + jQuery.extend( rgba, colors.transparent ); + } + return inst; + } + + // named colors + return colors[ string ]; +} + +color.fn = jQuery.extend( color.prototype, { + parse: function( red, green, blue, alpha ) { + if ( red === undefined ) { + this._rgba = [ null, null, null, null ]; + return this; + } + if ( red.jquery || red.nodeType ) { + red = jQuery( red ).css( green ); + green = undefined; + } + + var inst = this, + type = jQuery.type( red ), + rgba = this._rgba = []; + + // more than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } + + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } + + if ( type === "array" ) { + each( spaces.rgba.props, function( key, prop ) { + rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + }); + return this; + } + + if ( type === "object" ) { + if ( red instanceof color ) { + each( spaces, function( spaceName, space ) { + if ( red[ space.cache ] ) { + inst[ space.cache ] = red[ space.cache ].slice(); + } + }); + } else { + each( spaces, function( spaceName, space ) { + var cache = space.cache; + each( space.props, function( key, prop ) { + + // if the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { + + // if the value was null, we don't need to copy it + // if the key was alpha, we don't need to copy it either + if ( key === "alpha" || red[ key ] == null ) { + return; + } + inst[ cache ] = space.to( inst._rgba ); + } + + // this is the only case where we allow nulls for ALL properties. + // call clamp with alwaysAllowEmpty + inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); + }); + + // everything defined but alpha? + if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + // use the default of 1 + inst[ cache ][ 3 ] = 1; + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + }); + } + return this; + } + }, + is: function( compare ) { + var is = color( compare ), + same = true, + inst = this; + + each( spaces, function( _, space ) { + var localCache, + isCache = is[ space.cache ]; + if (isCache) { + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; + each( space.props, function( _, prop ) { + if ( isCache[ prop.idx ] != null ) { + same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); + return same; + } + }); + } + return same; + }); + return same; + }, + _space: function() { + var used = [], + inst = this; + each( spaces, function( spaceName, space ) { + if ( inst[ space.cache ] ) { + used.push( spaceName ); + } + }); + return used.pop(); + }, + transition: function( other, distance ) { + var end = color( other ), + spaceName = end._space(), + space = spaces[ spaceName ], + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), + result = start.slice(); + + end = end[ space.cache ]; + each( space.props, function( key, prop ) { + var index = prop.idx, + startValue = start[ index ], + endValue = end[ index ], + type = propTypes[ prop.type ] || {}; + + // if null, don't override start value + if ( endValue === null ) { + return; + } + // if null - use end + if ( startValue === null ) { + result[ index ] = endValue; + } else { + if ( type.mod ) { + if ( endValue - startValue > type.mod / 2 ) { + startValue += type.mod; + } else if ( startValue - endValue > type.mod / 2 ) { + startValue -= type.mod; + } + } + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + } + }); + return this[ spaceName ]( result ); + }, + blend: function( opaque ) { + // if we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } + + var rgb = this._rgba.slice(), + a = rgb.pop(), + blend = color( opaque )._rgba; + + return color( jQuery.map( rgb, function( v, i ) { + return ( 1 - a ) * blend[ i ] + a * v; + })); + }, + toRgbaString: function() { + var prefix = "rgba(", + rgba = jQuery.map( this._rgba, function( v, i ) { + return v == null ? ( i > 2 ? 1 : 0 ) : v; + }); + + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } + + return prefix + rgba.join() + ")"; + }, + toHslaString: function() { + var prefix = "hsla(", + hsla = jQuery.map( this.hsla(), function( v, i ) { + if ( v == null ) { + v = i > 2 ? 1 : 0; + } + + // catch 1 and 2 + if ( i && i < 3 ) { + v = Math.round( v * 100 ) + "%"; + } + return v; + }); + + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; + } + return prefix + hsla.join() + ")"; + }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); + + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); + } + + return "#" + jQuery.map( rgba, function( v ) { + + // default to 0 when nulls exist + v = ( v || 0 ).toString( 16 ); + return v.length === 1 ? "0" + v : v; + }).join(""); + }, + toString: function() { + return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + } +}); +color.fn.parse.prototype = color.fn; + +// hsla conversions adapted from: +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 + +function hue2rgb( p, q, h ) { + h = ( h + 1 ) % 1; + if ( h * 6 < 1 ) { + return p + (q - p) * h * 6; + } + if ( h * 2 < 1) { + return q; + } + if ( h * 3 < 2 ) { + return p + (q - p) * ((2/3) - h) * 6; + } + return p; +} + +spaces.hsla.to = function ( rgba ) { + if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { + return [ null, null, null, rgba[ 3 ] ]; + } + var r = rgba[ 0 ] / 255, + g = rgba[ 1 ] / 255, + b = rgba[ 2 ] / 255, + a = rgba[ 3 ], + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + diff = max - min, + add = max + min, + l = add * 0.5, + h, s; + + if ( min === max ) { + h = 0; + } else if ( r === max ) { + h = ( 60 * ( g - b ) / diff ) + 360; + } else if ( g === max ) { + h = ( 60 * ( b - r ) / diff ) + 120; + } else { + h = ( 60 * ( r - g ) / diff ) + 240; + } + + // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% + // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) + if ( diff === 0 ) { + s = 0; + } else if ( l <= 0.5 ) { + s = diff / add; + } else { + s = diff / ( 2 - add ); + } + return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; +}; + +spaces.hsla.from = function ( hsla ) { + if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { + return [ null, null, null, hsla[ 3 ] ]; + } + var h = hsla[ 0 ] / 360, + s = hsla[ 1 ], + l = hsla[ 2 ], + a = hsla[ 3 ], + q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, + p = 2 * l - q; + + return [ + Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), + Math.round( hue2rgb( p, q, h ) * 255 ), + Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), + a + ]; +}; + + +each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; + + // makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { + + // generate a cache for this space if it doesn't exist + if ( to && !this[ cache ] ) { + this[ cache ] = to( this._rgba ); + } + if ( value === undefined ) { + return this[ cache ].slice(); + } + + var ret, + type = jQuery.type( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); + + each( props, function( key, prop ) { + var val = arr[ type === "object" ? key : prop.idx ]; + if ( val == null ) { + val = local[ prop.idx ]; + } + local[ prop.idx ] = clamp( val, prop ); + }); + + if ( from ) { + ret = color( from( local ) ); + ret[ cache ] = local; + return ret; + } else { + return color( local ); + } + }; + + // makes red() green() blue() alpha() hue() saturation() lightness() + each( props, function( key, prop ) { + // alpha is included in more than one space + if ( color.fn[ key ] ) { + return; + } + color.fn[ key ] = function( value ) { + var vtype = jQuery.type( value ), + fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), + local = this[ fn ](), + cur = local[ prop.idx ], + match; + + if ( vtype === "undefined" ) { + return cur; + } + + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = jQuery.type( value ); + } + if ( value == null && prop.empty ) { + return this; + } + if ( vtype === "string" ) { + match = rplusequals.exec( value ); + if ( match ) { + value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + } + } + local[ prop.idx ] = value; + return this[ fn ]( local ); + }; + }); +}); + +// add cssHook and .fx.step function for each named hook. +// accept a space separated string of properties +color.hook = function( hook ) { + var hooks = hook.split( " " ); + each( hooks, function( i, hook ) { + jQuery.cssHooks[ hook ] = { + set: function( elem, value ) { + var parsed, curElem, + backgroundColor = ""; + + if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { + value = color( parsed || value ); + if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + curElem = hook === "backgroundColor" ? elem.parentNode : elem; + while ( + (backgroundColor === "" || backgroundColor === "transparent") && + curElem && curElem.style + ) { + try { + backgroundColor = jQuery.css( curElem, "backgroundColor" ); + curElem = curElem.parentNode; + } catch ( e ) { + } + } + + value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + backgroundColor : + "_default" ); + } + + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch( e ) { + // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' + } + } + }; + jQuery.fx.step[ hook ] = function( fx ) { + if ( !fx.colorInit ) { + fx.start = color( fx.elem, hook ); + fx.end = color( fx.end ); + fx.colorInit = true; + } + jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); + }; + }); + +}; + +color.hook( stepHooks ); + +jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; + + each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { + expanded[ "border" + part + "Color" ] = value; + }); + return expanded; + } +}; + +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. +colors = jQuery.Color.names = { + // 4.1. Basic color keywords + aqua: "#00ffff", + black: "#000000", + blue: "#0000ff", + fuchsia: "#ff00ff", + gray: "#808080", + green: "#008000", + lime: "#00ff00", + maroon: "#800000", + navy: "#000080", + olive: "#808000", + purple: "#800080", + red: "#ff0000", + silver: "#c0c0c0", + teal: "#008080", + white: "#ffffff", + yellow: "#ffff00", + + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], + + _default: "#ffffff" +}; + +})( jQuery ); + + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ +(function() { + +var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + +$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; +}); + +function getElementStyles( elem ) { + var key, len, + style = elem.ownerDocument.defaultView ? + elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.currentStyle, + styles = {}; + + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + styles[ $.camelCase( key ) ] = style[ key ]; + } + } + // support: Opera, IE <9 + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + styles[ key ] = style[ key ]; + } + } + } + + return styles; +} + + +function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; + + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] !== value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } + + return diff; +} + +// support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +$.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + applyClassChange, + allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + + // map the animated objects to store the original styles. + allAnimations = allAnimations.map(function() { + var el = $( this ); + return { + el: el, + start: getElementStyles( this ) + }; + }); + + // apply class change + applyClassChange = function() { + $.each( classAnimationActions, function(i, action) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + }); + }; + applyClassChange(); + + // map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map(function() { + this.end = getElementStyles( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + }); + + // apply original class + animated.attr( "class", baseClass ); + + // map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map(function() { + var styleInfo = this, + dfd = $.Deferred(), + opts = $.extend({}, o, { + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + }); + + this.el.animate( this.diff, opts ); + return dfd.promise(); + }); + + // once all animations have completed: + $.when.apply( $, allAnimations.get() ).done(function() { + + // set the final class + applyClassChange(); + + // for each animated element, + // clear all css properties that were animated + $.each( arguments, function() { + var el = this.el; + $.each( this.diff, function(key) { + el.css( key, "" ); + }); + }); + + // this is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + }); + }); +}; + +$.fn.extend({ + addClass: (function( orig ) { + return function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.call( this, + { add: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + })( $.fn.addClass ), + + removeClass: (function( orig ) { + return function( classNames, speed, easing, callback ) { + return arguments.length > 1 ? + $.effects.animateClass.call( this, + { remove: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + })( $.fn.removeClass ), + + toggleClass: (function( orig ) { + return function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { + // without speed parameter + return orig.apply( this, arguments ); + } else { + return $.effects.animateClass.call( this, + (force ? { add: classNames } : { remove: classNames }), + speed, easing, callback ); + } + } else { + // without force parameter + return $.effects.animateClass.call( this, + { toggle: classNames }, force, speed, easing ); + } + }; + })( $.fn.toggleClass ), + + switchClass: function( remove, add, speed, easing, callback) { + return $.effects.animateClass.call( this, { + add: add, + remove: remove + }, speed, easing, callback ); + } +}); + +})(); + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +(function() { + +$.extend( $.effects, { + version: "1.10.3", + + // Saves a set of properties in a data storage + save: function( element, set ) { + for( var i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + var val, i; + for( i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + // support: jQuery 1.6.2 + // http://bugs.jquery.com/ticket/9917 + // jQuery 1.6.2 incorrectly returns undefined for any falsy value. + // We can't differentiate between "" and 0 here, so we just assume + // empty string since it's likely to be a more common value... + if ( val === undefined ) { + val = ""; + } + element.css( set[ i ], val ); + } + } + }, + + setMode: function( el, mode ) { + if (mode === "toggle") { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + // this should be a little more flexible in the future to handle a string & hash + getBaseline: function( origin, original ) { + var y, x; + switch ( origin[ 0 ] ) { + case "top": y = 0; break; + case "middle": y = 0.5; break; + case "bottom": y = 1; break; + default: y = origin[ 0 ] / original.height; + } + switch ( origin[ 1 ] ) { + case "left": x = 0; break; + case "center": x = 0.5; break; + case "right": x = 1; break; + default: x = origin[ 1 ] / original.width; + } + return { + x: x, + y: y + }; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { + + // if the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" )) { + return element.parent(); + } + + // wrap the element + var props = { + width: element.outerWidth(true), + height: element.outerHeight(true), + "float": element.css( "float" ) + }, + wrapper = $( "
" ) + .addClass( "ui-effects-wrapper" ) + .css({ + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + }), + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + // support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + active.id; + } catch( e ) { + active = document.body; + } + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element + + // transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css({ position: "relative" }); + element.css({ position: "relative" }); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + }); + $.each([ "top", "left", "bottom", "right" ], function(i, pos) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; + } + }); + element.css({ + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + }); + } + element.css(size); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + } + + + return element; + }, + + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function( i, x ) { + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) { + value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + } + }); + return value; + } +}); + +// return an effect options object for the given parameters: +function _normalizeArguments( effect, options, speed, callback ) { + + // allow passing all options as the first parameter + if ( $.isPlainObject( effect ) ) { + options = effect; + effect = effect.effect; + } + + // convert to an object + effect = { effect: effect }; + + // catch (effect, null, ...) + if ( options == null ) { + options = {}; + } + + // catch (effect, callback) + if ( $.isFunction( options ) ) { + callback = options; + speed = null; + options = {}; + } + + // catch (effect, speed, ?) + if ( typeof options === "number" || $.fx.speeds[ options ] ) { + callback = speed; + speed = options; + options = {}; + } + + // catch (effect, options, callback) + if ( $.isFunction( speed ) ) { + callback = speed; + speed = null; + } + + // add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : + typeof speed === "number" ? speed : + speed in $.fx.speeds ? $.fx.speeds[ speed ] : + $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; +} + +function standardAnimationOption( option ) { + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + return true; + } + + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } + + // Complete callback + if ( $.isFunction( option ) ) { + return true; + } + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } + + // Didn't match any standard API + return false; +} + +$.fn.extend({ + effect: function( /* effect, options, speed, callback */ ) { + var args = _normalizeArguments.apply( this, arguments ), + mode = args.mode, + queue = args.queue, + effectMethod = $.effects.effect[ args.effect ]; + + if ( $.fx.off || !effectMethod ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, args.complete ); + } else { + return this.each( function() { + if ( args.complete ) { + args.complete.call( this ); + } + }); + } + } + + function run( next ) { + var elem = $( this ), + complete = args.complete, + mode = args.mode; + + function done() { + if ( $.isFunction( complete ) ) { + complete.call( elem[0] ); + } + if ( $.isFunction( next ) ) { + next(); + } + } + + // If the element already has the correct final state, delegate to + // the core methods so the internal tracking of "olddisplay" works. + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[0], args, done ); + } + } + + return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); + }, + + show: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + })( $.fn.show ), + + hide: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + })( $.fn.hide ), + + toggle: (function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }; + })( $.fn.toggle ), + + // helper functions + cssUnit: function(key) { + var style = this.css( key ), + val = []; + + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { + if ( style.indexOf( unit ) > 0 ) { + val = [ parseFloat( style ), unit ]; + } + }); + return val; + } +}); + +})(); + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + +(function() { + +// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) + +var baseEasings = {}; + +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; +}); + +$.extend( baseEasings, { + Sine: function ( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); + }, + Circ: function ( p ) { + return 1 - Math.sqrt( 1 - p * p ); + }, + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); + }, + Back: function( p ) { + return p * p * ( 3 * p - 2 ); + }, + Bounce: function ( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); + } +}); + +$.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < 0.5 ? + easeIn( p * 2 ) / 2 : + 1 - easeIn( p * -2 + 2 ) / 2; + }; +}); + +})(); + +})(jQuery); +(function( $, undefined ) { + +$.effects.effect.highlight = function( o, done ) { + var elem = $( this ), + props = [ "backgroundImage", "backgroundColor", "opacity" ], + mode = $.effects.setMode( elem, o.mode || "show" ), + animation = { + backgroundColor: elem.css( "backgroundColor" ) + }; + + if (mode === "hide") { + animation.opacity = 0; + } + + $.effects.save( elem, props ); + + elem + .show() + .css({ + backgroundImage: "none", + backgroundColor: o.color || "#ffff99" + }) + .animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + elem.hide(); + } + $.effects.restore( elem, props ); + done(); + } + }); +}; + +})(jQuery); diff --git a/admin/src/js/jquery.js b/admin/src/js/jquery.js new file mode 100644 index 00000000..7971feaa --- /dev/null +++ b/admin/src/js/jquery.js @@ -0,0 +1,9184 @@ +/*! + * jQuery JavaScript Library v2.1.1-rc2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-21T20:27Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var arr = []; + +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 support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.1-rc2", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: 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() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android < 4.0, iOS < 6 (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 ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + 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 ); + }, + + 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 value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var 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 +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = ""; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari:) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + 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; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // 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; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + 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; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +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 = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return 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.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + 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 jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return 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.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < 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; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Math.random(); +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android < 4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // 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) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(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, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = 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, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.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 = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + name = attrs[ i ].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // 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 + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.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 intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.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 = data_priv.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 cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + // Support: Windows Web Apps (WWA) + // `name` and `type` need .setAttribute for WWA + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE9-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.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; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && 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, false ); + } + } + } + + 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 = data_priv.hasData( elem ) && data_priv.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 the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.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; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG