[
  {
    "path": ".gitignore",
    "content": "01-clojure-literate-ants/literate-ants.clj\n01-clojure-literate-ants/project.clj\n02-minimal-clojure-app/src/\n02-minimal-clojure-app/test/"
  },
  {
    "path": "00-just-code-blocks/simple-code-blocks.org",
    "content": "#+TITLE: Simple Code Blocks - a Literate Programming File\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+LANGUAGE: en\n#+STARTUP: align hidestars lognotestate\n\n\n* Introduction\nThis file just shows simple usage of code blocks in Org mode; unlike\nlater examples, there are no Org =:tangle= file locations used here.\nInstead, we just show how easy and convenient it is to mix structured\nprose/markup with code blocks.\n\n\n* 4Clojure problem 42 , [[http://www.4clojure.com/problem/42][Factorial Fun]] - first solved [2012-05-23 Wed]\nWrite a function which calculates factorials.\n\n** My solution, <1 minute: reduce w/ range\n#+BEGIN_SRC clojure\n#(reduce * (range 1 (inc %)))\n#+END_SRC\n\n** Other solutions: =reduce=, or use =apply= with =range=\n#+BEGIN_SRC clojure\n;; maximental's solution:\n#(apply * % (range 2 %))\n\n\n;; daowen's solution:\n#(apply * (range 1 (inc %)))\n\n\n;; redraiment's solution:\n#(apply * % (range 1 %))\n\n\n;; sheldon's solution:\n#(loop [x % r 1] (if (= x 1) r (recur (dec x) (* r x))))\n\n\n;; vyzamyatin's solution:\n#(reduce * (range 1 (inc %)))\n\n\n;; amcnamara's solution:\n#(apply * (range 1 (inc %)))\n#+END_SRC\n"
  },
  {
    "path": "01-clojure-literate-ants/literate-ants.org",
    "content": "#+TITLE: The Clojure Ants Simulation, in Literate Form\n#+AUTHOR: Rich Hickey (this literate/org-babel version, Kai Wu)\n#+EMAIL: k@limist.com\n#+LANGUAGE: en\n#+STARTUP: align indent fold nodlcheck hidestars oddeven lognotestate\n#+PROPERTY: tangle literate-ants.clj\n\n\n* Introduction\n** What is this, why is it worthwhile? Quickly please!\n+ You're looking at a literate programming (LP) style, single-file\n  version of Rich Hickey's Clojure ants simulator, in Org mode format.\n+ For best results please *use Emacs with Org mode to view this*\n  =.org= *file*. If you're looking at this on Github.com, STOP - the\n  rendering there is neither complete nor correct!\n\n** The *benefits* of LP using Emacs + Org\n1. Docs matter, a lot. With LP, documentation is integral to\n   development, never an afterthought.\n   - For all but small throwaway systems, you're likely keeping a\n     separate file of development notes already; LP would integrate\n     that.\n2. With one LP file, avoid the incidental/inessential complexity of\n   the filesystem: avoid context-switch overhead moving between files,\n   and sidestep your language's imposed filesystem structure.\n3. Org rocks for prose:\n   - Org's plain-text *markup is lightweight*, yet more powerful than\n     Markdown, and cleaner than rST.\n   - The *structural editing* provided by Org documents lets you\n     organize your thoughts/writing/code very quickly.  With good\n     structure even major revisions are easy.\n   - Org's exporter lets your *write-once, express-many-times*: you\n     can export an Org file to HTML (e.g. for blogging) or LaTeX\n     (for serious publishing).\n   - It's easy to version-control Org files.\n4. Org rocks for code:\n   - Each code block has flexible granularity: can be named and\n     referred to; evaluated or not; have data sent in or exported;\n     specify different REPL sessions; specify different target/tangled\n     files.\n   - Code blocks are syntax-highlighted.\n   - Code blocks are ready to edit: jump to major-mode editing easily.\n   - A single Org file can mix different languages.\n5. Meta-development, manage complexity from a coherent perspective: a\n   unified, single-file approach encourages holistic software\n   development and exposition, in a natural order, using structure to\n   enhance understanding.  LP is not just documentation and code\n   together: it's a *process and abstraction unifying the development\n   lifecycle*: requirements, architecture, design, code, tests,\n   deployment, and maintenance - can all be bound coherently in one\n   active format.\n\n** Why Clojure?\n[[http://clojure.org][Clojure]] is a modern Lisp dialect that runs (primarily) on the [[http://en.wikipedia.org/wiki/Jvm][Java\nVirtual Machine]]. As a language its main paradigm is [[http://en.wikipedia.org/wiki/Functional_programming][functional\nprogramming]] (vs. the usual [[http://en.wikipedia.org/wiki/Object-oriented_programming][OO]] or [[http://en.wikipedia.org/wiki/Imperative_programming][imperative]] languages of Java, Python,\nRuby), and it also provides powerful constructs for concurrency such\nas [[http://en.wikipedia.org/wiki/Software_transactional_memory][software transactional memory (STM)]].\n\nSo why use or learn Clojure?\n1. There are *technical* reasons, better covered elsewhere.\n2. There are *aesthetic* reasons: code is poetry, and like the best\n   poems, expressiveness (the ratio of power:symbols) matters, and\n   Clojure excels there.\n3. Last but certainly not least, there are *human* reasons: I've found\n   the Clojure community to be one of the smartest and friendliest\n   around: there's a lot of brilliant-yet-humble innovation going\n   on. If you've watched Hickey's talks and gotten a sense of his\n   character, the same spirit generally pervades Clojurians.\n\n** Why literate ants?\nWhen Clojure was invented and began picking up interest from\n2007/2008, its creator Rich Hickey would [[http://www.youtube.com/watch?v=dGVqrGmwOAw][highlight Clojure's features\nwith a demo program]]: a visual simulation of ants seeking food on a\nfinite 2-D \"world\" board. I found the =ants.clj= program fascinating,\nparticularly as simulation is a core interest. Historically,\n[[https://en.wikipedia.org/wiki/Object-oriented_programming#History][simulations motivated the object-oriented programming]] paradigm, so\nseeing a very different yet concise way to fulfill requirements of\nencapsulation, concurrent state, and modeling changes over time drew\nme in to Clojure.\n\nTo build more skill in Clojure, I wanted to fully understand\n=ants.clj=.  I also wanted to try Knuth's [[http://vasc.ri.cmu.edu/old_help/Programming/Literate/literate.html][literate programming\napproach]] (LP), using my favorite tool: [[http://www.gnu.org/software/emacs/][Emacs]] and its peerless\n[[http://orgmode.org][org-mode]]. Thus this =.org= file (and its HTML or PDF version) you're\nnow looking at is the literate version of Hickey's =ants.clj= code. I\ntook the original program, made minor changes for my comprehension,\nand offer it as a working example of literate Clojure.\n\n** Overview and setup\n*** Prerequisites\n1. A recent version of Emacs (ideally 24.3+).\n2. Both org-mode and =clojure-mode= installed; use Emacs ELPA.\n   - Consider using an Emacs \"starter package\" that provides a good\n     baseline, like [[http://batsov.com/prelude/][Emacs Prelude]] or [[http://overtone.github.io/emacs-live/][Emacs Live]].\n\nThen if you start Emacs and load this file, you'll see it the way it's\nmeant to be seen: as a multi-level, hierarchically organized and\nstructured literate code file, w/ syntax-highlighted code blocks.  \n\n*** Useful commands\n- Use =SHIFT-TAB= and org-mode will cycle through top-level, headings,\n  and full-expanded displays.\n- To generate a source-file from this =.org= file, =CTRL-c-v-t= to do\n  the /tangling/ step; that means org-mode will process each code\n  block below, and generate the source file =literate-ants.clj=\n\n*** Skip to the end? Good idea!\nBefore you dive into the actual code, you may want to run the ants\nsimulation first - seeing it in action will help with understanding\nthe details too.  So tangle this literate file per above instructions,\nso you have the =literate-ants.clj= file, then jump down to [[Running\nthe Program]].\n\n** Caveats - this may not be the LP you're looking for\n1. Don't take this file as anything like an ideal literate programming\n   example!  This is just my version of understanding Rich Hickey's\n   code, thus it does not reflect a complete or proper literate\n   programming approach to use.\n   - And what's *proper LP*? See the last 2009 comment on the\n     [[http://www.literateprogramming.com/][literateprogramming.com page]].  LP is not just about\n     documentation, but is a tool/approach for higher-level\n     abstraction, combining human thought and code.\n   - So beware: much of my prose below is relatively verbose and\n     explanatory (the /what/ and /how/ of code), as opposed to what\n     could/should be in the literate sections: meta, /why/, high-level\n     discussion of major design choices.\n2. This version does not yet reflect more recent (post Clojure 1.2)\n   changes to the language, e.g. =defstruct= is still used below, but\n   has been deprecated in favor of [[http://clojure.org/datatypes][Clojure records]].\n3. My Java experience is quite limited, so parts which rely heavily on\n   Java, such as the UI, I don't attempt to explain in-depth.\n\n\n* The Simulation World\nThe first part of =ants.clj= sets up the simulation world, where we'll\nbe introduced to some of Clojure's powers.\n\n** Initial setup of constants/magic-numbers\nAfter the copyright notice, the initial setup code of =ants.clj= is\neasy to understand (for coders at least), even if you've never dealt\nwith Lisp before. We see parameters (aka constants and magic numbers)\nbeing defined for later use using Clojure's =[[http://clojure.org/special_forms#def][def]]= special form: =def=\ncreates a var (a mutable storage location) which connects a symbol to\na value in the current [[http://clojure.org/namespaces][namespace]].\n\n#+name: sim-world-setup\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ant sim ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;;   Copyright (c) Rich Hickey. All rights reserved.\n;;\n;;   The use and distribution terms for this software are covered by the\n;;   Common Public License 1.0 (http://opensource.org/licenses/cpl.php)\n;;   which can be found in the file CPL.TXT at the root of this distribution.\n;;   By using this software in any fashion, you are agreeing to be bound by\n;;   the terms of this license.\n;;\n;;   You must not remove this notice, or any other, from this software.\n\n\n;; Set dimensions of the world, as a square 2-D board:\n(def dim 80)\n;; Number of ants = nants-sqrt^2\n(def nants-sqrt 7)\n;; Number of places with food:\n(def food-places 35)\n;; Range of amount of food at a place:\n(def food-range 100)\n;; Scale factor for pheromone drawing:\n(def pher-scale 20.0)\n;; Scale factor for food drawing:\n(def food-scale 30.0)\n;; Evaporation rate:\n(def evap-rate 0.99)\n\n(def animation-sleep-ms 100)\n(def ant-sleep-ms 40)\n(def evap-sleep-ms 1000)\n  \n(def running true)\n#+END_SRC\n\n** The board: ready to mutate via transactions\nThings get more interesting once the actual simulation environment\nneeds defining: \n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defstruct cell :food :pher)  ; May also have :ant and :home values\n#+END_SRC\nFirst, a call to =[[http://clojuredocs.org/clojure_core/clojure.core/defstruct][defstruct]]= (like a hashmap or dictionary in other\nlanguages) defines a baseline /cell/. \n- =defstruct= is like a very lightweight class or\n  constructor/template function, and conveniently wraps Clojure's\n  =[[http://clojuredocs.org/clojure_core/clojure.core/create-struct][create-struct]]=.\n- Here, a cell has two keys to start, =:food= and =:pher=, to\n  indicate the presence of food and pheromones. A cell may also have\n  keys of =:ant= and =:home=, depending on whether an ant and/or the\n  home-colony is present.\n\nNext, the =world= function creates the 2-dimensional \"board\" of cells\n(here, a square of 80x80 cells), represented as vectors (rows or the\nvertical y-dimension) of a vector (the horizontal x-dimension columns\nin one row):\n#+name sim-world-board-creation\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n;; World is a 2d vector of refs to cells\n(def world \n     (apply vector \n            (map (fn [_] \n                   (apply vector\n                          (map (fn [_]\n                                 (ref (struct cell 0 0))) \n                               (range dim)))) \n                 (range dim))))\n#+END_SRC\nReading the above:\n- Start with the innermost =[[http://clojuredocs.org/clojure_core/clojure.core/map][map]]= call, which uses an anonymous\n  function to create one column of 80 cells, per =(range dim)=. The\n  =[[http://clojuredocs.org/clojure_core/clojure.core/struct][struct]]= returns a new structmap instance using the earlier cell as\n  the basis, initializing the =:food= and =:pher= values to zero.\n- But notice that =struct= is wrapped with a [[http://clojure.org/refs][transactional ref]], and\n  here's the first glimpse of Clojure's concurrency powers. With\n  each cell being stateful (possibly time-varying values of =:food=,\n  =:pher=, =:ant=, and =:home= values) and with multiple threads\n  updating the board and board elements, we'd typically think of\n  using locks on each cell when updating its state.\n\n  But in Clojure with its [[http://en.wikipedia.org/wiki/Software_transactional_memory][software transactional memory]] (STM), we\n  just use =ref= for safe references to mutable collections (here, a\n  =struct=) - all changes to a cell will then be atomic, consistent,\n  and isolated![fn:Databases-ACID] Like using an RDBMS, you don't\n  need to manually manage concurrency.\n- Once you understand the innermost =(ref (struct cell 0 0 ))= =map=\n  call, the rest of =(def world...)= is straightforward: =apply=\n  uses =vector= as a constructor function with the =map= function\n  producing the vector's arguments, creating a \"column\" in the 2-D\n  board.\n- Then the pattern is repeated in the outermost \n  =(apply vector (map...))= call, creating all the columns of the\n  2-D board.\n- Note that as defined, each vector in =world= (again, a 2-D vector of\n  vectors) corresponds to an x-position, and of course, within that\n  vector are the y-positions (here, a total of 80 cells).\n\n\nThe =place= function is a selector function (think of \"place\" as the\nnoun, not the verb) returning particular cells in the 2-D world. Once\nwe have a cell, we can then mutate it to represent ants, food, and\npheromones (or their absence):\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn place [[x y]]\n  (-> world (nth x) (nth y)))\n#+END_SRC\n- =place= takes a single vector argument (having two elements x and\n  y), then applies the [[http://www.colourcoding.net/blog/archive/2011/07/09/another-go-at-explaining-the-thrush-operator-in-clojure.aspx][thrush operator]] (the [[http://clojuredocs.org/clojure_core/clojure.core/-%3E][arrow-like ->]]) on the\n  world object, first selecting the \"column\" =(nth x)= on world, then\n  the \"row\" =(nth y)= on that column.\n\n\n[fn:Databases-ACID] STM is like a memory-only SQL database, thus the last property of being durable/persistent won't be satisfied.\n\n*** Aside: the thrush operator\nThe thrush operator helps make code more concise, and arguably\nclearer: instead of reading code \"inside-out\" to mentally evaluate it,\nwe can read it left-to-right.[fn:Fogus-on-thrush] Consider how the\nequivalent =place= function would look without thrushing:\n\n#+BEGIN_SRC clojure :exports code\n(defn place-verbose [[x y]]\n  (nth (nth world x) y))\n#+END_SRC\n\n[fn:Fogus-on-thrush] Apparently Clojure's thrush is not quite a true\nthrush, see [[http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/][Michael Fogus' article]].\n\n** Ants as agents - doing asynchronous uncoordinated changes\nNext we'll consider the \"active things\" in =ants.clj=, the ants\nthemselves. As before, we start with =defstruct=, defining an ant as\nhaving only one required key, its direction. (An ant may temporarily\nhave another key, =:food=.)\n\n#+name ants-defined\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defstruct ant :dir)  ; Always has dir heading; may also have :food\n\n(defn create-ant \n  \"Create an ant at given location, returning an ant agent on the location.\"\n  [location direction]\n    (sync nil\n      (let [the-place (place location)\n            the-ant (struct ant direction)]\n        (alter the-place assoc :ant the-ant)\n        (agent location))))\n\n#+END_SRC\n\nTo explain the above constructor function for ants, =create-ant=:\n+ Takes two arguments, =location= and =direction=. =location= will be\n  a vector =[x y]=, and as we saw, passed on to the place function as\n  an argument; =direction= is a number from 0-7 inclusive\n  corresponding to one of the eight cardinal directions.\n+ More concurrency support: the [[http://clojuredocs.org/clojure_core/clojure.core/sync][sync function]] takes a flags argument\n  (as of Clojure 1.3, it's still ignored so just pass nil), and then a\n  list of expressions that will be executed together atomically (all\n  or nothing) as a transaction.\n+ The [[http://clojuredocs.org/clojure_core/clojure.core/let][let special form]] binds pairs of symbols and expressions in its\n  arguments vector, providing local, lexical bindings within the scope\n  of the body following.\n+ =sync= will ensure that any mutations of refs using the [[http://clojuredocs.org/clojure_core/clojure.core/alter][alter\n  function]] will be atomic. Previously we had used =ref= around each\n  cell, so in the above code where =the-place= is such a ref-wrapped\n  cell, =alter= takes =the-place= ref as its first argument, then\n  =[[http://clojuredocs.org/clojure_contrib/clojure.contrib.generic.collection/assoc][assoc]]= as the function to be [[http://clojuredocs.org/clojure_core/clojure.core/apply][apply]]'ed on the-place, tying a new ant\n  instance to it (remember that as a cell, =the-place= is sure to have\n  =:food= and =:pher= key-values already, now we add =:ant=). Like the\n  thrush operator earlier, the syntax of =alter= enables convenient\n  left-to-right reading.\n+ Finally, the [[http://clojuredocs.org/clojure_core/clojure.core/agent][agent function]]. What are Clojure agents? To quote the\n  docs, \n  #+BEGIN_QUOTE\n  Agents provide shared access to mutable state. They allow\n  non-blocking (asynchronous as opposed to synchronous atoms) and\n  independent change of individual locations (unlike coordinated\n  change of multiple locations through refs).\n  #+END_QUOTE\n\n  Clojure's =agent= function takes one required argument of state,\n  returning an agent object with initial value of that given state.\n  Here, as the last line of =create-ant=, =agent= effectively returns\n  the ant object at its starting location. Ants as agents make sense:\n  we expect them to move around independently (i.e. asynchronously) in\n  the simulation world.\n\n** Setting up the home, and ants\nThe home of the ants is not a single cell on the world-board, but a\nsquare of cells, with its top-left corner offset from the origin (0,\n0). Its sides are proportional to the number of ants because the home\nsquare will initially contain all the ants - one ant per cell - before\nthe simulation runs. We can see these two aspects of the home-square\nin the two =def= calls for =home-offset= and =home-range= below.\n\n#+name home-setup\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(def home-offset (/ dim 4))\n(def home-range (range home-offset (+ nants-sqrt home-offset)))\n\n(defn setup \n  \"Places initial food and ants, returns seq of ant agents.\"\n  []\n  (sync nil\n    (dotimes [i food-places]\n      (let [p (place [(rand-int dim) (rand-int dim)])]\n        (alter p assoc :food (rand-int food-range))))\n    (doall\n     (for [x home-range y home-range]\n       (do\n         (alter (place [x y]) assoc :home true)\n         (create-ant [x y] (rand-int 8)))))))\n#+END_SRC\n\nThe =setup= function's docstring tells us what it's doing, so on to\nthe details:\n+ =setup= takes no arguments.\n+ As we saw before in =create-ant=, the =sync= function wraps a\n  sequence of expressions that together should be executed atomically,\n  all-or-nothing.\n+ Setup initial food: The [[http://clojuredocs.org/clojure_core/clojure.core/dotimes][dotimes function]] takes two arguments, the\n  first a vector =[name n]= with =n= being the number of times that\n  the =body= (the second argument) will be repeatedly executed,\n  usually for its side-effects/mutations.\n  - Here, the unused name =i= is bound to the integers from 0 to 34,\n    since we had specified food-places as 35 initially.\n  - The =body= is clear enough: bind =p= to the randomly chosen place\n    on the world-board (using the [[http://clojuredocs.org/clojure_core/clojure.core/rand-int][rand-int function]] for x, y). The\n    already-seen =alter= function modifies that =p= to have a random\n    amount of food value.\n+ Placing the ants in their starting positions: The [[http://clojuredocs.org/clojure_core/clojure.core/doall][doall function]]\n  forces immediate evaluation of a lazy sequence - in this case the\n  lazy sequence produced by the [[http://clojuredocs.org/clojure_core/clojure.core/for][for function]].\n  - Here, the =for= function's first argument is: two\n    binding-form/collection-expr pairs for every x and y position\n    within the square of the ants' home.\n  - The =for= function's second argument is the body-expression, here\n    wrapped in the [[http://clojuredocs.org/clojure_core/clojure.core/do][do special form]] which ensures order of evaluation\n    (usually, of expressions having side-effects): designate the place\n    as a home position, then create an ant on that place with a random\n    initial direction.\n\nIn sum, the =setup= function shows how to deal with state and its\nmutation in Clojure: we started with a 2-D world-board of places\n(cells) as Clojure refs; then we modify/mutate each place using\n=alter=. We can use various looping functions such as =dotimes= and\n=doall= to process a batch of state-mutations (of the world-board)\natomically and consistently.\n\n** Orientation and moving around the world\nNext, consider facing/orientation and moving to another place in the\n2-D world. Three functions below, followed by explanations:\n\n#+name world-wrapping\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn bound \n  \"Returns given n, wrapped into range 0-b\"\n  [b n]\n  (let [n (rem n b)]\n    (if (neg? n) \n      (+ n b) \n      n)))\n\n;; Directions are 0-7, starting at north and going clockwise. These are\n;; the 2-D deltas in order to move one step in a given direction.\n(def direction-delta {0 [0 -1]\n                      1 [1 -1]\n                      2 [1 0]\n                      3 [1 1]\n                      4 [0 1]\n                      5 [-1 1]\n                      6 [-1 0]\n                      7 [-1 -1]})\n\n(defn delta-location \n  \"Returns the location one step in the given direction. Note the\n  world is a torus.\"\n  [[x y] direction]\n  (let [[dx dy] (direction-delta (bound 8 direction))]\n    [(bound dim (+ x dx)) (bound dim (+ y dy))]))\n#+END_SRC\n\nWith the 2-D world board, we have the 8 cardinal directions (North,\nNorth-East, East, etc.), and board edges that wrap-around to the\nopposite side - like the old arcade games of the 1980's, e.g. [[http://en.wikipedia.org/wiki/Pac-Man][Pac-Man]]\nand [[http://en.wikipedia.org/wiki/Asteroids_(video_game)][Asteroids]]. The functions =bound= and =delta-location= help enforce\nthese world-behaviors, while the definition of =direction-delta= maps\na movement in a cardinal direction to the corresponding change in x\nand y. A few comments on each:\n- The =bound= function using the built-in [[http://clojuredocs.org/clojure_core/clojure.core/rem][rem (i.e. remainder)\n  function]] is straightforward. Observe how =bound= is used in\n  delta-location to ensure wrap-around behavior in: 1) cardinal\n  directions; 2) the world-board, at its edges given by =dim=.\n- =direction-delta= maps the eight cardinal directions (0 is North) to\n  the corresponding changes in =[x y]=. Note the syntax: it's an\n  array-map literal, where the order of insertion of key-value pairs\n  (here, keys 0-7) will be preserved.\n- =delta-location= takes the current =[x y]= location and a direction,\n  returning the new corresponding location on the world-board.\n\n** Ant-agent behavior functions\nIn Hickey's simulation, ants need to move (rotation and translation),\npick up and drop-off food, and make rudimentary decisions.\n\n*** Ant movements\nOur ants need two behaviors to get around their world: turning (or\nchanging the direction they \"face\"), and stepping forward.  Let's deal\nwith turning first:\n\n#+name ant-agent-turn\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n;; An ant agent tracks the location of an ant, and controls the\n;; behavior of the ant at that location.\n\n(defn turn \n  \"Turns the ant at the location by the given amount.\"\n  [loc amt]\n  (dosync\n   (let [p (place loc)\n         ant (:ant @p)]\n     (alter p assoc :ant (assoc ant :dir (bound 8 (+ (:dir ant) amt))))))\n  loc)\n#+END_SRC\n\nThe =turn= function takes two arguments, location and the amount of\nturn. What's interesting is the usage of [[http://clojuredocs.org/clojure_core/clojure.core/dosync][the dosync function]], which\nensures the ant's turn - the changes of state within the =assoc=\nfunction calls - is all-or-nothing. The ant gets a new direction per\nthe innermost =assoc=, then the outermost =assoc= updates the =place=\nwith the updated ant.\n\nNow for actual movement to a new place:\n\n#+name ant-agent-move\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn move \n  \"Moves the ant in the direction it is heading. Must be called in a\n  transaction that has verified the way is clear.\"\n  [startloc]\n  (let [oldp (place startloc)\n        ant (:ant @oldp)\n        newloc (delta-location startloc (:dir ant))\n        newp (place newloc)]\n    ;; move the ant\n    (alter newp assoc :ant ant)\n    (alter oldp dissoc :ant)\n    ;; leave pheromone trail\n    (when-not (:home @oldp)\n      (alter oldp assoc :pher (inc (:pher @oldp))))\n    newloc))\n#+END_SRC\n\nThe =move= function changes state of both the ant and board, thus the\ndoc-string note that it must be called in a transaction. The code is\nself-explanatory, though if \"pheromone\" is a new term to you, you'll\nwant to [[http://en.wikipedia.org/wiki/Pheromone][learn about a dominant form of chemical communication]] on\nEarth. Whenever our artificial ant is not within its home, it will\n\"secrete\" pheromone (=inc= the =:pher= value by 1) at the place it\njust left, making it easier (more likely) for it and other ants to\ntravel between home and food locations in the future (instead of doing\na completely random walk).\n\n*** Ants and food\nWhen an ant finds food, it \"picks up\" one unit of it; when it returns\nhome with a food unit, it will \"drop\" its food there. These two\ninteractions (each having two steps) change the board, and as with the\n=move= function, they need to occur atomically (all-or-nothing) to\nensure the [[http://www.youtube.com/watch?v=z_KmNZNT5xw][world is in a consistent state]]. \n\n#+name ant-agent-food\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn take-food [loc]\n  \"Takes one food from current location. Must be called in a\n  transaction that has verified there is food available.\"\n  (let [p (place loc)\n        ant (:ant @p)]    \n    (alter p assoc \n           :food (dec (:food @p))\n           :ant (assoc ant :food true))\n    loc))\n\n(defn drop-food [loc]\n  \"Drops food at current location. Must be called in a\n  transaction that has verified the ant has food.\"\n  (let [p (place loc)\n        ant (:ant @p)]    \n    (alter p assoc \n           :food (inc (:food @p))\n           :ant (dissoc ant :food))\n    loc))\n#+END_SRC\n\nNotice how similar the structure is for the two functions above;\npossibly they're candidates for macro refactoring.\n\n*** Ant judgment\nOur ants need some decision-making for their overall task of finding\nfood and bringing it home.  As we'll see shortly, an ant's behavior\nis based on two states, either:\n1. The ant does not have food, and is looking for it. In this mode, it\n   weighs the three map locations ahead of it (ahead, ahead-left,\n   ahead-right) by the presence of either food or pheromone.\n2. The ant has food, and needs to bring it to the home box/location.\n   Now it weighs which of the three ahead-positions to take by the\n   presence of pheromone, or home.\n\nSo we need functions to express preference of the next location for an\nant. The functions =rank-by= and =wrand= help with that.\n\n#+name ant-agent-judgment-1\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn rank-by \n  \"Returns a map of xs to their 1-based rank when sorted by keyfn.\"\n  [keyfn xs]\n  (let [sorted (sort-by (comp float keyfn) xs)]\n    (reduce (fn [ret i] (assoc ret (nth sorted i) (inc i)))\n            {} (range (count sorted)))))\n#+END_SRC\n\nThe =rank-by= function gives weights to where an ant will move next in\nthe simulation world. It takes two arguments, =keyfn= and =xs= - but\nwhat do those args look like, and where is =rank-by= used? In the\n=behave= function below; you'll see that the =keyfn= checks for the\npresence of =:food=, =:pher=, or =:home= - in the three cells (board\nlocations) of the =xs= vector of =[ahead ahead-left ahead-right]=.[fn:Mutex-cell-values]\n- The [[http://clojuredocs.org/clojure_core/clojure.core/sort-by][(sort-by keyfn coll) function]] returns a sorted sequence of items\n  in coll, ordered by comparing =(keyfn item)=. Here, for the local\n  value sorted, it will be ascending order of cells/places, by\n  their :food/:home/:pher values - each of those is valuable to an ant\n  depending on whether it's looking for food, or bringing it home.\n- The [[http://clojuredocs.org/clojure_core/clojure.core/reduce][(reduce f initial-val coll) functionn]] in its 3-arguments form\n  here has its 1st argument =f= as a function taking two arguments, the\n  current/initial-val value and the next/first item from coll. In this\n  case, it will \"build-up\" a map from the local sorted value, with the\n  keys being the ranked cells/places, and the values being integers 1,\n  2 and 3. To get a sense of what's going on, try this on your Clojure\n  REPL:\n  #+BEGIN_SRC clojure\n  (let [sorted [0 0.7 1.0]] \n    (reduce (fn [ret i] (assoc ret (nth sorted i) (inc i)))\n            {} \n            (range (count sorted))))\n  ;; You should see {1.0 3, 0.7 2, 0 1}\n  ;; \n  ;; Within the behave function below, the return value might be\n  ;; like {<cell-ahead-left> 3, <cell-ahead-right> 2, <cell-ahead> 1} \n  ;; or similar.\n  #+END_SRC\n\n[fn:Mutex-cell-values] Remember that =:food=, =:pher=, and =:home= are mutually exclusive in a cell. When an ant wants to go home with food, and the home cell(s) is ahead of it, it will always go home, there won't be competing =:pher= presence.\n\nNext: The =wrand= function helps with the larger task of randomizing\nwhich location/cell the ant moves to next in a weighted manner; i.e.\nthe \"dice\" are loaded with =rank-by=, then \"rolled\" here:\n\n#+name ant-agent-judgment-2\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn wrand \n  \"Given a vector of slice sizes, returns the index of a slice given a\n  random spin of a roulette wheel with compartments proportional to\n  slices.\"\n  [slices]\n  (let [total (reduce + slices)\n        r (rand total)]\n    (loop [i 0 sum 0]\n      (if (< r (+ (slices i) sum))\n        i\n        (recur (inc i) (+ (slices i) sum))))))\n#+END_SRC\n\nHow is =wrand= used? Like =rank-by=, look in the =behave= function:\nits single argument of slices is a vector of 3 integers (from\n=rank-by= above), corresponding to the relative desirability of the 3\ncells ahead of the ant. So if the slices argument looked like =[0 3\n1]=, that would correspond to zero probability of moving ahead, and\n3/4 chance moving to the ahead-left cell over the ahead-right cell.\n- The =let= value =total= uses =reduce= to set the upper bound on the\n  random number; loosely like setting the maximum number of faces on\n  the die to be rolled (albeit that some die numbers are geometrically\n  impossible).\n- The [[http://clojuredocs.org/clojure_core/clojure.core/rand][rand function]] returns a random floating point number from 0\n  (inclusive) to n (exclusive).\n- Here's the only looping construct in the entire ants program: it's\n  analogous to checking which compartment of the roulette wheel the\n  ball fell in. The =if= checks if =r= \"fell into\" the current\n  pocket - the size of which is given by =(slices i)=. If yes, return\n  the index corresponding to that pocket; if not, check the next\n  pocket/slice.\n\n*** Tying it all together: the =behave= function for ants\nThe =behave= function below is the largest one, so it helps to keep in\nmind its main parts while diving into details:\n1. =let= values - help with readability.\n2. =Thread/sleep= - helps slow down ants in the UI display.\n3. =dosync= - ensures ants behavior is transactional, all-or-nothing.\n4. =if= branch: main logic for an ant, if ant has =:food= take it\n   home, otherwise look for food.\n\nAlso, consider the context of how =behave= is first used: within the\nmain invocation at the end, there's the expression:\n\nsrc_clojure{(dorun (map #(send-off % behave) ants))}\n\nSo the =behave= function is called on every ant agent via the [[http://clojuredocs.org/clojure_core/clojure.core/send-off][send-off\nfunction]], which is how Clojure dispatches potentially blocking actions\nto agents. And there certainly are potentially blocking actions when\nusing =behave=, since ants may try to move into the same cell, try to\nacquire the same food, etc.\n\n#+name ant-agent-behave\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn behave \n  \"The main function for the ant agent.\"\n  [loc]\n  (let [p (place loc)\n        ant (:ant @p)\n        ahead (place (delta-location loc (:dir ant)))\n        ahead-left (place (delta-location loc (dec (:dir ant))))\n        ahead-right (place (delta-location loc (inc (:dir ant))))\n        places [ahead ahead-left ahead-right]]\n    ;; Old way of Java interop: (. Thread (sleep ant-sleep-ms))\n    ;; New idiomatic way is,\n    (Thread/sleep ant-sleep-ms)\n    (dosync\n     (when running\n       (send-off *agent* #'behave))\n     (if (:food ant)\n       ;; Then take food home:\n       (cond \n        (:home @p)                              \n          (-> loc drop-food (turn 4))\n        (and (:home @ahead) (not (:ant @ahead))) \n          (move loc)\n        :else\n          (let [ranks (merge-with + \n                        (rank-by (comp #(if (:home %) 1 0) deref) places)\n                        (rank-by (comp :pher deref) places))]\n          (([move #(turn % -1) #(turn % 1)]\n            (wrand [(if (:ant @ahead) 0 (ranks ahead)) \n                    (ranks ahead-left) (ranks ahead-right)]))\n           loc)))\n       ;; No food, go foraging:\n       (cond \n        (and (pos? (:food @p)) (not (:home @p))) \n          (-> loc take-food (turn 4))\n        (and (pos? (:food @ahead)) (not (:home @ahead)) (not (:ant @ahead)))\n          (move loc)\n        :else\n          (let [ranks (merge-with + \n                                  (rank-by (comp :food deref) places)\n                                  (rank-by (comp :pher deref) places))]\n          (([move #(turn % -1) #(turn % 1)]\n            (wrand [(if (:ant @ahead) 0 (ranks ahead)) \n                    (ranks ahead-left) (ranks ahead-right)]))\n           loc)))))))\n#+END_SRC\n\n**** The =let= values\nThe =let= values: quite straightforward, just note the twist in how\n=behave= receives a cell/location as its argument, not an ant (which\nan OO-centric design might expect).\n\n**** The only JVM/concurrency leakage: =Thread/sleep=\nThe src_clojure{(. Thread (sleep ant-sleep-ms))}, or\nsrc_clojure{(Thread/sleep ant-sleep-ms)} call is our first encounter\nwith [[http://clojure.org/java_interop][Clojure's Java Interop]]. \n- The first version uses [[http://clojure.org/java_interop#Java Interop-The Dot special form][the dot special form]] and in particular, the \n  src_clojure{(. Classname-symbol (method-symbol args*))} format, with\n  =Thread= as the Classname-symbol, and =sleep= as the method-symbol.\n- However, outside of macros, the idiomatic form for accessing method\n  members is the second form, src_clojure{(Classname/staticMethod args*)}\n- Beyond syntax, the point of this expression is to slow down an ant\n  (one ant-agent per thread) between their movements, so you can see\n  in the UI what they're doing, and they'll appear more realistic. \nBut more interesting still: in this highly concurrent program, the\n=sleep= expression is about the *only explicit reference to threads*\nin the entire code, i.e. one of the very few \"leaky abstractions\"\nhinting at Clojure's use of underlying JVM concurrency constructs.\nBesides this call, there are no locks, and no explicit thread\nallocations.\n\n**** The main =dosync= call\nNext, let's look at what's going on within the =dosync= transaction.\n\n***** Repeating asynchronously, without looping\nThe first expression is:\n\nsrc_clojure{(when running (send-off *agent* #'behave))}\n\nInitially this may seem strange; aren't we in the =behave= function\nbecause =send-off= already called it before entering it? Won't this\njust loop uselessly, not hitting the core =if= code below? Not quite:\n- Instead, =send-off= adds another execution of =behave= to the\n  current agent's *queue* of work/functions, and immediately returns.\n  - The current agent is referenced by the asterisk-surrounded\n    ~*agent*~ which Clojure dynamically binds to the current active\n    agent on a thread-local basis.\n- Thus after finishing this call of =behave= the ant will do another\n  action (execute =behave= again), and another, and so on. No explicit\n  looping, just *queue and repeat*.\n\nAlso, note the ~#'~ sharp-quote, before =behave=; this is a Clojure\nVar, one of Clojure's mutable reference types. It's just syntactic\nsugar for =(var behave)=. Invoking a Var referring to a function is\nthe same as invoking the function itself...so why bother with it?  I\ndon't know; here's what I could find:\n- Besides Clojure docs, this SO thread also suggests there's no\n  difference, \"Apply a =var= is the same as applying the value store\n  in the =var=.\"\n  http://stackoverflow.com/questions/9760480/in-clojure-difference-between-function-quoted-function-and-sharp-quote-functio\n- Maybe the #' prefix on =behave= causes the current thread's value\n  of the function (with the current ant/location) to be sent to the\n  queue? NO/unlikely. If it was mean to be a dynamic var, it would\n  have asterisks around it like =*agent*=.\n\nWhy use =send-off= instead of =send= ?\n- [[http://stackoverflow.com/questions/1646351/what-is-the-difference-between-clojures-send-and-send-off-functions-with-re][send vs. send-off]] - =send= uses threadpool of fixed size which has\n  low switching overhead but blocking can dry up the threadpool. By\n  contrast, =send-off= uses a dynamic threadpool and blocking is\n  tolerated - and that's the right approach here as ant contention for\n  the same location/food can certainly cause (temporary) blocking.\n- http://stackoverflow.com/questions/5964997/clojure-agent-question-using-send-off\n\n***** Determining what the ant does next\nFinally, the ant's logic for what to do next is in the large =if=\nexpression. The code looks dense but at the top level it's just a\nbinary choice:\n+ If the ant has food, take it home; the =cond= specifies 3\n  sub-cases: \n  1. At a home cell, drop the food and turn around 180 degrees, to\n     exit home for more food.\n  2. If a home cell is ahead, move to it.\n  3. Otherwise, do a ranking of cells ahead (=places= has the cells\n     =ahead=, =ahead-left=, =ahead-right=) per presence of pheromones,\n     or home, and then randomly select from those 3 cells per their\n     ranking/weighting.\n\n** World behavior: pheromone evaporation\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn evaporate \n  \"Causes all the pheromones to evaporate a bit.\"\n  []\n  (dorun \n   (for [x (range dim) y (range dim)]\n     (dosync \n      (let [p (place [x y])]\n        (alter p assoc :pher (* evap-rate (:pher @p))))))))\n#+END_SRC\n\nFor a bit of realism and a cleaner UI/visual, it's useful to have the\nants' pheromones diminish and evaporate from the world over time.\nThe =evaporate= function fulfills that requirement: \n+ It takes no arguments, it will work over the entire world/board of\n  cells, accessed via the tuples of =x= and =y=.\n+ The =[[http://clojuredocs.org/clojure_core/clojure.core/dorun][dorun]]= function takes a lazy collection/sequence (here, that of\n  the =for= expression) and forces the realization of that collection\n  for its side effects, discarding any returned values.\n  - It's unlike the similarly-named =doall= where we do care about the\n    values.\n  - And it's unlike =doseq=, which is like Clojure's =for= but runs\n    immediately and does not collect the results.\n+ =dosync= is used as before, for lock-free updating of a =place=\n  cell.  Here, the desired side-effect/\"mutation\" is to update the\n  =:pher= value at the =place= cell with a lower number.  \n\nWe'll see shortly that =evaporate= will run every second, a process\nthat (like the ants) will be handled asynchronously using a Clojure\nagent.\n\n\n* The UI\nThe user interface for the ants relies heavily on Clojure's Java\ninter-operation capabilities. But as we'll see, it's more than just\nwrapping calls to Java.\n\n** Using the Java AWT\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(import \n '(java.awt Color Graphics Dimension)\n '(java.awt.image BufferedImage)\n '(javax.swing JPanel JFrame))\n#+END_SRC\n\nThe =import= pulls in classes from [[http://docs.oracle.com/javase/6/docs/api/java/awt/package-summary.html][Java's Abstract Window Toolkit]]\n(AWT) package, and from the Java Swing package. (Aside: curious [[http://stackoverflow.com/questions/727844/javax-vs-java-package][why\nSwing is in the =javax= namespace]]?)  Assuming unfamiliarity with Java\nSwing, let's describe the classes used:\n+ The =[[http://docs.oracle.com/javase/6/docs/api/java/awt/Color.html][Color]]= class encapsulates a color in the standard RGB color\n  space. In the code below, its usage as a constructor for a color\n  instance follows several arities:\n  - 4 integer arguments: r, g, b, and a for the alpha/transparency (0\n    transparent, 255 opaque)\n  - 3 integer arguments: r g b\n  - 1 argument: not a constructor call, but an access of a predefined\n    static =Color= field by name, returning the color in the RGB color\n    space.\n+ The =[[http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics.html][Graphics]]= class is an abstract base class for all graphics\n  contexts, i.e. a =Graphics= instance holds the current state data\n  needed for rendering it: the =[[http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html][Component]]= object on which to draw,\n  the current clip, color, and font, etc. Below, we'll see that the\n  Clojure functions that take a =Graphics= instance as an argument:\n  - =fill-cell=\n  - =render-ant=\n  - =render-place=\n  - =render=\n  ...all do some kind of rendering/drawing.\n+ The =[[http://docs.oracle.com/javase/6/docs/api/java/awt/Dimension.html][Dimension]]= class encapsulates the integer width and height of a\n  component. This class is used just once below, in setting the size\n  of the panel of the UI.\n+ =[[http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html][BufferedImage]]= class is needed for raster image data; below, the\n  =render= function uses it to paint the background panel.\n+ The =[[http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/JPanel.html][JPanel]]= class is the generic \"lightweight\" UI container in Java\n  Swing (seems like the =div= element in HTML).  Below, it's used just\n  once for the main display.\n+ The =[[http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/JFrame.html][JFrame]]= class creates a top-level window (w/ title and border)\n  in Swing; it's used just once below for the main ants UI window.\n\n** Functions to render the board and the ants\nEach discrete cell on the world board is a square matrix of pixels;\nwith an odd number of pixels chosen, we can have a central position:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(def scale 5)  ; A world cell is 5x5 pixels.\n#+END_SRC\n\nBy default, cells are empty; drawing cells having food or\nant-deposited pheromones is done by filling with symbolic colors -\nhere by running the Java methods =setColor= and =fillRect=:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn fill-cell [#^Graphics g x y c]\n  (doto g\n    (.setColor c)\n    (.fillRect (* x scale) (* y scale) scale scale)))\n#+END_SRC\nNote the use of the =[[http://clojuredocs.org/clojure_core/clojure.core/doto][doto]]= function here and in many places below: in\nJava, procedural mutation of a newly constructed instance is common\nfor initialization. Clojure's =doto= function is meant to be more\nconcise in specifying the target object just once, and then\nmethods/setters acting on it and then returning it, implicitly.\n\n\nDrawing an ant: the graphical appearance of an ant is just a (5-pixel\nlong) line pointing in one of the 8 cardinal directions, of two\ndifferent colors (having food or not):\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn render-ant [ant #^Graphics g x y]\n  (let [black (. (new Color 0 0 0 255) (getRGB))\n        gray (. (new Color 100 100 100 255) (getRGB))\n        red (. (new Color 255 0 0 255) (getRGB))\n        [hx hy tx ty] ({0 [2 0 2 4]  ; Up/North pointing\n                        1 [4 0 0 4] \n                        2 [4 2 0 2] \n                        3 [4 4 0 0] \n                        4 [2 4 2 0]  ; Down/South \n                        5 [0 4 4 0] \n                        6 [0 2 4 2] \n                        7 [0 0 4 4]}\n                       (:dir ant))]\n    (doto g\n      (.setColor (if (:food ant) \n                  (new Color 255 0 0 255) \n                  (new Color 0 0 0 255)))\n      (.drawLine (+ hx (* x scale)) (+ hy (* y scale)) \n                (+ tx (* x scale)) (+ ty (* y scale))))))\n#+END_SRC\nNote the cleverly concise destructuring for the start and end drawing\ncoordinates, needed in AWT's =[[http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/Graphics.html#drawLine%28int,%20int,%20int,%20int%29][drawLine]]= method.\n\n\nIf a cell in the ants' world is not empty, it has one or more of three\nthings present: pheromone, food, or an ant.  The =render-place=\nfunction updates the cell's appearance accordingly:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn render-place [g p x y]\n  (when (pos? (:pher p))\n    (fill-cell g x y (new Color 0 255 0 \n                          (int (min 255 (* 255 (/ (:pher p) pher-scale)))))))\n  (when (pos? (:food p))\n    (fill-cell g x y (new Color 255 0 0 \n                          (int (min 255 (* 255 (/ (:food p) food-scale)))))))\n  (when (:ant p)\n    (render-ant (:ant p) g x y)))\n#+END_SRC\n\n\nFinally, the =render= function ties everything together: initializing\nthe UI/window appearance by applying =render=place= to every cell, and\nalso drawing the home space of the ants.  Note the heavy usage of the\ndot special form: the UI code relies heavily on Java, though Clojure's\n=for= and =doto= help us avoid Java boilerplate and stay concise:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn render [g]\n  (let [v (dosync (apply vector (for [x (range dim) y (range dim)] \n                                   @(place [x y]))))\n        img (new BufferedImage (* scale dim) (* scale dim) \n                 (. BufferedImage TYPE_INT_ARGB))\n        bg (. img (getGraphics))]\n    ;; First paint everything white, on the bg instance:\n    (doto bg\n      (.setColor (. Color white))\n      (.fillRect 0 0 (. img (getWidth)) (. img (getHeight))))\n    (dorun \n     (for [x (range dim) y (range dim)]\n       (render-place bg (v (+ (* x dim) y)) x y)))\n    ;; Draw the home space of the ants:\n    (doto bg\n      (.setColor (. Color blue))\n      (.drawRect (* scale home-offset) (* scale home-offset) \n                 (* scale nants-sqrt) (* scale nants-sqrt)))\n    (. g (drawImage img 0 0 nil))\n    (. bg (dispose))))  ; Finished using Graphics object, release it.\n#+END_SRC\n\n** Setting the scene, then updating it continually\nAlmost ready to begin our simulation; we need to setup some additional\nelements per AWT conventions: the main UI =panel= where visual changes\ntake place, the top-level window =frame=, and an =animator= agent that\ncontinually updates the visual elements:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(def panel (doto \n             (proxy [JPanel] [] (paint [g] (render g)))\n             (.setPreferredSize (new Dimension \n                                     (* scale dim) \n                                     (* scale dim)))))\n\n(def frame (doto (new JFrame) (.add panel) .pack .show))\n\n(def animator (agent nil))\n#+END_SRC\n\n*** Animation, panel-by-panel\nNow for bringing the static starting \"picture\" to life - like the\ncartoons of old, the =animation= function will \"draw\" the next state\nof the main panel displaying the ants.  Below, Hickey uses the\nqueue-itself-then-run, again-and-again code pattern we've seen before\n(above, in updating an ant's state):\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(defn animation [x]\n  (when running\n    (send-off *agent* #'animation))\n  (. panel (repaint))\n  (. Thread (sleep animation-sleep-ms))\n  nil)\n#+END_SRC\n\nFinally, we need another agent to handle one more time-track of\nchanges: evaporation, using the =evaporate= function defined above.\n#+BEGIN_SRC clojure :exports code :results silent :session s1 \n(def evaporator (agent nil))\n\n(defn evaporation [x]\n  (when running\n    (send-off *agent* #'evaporation))\n  (evaporate)\n  (. Thread (sleep evap-sleep-ms))\n  nil)\n#+END_SRC\n\n\n* Running the Program\n** The =project.clj= file\nWhen you tangle this file, the local =project.clj= file will be\ncreated alongside =ants.clj=.  Assuming you've installed the excellent\n[[http://leiningen.org/][Leiningen]], you'd then:\n1. Enter =lein deps= at the shell prompt to get dependencies.\n2. Then you can start a REPL with =lein repl=, from which you can\n   start the simulator (see next section).\n\n#+BEGIN_SRC clojure :tangle project.clj\n(defproject literate-ants \"1.0.0-SNAPSHOT\"\n  :description \"This is a literate version of: Rich Hickey's Ants simulator, demonstrating Clojure's concurrency support.\"\n  :dev-dependencies []\n  :dependencies [[org.clojure/clojure \"1.5.1\"]]\n  )\n#+END_SRC\n\n** Running the simulator\nAt the REPL, you can enter the entire =do= expression below, or try\neach line within it separately:\n#+BEGIN_SRC clojure :tangle no\n(do \n  (load-file \"./literate-ants.clj\")\n  (def ants (setup))\n  (send-off animator animation)\n  (dorun (map #(send-off % behave) ants))\n  (send-off evaporator evaporation))\n#+END_SRC\nEither way you'll see a new window appear with a white background,\nblue square representing the ants' home, red squares of food, black or\nred (w/ food) moving lines representing each ant, and green squares\nfor pheromones in various concentrations.  A lot happening\nconcurrently, with no locks, and beautifully concise code - welcome to\nClojure!\n\n\n** Unused                                                 :ARCHIVE:NOEXPORT:\n#+BEGIN_SRC clojure :exports code :results silent :session s1 :tangle no\n(comment\n;demo\n(load-file \"/Users/rich/dev/clojure/ants.clj\")\n(def ants (setup))\n(send-off animator animation)\n(dorun (map #(send-off % behave) ants))\n(send-off evaporator evaporation)\n)\n#+END_SRC\n\n\n#+name: ants\n#+BEGIN_SRC clojure :tangle no :exports none :noweb yes\n<<sim-world-setup>>\n\n<<sim-world-board-creation>>\n\n<<ants-defined>>\n#+end_src\n"
  },
  {
    "path": "02-minimal-clojure-app/clojure-app-skeleton.org",
    "content": "#+TITLE: Clojure App Skeleton, using Org literate programming\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+LANGUAGE: en\n#+STARTUP: align overview indent fold nodlcheck hidestars oddeven lognotestate\n#+PROPERTY: mkdirp yes\n\n\n* Meta: this file, Clojure + Org → LP, etc.\nYou're looking at a literate programming (LP) file, specifically an\n[[http://orgmode.org][Org mode]] formatted file combining both documentation (Org's structured\nmarkup) and code blocks (Clojure code).\n\nFor best results please *use Emacs 24.3 or later to view this* =.org=\n*file*. If you're looking at this on Github.com, STOP - the rendering\nthere is neither complete nor correct!\n\n** The *benefits* of LP using Emacs + Org\n1. Docs matter, a lot. With LP, documentation is integral to\n   development, never an afterthought.\n   - For all but small throwaway systems, you're likely keeping a\n     separate file of development notes already; LP would integrate\n     that.\n2. With one LP file, avoid the incidental/inessential complexity of\n   the filesystem: avoid context-switch overhead moving between files,\n   and sidestep your language's imposed filesystem structure.\n3. Org rocks for prose:\n   - Org's plain-text *markup is lightweight*, yet more powerful than\n     Markdown, and cleaner than rST.\n   - The *structural editing* provided by Org documents lets you\n     organize your thoughts/writing/code very quickly.  With good\n     structure even major revisions are easy.\n   - Org's exporter lets your *write-once, express-many-times*: you\n     can export an Org file to HTML (e.g. for blogging) or LaTeX\n     (for serious publishing).\n   - It's easy to version-control Org files.\n4. Org rocks for code:\n   - Each code block has flexible granularity: can be named and\n     referred to; evaluated or not; have data sent in or exported;\n     specify different REPL sessions; specify different target/tangled\n     files.\n   - Code blocks are syntax-highlighted.\n   - Code blocks are ready to edit: jump to major-mode editing easily.\n   - A single Org file can mix different languages.\n5. Meta-development, manage complexity from a coherent perspective: a\n   unified, single-file approach encourages holistic software\n   development and exposition, in a natural order, using structure to\n   enhance understanding.  LP is not just documentation and code\n   together: it's a *process and abstraction unifying the development\n   lifecycle*: requirements, architecture, design, code, tests,\n   deployment, and maintenance - can all be bound coherently in one\n   active format.\n\n\n* Using this file\n** Prerequisites\n1. A recent version of Emacs, 24.3+.\n2. Both org-mode (included w/ Emacs 24) and =clojure-mode= installed;\n   use Emacs ELPA as needed.\n   - Consider using an Emacs \"starter package\" that provides a good\n     baseline, like [[http://batsov.com/prelude/][Emacs Prelude]] or [[http://overtone.github.io/emacs-live/][Emacs Live]].\n\nThen if you start Emacs and load this file, you'll see it the way it's\nmeant to be seen: as a multi-level, hierarchically organized and\nstructured literate code file, w/ syntax-highlighted code blocks.  \n\n** Weaving and tangling\nTo use the original Knuth terminology, this single file can be /woven/\ninto documentation, or /tangled/ to code.\n\n*** Weave/export, to documentation\n+ To /weave/: the Org equivalent of /weaving/ is to export this file,\n  typically to HTML or LaTeX/PDF. The keystroke is =C-c-e= i.e. hold\n  down the Control key while pressing \"c\" then \"e\" to view the export\n  options.\n  - e.g. export this file to HTML with =CTRL-c-e h= or, to see it\n    immediately in a browser window, =CTRL-c-e b=.\n+ You don't have to export this file though; if/when you're comfy in\n  Emacs, the Org format itself is great.\n\n*** Tangle, to code\n+ To /tangle/: in Org, it's the same word/term. =C-c-v-t= will cause\n  all designated code blocks in this file to appear in the filesystem.\n  Here, the code blocks go to files and directories matching a new\n  Clojure app, as would be produced by =lein new app\n  the-project-name=.\n\n** Other coolness\n- =SHIFT-TAB= will *cycle* the display: top-level headings only, all\n  headings, or fully-expanded.\n- Within a code block, =CTRL-c= ='= will open a buffer to edit the\n  code. For full power, be sure =clojure-mode=, =paredit=, and\n  =nrepl= are installed.\n- Org docs: see [[http://orgmode.org/org.html][main documentation]], especially sections on [[http://orgmode.org/org.html#Document-Structure][structure]],\n  [[http://orgmode.org/org.html#Hyperlinks][links]], [[http://orgmode.org/org.html#Markup][markup]], and [[http://orgmode.org/org.html#Working-With-Source-Code][literate programming]] features.\n\n\n* Project meta\n** Project definition\n#+BEGIN_SRC clojure :tangle project.clj\n(defproject skeleton-app \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"http://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"http://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.5.1\"]]\n  :main skeleton-app.core\n  :profiles {:uberjar {:aot :all}})\n#+END_SRC\n\n** The README\nIt would be nice to auto-generate the README.md from selected parts of\nthis =org= file; TBD how.\n\n#+BEGIN_SRC markdown :tangle README.md\n# skeleton-app\n\nFIXME: description\n\n## Installation\n\nDownload from http://example.com/FIXME.\n\n## Usage\n\nFIXME: explanation\n\n    $ java -jar skeleton-app-0.1.0-standalone.jar [args]\n\n## Options\n\nFIXME: listing of options this app accepts.\n\n## Examples\n\n...\n\n### Bugs\n\n...\n\n### Any Other Sections\n### That You Think\n### Might be Useful\n\n## License\n\nCopyright © 2013 FIXME\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n#+END_SRC\n\n** License notice\n#+BEGIN_SRC text :tangle LICENSE\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM\nCONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and\ndocumentation distributed under this Agreement, and\n\nb) in the case of each subsequent Contributor:\n\ni) changes to the Program, and\n\nii) additions to the Program;\n\nwhere such changes and/or additions to the Program originate from and are\ndistributed by that particular Contributor. A Contribution 'originates' from\na Contributor if it was added to the Program by such Contributor itself or\nanyone acting on such Contributor's behalf. Contributions do not include\nadditions to the Program which: (i) are separate modules of software\ndistributed in conjunction with the Program under their own license\nagreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which are\nnecessarily infringed by the use or sale of its Contribution alone or when\ncombined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement,\nincluding all Contributors.\n\n2. GRANT OF RIGHTS\n\na) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free copyright license to\nreproduce, prepare derivative works of, publicly display, publicly perform,\ndistribute and sublicense the Contribution of such Contributor, if any, and\nsuch derivative works, in source code and object code form.\n\nb) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free patent license under\nLicensed Patents to make, use, sell, offer to sell, import and otherwise\ntransfer the Contribution of such Contributor, if any, in source code and\nobject code form.  This patent license shall apply to the combination of the\nContribution and the Program if, at the time the Contribution is added by the\nContributor, such addition of the Contribution causes such combination to be\ncovered by the Licensed Patents. The patent license shall not apply to any\nother combinations which include the Contribution. No hardware per se is\nlicensed hereunder.\n\nc) Recipient understands that although each Contributor grants the licenses\nto its Contributions set forth herein, no assurances are provided by any\nContributor that the Program does not infringe the patent or other\nintellectual property rights of any other entity. Each Contributor disclaims\nany liability to Recipient for claims brought by any other entity based on\ninfringement of intellectual property rights or otherwise. As a condition to\nexercising the rights and licenses granted hereunder, each Recipient hereby\nassumes sole responsibility to secure any other intellectual property rights\nneeded, if any. For example, if a third party patent license is required to\nallow Recipient to distribute the Program, it is Recipient's responsibility\nto acquire that license before distributing the Program.\n\nd) Each Contributor represents that to its knowledge it has sufficient\ncopyright rights in its Contribution, if any, to grant the copyright license\nset forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under\nits own license agreement, provided that:\n\na) it complies with the terms and conditions of this Agreement; and\n\nb) its license agreement:\n\ni) effectively disclaims on behalf of all Contributors all warranties and\nconditions, express and implied, including warranties or conditions of title\nand non-infringement, and implied warranties or conditions of merchantability\nand fitness for a particular purpose;\n\nii) effectively excludes on behalf of all Contributors all liability for\ndamages, including direct, indirect, special, incidental and consequential\ndamages, such as lost profits;\n\niii) states that any provisions which differ from this Agreement are offered\nby that Contributor alone and not by any other party; and\n\niv) states that source code for the Program is available from such\nContributor, and informs licensees how to obtain it in a reasonable manner on\nor through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\na) it must be made available under this Agreement; and\n\nb) a copy of this Agreement must be included with each copy of the Program.\n\nContributors may not remove or alter any copyright notices contained within\nthe Program.\n\nEach Contributor must identify itself as the originator of its Contribution,\nif any, in a manner that reasonably allows subsequent Recipients to identify\nthe originator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities with\nrespect to end users, business partners and the like. While this license is\nintended to facilitate the commercial use of the Program, the Contributor who\nincludes the Program in a commercial product offering should do so in a\nmanner which does not create potential liability for other Contributors.\nTherefore, if a Contributor includes the Program in a commercial product\noffering, such Contributor (\"Commercial Contributor\") hereby agrees to defend\nand indemnify every other Contributor (\"Indemnified Contributor\") against any\nlosses, damages and costs (collectively \"Losses\") arising from claims,\nlawsuits and other legal actions brought by a third party against the\nIndemnified Contributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program in\na commercial product offering.  The obligations in this section do not apply\nto any claims or Losses relating to any actual or alleged intellectual\nproperty infringement. In order to qualify, an Indemnified Contributor must:\na) promptly notify the Commercial Contributor in writing of such claim, and\nb) allow the Commercial Contributor tocontrol, and cooperate with the\nCommercial Contributor in, the defense and any related settlement\nnegotiations. The Indemnified Contributor may participate in any such claim\nat its own expense.\n\nFor example, a Contributor might include the Program in a commercial product\noffering, Product X. That Contributor is then a Commercial Contributor. If\nthat Commercial Contributor then makes performance claims, or offers\nwarranties related to Product X, those performance claims and warranties are\nsuch Commercial Contributor's responsibility alone. Under this section, the\nCommercial Contributor would have to defend claims against the other\nContributors related to those performance claims and warranties, and if a\ncourt requires any other Contributor to pay any damages as a result, the\nCommercial Contributor must pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON\nAN \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER\nEXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR\nCONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A\nPARTICULAR PURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all risks\nassociated with its exercise of rights under this Agreement , including but\nnot limited to the risks and costs of program errors, compliance with\napplicable laws, damage to or loss of data, programs or equipment, and\nunavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY\nCONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION\nLOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY\nOF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of the\nremainder of the terms of this Agreement, and without further action by the\nparties hereto, such provision shall be reformed to the minimum extent\nnecessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Program itself\n(excluding combinations of the Program with other software or hardware)\ninfringes such Recipient's patent(s), then such Recipient's rights granted\nunder Section 2(b) shall terminate as of the date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it fails to\ncomply with any of the material terms or conditions of this Agreement and\ndoes not cure such failure in a reasonable period of time after becoming\naware of such noncompliance. If all Recipient's rights under this Agreement\nterminate, Recipient agrees to cease use and distribution of the Program as\nsoon as reasonably practicable. However, Recipient's obligations under this\nAgreement and any licenses granted by Recipient relating to the Program shall\ncontinue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement, but in\norder to avoid inconsistency the Agreement is copyrighted and may only be\nmodified in the following manner. The Agreement Steward reserves the right to\npublish new versions (including revisions) of this Agreement from time to\ntime. No one other than the Agreement Steward has the right to modify this\nAgreement. The Eclipse Foundation is the initial Agreement Steward. The\nEclipse Foundation may assign the responsibility to serve as the Agreement\nSteward to a suitable separate entity. Each new version of the Agreement will\nbe given a distinguishing version number. The Program (including\nContributions) may always be distributed subject to the version of the\nAgreement under which it was received. In addition, after a new version of\nthe Agreement is published, Contributor may elect to distribute the Program\n(including its Contributions) under the new version. Except as expressly\nstated in Sections 2(a) and 2(b) above, Recipient receives no rights or\nlicenses to the intellectual property of any Contributor under this\nAgreement, whether expressly, by implication, estoppel or otherwise. All\nrights in the Program not expressly granted under this Agreement are\nreserved.\n\nThis Agreement is governed by the laws of the State of Washington and the\nintellectual property laws of the United States of America. No party to this\nAgreement will bring a legal action under this Agreement more than one year\nafter the cause of action arose. Each party waives its rights to a jury trial\nin any resulting litigation.\n#+END_SRC\n\n\n* Requirements\n** The user-story\nMax touches the GO button using this app, and justly rebuilds the\nworld with Clojure.\n\n** Non-user-visible requirements\n1. Logging\n2. Security\n\n\n* Architecture\n1. Foo back-end\n2. Bar front-end\n   - Probably use a Pedestal App client\n\n\n| Part | Description                 | Alternatives  |\n|------+-----------------------------+---------------|\n| Bar  | Bar presents via D3 charts  | Flash? Nein!! |\n| Foo  | Foo has the data we worship |               |\n|      |                             |               |\n\n\n* Design\n** Foo design\n** Bar design\n\n\n* Source-code\nThe default =lein new app *= command just produces two files with\nactual Clojure code.\n\n** core\n#+NAME: core\n#+BEGIN_SRC clojure :tangle src/skeleton_app/core.clj\n(ns skeleton-app.core\n  (:gen-class))\n\n(defn -main\n  \"I don't do a whole lot ... yet.\"\n  [& args]\n  (println \"Hello, World!\"))\n\n#+END_SRC\n\n*** Tests\n#+BEGIN_SRC clojure :tangle test/skeleton_app/core_test.clj\n(ns skeleton-app.core-test\n  (:require [clojure.test :refer :all]\n            [skeleton-app.core :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))\n\n#+END_SRC\n"
  },
  {
    "path": "02-minimal-clojure-project/clojure-default-skeleton.org",
    "content": "#+TITLE: Clojure Default/Project Skeleton, Using Org Literate Programming\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+LANGUAGE: en\n#+STARTUP: align overview indent fold nodlcheck hidestars oddeven lognotestate\n#+PROPERTY: mkdirp yes\n\n\n* Meta: this file, Clojure + Org → LP, etc.\nYou're looking at a literate programming (LP) file, specifically an\n[[http://orgmode.org][Org mode]] formatted file combining both documentation (Org's structured\nmarkup) and code blocks (Clojure code).\n\nFor best results please *use Emacs 24.3 or later to view this* =.org=\n*file*. If you're looking at this on Github.com, STOP - the rendering\nthere is neither complete nor correct!\n\n** The *benefits* of LP using Emacs + Org\n1. Docs matter, a lot. With LP, documentation is integral to\n   development, never an afterthought.\n   - For all but small throwaway systems, you're likely keeping a\n     separate file of development notes already; LP would integrate\n     that.\n2. With one LP file, avoid the incidental/inessential complexity of\n   the filesystem: avoid context-switch overhead moving between files,\n   and sidestep your language's imposed filesystem structure.\n3. Org rocks for prose:\n   - Org's plain-text *markup is lightweight*, yet more powerful than\n     Markdown, and cleaner than rST.\n   - The *structural editing* provided by Org documents lets you\n     organize your thoughts/writing/code very quickly.  With good\n     structure even major revisions are easy.\n   - Org's exporter lets your *write-once, express-many-times*: you\n     can export an Org file to HTML (e.g. for blogging) or LaTeX\n     (for serious publishing).\n   - It's easy to version-control Org files.\n4. Org rocks for code:\n   - Each code block has flexible granularity: can be named and\n     referred to; evaluated or not; have data sent in or exported;\n     specify different REPL sessions; specify different target/tangled\n     files.\n   - Code blocks are syntax-highlighted.\n   - Code blocks are ready to edit: jump to major-mode editing easily.\n   - A single Org file can mix different languages.\n5. Meta-development, manage complexity from a coherent perspective: a\n   unified, single-file approach encourages holistic software\n   development and exposition, in a natural order, using structure to\n   enhance understanding.  LP is not just documentation and code\n   together: it's a *process and abstraction unifying the development\n   lifecycle*: requirements, architecture, design, code, tests,\n   deployment, and maintenance - can all be bound coherently in one\n   active format.\n\n\n* Using this file\n** Prerequisites\n1. A recent version of Emacs, 24.3+.\n2. Both org-mode (included w/ Emacs 24) and =clojure-mode= installed;\n   use Emacs ELPA as needed.\n   - Consider using an Emacs \"starter package\" that provides a good\n     baseline, like [[http://batsov.com/prelude/][Emacs Prelude]] or [[http://overtone.github.io/emacs-live/][Emacs Live]].\n\nThen if you start Emacs and load this file, you'll see it the way it's\nmeant to be seen: as a multi-level, hierarchically organized and\nstructured literate code file, w/ syntax-highlighted code blocks.  \n\n** Weaving and tangling\nTo use the original Knuth terminology, this single file can be /woven/\ninto documentation, or /tangled/ to code.\n\n*** Weave/export, to documentation\n+ To /weave/: the Org equivalent of /weaving/ is to export this file,\n  typically to HTML or LaTeX/PDF. The keystroke is =C-c-e= i.e. hold\n  down the Control key while pressing \"c\" then \"e\" to view the export\n  options.\n  - e.g. export this file to HTML with =CTRL-c-e h= or, to see it\n    immediately in a browser window, =CTRL-c-e b=.\n+ You don't have to export this file though; if/when you're comfy in\n  Emacs, the Org format itself is great.\n\n*** Tangle, to code\n+ To /tangle/: in Org, it's the same word/term. =C-c-v-t= will cause\n  all designated code blocks in this file to appear in the filesystem.\n  Here, the code blocks go to files and directories matching a new\n  Clojure app, as would be produced by =lein new app\n  the-project-name=.\n\n** Other coolness\n- =SHIFT-TAB= will *cycle* the display: top-level headings only, all\n  headings, or fully-expanded.\n- Within a code block, =CTRL-c= ='= will open a buffer to edit the\n  code. For full power, be sure =clojure-mode=, =paredit=, and\n  =nrepl= are installed.\n- Org docs: see [[http://orgmode.org/org.html][main documentation]], especially sections on [[http://orgmode.org/org.html#Document-Structure][structure]],\n  [[http://orgmode.org/org.html#Hyperlinks][links]], [[http://orgmode.org/org.html#Markup][markup]], and [[http://orgmode.org/org.html#Working-With-Source-Code][literate programming]] features.\n\n\n* Project meta\n** Project definition\n#+BEGIN_SRC clojure :tangle project.clj\n(defproject default-skeleton \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"http://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"http://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.5.1\"]])\n#+END_SRC\n\n** The README\nIt would be nice to auto-generate the README.md from selected parts of\nthis =org= file; TBD how.\n\n#+BEGIN_SRC markdown :tangle README.md\n# default-skeleton\n\nFIXME: description\n\n## Installation\n\nDownload from http://example.com/FIXME.\n\n## Usage\n\nFIXME: explanation\n\n    $ java -jar default-skeleton-0.1.0-standalone.jar [args]\n\n## Options\n\nFIXME: listing of options this app accepts.\n\n## Examples\n\n...\n\n### Bugs\n\n...\n\n### Any Other Sections\n### That You Think\n### Might be Useful\n\n## License\n\nCopyright © 2013 FIXME\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n#+END_SRC\n\n** License notice\n#+BEGIN_SRC text :tangle LICENSE\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM\nCONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and\ndocumentation distributed under this Agreement, and\n\nb) in the case of each subsequent Contributor:\n\ni) changes to the Program, and\n\nii) additions to the Program;\n\nwhere such changes and/or additions to the Program originate from and are\ndistributed by that particular Contributor. A Contribution 'originates' from\na Contributor if it was added to the Program by such Contributor itself or\nanyone acting on such Contributor's behalf. Contributions do not include\nadditions to the Program which: (i) are separate modules of software\ndistributed in conjunction with the Program under their own license\nagreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which are\nnecessarily infringed by the use or sale of its Contribution alone or when\ncombined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement,\nincluding all Contributors.\n\n2. GRANT OF RIGHTS\n\na) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free copyright license to\nreproduce, prepare derivative works of, publicly display, publicly perform,\ndistribute and sublicense the Contribution of such Contributor, if any, and\nsuch derivative works, in source code and object code form.\n\nb) Subject to the terms of this Agreement, each Contributor hereby grants\nRecipient a non-exclusive, worldwide, royalty-free patent license under\nLicensed Patents to make, use, sell, offer to sell, import and otherwise\ntransfer the Contribution of such Contributor, if any, in source code and\nobject code form.  This patent license shall apply to the combination of the\nContribution and the Program if, at the time the Contribution is added by the\nContributor, such addition of the Contribution causes such combination to be\ncovered by the Licensed Patents. The patent license shall not apply to any\nother combinations which include the Contribution. No hardware per se is\nlicensed hereunder.\n\nc) Recipient understands that although each Contributor grants the licenses\nto its Contributions set forth herein, no assurances are provided by any\nContributor that the Program does not infringe the patent or other\nintellectual property rights of any other entity. Each Contributor disclaims\nany liability to Recipient for claims brought by any other entity based on\ninfringement of intellectual property rights or otherwise. As a condition to\nexercising the rights and licenses granted hereunder, each Recipient hereby\nassumes sole responsibility to secure any other intellectual property rights\nneeded, if any. For example, if a third party patent license is required to\nallow Recipient to distribute the Program, it is Recipient's responsibility\nto acquire that license before distributing the Program.\n\nd) Each Contributor represents that to its knowledge it has sufficient\ncopyright rights in its Contribution, if any, to grant the copyright license\nset forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under\nits own license agreement, provided that:\n\na) it complies with the terms and conditions of this Agreement; and\n\nb) its license agreement:\n\ni) effectively disclaims on behalf of all Contributors all warranties and\nconditions, express and implied, including warranties or conditions of title\nand non-infringement, and implied warranties or conditions of merchantability\nand fitness for a particular purpose;\n\nii) effectively excludes on behalf of all Contributors all liability for\ndamages, including direct, indirect, special, incidental and consequential\ndamages, such as lost profits;\n\niii) states that any provisions which differ from this Agreement are offered\nby that Contributor alone and not by any other party; and\n\niv) states that source code for the Program is available from such\nContributor, and informs licensees how to obtain it in a reasonable manner on\nor through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\na) it must be made available under this Agreement; and\n\nb) a copy of this Agreement must be included with each copy of the Program.\n\nContributors may not remove or alter any copyright notices contained within\nthe Program.\n\nEach Contributor must identify itself as the originator of its Contribution,\nif any, in a manner that reasonably allows subsequent Recipients to identify\nthe originator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities with\nrespect to end users, business partners and the like. While this license is\nintended to facilitate the commercial use of the Program, the Contributor who\nincludes the Program in a commercial product offering should do so in a\nmanner which does not create potential liability for other Contributors.\nTherefore, if a Contributor includes the Program in a commercial product\noffering, such Contributor (\"Commercial Contributor\") hereby agrees to defend\nand indemnify every other Contributor (\"Indemnified Contributor\") against any\nlosses, damages and costs (collectively \"Losses\") arising from claims,\nlawsuits and other legal actions brought by a third party against the\nIndemnified Contributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program in\na commercial product offering.  The obligations in this section do not apply\nto any claims or Losses relating to any actual or alleged intellectual\nproperty infringement. In order to qualify, an Indemnified Contributor must:\na) promptly notify the Commercial Contributor in writing of such claim, and\nb) allow the Commercial Contributor tocontrol, and cooperate with the\nCommercial Contributor in, the defense and any related settlement\nnegotiations. The Indemnified Contributor may participate in any such claim\nat its own expense.\n\nFor example, a Contributor might include the Program in a commercial product\noffering, Product X. That Contributor is then a Commercial Contributor. If\nthat Commercial Contributor then makes performance claims, or offers\nwarranties related to Product X, those performance claims and warranties are\nsuch Commercial Contributor's responsibility alone. Under this section, the\nCommercial Contributor would have to defend claims against the other\nContributors related to those performance claims and warranties, and if a\ncourt requires any other Contributor to pay any damages as a result, the\nCommercial Contributor must pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON\nAN \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER\nEXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR\nCONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A\nPARTICULAR PURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all risks\nassociated with its exercise of rights under this Agreement , including but\nnot limited to the risks and costs of program errors, compliance with\napplicable laws, damage to or loss of data, programs or equipment, and\nunavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY\nCONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION\nLOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY\nOF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of the\nremainder of the terms of this Agreement, and without further action by the\nparties hereto, such provision shall be reformed to the minimum extent\nnecessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Program itself\n(excluding combinations of the Program with other software or hardware)\ninfringes such Recipient's patent(s), then such Recipient's rights granted\nunder Section 2(b) shall terminate as of the date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it fails to\ncomply with any of the material terms or conditions of this Agreement and\ndoes not cure such failure in a reasonable period of time after becoming\naware of such noncompliance. If all Recipient's rights under this Agreement\nterminate, Recipient agrees to cease use and distribution of the Program as\nsoon as reasonably practicable. However, Recipient's obligations under this\nAgreement and any licenses granted by Recipient relating to the Program shall\ncontinue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement, but in\norder to avoid inconsistency the Agreement is copyrighted and may only be\nmodified in the following manner. The Agreement Steward reserves the right to\npublish new versions (including revisions) of this Agreement from time to\ntime. No one other than the Agreement Steward has the right to modify this\nAgreement. The Eclipse Foundation is the initial Agreement Steward. The\nEclipse Foundation may assign the responsibility to serve as the Agreement\nSteward to a suitable separate entity. Each new version of the Agreement will\nbe given a distinguishing version number. The Program (including\nContributions) may always be distributed subject to the version of the\nAgreement under which it was received. In addition, after a new version of\nthe Agreement is published, Contributor may elect to distribute the Program\n(including its Contributions) under the new version. Except as expressly\nstated in Sections 2(a) and 2(b) above, Recipient receives no rights or\nlicenses to the intellectual property of any Contributor under this\nAgreement, whether expressly, by implication, estoppel or otherwise. All\nrights in the Program not expressly granted under this Agreement are\nreserved.\n\nThis Agreement is governed by the laws of the State of Washington and the\nintellectual property laws of the United States of America. No party to this\nAgreement will bring a legal action under this Agreement more than one year\nafter the cause of action arose. Each party waives its rights to a jury trial\nin any resulting litigation.\n#+END_SRC\n\n\n* Requirements\n** The user-story\nImport this library, and enjoy magical powers.\n\n** Non-user-visible requirements\n1. Logging\n2. Security\n\n\n* Architecture\n1. Data processing, \n2. Data storage\n3. Long-running service\n4. API\n\n\n| Part    | Description                                   | Alternatives           |\n|---------+-----------------------------------------------+------------------------|\n| API     | How other Clojure code accesses this library. |                        |\n| Service | Should execute data processing periodically.  | Manual, cmd-line start |\n|         |                                               |                        |\n\n\n* Design\n** API design\n- Always keep it minimal at first! You can add later, but removing\n  stuff is a pain.\n- Don't require the client/user of the API to do anything the library\n  could do.\n- See Joshua Bloch's talk, [[http://limist.com/coding/talk-notes-how-to-design-a-good-api-and-why-it-matters-bloch.html][How to Design an Good API and Why It Matters]]\n\n\n* Source-code\nThe =lein new default my-new-library= command just produces two files with\nactual Clojure code.\n\n** core\n#+NAME: core\n#+BEGIN_SRC clojure :tangle src/default_skeleton/core.clj\n(ns default-skeleton.core)\n\n(defn foo\n  \"I don't do a whole lot.\"\n  [x]\n  (println x \"Hello, World!\"))\n#+END_SRC\n\n*** Tests\n#+BEGIN_SRC clojure :tangle test/default_skeleton/core_test.clj\n(ns default-skeleton.core-test\n  (:require [clojure.test :refer :all]\n            [default-skeleton.core :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))\n#+END_SRC\n"
  },
  {
    "path": "03-pedestal-app/pedestal-app-skeleton.org",
    "content": "#+TITLE: Pedestal App, in Org literate programming form\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+STARTUP: align overview indent fold nodlcheck hidestars oddeven lognotestate\n#+PROPERTY: mkdirp yes\n\n\n* Project meta\n** Project definition\n#+BEGIN_SRC clojure :tangle project.clj\n(defproject skeleton-app \"0.0.1-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :dependencies [[org.clojure/clojure \"1.5.1\"]\n                 [org.clojure/clojurescript \"0.0-1586\"]\n                 [domina \"1.0.1\"]\n                 [ch.qos.logback/logback-classic \"1.0.7\" :exclusions [org.slf4j/slf4j-api]]\n                 [io.pedestal/pedestal.app \"0.1.8\"]\n                 [io.pedestal/pedestal.app-tools \"0.1.8\"]]\n  :profiles {:dev {:source-paths [\"dev\"]}}\n  :min-lein-version \"2.0.0\"\n  :source-paths [\"app/src\" \"app/templates\"]\n  :resource-paths [\"config\"]\n  :target-path \"out/\"\n  :aliases {\"dumbrepl\" [\"trampoline\" \"run\" \"-m\" \"clojure.main/main\"]})\n#+END_SRC\n\n\n* Main application\n** Behavior\n#+BEGIN_SRC clojure :tangle app/src/skeleton_app/behavior.clj\n(ns ^:shared skeleton-app.behavior\n    (:require [clojure.string :as string]\n              [io.pedestal.app.messages :as msg]))\n\n;; While creating new behavior, write tests to confirm that it is\n;; correct. For examples of various kinds of tests, see\n;; test/skeleton_app/test/behavior.clj.\n\n(defn set-value-transform [old-value message]\n  (:value message))\n\n(def example-app\n  {;; There are currently 2 versions (formats) for dataflow\n   ;; descritpion: the original version (version 1) and the current\n   ;; version (version 2). If the version is not specified, the\n   ;; descritpion will be assumed to be version 1 and an attempt\n   ;; will be made to convert it to version 2.\n   :version 2\n   :transform [[:set-value [:greeting] set-value-transform]]})\n\n\n;; Once this behavior works, run the Data UI and record\n;; rendering data which can be used while working on a custom\n;; renderer. Rendering involves making a template:\n;;\n;; app/templates/skeleton-app.html\n;;\n;; slicing the template into pieces you can use:\n;;\n;; app/src/skeleton_app/html_templates.cljs\n;;\n;; and then writing the rendering code:\n;;\n;; app/src/skeleton_app/rendering.cljs\n\n\n(comment\n  \n  ;; The examples below show the signature of each type of function\n  ;; that is used to build a behavior dataflow.\n  \n  ;; transform\n  \n  (defn example-transform [old-state message]\n    ;; returns new state\n    )\n\n  ;; derive\n  \n  (defn example-derive [old-state inputs]\n    ;; returns new state\n    )\n\n  ;; emit\n  \n  (defn example-emit [inputs]\n    ;; returns rendering deltas\n    )\n    \n  ;; effect\n  \n  (defn example-effect [inputs]\n    ;; returns a vector of messages which effect the outside world\n    )\n  \n  ;; continue\n  \n  (defn example-continue [inputs]\n    ;; returns a vector of messages which will be processed as part of\n    ;; the same dataflow transaction\n    )\n  \n  ;; dataflow description reference\n  \n  {:transform [[:op [:path] example-transform]]\n   :derive    #{[#{[:in]} [:path] example-derive]}\n   :effect    #{[#{[:in]} example-effect]}\n   :continue  #{[#{[:in]} example-continue]}\n   :emit      [[#{[:in]} example-emit]]}\n  \n  )\n#+END_SRC\n\n** HTML templates\n#+BEGIN_SRC clojure :tangle app/src/skeleton_app/html_templates.clj\n(ns skeleton-app.html-templates\n  (:use [io.pedestal.app.templates :only [tfn dtfn tnodes]]))\n\n(defmacro skeleton-app-templates\n  []\n  ;; Extract the 'hello' template from the template file skeleton-app.html.\n  ;; The 'dtfn' function will create a dynamic template which can be\n  ;; updated after it has been attached to the DOM.\n  ;;\n  ;; To see how this template is used, refer to\n  ;;\n  ;; app/src/skeleton_app/rendering.cljs\n  ;;\n  ;; The last argument to 'dtfn' is a set of fields that should be\n  ;; treated as static fields (may only be set once). Dynamic templates\n  ;; use ids to set values so you cannot dynamically set an id.\n  {:skeleton-app-page (dtfn (tnodes \"skeleton-app.html\" \"hello\") #{:id})})\n\n;; Note: this file will not be reloaded automatically when it is changed.\n#+END_SRC\n\n** Rendering\n#+BEGIN_SRC clojurescript :tangle app/src/skeleton_app/rendering.cljs\n(ns skeleton-app.rendering\n  (:require [domina :as dom]\n            [io.pedestal.app.render.push :as render]\n            [io.pedestal.app.render.push.templates :as templates]\n            [io.pedestal.app.render.push.handlers.automatic :as d])\n  (:require-macros [skeleton-app.html-templates :as html-templates]))\n\n;; Load templates.\n\n(def templates (html-templates/skeleton-app-templates))\n\n;; The way rendering is handled below is the result of using the\n;; renderer provided in `io.pedestal.app.render`. The only requirement\n;; for a renderer is that it must implement the Renderer protocol.\n;;\n;; This renderer dispatches to rendering functions based on the\n;; requested change. See the render-config table below. Each render\n;; function takes three arguments: renderer, render operation and a\n;; a transmitter which is used to send data back to the application's\n;; behavior. This example does not use the transmitter.\n\n(defn render-page [renderer [_ path] transmitter]\n  (let [;; The renderer that we are using here helps us map changes to\n        ;; the UI tree to the DOM. It keeps a mapping of paths to DOM\n        ;; ids. The `get-parent-id` function will return the DOM id of\n        ;; the parent of the node at path. If the path is [:a :b :c]\n        ;; then this will find the id associated with [:a :b]. The\n        ;; root node [] is configured when we created the renderer.\n        parent (render/get-parent-id renderer path)\n        ;; Use the `new-id!` function to associate a new id to the\n        ;; given path. With two arguments, this function will generate\n        ;; a random unique id. With three arguments, the given id will\n        ;; be associated with the given path.\n        id (render/new-id! renderer path)\n        ;; Get the dynamic template named :skeleton-app-page\n        ;; from the templates map. The `add-template` function will\n        ;; associate this template with the node at\n        ;; path. `add-template` returns a function that can be called\n        ;; to generate the initial HTML.\n        html (templates/add-template renderer path (:skeleton-app-page templates))]\n    ;; Call the `html` function, passing the initial values for the\n    ;; template. This returns an HTML string which is then added to\n    ;; the DOM using Domina.\n    (dom/append! (dom/by-id parent) (html {:id id :message \"\"}))))\n\n(defn render-message [renderer [_ path _ new-value] transmitter]\n  ;; This function responds to a :value event. It uses the\n  ;; `update-t` function to update the template at `path` with the new\n  ;; values in the passed map.\n  (templates/update-t renderer path {:message new-value}))\n\n;; The data structure below is used to map rendering data to functions\n;; which handle rendering for that specific change. This function is\n;; referenced in config/config.clj and must be a function in order to\n;; be used from the tool's \"render\" view.\n\n(defn render-config []\n  [;; All :node-create deltas for the node at :greeting will\n   ;; be rendered by the `render-page` function. The node name\n   ;; :greeting is a default name that is used when we don't\n   ;; provide our own combines and emits. To name your own nodes,\n   ;; create a custom combine or emit in the application's behavior.\n   [:node-create  [:greeting] render-page]\n   ;; All :node-destroy deltas for this path will be handled by the\n   ;; library function `d/default-exit`.\n   [:node-destroy   [:greeting] d/default-exit]\n   ;; All :value deltas for this path will be handled by the\n   ;; function `render-message`.\n   [:value [:greeting] render-message]])\n\n;; In render-config, paths can use wildcard keywords :* and :**. :*\n;; means exactly one segment with any value. :** means 0 or more\n;; elements.\n#+END_SRC\n\n** Back-end/external communications\n#+BEGIN_SRC clojurescript :tangle app/src/skeleton_app/services.cljs\n(ns skeleton-app.services)\n\n;; The services namespace responsible for communicating with back-end\n;; services. It receives messages from the application's behavior,\n;; makes requests to services and sends responses back to the\n;; behavior.\n;;\n;; This namespace will usually contain a function which can be\n;; configured to receive effect events from the behavior in the file\n;;\n;; app/src/skeleton_app/start.cljs\n;;\n;; After creating a new application, set the effect handler function\n;; to receive effect\n;;\n;; (app/consume-effect app services-fn)\n;;\n;; A very simple example of a services function which echos all events\n;; back to the behavior is shown below\n\n(comment\n\n  ;; The services implementation will need some way to send messages\n  ;; back to the application. The queue passed to the services function\n  ;; will convey messages to the application.\n  (defn echo-services-fn [message queue]\n    (put-message queue message))\n  \n  )\n\n;; During development, it is helpful to implement services which\n;; simulate communication with the real services. This implementaiton\n;; can be placed in the file\n;;\n;; app/src/skeleton_app/simulated/services.cljs\n;;\n#+END_SRC\n\n** Start\n#+BEGIN_SRC clojurescript :tangle app/src/skeleton_app/start.cljs\n(ns skeleton-app.start\n  (:require [io.pedestal.app.protocols :as p]\n            [io.pedestal.app :as app]\n            [io.pedestal.app.render.push :as push-render]\n            [io.pedestal.app.render :as render]\n            [io.pedestal.app.messages :as msg]\n            [skeleton-app.behavior :as behavior]\n            [skeleton-app.rendering :as rendering]))\n\n;; In this namespace, the application is built and started.\n\n(defn create-app [render-config]\n  (let [;; Build the application described in the map\n        ;; 'behavior/example-app'. The application is a record which\n        ;; implements the Receiver protocol.\n        app (app/build behavior/example-app)\n        ;; Create the render function that will be used by this\n        ;; application. A renderer function takes two arguments: the\n        ;; application model deltas and the input queue.\n        ;;\n        ;; On the line below, we create a renderer that will help in\n        ;; mapping UI data to the DOM. \n        ;;\n        ;; The file, app/src/skeleton_app/rendering.cljs contains\n        ;; the code which does all of the rendering as well as the\n        ;; render-config which is used to map renderering data to\n        ;; specific functions.\n        render-fn (push-render/renderer \"content\" render-config render/log-fn)\n        ;; This application does not yet have services, but if it did,\n        ;; this would be a good place to create it.\n        ;; services-fn (fn [message input-queue] ...)\n\n        ;; Configure the application to send all rendering data to this\n        ;; renderer.\n        app-model (render/consume-app-model app render-fn)]\n    ;; If services existed, configure the application to send all\n    ;; effects there.\n    ;; (app/consume-effect app services-fn)\n    ;;\n    ;; Start the application\n    (app/begin app)\n    ;; Send a message to the application so that it does something.\n    (p/put-message (:input app) {msg/type :set-value msg/topic [:greeting] :value \"Hello World!\"})\n    ;; Returning the app and app-model from the main function allows\n    ;; the tooling to add support for useful features like logging\n    ;; and recording.\n    {:app app :app-model app-model}))\n\n(defn ^:export main []\n  ;; config/config.clj refers to this namespace as a main namespace\n  ;; for several aspects. A main namespace must have a no argument\n  ;; main function. To tie into tooling, this function should return\n  ;; the newly created app.\n  (create-app (rendering/render-config)))\n\n#+END_SRC\n\n** Simulated back-end\n#+BEGIN_SRC clojurescript :tangle app/src/skeleton_app/simulated/services.cljs\n(ns skeleton-app.simulated.services)\n\n;; Implement services to simulate talking to back-end services\n#+END_SRC\n\n\n#+BEGIN_SRC clojurescript :tangle app/src/skeleton_app/simulated/start.cljs\n(ns skeleton-app.simulated.start\n  (:require [io.pedestal.app.render.push.handlers.automatic :as d]\n            [skeleton-app.start :as start]\n            ;; This needs to be included somewhere in order for the\n            ;; tools to work.\n            [io.pedestal.app-tools.tooling :as tooling]))\n\n(defn ^:export main []\n  ;; Create an application which uses the data renderer. The :data-ui\n  ;; aspect is configured to run this main function. See\n  ;;\n  ;; config/config.clj\n  ;;\n  (start/create-app d/data-renderer-config))\n#+END_SRC\n\n\n* Assets\n#+BEGIN_SRC javascript :tangle app/assets/javascripts/xpath.js\n(function(){var ca=void(0);var da={targetFrame:ca,exportInstaller:false,useNative:true,useInnerText:true};var ea;if(window.jsxpath){ea=window.jsxpath;}\nelse{var fa=document.getElementsByTagName('script');var ga=fa[fa.length-1];var ha=ga.src;ea={};var ia=ha.match(/\\?(.*)$/);if(ia){var ja=ia[1].split('&');for(var i=0,l=ja.length;i<l;i++){var ka=ja[i];var la=ka.split('=');var ma=la[0];var na=la[1];if(na==ca){na==true;}\nelse if(na=='false'||/^-?\\d+$/.test(na)){na=eval(na);}\nea[ma]=na;}}}\nfor(var n in da){if(!(n in ea))ea[n]=da[n];}\nea.hasNative=!!(document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature(\"XPath\",null));if(ea.hasNative&&ea.useNative&&!ea.exportInstaller){return;}\nvar oa;var pa;var qa;var ra;var sa;var ta;var va;var wa;var xa;var ya;var za;var Aa;var Ba;var Ca;var Da=new function(){var ua=navigator.userAgent;if(RegExp==ca){if(ua.indexOf(\"Opera\")>=0){this.opera=true;}\nelse if(ua.indexOf(\"Netscape\")>=0){this.netscape=true;}\nelse if(ua.indexOf(\"Mozilla/\")==0){this.mozilla=true;}\nelse{this.unknown=true;}\nif(ua.indexOf(\"Gecko/\")>=0){this.gecko=true;}\nif(ua.indexOf(\"Win\")>=0){this.windows=true;}\nelse if(ua.indexOf(\"Mac\")>=0){this.mac=true;}\nelse if(ua.indexOf(\"Linux\")>=0){this.linux=true;}\nelse if(ua.indexOf(\"BSD\")>=0){this.bsd=true;}\nelse if(ua.indexOf(\"SunOS\")>=0){this.sunos=true;}}\nelse{ /*@cc_on @if(@_jscript)function jscriptVersion(){switch(@_jscript_version){case 3.0:return \"4.0\";case 5.0:return \"5.0\";case 5.1:return \"5.01\";case 5.5:return \"5.5\";case 5.6:if(\"XMLHttpRequest\" in window)return \"7.0\";return \"6.0\";case 5.7:return \"7.0\";default:return true;}}\nif(@_win16||@_win32||@_win64){this.windows=true;this.trident=jscriptVersion();}\nelse if(@_mac||navigator.platform.indexOf(\"Mac\")>=0){this.mac=true;this.tasman=jscriptVersion();}\nif(/MSIE (\\d+\\.\\d+)b?;/.test(ua)){this.ie=RegExp.$1;this['ie'+RegExp.$1.charAt(0)]=true;}@else @*/ \nif(/AppleWebKit\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.applewebkit=RegExp.$1;if(RegExp.$1.charAt(0)==4){this.applewebkit2=true;}\nelse{this.applewebkit3=true;}}\nelse if(typeof Components==\"object\"&&(/Gecko\\/(\\d{8})/.test(ua)||navigator.product==\"Gecko\"&&/^(\\d{8})$/.test(navigator.productSub))){this.gecko=RegExp.$1;}/*@end @*/ \nif(typeof(opera)==\"object\"&&typeof(opera.version)==\"function\"){this.opera=opera.version();this['opera'+this.opera[0]+this.opera[2]]=true;}\nelse if(typeof opera==\"object\"&&(/Opera[\\/ ](\\d+\\.\\d+)/.test(ua))){this.opera=RegExp.$1;}\nelse if(this.ie){}\nelse if(/Safari\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.safari=RegExp.$1;}\nelse if(/NetFront\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.netfront=RegExp.$1;}\nelse if(/Konqueror\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.konqueror=RegExp.$1;}\nelse if(ua.indexOf(\"(compatible;\")<0&&(/^Mozilla\\/(\\d+\\.\\d+)/.test(ua))){this.mozilla=RegExp.$1;if(/\\([^(]*rv:(\\d+(?:\\.\\d+)*).*?\\)/.test(ua))this.mozillarv=RegExp.$1;if(/Firefox\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.firefox=RegExp.$1;}\nelse if(/Netscape\\d?\\/(\\d+(?:\\.\\d+)*)/.test(ua)){this.netscape=RegExp.$1;}}\nelse{this.unknown=true;}\nif(ua.indexOf(\"Win 9x 4.90\")>=0){this.windows=\"ME\";}\nelse if(/Win(?:dows)? ?(NT ?(\\d+\\.\\d+)?|\\d+|ME|Vista|XP)/.test(ua)){this.windows=RegExp.$1;if(RegExp.$2){this.winnt=RegExp.$2;}\nelse switch(RegExp.$1){case \"2000\":this.winnt=\"5.0\";break;case \"XP\":this.winnt=\"5.1\";break;case \"Vista\":this.winnt=\"6.0\";break;}}\nelse if(ua.indexOf(\"Mac\")>=0){this.mac=true;}\nelse if(ua.indexOf(\"Linux\")>=0){this.linux=true;}\nelse if(/(\\w*BSD)/.test(ua)){this.bsd=RegExp.$1;}\nelse if(ua.indexOf(\"SunOS\")>=0){this.sunos=true;}}};var Ea=function(Fa){var Ga=Ea.prototype;var Ha=Fa.match(Ga.regs.token);for(var i=0,l=Ha.length;i<l;i++){if(Ga.regs.strip.test(Ha[i])){Ha.splice(i,1);}}\nfor(var n in Ga)Ha[n]=Ga[n];Ha.index=0;return Ha;};Ea.prototype.regs={token:/\\$?(?:(?![0-9-])[\\w-]+:)?(?![0-9-])[\\w-]+|\\/\\/|\\.\\.|::|\\d+(?:\\.\\d*)?|\\.\\d+|\"[^\"]*\"|'[^']*'|[!<>]=|(?![0-9-])[\\w-]+:\\*|\\s+|./g,strip:/^\\s/};Ea.prototype.peek=function(i){return this[this.index+(i||0)];};Ea.prototype.next=function(){return this[this.index++];};Ea.prototype.back=function(){this.index--;};Ea.prototype.empty=function(){return this.length<=this.index;};var Ia=function(Ja,Ka,La){this.node=Ja;this.position=Ka||1;this.last=La||1;};var Ma=function(){};Ma.prototype.number=function(Na){var Oa=this.evaluate(Na);if(Oa.isNodeSet)return Oa.number();return+Oa;};Ma.prototype.string=function(Pa){var Qa=this.evaluate(Pa);if(Qa.isNodeSet)return Qa.string();return ''+Qa;};Ma.prototype.bool=function(Ra){var Sa=this.evaluate(Ra);if(Sa.isNodeSet)return Sa.bool();return!!Sa;};var Ta=function(){};Ta.parsePredicates=function(Ua,Va){while(Ua.peek()=='['){Ua.next();if(Ua.empty()){throw Error('missing predicate expr');}\nvar Wa=oa.parse(Ua);Va.predicate(Wa);if(Ua.empty()){throw Error('unclosed predicate expr');}\nif(Ua.next()!=']'){Ua.back();throw Error('bad token: '+Ua.next());}}};Ta.prototype=new Ma();Ta.prototype.evaluatePredicates=function(Xa,Ya){var Za,predicate,nodes,node,Xa,position,reverse;reverse=this.reverse;Za=this.predicates;Xa.sort();for(var i=Ya||0,l0=Za.length;i<l0;i++){predicate=Za[i];var $a=[];var ab=Xa.list();for(var j=0,l1=ab.length;j<l1;j++){position=reverse?(l1-j):(j+1);exrs=predicate.evaluate(new Ia(ab[j],position,l1));switch(typeof exrs){case 'number':exrs=(position==exrs);break;case 'string':exrs=!!exrs;break;case 'object':exrs=exrs.bool();break;}\nif(!exrs){$a.push(j);}}\nfor(var j=$a.length-1,l1=0;j>=l1;j--){Xa.del($a[j]);}}\nreturn Xa;};if(!window.BinaryExpr&&window.defaultConfig)window.BinaryExpr=null;oa=function(op,bb,cb,db){this.op=op;this.left=bb;this.right=cb;this.datatype=oa.ops[op][2];this.needContextPosition=bb.needContextPosition||cb.needContextPosition;this.needContextNode=bb.needContextNode||cb.needContextNode;if(this.op=='='){if(!cb.needContextNode&&!cb.needContextPosition&&cb.datatype!='nodeset'&&cb.datatype!='void'&&bb.quickAttr){this.quickAttr=true;this.attrName=bb.attrName;this.attrValueExpr=cb;}\nelse if(!bb.needContextNode&&!bb.needContextPosition&&bb.datatype!='nodeset'&&bb.datatype!='void'&&cb.quickAttr){this.quickAttr=true;this.attrName=cb.attrName;this.attrValueExpr=bb;}}};oa.compare=function(op,eb,fb,gb,hb){var ib,lnodes,rnodes,nodes,nodeset,primitive;fb=fb.evaluate(hb);gb=gb.evaluate(hb);if(fb.isNodeSet&&gb.isNodeSet){lnodes=fb.list();rnodes=gb.list();for(var i=0,l0=lnodes.length;i<l0;i++)for(var j=0,l1=rnodes.length;j<l1;j++)if(eb(wa.to('string',lnodes[i]),wa.to('string',rnodes[j])))return true;return false;}\nif(fb.isNodeSet||gb.isNodeSet){if(fb.isNodeSet)nodeset=fb,primitive=gb;else nodeset=gb,primitive=fb;nodes=nodeset.list();ib=typeof primitive;for(var i=0,l=nodes.length;i<l;i++){if(eb(wa.to(ib,nodes[i]),primitive))return true;}\nreturn false;}\nif(op=='='||op=='!='){if(typeof fb=='boolean'||typeof gb=='boolean'){return eb(!!fb,!!gb);}\nif(typeof fb=='number'||typeof gb=='number'){return eb(+fb,+gb);}\nreturn eb(fb,gb);}\nreturn eb(+fb,+gb);};oa.ops={'div':[6,function(jb,kb,lb){return jb.number(lb)/kb.number(lb);},'number'],'mod':[6,function(mb,nb,ob){return mb.number(ob)%nb.number(ob);},'number'],'*':[6,function(pb,qb,rb){return pb.number(rb)*qb.number(rb);},'number'],'+':[5,function(sb,tb,ub){return sb.number(ub)+tb.number(ub);},'number'],'-':[5,function(vb,wb,xb){return vb.number(xb)-wb.number(xb);},'number'],'<':[4,function(yb,zb,Ab){return oa.compare('<',function(a,b){return a<b},yb,zb,Ab);},'boolean'],'>':[4,function(Bb,Cb,Db){return oa.compare('>',function(a,b){return a>b},Bb,Cb,Db);},'boolean'],'<=':[4,function(Eb,Fb,Gb){return oa.compare('<=',function(a,b){return a<=b},Eb,Fb,Gb);},'boolean'],'>=':[4,function(Hb,Ib,Jb){return oa.compare('>=',function(a,b){return a>=b},Hb,Ib,Jb);},'boolean'],'=':[3,function(Kb,Lb,Mb){return oa.compare('=',function(a,b){return a==b},Kb,Lb,Mb);},'boolean'],'!=':[3,function(Nb,Ob,Pb){return oa.compare('!=',function(a,b){return a!=b},Nb,Ob,Pb);},'boolean'],'and':[2,function(Qb,Rb,Sb){return Qb.bool(Sb)&&Rb.bool(Sb);},'boolean'],'or':[1,function(Tb,Ub,Vb){return Tb.bool(Vb)||Ub.bool(Vb);},'boolean']};oa.parse=function(Wb){var op,precedence,info,expr,stack=[],index=Wb.index;while(true){if(Wb.empty()){throw Error('missing right expression');}\nexpr=Aa.parse(Wb);op=Wb.next();if(!op){break;}\ninfo=this.ops[op];precedence=info&&info[0];if(!precedence){Wb.back();break;}\nwhile(stack.length&&precedence<=this.ops[stack[stack.length-1]][0]){expr=new oa(stack.pop(),stack.pop(),expr);}\nstack.push(expr,op);}\nwhile(stack.length){expr=new oa(stack.pop(),stack.pop(),expr);}\nreturn expr;};oa.prototype=new Ma();oa.prototype.evaluate=function(Xb){return oa.ops[this.op][1](this.left,this.right,Xb);};oa.prototype.show=function(Yb){Yb=Yb||'';var t='';t+=Yb+'binary: '+this.op+'\\n';Yb+='    ';t+=this.left.show(Yb);t+=this.right.show(Yb);return t;};if(!window.UnaryExpr&&window.defaultConfig)window.UnaryExpr=null;Aa=function(op,Zb){this.op=op;this.expr=Zb;this.needContextPosition=Zb.needContextPosition;this.needContextNode=Zb.needContextNode;};Aa.ops={'-':1};Aa.parse=function($b){var ac;if(this.ops[$b.peek()])return new Aa($b.next(),Aa.parse($b));else return Ba.parse($b);};Aa.prototype=new Ma();Aa.prototype.datatype='number';Aa.prototype.evaluate=function(bc){return-this.expr.number(bc);};Aa.prototype.show=function(cc){cc=cc||'';var t='';t+=cc+'unary: '+this.op+'\\n';cc+='    ';t+=this.expr.show(cc);return t;};if(!window.UnionExpr&&window.defaultConfig)window.UnionExpr=null;Ba=function(){this.paths=[];};Ba.ops={'|':1};Ba.parse=function(dc){var ec,expr;expr=ya.parse(dc);if(!this.ops[dc.peek()])return expr;ec=new Ba();ec.path(expr);while(true){if(!this.ops[dc.next()])break;if(dc.empty()){throw Error('missing next union location path');}\nec.path(ya.parse(dc));}\ndc.back();return ec;};Ba.prototype=new Ma();Ba.prototype.datatype='nodeset';Ba.prototype.evaluate=function(fc){var gc=this.paths;var hc=new ta();for(var i=0,l=gc.length;i<l;i++){var ic=gc[i].evaluate(fc);if(!ic.isNodeSet)throw Error('PathExpr must be nodeset');hc.merge(ic);}\nreturn hc;};Ba.prototype.path=function(jc){this.paths.push(jc);if(jc.needContextPosition){this.needContextPosition=true;}\nif(jc.needContextNode){this.needContextNode=true;}}\nBa.prototype.show=function(kc){kc=kc||'';var t='';t+=kc+'union:'+'\\n';kc+='    ';for(var i=0;i<this.paths.length;i++){t+=this.paths[i].show(kc);}\nreturn t;};if(!window.PathExpr&&window.defaultConfig)window.PathExpr=null;ya=function(lc){this.filter=lc;this.steps=[];this.datatype=lc.datatype;this.needContextPosition=lc.needContextPosition;this.needContextNode=lc.needContextNode;};ya.ops={'//':1,'/':1};ya.parse=function(mc){var op,expr,path,token;if(this.ops[mc.peek()]){op=mc.next();token=mc.peek();if(op=='/'&&(mc.empty()||(token!='.'&&token!='..'&&token!='@'&&token!='*'&&!/(?![0-9])[\\w]/.test(token)))){return pa.root();}\npath=new ya(pa.root());if(mc.empty()){throw Error('missing next location step');}\nexpr=za.parse(mc);path.step(op,expr);}\nelse{expr=pa.parse(mc);if(!expr){expr=za.parse(mc);path=new ya(pa.context());path.step('/',expr);}\nelse if(!this.ops[mc.peek()])return expr;else path=new ya(expr);}\nwhile(true){if(!this.ops[mc.peek()])break;op=mc.next();if(mc.empty()){throw Error('missing next location step');}\npath.step(op,za.parse(mc));}\nreturn path;};ya.prototype=new Ma();ya.prototype.evaluate=function(nc){var oc=this.filter.evaluate(nc);if(!oc.isNodeSet)throw Exception('Filter nodeset must be nodeset type');var pc=this.steps;for(var i=0,l0=pc.length;i<l0&&oc.length;i++){var qc=pc[i][1];var rc=qc.reverse;var sc=oc.iterator(rc);var tc=oc;oc=null;var uc,next;if(!qc.needContextPosition&&qc.axis=='following'){for(uc=sc();next=sc();uc=next){if(Da.applewebkit2){var vc=false;var wc=next;do{if(wc==uc){vc=true;break;}}\nwhile(wc=wc.parentNode);if(!vc)break;}\nelse{try{if(!uc.contains(next))break}\ncatch(e){if(!(next.compareDocumentPosition(uc)&8))break}}}\noc=qc.evaluate(new Ia(uc));}\nelse if(!qc.needContextPosition&&qc.axis=='preceding'){uc=sc();oc=qc.evaluate(new Ia(uc));}\nelse{uc=sc();var j=0;oc=qc.evaluate(new Ia(uc),false,tc,j);while(uc=sc()){j++;oc.merge(qc.evaluate(new Ia(uc),false,tc,j));}}}\nreturn oc;};ya.prototype.step=function(op,xc){xc.op=op;this.steps.push([op,xc]);this.quickAttr=false;if(this.steps.length==1){if(op=='/'&&xc.axis=='attribute'){var yc=xc.test;if(!yc.notOnlyElement&&yc.name!='*'){this.quickAttr=true;this.attrName=yc.name;}}}};ya.prototype.show=function(zc){zc=zc||'';var t='';t+=zc+'path:'+'\\n';zc+='    ';t+=zc+'filter:'+'\\n';t+=this.filter.show(zc+'    ');if(this.steps.length){t+=zc+'steps:'+'\\n';zc+='    ';for(var i=0;i<this.steps.length;i++){var Ac=this.steps[i];t+=zc+'operator: '+Ac[0]+'\\n';t+=Ac[1].show(zc);}}\nreturn t;};if(!window.FilterExpr&&window.defaultConfig)window.FilterExpr=null;pa=function(Bc){this.primary=Bc;this.predicates=[];this.datatype=Bc.datatype;this.needContextPosition=Bc.needContextPosition;this.needContextNode=Bc.needContextNode;};pa.parse=function(Cc){var Dc,filter,token,ch;token=Cc.peek();ch=token.charAt(0);switch(ch){case '$':Dc=Ca.parse(Cc);break;case '(':Cc.next();Dc=oa.parse(Cc);if(Cc.empty()){throw Error('unclosed \"(\"');}\nif(Cc.next()!=')'){Cc.back();throw Error('bad token: '+Cc.next());}\nbreak;case '\"':case \"'\":Dc=ra.parse(Cc);break;default:if(!isNaN(+token)){Dc=xa.parse(Cc);}\nelse if(va.types[token]){return null;}\nelse if(/(?![0-9])[\\w]/.test(ch)&&Cc.peek(1)=='('){Dc=qa.parse(Cc);}\nelse{return null;}\nbreak;}\nif(Cc.peek()!='[')return Dc;filter=new pa(Dc);Ta.parsePredicates(Cc,filter);return filter;};pa.root=function(){return new qa('root-node');};pa.context=function(){return new qa('context-node');};pa.prototype=new Ta();pa.prototype.evaluate=function(Ec){var Fc=this.primary.evaluate(Ec);if(!Fc.isNodeSet){if(this.predicates.length)throw Error('Primary result must be nodeset type '+'if filter have predicate expression');return Fc;}\nreturn this.evaluatePredicates(Fc);};pa.prototype.predicate=function(Gc){this.predicates.push(Gc);};pa.prototype.show=function(Hc){Hc=Hc||'';var t='';t+=Hc+'filter: '+'\\n';Hc+='    ';t+=this.primary.show(Hc);if(this.predicates.length){t+=Hc+'predicates: '+'\\n';Hc+='    ';for(var i=0;i<this.predicates.length;i++){t+=this.predicates[i].show(Hc);}}\nreturn t;};if(!window.NodeUtil&&window.defaultConfig)window.NodeUtil=null;wa={to:function(Ic,Jc){var t,type=Jc.nodeType;if(type==1&&ea.useInnerText&&!Da.applewebkit2){t=Jc.textContent;t=(t==ca||t==null)?Jc.innerText:t;t=(t==ca||t==null)?'':t;}\nif(typeof t!='string'){ /*@cc_on \nif(type==1&&Jc.nodeName.toLowerCase()=='title'){t=Jc.text;}\nelse@*/if(type==9||type==1){if(type==9){Jc=Jc.documentElement;}\nelse{Jc=Jc.firstChild;}\nfor(t='',stack=[],i=0;Jc;){do{if(Jc.nodeType!=1){t+=Jc.nodeValue;} /*@cc_on \nelse if(Jc.nodeName.toLowerCase()=='title'){t+=Jc.text;}@*/stack[i++]=Jc;}\nwhile(Jc=Jc.firstChild);while(i&&!(Jc=stack[--i].nextSibling)){}}}\nelse{t=Jc.nodeValue;}}\nswitch(Ic){case 'number':return+t;case 'boolean':return!!t;default:return t;}},attrPropMap:{name:'name','class':'className',dir:'dir',id:'id',name:'name',title:'title'},attrMatch:function(Kc,Lc,Mc){ /*@cc_on @if(@_jscript)var Nc=wa.attrPropMap[Lc];if(!Lc||Mc==null&&(Nc&&Kc[Nc]||!Nc&&Kc.getAttribute&&Kc.getAttribute(Lc,2))||Mc!=null&&(Nc&&Kc[Nc]==Mc||!Nc&&Kc.getAttribute&&Kc.getAttribute(Lc,2)==Mc)){@else @*/ \nif(!Lc||Mc==null&&Kc.hasAttribute&&Kc.hasAttribute(Lc)||Mc!=null&&Kc.getAttribute&&Kc.getAttribute(Lc)==Mc){/*@end @*/ \nreturn true;}\nelse{return false;}},getDescendantNodes:function(Oc,Kc,Pc,Lc,Mc,Qc,Rc){if(Qc){Qc.delDescendant(Kc,Rc);} /*@cc_on \ntry{if(!Oc.notOnlyElement||Oc.type==8||(Lc&&Oc.type==0)){var Sc=Kc.all;if(!Sc){return Pc;}\nvar Tc=Oc.name;if(Oc.type==8)Tc='!';else if(Oc.type==0)Tc='*';if(Tc!='*'){Sc=Sc.tags(Tc);if(!Sc){return Pc;}}\nif(Lc){var Uc=[]\nvar i=0;if(Mc!=null&&(Lc=='id'||Lc=='name')){Sc=Sc[Mc];if(!Sc){return Pc;}\nif(!Sc.length||Sc.nodeType){Sc=[Sc];}}\nwhile(Kc=Sc[i++]){if(wa.attrMatch(Kc,Lc,Mc))Uc.push(Kc);}\nSc=Uc;}\nvar i=0;while(Kc=Sc[i++]){if(Tc!='*'||Kc.tagName!='!'){Pc.push(Kc);}}\nreturn Pc;}(function(Vc){var g=arguments.callee;var Kc=Vc.firstChild;if(Kc){for(;Kc;Kc=Kc.nextSibling){if(wa.attrMatch(Kc,Lc,Mc)){if(Oc.match(Kc))Pc.push(Kc);}\ng(Kc);}}})(Kc);return Pc;}\ncatch(e){@*/if(Mc&&Lc=='id'&&Kc.getElementById){Kc=Kc.getElementById(Mc);if(Kc&&Oc.match(Kc)){Pc.push(Kc);}}\nelse if(Mc&&Lc=='name'&&Kc.getElementsByName){var Wc=Kc.getElementsByName(Mc);for(var i=0,l=Wc.length;i<l;i++){Kc=Wc[i];if(Da.opera?(Kc.name==Mc&&Oc.match(Kc)):Oc.match(Kc)){Pc.push(Kc);}}}\nelse if(Mc&&Lc=='class'&&Kc.getElementsByClassName){var Wc=Kc.getElementsByClassName(Mc);for(var i=0,l=Wc.length;i<l;i++){Kc=Wc[i];if(Kc.className==Mc&&Oc.match(Kc)){Pc.push(Kc);}}}\nelse if(Oc.notOnlyElement){(function(Xc){var f=arguments.callee;for(var Kc=Xc.firstChild;Kc;Kc=Kc.nextSibling){if(wa.attrMatch(Kc,Lc,Mc)){if(Oc.match(Kc.nodeType))Pc.push(Kc);}\nf(Kc);}})(Kc);}\nelse{var Tc=Oc.name;if(Kc.getElementsByTagName){var Wc=Kc.getElementsByTagName(Tc);if(Wc){var i=0;while(Kc=Wc[i++]){if(wa.attrMatch(Kc,Lc,Mc))Pc.push(Kc);}}}}\nreturn Pc; /*@cc_on }@*/},getChildNodes:function(Yc,Kc,Zc,Lc,Mc){ /*@cc_on \ntry{var $c;if((!Yc.notOnlyElement||Yc.type==8||(Lc&&Yc.type==0))&&($c=Kc.children)){var ad,elm;ad=Yc.name;if(Yc.type==8)ad='!';else if(Yc.type==0)ad='*';if(ad!='*'){$c=$c.tags(ad);if(!$c){return Zc;}}\nif(Lc){var bd=[]\nvar i=0;if(Lc=='id'||Lc=='name'){$c=$c[Mc];if(!$c){return Zc;}\nif(!$c.length||$c.nodeType){$c=[$c];}}\nwhile(Kc=$c[i++]){if(wa.attrMatch(Kc,Lc,Mc))bd.push(Kc);}\n$c=bd;}\nvar i=0;while(Kc=$c[i++]){if(ad!='*'||Kc.tagName!='!'){Zc.push(Kc);}}\nreturn Zc;}\nfor(var i=0,Kc=Kc.firstChild;Kc;i++,Kc=Kc.nextSibling){if(wa.attrMatch(Kc,Lc,Mc)){if(Yc.match(Kc))Zc.push(Kc);}}\nreturn Zc;}\ncatch(e){@*/for(var Kc=Kc.firstChild;Kc;Kc=Kc.nextSibling){if(wa.attrMatch(Kc,Lc,Mc)){if(Yc.match(Kc))Zc.push(Kc);}}\nreturn Zc; /*@cc_on }@*/}}; /*@cc_on \nvar cd=function(dd,ed,fd){this.node=dd;this.nodeType=2;this.nodeValue=dd.nodeValue;this.nodeName=dd.nodeName;this.parentNode=ed;this.ownerElement=ed;this.parentSourceIndex=fd;};@*/if(!window.Step&&window.defaultConfig)window.Step=null;za=function(gd,hd){this.axis=gd;this.reverse=za.axises[gd][0];this.func=za.axises[gd][1];this.test=hd;this.predicates=[];this._quickAttr=za.axises[gd][2]};za.axises={ancestor:[true,function(jd,kd,ld,_,md,od,pd){while(kd=kd.parentNode){if(od&&kd.nodeType==1){od.reserveDelByNode(kd,pd,true);}\nif(jd.match(kd))ld.unshift(kd);}\nreturn ld;}],'ancestor-or-self':[true,function(qd,rd,sd,_,td,ud,vd){do{if(ud&&rd.nodeType==1){ud.reserveDelByNode(rd,vd,true);}\nif(qd.match(rd))sd.unshift(rd);}\nwhile(rd=rd.parentNode)return sd;}],attribute:[false,function(wd,xd,yd){var zd=xd.attributes;if(zd){ /*@cc_on \nvar Ad=xd.sourceIndex;@*/if((wd.notOnlyElement&&wd.type==0)||wd.name=='*'){for(var i=0,attr;attr=zd[i];i++){ /*@cc_on @if(@_jscript)if(attr.nodeValue){yd.push(new cd(attr,xd,Ad));}@else @*/ \nyd.push(attr);/*@end @*/ }}\nelse{var Bd=zd.getNamedItem(wd.name); /*@cc_on @if(@_jscript)if(Bd&&Bd.nodeValue){Bd=new cd(Bd,xd,Ad);;@else @*/ \nif(Bd){/*@end @*/ \nyd.push(Bd);}}}\nreturn yd;}],child:[false,wa.getChildNodes,true],descendant:[false,wa.getDescendantNodes,true],'descendant-or-self':[false,function(wd,xd,yd,Cd,Dd,Ed,Fd){if(wa.attrMatch(xd,Cd,Dd)){if(wd.match(xd))yd.push(xd);}\nreturn wa.getDescendantNodes(wd,xd,yd,Cd,Dd,Ed,Fd);},true],following:[false,function(wd,xd,yd,Gd,Hd){do{var Id=xd;while(Id=Id.nextSibling){if(wa.attrMatch(Id,Gd,Hd)){if(wd.match(Id))yd.push(Id);}\nyd=wa.getDescendantNodes(wd,Id,yd,Gd,Hd);}}\nwhile(xd=xd.parentNode);return yd;},true],'following-sibling':[false,function(wd,xd,yd,_,Jd,Kd,Ld){while(xd=xd.nextSibling){if(Kd&&xd.nodeType==1){Kd.reserveDelByNode(xd,Ld);}\nif(wd.match(xd)){yd.push(xd);}}\nreturn yd;}],namespace:[false,function(wd,xd,yd){return yd;}],parent:[false,function(wd,xd,yd){if(xd.nodeType==9){return yd;}\nif(xd.nodeType==2){yd.push(xd.ownerElement);return yd;}\nvar xd=xd.parentNode;if(wd.match(xd))yd.push(xd);return yd;}],preceding:[true,function(wd,xd,yd,Md,Nd){var Od=[];do{Od.unshift(xd);}\nwhile(xd=xd.parentNode);for(var i=1,l0=Od.length;i<l0;i++){var Pd=[];xd=Od[i];while(xd=xd.previousSibling){Pd.unshift(xd);}\nfor(var j=0,l1=Pd.length;j<l1;j++){xd=Pd[j];if(wa.attrMatch(xd,Md,Nd)){if(wd.match(xd))yd.push(xd);}\nyd=wa.getDescendantNodes(wd,xd,yd,Md,Nd);}}\nreturn yd;},true],'preceding-sibling':[true,function(wd,xd,yd,_,Qd,Rd,Sd){while(xd=xd.previousSibling){if(Rd&&xd.nodeType==1){Rd.reserveDelByNode(xd,Sd,true);}\nif(wd.match(xd)){yd.unshift(xd)}}\nreturn yd;}],self:[false,function(wd,xd,yd){if(wd.match(xd))yd.push(xd);return yd;}]};za.parse=function(Td){var Ud,test,step,token;if(Td.peek()=='.'){step=this.self();Td.next();}\nelse if(Td.peek()=='..'){step=this.parent();Td.next();}\nelse{if(Td.peek()=='@'){Ud='attribute';Td.next();if(Td.empty()){throw Error('missing attribute name');}}\nelse{if(Td.peek(1)=='::'){if(!/(?![0-9])[\\w]/.test(Td.peek().charAt(0))){throw Error('bad token: '+Td.next());}\nUd=Td.next();Td.next();if(!this.axises[Ud]){throw Error('invalid axis: '+Ud);}\nif(Td.empty()){throw Error('missing node name');}}\nelse{Ud='child';}}\ntoken=Td.peek();if(!/(?![0-9])[\\w]/.test(token.charAt(0))){if(token=='*'){test=sa.parse(Td)}\nelse{throw Error('bad token: '+Td.next());}}\nelse{if(Td.peek(1)=='('){if(!va.types[token]){throw Error('invalid node type: '+token);}\ntest=va.parse(Td)}\nelse{test=sa.parse(Td);}}\nstep=new za(Ud,test);}\nTa.parsePredicates(Td,step);return step;};za.self=function(){return new za('self',new va('node'));};za.parent=function(){return new za('parent',new va('node'));};za.prototype=new Ta();za.prototype.evaluate=function(Vd,Wd,Xd,Yd){var Zd=Vd.node;var $d=false;if(!Wd&&this.op=='//'){if(!this.needContextPosition&&this.axis=='child'){if(this.quickAttr){var ae=this.attrValueExpr?this.attrValueExpr.string(Vd):null;var be=wa.getDescendantNodes(this.test,Zd,new ta(),this.attrName,ae,Xd,Yd);be=this.evaluatePredicates(be,1);}\nelse{var be=wa.getDescendantNodes(this.test,Zd,new ta(),null,null,Xd,Yd);be=this.evaluatePredicates(be);}}\nelse{var ce=new za('descendant-or-self',new va('node'));var de=ce.evaluate(Vd,false,Xd,Yd).list();var be=null;ce.op='/';for(var i=0,l=de.length;i<l;i++){if(!be){be=this.evaluate(new Ia(de[i]),true);}\nelse{be.merge(this.evaluate(new Ia(de[i]),true));}}\nbe=be||new ta();}}\nelse{if(this.needContextPosition){Xd=null;Yd=null;}\nif(this.quickAttr){var ae=this.attrValueExpr?this.attrValueExpr.string(Vd):null;var be=this.func(this.test,Zd,new ta(),this.attrName,ae,Xd,Yd);be=this.evaluatePredicates(be,1);}\nelse{var be=this.func(this.test,Zd,new ta(),null,null,Xd,Yd);be=this.evaluatePredicates(be);}\nif(Xd){Xd.doDel();}}\nreturn be;};za.prototype.predicate=function(ee){this.predicates.push(ee);if(ee.needContextPosition||ee.datatype=='number'||ee.datatype=='void'){this.needContextPosition=true;}\nif(this._quickAttr&&this.predicates.length==1&&ee.quickAttr){var fe=ee.attrName; /*@cc_on @if(@_jscript)this.attrName=fe.toLowerCase();@else @*/ \nthis.attrName=fe;/*@end @*/ \nthis.attrValueExpr=ee.attrValueExpr;this.quickAttr=true;}};za.prototype.show=function(ge){ge=ge||'';var t='';t+=ge+'step: '+'\\n';ge+='    ';if(this.axis)t+=ge+'axis: '+this.axis+'\\n';t+=this.test.show(ge);if(this.predicates.length){t+=ge+'predicates: '+'\\n';ge+='    ';for(var i=0;i<this.predicates.length;i++){t+=this.predicates[i].show(ge);}}\nreturn t;};if(!window.NodeType&&window.defaultConfig)window.NodeType=null;va=function(he,je){this.name=he;this.literal=je;switch(he){case 'comment':this.type=8;break;case 'text':this.type=3;break;case 'processing-instruction':this.type=7;break;case 'node':this.type=0;break;}};va.types={'comment':1,'text':1,'processing-instruction':1,'node':1};va.parse=function(ke){var le,literal,ch;le=ke.next();ke.next();if(ke.empty()){throw Error('bad nodetype');}\nch=ke.peek().charAt(0);if(ch=='\"'||ch==\"'\"){literal=ra.parse(ke);}\nif(ke.empty()){throw Error('bad nodetype');}\nif(ke.next()!=')'){ke.back();throw Error('bad token '+ke.next());}\nreturn new va(le,literal);};va.prototype=new Ma();va.prototype.notOnlyElement=true;va.prototype.match=function(me){return!this.type||this.type==me.nodeType;};va.prototype.show=function(ne){ne=ne||'';var t='';t+=ne+'nodetype: '+this.type+'\\n';if(this.literal){ne+='    ';t+=this.literal.show(ne);}\nreturn t;};if(!window.NameTest&&window.defaultConfig)window.NameTest=null;sa=function(oe){this.name=oe.toLowerCase();};sa.parse=function(pe){if(pe.peek()!='*'&&pe.peek(1)==':'&&pe.peek(2)=='*'){return new sa(pe.next()+pe.next()+pe.next());}\nreturn new sa(pe.next());};sa.prototype=new Ma();sa.prototype.match=function(qe){var re=qe.nodeType;if(re==1||re==2){if(this.name=='*'||this.name==qe.nodeName.toLowerCase()){return true;}}\nreturn false;};sa.prototype.show=function(se){se=se||'';var t='';t+=se+'nametest: '+this.name+'\\n';return t;};if(!window.VariableReference&&window.defaultConfig)window.VariableReference=null;Ca=function(te){this.name=te.substring(1);};Ca.parse=function(ue){var ve=ue.next();if(ve.length<2){throw Error('unnamed variable reference');}\nreturn new Ca(ve)};Ca.prototype=new Ma();Ca.prototype.datatype='void';Ca.prototype.show=function(we){we=we||'';var t='';t+=we+'variable: '+this.name+'\\n';return t;};if(!window.Literal&&window.defaultConfig)window.Literal=null;ra=function(xe){this.text=xe.substring(1,xe.length-1);};ra.parse=function(ye){var ze=ye.next();if(ze.length<2){throw Error('unclosed literal string');}\nreturn new ra(ze)};ra.prototype=new Ma();ra.prototype.datatype='string';ra.prototype.evaluate=function(Ae){return this.text;};ra.prototype.show=function(Be){Be=Be||'';var t='';t+=Be+'literal: '+this.text+'\\n';return t;};if(!window.Number&&window.defaultConfig)window.Number=null;xa=function(Ce){this.digit=+Ce;};xa.parse=function(De){return new xa(De.next());};xa.prototype=new Ma();xa.prototype.datatype='number';xa.prototype.evaluate=function(Ee){return this.digit;};xa.prototype.show=function(Fe){Fe=Fe||'';var t='';t+=Fe+'number: '+this.digit+'\\n';return t;};if(!window.FunctionCall&&window.defaultConfig)window.FunctionCall=null;qa=function(Ge){var He=qa.funcs[Ge];if(!He)throw Error(Ge+' is not a function');this.name=Ge;this.func=He[0];this.args=[];this.datatype=He[1];if(He[2]){this.needContextPosition=true;}\nthis.needContextNodeInfo=He[3];this.needContextNode=this.needContextNodeInfo[0]};qa.funcs={'context-node':[function(){if(arguments.length!=0){throw Error('Function context-node expects ()');}\nvar ns;ns=new ta();ns.push(this.node);return ns;},'nodeset',false,[true]],'root-node':[function(){if(arguments.length!=0){throw Error('Function root-node expects ()');}\nvar ns,ctxn;ns=new ta();ctxn=this.node;if(ctxn.nodeType==9)ns.push(ctxn);else ns.push(ctxn.ownerDocument);return ns;},'nodeset',false,[]],last:[function(){if(arguments.length!=0){throw Error('Function last expects ()');}\nreturn this.last;},'number',true,[]],position:[function(){if(arguments.length!=0){throw Error('Function position expects ()');}\nreturn this.position;},'number',true,[]],count:[function(ns){if(arguments.length!=1||!(ns=ns.evaluate(this)).isNodeSet){throw Error('Function count expects (nodeset)');}\nreturn ns.length;},'number',false,[]],id:[function(s){var Ie,ns,i,id,elm,ctxn,doc;if(arguments.length!=1){throw Error('Function id expects (object)');}\nctxn=this.node;if(ctxn.nodeType==9)doc=ctxn;else doc=ctxn.ownerDocument; /*@cc_on \nall=doc.all;@*/s=s.string(this);Ie=s.split(/\\s+/);ns=new ta();for(i=0,l=Ie.length;i<l;i++){id=Ie[i]; /*@cc_on @if(@_jscript)elm=all[id];if(elm){if((!elm.length||elm.nodeType)&&id==elm.id){ns.push(elm)}\nelse if(elm.length){var Je=elm;for(var j=0,l0=Je.length;j<l0;j++){var Ke=Je[j];if(id==Ke.id){ns.push(Ke);break;}}}}@else @*/ \nelm=doc.getElementById(id);if(Da.opera&&elm&&elm.id!=id){var Je=doc.getElementsByName(id);for(var j=0,l0=Je.length;j<l0;j++){elm=Je[j];if(elm.id==id){ns.push(elm);}}}\nelse{if(elm)ns.push(elm)}/*@end @*/ }\nns.isSorted=false;return ns;},'nodeset',false,[]],'local-name':[function(ns){var nd;switch(arguments.length){case 0:nd=this.node;break;case 1:if((ns=ns.evaluate(this)).isNodeSet){nd=ns.first();break;}\ndefault:throw Error('Function local-name expects (nodeset?)');break;}\nreturn ''+nd.nodeName.toLowerCase();},'string',false,[true,false]],name:[function(ns){return qa.funcs['local-name'][0].apply(this,arguments);},'string',false,[true,false]],'namespace-uri':[function(ns){return '';},'string',false,[true,false]],string:[function(s){switch(arguments.length){case 0:s=wa.to('string',this.node);break;case 1:s=s.string(this);break;default:throw Error('Function string expects (object?)');break;}\nreturn s;},'string',false,[true,false]],concat:[function(s1,s2){if(arguments.length<2){throw Error('Function concat expects (string, string[, ...])');}\nfor(var t='',i=0,l=arguments.length;i<l;i++){t+=arguments[i].string(this);}\nreturn t;},'string',false,[]],'starts-with':[function(s1,s2){if(arguments.length!=2){throw Error('Function starts-with expects (string, string)');}\ns1=s1.string(this);s2=s2.string(this);return s1.indexOf(s2)==0;},'boolean',false,[]],contains:[function(s1,s2){if(arguments.length!=2){throw Error('Function contains expects (string, string)');}\ns1=s1.string(this);s2=s2.string(this);return s1.indexOf(s2)!=-1;},'boolean',false,[]],substring:[function(s,n1,n2){var a1,a2;s=s.string(this);n1=n1.number(this);switch(arguments.length){case 2:n2=s.length-n1+1;break;case 3:n2=n2.number(this);break;default:throw Error('Function substring expects (string, string)');break;}\nn1=Math.round(n1);n2=Math.round(n2);a1=n1-1;a2=n1+n2-1;if(a2==Infinity){return s.substring(a1<0?0:a1);}\nelse{return s.substring(a1<0?0:a1,a2)}},'string',false,[]],'substring-before':[function(s1,s2){var n;if(arguments.length!=2){throw Error('Function substring-before expects (string, string)');}\ns1=s1.string(this);s2=s2.string(this);n=s1.indexOf(s2);if(n==-1)return '';return s1.substring(0,n);},'string',false,[]],'substring-after':[function(s1,s2){if(arguments.length!=2){throw Error('Function substring-after expects (string, string)');}\ns1=s1.string(this);s2=s2.string(this);var n=s1.indexOf(s2);if(n==-1)return '';return s1.substring(n+s2.length);},'string',false,[]],'string-length':[function(s){switch(arguments.length){case 0:s=wa.to('string',this.node);break;case 1:s=s.string(this);break;default:throw Error('Function string-length expects (string?)');break;}\nreturn s.length;},'number',false,[true,false]],'normalize-space':[function(s){switch(arguments.length){case 0:s=wa.to('string',this.node);break;case 1:s=s.string(this);break;default:throw Error('Function normalize-space expects (string?)');break;}\nreturn s.replace(/\\s+/g,' ').replace(/^ /,'').replace(/ $/,'');},'string',false,[true,false]],translate:[function(s1,s2,s3){if(arguments.length!=3){throw Error('Function translate expects (string, string, string)');}\ns1=s1.string(this);s2=s2.string(this);s3=s3.string(this);var Le=[];for(var i=0,l=s2.length;i<l;i++){var ch=s2.charAt(i);if(!Le[ch])Le[ch]=s3.charAt(i)||'';}\nfor(var t='',i=0,l=s1.length;i<l;i++){var ch=s1.charAt(i);var Me=Le[ch]\nt+=(Me!=ca)?Me:ch;}\nreturn t;},'string',false,[]],'boolean':[function(b){if(arguments.length!=1){throw Error('Function boolean expects (object)');}\nreturn b.bool(this)},'boolean',false,[]],not:[function(b){if(arguments.length!=1){throw Error('Function not expects (object)');}\nreturn!b.bool(this)},'boolean',false,[]],'true':[function(){if(arguments.length!=0){throw Error('Function true expects ()');}\nreturn true;},'boolean',false,[]],'false':[function(){if(arguments.length!=0){throw Error('Function false expects ()');}\nreturn false;},'boolean',false,[]],lang:[function(s){return false;},'boolean',false,[]],number:[function(n){switch(arguments.length){case 0:n=wa.to('number',this.node);break;case 1:n=n.number(this);break;default:throw Error('Function number expects (object?)');break;}\nreturn n;},'number',false,[true,false]],sum:[function(ns){var Ne,n,i,l;if(arguments.length!=1||!(ns=ns.evaluate(this)).isNodeSet){throw Error('Function sum expects (nodeset)');}\nNe=ns.list();n=0;for(i=0,l=Ne.length;i<l;i++){n+=wa.to('number',Ne[i]);}\nreturn n;},'number',false,[]],floor:[function(n){if(arguments.length!=1){throw Error('Function floor expects (number)');}\nn=n.number(this);return Math.floor(n);},'number',false,[]],ceiling:[function(n){if(arguments.length!=1){throw Error('Function ceiling expects (number)');}\nn=n.number(this);return Math.ceil(n);},'number',false,[]],round:[function(n){if(arguments.length!=1){throw Error('Function round expects (number)');}\nn=n.number(this);return Math.round(n);},'number',false,[]]};qa.parse=function(Oe){var Pe,func=new qa(Oe.next());Oe.next();while(Oe.peek()!=')'){if(Oe.empty()){throw Error('missing function argument list');}\nPe=oa.parse(Oe);func.arg(Pe);if(Oe.peek()!=',')break;Oe.next();}\nif(Oe.empty()){throw Error('unclosed function argument list');}\nif(Oe.next()!=')'){Oe.back();throw Error('bad token: '+Oe.next());}\nreturn func};qa.prototype=new Ma();qa.prototype.evaluate=function(Qe){return this.func.apply(Qe,this.args);};qa.prototype.arg=function(Re){this.args.push(Re);if(Re.needContextPosition){this.needContextPosition=true;}\nvar Se=this.args;if(Re.needContextNode){Se.needContexNode=true;}\nthis.needContextNode=Se.needContextNode||this.needContextNodeInfo[Se.length];};qa.prototype.show=function(Te){Te=Te||'';var t='';t+=Te+'function: '+this.name+'\\n';Te+='    ';if(this.args.length){t+=Te+'arguments: '+'\\n';Te+='    ';for(var i=0;i<this.args.length;i++){t+=this.args[i].show(Te);}}\nreturn t;}; /*@cc_on @if(@_jscript)var Ue=function(Ve,We,Xe,Ye){this.node=Ve;this.nodeType=Ve.nodeType;this.sourceIndex=We;this.subIndex=Xe;this.attributeName=Ye||'';this.order=String.fromCharCode(We)+String.fromCharCode(Xe)+Ye;};Ue.prototype.toString=function(){return this.order;};@else @*/ \nvar Ze={uuid:1,get:function($e){return $e.__ba||($e.__ba=this.uuid++);}};/*@end @*/ \nif(!window.NodeSet&&window.defaultConfig)window.NodeSet=null;ta=function(){this.length=0;this.nodes=[];this.seen={};this.idIndexMap=null;this.reserveDels=[];};ta.prototype.isNodeSet=true;ta.prototype.isSorted=true; /*@_cc_on\nta.prototype.shortcut=true;@*/ta.prototype.merge=function(af){this.isSorted=false;if(af.only){return this.push(af.only);}\nif(this.only){var bf=this.only;delete this.only;this.push(bf);this.length--;}\nvar cf=af.nodes;for(var i=0,l=cf.length;i<l;i++){this._add(cf[i]);}};ta.prototype.sort=function(){if(this.only)return;if(this.sortOff)return;if(!this.isSorted){this.isSorted=true;this.idIndexMap=null; /*@cc_on \nif(this.shortcut){this.nodes.sort();}\nelse{this.nodes.sort(function(a,b){var df;df=a.sourceIndex-b.sourceIndex;if(df==0)return a.subIndex-a.subIndex;else return df;});}\nreturn;@*/var ef=this.nodes;ef.sort(function(a,b){if(a==b)return 0;if(a.compareDocumentPosition){var ff=a.compareDocumentPosition(b);if(ff&2)return 1;if(ff&4)return -1;return 0;}\nelse{var gf=a,node2=b,ancestor1=a,ancestor2=b,deep1=0,deep2=0;while(ancestor1=ancestor1.parentNode)deep1++;while(ancestor2=ancestor2.parentNode)deep2++;if(deep1>deep2){while(deep1--!=deep2)gf=gf.parentNode;if(gf==node2)return 1;}\nelse if(deep2>deep1){while(deep2--!=deep1)node2=node2.parentNode;if(gf==node2)return -1;}\nwhile((ancestor1=gf.parentNode)!=(ancestor2=node2.parentNode)){gf=ancestor1;node2=ancestor2;}\nwhile(gf=gf.nextSibling)if(gf==node2)return -1;return 1;}});}}; /*@cc_on @if(@_jscript)ta.prototype.sourceOffset=1;ta.prototype.subOffset=2;ta.prototype.createWrapper=function(hf){var jf,child,attributes,attributesLength,sourceIndex,subIndex,attributeName;sourceIndex=hf.sourceIndex;if(typeof sourceIndex!='number'){type=hf.nodeType;switch(type){case 2:jf=hf.parentNode;sourceIndex=hf.parentSourceIndex;subIndex=-1;attributeName=hf.nodeName;break;case 9:subIndex=-2;sourceIndex=-1;break;default:child=hf;subIndex=0;do{subIndex++;sourceIndex=child.sourceIndex;if(sourceIndex){jf=child;child=child.lastChild;if(!child){child=jf;break;}\nsubIndex++;}}\nwhile(child=child.previousSibling);if(!sourceIndex){sourceIndex=hf.parentNode.sourceIndex;}\nbreak;}}\nelse{subIndex=-2;}\nsourceIndex+=this.sourceOffset;subIndex+=this.subOffset;return new Ue(hf,sourceIndex,subIndex,attributeName);};ta.prototype.reserveDelBySourceIndexAndSubIndex=function(kf,lf,mf,nf){var of=this.createIdIndexMap();var pf;if((of=of[kf])&&(pf=of[lf])){if(nf&&(this.length-mf-1)>pf||!nf&&mf<pf){var qf={value:pf,order:String.fromCharCode(pf),toString:function(){return this.order},valueOf:function(){return this.value}};this.reserveDels.push(qf);}}};@else @*/ \nta.prototype.reserveDelByNodeID=function(id,rf,sf){var tf=this.createIdIndexMap();var uf;if(uf=tf[id]){if(sf&&(this.length-rf-1)>uf||!sf&&rf<uf){var vf={value:uf,order:String.fromCharCode(uf),toString:function(){return this.order},valueOf:function(){return this.value}};this.reserveDels.push(vf);}}};/*@end @*/ \nta.prototype.reserveDelByNode=function(wf,xf,yf){ /*@cc_on @if(@_jscript)wf=this.createWrapper(wf);this.reserveDelBySourceIndexAndSubIndex(wf.sourceIndex,wf.subIndex,xf,yf);@else @*/ \nthis.reserveDelByNodeID(Ze.get(wf),xf,yf);/*@end @*/ };ta.prototype.doDel=function(){if(!this.reserveDels.length)return;if(this.length<0x10000){var zf=this.reserveDels.sort(function(a,b){return b-a});}\nelse{var zf=this.reserveDels.sort(function(a,b){return b-a});}\nfor(var i=0,l=zf.length;i<l;i++){this.del(zf[i]);}\nthis.reserveDels=[];this.idIndexMap=null;};ta.prototype.createIdIndexMap=function(){if(this.idIndexMap){return this.idIndexMap;}\nelse{var Af=this.idIndexMap={};var Bf=this.nodes;for(var i=0,l=Bf.length;i<l;i++){var Cf=Bf[i]; /*@cc_on @if(@_jscript)var Df=Cf.sourceIndex;var Ef=Cf.subIndex;if(!Af[Df])Af[Df]={};Af[Df][Ef]=i;@else @*/ \nvar id=Ze.get(Cf);Af[id]=i;/*@end @*/ }\nreturn Af;}};ta.prototype.del=function(Ff){this.length--;if(this.only){delete this.only;}\nelse{var Gf=this.nodes.splice(Ff,1)[0];if(this._first==Gf){delete this._first;delete this._firstSourceIndex;delete this._firstSubIndex;} /*@cc_on @if(@_jscript)delete this.seen[Gf.sourceIndex][Gf.subIndex];@else @*/ \ndelete this.seen[Ze.get(Gf)];/*@end @*/ }};ta.prototype.delDescendant=function(Hf,If){if(this.only)return;var Jf=Hf.nodeType;if(Jf!=1&&Jf!=9)return;if(Da.applewebkit2)return;if(!Hf.contains){if(Jf==1){var Kf=Hf;Hf={contains:function(Lf){return Lf.compareDocumentPosition(Kf)&8;}};}\nelse{Hf={contains:function(){return true;}};}}\nvar Mf=this.nodes;for(var i=If+1;i<Mf.length;i++){ /*@cc_on @if(@_jscript)if(Mf[i].node.nodeType==1&&Hf.contains(Mf[i].node)){@else @*/ \nif(Hf.contains(Mf[i])){/*@end @*/ \nthis.del(i);i--;}}};ta.prototype._add=function(Nf,Of){ /*@cc_on @if(@_jscript)var Pf,firstSourceIndex,firstSubIndex,sourceIndex,subIndex,attributeName;sourceIndex=Nf.sourceIndex;subIndex=Nf.subIndex;attributeName=Nf.attributeName;seen=this.seen;seen=seen[sourceIndex]||(seen[sourceIndex]={});if(Nf.nodeType==2){seen=seen[subIndex]||(seen[subIndex]={});if(seen[attributeName]){return true;}\nseen[attributeName]=true;}\nelse{if(seen[subIndex]){return true;}\nseen[subIndex]=true;}\nif(sourceIndex>=0x10000||subIndex>=0x10000){this.shortcut=false;}\nif(this._first||this.nodes.length==0){Pf=this._first;firstSourceIndex=this._firstSourceIndex;firstSubIndex=this._firstSubIndex;if(!Pf||firstSourceIndex>sourceIndex||(firstSourceIndex==sourceIndex&&firstSubIndex>subIndex)){this._first=Nf;this._firstSourceIndex=sourceIndex;this._firstSubIndex=subIndex}}@else @*/ \nvar Qf=this.seen;var id=Ze.get(Nf);if(Qf[id])return true;Qf[id]=true;/*@end @*/ \nthis.length++;if(Of)this.nodes.unshift(Nf);else this.nodes.push(Nf);};ta.prototype.unshift=function(Rf){if(!this.length){this.length++;this.only=Rf;return}\nif(this.only){var Sf=this.only;delete this.only;this.unshift(Sf);this.length--;} /*@cc_on \nRf=this.createWrapper(Rf);@*/return this._add(Rf,true);};ta.prototype.push=function(Tf){if(!this.length){this.length++;this.only=Tf;return;}\nif(this.only){var Uf=this.only;delete this.only;this.push(Uf);this.length--;} /*@cc_on \nTf=this.createWrapper(Tf);@*/return this._add(Tf);};ta.prototype.first=function(){if(this.only)return this.only; /*@cc_on \nif(this._first)return this._first.node;if(this.nodes.length>1)this.sort();var Vf=this.nodes[0];return Vf?Vf.node:ca;@*/if(this.nodes.length>1)this.sort();return this.nodes[0];};ta.prototype.list=function(){if(this.only)return[this.only];this.sort(); /*@cc_on \nvar i,l,Mf,results;Mf=this.nodes;results=[];for(i=0,l=Mf.length;i<l;i++){results.push(Mf[i].node);}\nreturn results;@*/return this.nodes;};ta.prototype.string=function(){var Wf=this.only||this.first();return Wf?wa.to('string',Wf):'';};ta.prototype.bool=function(){return!!(this.length||this.only);};ta.prototype.number=function(){return+this.string();};ta.prototype.iterator=function(Xf){this.sort();var Yf=this;if(!Xf){var Zf=0;return function(){if(Yf.only&&Zf++==0)return Yf.only; /*@cc_on @if(@_jscript)var $f=Yf.nodes[Zf++];if($f)return $f.node;return ca;@else @*/ \nreturn Yf.nodes[Zf++];/*@end @*/ };}\nelse{var Zf=0;return function(){var ag=Yf.length-(Zf++)-1;if(Yf.only&&ag==0)return Yf.only; /*@cc_on @if(@_jscript)var bg=Yf.nodes[ag];if(bg)return bg.node;return ca;@else @*/ \nreturn Yf.nodes[ag];/*@end @*/ };}};var cg=function(dg){dg=dg||this;var eg=dg.document;var ca=dg.undefined;dg.XPathExpression=function(fg){if(!fg.length){throw dg.Error('no expression');}\nvar gg=this.lexer=Ea(fg);if(gg.empty()){throw dg.Error('no expression');}\nthis.expr=oa.parse(gg);if(!gg.empty()){throw dg.Error('bad token: '+gg.next());}};dg.XPathExpression.prototype.evaluate=function(hg,ig){return new dg.XPathResult(this.expr.evaluate(new Ia(hg)),ig);};dg.XPathResult=function(jg,kg){if(kg==0){switch(typeof jg){case 'object':kg++;case 'boolean':kg++;case 'string':kg++;case 'number':kg++;}}\nthis.resultType=kg;switch(kg){case 1:this.numberValue=jg.isNodeSet?jg.number():+jg;return;case 2:this.stringValue=jg.isNodeSet?jg.string():''+jg;return;case 3:this.booleanValue=jg.isNodeSet?jg.bool():!!jg;return;case 4:case 5:case 6:case 7:this.nodes=jg.list();this.snapshotLength=jg.length;this.index=0;this.invalidIteratorState=false;break;case 8:case 9:this.singleNodeValue=jg.first();return;}};dg.XPathResult.prototype.iterateNext=function(){return this.nodes[this.index++]};dg.XPathResult.prototype.snapshotItem=function(i){return this.nodes[i]};dg.XPathResult.ANY_TYPE=0;dg.XPathResult.NUMBER_TYPE=1;dg.XPathResult.STRING_TYPE=2;dg.XPathResult.BOOLEAN_TYPE=3;dg.XPathResult.UNORDERED_NODE_ITERATOR_TYPE=4;dg.XPathResult.ORDERED_NODE_ITERATOR_TYPE=5;dg.XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE=6;dg.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE=7;dg.XPathResult.ANY_UNORDERED_NODE_TYPE=8;dg.XPathResult.FIRST_ORDERED_NODE_TYPE=9;eg.createExpression=function(lg){return new dg.XPathExpression(lg,null);};eg.evaluate=function(mg,ng,_,og){return eg.createExpression(mg,null).evaluate(ng,og);};};var pg;if(ea.targetFrame){var qg=document.getElementById(ea.targetFrame);if(qg)pg=qg.contentWindow;}\nif(ea.exportInstaller){window.install=cg;}\nif(!ea.hasNative||!ea.useNative){cg(pg||window);}})();\n#+END_SRC\n"
  },
  {
    "path": "03-pedestal-service/pedestal-service-skeleton.org",
    "content": "#+TITLE: Pedestal Service, in Org literate programming form\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+STARTUP: overview hidestars\n#+PROPERTY: mkdirp yes\n\n\nThis is a literate programming (LP) file for a Pedestal Service\n(back-end, multi-thread per HTTP request), in Emacs Org mode format.\nTo start building your Service, you'd likely begin by doing\nsearch-and-replace to update the default names of \"mysvc\" below; then\nsave this LP file to the top-level of your project directory.  NOTE\nthat the :tangle paths specified below assume this LP file sits above\n(not in) the directory containing the Pedestal Service; if that's not\nwhat you want, drop the leading \"mysvc/\" in the :tangle paths.\n\n\n* Project meta\n** Leiningen configuration\n#+BEGIN_SRC clojure :tangle mysvc/project.clj\n(defproject mysvc \"0.0.1-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"http://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"http://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.5.1\"]\n                 [io.pedestal/pedestal.service \"0.2.1\"]\n                 [io.pedestal/pedestal.service-tools \"0.2.1\"]\n\n                 ;; Remove this line and uncomment the next line to\n                 ;; use Tomcat instead of Jetty:\n                 [io.pedestal/pedestal.jetty \"0.2.1\"]\n                 ;; [io.pedestal/pedestal.tomcat \"0.2.1\"]\n                 ]\n  :min-lein-version \"2.0.0\"\n  :resource-paths [\"config\", \"resources\"]\n  :aliases {\"run-dev\" [\"trampoline\" \"run\" \"-m\" \"mysvc.server/run-dev\"]}\n  :repl-options  {:init-ns user\n                  :init (try\n                          (use 'io.pedestal.service-tools.dev)\n                          (require 'mysvc.service)\n                          ;; Nasty trick to get around being unable to reference non-clojure.core symbols in :init\n                          (eval '(init mysvc.service/service #'mysvc.service/routes))\n                          (catch Throwable t\n                            (println \"ERROR: There was a problem loading io.pedestal.service-tools.dev\")\n                            (clojure.stacktrace/print-stack-trace t)\n                            (println)))\n                  :welcome (println \"Welcome to pedestal-service! Run (tools-help) to see a list of useful functions.\")}\n  :main ^{:skip-aot true} mysvc.server)\n\n#+END_SRC\n\n** README\n#+BEGIN_SRC markdown :tangle mysvc/README.md\n# mysvc\n\nFIXME\n\n## Getting Started\n\n1. Start the application: `lein run`\n2. Go to [localhost:8080](http://localhost:8080/) to see: `Hello World!`\n3. Read your app's source code at src/mysvc/service.clj. Explore the docs of functions\n   that define routes and responses.\n4. Run your app's tests with `lein test`. Read the tests at test/mysvc/service_test.clj.\n5. Learn more! See the [Links section below](#links).\n\n## Configuration\n\nTo configure logging see config/logback.xml. By default, the app logs to stdout and logs/.\nTo learn more about configuring Logback, read its [documentation](http://logback.qos.ch/documentation.html).\n\n## Links\n- [Other examples](https://github.com/pedestal/samples)\n\n#+END_SRC\n\n** User/REPL configuration\n#+BEGIN_SRC clojure :tangle mysvc/config/user.clj\n;; Empty file to permit project.clj :repl-options {:init user} to work\n\n#+END_SRC\n\n** Logback configuration\n#+BEGIN_SRC xml :tangle mysvc/config/logback.xml\n<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->\n<configuration scan=\"true\" scanPeriod=\"10 seconds\">\n\n  <!-- Simple file output -->\n  <appender name=\"FILE\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\">\n    <!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder -->\n    <encoder>\n      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n    </encoder>\n\n    <rollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\">\n      <!-- rollover daily -->\n      <fileNamePattern>logs/mysvc-%d{yyyy-MM-dd}.%i.log</fileNamePattern>\n      <timeBasedFileNamingAndTriggeringPolicy\n          class=\"ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP\">\n        <!-- or whenever the file size reaches 64 MB -->\n        <maxFileSize>64 MB</maxFileSize>\n      </timeBasedFileNamingAndTriggeringPolicy>\n    </rollingPolicy>\n\n    <!-- Safely log to the same file from multiple JVMs. Degrades performance! -->\n    <prudent>true</prudent>\n  </appender>\n\n\n  <!-- Console output -->\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder -->\n    <encoder>\n      <pattern>%-5level %logger{36} - %msg%n</pattern>\n    </encoder>\n    <!-- Only log level INFO and above -->\n    <filter class=\"ch.qos.logback.classic.filter.ThresholdFilter\">\n      <level>INFO</level>\n    </filter>\n  </appender>\n\n\n  <!-- Enable FILE and STDOUT appenders for all log messages.\n       By default, only log at level INFO and above. -->\n  <root level=\"INFO\">\n    <appender-ref ref=\"FILE\" />\n    <appender-ref ref=\"STDOUT\" />\n  </root>\n\n  <!-- For loggers in the these namespaces, log at all levels. -->\n  <logger name=\"user\" level=\"ALL\" />\n  <!-- To log pedestal internals, enable this and change ThresholdFilter to DEBUG\n    <logger name=\"pedestal\" level=\"ALL\" />\n  -->\n\n</configuration>\n\n#+END_SRC\n\n\n* Code and tests\n** The web service\n#+BEGIN_SRC clojure :tangle mysvc/src/mysvc/service.clj\n(ns mysvc.service\n    (:require [io.pedestal.service.http :as bootstrap]\n              [io.pedestal.service.http.route :as route]\n              [io.pedestal.service.http.body-params :as body-params]\n              [io.pedestal.service.http.route.definition :refer [defroutes]]\n              [ring.util.response :as ring-resp]))\n\n(defn about-page\n  [request]\n  (ring-resp/response (format \"Clojure %s\" (clojure-version))))\n\n(defn home-page\n  [request]\n  (ring-resp/response \"Hello World!\"))\n\n(defroutes routes\n  [[[\"/\" {:get home-page}\n     ;; Set default interceptors for /about and any other paths under /\n     ^:interceptors [(body-params/body-params) bootstrap/html-body]\n     [\"/about\" {:get about-page}]]]])\n\n;; You can use this fn or a per-request fn via io.pedestal.service.http.route/url-for\n(def url-for (route/url-for-routes routes))\n\n;; Consumed by mysvc.server/create-server\n(def service {:env :prod\n              ;; You can bring your own non-default interceptors. Make\n              ;; sure you include routing and set it up right for\n              ;; dev-mode. If you do, many other keys for configuring\n              ;; default interceptors will be ignored.\n              ;; :bootstrap/interceptors []\n              ::bootstrap/routes routes\n\n              ;; Uncomment next line to enable CORS support, add\n              ;; string(s) specifying scheme, host and port for\n              ;; allowed source(s):\n              ;;\n              ;; \"http://localhost:8080\"\n              ;;\n              ;;::bootstrap/allowed-origins [\"scheme://host:port\"]\n\n              ;; Root for resource interceptor that is available by default.\n              ::bootstrap/resource-path \"/public\"\n\n              ;; Either :jetty or :tomcat (see comments in project.clj\n              ;; to enable Tomcat)\n              ;;::bootstrap/host \"localhost\"\n              ::bootstrap/type :jetty\n              ::bootstrap/port 8080})\n\n#+END_SRC\n\n*** Tests\n#+BEGIN_SRC clojure :tangle mysvc/test/mysvc/service_test.clj\n(ns mysvc.service-test\n  (:require [clojure.test :refer :all]\n            [io.pedestal.service.test :refer :all]\n            [io.pedestal.service.http :as bootstrap]\n            [mysvc.service :as service]))\n\n(def service\n  (::bootstrap/service-fn (bootstrap/create-servlet service/service)))\n\n(deftest home-page-test\n  (is (=\n       (:body (response-for service :get \"/\"))\n       \"Hello World!\"))\n  (is (=\n       (:headers (response-for service :get \"/\"))\n       {\"Content-Type\" \"text/html;charset=UTF-8\"})))\n\n(deftest about-page-test\n  (is (.contains\n       (:body (response-for service :get \"/about\"))\n       \"Clojure 1.5\"))\n  (is (=\n       (:headers (response-for service :get \"/about\"))\n       {\"Content-Type\" \"text/html;charset=UTF-8\"})))\n\n#+END_SRC\n\n** Server/servlet definition\n#+BEGIN_SRC clojure :tangle mysvc/src/mysvc/server.clj\n(ns mysvc.server\n  (:gen-class) ; for -main method in uberjar\n  (:require [io.pedestal.service-tools.server :as server]\n            [mysvc.service :as service]\n            [io.pedestal.service-tools.dev :as dev]))\n\n(defn run-dev\n  \"The entry-point for 'lein run-dev'\"\n  [& args]\n  (dev/init service/service #'service/routes)\n  (apply dev/-main args))\n\n;; To implement your own server, copy io.pedestal.service-tools.server and\n;; customize it.\n\n(defn -main\n  \"The entry-point for 'lein run'\"\n  [& args]\n  (server/init service/service)\n  (apply server/-main args))\n\n;; Fns for use with io.pedestal.servlet.ClojureVarServlet\n\n(defn servlet-init [this config]\n  (server/init service/service)\n  (server/servlet-init this config))\n\n(defn servlet-destroy [this]\n  (server/servlet-destroy this))\n\n(defn servlet-service [this servlet-req servlet-resp]\n  (server/servlet-service this servlet-req servlet-resp))\n\n#+END_SRC\n"
  },
  {
    "path": "05-luminus-site/luminus-site-skeleton.org",
    "content": "#+TITLE: Luminus/Clojure Website Template, in Org/LP Format\n#+AUTHOR: Kai Wu\n#+EMAIL: k@limist.com\n#+LANGUAGE: en\n#+STARTUP: align hidestars lognotestate\n#+PROPERTY: mkdirp yes\n\n\n* Introduction\nThis is the Emacs [[http://orgmode.org][Org mode]] literate-programming single file template\nfor a web application using the Luminus \"framework.\"  For the\nstructure/files below, I used the command,\n=lein new luminus mysite +cljs +site +http-kit=\n\n** Useful Luminus information/links\nTaken from the Luminus-provided file at\n=mysite/resources/public/md/docs.md=\n\n1. [[http://www.luminusweb.net/docs/html_templating.md][HTML templating]]\n2. [[http://www.luminusweb.net/docs/database.md][Accessing the database]]\n3. [[http://www.luminusweb.net/docs/static_resources.md][Serving static resources]]\n4. [[http://www.luminusweb.net/docs/responses.md][Setting response types]]\n5. [[http://www.luminusweb.net/docs/routes.md][Defining routes]]\n6. [[http://www.luminusweb.net/docs/middleware.md][Adding middleware]]\n7. [[http://www.luminusweb.net/docs/sessions_cookies.md][Sessions and cookies]]\n8. [[http://www.luminusweb.net/docs/security.md][Security]]\n9. [[http://www.luminusweb.net/docs/deployment.md][Deploying the application]]\n\n** What files/directories are NOT included in this =.org= file?\n+ Everything under =mysite/resources= such as CSS, fonts, images, JS.\n  Since those files are not tangled/produced from here, you'll see the\n  =resources/= subdir already tracked in the git repository.\n\n\n* Project meta\n** Main configuration\nAs of [2013-10-29 Tue], the starting =project.clj= produced by the\nLuminus template used an indentation style that's unorthodox; the\nversion below differs with the Luminus one only in indentation.\n\n#+BEGIN_SRC clojure :tangle mysite/project.clj\n(defproject\n  mysite \"0.1.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.5.1\"]\n                 [lib-noir \"0.7.4\"]\n                 [compojure \"1.1.5\"]\n                 [ring-server \"0.3.0\"]\n                 [selmer \"0.5.1\"]\n                 [com.taoensso/timbre \"2.6.3\"]\n                 [com.postspectacular/rotor \"0.1.0\"]\n                 [com.taoensso/tower \"1.7.1\"]\n                 [markdown-clj \"0.9.33\"]\n                 [com.h2database/h2 \"1.3.173\"]\n                 [korma \"0.3.0-RC6\"]\n                 [log4j \"1.2.17\" :exclusions [javax.mail/mail\n                                              javax.jms/jms\n                                              com.sun.jdmk/jmxtools\n                                              com.sun.jmx/jmxri]]\n                 [http-kit \"2.1.11\"]\n                 [org.clojure/clojurescript \"0.0-1934\"]\n                 [domina \"1.0.2\"]\n                 [prismatic/dommy \"0.1.2\"]\n                 [cljs-ajax \"0.2.0\"]]\n  :cljsbuild {:builds [{:source-paths [\"src-cljs\"],\n                        :compiler {:pretty-print false,\n                                   :output-to \"resources/public/js/site.js\",\n                                   :optimizations :advanced}}]}\n  :ring {:handler mysite.handler/app,\n         :init mysite.handler/init,\n         :destroy mysite.handler/destroy}\n  :profiles {:production {:ring {:open-browser? false, :stacktraces? false, :auto-reload? false}},\n             :dev {:dependencies [[ring-mock \"0.1.5\"] [ring/ring-devel \"1.2.0\"]]}}\n  :url \"http://example.com/FIXME\"\n  :aot all\n  :main mysite.core\n  :plugins [[lein-ring \"0.8.7\"] [lein-cljsbuild \"0.3.3\"]]\n  :description \"FIXME: write description\"\n  :min-lein-version \"2.0.0\")\n#+END_SRC\n\n** Procfile, for Heroku deployment\nIf you want to use this, change the =:tangle no= below to \n=:tangle mysite/Procfile=\n\n#+BEGIN_SRC text :tangle no\nweb: lein with-profile production trampoline ring server\n#+END_SRC\n\n** The README\nOr you could just do your documentation here in this Org file, which\nis superior to Markdown because Org has powerful structural editing.\n\n#+BEGIN_SRC markdown :tangle mysite/README.md\n# mysite\n\nFIXME\n\n## Prerequisites\n\nYou will need [Leiningen][1] 2.0 or above installed.\n\n[1]: https://github.com/technomancy/leiningen\n\n## Running\n\nTo start a web server for the application, run:\n\n    lein ring server\n\n## License\n\nCopyright © 2013 FIXME\n\n#+END_SRC\n\n** =.gitignore=\n#+BEGIN_SRC shell :tangle mysite/.gitignore\n/target\n/lib\n/classes\n/checkouts\npom.xml\n*.jar\n*.class\n/.lein-*\n/.env\n\n# Ignore all files tangled from this Org/LP file:\nproject.clj\nREADME.md\nProcfile\nsrc/\nsrc-cljs/\ntest/\n#+END_SRC\n\n\n* Code and tests\n** log4j configuration, for Korma\nNote that for application/Clojure-level logging we use [[https://github.com/ptaoussanis/timbre][Timbre]].\n\nNote the header argument of =:padline no= for XML files is needed to\navoid an error in XML parsing.\n\n#+BEGIN_SRC xml :tangle mysite/src/log4j.xml :padline no\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">\n<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\">\n  <logger name=\"com.mchange\">\n    <level value=\"WARN\"/>\n  </logger>\n</log4j:configuration>\n\n#+END_SRC\n\n** Server-side\n*** The core: server definition\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/core.clj\n(ns mysite.core\n  (:require [mysite.handler :refer [app]]\n            [ring.middleware.reload :as reload]\n            [org.httpkit.server :as http-kit]\n            [taoensso.timbre :as timbre])\n  (:gen-class))\n\n(defn dev? [args] (some #{\"-dev\"} args))\n\n(defn port [args]\n  (if-let [port (first (remove #{\"-dev\"} args))]\n    (Integer/parseInt port)\n    3000))\n\n(defn -main [& args]\n  (http-kit/run-server\n    (if (dev? args) (reload/wrap-reload app) app)\n    {:port (port args)})\n  (timbre/info \"server started on port\"))\n\n#+END_SRC\n\n**** Control the server from the REPL\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/repl.clj\n(ns mysite.repl\n  (:use mysite.handler\n        ring.server.standalone\n        [ring.middleware file-info file]))\n\n(defonce server (atom nil))\n\n(defn get-handler []\n  ;; #'app expands to (var app) so that when we reload our code,\n  ;; the server is forced to re-resolve the symbol in the var\n  ;; rather than having its own copy. When the root binding\n  ;; changes, the server picks it up without having to restart.\n  (-> #'app\n    ; Makes static assets in $PROJECT_DIR/resources/public/ available.\n    (wrap-file \"resources\")\n    ; Content-Type, Content-Length, and Last Modified headers for files in body\n    (wrap-file-info)))\n\n(defn start-server\n  \"used for starting the server in development mode from REPL\"\n  [& [port]]\n  (let [port (if port (Integer/parseInt port) 3000)]\n    (reset! server\n            (serve (get-handler)\n                   {:port port\n                    :init init\n                    :auto-reload? true\n                    :destroy destroy\n                    :join? false}))\n    (println (str \"You can view the site at http://localhost:\" port))))\n\n(defn stop-server []\n  (.stop @server)\n  (reset! server nil))\n\n#+END_SRC\n\n*** Handler: base routes, app-level config\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/handler.clj\n(ns mysite.handler\n  (:require [compojure.core :refer [defroutes]]\n            [mysite.routes.home :refer [home-routes]]\n            [noir.util.middleware :as middleware]\n            [compojure.route :as route]\n            [taoensso.timbre :as timbre]\n            [com.postspectacular.rotor :as rotor]\n            [mysite.routes.auth :refer [auth-routes]]\n            [mysite.models.schema :as schema]\n            [mysite.routes.cljsexample :refer [cljs-routes]]))\n\n(defroutes app-routes\n  (route/resources \"/\")\n  (route/not-found \"Not Found\"))\n\n(defn init\n  \"init will be called once when\n   app is deployed as a servlet on\n   an app server such as Tomcat\n   put any initialization code here\"\n  []\n  (timbre/set-config!\n    [:appenders :rotor]\n    {:min-level :info,\n     :enabled? true,\n     :async? false,\n     :max-message-per-msecs nil,\n     :fn rotor/append})\n  (timbre/set-config!\n    [:shared-appender-config :rotor]\n    {:path \"mysite.log\", :max-size (* 512 1024), :backlog 10})\n  (if-not (schema/initialized?) (schema/create-tables))\n  (timbre/info \"mysite started successfully\"))\n\n(defn destroy\n  \"destroy will be called when your application\n   shuts down, put any clean up code here\"\n  []\n  (timbre/info \"mysite is shutting down...\"))\n\n(def app\n (middleware/app-handler\n   [cljs-routes auth-routes home-routes app-routes]\n   :middleware\n   []\n   :access-rules\n   []\n   :formats\n   [:json-kw :edn]))\n\n#+END_SRC\n\n**** Tests\n#+BEGIN_SRC clojure :tangle mysite/test/mysite/test/handler.clj\n(ns mysite.test.handler\n  (:use clojure.test\n        ring.mock.request\n        mysite.handler))\n\n(deftest test-app\n  (testing \"main route\"\n    (let [response (app (request :get \"/\"))]\n      (is (= (:status response) 200))\n      (is (= (:body response)\n             \"<html>\\n    <head>\\n        <title>Welcome to mysite</title>\\n        <link href=\\\"/css/screen.css\\\" rel=\\\"stylesheet\\\" type=\\\"text/css\\\"></link>\\n    </head>\\n    <body>\\n        <div class=\\\"navbar navbar-fixed-top navbar-inverse\\\">\\n            <ul class=\\\"nav\\\">\\n                <li>\\n                    <a href=\\\"/\\\">Home</a>\\n                </li>\\n                <li>\\n                    <a href=\\\"/about\\\">About</a>\\n                </li>\\n            </ul>\\n        </div>\\n        <div id=\\\"content\\\">\\n        <h1>Welcome to mysite</h1>\\n        \\n<h2>Some links to get started</h2><ol><li><a href='http://www.luminusweb.net/docs/html&#95;templating.md'>HTML templating</a></li><li><a href='http://www.luminusweb.net/docs/database.md'>Accessing the database</a></li><li><a href='http://www.luminusweb.net/docs/static&#95;resources.md'>Serving static resources</a></li><li><a href='http://www.luminusweb.net/docs/responses.md'>Setting response types</a></li><li><a href='http://www.luminusweb.net/docs/routes.md'>Defining routes</a></li><li><a href='http://www.luminusweb.net/docs/middleware.md'>Adding middleware</a></li><li><a href='http://www.luminusweb.net/docs/sessions&#95;cookies.md'>Sessions and cookies</a></li><li><a href='http://www.luminusweb.net/docs/security.md'>Security</a></li><li><a href='http://www.luminusweb.net/docs/deployment.md'>Deploying the application</a></li></ol>\\n\\n        </div>        \\n        <footer>Copyright ...</footer>\\n    </body>\\n</html>\\n\\n\\n\"))))\n\n  (testing \"not-found route\"\n    (let [response (app (request :get \"/invalid\"))]\n      (is (= (:status response) 404)))))\n\n#+END_SRC\n\n*** Models and persistence\n**** Database queries/functions\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/models/db.clj\n(ns mysite.models.db\n  (:use korma.core\n        [korma.db :only (defdb)])\n  (:require [mysite.models.schema :as schema]))\n\n(defdb db schema/db-spec)\n\n(defentity users)\n\n(defn create-user [user]\n  (insert users\n          (values user)))\n\n(defn update-user [id first-name last-name email]\n  (update users\n  (set-fields {:first_name first-name\n               :last_name last-name\n               :email email})\n  (where {:id id})))\n\n(defn get-user [id]\n  (first (select users\n                 (where {:id id})\n                 (limit 1))))\n#+END_SRC\n\n**** Schema\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/models/schema.clj\n(ns mysite.models.schema\n  (:require [clojure.java.jdbc :as sql]\n            [noir.io :as io]))\n\n(def db-store \"site.db\")\n\n(def db-spec {:classname \"org.h2.Driver\"\n              :subprotocol \"h2\"\n              :subname (str (io/resource-path) db-store)\n              :user \"sa\"\n              :password \"\"\n              :naming {:keys clojure.string/lower-case\n                       :fields clojure.string/upper-case}})\n(defn initialized?\n  \"checks to see if the database schema is present\"\n  []\n  (.exists (new java.io.File (str (io/resource-path) db-store \".h2.db\"))))\n\n(defn create-users-table\n  []\n  (sql/with-connection db-spec\n    (sql/create-table\n      :users\n      [:id \"varchar(20) PRIMARY KEY\"]\n      [:first_name \"varchar(30)\"]\n      [:last_name \"varchar(30)\"]\n      [:email \"varchar(30)\"]\n      [:admin :boolean]\n      [:last_login :time]\n      [:is_active :boolean]\n      [:pass \"varchar(100)\"])))\n\n(defn create-tables\n  \"creates the database tables used by the application\"\n  []\n  (create-users-table))\n\n#+END_SRC\n\n*** Routes: URLs/pages and workflows\n**** Authentication workflow\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/routes/auth.clj\n(ns mysite.routes.auth\n  (:use compojure.core)\n  (:require [mysite.views.layout :as layout]\n            [noir.session :as session]\n            [noir.response :as resp]\n            [noir.validation :as vali]\n            [noir.util.crypt :as crypt]\n            [mysite.models.db :as db]))\n\n(defn valid? [id pass pass1]\n  (vali/rule (vali/has-value? id)\n             [:id \"user ID is required\"])\n  (vali/rule (vali/min-length? pass 5)\n             [:pass \"password must be at least 5 characters\"])\n  (vali/rule (= pass pass1)\n             [:pass1 \"entered passwords do not match\"])\n  (not (vali/errors? :id :pass :pass1)))\n\n(defn register [& [id]]\n  (layout/render\n    \"registration.html\"\n    {:id id\n     :id-error (vali/on-error :id first)\n     :pass-error (vali/on-error :pass first)\n     :pass1-error (vali/on-error :pass1 first)}))\n\n(defn handle-registration [id pass pass1]\n  (if (valid? id pass pass1)\n    (try\n      (do\n        (db/create-user {:id id :pass (crypt/encrypt pass)})\n        (session/put! :user-id id)\n        (resp/redirect \"/\"))\n      (catch Exception ex\n        (vali/rule false [:id (.getMessage ex)])\n        (register)))\n    (register id)))\n\n(defn profile []\n  (layout/render\n    \"profile.html\"\n    {:user (db/get-user (session/get :user-id))}))\n\n(defn update-profile [{:keys [first-name last-name email]}]\n  (db/update-user (session/get :user-id) first-name last-name email)\n  (profile))\n\n(defn handle-login [id pass]\n  (let [user (db/get-user id)]\n    (if (and user (crypt/compare pass (:pass user)))\n      (session/put! :user-id id))\n    (resp/redirect \"/\")))\n\n(defn logout []\n  (session/clear!)\n  (resp/redirect \"/\"))\n\n(defroutes auth-routes\n  (GET \"/register\" []\n       (register))\n\n  (POST \"/register\" [id pass pass1]\n        (handle-registration id pass pass1))\n\n  (GET \"/profile\" [] (profile))\n\n  (POST \"/update-profile\" {params :params} (update-profile params))\n\n  (POST \"/login\" [id pass]\n        (handle-login id pass))\n\n  (GET \"/logout\" []\n        (logout)))\n\n#+END_SRC\n\n**** Routes->pages: homepage, about\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/routes/home.clj\n(ns mysite.routes.home\n  (:use compojure.core)\n  (:require [mysite.views.layout :as layout]\n            [mysite.util :as util]))\n\n(defn home-page []\n  (layout/render\n    \"home.html\" {:content (util/md->html \"/md/docs.md\")}))\n\n(defn about-page []\n  (layout/render \"about.html\"))\n\n(defroutes home-routes\n  (GET \"/\" [] (home-page))\n  (GET \"/about\" [] (about-page)))\n\n#+END_SRC\n\n**** CLJS client app hosting\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/routes/cljsexample.clj\n(ns mysite.routes.cljsexample\n  (:require [compojure.core :refer :all]\n            [noir.response :as response]\n            [mysite.views.layout :as layout]))\n\n(def messages\n  (atom \n    [{:message \"Hello world\"\n      :user    \"Foo\"}\n     {:message \"Ajax is fun\"\n      :user    \"Bar\"}]))\n\n(defroutes cljs-routes\n  (GET \"/cljsexample\" [] (layout/render \"cljsexample.html\")) \n  (GET \"/messages\" [] (response/edn @messages))\n  (POST \"/add-message\" [message user] \n        (response/edn \n          (swap! messages conj {:message message :user user}))))\n\n#+END_SRC\n\n*** Utility/helper functions\nIn other words, useful code that doesn't fit elsewhere:\n\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/util.clj\n(ns mysite.util\n  (:require [noir.io :as io]\n            [markdown.core :as md]))\n\n(defn md->html\n  \"reads a markdown file from public/md and returns an HTML string\"\n  [filename]\n  (->>\n    (io/slurp-resource filename)\n    (md/md-to-html-string)))\n\n#+END_SRC\n\n*** Visuals and templates/layouts\n**** Layout\n#+BEGIN_SRC clojure :tangle mysite/src/mysite/views/layout.clj\n(ns mysite.views.layout\n  (:require [selmer.parser :as parser]\n            [clojure.string :as s]\n            [ring.util.response :refer [content-type response]]\n            [noir.session :as session])\n  (:import compojure.response.Renderable))\n\n(def template-path \"mysite/views/templates/\")\n\n(deftype\n  RenderableTemplate\n  [template params]\n  Renderable\n  (render\n    [this request]\n    (content-type\n      (->>\n        (assoc\n          params\n          (keyword (s/replace template #\".html\" \"-selected\"))\n          \"active\"\n          :servlet-context\n          (:context request)\n          :user-id\n          (session/get :user-id))\n        (parser/render-file (str template-path template))\n        response)\n      \"text/html; charset=utf-8\")))\n\n(defn render [template & [params]]\n  (RenderableTemplate. template params))\n\n#+END_SRC\n**** About page\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/about.html\n{% extends \"mysite/views/templates/base.html\" %}\n{% block content %}\n <p>this is the story of mysite... work in progress</p>\n{% endblock %}\n\n#+END_SRC\n\n**** Base page\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/base.html\n<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>Welcome to mysite</title>\n\t</head>\n\t<body>\n\t\t\t<div class=\"navbar navbar-default navbar-fixed-top\">\n\t\t\t\t<div class=\"container\">\n\t\t\t\t\t<div class=\"navbar-header\">\n\t\t\t\t\t\t<button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n\t\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t\t\t<span class=\"icon-bar\"></span>\n\t\t\t\t\t\t</button> \n\t\t\t\t\t\t<a class=\"navbar-brand\" href=\"{{servlet-context}}/\">mysite</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t{% block menu %}\n\t\t\t\t\t{% include \"mysite/views/templates/menu.html\" %}\n\t\t\t\t\t{% endblock %}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"container\">\n\t\t\t\t{% block content %}\n\t\t\t\t{% endblock %}\n\t\t\t</div>\n\t\t<!-- scripts and styles -->\n        {% style \"/css/bootstrap-theme.min.css\" %}\n        {% style \"/css/bootstrap.min.css\" %}\n        {% style \"/css/screen.css\" %}\n        <script src=\"//code.jquery.com/jquery-2.0.3.min.js\" type=\"text/javascript\"></script>\n        {% script \"/js/bootstrap.min.js\" %}\n        <script type=\"text/javascript\">\n            var context = \"{{servlet-context}}\";\n            $(function() {\n              $(\"#{{selected-page}}\").addClass(\"active\");\n            });\n        </script>\n\t</body>\n</html>\n\n#+END_SRC\n\n**** CLJS example\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/cljsexample.html\n{% extends \"mysite/views/templates/base.html\" %}\n\n{% block content %}\n\n<br/>\n<div id=\"messages\"></div>\n<textarea id=\"message\"></textarea>\n<br/>\n<input type=\"text\" id=\"user\"></input>\n<br/>\n<button id=\"send\">add message</button>\n\n<!--  scripts -->\n<script type=\"text/javascript\" src=\"{{servlet-context}}/js/site.js\"></script>\n<script type=\"text/javascript\">\n\tmysite.main.init();\n</script>\n{% endblock %}\n\n#+END_SRC\n\n**** Homepage\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/home.html\n{% extends \"mysite/views/templates/base.html\" %}\n{% block content %}\n <div class=\"jumbotron\">\n    <h1>Welcome to mysite</h1>\n    <p>Time to start building your site!</p>\n    <p><a class=\"btn btn-primary btn-large\" href=\"http://luminusweb.net\">Learn more &raquo;</a></p>\n </div>\n\n <div class=\"row-fluid\">\n    <div class=\"span8\">\n    {{content|safe}}\n    </div>\n </div>\n{% endblock %}\n\n#+END_SRC\n\n**** Menu template\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/menu.html\n<div class=\"navbar-collapse collapse\">\n{% if user-id %}\n\t<div class=\"btn-group pull-right\">\n\t\t<ul class=\"nav navbar-nav\">\n\t\t\t <li class=\"dropdown\">\n\t\t\t\t <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n\t\t\t\t \t<i class=\"icon-user\"></i>{{user-id}} <b class=\"caret\"></b>\n\t\t\t\t </a>\n\t\t\t\t <ul class=\"dropdown-menu\">\n\t\t\t\t \t<li><a href=\"{{servlet-context}}/profile\">Profile</a></li>\n\t\t\t\t\t<li class=\"divider\"></li>\n\t\t\t\t\t<li><a href=\"{{servlet-context}}/logout\">Sign Out</a></li>\n\t\t\t\t </ul>\n\t\t\t </li>\n\t\t</ul>\n\t</div>\n\t{% else %}\n\t<div class=\"btn-group pull-right\">\n\t\t<ul class=\"nav navbar-nav\">\n\t\t\t <li class=\"dropdown\">\n\t\t\t\t<form action=\"{{servlet-context}}/login\" class=\"navbar-form\" method=\"POST\">\n\t\t\t\t\t<input class=\"span2\"\n\t\t\t\t\t       id=\"id\"\n\t\t\t\t\t       name=\"id\"\n\t\t\t\t\t       placeholder=\"user id\"\n\t\t\t\t\t\t   style=\"margin-right: 5px\"\n\t\t\t\t\t\t   type=\"text\"/>\n\t\t\t\t\t <input class=\"span2\"\n\t\t\t\t        id=\"pass\"\n\t\t\t\t        name=\"pass\"\n\t\t\t\t        placeholder=\"password\"\n\t\t\t\t\t    style=\"margin-right: 5px\"\n\t\t\t\t\t    type=\"password\"/>\n                    <input class=\"btn\" type=\"submit\" value=\"Login\"/>\n\t\t\t\t</form>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\t<a href=\"{{servlet-context}}/register\">Register</a>\n\t\t\t</li>\n\t\t</ul>\n\t</div>\n{% endif %}\n</div>\n\n#+END_SRC\n\n**** Profile template\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/profile.html\n{% extends \"mysite/views/templates/base.html\" %}\n{% block menu %}\n{% endblock %}\n{% block content %}\n<h2>User details for {{user.id}}</h2>\n\t\t<form action=\"{{servlet-context}}/update-profile\" method=\"POST\">\n\t\t\t<label for=\"id\">first name</label>\t\t\t\n\t\t\t<p>\n\t\t\t\t<input id=\"first-name\" name=\"first-name\" tabindex=\"1\" type=\"text\" value={{user.first_name}}></input>\n\t\t\t</p>\n\t\t\t<label for=\"id\">last name</label>\n\t\t\t<p>\n\t\t\t\t<input id=\"last-name\" name=\"last-name\" tabindex=\"1\" type=\"text\" value={{user.last_name}}></input>\n\t\t\t</p>\n\t\t\t<label for=\"id\">email</label>\n\t\t\t<p>\n\t\t\t\t<input id=\"email\" name=\"email\" tabindex=\"1\" type=\"text\" value={{user.email}}></input>\n\t\t\t</p>\t\t\t\n\t\t\t<input class=\"btn\" tabindex=\"4\" type=\"submit\" value=\"update profile\">\n\t\t</form>\n{% endblock %}\n\n#+END_SRC\n\n**** Registration page\n#+BEGIN_SRC html :tangle mysite/src/mysite/views/templates/registration.html\n{% extends \"mysite/views/templates/base.html\" %}\n{% block menu %}\n{% endblock %}\n{% block content %}\n\t\t<form action=\"{{servlet-context}}/register\" method=\"POST\">\n\t\t\t<label for=\"id\">user id</label>\n\t\t\t{% if id-error %}\n\t\t\t<div class=\"error\">{{id-error}}</div>\n\t\t\t{% endif %}\n\t\t\t<p>\n\t\t\t\t<input id=\"id\" name=\"id\" tabindex=\"1\" type=\"text\" value={{id}}></input>\n\t\t\t</p>\n\t\t\t<label for=\"pass\">password</label>\n\t\t\t{% if pass-error %}\n\t\t\t<div class=\"error\">{{pass-error}}</div>\n\t\t\t{% endif %}\n\t\t\t<p>\n\t\t\t\t<input id=\"pass\" name=\"pass\" tabindex=\"2\" type=\"password\"></input>\n\t\t\t</p>\n\t\t\t<label for=\"pass1\">retype password</label>\n\t\t\t{% if pass1-error %}\n\t\t\t<div class=\"error\">{{pass1-error}}</div>\n\t\t\t{% endif %}\n\t\t\t<p>\n\t\t\t\t<input id=\"pass1\" name=\"pass1\" tabindex=\"3\" type=\"password\"></input>\n\t\t\t</p>\n\t\t\t<input class=\"btn\" tabindex=\"4\" type=\"submit\" value=\"create account\">\n\t\t</form>\n{% endblock %}\n\n#+END_SRC\n\n** Client-side\n*** ClojureScript\n#+BEGIN_SRC clojurescript :tangle mysite/src-cljs/main.cljs\n(ns mysite.main\n  (:require [ajax.core :refer [GET POST]]\n            [domina :refer [value by-id destroy-children! append!]]\n            [domina.events :refer [listen!]]\n            [dommy.template :as template]))\n\n(defn render-message [{:keys [message user]}]\n  [:li [:p {:id user} message \" - \" user]])\n\n(defn render-messages [messages]\n  (let [messages-div (by-id \"messages\")]\n    (destroy-children! messages-div)\n    (->> messages\n         (map render-message)\n         (into [:ul])\n         template/node\n         (append! messages-div))))\n\n(defn add-message [_]\n  (POST \"/add-message\"\n        {:params {:message (value (by-id \"message\"))\n                  :user    (value (by-id \"user\"))}\n         :handler render-messages}))\n\n(defn ^:export init []\n  (GET \"/messages\" {:handler render-messages})\n  (listen! (by-id \"send\") :click add-message))\n\n#+END_SRC\n"
  },
  {
    "path": "05-luminus-site/mysite/resources/public/css/screen.css",
    "content": "html,\nbody {\n\tfont-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n    height: 100%;\n    padding-top: 70px;\n}\n\n.error {\n    color: red;\n}\n"
  },
  {
    "path": "05-luminus-site/mysite/resources/public/md/docs.md",
    "content": "### Here are some links to get started\n\n1. [HTML templating](http://www.luminusweb.net/docs/html_templating.md)\n2. [Accessing the database](http://www.luminusweb.net/docs/database.md)\n3. [Serving static resources](http://www.luminusweb.net/docs/static_resources.md)\n4. [Setting response types](http://www.luminusweb.net/docs/responses.md)\n5. [Defining routes](http://www.luminusweb.net/docs/routes.md)\n6. [Adding middleware](http://www.luminusweb.net/docs/middleware.md)\n7. [Sessions and cookies](http://www.luminusweb.net/docs/sessions_cookies.md)\n8. [Security](http://www.luminusweb.net/docs/security.md)\n9. [Deploying the application](http://www.luminusweb.net/docs/deployment.md)\n"
  },
  {
    "path": "LICENSE",
    "content": "Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM\nCONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and documentation\n   distributed under this Agreement, and\nb) in the case of each subsequent Contributor:\n    i) changes to the Program, and\n   ii) additions to the Program;\n\n   where such changes and/or additions to the Program originate from and are\n   distributed by that particular Contributor. A Contribution 'originates' from\n   a Contributor if it was added to the Program by such Contributor itself or\n   anyone acting on such Contributor's behalf. Contributions do not include\n   additions to the Program which: (i) are separate modules of software\n   distributed in conjunction with the Program under their own license\n   agreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which are\nnecessarily infringed by the use or sale of its Contribution alone or when\ncombined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this Agreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement,\nincluding all Contributors.\n\n2. GRANT OF RIGHTS\n  a) Subject to the terms of this Agreement, each Contributor hereby grants\n     Recipient a non-exclusive, worldwide, royalty-free copyright license to\n     reproduce, prepare derivative works of, publicly display, publicly perform,\n     distribute and sublicense the Contribution of such Contributor, if any, and\n     such derivative works, in source code and object code form.\n  b) Subject to the terms of this Agreement, each Contributor hereby grants\n     Recipient a non-exclusive, worldwide, royalty-free patent license under\n     Licensed Patents to make, use, sell, offer to sell, import and otherwise\n     transfer the Contribution of such Contributor, if any, in source code and\n     object code form. This patent license shall apply to the combination of the\n     Contribution and the Program if, at the time the Contribution is added by\n     the Contributor, such addition of the Contribution causes such combination\n     to be covered by the Licensed Patents. The patent license shall not apply\n     to any other combinations which include the Contribution. No hardware per\n     se is licensed hereunder.\n  c) Recipient understands that although each Contributor grants the licenses to\n     its Contributions set forth herein, no assurances are provided by any\n     Contributor that the Program does not infringe the patent or other\n     intellectual property rights of any other entity. Each Contributor\n     disclaims any liability to Recipient for claims brought by any other entity\n     based on infringement of intellectual property rights or otherwise. As a\n     condition to exercising the rights and licenses granted hereunder, each\n     Recipient hereby assumes sole responsibility to secure any other\n     intellectual property rights needed, if any. For example, if a third party\n     patent license is required to allow Recipient to distribute the Program, it\n     is Recipient's responsibility to acquire that license before distributing\n     the Program.\n  d) Each Contributor represents that to its knowledge it has sufficient\n     copyright rights in its Contribution, if any, to grant the copyright\n     license set forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under its\nown license agreement, provided that:\n\n  a) it complies with the terms and conditions of this Agreement; and\n  b) its license agreement:\n      i) effectively disclaims on behalf of all Contributors all warranties and\n         conditions, express and implied, including warranties or conditions of\n         title and non-infringement, and implied warranties or conditions of\n         merchantability and fitness for a particular purpose;\n     ii) effectively excludes on behalf of all Contributors all liability for\n         damages, including direct, indirect, special, incidental and\n         consequential damages, such as lost profits;\n    iii) states that any provisions which differ from this Agreement are offered\n         by that Contributor alone and not by any other party; and\n     iv) states that source code for the Program is available from such\n         Contributor, and informs licensees how to obtain it in a reasonable\n         manner on or through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\n  a) it must be made available under this Agreement; and\n  b) a copy of this Agreement must be included with each copy of the Program.\n     Contributors may not remove or alter any copyright notices contained within\n     the Program.\n\nEach Contributor must identify itself as the originator of its Contribution, if\nany, in a manner that reasonably allows subsequent Recipients to identify the\noriginator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities with\nrespect to end users, business partners and the like. While this license is\nintended to facilitate the commercial use of the Program, the Contributor who\nincludes the Program in a commercial product offering should do so in a manner\nwhich does not create potential liability for other Contributors. Therefore, if\na Contributor includes the Program in a commercial product offering, such\nContributor (\"Commercial Contributor\") hereby agrees to defend and indemnify\nevery other Contributor (\"Indemnified Contributor\") against any losses, damages\nand costs (collectively \"Losses\") arising from claims, lawsuits and other legal\nactions brought by a third party against the Indemnified Contributor to the\nextent caused by the acts or omissions of such Commercial Contributor in\nconnection with its distribution of the Program in a commercial product\noffering. The obligations in this section do not apply to any claims or Losses\nrelating to any actual or alleged intellectual property infringement. In order\nto qualify, an Indemnified Contributor must: a) promptly notify the Commercial\nContributor in writing of such claim, and b) allow the Commercial Contributor to\ncontrol, and cooperate with the Commercial Contributor in, the defense and any\nrelated settlement negotiations. The Indemnified Contributor may participate in\nany such claim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial product\noffering, Product X. That Contributor is then a Commercial Contributor. If that\nCommercial Contributor then makes performance claims, or offers warranties\nrelated to Product X, those performance claims and warranties are such\nCommercial Contributor's responsibility alone. Under this section, the\nCommercial Contributor would have to defend claims against the other\nContributors related to those performance claims and warranties, and if a court\nrequires any other Contributor to pay any damages as a result, the Commercial\nContributor must pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN\n\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each\nRecipient is solely responsible for determining the appropriateness of using and\ndistributing the Program and assumes all risks associated with its exercise of\nrights under this Agreement , including but not limited to the risks and costs\nof program errors, compliance with applicable laws, damage to or loss of data,\nprograms or equipment, and unavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY\nCONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST\nPROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\nSTRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS\nGRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under applicable\nlaw, it shall not affect the validity or enforceability of the remainder of the\nterms of this Agreement, and without further action by the parties hereto, such\nprovision shall be reformed to the minimum extent necessary to make such\nprovision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Program itself\n(excluding combinations of the Program with other software or hardware)\ninfringes such Recipient's patent(s), then such Recipient's rights granted under\nSection 2(b) shall terminate as of the date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it fails to\ncomply with any of the material terms or conditions of this Agreement and does\nnot cure such failure in a reasonable period of time after becoming aware of\nsuch noncompliance. If all Recipient's rights under this Agreement terminate,\nRecipient agrees to cease use and distribution of the Program as soon as\nreasonably practicable. However, Recipient's obligations under this Agreement\nand any licenses granted by Recipient relating to the Program shall continue and\nsurvive.\n\nEveryone is permitted to copy and distribute copies of this Agreement, but in\norder to avoid inconsistency the Agreement is copyrighted and may only be\nmodified in the following manner. The Agreement Steward reserves the right to\npublish new versions (including revisions) of this Agreement from time to time.\nNo one other than the Agreement Steward has the right to modify this Agreement.\nThe Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation\nmay assign the responsibility to serve as the Agreement Steward to a suitable\nseparate entity. Each new version of the Agreement will be given a\ndistinguishing version number. The Program (including Contributions) may always\nbe distributed subject to the version of the Agreement under which it was\nreceived. In addition, after a new version of the Agreement is published,\nContributor may elect to distribute the Program (including its Contributions)\nunder the new version. Except as expressly stated in Sections 2(a) and 2(b)\nabove, Recipient receives no rights or licenses to the intellectual property of\nany Contributor under this Agreement, whether expressly, by implication,\nestoppel or otherwise. All rights in the Program not expressly granted under\nthis Agreement are reserved.\n\nThis Agreement is governed by the laws of the State of New York and the\nintellectual property laws of the United States of America. No party to this\nAgreement will bring a legal action under this Agreement more than one year\nafter the cause of action arose. Each party waives its rights to a jury trial in\nany resulting litigation.\n"
  },
  {
    "path": "README.md",
    "content": "Literate Programming Examples\n=============================\n\nA literate program combines code and prose (documentation) in one file\nformat. The term was coined by Donald Knuth in his September 1983\npaper, *Literate Programming*,\n[available online](http://literateprogramming.com/knuthweb.pdf). Decades\nlater,\n[Knuth asserts that literate programming](http://www.informit.com/articles/article.aspx?p=1193856):\n\n1. Was the most important outcome of creating TeX.\n2. Enables faster and more reliable creation of software.\n3. Manages complexity better than any other methodology he's aware of.\n4. Is a source of joy when programming.\n5. Enables extraordinary achievements in creating software.\n\nCan these claims be made by non-Knuth programmers who adopt literate\nprogramming (LP) for themselves? I believe the time is ripe to find\nout, as we finally have a tool that is simple (plain text), flexible,\nand powerful, with mature LP capabilities:\n[Emacs Org mode](http://orgmode.org).\n\nThus this repository is a collection of literate programming (LP)\nexamples, using Emacs Org mode.  These examples are intended to be\ndirectly usable (copy and start hacking), and/or to serve as\neducational literate programs.  The long-term goal is to collect and\norganize a corpus of useful LP examples that point towards Knuth's\nvision of programs-as-literature.\n\n\nPrerequisites\n=============\n\n1. Install a recent version of Emacs, 24.3+.\n2. Install both `org-mode` (older version should be included w/ Emacs\n   24+) and `clojure-mode`.  Use Emacs ELPA as needed (it can also\n   upgrade Emacs packages); you can invoke that from Emacs with\n   `M-x package-list-packages`\n   - Consider using an Emacs \"starter package\" that provides a good\n     baseline configuration, like\n     [Emacs Prelude](http://batsov.com/prelude/) or\n     [Emacs Live](http://overtone.github.io/emacs-live/).  Both those\n     packages choose reasonable/good default configurations, and\n     support Clojure (other languages too).\n3. Update your `.emacs` file to support Org's LP features for Clojure\n   (and possibly other languages). \n   - The exact location and name varies, depending on whether you\n     chose one of the starter packages mentioned; e.g. with Emacs\n     Prelude you'd have a file like\n     `~/.emacs.d/personal/yourUsername.el`\n   - You'll need to add the following somewhere within the `.emacs`;\n     note that the `emacs-lisp` line below is optional, it's just\n     meant to show that supporting additional languages is easy:\n\n     ```elisp\n     (org-babel-do-load-languages\n       'org-babel-load-languages\n       '((emacs-lisp . t)\n         (clojure . t)))\n     ;; Show syntax highlighting per language native mode in *.org\n     (setq org-src-fontify-natively t)\n     ;; For languages with significant whitespace like Python:\n     (setq org-src-preserve-indentation t)\n     ```\n\n\nThe benefits of LP using Emacs + Org\n====================================\n\n1. Documentation matters, a lot.\n   - For starters, do you judge a Github project by its README?\n   - For all but small throwaway systems, you're likely keeping a\n     separate file of development notes already; LP would integrate\n     that.\n   - No matter how clear the function and data names are, code itself\n     rarely clarifies larger issues of architecture and design, and\n     the decision histories therein.\n   - With literate programming, documentation is integral to\n     development, never an afterthought.\n2. With one LP file, you avoid the incidental/inessential complexity\n   of the filesystem, by avoiding the frequent context-switching\n   overhead in moving between files.  And you sidestep your language's\n   imposed filesystem structure.\n3. Org rocks for prose:\n   - Org's plain-text markup is lightweight, yet more powerful than\n     Markdown (which lacks hierarchical structuring), and cleaner than\n     rST.\n   - The structural editing provided by Org documents lets you\n     organize your thoughts/writing/code very quickly.  With good\n     structure even major revisions are easy.\n   - Org's exporter lets your write-once, express-many-times: you\n     can export an Org file to HTML (e.g. for blogging) or LaTeX (for\n     serious publishing) and PDF.\n   - It's easy to version-control Org files; it's just plain-text.\n4. Org rocks for code:\n   - Each code block has flexible granularity: can be named and\n     referred to; evaluated or not; have data sent in or exported;\n     specify different REPL sessions; specify different target/tangled\n     files (in arbitrary subdirectories).\n   - Code blocks are syntax-highlighted.\n   - Code blocks are ready to edit: jump to major-mode editing easily;\n     edit/REPL as usual; changes will flow back to the containing Org\n     file.\n   - A single Org file can mix multiple languages together.\n5. Meta-development, manage complexity from a coherent perspective: a\n   unified, single-file approach encourages holistic software\n   development and exposition, in a natural order, using structure to\n   enhance understanding.  LP is not just documentation and code\n   together: it's a **process and abstraction unifying the development\n   lifecycle**: requirements, architecture, design, code, tests,\n   deployment, and maintenance - can all be bound coherently in one\n   active format.\n\n\nMore information\n================\n\n- Emacs: no flamebait here; I will simply say that having Org is\n  sufficient reason to use the Eternal Editor.  Just be sure to\n  [remap your CapsLock to Control](http://www.emacswiki.org/emacs/MovingTheCtrlKey),\n  for happy hands.\n- [Org documentation](http://orgmode.org/org.html), especially the\n  section on\n  [Working with source code](http://orgmode.org/org.html#Working-With-Source-Code)\n- The excellent paper by Schulte and Davison,\n  [Active Documents with Org-Mode](http://www.cs.unm.edu/~eschulte/data/CISE-13-3-SciProg.pdf)\n\n- Pro-tip: when you want to \"tangle\" or export code blocks from an org\n  file, =CTRL-c-v-t= is the keystroke combo to tangle all blocks.  To\n  tangle only ONE block, the current one your cursor is in, just use\n  the Emacs prefix code first: =CTRL-u-c-v-t= For big org files, this\n  saves time, as it's essentially instantaneous to tangle/export one\n  block.\n"
  }
]