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..87b7ba8 --- /dev/null +++ b/docs/cloverage/index.html @@ -0,0 +1,157 @@ + + + + + Coverage Summary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Namespace Forms Forms % Lines Lines %TotalBlankInstrumented
mw-engine.core
51
103
33.12 %
12
1
20
39.39 %1151533
mw-engine.display
9
79
10.23 %
8
11
42.11 %65819
mw-engine.drainage
88
301
22.62 %
31
59
34.44 %2173090
mw-engine.flow
447
69
86.63 %
47
4
4
92.73 %1411555
mw-engine.heightmap
136
11
92.52 %
40
2
2
95.45 %1271144
mw-engine.natural-rules
51
605
7.77 %
35
5
66
37.74 %18414106
mw-engine.utils
376
162
69.89 %
82
1
29
74.11 %30135112
mw-engine.world
63
53
54.31 %
11
1
14
46.15 %891226
Totals:46.89 %57.73 %
+ + diff --git a/docs/cloverage/mw_engine/core.clj.html b/docs/cloverage/mw_engine/core.clj.html new file mode 100644 index 0000000..e540e94 --- /dev/null +++ b/docs/cloverage/mw_engine/core.clj.html @@ -0,0 +1,353 @@ + + + + mw_engine/core.clj + + + + 001  (ns ^{:doc "Functions to transform a world and run rules. +
+ + 002               +
+ + 003              Every rule is a function of two arguments, a cell and a world. If the rule +
+ + 004              fires, it returns a new cell, which should have the same values for `:x` and +
+ + 005              `:y` as the old cell. Anything else can be modified. +
+ + 006   +
+ + 007              While any function of two arguments can be used as a rule, a special high +
+ + 008              level rule language is provided by the `mw-parser` package, which compiles +
+ + 009              rules expressed in a subset of English rules into suitable functions. +
+ + 010   +
+ + 011              A cell is a map containing at least values for the keys :x, :y, and :state; +
+ + 012              a transformation should not alter the values of :x or :y, and should not +
+ + 013              return a cell without a keyword as the value of :state. Anything else is +
+ + 014              legal. +
+ + 015   +
+ + 016              A world is a two dimensional matrix (sequence of sequences) of cells, such +
+ + 017              that every cell's `:x` and `:y` properties reflect its place in the matrix. +
+ + 018              See `world.clj`. +
+ + 019   +
+ + 020              Each time the world is transformed (see `transform-world`), for each cell, +
+ + 021              rules are applied in turn until one matches. Once one rule has matched no +
+ + 022              further rules can be applied to that cell." +
+ + 023        :author "Simon Brooke"} +
+ + 024   mw-engine.core +
+ + 025    (:require [mw-engine.utils :refer [get-int-or-zero map-world]] +
+ + 026              [taoensso.timbre :as l])) +
+ + 027   +
+ + 028  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 029  ;;;; +
+ + 030  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 031  ;;;; +
+ + 032  ;;;; This program is free software; you can redistribute it and/or +
+ + 033  ;;;; modify it under the terms of the GNU General Public License +
+ + 034  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 035  ;;;; of the License, or (at your option) any later version. +
+ + 036  ;;;; +
+ + 037  ;;;; This program is distributed in the hope that it will be useful, +
+ + 038  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 039  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 040  ;;;; GNU General Public License for more details. +
+ + 041  ;;;; +
+ + 042  ;;;; You should have received a copy of the GNU General Public License +
+ + 043  ;;;; along with this program; if not, write to the Free Software +
+ + 044  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 045  ;;;; USA. +
+ + 046  ;;;; +
+ + 047  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 048  ;;;; +
+ + 049  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 050   +
+ + 051  (defn apply-rule +
+ + 052    "Apply a single `rule` to a `cell`. What this is about is that I want to be able, +
+ + 053     for debugging purposes, to tag a cell with the rule text of the rule which +
+ + 054     fired (and especially so when an exception is thrown. So a rule may be either +
+ + 055     an ifn, or a list (ifn source-text). This function deals with despatching +
+ + 056     on those two possibilities. `world` is also passed in in order to be able +
+ + 057     to access neighbours." +
+ + 058    ([world cell rule] +
+ + 059     (cond +
+ + 060       (ifn? rule) (apply-rule world cell rule nil) +
+ + 061       (seq? rule) (let [[afn src] rule] (apply-rule world cell afn src)))) +
+ + 062    ([world cell rule source] +
+ + 063     (let [result (apply rule (list cell world))] +
+ + 064       (cond +
+ + 065         (and result source) (merge result {:rule source}) +
+ + 066         :else result)))) +
+ + 067   +
+ + 068  (defn- apply-rules +
+ + 069    "Derive a cell from this `cell` of this `world` by applying these `rules`." +
+ + 070    [world cell rules] +
+ + 071    (cond (empty? rules) cell +
+ + 072          :else (let [result (apply-rule world cell (first rules))] +
+ + 073                  (cond result result +
+ + 074                        :else (apply-rules world cell (rest rules)))))) +
+ + 075   +
+ + 076  (defn- transform-cell +
+ + 077    "Derive a cell from this `cell` of this `world` by applying these `rules`. If an +
+ + 078     exception is thrown, cache its message on the cell and set it's state to error" +
+ + 079    [world cell rules] +
+ + 080    (try +
+ + 081      (merge +
+ + 082       (apply-rules world cell rules) +
+ + 083       {:generation (+ (get-int-or-zero cell :generation) 1)}) +
+ + 084      (catch Exception e +
+ + 085        (merge cell {:error +
+ + 086                     (format "%s at generation %d when in state %s" +
+ + 087                             (.getMessage e) +
+ + 088                             (:generation cell) +
+ + 089                             (:state cell)) +
+ + 090                     :stacktrace (map #(.toString %) (.getStackTrace e)) +
+ + 091                     :state :error})))) +
+ + 092   +
+ + 093  (defn transform-world +
+ + 094    "Return a world derived from this `world` by applying these `rules` to each cell." +
+ + 095    ([world rules] +
+ + 096     (map-world world transform-cell (list rules)))) +
+ + 097   +
+ + 098  (defn run-world +
+ + 099    "Run this world with these rules for this number of generations. +
+ + 100   +
+ + 101    * `world` a world as discussed above; +
+ + 102    * `init-rules` a sequence of rules as defined above, to be run once to initialise the world; +
+ + 103    * `rules` a sequence of rules as defined above, to be run iteratively for each generation; +
+ + 104    * `generations` an (integer) number of generations. +
+ + 105   +
+ + 106    Return the final generation of the world." +
+ + 107    [world init-rules rules generations] +
+ + 108    (reduce (fn [world iteration] +
+ + 109              (l/info "Running iteration " iteration) +
+ + 110              (transform-world world rules)) +
+ + 111            (transform-world world init-rules) +
+ + 112            (range generations))) +
+ + 113   +
+ + 114   +
+ + 115   +
+ + diff --git a/docs/cloverage/mw_engine/display.clj.html b/docs/cloverage/mw_engine/display.clj.html new file mode 100644 index 0000000..a370627 --- /dev/null +++ b/docs/cloverage/mw_engine/display.clj.html @@ -0,0 +1,203 @@ + + + + mw_engine/display.clj + + + + 001  (ns ^{:doc "Simple functions to allow a world to be visualised." +
+ + 002        :author "Simon Brooke"} +
+ + 003    mw-engine.display) +
+ + 004   +
+ + 005  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 006  ;;;; +
+ + 007  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 008  ;;;; +
+ + 009  ;;;; This program is free software; you can redistribute it and/or +
+ + 010  ;;;; modify it under the terms of the GNU General Public License +
+ + 011  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 012  ;;;; of the License, or (at your option) any later version. +
+ + 013  ;;;; +
+ + 014  ;;;; This program is distributed in the hope that it will be useful, +
+ + 015  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 016  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 017  ;;;; GNU General Public License for more details. +
+ + 018  ;;;; +
+ + 019  ;;;; You should have received a copy of the GNU General Public License +
+ + 020  ;;;; along with this program; if not, write to the Free Software +
+ + 021  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 022  ;;;; USA. +
+ + 023  ;;;; +
+ + 024  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 025  ;;;; +
+ + 026  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 027   +
+ + 028  (def ^:dynamic *image-base* +
+ + 029    "Base url (i.e., url of directory) from which to load tile images." +
+ + 030    "img/tiles") +
+ + 031   +
+ + 032  (defn format-css-class +
+ + 033    "Format this `state`, assumed to be a keyword indicating a state in the +
+ + 034     world, into a CSS class" +
+ + 035    [state] +
+ + 036    (subs (str state) 1)) +
+ + 037   +
+ + 038  (defn format-image-path +
+ + 039    "Render this `state`, assumed to be a keyword indicating a state in the +
+ + 040     world, into a path which should recover the corresponding image file." +
+ + 041    [state] +
+ + 042    (format "%s/%s.png" *image-base* (format-css-class state))) +
+ + 043   +
+ + 044  (defn format-mouseover [cell] +
+ + 045    (str cell)) +
+ + 046   +
+ + 047  (defn render-cell +
+ + 048    "Render this world cell as a Hiccup table cell." +
+ + 049    [cell] +
+ + 050    (let [state (:state cell)] +
+ + 051      [:td {:class (format-css-class state) :title (format-mouseover cell)} +
+ + 052       [:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))} +
+ + 053        [:img {:alt (:state cell) :width 32 :height 32 :src (format-image-path state)}]]])) +
+ + 054   +
+ + 055  (defn render-world-row +
+ + 056    "Render this world `row` as a Hiccup table row." +
+ + 057    [row] +
+ + 058    (apply vector (cons :tr (map render-cell row)))) +
+ + 059   +
+ + 060  (defn render-world-table +
+ + 061    "Render this `world` as a Hiccup table." +
+ + 062    [world] +
+ + 063    (apply vector +
+ + 064      (cons :table +
+ + 065        (map render-world-row world)))) +
+ + diff --git a/docs/cloverage/mw_engine/drainage.clj.html b/docs/cloverage/mw_engine/drainage.clj.html new file mode 100644 index 0000000..5b8d0b9 --- /dev/null +++ b/docs/cloverage/mw_engine/drainage.clj.html @@ -0,0 +1,659 @@ + + + + mw_engine/drainage.clj + + + + 001  (ns ^{:doc "Experimental, probably of no interest to anyone else; attempt to +
+ + 002        compute drainage on a world, assumed to have altitudes already set +
+ + 003        from a heightmap." +
+ + 004        :author "Simon Brooke"} +
+ + 005    mw-engine.drainage +
+ + 006    (:require [mw-engine.core :refer [run-world]] +
+ + 007              [mw-engine.heightmap :as heightmap] +
+ + 008              [mw-engine.utils :refer [get-int-or-zero get-least-cell get-neighbours +
+ + 009                                       get-neighbours-with-property-value +
+ + 010                                       map-world]])) +
+ + 011   +
+ + 012  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 013  ;;;; +
+ + 014  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 015  ;;;; +
+ + 016  ;;;; This program is free software; you can redistribute it and/or +
+ + 017  ;;;; modify it under the terms of the GNU General Public License +
+ + 018  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 019  ;;;; of the License, or (at your option) any later version. +
+ + 020  ;;;; +
+ + 021  ;;;; This program is distributed in the hope that it will be useful, +
+ + 022  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 023  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 024  ;;;; GNU General Public License for more details. +
+ + 025  ;;;; +
+ + 026  ;;;; You should have received a copy of the GNU General Public License +
+ + 027  ;;;; along with this program; if not, write to the Free Software +
+ + 028  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 029  ;;;; USA. +
+ + 030  ;;;; +
+ + 031  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 032  ;;;; +
+ + 033  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 034   +
+ + 035   +
+ + 036  (def ^:dynamic *sealevel* 10) +
+ + 037   +
+ + 038  ;; forward declaration of flow, to allow for a wee bit of mutual recursion. +
+ + 039  (declare flow) +
+ + 040   +
+ + 041  (defn rainfall +
+ + 042    "Compute rainfall for a cell with this `gradient` west-east, given +
+ + 043    `remaining` drops to distribute, and this overall map width." +
+ + 044    [gradient remaining map-width] +
+ + 045      (cond +
+ + 046        ;; if there's no rain left in the cloud, it can't fall; +
+ + 047        (zero? remaining) +
+ + 048        0 +
+ + 049        (pos? gradient) +
+ + 050        ;; rain, on prevailing westerly wind, falls preferentially on rising ground; +
+ + 051        (int (rand gradient)) +
+ + 052        ;; rain falls randomly across the width of the map... +
+ + 053        (zero? (int (rand map-width))) 1 +
+ + 054        :else +
+ + 055        0)) +
+ + 056   +
+ + 057  (defn rain-row +
+ + 058    "Return a row like this `row`, across which rainfall has been distributed; +
+ + 059    if `rain-probability` is specified, it is the probable rainfall on a cell +
+ + 060    with no gradient." +
+ + 061    ([row] +
+ + 062     (rain-row row 1)) +
+ + 063    ([row rain-probability] +
+ + 064     (rain-row row (count row) 0 (int (* (count row) rain-probability)))) +
+ + 065    ([row map-width previous-altitude drops-in-cloud] +
+ + 066     (cond +
+ + 067       (empty? row) nil +
+ + 068       (pos? drops-in-cloud) +
+ + 069       (let [cell (first row) +
+ + 070             alt (or (:altitude cell) 0) +
+ + 071             rising (- alt previous-altitude) +
+ + 072             fall (rainfall rising drops-in-cloud map-width)] +
+ + 073         (cons +
+ + 074           (assoc cell :rainfall fall) +
+ + 075           (rain-row (rest row) map-width alt (- drops-in-cloud fall)))) +
+ + 076       :else +
+ + 077       (map +
+ + 078         #(assoc % :rainfall 0) +
+ + 079         row)))) +
+ + 080   +
+ + 081   +
+ + 082  (defn rain-world +
+ + 083    "Simulate rainfall on this `world`. TODO: Doesn't really work just now - should +
+ + 084     rain more on west-facing slopes, and less to the east of high ground" +
+ + 085    [world] +
+ + 086    (map +
+ + 087      rain-row +
+ + 088      world)) +
+ + 089   +
+ + 090   +
+ + 091  (defn flow-contributors +
+ + 092    "Return a list of the cells in this `world` which are higher than this +
+ + 093    `cell` and for which this cell is the lowest neighbour, or which are at the +
+ + 094     same altitude and have greater flow" +
+ + 095    [cell world] +
+ + 096    (filter #(map? %) +
+ + 097            (map +
+ + 098              (fn [n] +
+ + 099                (cond +
+ + 100                  (= cell (get-least-cell (get-neighbours world n) :altitude)) n +
+ + 101                  (and (= (:altitude cell) (:altitude n)) +
+ + 102                       (> (or (:flow n) 0) (or (:flow cell) 0))) n)) +
+ + 103              (get-neighbours-with-property-value +
+ + 104                world (:x cell) (:y cell) 1 :altitude +
+ + 105                (or (:altitude cell) 0) >=)))) +
+ + 106   +
+ + 107   +
+ + 108  (defn is-hollow +
+ + 109    "Detects point hollows - that is, individual cells all of whose neighbours +
+ + 110     are higher. Return true if this `cell` has an altitude lower than any of +
+ + 111     its neighbours in this `world`" +
+ + 112    [world cell] +
+ + 113    ;; quicker to count the elements of the list and compare equality of numbers +
+ + 114    ;; than recursive equality check on members, I think. But worth benchmarking. +
+ + 115    (let [neighbours (get-neighbours world cell) +
+ + 116          altitude (get-int-or-zero cell :altitude)] +
+ + 117      (= (count neighbours) +
+ + 118         (count (get-neighbours-with-property-value +
+ + 119                  world (:x cell) (:y cell) 1 :altitude altitude >))))) +
+ + 120   +
+ + 121   +
+ + 122  (defn flood-hollow +
+ + 123    "Raise the altitude of a copy of this `cell` of this `world` to the altitude +
+ + 124     of the lowest of its `neighbours`." +
+ + 125    ([_world cell neighbours] +
+ + 126      (let [lowest (get-least-cell neighbours :altitude)] +
+ + 127        (merge cell {:state :water :altitude (:altitude lowest)}))) +
+ + 128    ([world cell] +
+ + 129      (flood-hollow world cell (get-neighbours world cell)))) +
+ + 130   +
+ + 131   +
+ + 132  (defn flood-hollows +
+ + 133    "Flood all local hollows in this `world`. At this stage only floods single +
+ + 134     cell hollows." +
+ + 135    [world] +
+ + 136    (map-world world +
+ + 137               #(if (is-hollow %1 %2) (flood-hollow %1 %2) %2))) +
+ + 138   +
+ + 139   +
+ + 140  (def max-altitude 255) +
+ + 141   +
+ + 142  (defn flow-nr +
+ + 143    "Experimental non recursive flow algorithm, needs to be run on a world as +
+ + 144     many times as there are distinct altitude values. This algorithm works only +
+ + 145     if applied sequentially from the highest altitude to the lowest, see +
+ + 146     `flow-world-nr`." +
+ + 147    [cell world] +
+ + 148    (when (= (- max-altitude (get-int-or-zero cell :generation)) +
+ + 149           (get-int-or-zero cell :altitude)) +
+ + 150      (merge cell +
+ + 151             {:flow (reduce + +
+ + 152                            (map +
+ + 153                              #(+ (get-int-or-zero % :rainfall) +
+ + 154                                  (get-int-or-zero % :flow)) +
+ + 155                              (flow-contributors cell world)))}))) +
+ + 156   +
+ + 157   +
+ + 158  (def flow +
+ + 159    "Compute the total flow upstream of this `cell` in this `world`, and return a cell identical +
+ + 160    to this one but having a value of its flow property set from that computation. The function is +
+ + 161    memoised because the consequence of mapping a recursive function across an array is that many +
+ + 162    cells will be revisited - potentially many times. +
+ + 163   +
+ + 164    Flow comes from a higher cell to a lower only if the lower is the lowest neighbour of the higher." +
+ + 165    (memoize +
+ + 166     (fn [cell world] +
+ + 167       (cond +
+ + 168        (not (nil? (:flow cell))) cell +
+ + 169        (<= (or (:altitude cell) 0) *sealevel*) cell +
+ + 170        :else +
+ + 171        (merge cell +
+ + 172               {:flow (+ (:rainfall cell) +
+ + 173                         (apply + +
+ + 174                                (map (fn [neighbour] (:flow (flow neighbour world))) +
+ + 175                                     (flow-contributors cell world))))}))))) +
+ + 176   +
+ + 177   +
+ + 178  (defn flow-world-nr +
+ + 179    "Experimental non-recursive flow-world algorithm" +
+ + 180    [world] +
+ + 181    (run-world world nil (list flow-nr) max-altitude)) +
+ + 182   +
+ + 183  (defn flow-world +
+ + 184    "Return a world like this `world`, but with cells tagged with the amount of +
+ + 185     water flowing through them." +
+ + 186    [world] +
+ + 187    (map-world (rain-world world) flow)) +
+ + 188   +
+ + 189  (defn explore-lake +
+ + 190    "Return a sequence of cells starting with this `cell` in this `world` which +
+ + 191    form a contiguous lake" +
+ + 192    [_world _cell] +
+ + 193    ) +
+ + 194   +
+ + 195  (defn is-lake? +
+ + 196    "If this `cell` in this `world` is not part of a lake, return nil. If it is, +
+ + 197    return a cell like this `cell` tagged as part of a lake." +
+ + 198    [world cell] +
+ + 199    (if +
+ + 200      ;; if it's already tagged as a lake, it's a lake +
+ + 201      (:lake cell) cell +
+ + 202      (let +
+ + 203        [outflow (apply min (map :altitude (get-neighbours world cell)))] +
+ + 204        (when-not +
+ + 205          (> (:altitude cell) outflow) +
+ + 206          (assoc cell :lake true))))) +
+ + 207   +
+ + 208   +
+ + 209  (defn find-lakes +
+ + 210    [_world] +
+ + 211    ) +
+ + 212   +
+ + 213  (defn run-drainage +
+ + 214    "Create a world from the heightmap `hmap`, rain on it, and then compute river +
+ + 215     flows." +
+ + 216    [hmap] +
+ + 217    (flow-world (rain-world (flood-hollows (heightmap/apply-heightmap hmap))))) +
+ + diff --git a/docs/cloverage/mw_engine/flow.clj.html b/docs/cloverage/mw_engine/flow.clj.html new file mode 100644 index 0000000..8246897 --- /dev/null +++ b/docs/cloverage/mw_engine/flow.clj.html @@ -0,0 +1,431 @@ + + + + mw_engine/flow.clj + + + + 001  (ns mw-engine.flow +
+ + 002    "Allow flows of values between cells in the world. +
+ + 003      +
+ + 004     The design here is: a flow object is a map with the following properties: +
+ + 005   +
+ + 006     1. `:source`, whose value is a location; +
+ + 007     2. `:destination`, whose value is a location; +
+ + 008     3. `:property`, whose value is a keyword; +
+ + 009     4. `:quantity`, whose value is a positive real number. +
+ + 010   +
+ + 011     A location object is a map with the following properties: +
+ + 012   +
+ + 013     1. `:x`, whose value is a natural number not greater than the extent of the world; +
+ + 014     2. `:y`, whose value is a natural number not greater than the extent of the world. +
+ + 015   +
+ + 016     To execute a flow is transfer the quantity specified of the property specified +
+ + 017     from the cell at the source specified to the cell at the destination specified; +
+ + 018     if the source doesn't have sufficient of the property, then all it has should +
+ + 019     be transferred, but no more: properties to be flowed cannot be pulled negative. +
+ + 020      +
+ + 021     Flowing values through the world is consequently a two stage process: firstly +
+ + 022     there's a planning stage, in which all the flows to be executed are computed +
+ + 023     without changing the world, and then an execution stage, where they're all  +
+ + 024     executed. This namespace deals with mainly with execution." +
+ + 025    (:require [mw-engine.utils :refer [get-cell get-num in-bounds? merge-cell]] +
+ + 026              [taoensso.timbre :refer [info warn]])) +
+ + 027   +
+ + 028  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 029  ;;;; +
+ + 030  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 031  ;;;; +
+ + 032  ;;;; This program is free software; you can redistribute it and/or +
+ + 033  ;;;; modify it under the terms of the GNU General Public License +
+ + 034  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 035  ;;;; of the License, or (at your option) any later version. +
+ + 036  ;;;; +
+ + 037  ;;;; This program is distributed in the hope that it will be useful, +
+ + 038  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 039  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 040  ;;;; GNU General Public License for more details. +
+ + 041  ;;;; +
+ + 042  ;;;; You should have received a copy of the GNU General Public License +
+ + 043  ;;;; along with this program; if not, write to the Free Software +
+ + 044  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 045  ;;;; USA. +
+ + 046  ;;;; +
+ + 047  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 048  ;;;; +
+ + 049  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 050   +
+ + 051  (defn coordinate? +
+ + 052    "Return `true` if this object `o` is a valid coordinate with respect to +
+ + 053       this `world`, else `false`. Assumes square worlds." +
+ + 054    [o world] +
+ + 055    (try +
+ + 056      (and (or (zero? o) (pos-int? o)) +
+ + 057           (< o (count world))) +
+ + 058      (catch Exception e +
+ + 059        (warn (format "Not a valid coordinate: %s; %s" o (.getMessage e))) +
+ + 060        false))) +
+ + 061   +
+ + 062  (defn location? +
+ + 063    "Return `true` if this object `o` is a location as defined above with respect to +
+ + 064     this `world`, else `false`." +
+ + 065    [o world] +
+ + 066    (try +
+ + 067      (and (map? o) +
+ + 068           (integer? (:x o)) +
+ + 069           (integer? (:y o)) +
+ + 070           (in-bounds? world (:x o) (:y o))) +
+ + 071      (catch Exception e +
+ + 072        (warn (format "Not a valid location: %s; %s" o (.getMessage e))) +
+ + 073        false))) +
+ + 074   +
+ + 075  (defn flow? +
+ + 076    "Return `true` if this object `o` is a flow as defined above with respect to +
+ + 077     this `world`, else `false`. Assumes square worlds." +
+ + 078    [o world] +
+ + 079    (try +
+ + 080      (and (map? o) +
+ + 081           (location? (:source o) world) +
+ + 082           (location? (:destination o) world) +
+ + 083           (keyword? (:property o)) +
+ + 084           (pos? (:quantity o))) +
+ + 085      (catch Exception e +
+ + 086        (warn (format "Not a valid flow: %s; %s" o (.getMessage e))) +
+ + 087        false))) +
+ + 088   +
+ + 089  (defn execute +
+ + 090    "Return a world like this `world`, except with the quantity of the property +
+ + 091     described in this `flow` object transferred from the source of that flow +
+ + 092     to its destination." +
+ + 093    [world flow] +
+ + 094    (try +
+ + 095      (let [sx (-> flow :source :x) +
+ + 096            sy (-> flow :source :y) +
+ + 097            source (get-cell world sx sy) +
+ + 098            dx (-> flow :destination :x) +
+ + 099            dy (-> flow :destination :y) +
+ + 100            dest (get-cell world dx dy) +
+ + 101            p (:property flow) +
+ + 102            q (min (:quantity flow) (get-num source p)) +
+ + 103            s' (assoc source p (- (source p) q)) +
+ + 104            d' (assoc dest p (+ (get-num dest p) q))] +
+ + 105        (if (= q (:quantity flow)) +
+ + 106          (info (format "Moving %f units of %s from %d,%d to %d,%d" +
+ + 107                      (float q) (name p) sx sy dx dy)) +
+ + 108          (warn (format "Moving %s from %d,%d to %d,%d; %f units ordered but only %f available" +
+ + 109                        (name p) sx sy dx dy (float (:quantity flow)) (float q)))) +
+ + 110        (merge-cell (merge-cell world s') d')) +
+ + 111      (catch Exception e +
+ + 112        (warn (format "Failed to execute flow %s: %s" flow (.getMessage e))) +
+ + 113        ;; return the world unmodified. +
+ + 114        world))) +
+ + 115   +
+ + 116  (defn execute-flows +
+ + 117    "Return a world like this `world`, but with each of these flows executed." +
+ + 118    [world flows] +
+ + 119    (reduce execute world (filter #(flow? % world) flows))) +
+ + 120   +
+ + 121  ;; building blocks for compiled flow rules +
+ + 122   +
+ + 123  (defmacro create-location +
+ + 124    [cell] +
+ + 125    `(select-keys ~cell [:x :y])) +
+ + 126   +
+ + 127  (defmacro create-flow-quantity +
+ + 128    [source dest prop quantity] +
+ + 129    `{:source (create-location ~source) +
+ + 130      :destination (create-location ~dest) +
+ + 131      :prop ~prop +
+ + 132      :quantity ~quantity}) +
+ + 133   +
+ + 134  (defmacro create-flow-fraction +
+ + 135    [source dest prop fraction] +
+ + 136    `(create-flow-quantity ~source ~dest ~prop +
+ + 137                           (* ~fraction (get-num ~source ~prop)))) +
+ + 138   +
+ + 139  (defmacro create-flow-percent +
+ + 140    [source dest prop percent] +
+ + 141    `(create-flow-fraction ~source ~dest ~prop (/ ~percent 100))) +
+ + diff --git a/docs/cloverage/mw_engine/heightmap.clj.html b/docs/cloverage/mw_engine/heightmap.clj.html new file mode 100644 index 0000000..3926ecb --- /dev/null +++ b/docs/cloverage/mw_engine/heightmap.clj.html @@ -0,0 +1,389 @@ + + + + mw_engine/heightmap.clj + + + + 001  (ns ^{:doc "Functions to apply a heightmap to a world. +
+ + 002               +
+ + 003              Heightmaps are considered only as greyscale images, so colour is redundent +
+ + 004              (will be ignored). Darker shades are higher." +
+ + 005        :author "Simon Brooke"} +
+ + 006    mw-engine.heightmap +
+ + 007    (:require [mikera.image.core :refer [load-image filter-image]] +
+ + 008              [mikera.image.filters :as filters] +
+ + 009              [mw-engine.utils :refer [get-int get-neighbours map-world]] +
+ + 010              [mw-engine.world :refer [make-world]])) +
+ + 011   +
+ + 012  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 013  ;;;; +
+ + 014  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 015  ;;;; +
+ + 016  ;;;; This program is free software; you can redistribute it and/or +
+ + 017  ;;;; modify it under the terms of the GNU General Public License +
+ + 018  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 019  ;;;; of the License, or (at your option) any later version. +
+ + 020  ;;;; +
+ + 021  ;;;; This program is distributed in the hope that it will be useful, +
+ + 022  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 023  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 024  ;;;; GNU General Public License for more details. +
+ + 025  ;;;; +
+ + 026  ;;;; You should have received a copy of the GNU General Public License +
+ + 027  ;;;; along with this program; if not, write to the Free Software +
+ + 028  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 029  ;;;; USA. +
+ + 030  ;;;; +
+ + 031  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 032  ;;;; +
+ + 033  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 034   +
+ + 035  (defn tag-property +
+ + 036    "Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`. +
+ + 037     If the heightmap you supply is smaller than the world, this will break. +
+ + 038   +
+ + 039     * `world` not actually used, but present to enable this function to be +
+ + 040       passed as an argument to `mw-engine.utils/map-world`, q.v. +
+ + 041     * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map; +
+ + 042     * `property` the property (normally a keyword) whose value will be set on the cell. +
+ + 043     * `heightmap` an (ideally) greyscale image, whose x and y dimensions should +
+ + 044       exceed those of the world of which the `cell` forms part." +
+ + 045    ([_ cell property heightmap] +
+ + 046      (tag-property cell property heightmap)) +
+ + 047    ([cell property heightmap] +
+ + 048      (merge cell +
+ + 049             {property +
+ + 050              (+ (get-int cell property) +
+ + 051                 (- 256 +
+ + 052                    (abs +
+ + 053                      (mod +
+ + 054                        (.getRGB heightmap +
+ + 055                          (get-int cell :x) +
+ + 056                          (get-int cell :y)) 256))))}))) +
+ + 057   +
+ + 058  (defn tag-gradient +
+ + 059    "Set the `gradient` property of this `cell` of this `world` to the difference in +
+ + 060     altitude between its highest and lowest neghbours." +
+ + 061    [world cell] +
+ + 062    (let [heights (remove nil? (map :altitude (get-neighbours world cell))) +
+ + 063          highest (cond (empty? heights) 0 ;; shouldn't happen +
+ + 064                    :else (apply max heights)) +
+ + 065          lowest (cond (empty? heights) 0 ;; shouldn't +
+ + 066                   :else (apply min heights)) +
+ + 067          gradient (- highest lowest)] +
+ + 068      (merge cell {:gradient gradient}))) +
+ + 069   +
+ + 070  (defn tag-gradients +
+ + 071    "Set the `gradient` property of each cell in this `world` to the difference in +
+ + 072     altitude between its highest and lowest neghbours." +
+ + 073    [world] +
+ + 074    (map-world world tag-gradient)) +
+ + 075   +
+ + 076  (defn tag-altitude +
+ + 077    "Set the altitude of this cell from the corresponding pixel of this heightmap. +
+ + 078     If the heightmap you supply is smaller than the world, this will break. +
+ + 079   +
+ + 080     * `world` not actually used, but present to enable this function to be +
+ + 081       passed as an argument to `mw-engine.utils/map-world`, q.v.; +
+ + 082     * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map; +
+ + 083     * `heightmap` an (ideally) greyscale image, whose x and y dimensions should +
+ + 084       exceed those of the world of which the `cell` forms part." +
+ + 085    ([_ cell heightmap] +
+ + 086      (tag-property cell :altitude heightmap)) +
+ + 087    ([cell heightmap] +
+ + 088      (tag-property cell :altitude heightmap))) +
+ + 089   +
+ + 090  (defn apply-heightmap +
+ + 091    "Apply the image file loaded from this path to this world, and return a world whose +
+ + 092    altitudes are modified (added to) by the altitudes in the heightmap. It is assumed that +
+ + 093    the heightmap is at least as large in x and y dimensions as the world. Note that, in +
+ + 094    addition to setting the `:altitude` of each cell, this function also sets the `:gradient`. +
+ + 095   +
+ + 096    * `world` a world, as defined in `world.clj`, q.v.; if world is not supplied, +
+ + 097      a world the size of the heightmap will be created; +
+ + 098    * `imagepath` a file path or URL which indicates an (ideally greyscale) image file." +
+ + 099    ([world imagepath] +
+ + 100      (let [heightmap (filter-image +
+ + 101                       (load-image imagepath) +
+ + 102                        (filters/grayscale))] +
+ + 103        (map-world +
+ + 104          (map-world world tag-altitude (list heightmap)) +
+ + 105          tag-gradient))) +
+ + 106     ([imagepath] +
+ + 107      (let [heightmap (filter-image +
+ + 108                        (load-image imagepath) +
+ + 109                        (filters/grayscale)) +
+ + 110            world (make-world (.getWidth heightmap) (.getHeight heightmap))] +
+ + 111        (map-world +
+ + 112          (map-world world tag-altitude (list heightmap)) +
+ + 113          tag-gradient)))) +
+ + 114   +
+ + 115  (defn apply-valuemap +
+ + 116    "Generalised from apply-heightmap, set an arbitrary property on each cell +
+ + 117     of this `world` from the values in this (ideally greyscale) heightmap. +
+ + 118   +
+ + 119     * `world` a world, as defined in `world.clj`, q.v.; +
+ + 120     * `imagepath` a file path or URL which indicates an (ideally greyscale) image file; +
+ + 121     * `property` the property of each cell whose value should be added to from the +
+ + 122        intensity of the corresponding cell of the image." +
+ + 123    [world imagepath property] +
+ + 124      (let [heightmap (filter-image +
+ + 125                        (load-image imagepath) +
+ + 126                        (filters/grayscale))] +
+ + 127        (map-world world tag-property (list property heightmap)))) +
+ + diff --git a/docs/cloverage/mw_engine/natural_rules.clj.html b/docs/cloverage/mw_engine/natural_rules.clj.html new file mode 100644 index 0000000..d3b0094 --- /dev/null +++ b/docs/cloverage/mw_engine/natural_rules.clj.html @@ -0,0 +1,560 @@ + + + + mw_engine/natural_rules.clj + + + + 001  (ns ^{:doc "A set of MicroWorld rules describing a simplified natural ecosystem. +
+ + 002   +
+ + 003              Since the completion of the rule language this is more or less obsolete - +
+ + 004              there are still a few things that you can do with rules written in Clojure +
+ + 005              that you can't do in the rule language, but not many and I doubt they're +
+ + 006              important. " +
+ + 007         :author " Simon Brooke "} +
+ + 008    mw-engine.natural-rules +
+ + 009    (:require [mw-engine.utils :refer [get-int get-neighbours get-neighbours-with-state member?]])) +
+ + 010   +
+ + 011  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 012  ;;;; +
+ + 013  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 014  ;;;; +
+ + 015  ;;;; This program is free software; you can redistribute it and/or +
+ + 016  ;;;; modify it under the terms of the GNU General Public License +
+ + 017  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 018  ;;;; of the License, or (at your option) any later version. +
+ + 019  ;;;; +
+ + 020  ;;;; This program is distributed in the hope that it will be useful, +
+ + 021  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 022  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 023  ;;;; GNU General Public License for more details. +
+ + 024  ;;;; +
+ + 025  ;;;; You should have received a copy of the GNU General Public License +
+ + 026  ;;;; along with this program; if not, write to the Free Software +
+ + 027  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 028  ;;;; USA. +
+ + 029  ;;;; +
+ + 030  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 031  ;;;; +
+ + 032  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 033   +
+ + 034  ;; treeline at arbitrary altitude. +
+ + 035  (def treeline 150) +
+ + 036   +
+ + 037  ;; waterline also at arbitrary altitude. +
+ + 038  (def waterline 10) +
+ + 039   +
+ + 040  ;; and finally snowline is also arbitrary. +
+ + 041  (def snowline 200) +
+ + 042   +
+ + 043  ;; Rare chance of lightning strikes +
+ + 044  (def lightning-probability 500) +
+ + 045   +
+ + 046  ;; rules describing vegetation +
+ + 047  (def vegetation-rules +
+ + 048    (list +
+ + 049      ;; Randomly, birds plant tree seeds into grassland. +
+ + 050      (fn [cell _] (cond (and (= (:state cell) :grassland)(< (rand 10) 1))(merge cell {:state :heath}))) +
+ + 051      ;; heath below the treeline grows gradually into forest, providing browsing pressure is not to high +
+ + 052      (fn [cell _] +
+ + 053        (cond (and +
+ + 054                (= (:state cell) :heath) +
+ + 055                ;; browsing limit really ought to vary with soil fertility, but... +
+ + 056                (< (+ (get-int cell :deer)(get-int cell :sheep)) 6) +
+ + 057                (< (get-int cell :altitude) treeline)) +
+ + 058          (merge cell {:state :scrub}))) +
+ + 059      (fn [cell _] (cond (= (:state cell) :scrub) (merge cell {:state :forest}))) +
+ + 060      ;; Forest on fertile land grows to climax +
+ + 061      (fn [cell _] +
+ + 062        (cond +
+ + 063          (and +
+ + 064            (= (:state cell) :forest) +
+ + 065            (> (get-int cell :fertility) 10)) +
+ + 066          (merge cell {:state :climax}))) +
+ + 067      ;; Climax forest occasionally catches fire (e.g. lightning strikes) +
+ + 068      (fn [cell _] (cond (and (= (:state cell) :climax)(< (rand lightning-probability) 1)) (merge cell {:state :fire}))) +
+ + 069      ;; Climax forest neighbouring fires is likely to catch fire +
+ + 070      (fn [cell world] +
+ + 071        (cond +
+ + 072          (and (= (:state cell) :climax) +
+ + 073               (< (rand 3) 1) +
+ + 074               (not (empty? (get-neighbours-with-state world (:x cell) (:y cell) 1 :fire)))) +
+ + 075          (merge cell {:state :fire}))) +
+ + 076      ;; After fire we get waste +
+ + 077      (fn [cell _] (cond (= (:state cell) :fire) (merge cell {:state :waste}))) +
+ + 078      ;; And after waste we get pioneer species; if there's a woodland seed +
+ + 079      ;; source, it's going to be heath, otherwise grassland. +
+ + 080      (fn [cell world] +
+ + 081        (cond +
+ + 082          (and (= (:state cell) :waste) +
+ + 083               (not +
+ + 084                 (empty? +
+ + 085                   (flatten +
+ + 086                     (list +
+ + 087                       (get-neighbours-with-state world (:x cell) (:y cell) 1 :scrub) +
+ + 088                       (get-neighbours-with-state world (:x cell) (:y cell) 1 :forest) +
+ + 089                       (get-neighbours-with-state world (:x cell) (:y cell) 1 :climax)))))) +
+ + 090          (merge cell {:state :heath}))) +
+ + 091      (fn [cell _] +
+ + 092        (cond (= (:state cell) :waste) +
+ + 093          (merge cell {:state :grassland}))) +
+ + 094      ;; Forest increases soil fertility +
+ + 095      (fn [cell _] +
+ + 096        (cond (member? (:state cell) '(:forest :climax)) +
+ + 097          (merge cell {:fertility (+ (get-int cell :fertility) 1)}))))) +
+ + 098   +
+ + 099   +
+ + 100  ;; rules describing herbivore behaviour +
+ + 101  (def herbivore-rules +
+ + 102    (list +
+ + 103      ;; if there are too many deer for the fertility of the area to sustain, +
+ + 104      ;; some die or move on. +
+ + 105      (fn [cell _] +
+ + 106        (cond (> (get-int cell :deer) (get-int cell :fertility)) +
+ + 107          (merge cell {:deer (get-int cell :fertility)}))) +
+ + 108      ;; deer arrive occasionally at the edge of the map. +
+ + 109      (fn [cell world] +
+ + 110        (cond (and (< (count (get-neighbours world cell)) 8) +
+ + 111                   (< (rand 50) 1) +
+ + 112                   (> (get-int cell :fertility) 0) +
+ + 113                   (= (get-int cell :deer) 0)) +
+ + 114          (merge cell {:deer 2}))) +
+ + 115      ;; deer gradually spread through the world by breeding or migrating. +
+ + 116      (fn [cell world] +
+ + 117        (let [n (apply + (map #(get-int % :deer) (get-neighbours world cell)))] +
+ + 118          (cond (and +
+ + 119                  (> (get-int cell :fertility) 0) +
+ + 120                  (= (get-int cell :deer) 0) +
+ + 121                  (>= n 2)) +
+ + 122            (merge cell {:deer (int (/ n 2))})))) +
+ + 123      ;; deer breed. +
+ + 124      (fn [cell _] +
+ + 125        (cond +
+ + 126          (>= (get-int cell :deer) 2) +
+ + 127          (merge cell {:deer (int (* (:deer cell) 2))}))))) +
+ + 128   +
+ + 129    ;; rules describing predator behaviour +
+ + 130    (def predator-rules +
+ + 131      (list +
+ + 132       ;; wolves eat deer +
+ + 133       (fn [cell _] +
+ + 134        (cond +
+ + 135         (>= (get-int cell :wolves) 1) +
+ + 136         (merge cell {:deer (max 0 (- (get-int cell :deer) (get-int cell :wolves)))}))) +
+ + 137  ;;      ;; not more than eight wolves in a pack, for now (hack because wolves are not dying) +
+ + 138  ;;      (fn [cell world] +
+ + 139  ;;        (cond (> (get-int cell :wolves) 8) (merge cell {:wolves 8}))) +
+ + 140      ;; if there are not enough deer to sustain the get-int of wolves, +
+ + 141      ;; some wolves die or move on. (doesn't seem to be working?) +
+ + 142      (fn [cell _] +
+ + 143         (cond (> (get-int cell :wolves) (get-int cell :deer)) +
+ + 144           (merge cell {:wolves 0}))) +
+ + 145      ;; wolves arrive occasionally at the edge of the map. +
+ + 146      (fn [cell world] +
+ + 147        (cond (and (< (count (get-neighbours world cell)) 8) +
+ + 148                   (< (rand 50) 1) +
+ + 149                   (not (= (:state cell) :water)) +
+ + 150                   (= (get-int cell :wolves) 0)) +
+ + 151          (merge cell {:wolves 2}))) +
+ + 152      ;; wolves gradually spread through the world by breeding or migrating. +
+ + 153      (fn [cell world] +
+ + 154        (let [n (apply + (map #(get-int % :wolves) (get-neighbours world cell)))] +
+ + 155          (cond (and +
+ + 156                  (not (= (:state cell) :water)) +
+ + 157                  (= (get-int cell :wolves) 0) +
+ + 158                  (>= n 2)) +
+ + 159            (merge cell {:wolves 2})))) +
+ + 160      ;; wolves breed. +
+ + 161      (fn [cell _] +
+ + 162        (cond +
+ + 163          (>= (get-int cell :wolves) 2) +
+ + 164          (merge cell {:wolves (int (* (:wolves cell) 2))}))))) +
+ + 165   +
+ + 166   +
+ + 167    ;; rules which initialise the world +
+ + 168    (def init-rules +
+ + 169      (list +
+ + 170       ;; below the waterline, we have water. +
+ + 171       (fn [cell _] +
+ + 172         (cond (and (= (:state cell) :new) (< (get-int cell :altitude) waterline)) (merge cell {:state :water}))) +
+ + 173       ;; above the snowline, we have snow. +
+ + 174       (fn [cell _] +
+ + 175         (cond (and (= (:state cell) :new) (> (get-int cell :altitude) snowline)) (merge cell {:state :snow}))) +
+ + 176       ;; in between, we have a wasteland. +
+ + 177       (fn [cell _] (cond (= (:state cell) :new) (merge cell {:state :grassland}))))) +
+ + 178   +
+ + 179   +
+ + 180  (def natural-rules (flatten +
+ + 181                      (list +
+ + 182                       vegetation-rules +
+ + 183                       herbivore-rules +
+ + 184                       predator-rules))) +
+ + diff --git a/docs/cloverage/mw_engine/utils.clj.html b/docs/cloverage/mw_engine/utils.clj.html new file mode 100644 index 0000000..0ff50d2 --- /dev/null +++ b/docs/cloverage/mw_engine/utils.clj.html @@ -0,0 +1,911 @@ + + + + mw_engine/utils.clj + + + + 001  (ns ^{:doc " Utility functions needed by MicroWorld and, specifically, in the +
+ + 002        interpretation of MicroWorld rule." +
+ + 003        :author "Simon Brooke"} +
+ + 004   mw-engine.utils +
+ + 005    (:require +
+ + 006     [clojure.math.combinatorics :as combo])) +
+ + 007   +
+ + 008  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 009  ;;;; +
+ + 010  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 011  ;;;; +
+ + 012  ;;;; This program is free software; you can redistribute it and/or +
+ + 013  ;;;; modify it under the terms of the GNU General Public License +
+ + 014  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 015  ;;;; of the License, or (at your option) any later version. +
+ + 016  ;;;; +
+ + 017  ;;;; This program is distributed in the hope that it will be useful, +
+ + 018  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 019  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 020  ;;;; GNU General Public License for more details. +
+ + 021  ;;;; +
+ + 022  ;;;; You should have received a copy of the GNU General Public License +
+ + 023  ;;;; along with this program; if not, write to the Free Software +
+ + 024  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 025  ;;;; USA. +
+ + 026  ;;;; +
+ + 027  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 028  ;;;; +
+ + 029  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 030   +
+ + 031  (defn member? +
+ + 032    "Return 'true' if elt is a member of col, else 'false'." +
+ + 033    [elt col]  +
+ + 034    (contains? (set col) elt)) +
+ + 035   +
+ + 036  (defn get-int-or-zero +
+ + 037    "Return the value of this `property` from this `map` if it is a integer; +
+ + 038     otherwise return zero." +
+ + 039    [map property] +
+ + 040    (let [value (map property)] +
+ + 041      (if (integer? value) value 0))) +
+ + 042   +
+ + 043  (defn init-generation +
+ + 044    "Return a cell like this `cell`, but having a value for :generation, zero if +
+ + 045     the cell passed had no integer value for generation, otherwise the value +
+ + 046     taken from the cell passed. The `world` argument is present only for +
+ + 047     consistency with the rule engine and is ignored." +
+ + 048    [_ cell] +
+ + 049    (merge cell {:generation (get-int-or-zero cell :generation)})) +
+ + 050   +
+ + 051  (defn in-bounds +
+ + 052    "True if x, y are in bounds for this world (i.e., there is a cell at x, y) +
+ + 053     else false. *DEPRECATED*: it's a predicate, prefer `in-bounds?`. +
+ + 054   +
+ + 055    * `world` a world as defined in [world.clj](mw-engine.world.html); +
+ + 056    * `x` a number which may or may not be a valid x coordinate within that world; +
+ + 057    * `y` a number which may or may not be a valid y coordinate within that world." +
+ + 058    {:deprecated "1.1.7"} +
+ + 059    [world x y] +
+ + 060    (and (>= x 0) (>= y 0) (< y (count world)) (< x (count (first world))))) +
+ + 061   +
+ + 062  (defn in-bounds? +
+ + 063    "True if x, y are in bounds for this world (i.e., there is a cell at x, y) +
+ + 064     else false. +
+ + 065   +
+ + 066    * `world` a world as defined in [world.clj](mw-engine.world.html); +
+ + 067    * `x` a number which may or may not be a valid x coordinate within that world; +
+ + 068    * `y` a number which may or may not be a valid y coordinate within that world." +
+ + 069    {:added "1.1.7"} +
+ + 070    [world x y] +
+ + 071    (and (>= x 0) (>= y 0) (< y (count world)) (< x (count (first world))))) +
+ + 072   +
+ + 073  (defn map-world-n-n +
+ + 074    "Wholly non-parallel map world implementation; see documentation for `map-world`." +
+ + 075    ([world function] +
+ + 076     (map-world-n-n world function nil)) +
+ + 077    ([world function additional-args] +
+ + 078     (into [] +
+ + 079           (map (fn [row] +
+ + 080                  (into [] (map +
+ + 081                            #(apply function +
+ + 082                                    (cons world (cons % additional-args))) +
+ + 083                            row))) +
+ + 084                world)))) +
+ + 085   +
+ + 086   +
+ + 087  (defn map-world-p-p +
+ + 088    "Wholly parallel map-world implementation; see documentation for `map-world`." +
+ + 089    ([world function] +
+ + 090     (map-world-p-p world function nil)) +
+ + 091    ([world function additional-args] +
+ + 092     (into [] +
+ + 093           (pmap (fn [row] +
+ + 094                   (into [] (pmap +
+ + 095                             #(apply function +
+ + 096                                     (cons world (cons % additional-args))) +
+ + 097                             row))) +
+ + 098                 world)))) +
+ + 099   +
+ + 100  (defn map-world +
+ + 101    "Apply this `function` to each cell in this `world` to produce a new world. +
+ + 102    the arguments to the function will be the world, the cell, and any +
+ + 103    `additional-args` supplied. Note that we parallel map over rows but +
+ + 104    just map over cells within a row. That's because it isn't worth starting +
+ + 105    a new thread for each cell, but there may be efficiency gains in +
+ + 106    running rows in parallel." +
+ + 107    ([world function] +
+ + 108     (map-world world function nil)) +
+ + 109    ([world function additional-args] +
+ + 110     (into [] +
+ + 111           (pmap (fn [row] +
+ + 112                   (into [] (map +
+ + 113                             #(apply function +
+ + 114                                     (cons world (cons % additional-args))) +
+ + 115                             row))) +
+ + 116                 world)))) +
+ + 117   +
+ + 118  (defn get-cell +
+ + 119    "Return the cell a x, y in this world, if any. +
+ + 120   +
+ + 121    * `world` a world as defined in [world.clj](mw-engine.world.html); +
+ + 122    * `x` a number which may or may not be a valid x coordinate within that world; +
+ + 123    * `y` a number which may or may not be a valid y coordinate within that world." +
+ + 124    [world x y] +
+ + 125    (when (in-bounds? world x y) +
+ + 126      (nth (nth world y) x))) +
+ + 127   +
+ + 128  (defn get-int +
+ + 129    "Get the value of a property expected to be an integer from a map; if not +
+ + 130     present (or not an integer) return 0. +
+ + 131   +
+ + 132    * `map` a map; +
+ + 133    * `key` a symbol or keyword, presumed to be a key into the `map`." +
+ + 134    [map key] +
+ + 135    (if (map? map) +
+ + 136      (let [v (map key)] +
+ + 137        (cond (and v (integer? v)) v +
+ + 138              :else 0)) +
+ + 139      (throw (Exception. "No map passed?")))) +
+ + 140   +
+ + 141  (defn get-num +
+ + 142    "Get the value of a property expected to be a number from a map; if not +
+ + 143     present (or not a number) return 0. +
+ + 144   +
+ + 145    * `map` a map; +
+ + 146    * `key` a symbol or keyword, presumed to be a key into the `map`." +
+ + 147    [map key] +
+ + 148    (if (map? map) +
+ + 149      (let [v (map key)] +
+ + 150        (cond (and v (number? v)) v +
+ + 151              :else 0)) +
+ + 152      (throw (Exception. "No map passed?")))) +
+ + 153   +
+ + 154  (defn population +
+ + 155    "Return the population of this species in this cell. Currently a synonym for +
+ + 156     `get-int`, but may not always be (depending whether species are later +
+ + 157     implemented as actors) +
+ + 158   +
+ + 159    * `cell` a map; +
+ + 160    * `species` a keyword representing a species which may populate that cell." +
+ + 161    [cell species] +
+ + 162    (get-int cell species)) +
+ + 163   +
+ + 164  (def memo-get-neighbours +
+ + 165    "Memoised get neighbours is more efficient when running deeply recursive +
+ + 166     algorithms on the same world. But it's less efficient when running the +
+ + 167     engine in its normal iterative style, because then we will rarely call +
+ + 168     get naighbours on the same cell of the same world twice." +
+ + 169    (memoize +
+ + 170     (fn [world x y depth] +
+ + 171       (remove nil? +
+ + 172               (map #(get-cell world (first %) (first (rest %))) +
+ + 173                    (remove #(= % (list x y)) +
+ + 174                            (combo/cartesian-product +
+ + 175                             (range (- x depth) (+ x depth 1)) +
+ + 176                             (range (- y depth) (+ y depth 1))))))))) +
+ + 177   +
+ + 178  (defn get-neighbours +
+ + 179    "Get the neighbours to distance depth of a cell in this world. +
+ + 180   +
+ + 181      Several overloads: +
+ + 182      * `world` a world, as described in [world.clj](mw-engine.world.html); +
+ + 183      * `cell` a cell within that world +
+ + 184      Gets immediate neighbours of the specified cell. +
+ + 185   +
+ + 186      * `world` a world, as described in[world.clj](mw-engine.world.html); +
+ + 187      * `cell` a cell within that world +
+ + 188      * `depth` an integer representing the depth to search from the +
+ + 189        `cell` +
+ + 190      Gets neighbours within the specified distance of the cell. +
+ + 191   +
+ + 192      * `world` a world, as described in[world.clj](mw-engine.world.html); +
+ + 193      * `x` an integer representing an x coordinate in that world; +
+ + 194      * `y` an integer representing an y coordinate in that world; +
+ + 195      * `depth` an integer representing the distance from [x,y] that +
+ + 196        should be searched +
+ + 197      Gets the neighbours within the specified distance of the cell at +
+ + 198      coordinates [x,y] in this world." +
+ + 199    ([world x y depth] +
+ + 200     (memo-get-neighbours world x y depth)) +
+ + 201    ([world cell depth] +
+ + 202     (memo-get-neighbours world (:x cell) (:y cell) depth)) +
+ + 203    ([world cell] +
+ + 204     (memo-get-neighbours world (:x cell) (:y cell) 1))) +
+ + 205   +
+ + 206  (defn get-neighbours-with-property-value +
+ + 207    "Get the neighbours to distance depth of the cell at x, y in this world which +
+ + 208     have this value for this property. +
+ + 209   +
+ + 210      * `world` a world, as described in [world.clj](mw-engine.world.html); +
+ + 211      * `cell` a cell within that world; +
+ + 212      * `depth` an integer representing the distance from [x,y] that +
+ + 213        should be searched (optional); +
+ + 214      * `property` a keyword representing a property of the neighbours; +
+ + 215      * `value` a value of that property (or, possibly, the name of another); +
+ + 216      * `op` a comparator function to use in place of `=` (optional). +
+ + 217   +
+ + 218     It gets messy." +
+ + 219    ([world x y depth property value op] +
+ + 220     (filter +
+ + 221      #(eval +
+ + 222        (list op +
+ + 223              (or (get % property) (get-int % property)) +
+ + 224              value)) +
+ + 225      (get-neighbours world x y depth))) +
+ + 226    ([world x y depth property value] +
+ + 227     (get-neighbours-with-property-value world x y depth property value =)) +
+ + 228    ([world cell depth property value] +
+ + 229     (get-neighbours-with-property-value world (:x cell) (:y cell) depth +
+ + 230                                         property value)) +
+ + 231    ([world cell property value] +
+ + 232     (get-neighbours-with-property-value world cell 1 +
+ + 233                                         property value))) +
+ + 234   +
+ + 235  (defn get-neighbours-with-state +
+ + 236    "Get the neighbours to distance depth of the cell at x, y in this world which +
+ + 237     have this state. +
+ + 238   +
+ + 239      * `world` a world, as described in [world.clj](mw-engine.world.html); +
+ + 240      * `cell` a cell within that world; +
+ + 241      * `depth` an integer representing the distance from [x,y] that +
+ + 242        should be searched; +
+ + 243      * `state` a keyword representing a state in the world." +
+ + 244    ([world x y depth state] +
+ + 245     (filter #(= (:state %) state) (get-neighbours world x y depth))) +
+ + 246    ([world cell depth state] +
+ + 247     (get-neighbours-with-state world (:x cell) (:y cell) depth state)) +
+ + 248    ([world cell state] +
+ + 249     (get-neighbours-with-state world cell 1 state))) +
+ + 250   +
+ + 251  (defn get-least-cell +
+ + 252    "Return the cell from among these `cells` which has the lowest numeric value +
+ + 253    for this `property`." +
+ + 254    [cells property] +
+ + 255    (first (sort-by property (filter #(number? (property %)) cells)))) +
+ + 256   +
+ + 257  (defn get-most-cell +
+ + 258    "Return the cell from among these `cells` which has the highest numeric value +
+ + 259    for this `property`." +
+ + 260    [cells property] +
+ + 261    (last (sort-by property (filter #(number? (property %)) cells)))) +
+ + 262   +
+ + 263  (defn- set-cell-property +
+ + 264    "If this `cell`s x and y properties are equal to these `x` and `y` values, +
+ + 265     return a cell like this cell but with the value of this `property` set to +
+ + 266     this `value`. Otherwise, just return this `cell`." +
+ + 267    [cell x y property value] +
+ + 268    (cond +
+ + 269      (and (= x (:x cell)) (= y (:y cell))) +
+ + 270      (merge cell {property value :rule "Set by user"}) +
+ + 271      :else cell)) +
+ + 272   +
+ + 273  (defn set-property +
+ + 274    "Return a world like this `world` but with the value of exactly one `property` +
+ + 275     of one `cell` changed to this `value`" +
+ + 276    ([world cell property value] +
+ + 277     (set-property world (:x cell) (:y cell) property value)) +
+ + 278    ([world x y property value] +
+ + 279     (apply +
+ + 280      vector ;; we want a vector of vectors, not a list of lists, for efficiency +
+ + 281      (map +
+ + 282       (fn [row] +
+ + 283         (apply +
+ + 284          vector +
+ + 285          (map #(set-cell-property % x y property value) +
+ + 286               row))) +
+ + 287       world)))) +
+ + 288   +
+ + 289  (defn merge-cell +
+ + 290    "Return a world like this `world`, but merge the values from this `cell` with +
+ + 291     those from the cell in the world with the same co-ordinates" +
+ + 292    [world cell] +
+ + 293    (if (in-bounds? world (:x cell) (:y cell)) +
+ + 294      (map-world world +
+ + 295                 #(if +
+ + 296                   (and +
+ + 297                    (= (:x cell) (:x %2)) +
+ + 298                    (= (:y cell) (:y %2))) +
+ + 299                    (merge %2 cell) +
+ + 300                    %2)) +
+ + 301      world)) +
+ + diff --git a/docs/cloverage/mw_engine/world.clj.html b/docs/cloverage/mw_engine/world.clj.html new file mode 100644 index 0000000..2bfd094 --- /dev/null +++ b/docs/cloverage/mw_engine/world.clj.html @@ -0,0 +1,275 @@ + + + + mw_engine/world.clj + + + + 001  (ns ^{:doc "Functions to create and to print two dimensional cellular automata. +
+ + 002               +
+ + 003              Nothing in this namespace should determine what states are possible within +
+ + 004              the automaton, except for the initial state, :new. +
+ + 005   +
+ + 006              A cell is a map containing at least values for the keys `:x`, `:y`, and `:state`. +
+ + 007   +
+ + 008              A world is a two dimensional matrix (sequence of sequences) of cells, such +
+ + 009              that every cell's `:x` and `:y` properties reflect its place in the matrix." +
+ + 010        :author "Simon Brooke"} +
+ + 011   mw-engine.world +
+ + 012    (:require [clojure.string :as string] +
+ + 013              [mw-engine.utils :refer [population]])) +
+ + 014   +
+ + 015  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 016  ;;;; +
+ + 017  ;;;; mw-engine: the state/transition engine of MicroWorld. +
+ + 018  ;;;; +
+ + 019  ;;;; This program is free software; you can redistribute it and/or +
+ + 020  ;;;; modify it under the terms of the GNU General Public License +
+ + 021  ;;;; as published by the Free Software Foundation; either version 2 +
+ + 022  ;;;; of the License, or (at your option) any later version. +
+ + 023  ;;;; +
+ + 024  ;;;; This program is distributed in the hope that it will be useful, +
+ + 025  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +
+ + 026  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +
+ + 027  ;;;; GNU General Public License for more details. +
+ + 028  ;;;; +
+ + 029  ;;;; You should have received a copy of the GNU General Public License +
+ + 030  ;;;; along with this program; if not, write to the Free Software +
+ + 031  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, +
+ + 032  ;;;; USA. +
+ + 033  ;;;; +
+ + 034  ;;;; Copyright (C) 2014 Simon Brooke +
+ + 035  ;;;; +
+ + 036  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +
+ + 037   +
+ + 038  (defmacro make-cell +
+ + 039    "Create a minimal default cell at x, y +
+ + 040   +
+ + 041    * `x` the x coordinate at which this cell is created; +
+ + 042    * `y` the y coordinate at which this cell is created." +
+ + 043    [x y] +
+ + 044    `{:x ~x :y ~y :state :new}) +
+ + 045   +
+ + 046  (defn make-world +
+ + 047    "Make a world width cells from east to west, and height cells from north to +
+ + 048     south. +
+ + 049   +
+ + 050    * `width` a natural number representing the width of the matrix to be created; +
+ + 051    * `height` a natural number representing the height of the matrix to be created." +
+ + 052    [width height] +
+ + 053    (apply vector +
+ + 054           (map (fn [h] +
+ + 055                  (apply vector (map #(make-cell % h) (range width)))) +
+ + 056                (range height)))) +
+ + 057   +
+ + 058  (defn truncate-state +
+ + 059    "Truncate the print name of the state of this cell to at most limit characters." +
+ + 060    [cell limit] +
+ + 061    (let [s (:state cell)] +
+ + 062      (cond (> (count (str s)) limit) (subs s 0 limit) +
+ + 063            :else s))) +
+ + 064   +
+ + 065  (defn format-cell +
+ + 066    "Return a formatted string summarising the current state of this cell." +
+ + 067    [cell] +
+ + 068    (format "%10s(%2d/%2d)" +
+ + 069            (truncate-state cell 10) +
+ + 070            (population cell :deer) +
+ + 071            (population cell :wolves))) +
+ + 072   +
+ + 073  (defn- format-world-row +
+ + 074    "Format one row in the state of a world for printing." +
+ + 075    [row] +
+ + 076    (string/join (map format-cell row))) +
+ + 077   +
+ + 078  (defn print-world +
+ + 079    "Print the current state of this world, and return nil. +
+ + 080   +
+ + 081    * `world` a world as defined above." +
+ + 082    [world] +
+ + 083    (println) +
+ + 084    (dorun +
+ + 085     (map +
+ + 086      #(println +
+ + 087        (format-world-row %)) +
+ + 088      world)) +
+ + 089    nil) +
+ + 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..1c9e38a --- /dev/null +++ b/docs/codox/index.html @@ -0,0 +1,11 @@ + +Mw-engine 0.2.0-SNAPSHOT

Mw-engine 0.2.0-SNAPSHOT

Released under the GNU General Public License v2

Cellular automaton world builder.

Installation

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

[mw-engine "0.2.0-SNAPSHOT"]

Topics

Namespaces

mw-engine.core

Functions to transform a world and run rules.

+

Public variables and functions:

mw-engine.display

Simple functions to allow a world to be visualised.

+

mw-engine.drainage

Experimental, probably of no interest to anyone else; attempt to compute drainage on a world, assumed to have altitudes already set from a heightmap.

+

mw-engine.flow

Allow flows of values between cells in the world.

+

mw-engine.heightmap

Functions to apply a heightmap to a world.

+

mw-engine.natural-rules

A set of MicroWorld rules describing a simplified natural ecosystem.

+

mw-engine.world

Functions to create and to print two dimensional cellular automata.

+

Public variables and functions:

\ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html new file mode 100644 index 0000000..2dd3792 --- /dev/null +++ b/docs/codox/intro.html @@ -0,0 +1,5 @@ + +Introduction to mw-engine

Introduction to mw-engine

+

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