From e2e06d0244fe83b632d127494d209769c2812dac Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 4 Jan 2023 19:42:41 +0000 Subject: [PATCH] Added `get-message` function, with simpler parameters. Also brought up to date, and fixed some stylistic errors noted by Kondo, and set the default locale to the runtime default locale. --- README.md | 80 ++- doc/intro.md | 84 ++- docs/MagrittePipe.jpeg | Bin 0 -> 34329 bytes docs/cloverage/codecov.json | 18 + docs/cloverage/coverage.css | 40 ++ docs/cloverage/coverage.xml | 1 + docs/cloverage/index.html | 42 ++ docs/cloverage/scot/weft/i18n/core.clj.html | 656 ++++++++++++++++++++ docs/codox/css/default.css | 551 ++++++++++++++++ docs/codox/css/highlight.css | 97 +++ docs/codox/index.html | 3 + docs/codox/intro.html | 87 +++ docs/codox/js/highlight.min.js | 2 + docs/codox/js/jquery.min.js | 4 + docs/codox/js/page_effects.js | 112 ++++ docs/codox/scot.weft.i18n.core.html | 30 + docs/index.html | 17 + project.clj | 24 +- resources/i18n/ru.edn | 3 + src/scot/weft/i18n/core.clj | 135 ++-- test/scot/weft/i18n/test/core.clj | 326 +++++----- 21 files changed, 2073 insertions(+), 239 deletions(-) create mode 100644 docs/MagrittePipe.jpeg create mode 100644 docs/cloverage/codecov.json create mode 100644 docs/cloverage/coverage.css create mode 100644 docs/cloverage/coverage.xml create mode 100644 docs/cloverage/index.html create mode 100644 docs/cloverage/scot/weft/i18n/core.clj.html create mode 100644 docs/codox/css/default.css create mode 100644 docs/codox/css/highlight.css create mode 100644 docs/codox/index.html create mode 100644 docs/codox/intro.html create mode 100644 docs/codox/js/highlight.min.js create mode 100644 docs/codox/js/jquery.min.js create mode 100644 docs/codox/js/page_effects.js create mode 100644 docs/codox/scot.weft.i18n.core.html create mode 100644 docs/index.html create mode 100644 resources/i18n/ru.edn diff --git a/README.md b/README.md index 21064bf..309c761 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,92 @@ A Clojure library designed to provide simple interationalisation of user-facing To use this library in your project, add the following leiningen dependency: - [org.clojars.simon_brooke/internationalisation "1.0.0"] + [org.clojars.simon_brooke/internationalisation "1.0.4"] To use it in your namespace, require: - [scot.weft.i18n.core :refer [get-messages]] + [scot.weft.i18n.core :refer [get-message get-messages]] -There is only one function you should need to use: +There is only two functions you may need to use: ### get-messages - (get-messages accept-language-header resource-path default-locale) +```clojure +(get-messages accept-language-header resource-path default-locale) +``` +Return the most acceptable messages collection we have given this `accept-language-header`. -Return the most acceptable messages collection we have given this accept-language-header. Use this function instrad of the unmemoized variant raw-get-messages, as performance will be very much better. +* `accept-language-header` should be a string representing the value of an RFC 2616 Accept-Language header; +* `resource-path` should be a string representing the fully-qualified path name of the directory in which message files are stored; +* `default-locale` should be a string representing a locale specifier to use if no acceptable locale can be identified. -* `accept-language-header` should be the value of an RFC 2616 Accept-Language header; -* `resource-path` should be the fully-qualified path name of the directory in which message files are stored; -* `default-locale` should be a locale specifier to use if no acceptable locale can be identified. +For example: +```clojure +(get-messages "en-GB;q=0.9, fr-FR" "i18n" "en-GB") +``` Returns a map of message keys to strings. See [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt). +**NOTE THAT** `get-messages` is [memoized](https://clojuredocs.org/clojure.core/memoize) resulting in faster response when called repeatedly with similar arguments. + +### get-message + +A wrapper around `get-messages` to resolve a single, particular message. +```clojure +(get-message token) + +(get-message token accept-language-header) + +(get-message token accept-language-header resource-path default-locale) +``` + +where + +* `token` is the Clojure [keyword](https://clojuredocs.org/clojure.core/keyword) which identifies the particular message you want to retrieve; + +and all the other arguments are as defined above. + +For example: +```clojure +(get-message :pipe) + +(get-message :pipe "en-GB;q=0.9, fr-FR") + +(get-message :pipe "de-DE" "i18n" "ru") +``` + +So how does this work? When one calls `(get-message token accept-language-header)`, how does it know where to find resources? The answer is that there are two dynamic variables: + +* `*resource-path*`, the default path within the resources space on which + translation files will be sought. Initialised to `i18n`. +* `*default-language*`, the language tag for the language to use when no + otherwise suitable language can be identified. Initialised to the default + language of the runtime session, so this may well be different on your + machine from someone elses running identical software. + +Thus +```clojure +(binding [*resource-path* "language-files" + *default-language* "en-CA"] + (get-message :pipe "en-GB;q=0.9, fr-FR") +) +``` +and +```clojure +(get-message :pipe "en-GB;q=0.9, fr-FR" "language-files" "en-CA") +``` +are effectively the same. + +The intelligent reader will note that if one calls +```clojure +(get-message :pipe) +``` +there's no mechanism to set the `accept-header`. This is true. The expected use case for this arity of the function is in desktop applications where the locale of the local machine will always be the correct locale to use. The two-argument arity of the function is intended for web applications, where different clients may have different linguistic needs. + +**NOTE THAT** `get-message` is also memoized, and for the same reason. + ## The translation files Obviously, this only works if you provide files with translations of your interesting strings. These files should contain Clojure maps, and the file names should be the locale string for which the file is relevent followed by the extension ".edn". All the translation files should be in the same directory. diff --git a/doc/intro.md b/doc/intro.md index f961eda..309c761 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -1,31 +1,97 @@ -# Introduction to internationalisation +# internationalisation + +A Clojure library designed to provide simple interationalisation of user-facing messages. ## Usage To use this library in your project, add the following leiningen dependency: - [org.clojars.simon_brooke/internationalisation "1.0.0"] + [org.clojars.simon_brooke/internationalisation "1.0.4"] To use it in your namespace, require: - [scot.weft.i18n.core :refer [get-messages]] + [scot.weft.i18n.core :refer [get-message get-messages]] -There is only one function you should need to use: +There is only two functions you may need to use: ### get-messages - (get-messages accept-language-header resource-path default-locale) +```clojure +(get-messages accept-language-header resource-path default-locale) +``` +Return the most acceptable messages collection we have given this `accept-language-header`. -Return the most acceptable messages collection we have given this accept-language-header. Use this function instrad of the unmemoized variant raw-get-messages, as performance will be very much better. +* `accept-language-header` should be a string representing the value of an RFC 2616 Accept-Language header; +* `resource-path` should be a string representing the fully-qualified path name of the directory in which message files are stored; +* `default-locale` should be a string representing a locale specifier to use if no acceptable locale can be identified. -* `accept-language-header` should be the value of an RFC 2616 Accept-Language header; -* `resource-path` should be the fully-qualified path name of the directory in which message files are stored; -* `default-locale` should be a locale specifier to use if no acceptable locale can be identified. +For example: +```clojure +(get-messages "en-GB;q=0.9, fr-FR" "i18n" "en-GB") +``` Returns a map of message keys to strings. See [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt). +**NOTE THAT** `get-messages` is [memoized](https://clojuredocs.org/clojure.core/memoize) resulting in faster response when called repeatedly with similar arguments. + +### get-message + +A wrapper around `get-messages` to resolve a single, particular message. +```clojure +(get-message token) + +(get-message token accept-language-header) + +(get-message token accept-language-header resource-path default-locale) +``` + +where + +* `token` is the Clojure [keyword](https://clojuredocs.org/clojure.core/keyword) which identifies the particular message you want to retrieve; + +and all the other arguments are as defined above. + +For example: +```clojure +(get-message :pipe) + +(get-message :pipe "en-GB;q=0.9, fr-FR") + +(get-message :pipe "de-DE" "i18n" "ru") +``` + +So how does this work? When one calls `(get-message token accept-language-header)`, how does it know where to find resources? The answer is that there are two dynamic variables: + +* `*resource-path*`, the default path within the resources space on which + translation files will be sought. Initialised to `i18n`. +* `*default-language*`, the language tag for the language to use when no + otherwise suitable language can be identified. Initialised to the default + language of the runtime session, so this may well be different on your + machine from someone elses running identical software. + +Thus +```clojure +(binding [*resource-path* "language-files" + *default-language* "en-CA"] + (get-message :pipe "en-GB;q=0.9, fr-FR") +) +``` +and +```clojure +(get-message :pipe "en-GB;q=0.9, fr-FR" "language-files" "en-CA") +``` +are effectively the same. + +The intelligent reader will note that if one calls +```clojure +(get-message :pipe) +``` +there's no mechanism to set the `accept-header`. This is true. The expected use case for this arity of the function is in desktop applications where the locale of the local machine will always be the correct locale to use. The two-argument arity of the function is intended for web applications, where different clients may have different linguistic needs. + +**NOTE THAT** `get-message` is also memoized, and for the same reason. + ## The translation files Obviously, this only works if you provide files with translations of your interesting strings. These files should contain Clojure maps, and the file names should be the locale string for which the file is relevent followed by the extension ".edn". All the translation files should be in the same directory. diff --git a/docs/MagrittePipe.jpeg b/docs/MagrittePipe.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..71bb3ab51f39e88be6e0623da3f08cb8f6062a9b GIT binary patch literal 34329 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 \ No newline at end of file diff --git a/docs/cloverage/index.html b/docs/cloverage/index.html new file mode 100644 index 0000000..7592895 --- /dev/null +++ b/docs/cloverage/index.html @@ -0,0 +1,42 @@ + + + + + Coverage Summary + + + + + + + + + + + + + + + + + + + + + + + + +
Namespace Forms Forms % Lines Lines %TotalBlankInstrumented
scot.weft.i18n.core
333
34
90.74 %
86
2
5
94.62 %2162393
Totals:90.74 %94.62 %
+ + diff --git a/docs/cloverage/scot/weft/i18n/core.clj.html b/docs/cloverage/scot/weft/i18n/core.clj.html new file mode 100644 index 0000000..01c1586 --- /dev/null +++ b/docs/cloverage/scot/weft/i18n/core.clj.html @@ -0,0 +1,656 @@ + + + + scot/weft/i18n/core.clj + + + + 001  (ns ^{:doc "Internationalisation." +
+ + 002        :author "Simon Brooke"} +
+ + 003   scot.weft.i18n.core +
+ + 004    (:require [clojure.java.io :as io] +
+ + 005              [clojure.pprint :refer [pprint]] +
+ + 006              [clojure.string :refer [join]] +
+ + 007              [instaparse.core :as insta] +
+ + 008              [taoensso.timbre :as timbre] +
+ + 009              [trptr.java-wrapper.locale :as locale]) +
+ + 010    (:import [clojure.lang Keyword])) +
+ + 011   +
+ + 012  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 013  ;;;; +
+ + 014  ;;;; scot.weft.i18n: a simple internationalisation library for Clojure. +
+ + 015  ;;;; +
+ + 016  ;;;; This library is distributed under the Eclipse Licence in the hope +
+ + 017  ;;;; that it may be useful, but without guarantee. +
+ + 018  ;;;; +
+ + 019  ;;;; Copyright (C) 2017 Simon Brooke +
+ + 020  ;;;; +
+ + 021  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 022   +
+ + 023  (def ^:dynamic *resource-path* +
+ + 024    "The default path within the resources space on which translation files  +
+ + 025     will be sought." +
+ + 026    "i18n") +
+ + 027   +
+ + 028  (def ^:dynamic *default-language* +
+ + 029    "The default language to seek." +
+ + 030    (-> (locale/get-default) locale/to-language-tag)) +
+ + 031   +
+ + 032  (def accept-language-grammar +
+ + 033    "Grammar for `Accept-Language` headers" +
+ + 034    "HEADER := SPECIFIER | SPECIFIERS; +
+ + 035    SPECIFIERS:= SPECIFIER | SPECIFIER SPEC-SEP SPECIFIERS; +
+ + 036    SPEC-SEP := #',\\s*'; +
+ + 037    SPECIFIER := LANGUAGE-TAG | LANGUAGE-TAG Q-SEP Q-VALUE; +
+ + 038    LANGUAGE-TAG := PRIMARY-TAG | PRIMARY-TAG '-' SUB-TAGS; +
+ + 039    PRIMARY-TAG := #'[a-zA-Z]+'; +
+ + 040    SUB-TAGS := SUB-TAG | SUB-TAG '-' SUB-TAGS; +
+ + 041    SUB-TAG := #'[a-zA-Z0-9]+'; +
+ + 042    Q-SEP := #';\\s*q=' +
+ + 043    Q-VALUE := '1' | #'0.[0-9]+';") +
+ + 044   +
+ + 045  (def parse-accept-language-header +
+ + 046    "Parse an `Accept-Language` header" +
+ + 047    (insta/parser accept-language-grammar)) +
+ + 048   +
+ + 049  (defn generate-accept-languages +
+ + 050    "From a `parse-tree` generated by the `language-specifier-grammar`, generate +
+ + 051    a list of maps each having a `:language` key, a `:preference` key and a +
+ + 052    `:qualifier` key." +
+ + 053    {:doc/format :markdown} +
+ + 054    [parse-tree] +
+ + 055    (if +
+ + 056     (nil? parse-tree) +
+ + 057      nil +
+ + 058      (case +
+ + 059       (first parse-tree) +
+ + 060        :HEADER (generate-accept-languages (second parse-tree)) +
+ + 061        :SPECIFIERS (cons +
+ + 062                     (generate-accept-languages (second parse-tree)) +
+ + 063                     (when (>= (count parse-tree) 3) +
+ + 064                       (generate-accept-languages (nth parse-tree 3)))) +
+ + 065        :SPEC-SEP nil +
+ + 066        :SPECIFIER (assoc +
+ + 067                    (generate-accept-languages (second parse-tree)) +
+ + 068                    :preference +
+ + 069                    (if +
+ + 070                     (>= (count parse-tree) 3) +
+ + 071                      (generate-accept-languages (nth parse-tree 3)) +
+ + 072                      1)) +
+ + 073        :LANGUAGE-TAG (if +
+ + 074                       (>= (count parse-tree) 3) +
+ + 075                        (assoc +
+ + 076                         (generate-accept-languages (second parse-tree)) +
+ + 077                         :qualifier +
+ + 078                         (generate-accept-languages (nth parse-tree 3))) +
+ + 079                        (generate-accept-languages (second parse-tree))) +
+ + 080        :PRIMARY-TAG {:language (second parse-tree) :qualifier "*"} +
+ + 081        :SUB-TAGS (if +
+ + 082                   (>= (count parse-tree) 3) +
+ + 083                    (str +
+ + 084                     (generate-accept-languages (second parse-tree)) +
+ + 085                     "-" +
+ + 086                     (generate-accept-languages (nth parse-tree 3))) +
+ + 087                    (generate-accept-languages (second parse-tree))) +
+ + 088        :SUB-TAG (second parse-tree) +
+ + 089        :Q-SEP nil +
+ + 090        :Q-VALUE (read-string (second parse-tree)) +
+ + 091        ;; default +
+ + 092        (do +
+ + 093          (timbre/error "Unable to parse header.") +
+ + 094          nil)))) +
+ + 095   +
+ + 096  (defn acceptable-languages +
+ + 097    "Generate an ordered list of acceptable languages, most-preferred first. +
+ + 098   +
+ + 099    * `accept-language-header` should be the value of an RFC2616 `Accept-Language` header. +
+ + 100   +
+ + 101    Returns a list of maps as generated by `generate-accept-languages`, in descending order +
+ + 102    of preference." +
+ + 103    {:doc/format :markdown} +
+ + 104    [accept-language-header] +
+ + 105    (let [parse-tree (parse-accept-language-header accept-language-header)] +
+ + 106      (if (vector? parse-tree) +
+ + 107        (reverse +
+ + 108         (sort-by +
+ + 109          :preference +
+ + 110          (generate-accept-languages +
+ + 111           parse-tree))) +
+ + 112        (timbre/error "Failed to parse Accept-Language header '" accept-language-header "':\n" (str parse-tree))))) +
+ + 113   +
+ + 114   +
+ + 115  (defn slurp-resource +
+ + 116    "Slurp the resource of this name and return its contents as a string; but if it doesn't +
+ + 117     exist log the fact and return nil, rather than throwing an exception." +
+ + 118    [name] +
+ + 119    (try +
+ + 120      (slurp (io/resource name)) +
+ + 121      (catch Exception _ +
+ + 122        (timbre/error (str "Resource at " name " does not exist.")) +
+ + 123        nil))) +
+ + 124   +
+ + 125   +
+ + 126  (defn find-language-file-name +
+ + 127    "Find the name of a messages file on this resource path which matches this `language-spec`. +
+ + 128   +
+ + 129    * `language-spec` should be either a map as generated by `generate-accept-languages`, or +
+ + 130    else a string; +
+ + 131    * `resource-path` should be the path name of the directory in which message files are stored, +
+ + 132    within the resources on the classpath. +
+ + 133   +
+ + 134    Returns the name of an appropriate file if any is found, else nil." +
+ + 135    {:doc/format :markdown} +
+ + 136    [language-spec resource-path] +
+ + 137    (let [file-path (when +
+ + 138                     (string? language-spec) +
+ + 139                      (join +
+ + 140                       java.io.File/separator +
+ + 141                       [resource-path (str language-spec ".edn")])) +
+ + 142          contents (when file-path (slurp-resource file-path))] +
+ + 143      (cond +
+ + 144        contents +
+ + 145        file-path +
+ + 146        (map? language-spec) +
+ + 147        (or +
+ + 148         (find-language-file-name +
+ + 149          (str (:language language-spec) "-" (:qualifier language-spec)) +
+ + 150          resource-path) +
+ + 151         (find-language-file-name +
+ + 152          (:language language-spec) +
+ + 153          resource-path))))) +
+ + 154   +
+ + 155   +
+ + 156  (defn raw-get-messages +
+ + 157    "Return the most acceptable messages collection we have given this `accept-language-header`. +
+ + 158    Do not use this function directly, use the memoized variant `get-messages`, as performance +
+ + 159    will be very much better. +
+ + 160   +
+ + 161    * `accept-language-header` should be the value of an RFC2616 `Accept-Language` header; +
+ + 162    * `resource-path` should be the fully-qualified path name of the directory in which +
+ + 163    message files are stored; +
+ + 164    * `default-locale` should be a locale specifier to use if no acceptable locale can be +
+ + 165    identified. +
+ + 166   +
+ + 167    Returns a map of message keys to strings; if no useable file is found, returns nil." +
+ + 168    {:doc/format :markdown} +
+ + 169    [^String accept-language-header ^String resource-path ^String default-locale] +
+ + 170    (let [file-path (first +
+ + 171                     (remove +
+ + 172                      nil? +
+ + 173                      (map +
+ + 174                       #(find-language-file-name % resource-path) +
+ + 175                       (acceptable-languages accept-language-header))))] +
+ + 176      (timbre/debug (str "Found i18n file at '" file-path "'")) +
+ + 177      (try +
+ + 178        (read-string +
+ + 179         (slurp-resource +
+ + 180          (or +
+ + 181           file-path +
+ + 182           (join java.io.File/separator +
+ + 183                 [resource-path +
+ + 184                  (str default-locale ".edn")])))) +
+ + 185        (catch Exception any +
+ + 186          (timbre/error (str "Failed to load internationalisation because " (.getMessage any))) +
+ + 187          nil)))) +
+ + 188   +
+ + 189  (def get-messages +
+ + 190    "Return the most acceptable messages collection we have given this `accept-language-header` +
+ + 191   +
+ + 192    * `accept-language-header` should be the value of an RFC2616 `Accept-Language` header; +
+ + 193    * `resource-path` should be the fully-qualified path name of the directory in which +
+ + 194    message files are stored; +
+ + 195    * `default-locale` should be a locale specifier to use if no acceptable locale can be +
+ + 196    identified. +
+ + 197   +
+ + 198    Returns a map of message keys to strings.; if no useable file is found, returns nil." +
+ + 199    (memoize raw-get-messages)) +
+ + 200   +
+ + 201  (def get-message +
+ + 202    "Return the message keyed by this `token` from the most acceptable messages collection   +
+ + 203     we have given this `accept-language-header`. +
+ + 204      +
+ + 205     * `token` should be a clojure keyword identifying the message to be retrieved; +
+ + 206     * `accept-language-header` should be the value of an RFC2616 `Accept-Language` header; +
+ + 207     * `resource-path` should be the fully-qualified path name of the directory in which +
+ + 208       message files are stored; +
+ + 209     * `default-locale` should be a locale specifier to use if no acceptable locale can be +
+ + 210       identified." +
+ + 211    (fn ([^Keyword token ^String accept-language-header ^String resource-path ^String default-locale] +
+ + 212         ((get-messages accept-language-header resource-path default-locale) token)) +
+ + 213      ([^Keyword token ^String accept-language-header] +
+ + 214       (get-message token accept-language-header *resource-path* *default-language*)) +
+ + 215      ([^Keyword token] +
+ + 216       (get-message token nil *resource-path* *default-language*)))) +
+ + diff --git a/docs/codox/css/default.css b/docs/codox/css/default.css new file mode 100644 index 0000000..33f78fe --- /dev/null +++ b/docs/codox/css/default.css @@ -0,0 +1,551 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 15px; +} + +pre, code { + font-family: Monaco, DejaVu Sans Mono, Consolas, monospace; + font-size: 9pt; + margin: 15px 0; +} + +h1 { + font-weight: normal; + font-size: 29px; + margin: 10px 0 2px 0; + padding: 0; +} + +h2 { + font-weight: normal; + font-size: 25px; +} + +h5.license { + margin: 9px 0 22px 0; + color: #555; + font-weight: normal; + font-size: 12px; + font-style: italic; +} + +.document h1, .namespace-index h1 { + font-size: 32px; + margin-top: 12px; +} + +#header, #content, .sidebar { + position: fixed; +} + +#header { + top: 0; + left: 0; + right: 0; + height: 22px; + color: #f5f5f5; + padding: 5px 7px; +} + +#content { + top: 32px; + right: 0; + bottom: 0; + overflow: auto; + background: #fff; + color: #333; + padding: 0 18px; +} + +.sidebar { + position: fixed; + top: 32px; + bottom: 0; + overflow: auto; +} + +.sidebar.primary { + background: #e2e2e2; + border-right: solid 1px #cccccc; + left: 0; + width: 250px; +} + +.sidebar.secondary { + background: #f2f2f2; + border-right: solid 1px #d7d7d7; + left: 251px; + width: 200px; +} + +#content.namespace-index, #content.document { + left: 251px; +} + +#content.namespace-docs { + left: 452px; +} + +#content.document { + padding-bottom: 10%; +} + +#header { + background: #3f3f3f; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); + z-index: 100; +} + +#header h1 { + margin: 0; + padding: 0; + font-size: 18px; + font-weight: lighter; + text-shadow: -1px -1px 0px #333; +} + +#header h1 .project-version { + font-weight: normal; +} + +.project-version { + padding-left: 0.15em; +} + +#header a, .sidebar a { + display: block; + text-decoration: none; +} + +#header a { + color: #f5f5f5; +} + +.sidebar a { + color: #333; +} + +#header h2 { + float: right; + font-size: 9pt; + font-weight: normal; + margin: 4px 3px; + padding: 0; + color: #bbb; +} + +#header h2 a { + display: inline; +} + +.sidebar h3 { + margin: 0; + padding: 10px 13px 0 13px; + font-size: 19px; + font-weight: lighter; +} + +.sidebar h3 a { + color: #444; +} + +.sidebar h3.no-link { + color: #636363; +} + +.sidebar ul { + padding: 7px 0 6px 0; + margin: 0; +} + +.sidebar ul.index-link { + padding-bottom: 4px; +} + +.sidebar li { + display: block; + vertical-align: middle; +} + +.sidebar li a, .sidebar li .no-link { + border-left: 3px solid transparent; + padding: 0 10px; + white-space: nowrap; +} + +.sidebar li .no-link { + display: block; + color: #777; + font-style: italic; +} + +.sidebar li .inner { + display: inline-block; + padding-top: 7px; + height: 24px; +} + +.sidebar li a, .sidebar li .tree { + height: 31px; +} + +.depth-1 .inner { padding-left: 2px; } +.depth-2 .inner { padding-left: 6px; } +.depth-3 .inner { padding-left: 20px; } +.depth-4 .inner { padding-left: 34px; } +.depth-5 .inner { padding-left: 48px; } +.depth-6 .inner { padding-left: 62px; } + +.sidebar li .tree { + display: block; + float: left; + position: relative; + top: -10px; + margin: 0 4px 0 0; + padding: 0; +} + +.sidebar li.depth-1 .tree { + display: none; +} + +.sidebar li .tree .top, .sidebar li .tree .bottom { + display: block; + margin: 0; + padding: 0; + width: 7px; +} + +.sidebar li .tree .top { + border-left: 1px solid #aaa; + border-bottom: 1px solid #aaa; + height: 19px; +} + +.sidebar li .tree .bottom { + height: 22px; +} + +.sidebar li.branch .tree .bottom { + border-left: 1px solid #aaa; +} + +.sidebar.primary li.current a { + border-left: 3px solid #a33; + color: #a33; +} + +.sidebar.secondary li.current a { + border-left: 3px solid #33a; + color: #33a; +} + +.namespace-index h2 { + margin: 30px 0 0 0; +} + +.namespace-index h3 { + font-size: 16px; + font-weight: bold; + margin-bottom: 0; +} + +.namespace-index .topics { + padding-left: 30px; + margin: 11px 0 0 0; +} + +.namespace-index .topics li { + padding: 5px 0; +} + +.namespace-docs h3 { + font-size: 18px; + font-weight: bold; +} + +.public h3 { + margin: 0; + float: left; +} + +.usage { + clear: both; +} + +.public { + margin: 0; + border-top: 1px solid #e0e0e0; + padding-top: 14px; + padding-bottom: 6px; +} + +.public:last-child { + margin-bottom: 20%; +} + +.members .public:last-child { + margin-bottom: 0; +} + +.members { + margin: 15px 0; +} + +.members h4 { + color: #555; + font-weight: normal; + font-variant: small-caps; + margin: 0 0 5px 0; +} + +.members .inner { + padding-top: 5px; + padding-left: 12px; + margin-top: 2px; + margin-left: 7px; + border-left: 1px solid #bbb; +} + +#content .members .inner h3 { + font-size: 12pt; +} + +.members .public { + border-top: none; + margin-top: 0; + padding-top: 6px; + padding-bottom: 0; +} + +.members .public:first-child { + padding-top: 0; +} + +h4.type, +h4.dynamic, +h4.added, +h4.deprecated { + float: left; + margin: 3px 10px 15px 0; + font-size: 15px; + font-weight: bold; + font-variant: small-caps; +} + +.public h4.type, +.public h4.dynamic, +.public h4.added, +.public h4.deprecated { + font-size: 13px; + font-weight: bold; + margin: 3px 0 0 10px; +} + +.members h4.type, +.members h4.added, +.members h4.deprecated { + margin-top: 1px; +} + +h4.type { + color: #717171; +} + +h4.dynamic { + color: #9933aa; +} + +h4.added { + color: #508820; +} + +h4.deprecated { + color: #880000; +} + +.namespace { + margin-bottom: 30px; +} + +.namespace:last-child { + margin-bottom: 10%; +} + +.index { + padding: 0; + font-size: 80%; + margin: 15px 0; + line-height: 16px; +} + +.index * { + display: inline; +} + +.index p { + padding-right: 3px; +} + +.index li { + padding-right: 5px; +} + +.index ul { + padding-left: 0; +} + +.type-sig { + clear: both; + color: #088; +} + +.type-sig pre { + padding-top: 10px; + margin: 0; +} + +.usage code { + display: block; + color: #008; + margin: 2px 0; +} + +.usage code:first-child { + padding-top: 10px; +} + +p { + margin: 15px 0; +} + +.public p:first-child, .public pre.plaintext { + margin-top: 12px; +} + +.doc { + margin: 0 0 26px 0; + clear: both; +} + +.public .doc { + margin: 0; +} + +.namespace-index .doc { + margin-bottom: 20px; +} + +.namespace-index .namespace .doc { + margin-bottom: 10px; +} + +.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td { + line-height: 22px; +} + +.markdown li { + padding: 2px 0; +} + +.markdown h2 { + font-weight: normal; + font-size: 25px; + margin: 30px 0 10px 0; +} + +.markdown h3 { + font-weight: normal; + font-size: 20px; + margin: 30px 0 0 0; +} + +.markdown h4 { + font-size: 15px; + margin: 22px 0 -4px 0; +} + +.doc, .public, .namespace .index { + max-width: 680px; + overflow-x: visible; +} + +.markdown pre > code { + display: block; + padding: 10px; +} + +.markdown pre > code, .src-link a { + border: 1px solid #e4e4e4; + border-radius: 2px; +} + +.markdown code:not(.hljs), .src-link a { + background: #f6f6f6; +} + +pre.deps { + display: inline-block; + margin: 0 10px; + border: 1px solid #e4e4e4; + border-radius: 2px; + padding: 10px; + background-color: #f6f6f6; +} + +.markdown hr { + border-style: solid; + border-top: none; + color: #ccc; +} + +.doc ul, .doc ol { + padding-left: 30px; +} + +.doc table { + border-collapse: collapse; + margin: 0 10px; +} + +.doc table td, .doc table th { + border: 1px solid #dddddd; + padding: 4px 6px; +} + +.doc table th { + background: #f2f2f2; +} + +.doc dl { + margin: 0 10px 20px 10px; +} + +.doc dl dt { + font-weight: bold; + margin: 0; + padding: 3px 0; + border-bottom: 1px solid #ddd; +} + +.doc dl dd { + padding: 5px 0; + margin: 0 0 5px 10px; +} + +.doc abbr { + border-bottom: 1px dotted #333; + font-variant: none; + cursor: help; +} + +.src-link { + margin-bottom: 15px; +} + +.src-link a { + font-size: 70%; + padding: 1px 4px; + text-decoration: none; + color: #5555bb; +} diff --git a/docs/codox/css/highlight.css b/docs/codox/css/highlight.css new file mode 100644 index 0000000..d0cdaa3 --- /dev/null +++ b/docs/codox/css/highlight.css @@ -0,0 +1,97 @@ +/* +github.com style (c) Vasily Polovnyov +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/docs/codox/index.html b/docs/codox/index.html new file mode 100644 index 0000000..9250ac2 --- /dev/null +++ b/docs/codox/index.html @@ -0,0 +1,3 @@ + +Internationalisation 1.0.3-SNAPSHOT

Internationalisation 1.0.3-SNAPSHOT

Released under the Eclipse Public License

Internationalisation library for Clojure.

Installation

To install, add the following dependency to your project or build file:

[org.clojars.simon_brooke/internationalisation "1.0.3-SNAPSHOT"]

Topics

Namespaces

\ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html new file mode 100644 index 0000000..a580553 --- /dev/null +++ b/docs/codox/intro.html @@ -0,0 +1,87 @@ + +internationalisation

internationalisation

+

A Clojure library designed to provide simple interationalisation of user-facing messages.

+

Usage

+

To use this library in your project, add the following leiningen dependency:

+
[org.clojars.simon_brooke/internationalisation "1.0.4"]
+
+

To use it in your namespace, require:

+
[scot.weft.i18n.core :refer [get-message get-messages]]
+
+

There is only two functions you may need to use:

+

get-messages

+
(get-messages accept-language-header resource-path default-locale)
+
+

Return the most acceptable messages collection we have given this accept-language-header.

+
    +
  • accept-language-header should be a string representing the value of an RFC 2616 Accept-Language header;
  • +
  • resource-path should be a string representing the fully-qualified path name of the directory in which message files are stored;
  • +
  • default-locale should be a string representing a locale specifier to use if no acceptable locale can be identified.
  • +
+

For example:

+
(get-messages "en-GB;q=0.9, fr-FR" "i18n" "en-GB")
+
+

Returns a map of message keys to strings.

+

See RFC 2616.

+

NOTE THAT get-messages is memoized resulting in faster response when called repeatedly with similar arguments.

+

get-message

+

A wrapper around get-messages to resolve a single, particular message.

+
(get-message token)
+
+(get-message token accept-language-header)
+
+(get-message token accept-language-header resource-path default-locale)
+
+

where

+
    +
  • token is the Clojure keyword which identifies the particular message you want to retrieve;
  • +
+

and all the other arguments are as defined above.

+

For example:

+
(get-message :pipe)
+
+(get-message :pipe "en-GB;q=0.9, fr-FR")
+
+(get-message :pipe "de-DE" "i18n" "ru")
+
+

So how does this work? When one calls (get-message token accept-language-header), how does it know where to find resources? The answer is that there are two dynamic variables:

+
    +
  • *resource-path*, the default path within the resources space on which translation files will be sought. Initialised to i18n.
  • +
  • *default-language*, the language tag for the language to use when no otherwise suitable language can be identified. Initialised to the default language of the runtime session, so this may well be different on your machine from someone elses running identical software.
  • +
+

Thus

+
(binding [*resource-path* "language-files"
+          *default-language* "en-CA"]
+    (get-message :pipe "en-GB;q=0.9, fr-FR")
+)
+
+

and

+
(get-message :pipe "en-GB;q=0.9, fr-FR" "language-files" "en-CA")
+
+

are effectively the same.

+

The intelligent reader will note that if one calls

+
(get-message :pipe)
+
+

there’s no mechanism to set the accept-header. This is true. The expected use case for this arity of the function is in desktop applications where the locale of the local machine will always be the correct locale to use. The two-argument arity of the function is intended for web applications, where different clients may have different linguistic needs.

+

NOTE THAT get-message is also memoized, and for the same reason.

+

The translation files

+

Obviously, this only works if you provide files with translations of your interesting strings. These files should contain Clojure maps, and the file names should be the locale string for which the file is relevent followed by the extension “.edn”. All the translation files should be in the same directory.

+

In this project you will find two very simple example files, which should give you the idea:

+

en-GB.edn

+
;;;; This is a British English translation file.
+
+{:pipe "This is not a pipe"}
+
+

fr-FR.edn

+
;;;; This is a French translation file.
+
+{:pipe "Ceci n'est pas une pipe."}
+
+

Documentation

+

Documentation may be generated by running

+
lein codox
+
+

License

+

Copyright © 2017 Simon Brooke

+

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

\ No newline at end of file diff --git a/docs/codox/js/highlight.min.js b/docs/codox/js/highlight.min.js new file mode 100644 index 0000000..6486ffd --- /dev/null +++ b/docs/codox/js/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.6.0 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||R(i))return i}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):E(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?"":y.classPrefix,i='',i+n+o}function p(){var e,t,r,a;if(!E.k)return n(B);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)a+=n(B.substr(t,r.index-t)),e=g(E,r),e?(M+=e[1],a+=h(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return a+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?B+=n:(a.rE||a.eE||(B+=n),b(),a.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=i||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substr(O,I.index-O),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},a=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n,t,r,o,s,p=i(e);a(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("clojure-repl",function(e){return{c:[{cN:"meta",b:/^([\w.-]+|\s*#_)=>/,starts:{e:/$/,sL:"clojure"}}]}}); \ No newline at end of file diff --git a/docs/codox/js/jquery.min.js b/docs/codox/js/jquery.min.js new file mode 100644 index 0000000..73f33fb --- /dev/null +++ b/docs/codox/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("