diff --git a/README.md b/README.md index e335a1c..5066abe 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,66 @@ LISP 1.5 is to all Lisp dialects as Beowulf is to Emglish literature. A work-in-progress towards an implementation of Lisp 1.5 in Clojure. The objective is to build a complete and accurate implementation of Lisp 1.5 as described in the manual, with, in so far as is possible, exactly the -same bahaviour; the only intended deviation is that the parser reads -'mexprs' (meta language expressions) as well as sexprs. +same bahaviour - except as documented below. -## BUT WHY?!!?! +### Status + +Boots to REPL, but few functions yet available. + +### Architectural plan + +Not everything documented in this section is yet built. It indicates the +direction of travel and intended destination, not the current state. + +#### resources/lisp1.5.lsp + +The objective is to have within `resources/lisp1.5.lsp`, all those functions +defined in the Lisp 1.5 Programmer's Manual which can be implemented in Lisp. + +This means that, while Beowulf is hosted on Clojure, all that would be +required to rehost Lisp 1.5 on a different platform would be to reimplement + +* bootstrap.clj +* host.clj +* read.clj + +The objective this is to make it fairly easy to implement Lisp 1.5 on top of +any of the many [Make A Lisp](https://github.com/kanaka/mal) +implementations. + +#### beowulf/boostrap.clj + +This file is essentially Lisp as defined in Chapter 1 (pages 1-14) of the +Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, +which should, I believe, be sufficient in conjunction with the functions +provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5 +interpreter. + +In addition it contains the function `INTEROP`, which allows host language +functions to be called from Lisp. + +#### beowulf/host.clj + +This file provides Lisp 1.5 functions which can't be (or can't efficiently +be) implemented in Lisp 1.5, which therefore need to be implemented in the +host language, in this case Clojure. + +#### beowulf/read.clj + +This file provides the reader required for boostrapping. It's not a bad +reader - it provides feedback on errors found in the input - but it isn't +the real Lisp reader. + +Intended deviations from the behaviour of the real Lisp reader are as follows: + +1. It reads the meta-expression language `MEXPR` in addition to the + symbolic expression language `SEXPR`, which I do not believe the Lisp 1.5 + reader ever did; +2. It treats everything between a semi-colon and an end of line as a comment, + as most modern Lisps do; but I do not believe Lisp 1.5 had this feature. + + +### BUT WHY?!!?! Because. @@ -23,9 +79,24 @@ for modern machines. Because I'm barking mad, and this is therapy. +### Commentary + +What's surprised me in working on this is how much more polished Lisp 1.5 is +than legend had led me to believe. The language is remarkably close to +[Portable Standard Lisp](http://www.softwarepreservation.org/projects/LISP/standard_lisp_family/#Portable_Standard_LISP_) +which is in my opinion one of the best and most usable early Lisp +implementations. I'm convinced you could still use Lisp 1.5 for interesting +and useful software (which isn't to say that some modern Lisps aren't better, +but this is software which is almost sixty years old). + + ## Installation -Download from http://example.com/FIXME. +At present, clone the source and build it using + +`lein uberjar`. + +You will require to have [Leiningen](https://leiningen.org/) installed. ## Usage @@ -41,6 +112,17 @@ The `Lisp 1.5 Programmer's Manual` is still [in print, ISBN 13 978-0-262-13011-0](https://mitpress.mit.edu/books/lisp-15-programmers-manual); but it's also [available online](http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf). +## Other Lisp 1.5 resources + +The main resource I'm aware of is the Software Preservation Society's site, +[here](http://www.softwarepreservation.org/projects/LISP/lisp1.5). It has lots +of fascinating stuff including full assembler listings for various obsolete +processors, but I failed to find the Lisp source of Lisp functions as a text +file, which is why `resources/lisp1.5.lsp` is largely copytyped and +reconstructed from the manual. + +I'm not at this time aware of any other working Lisp 1.5 implementations. + ## License Copyright © 2019 Simon Brooke. Licensed under the GNU General Public License, diff --git a/docs/cloverage/beowulf/bootstrap.clj.html b/docs/cloverage/beowulf/bootstrap.clj.html new file mode 100644 index 0000000..b8944e7 --- /dev/null +++ b/docs/cloverage/beowulf/bootstrap.clj.html @@ -0,0 +1,1022 @@ + + + + beowulf/bootstrap.clj + + + + 001  (ns beowulf.bootstrap +
+ + 002    "Lisp as defined in Chapter 1 (pages 1-14) of the +
+ + 003    `Lisp 1.5 Programmer's Manual`; that is to say, a very simple Lisp language, +
+ + 004    which should, I believe, be sufficient in conjunction with the functions +
+ + 005    provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5 +
+ + 006    interpreter.. +
+ + 007   +
+ + 008    The convention is adopted that functions in this file with names in +
+ + 009    ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that +
+ + 010    therefore all arguments must be numbers, symbols or `beowulf.cons_cell.ConsCell` +
+ + 011    objects." +
+ + 012    (:require [clojure.tools.trace :refer :all] +
+ + 013              [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL T F]])) +
+ + 014   +
+ + 015  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 016  ;;; +
+ + 017  ;;; This file is essentially Lisp as defined in Chapter 1 (pages 1-14) of the +
+ + 018  ;;; Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, +
+ + 019  ;;; which should, I believe, be sufficient in conjunction with the functions +
+ + 020  ;;; provided by `beowulf.host`, be sufficient to bootstrap the full Lisp 1.5 +
+ + 021  ;;; interpreter. +
+ + 022  ;;; +
+ + 023  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 024   +
+ + 025  (declare EVAL) +
+ + 026   +
+ + 027  (def oblist +
+ + 028    "The default environment." +
+ + 029    (atom NIL)) +
+ + 030   +
+ + 031  (def ^:dynamic *options* +
+ + 032    "Command line options from invocation." +
+ + 033    {}) +
+ + 034   +
+ + 035  (defmacro NULL +
+ + 036    "Returns `T` if and only if the argument `x` is bound to `NIL`; else `F`." +
+ + 037    [x] +
+ + 038    `(if (= ~x NIL) T F)) +
+ + 039   +
+ + 040  (defmacro ATOM +
+ + 041    "Returns `T` if and only is the argument `x` is bound to and atom; else `F`. +
+ + 042    It is not clear to me from the documentation whether `(ATOM 7)` should return +
+ + 043    `T` or `F`. I'm going to assume `T`." +
+ + 044    [x] +
+ + 045    `(if (or (symbol? ~x) (number? ~x)) T F)) +
+ + 046   +
+ + 047  (defmacro ATOM? +
+ + 048    "The convention of returning `F` from predicates, rather than `NIL`, is going +
+ + 049    to tie me in knots. This is a variant of `ATOM` which returns `NIL` +
+ + 050    on failure." +
+ + 051    [x] +
+ + 052    `(if (or (symbol? ~x) (number? ~x)) T NIL)) +
+ + 053   +
+ + 054  (defn CAR +
+ + 055    "Return the item indicated by the first pointer of a pair. NIL is treated +
+ + 056    specially: the CAR of NIL is NIL." +
+ + 057    [x] +
+ + 058    (cond +
+ + 059      (= x NIL) NIL +
+ + 060      (instance? beowulf.cons_cell.ConsCell x) (.CAR x) +
+ + 061      :else +
+ + 062      (throw +
+ + 063        (Exception. +
+ + 064          (str "Cannot take CAR of `" x "` (" (.getName (.getClass x)) ")"))))) +
+ + 065   +
+ + 066  (defn CDR +
+ + 067    "Return the item indicated by the second pointer of a pair. NIL is treated +
+ + 068    specially: the CDR of NIL is NIL." +
+ + 069    [x] +
+ + 070    (cond +
+ + 071      (= x NIL) NIL +
+ + 072      (instance? beowulf.cons_cell.ConsCell x) (.CDR x) +
+ + 073      :else +
+ + 074      (throw +
+ + 075        (Exception. +
+ + 076          (str "Cannot take CDR of `" x "` (" (.getName (.getClass x)) ")"))))) +
+ + 077   +
+ + 078  (defn uaf +
+ + 079    "Universal access function; `l` is expected to be an arbitrary list, `path` +
+ + 080    a (clojure) list of the characters `a` and `d`. Intended to make declaring +
+ + 081    all those fiddly `#'c[ad]+r'` functions a bit easier" +
+ + 082    [l path] +
+ + 083    (cond +
+ + 084      (= l NIL) NIL +
+ + 085      (empty? path) l +
+ + 086      :else (case (last path) +
+ + 087              \a (uaf (CAR l) (butlast path)) +
+ + 088              \d (uaf (CDR l) (butlast path))))) +
+ + 089   +
+ + 090  (defn CAAR [x] (uaf x (seq "aa"))) +
+ + 091  (defn CADR [x] (uaf x (seq "ad"))) +
+ + 092  (defn CDDR [x] (uaf x (seq "dd"))) +
+ + 093  (defn CDAR [x] (uaf x (seq "da"))) +
+ + 094   +
+ + 095  (defn CAAAR [x] (uaf x (seq "aaa"))) +
+ + 096  (defn CAADR [x] (uaf x (seq "aad"))) +
+ + 097  (defn CADAR [x] (uaf x (seq "ada"))) +
+ + 098  (defn CADDR [x] (uaf x (seq "add"))) +
+ + 099  (defn CDDAR [x] (uaf x (seq "dda"))) +
+ + 100  (defn CDDDR [x] (uaf x (seq "ddd"))) +
+ + 101  (defn CDAAR [x] (uaf x (seq "daa"))) +
+ + 102  (defn CDADR [x] (uaf x (seq "dad"))) +
+ + 103   +
+ + 104  (defn CAAAAR [x] (uaf x (seq "aaaa"))) +
+ + 105  (defn CAADAR [x] (uaf x (seq "aada"))) +
+ + 106  (defn CADAAR [x] (uaf x (seq "adaa"))) +
+ + 107  (defn CADDAR [x] (uaf x (seq "adda"))) +
+ + 108  (defn CDDAAR [x] (uaf x (seq "ddaa"))) +
+ + 109  (defn CDDDAR [x] (uaf x (seq "ddda"))) +
+ + 110  (defn CDAAAR [x] (uaf x (seq "daaa"))) +
+ + 111  (defn CDADAR [x] (uaf x (seq "dada"))) +
+ + 112  (defn CAAADR [x] (uaf x (seq "aaad"))) +
+ + 113  (defn CAADDR [x] (uaf x (seq "aadd"))) +
+ + 114  (defn CADADR [x] (uaf x (seq "adad"))) +
+ + 115  (defn CADDDR [x] (uaf x (seq "addd"))) +
+ + 116  (defn CDDADR [x] (uaf x (seq "ddad"))) +
+ + 117  (defn CDDDDR [x] (uaf x (seq "dddd"))) +
+ + 118  (defn CDAADR [x] (uaf x (seq "daad"))) +
+ + 119  (defn CDADDR [x] (uaf x (seq "dadd"))) +
+ + 120   +
+ + 121  (defn EQ +
+ + 122    "Returns `T` if and only if both `x` and `y` are bound to the same atom, +
+ + 123    else `F`." +
+ + 124    [x y] +
+ + 125    (if (and (= (ATOM x) T) (= x y)) T F)) +
+ + 126   +
+ + 127  (defn EQUAL +
+ + 128    "This is a predicate that is true if its two arguments are identical +
+ + 129    S-expressions, and false if they are different. (The elementary predicate +
+ + 130    `EQ` is defined only for atomic arguments.) The definition of `EQUAL` is +
+ + 131    an example of a conditional expression inside a conditional expression. +
+ + 132   +
+ + 133    NOTE: returns `F` on failure, not `NIL`" +
+ + 134    [x y] +
+ + 135    (cond +
+ + 136      (= (ATOM x) T) (EQ x y) +
+ + 137      (= (EQUAL (CAR x) (CAR y)) T) (EQUAL (CDR x) (CDR y)) +
+ + 138      :else F)) +
+ + 139   +
+ + 140  (defn SUBST +
+ + 141    "This function gives the result of substituting the S-expression `x` for +
+ + 142    all occurrences of the atomic symbol `y` in the S-expression `z`." +
+ + 143    [x y z] +
+ + 144    (cond +
+ + 145      (= (EQUAL y z) T) x +
+ + 146      (= (ATOM? z) T) z ;; NIL is a symbol +
+ + 147      :else +
+ + 148      (make-cons-cell (SUBST x y (CAR z)) (SUBST x y (CDR z))))) +
+ + 149   +
+ + 150  (defn APPEND +
+ + 151    "Append the the elements of `y` to the elements of `x`. +
+ + 152   +
+ + 153    All args are assumed to be `beowulf.cons-cell/ConsCell` objects. +
+ + 154    See page 11 of the Lisp 1.5 Programmers Manual." +
+ + 155    [x y] +
+ + 156    (cond +
+ + 157      (= x NIL) y +
+ + 158      :else +
+ + 159      (make-cons-cell (CAR x) (APPEND (CDR x) y)))) +
+ + 160   +
+ + 161   +
+ + 162  (defn MEMBER +
+ + 163    "This predicate is true if the S-expression `x` occurs among the elements +
+ + 164    of the list `y`. +
+ + 165   +
+ + 166    All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects. +
+ + 167    See page 11 of the Lisp 1.5 Programmers Manual." +
+ + 168    [x y] +
+ + 169    (cond +
+ + 170      (= y NIL) F ;; NOTE: returns F on falsity, not NIL +
+ + 171      (= (EQUAL x (CAR y)) T) T +
+ + 172      :else (MEMBER x (CDR y)))) +
+ + 173   +
+ + 174  (defn PAIRLIS +
+ + 175    "This function gives the list of pairs of corresponding elements of the +
+ + 176    lists `x` and `y`, and APPENDs this to the list `a`. The resultant list +
+ + 177    of pairs, which is like a table with two columns, is called an +
+ + 178    association list. +
+ + 179   +
+ + 180    Eessentially, it builds the environment on the stack, implementing shallow +
+ + 181    binding. +
+ + 182   +
+ + 183    All args are assumed to be `beowulf.cons-cell/ConsCell` objects. +
+ + 184    See page 12 of the Lisp 1.5 Programmers Manual." +
+ + 185    [x y a] +
+ + 186    (cond +
+ + 187      ;; the original tests only x; testing y as well will be a little more +
+ + 188      ;; robust if `x` and `y` are not the same length. +
+ + 189      (or (= NIL x) (= NIL y)) a +
+ + 190      :else (make-cons-cell +
+ + 191              (make-cons-cell (CAR x) (CAR y)) +
+ + 192              (PAIRLIS (CDR x) (CDR y) a)))) +
+ + 193   +
+ + 194  (defn ASSOC +
+ + 195    "If a is an association list such as the one formed by PAIRLIS in the above +
+ + 196    example, then assoc will produce the first pair whose first term is x. Thus +
+ + 197    it is a table searching function. +
+ + 198   +
+ + 199    All args are assumed to be `beowulf.cons-cell/ConsCell` objects. +
+ + 200    See page 12 of the Lisp 1.5 Programmers Manual." +
+ + 201    [x a] +
+ + 202    (cond +
+ + 203      (= NIL a) NIL ;; this clause is not present in the original but is added for +
+ + 204      ;; robustness. +
+ + 205      (= (EQUAL (CAAR a) x) T) (CAR a) +
+ + 206      :else +
+ + 207      (ASSOC x (CDR a)))) +
+ + 208   +
+ + 209  (defn- SUB2 +
+ + 210    "Internal to `SUBLIS`, q.v., which SUBSTitutes into a list from a store. +
+ + 211    ? I think this is doing variable binding in the stack frame?" +
+ + 212    [a z] +
+ + 213    (cond +
+ + 214      (= NIL a) z +
+ + 215      (= (CAAR a) z) (CDAR a) ;; TODO: this looks definitely wrong +
+ + 216      :else +
+ + 217      (SUB2 (CDR a) z))) +
+ + 218   +
+ + 219  (defn SUBLIS +
+ + 220    "Here `a` is assumed to be an association list of the form +
+ + 221    `((ul . vl)...(un . vn))`, where the `u`s are atomic, and `y` is any +
+ + 222    S-expression. What `SUBLIS` does, is to treat the `u`s as variables when +
+ + 223    they occur in `y`, and to SUBSTitute the corresponding `v`s from the pair +
+ + 224    list. +
+ + 225   +
+ + 226    My interpretation is that this is variable binding in the stack frame. +
+ + 227   +
+ + 228    All args are assumed to be `beowulf.cons-cell/ConsCell` objects. +
+ + 229    See page 12 of the Lisp 1.5 Programmers Manual." +
+ + 230    [a y] +
+ + 231    (cond +
+ + 232      (= (ATOM? y) T) (SUB2 a y) +
+ + 233      :else +
+ + 234      (make-cons-cell (SUBLIS a (CAR y)) (SUBLIS a (CDR y))))) +
+ + 235   +
+ + 236  (defn APPLY +
+ + 237    "For bootstrapping, at least, a version of APPLY written in Clojure. +
+ + 238    All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects. +
+ + 239    See page 13 of the Lisp 1.5 Programmers Manual." +
+ + 240    [function args environment] +
+ + 241    (cond +
+ + 242      (= +
+ + 243        (ATOM? function) +
+ + 244        T)(cond +
+ + 245             ;; TODO: doesn't check whether `function` is bound in the environment; +
+ + 246             ;; we'll need that before we can bootstrap. +
+ + 247             (= function 'CAR) (CAAR args) +
+ + 248             (= function 'CDR) (CDAR args) +
+ + 249             (= function 'CONS) (make-cons-cell (CAR args) (CADR args)) +
+ + 250             (= function 'ATOM) (if (ATOM? (CAR args)) T NIL) +
+ + 251             (= function 'EQ) (if (= (CAR args) (CADR args)) T NIL) +
+ + 252             :else +
+ + 253             (APPLY +
+ + 254               (EVAL function environment) +
+ + 255               args +
+ + 256               environment)) +
+ + 257      (= (first function) 'LAMBDA) (EVAL +
+ + 258                                     (CADDR function) +
+ + 259                                     (PAIRLIS (CADR function) args environment)) +
+ + 260      (= (first function) 'LABEL) (APPLY +
+ + 261                                    (CADDR function) +
+ + 262                                    args +
+ + 263                                    (make-cons-cell +
+ + 264                                      (make-cons-cell +
+ + 265                                        (CADR function) +
+ + 266                                        (CADDR function)) +
+ + 267                                      environment)))) +
+ + 268   +
+ + 269  (defn- EVCON +
+ + 270    "Inner guts of primitive COND. All args are assumed to be +
+ + 271    `beowulf.cons-cell/ConsCell` objects. +
+ + 272    See page 13 of the Lisp 1.5 Programmers Manual." +
+ + 273    [clauses env] +
+ + 274    (if +
+ + 275      (not= (EVAL (CAAR clauses) env) NIL) +
+ + 276      (EVAL (CADAR clauses) env) +
+ + 277      (EVCON (CDR clauses) env))) +
+ + 278   +
+ + 279  (defn- EVLIS +
+ + 280    "Map `EVAL` across this list of `args` in the context of this +
+ + 281    `env`ironment.All args are assumed to be `beowulf.cons-cell/ConsCell` objects. +
+ + 282    See page 13 of the Lisp 1.5 Programmers Manual." +
+ + 283    [args env] +
+ + 284    (cond +
+ + 285      (= NIL args) NIL +
+ + 286      :else +
+ + 287      (make-cons-cell +
+ + 288        (EVAL (CAR args) env) +
+ + 289        (EVLIS (CDR args) env)))) +
+ + 290   +
+ + 291  (deftrace traced-eval +
+ + 292    "Essentially, identical to EVAL except traced." +
+ + 293    [expr env] +
+ + 294    (cond +
+ + 295      (= +
+ + 296        (ATOM? expr) T) +
+ + 297      (CDR (ASSOC expr env)) +
+ + 298      (= +
+ + 299        (ATOM? (CAR expr)) +
+ + 300        T)(cond +
+ + 301             (= (CAR expr) 'QUOTE) (CADR expr) +
+ + 302             (= (CAR expr) 'COND) (EVCON (CDR expr) env) +
+ + 303             :else (APPLY +
+ + 304                     (CAR expr) +
+ + 305                     (EVLIS (CDR expr) env) +
+ + 306                     env)) +
+ + 307      :else (APPLY +
+ + 308              (CAR expr) +
+ + 309              (EVLIS (CDR expr) env) +
+ + 310              env))) +
+ + 311   +
+ + 312  (defn EVAL +
+ + 313    "For bootstrapping, at least, a version of EVAL written in Clojure. +
+ + 314    All args are assumed to be symbols or `beowulf.cons-cell/ConsCell` objects. +
+ + 315    See page 13 of the Lisp 1.5 Programmers Manual." +
+ + 316    [expr env] +
+ + 317    (cond +
+ + 318      (true? (:trace *options*)) +
+ + 319      (traced-eval expr env) +
+ + 320      (= +
+ + 321        (ATOM? expr) T) +
+ + 322      (CDR (ASSOC expr env)) +
+ + 323      (= +
+ + 324        (ATOM? (CAR expr)) +
+ + 325        T)(cond +
+ + 326             (= (CAR expr) 'QUOTE) (CADR expr) +
+ + 327             (= (CAR expr) 'COND) (EVCON (CDR expr) env) +
+ + 328             :else (APPLY +
+ + 329                     (CAR expr) +
+ + 330                     (EVLIS (CDR expr) env) +
+ + 331                     env)) +
+ + 332      :else (APPLY +
+ + 333              (CAR expr) +
+ + 334              (EVLIS (CDR expr) env) +
+ + 335              env))) +
+ + 336   +
+ + 337   +
+ + 338   +
+ + diff --git a/docs/cloverage/beowulf/cons_cell.clj.html b/docs/cloverage/beowulf/cons_cell.clj.html new file mode 100644 index 0000000..5a58211 --- /dev/null +++ b/docs/cloverage/beowulf/cons_cell.clj.html @@ -0,0 +1,476 @@ + + + + beowulf/cons_cell.clj + + + + 001  (ns beowulf.cons-cell +
+ + 002    "The fundamental cons cell on which all Lisp structures are built. +
+ + 003    Lisp 1.5 lists do not necessarily have a sequence as their CDR, so +
+ + 004    cannot be implemented on top of Clojure lists.") +
+ + 005   +
+ + 006  (def NIL +
+ + 007    "The canonical empty list symbol." +
+ + 008    (symbol "NIL")) +
+ + 009   +
+ + 010  (def T +
+ + 011    "The canonical true value." +
+ + 012    (symbol "T")) ;; true. +
+ + 013   +
+ + 014  (def F +
+ + 015    "The canonical false value - different from `NIL`, which is not canonically +
+ + 016    false in Lisp 1.5." +
+ + 017    (symbol "F")) ;; false as distinct from nil +
+ + 018   +
+ + 019  (deftype ConsCell [CAR CDR] +
+ + 020    clojure.lang.ISeq +
+ + 021    (cons [this x] (ConsCell. x this)) +
+ + 022    (first [this] (.CAR this)) +
+ + 023    ;; next and more must return ISeq: +
+ + 024    ;; https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java +
+ + 025    (more [this] (if +
+ + 026                   (seq? (.CDR this)) +
+ + 027                   (.CDR this) +
+ + 028                   clojure.lang.PersistentList/EMPTY)) +
+ + 029    (next [this] (if +
+ + 030                   (seq? (.CDR this)) +
+ + 031                   (.CDR this) +
+ + 032                   nil ;; next returns nil when empty +
+ + 033                   )) +
+ + 034   +
+ + 035    clojure.lang.Seqable +
+ + 036    (seq [this] this) +
+ + 037   +
+ + 038    ;; for some reason this marker protocol is needed otherwise compiler complains +
+ + 039    ;; that `nth not supported on ConsCell` +
+ + 040    clojure.lang.Sequential +
+ + 041   +
+ + 042    clojure.lang.IPersistentCollection +
+ + 043    (count [this] (if +
+ + 044                    (coll? (.CDR this)) +
+ + 045                    (inc (.count (.CDR this))) +
+ + 046                    1)) +
+ + 047    (empty [this] false) ;; a cons cell is by definition not empty. +
+ + 048    (equiv [this other] (if +
+ + 049                          (seq? other) +
+ + 050                          (and +
+ + 051                            (if +
+ + 052                              (and +
+ + 053                                (seq? (first this)) +
+ + 054                                (seq? (first other))) +
+ + 055                              (.equiv (first this) (first other)) +
+ + 056                              (= (first this) (first other))) +
+ + 057                            (if +
+ + 058                              (and +
+ + 059                                (seq? (rest this)) +
+ + 060                                (seq? (rest other))) +
+ + 061                              (.equiv (rest this) (rest other)) +
+ + 062                              (= (rest this) (rest other)))) +
+ + 063                          false))) +
+ + 064   +
+ + 065  (defn- to-string +
+ + 066    "Printing ConsCells gave me a *lot* of trouble. This is an internal function +
+ + 067    used by the print-method override (below) in order that the standard Clojure +
+ + 068    `print` and `str` functions will print ConsCells correctly. The argument +
+ + 069    `cell` must, obviously, be an instance of `ConsCell`." +
+ + 070    [cell] +
+ + 071    (loop [c cell +
+ + 072           n 0 +
+ + 073           s "("] +
+ + 074      (if +
+ + 075        (instance? beowulf.cons_cell.ConsCell c) +
+ + 076        (let [car (.CAR c) +
+ + 077              cdr (.CDR c) +
+ + 078              cons? (instance? beowulf.cons_cell.ConsCell cdr) +
+ + 079              ss (str +
+ + 080                   s +
+ + 081                   (to-string car) +
+ + 082                   (cond +
+ + 083                     cons? +
+ + 084                     " " +
+ + 085                     (or (nil? cdr) (= cdr 'NIL)) +
+ + 086                     ")" +
+ + 087                     :else +
+ + 088                     (str " . " (to-string cdr) ")")))] +
+ + 089          (if +
+ + 090            cons? +
+ + 091            (recur cdr (inc n) ss) +
+ + 092            ss)) +
+ + 093        (str c)))) +
+ + 094   +
+ + 095  (defn pretty-print +
+ + 096    "This isn't the world's best pretty printer but it sort of works." +
+ + 097    ([^beowulf.cons_cell.ConsCell cell] +
+ + 098     (println (pretty-print cell 80 0))) +
+ + 099    ([^beowulf.cons_cell.ConsCell cell width level] +
+ + 100     (loop [c cell +
+ + 101            n (inc level) +
+ + 102            s "("] +
+ + 103       (if +
+ + 104         (instance? beowulf.cons_cell.ConsCell c) +
+ + 105         (let [car (.CAR c) +
+ + 106               cdr (.CDR c) +
+ + 107               cons? (instance? beowulf.cons_cell.ConsCell cdr) +
+ + 108               print-width (count (print-str c)) +
+ + 109               indent (apply str (repeat n "  ")) +
+ + 110               ss (str +
+ + 111                    s +
+ + 112                    (pretty-print car width n) +
+ + 113                    (cond +
+ + 114                      cons? +
+ + 115                      (if +
+ + 116                        (< (+ (count indent) print-width) width) +
+ + 117                        " " +
+ + 118                        (str "\n" indent)) +
+ + 119                      (or (nil? cdr) (= cdr 'NIL)) +
+ + 120                      ")" +
+ + 121                      :else +
+ + 122                      (str " . " (pretty-print cdr width n) ")")))] +
+ + 123           (if +
+ + 124             cons? +
+ + 125             (recur cdr n ss) +
+ + 126             ss)) +
+ + 127         (str c))))) +
+ + 128   +
+ + 129   +
+ + 130   +
+ + 131  (defmethod clojure.core/print-method +
+ + 132    ;;; I have not worked out how to document defmethod without blowing up the world. +
+ + 133    beowulf.cons_cell.ConsCell +
+ + 134    [this writer] +
+ + 135    (.write writer (to-string this))) +
+ + 136   +
+ + 137   +
+ + 138  (defmacro make-cons-cell +
+ + 139    "Construct a new instance of cons cell with this `car` and `cdr`." +
+ + 140    [car cdr] +
+ + 141    `(ConsCell. ~car ~cdr)) +
+ + 142   +
+ + 143  (defn make-beowulf-list +
+ + 144    "Construct a linked list of cons cells with the same content as the +
+ + 145    sequence `x`." +
+ + 146    [x] +
+ + 147    (cond +
+ + 148      (empty? x) NIL +
+ + 149      (coll? x) (ConsCell. +
+ + 150                  (if +
+ + 151                    (seq? (first x)) +
+ + 152                    (make-beowulf-list (first x)) +
+ + 153                    (first x)) +
+ + 154                  (make-beowulf-list (rest x))) +
+ + 155      :else +
+ + 156      NIL)) +
+ + diff --git a/docs/cloverage/beowulf/core.clj.html b/docs/cloverage/beowulf/core.clj.html new file mode 100644 index 0000000..13189d9 --- /dev/null +++ b/docs/cloverage/beowulf/core.clj.html @@ -0,0 +1,248 @@ + + + + beowulf/core.clj + + + + 001  (ns beowulf.core +
+ + 002    "Essentially, the `-main` function and the bootstrap read-eval-print loop." +
+ + 003    (:require [beowulf.bootstrap :refer [EVAL oblist *options*]] +
+ + 004              [beowulf.read :refer [READ]] +
+ + 005              [clojure.java.io :as io] +
+ + 006              [clojure.pprint :refer [pprint]] +
+ + 007              [clojure.tools.cli :refer [parse-opts]] +
+ + 008              [environ.core :refer [env]]) +
+ + 009    (:gen-class)) +
+ + 010   +
+ + 011  (def cli-options +
+ + 012    [["-h" "--help"] +
+ + 013     ["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT" +
+ + 014      :default "Sprecan::"] +
+ + 015     ["-r INITFILE" "--read INITFILE" "Read Lisp functions from the file INITFILE" +
+ + 016      :validate [#(and +
+ + 017                    (.exists (io/file %)) +
+ + 018                    (.canRead (io/file %))) +
+ + 019                 "Could not find initfile"]] +
+ + 020     ["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."] +
+ + 021     ["-t" "--trace" "Trace Lisp evaluation."]]) +
+ + 022   +
+ + 023  (defn repl +
+ + 024    "Read/eval/print loop." +
+ + 025    [prompt] +
+ + 026    (loop [] +
+ + 027      (print prompt) +
+ + 028      (flush) +
+ + 029      (try +
+ + 030        (let [input (read-line)] +
+ + 031          (cond +
+ + 032            (= input "quit") (throw (ex-info "\nFærwell!" {:cause :quit})) +
+ + 033            input (println (str ">  " (print-str (EVAL (READ input) @oblist)))) +
+ + 034            :else (println))) +
+ + 035        (catch +
+ + 036          Exception +
+ + 037          e +
+ + 038          (let [data (ex-data e)] +
+ + 039            (println (.getMessage e)) +
+ + 040            (if +
+ + 041              data +
+ + 042              (case (:cause data) +
+ + 043                :parse-failure (println (:failure data)) +
+ + 044                :strict nil ;; the message, which has already been printed, is enough. +
+ + 045                :quit (throw e) +
+ + 046                ;; default +
+ + 047                (pprint data)))))) +
+ + 048      (recur))) +
+ + 049   +
+ + 050  (defn -main +
+ + 051    "Parse options, print the banner, read the init file if any, and enter the +
+ + 052    read/eval/print loop." +
+ + 053    [& opts] +
+ + 054    (let [args (parse-opts opts cli-options)] +
+ + 055      (println +
+ + 056        (str +
+ + 057          "\nHider wilcuman. Béowulf is mín nama.\n" +
+ + 058          (if +
+ + 059            (System/getProperty "beowulf.version") +
+ + 060            (str "Síðe " (System/getProperty "beowulf.version") "\n")) +
+ + 061          (if +
+ + 062            (:help (:options args)) +
+ + 063            (:summary args)) +
+ + 064          (if (:errors args) +
+ + 065            (apply str (interpose "; " (:errors args)))) +
+ + 066          "\nSprecan 'quit' tó laéfan\n")) +
+ + 067      (binding [*options* (:options args)] +
+ + 068        (try +
+ + 069          (repl (str (:prompt (:options args)) " ")) +
+ + 070          (catch +
+ + 071            Exception +
+ + 072            e +
+ + 073            (let [data (ex-data e)] +
+ + 074              (if +
+ + 075                data +
+ + 076                (case (:cause data) +
+ + 077                  :quit nil +
+ + 078                  ;; default +
+ + 079                  (pprint data)) +
+ + 080                (println e)))))))) +
+ + diff --git a/docs/cloverage/beowulf/host.clj.html b/docs/cloverage/beowulf/host.clj.html new file mode 100644 index 0000000..3acdcf2 --- /dev/null +++ b/docs/cloverage/beowulf/host.clj.html @@ -0,0 +1,23 @@ + + + + beowulf/host.clj + + + + 001  (ns beowulf.host +
+ + 002    "provides Lisp 1.5 functions which can't be (or can't efficiently +
+ + 003     be) implemented in Lisp 1.5, which therefore need to be implemented in the +
+ + 004     host language, in this case Clojure.") +
+ + 005   +
+ + diff --git a/docs/cloverage/beowulf/read.clj.html b/docs/cloverage/beowulf/read.clj.html new file mode 100644 index 0000000..f999f3a --- /dev/null +++ b/docs/cloverage/beowulf/read.clj.html @@ -0,0 +1,953 @@ + + + + beowulf/read.clj + + + + 001  (ns beowulf.read +
+ + 002    "This provides the reader required for boostrapping. It's not a bad +
+ + 003    reader - it provides feedback on errors found in the input - but it isn't +
+ + 004    the real Lisp reader. +
+ + 005   +
+ + 006    Intended deviations from the behaviour of the real Lisp reader are as follows: +
+ + 007   +
+ + 008    1. It reads the meta-expression language `MEXPR` in addition to the +
+ + 009        symbolic expression language `SEXPR`, which I do not believe the Lisp 1.5 +
+ + 010        reader ever did; +
+ + 011    2. It treats everything between a semi-colon and an end of line as a comment, +
+ + 012        as most modern Lisps do; but I do not believe Lisp 1.5 had this feature. +
+ + 013   +
+ + 014    Both these extensions can be disabled by using the `--strict` command line +
+ + 015    switch." +
+ + 016    (:require [beowulf.bootstrap :refer [*options*]] +
+ + 017              [clojure.math.numeric-tower :refer [expt]] +
+ + 018              [clojure.string :refer [starts-with? upper-case]] +
+ + 019              [instaparse.core :as i] +
+ + 020              [beowulf.cons-cell :refer [make-beowulf-list make-cons-cell NIL]])) +
+ + 021   +
+ + 022  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 023  ;;; +
+ + 024  ;;; This file provides the reader required for boostrapping. It's not a bad +
+ + 025  ;;; reader - it provides feedback on errors found in the input - but it isn't +
+ + 026  ;;; the real Lisp reader. +
+ + 027  ;;; +
+ + 028  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 029   +
+ + 030  (declare generate) +
+ + 031   +
+ + 032  (def parse +
+ + 033    "Parse a string presented as argument into a parse tree which can then +
+ + 034    be operated upon further." +
+ + 035    (i/parser +
+ + 036      (str +
+ + 037        ;; top level: we accept mexprs as well as sexprs. +
+ + 038        "expr := mexpr | sexpr;" +
+ + 039   +
+ + 040        ;; mexprs. I'm pretty clear that Lisp 1.5 could never read these, +
+ + 041        ;; but it's a convenience. +
+ + 042        "mexpr := λexpr | fncall | defn | cond | mvar | mexpr comment; +
+ + 043        λexpr := λ lsqb bindings semi-colon body rsqb; +
+ + 044        λ := 'λ'; +
+ + 045        bindings := lsqb args rsqb; +
+ + 046        body := (expr semi-colon opt-space)* expr; +
+ + 047        fncall := fn-name lsqb args rsqb; +
+ + 048        lsqb := '['; +
+ + 049        rsqb := ']'; +
+ + 050        defn := mexpr opt-space '=' opt-space mexpr; +
+ + 051        cond := lsqb (cond-clause semi-colon opt-space)* cond-clause rsqb; +
+ + 052        cond-clause := expr opt-space arrow opt-space expr; +
+ + 053        arrow := '->'; +
+ + 054        args := (expr semi-colon opt-space)* expr; +
+ + 055        fn-name := mvar; +
+ + 056        mvar := #'[a-z]+'; +
+ + 057        semi-colon := ';';" +
+ + 058   +
+ + 059        ;; comments. I'm pretty confident Lisp 1.5 did NOT have these. +
+ + 060        "comment := opt-space <';;'> #'[^\\n\\r]*';" +
+ + 061   +
+ + 062        ;; sexprs. Note it's not clear to me whether Lisp 1.5 had the quote macro, +
+ + 063        ;; but I've included it on the basis that it can do little harm. +
+ + 064        "sexpr := quoted-expr | atom | number | dotted-pair | list | sexpr comment; +
+ + 065        list := lpar sexpr rpar | lpar (sexpr sep)* rpar | lpar (sexpr sep)* dot-terminal; +
+ + 066        dotted-pair := lpar dot-terminal ; +
+ + 067        dot := '.'; +
+ + 068        lpar := '('; +
+ + 069        rpar := ')'; +
+ + 070        quoted-expr := quote sexpr; +
+ + 071        quote := '\\''; +
+ + 072        dot-terminal := sexpr space dot space sexpr rpar; +
+ + 073        space := #'\\p{javaWhitespace}+'; +
+ + 074        opt-space := #'\\p{javaWhitespace}*'; +
+ + 075        sep := ',' | opt-space; +
+ + 076        atom := #'[A-Z][A-Z0-9]*';" +
+ + 077   +
+ + 078        ;; Lisp 1.5 supported octal as well as decimal and scientific notation +
+ + 079        "number := integer | decimal | scientific | octal; +
+ + 080        integer := #'-?[1-9][0-9]*'; +
+ + 081        decimal := #'-?[1-9][0-9]*\\.?[0-9]*' | #'0.[0-9]*'; +
+ + 082        scientific := coefficient e exponent; +
+ + 083        coefficient := decimal; +
+ + 084        exponent := integer; +
+ + 085        e := 'E'; +
+ + 086        octal := #'[+-]?[0-7]+{1,12}' q scale-factor; +
+ + 087        q := 'Q'; +
+ + 088        scale-factor := #'[0-9]*'"))) +
+ + 089   +
+ + 090  (defn simplify +
+ + 091    "Simplify this parse tree `p`. If `p` is an instaparse failure object, throw +
+ + 092    an `ex-info`, with `p` as the value of its `:failure` key." +
+ + 093    ([p] +
+ + 094     (if +
+ + 095       (instance? instaparse.gll.Failure p) +
+ + 096       (throw (ex-info "Ic ne behæfd" {:cause :parse-failure :failure p})) +
+ + 097       (simplify p :sexpr))) +
+ + 098    ([p context] +
+ + 099    (if +
+ + 100      (coll? p) +
+ + 101      (apply +
+ + 102        vector +
+ + 103        (remove +
+ + 104          #(if (coll? %) (empty? %)) +
+ + 105          (case (first p) +
+ + 106            (:arg :expr :coefficient :fn-name :number :sexpr) (simplify (second p) context) +
+ + 107            (:λexpr +
+ + 108              :args :bindings :body :cond :cond-clause :dot-terminal +
+ + 109              :fncall :octal :quoted-expr :scientific) (map #(simplify % context) p) +
+ + 110            (:arrow :dot :e :lpar :lsqb :opt-space :q :quote :rpar :rsqb +
+ + 111              :semi-colon :sep :space) nil +
+ + 112            :atom (if +
+ + 113                    (= context :mexpr) +
+ + 114                    [:quoted-expr p] +
+ + 115                    p) +
+ + 116            :comment (if +
+ + 117                       (:strict *options*) +
+ + 118                       (throw +
+ + 119                         (ex-info "Cannot parse comments in strict mode" +
+ + 120                                  {:cause :strict}))) +
+ + 121            :dotted-pair (if +
+ + 122                           (= context :mexpr) +
+ + 123                           [:fncall +
+ + 124                            [:mvar "cons"] +
+ + 125                            [:args +
+ + 126                             (simplify (nth p 1) context) +
+ + 127                             (simplify (nth p 2) context)]] +
+ + 128                           (map simplify p)) +
+ + 129            :mexpr (if +
+ + 130                     (:strict *options*) +
+ + 131                     (throw +
+ + 132                       (ex-info "Cannot parse meta expressions in strict mode" +
+ + 133                                {:cause :strict})) +
+ + 134                     (simplify (second p) :mexpr)) +
+ + 135            :list (if +
+ + 136                    (= context :mexpr) +
+ + 137                    [:fncall +
+ + 138                     [:mvar "list"] +
+ + 139                     [:args (apply vector (map simplify (rest p)))]] +
+ + 140                    (map #(simplify % context) p)) +
+ + 141            ;;default +
+ + 142            p))) +
+ + 143      p))) +
+ + 144   +
+ + 145   +
+ + 146  ;; # From Lisp 1.5 Programmers Manual, page 10 +
+ + 147  ;; Note that I've retyped much of this, since copy/pasting out of PDF is less +
+ + 148  ;; than reliable. Any typos are mine. Quote starts [[ +
+ + 149   +
+ + 150  ;; We are now in a position to define the universal LISP function +
+ + 151  ;; evalquote[fn;args], When evalquote is given a function and a list of arguments +
+ + 152  ;; for that function, it computes the value of the function applied to the arguments. +
+ + 153  ;; LISP functions have S-expressions as arguments. In particular, the argument "fn" +
+ + 154  ;; of the function evalquote must be an S-expression. Since we have been +
+ + 155  ;; writing functions as M-expressions, it is necessary to translate them into +
+ + 156  ;; S-expressions. +
+ + 157   +
+ + 158  ;; The following rules define a method of translating functions written in the +
+ + 159  ;; meta-language into S-expressions. +
+ + 160  ;; 1. If the function is represented by its name, it is translated by changing +
+ + 161  ;;    all of the letters to upper case, making it an atomic symbol. Thus is +
+ + 162  ;;    translated to CAR. +
+ + 163  ;; 2. If the function uses the lambda notation, then the expression +
+ + 164  ;;    λ[[x ..;xn]; ε] is translated into (LAMBDA (X1 ...XN) ε*), where ε* is the translation +
+ + 165  ;;    of ε. +
+ + 166  ;; 3. If the function begins with label, then the translation of +
+ + 167  ;;    label[α;ε] is (LABEL α* ε*). +
+ + 168   +
+ + 169  ;; Forms are translated as follows: +
+ + 170  ;; 1. A variable, like a function name, is translated by using uppercase letters. +
+ + 171  ;;    Thus the translation of varl is VAR1. +
+ + 172  ;; 2. The obvious translation of letting a constant translate into itself will not +
+ + 173  ;;    work. Since the translation of x is X, the translation of X must be something +
+ + 174  ;;    else to avoid ambiguity. The solution is to quote it. Thus X is translated +
+ + 175  ;;    into (QUOTE X). +
+ + 176  ;; 3. The form fn[argl;. ..;argn] is translated into (fn* argl* ...argn*) +
+ + 177  ;; 4. The conditional expression [pl-el;...;pn-en] is translated into +
+ + 178  ;;    (COND (p1* e1*)...(pn* en*)) +
+ + 179   +
+ + 180  ;; ## Examples +
+ + 181   +
+ + 182  ;; M-expressions                                S-expressions +
+ + 183  ;; x                                            X +
+ + 184  ;; car                                          CAR +
+ + 185  ;; car[x]                                       (CAR X) +
+ + 186  ;; T                                            (QUOTE T) +
+ + 187  ;; ff[car [x]]                                  (FF (CAR X)) +
+ + 188  ;; [atom[x]->x; T->ff[car[x]]]                  (COND ((ATOM X) X) +
+ + 189  ;;                                                ((QUOTE T)(FF (CAR X)))) +
+ + 190  ;; label[ff;λ[[x];[atom[x]->x; T->ff[car[x]]]]] (LABEL FF (LAMBDA (X) (COND +
+ + 191  ;;                                                ((ATOM X) X) +
+ + 192  ;;                                                ((QUOTE T)(FF (CAR X)))))) +
+ + 193   +
+ + 194  ;; ]] quote ends +
+ + 195   +
+ + 196  (defn gen-cond-clause +
+ + 197    "Generate a cond clause from this simplified parse tree fragment `p`; +
+ + 198    returns `nil` if `p` does not represent a cond clause." +
+ + 199    [p] +
+ + 200    (if +
+ + 201      (and (coll? p)(= :cond-clause (first p))) +
+ + 202      (make-beowulf-list +
+ + 203        (list (generate (nth p 1)) +
+ + 204                       (generate (nth p 2)))))) +
+ + 205   +
+ + 206  (defn gen-cond +
+ + 207    "Generate a cond statement from this simplified parse tree fragment `p`; +
+ + 208    returns `nil` if `p` does not represent a (MEXPR) cond statement." +
+ + 209    [p] +
+ + 210    (if +
+ + 211      (and (coll? p)(= :cond (first p))) +
+ + 212      (make-beowulf-list +
+ + 213        (cons +
+ + 214          'COND +
+ + 215          (map +
+ + 216            gen-cond-clause +
+ + 217            (rest p)))))) +
+ + 218   +
+ + 219  (defn gen-fn-call +
+ + 220    "Generate a function call from this simplified parse tree fragment `p`; +
+ + 221    returns `nil` if `p` does not represent a (MEXPR) function call." +
+ + 222    [p] +
+ + 223    (if +
+ + 224      (and (coll? p)(= :fncall (first p))(= :mvar (first (second p)))) +
+ + 225      (make-cons-cell +
+ + 226        (generate (second p)) +
+ + 227        (generate (nth p 2))))) +
+ + 228   +
+ + 229   +
+ + 230  (defn gen-dot-terminated-list +
+ + 231    "Generate a list, which may be dot-terminated, from this partial parse tree +
+ + 232    'p'. Note that the function acts recursively and progressively decapitates +
+ + 233    its argument, so that the argument will not always be a valid parse tree." +
+ + 234    [p] +
+ + 235    (cond +
+ + 236      (empty? p) +
+ + 237      NIL +
+ + 238      (and (coll? (first p)) (= :dot-terminal (first (first p)))) +
+ + 239      (let [dt (first p)] +
+ + 240        (make-cons-cell +
+ + 241          (generate (nth dt 1)) +
+ + 242          (generate (nth dt 2)))) +
+ + 243      :else +
+ + 244      (make-cons-cell +
+ + 245        (generate (first p)) +
+ + 246        (gen-dot-terminated-list (rest p))))) +
+ + 247   +
+ + 248   +
+ + 249  (defn strip-leading-zeros +
+ + 250    "`read-string` interprets strings with leading zeros as octal; strip +
+ + 251    any from this string `s`. If what's left is empty (i.e. there were +
+ + 252    only zeros, return `\"0\"`." +
+ + 253    ([s] +
+ + 254     (strip-leading-zeros s "")) +
+ + 255    ([s prefix] +
+ + 256     (if +
+ + 257       (empty? s) "0" +
+ + 258       (case (first s) +
+ + 259         (\+ \-)(strip-leading-zeros (subs s 1) (str (first s) prefix)) +
+ + 260         "0" (strip-leading-zeros (subs s 1) prefix) +
+ + 261         (str prefix s))))) +
+ + 262   +
+ + 263  (defn generate +
+ + 264    "Generate lisp structure from this parse tree `p`. It is assumed that +
+ + 265    `p` has been simplified." +
+ + 266    [p] +
+ + 267    (if +
+ + 268      (coll? p) +
+ + 269      (case (first p) +
+ + 270        :λ "LAMBDA" +
+ + 271        :λexpr (make-cons-cell +
+ + 272                 (generate (nth p 1)) +
+ + 273                 (make-cons-cell (generate (nth p 2)) +
+ + 274                                 (generate (nth p 3)))) +
+ + 275        (:args :list) (gen-dot-terminated-list (rest p)) +
+ + 276        :atom (symbol (second p)) +
+ + 277        :bindings (generate (second p)) +
+ + 278        :body (make-beowulf-list (map generate (rest p))) +
+ + 279        :cond (gen-cond p) +
+ + 280        (:decimal :integer) (read-string (strip-leading-zeros (second p))) +
+ + 281        :dotted-pair (make-cons-cell +
+ + 282                       (generate (nth p 1)) +
+ + 283                       (generate (nth p 2))) +
+ + 284        :exponent (generate (second p)) +
+ + 285        :fncall (gen-fn-call p) +
+ + 286        :mvar (symbol (upper-case (second p))) +
+ + 287        :octal (let [n (read-string (strip-leading-zeros (second p) "0")) +
+ + 288                     scale (generate (nth p 2))] +
+ + 289                 (* n (expt 8 scale))) +
+ + 290   +
+ + 291        ;; the quote read macro (which probably didn't exist in Lisp 1.5, but...) +
+ + 292        :quoted-expr (make-beowulf-list (list 'QUOTE (generate (second p)))) +
+ + 293        :scale-factor (if +
+ + 294                        (empty? (second p)) 0 +
+ + 295                        (read-string (strip-leading-zeros (second p)))) +
+ + 296        :scientific (let [n (generate (second p)) +
+ + 297                          exponent (generate (nth p 2))] +
+ + 298                      (* n (expt 10 exponent))) +
+ + 299   +
+ + 300        ;; default +
+ + 301        (throw (Exception. (str "Cannot yet generate " (first p))))) +
+ + 302      p)) +
+ + 303   +
+ + 304  (defmacro gsp +
+ + 305    "Shortcut macro - the internals of read; or, if you like, read-string. +
+ + 306    Argument `s` should be a string representation of a valid Lisp +
+ + 307    expression." +
+ + 308    [s] +
+ + 309    `(generate (simplify (parse ~s)))) +
+ + 310   +
+ + 311  (defn READ +
+ + 312    "An implementation of a Lisp reader sufficient for bootstrapping; not necessarily +
+ + 313    the final Lisp reader." +
+ + 314    [input] +
+ + 315    (gsp (or input (read-line)))) +
+ + diff --git a/docs/cloverage/coverage.css b/docs/cloverage/coverage.css new file mode 100644 index 0000000..2be4e57 --- /dev/null +++ b/docs/cloverage/coverage.css @@ -0,0 +1,40 @@ +.covered { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: #558B55; +} + +.not-covered { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: red; +} + +.partial { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; + background-color: orange; +} + +.not-tracked { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; +} + +.blank { + font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace; +} + +td { + padding-right: 10px; +} + +td.with-bar { + width: 250px; + text-align: center; +} + +td.with-number { + text-align: right; +} + +td.ns-name { + min-width: 150px; + padding-right: 25px; +} diff --git a/docs/cloverage/index.html b/docs/cloverage/index.html new file mode 100644 index 0000000..b2e4ae4 --- /dev/null +++ b/docs/cloverage/index.html @@ -0,0 +1,104 @@ + + + + + Coverage Summary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Namespace Forms Forms % Lines Lines %TotalBlankInstrumented
beowulf.bootstrap
752
363
67.44 %
103
41
32
81.82 %33840176
beowulf.cons-cell
129
98
56.83 %
39
3
26
61.76 %1561568
beowulf.core
170
17
90.91 %
43
1
5
89.80 %80349
beowulf.host
1
100.00 %
1
100.00 %511
beowulf.read
588
130
81.89 %
93
10
23
81.75 %31531126
Totals:72.95 %79.52 %
+ + diff --git a/docs/codox/beowulf.bootstrap.html b/docs/codox/beowulf.bootstrap.html new file mode 100644 index 0000000..4bd0a94 --- /dev/null +++ b/docs/codox/beowulf.bootstrap.html @@ -0,0 +1,12 @@ + +beowulf.bootstrap documentation

beowulf.bootstrap

Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host, be sufficient to bootstrap the full Lisp 1.5 interpreter..

+

The convention is adopted that functions in this file with names in ALLUPPERCASE are Lisp 1.5 functions (although written in Clojure) and that therefore all arguments must be numbers, symbols or beowulf.cons_cell.ConsCell objects.

*options*

dynamic

Command line options from invocation.

APPEND

(APPEND x y)

Append the the elements of y to the elements of x.

+

All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 11 of the Lisp 1.5 Programmers Manual.

APPLY

(APPLY function args environment)

For bootstrapping, at least, a version of APPLY written in Clojure. All args are assumed to be symbols or beowulf.cons-cell/ConsCell objects. See page 13 of the Lisp 1.5 Programmers Manual.

ASSOC

(ASSOC x a)

If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function.

+

All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 12 of the Lisp 1.5 Programmers Manual.

ATOM

macro

(ATOM x)

Returns T if and only is the argument x is bound to and atom; else F. It is not clear to me from the documentation whether (ATOM 7) should return T or F. I’m going to assume T.

ATOM?

macro

(ATOM? x)

The convention of returning F from predicates, rather than NIL, is going to tie me in knots. This is a variant of ATOM which returns NIL on failure.

CAAAAR

(CAAAAR x)

TODO: write docs

CAAADR

(CAAADR x)

TODO: write docs

CAAAR

(CAAAR x)

TODO: write docs

CAADAR

(CAADAR x)

TODO: write docs

CAADDR

(CAADDR x)

TODO: write docs

CAADR

(CAADR x)

TODO: write docs

CAAR

(CAAR x)

TODO: write docs

CADAAR

(CADAAR x)

TODO: write docs

CADADR

(CADADR x)

TODO: write docs

CADAR

(CADAR x)

TODO: write docs

CADDAR

(CADDAR x)

TODO: write docs

CADDDR

(CADDDR x)

TODO: write docs

CADDR

(CADDR x)

TODO: write docs

CADR

(CADR x)

TODO: write docs

CAR

(CAR x)

Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL.

CDAAAR

(CDAAAR x)

TODO: write docs

CDAADR

(CDAADR x)

TODO: write docs

CDAAR

(CDAAR x)

TODO: write docs

CDADAR

(CDADAR x)

TODO: write docs

CDADDR

(CDADDR x)

TODO: write docs

CDADR

(CDADR x)

TODO: write docs

CDAR

(CDAR x)

TODO: write docs

CDDAAR

(CDDAAR x)

TODO: write docs

CDDADR

(CDDADR x)

TODO: write docs

CDDAR

(CDDAR x)

TODO: write docs

CDDDAR

(CDDDAR x)

TODO: write docs

CDDDDR

(CDDDDR x)

TODO: write docs

CDDDR

(CDDDR x)

TODO: write docs

CDDR

(CDDR x)

TODO: write docs

CDR

(CDR x)

Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL.

EQ

(EQ x y)

Returns T if and only if both x and y are bound to the same atom, else F.

EQUAL

(EQUAL x y)

This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate EQ is defined only for atomic arguments.) The definition of EQUAL is an example of a conditional expression inside a conditional expression.

+

NOTE: returns F on failure, not NIL

EVAL

(EVAL expr env)

For bootstrapping, at least, a version of EVAL written in Clojure. All args are assumed to be symbols or beowulf.cons-cell/ConsCell objects. See page 13 of the Lisp 1.5 Programmers Manual.

MEMBER

(MEMBER x y)

This predicate is true if the S-expression x occurs among the elements of the list y.

+

All args are assumed to be symbols or beowulf.cons-cell/ConsCell objects. See page 11 of the Lisp 1.5 Programmers Manual.

NULL

macro

(NULL x)

Returns T if and only if the argument x is bound to NIL; else F.

oblist

The default environment.

PAIRLIS

(PAIRLIS x y a)

This function gives the list of pairs of corresponding elements of the lists x and y, and APPENDs this to the list a. The resultant list of pairs, which is like a table with two columns, is called an association list.

+

Eessentially, it builds the environment on the stack, implementing shallow binding.

+

All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 12 of the Lisp 1.5 Programmers Manual.

SUBLIS

(SUBLIS a y)

Here a is assumed to be an association list of the form ((ul . vl)...(un . vn)), where the us are atomic, and y is any S-expression. What SUBLIS does, is to treat the us as variables when they occur in y, and to SUBSTitute the corresponding vs from the pair list.

+

My interpretation is that this is variable binding in the stack frame.

+

All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 12 of the Lisp 1.5 Programmers Manual.

SUBST

(SUBST x y z)

This function gives the result of substituting the S-expression x for all occurrences of the atomic symbol y in the S-expression z.

traced-eval

(traced-eval & args__2885__auto__)

Essentially, identical to EVAL except traced.

uaf

(uaf l path)

Universal access function; l is expected to be an arbitrary list, path a (clojure) list of the characters a and d. Intended to make declaring all those fiddly #'c[ad]+r' functions a bit easier

\ No newline at end of file diff --git a/docs/codox/beowulf.cons-cell.html b/docs/codox/beowulf.cons-cell.html new file mode 100644 index 0000000..5db7b53 --- /dev/null +++ b/docs/codox/beowulf.cons-cell.html @@ -0,0 +1,3 @@ + +beowulf.cons-cell documentation

beowulf.cons-cell

The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, so cannot be implemented on top of Clojure lists.

F

The canonical false value - different from NIL, which is not canonically false in Lisp 1.5.

make-beowulf-list

(make-beowulf-list x)

Construct a linked list of cons cells with the same content as the sequence x.

make-cons-cell

macro

(make-cons-cell car cdr)

Construct a new instance of cons cell with this car and cdr.

NIL

The canonical empty list symbol.

pretty-print

(pretty-print cell)(pretty-print cell width level)

This isn’t the world’s best pretty printer but it sort of works.

T

The canonical true value.

\ No newline at end of file diff --git a/docs/codox/beowulf.core.html b/docs/codox/beowulf.core.html new file mode 100644 index 0000000..f5e11fe --- /dev/null +++ b/docs/codox/beowulf.core.html @@ -0,0 +1,3 @@ + +beowulf.core documentation

beowulf.core

Essentially, the -main function and the bootstrap read-eval-print loop.

-main

(-main & opts)

Parse options, print the banner, read the init file if any, and enter the read/eval/print loop.

cli-options

TODO: write docs

repl

(repl prompt)

Read/eval/print loop.

\ No newline at end of file diff --git a/docs/codox/beowulf.host.html b/docs/codox/beowulf.host.html new file mode 100644 index 0000000..946857b --- /dev/null +++ b/docs/codox/beowulf.host.html @@ -0,0 +1,3 @@ + +beowulf.host documentation

beowulf.host

provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.

\ No newline at end of file diff --git a/docs/codox/beowulf.read.html b/docs/codox/beowulf.read.html new file mode 100644 index 0000000..3deec4d --- /dev/null +++ b/docs/codox/beowulf.read.html @@ -0,0 +1,9 @@ + +beowulf.read documentation

beowulf.read

This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.

+

Intended deviations from the behaviour of the real Lisp reader are as follows:

+
    +
  1. It reads the meta-expression language MEXPR in addition to the symbolic expression language SEXPR, which I do not believe the Lisp 1.5 reader ever did;
  2. +
  3. It treats everything between a semi-colon and an end of line as a comment, as most modern Lisps do; but I do not believe Lisp 1.5 had this feature.
  4. +
+

Both these extensions can be disabled by using the --strict command line switch.

gen-cond

(gen-cond p)

Generate a cond statement from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) cond statement.

gen-cond-clause

(gen-cond-clause p)

Generate a cond clause from this simplified parse tree fragment p; returns nil if p does not represent a cond clause.

gen-dot-terminated-list

(gen-dot-terminated-list p)

Generate a list, which may be dot-terminated, from this partial parse tree ‘p’. Note that the function acts recursively and progressively decapitates its argument, so that the argument will not always be a valid parse tree.

gen-fn-call

(gen-fn-call p)

Generate a function call from this simplified parse tree fragment p; returns nil if p does not represent a (MEXPR) function call.

generate

(generate p)

Generate lisp structure from this parse tree p. It is assumed that p has been simplified.

gsp

macro

(gsp s)

Shortcut macro - the internals of read; or, if you like, read-string. Argument s should be a string representation of a valid Lisp expression.

parse

Parse a string presented as argument into a parse tree which can then be operated upon further.

READ

(READ input)

An implementation of a Lisp reader sufficient for bootstrapping; not necessarily the final Lisp reader.

simplify

(simplify p)(simplify p context)

Simplify this parse tree p. If p is an instaparse failure object, throw an ex-info, with p as the value of its :failure key.

strip-leading-zeros

(strip-leading-zeros s)(strip-leading-zeros s prefix)

read-string interprets strings with leading zeros as octal; strip any from this string s. If what’s left is empty (i.e. there were only zeros, return "0".

\ No newline at end of file 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..7dfb2d3 --- /dev/null +++ b/docs/codox/index.html @@ -0,0 +1,3 @@ + +Beowulf 0.2.0

Beowulf 0.2.0

Released under the GPL-2.0-or-later

An implementation of LISP 1.5 in Clojure.

Installation

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

[beowulf "0.2.0"]

Topics

Namespaces

beowulf.bootstrap

Lisp as defined in Chapter 1 (pages 1-14) of the Lisp 1.5 Programmer's Manual; that is to say, a very simple Lisp language, which should, I believe, be sufficient in conjunction with the functions provided by beowulf.host, be sufficient to bootstrap the full Lisp 1.5 interpreter..

beowulf.cons-cell

The fundamental cons cell on which all Lisp structures are built. Lisp 1.5 lists do not necessarily have a sequence as their CDR, so cannot be implemented on top of Clojure lists.

Public variables and functions:

beowulf.core

Essentially, the -main function and the bootstrap read-eval-print loop.

Public variables and functions:

beowulf.host

provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.

Public variables and functions:

    beowulf.read

    This provides the reader required for boostrapping. It’s not a bad reader - it provides feedback on errors found in the input - but it isn’t the real Lisp reader.

    \ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html new file mode 100644 index 0000000..17bdf0c --- /dev/null +++ b/docs/codox/intro.html @@ -0,0 +1,4 @@ + +Introduction to beowulf

    Introduction to beowulf

    +

    TODO: write great documentation

    \ 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("