summaryrefslogtreecommitdiff
path: root/srv/src/http/static/viz/1/viz
diff options
context:
space:
mode:
authorBrian Picciano <mediocregopher@gmail.com>2022-05-20 13:37:43 -0600
committerBrian Picciano <mediocregopher@gmail.com>2022-05-20 13:37:43 -0600
commit16cfbd19157df76e7296dddb287412f1099feb33 (patch)
treee4bbf892066cceeaeeaee4c25e5365152412a1c3 /srv/src/http/static/viz/1/viz
parent3cdee89c961ae9c836234f5aec87174a04a800a8 (diff)
Move static assets to within srv
Diffstat (limited to 'srv/src/http/static/viz/1/viz')
-rw-r--r--srv/src/http/static/viz/1/viz/core.cljs204
-rw-r--r--srv/src/http/static/viz/1/viz/core.cljs.cache.edn1
-rw-r--r--srv/src/http/static/viz/1/viz/core.js564
-rw-r--r--srv/src/http/static/viz/1/viz/core.js.map1
-rw-r--r--srv/src/http/static/viz/1/viz/forest.cljs96
-rw-r--r--srv/src/http/static/viz/1/viz/forest.cljs.cache.edn1
-rw-r--r--srv/src/http/static/viz/1/viz/forest.js111
-rw-r--r--srv/src/http/static/viz/1/viz/forest.js.map1
-rw-r--r--srv/src/http/static/viz/1/viz/ghost.cljs72
-rw-r--r--srv/src/http/static/viz/1/viz/ghost.cljs.cache.edn1
-rw-r--r--srv/src/http/static/viz/1/viz/ghost.js89
-rw-r--r--srv/src/http/static/viz/1/viz/ghost.js.map1
-rw-r--r--srv/src/http/static/viz/1/viz/grid.cljs63
-rw-r--r--srv/src/http/static/viz/1/viz/grid.cljs.cache.edn1
-rw-r--r--srv/src/http/static/viz/1/viz/grid.js27
-rw-r--r--srv/src/http/static/viz/1/viz/grid.js.map1
16 files changed, 1234 insertions, 0 deletions
diff --git a/srv/src/http/static/viz/1/viz/core.cljs b/srv/src/http/static/viz/1/viz/core.cljs
new file mode 100644
index 0000000..913cab4
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/core.cljs
@@ -0,0 +1,204 @@
+(ns viz.core
+ (:require [quil.core :as q :include-macros true]
+ [quil.middleware :as m]
+ [viz.forest :as forest]
+ [viz.grid :as grid]
+ [viz.ghost :as ghost]
+ [goog.string :as gstring]
+ [goog.string.format]
+ ;[gil.core :as gil]
+ ))
+
+(defn- debug [& args]
+ (.log js/console (clojure.string/join " " (map str args))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn- window-partial [k]
+ (int (* (aget js/document "documentElement" k) 0.95)))
+
+(def window-size [ (min 1025 (window-partial "clientWidth"))
+ (int (* (window-partial "clientHeight") 0.75))
+ ])
+(def window-half-size (apply vector (map #(float (/ %1 2)) window-size)))
+
+(defn- new-state []
+ {:frame-rate 15
+ :exit-wait-frames 40
+ :tail-length 15
+ :frame 0
+ :gif-seconds 0
+ :grid-width 30 ; from the center
+ :ghost (-> (ghost/new-ghost grid/euclidean)
+ (ghost/new-active-node [0 0])
+ )
+ })
+
+(defn- curr-second [state]
+ (float (/ (:frame state) (:frame-rate state))))
+
+(defn- grid-size [state]
+ (let [h (int (* (window-size 1)
+ (float (/ (:grid-width state) (window-size 0)))))]
+ [(:grid-width state) h]))
+
+(defn- positive [n] (if (> 0 n) (- n) n))
+
+(defn- spawn-chance [state]
+ (let [period-seconds 1
+ period-frames (* (:frame-rate state) period-seconds)]
+ (if (zero? (rem (:frame state) period-frames))
+ 1 100)
+ ))
+
+ ;(let [period-seconds 1
+ ; rad-per-second (float (/ (/ Math/PI 2) period-seconds))
+ ; rad (* rad-per-second (curr-second state))
+ ; chance-raw (positive (q/sin rad))
+ ; ]
+ ; (if (> chance-raw 0.97) 3 50)
+ ; ))
+
+
+;(defn- mk-poss-fn [state]
+; (let [chance (spawn-chance state)]
+; (fn [pos adj-poss]
+; (if (zero? (rand-int chance))
+; adj-poss
+; (take 1 (shuffle adj-poss))))
+; ))
+
+(defn- mk-poss-fn [state]
+ (fn [pos adj-poss]
+ (take 2 (random-sample 0.6 adj-poss))))
+
+(defn setup []
+ (let [state (new-state)]
+ (q/frame-rate (:frame-rate state))
+ state))
+
+(defn- scale [state xy]
+ (map-indexed #(* %2 (float (/ (window-half-size %1)
+ ((grid-size state) %1)))) xy))
+
+; each bound is a position vector
+(defn- in-bounds? [min-bound max-bound pos]
+ (let [pos-k (keep-indexed #(let [mini (min-bound %1)
+ maxi (max-bound %1)]
+ (when (and (>= %2 mini) (<= %2 maxi)) %2)) pos)]
+ (= (count pos) (count pos-k))))
+
+(defn- quil-bounds [state buffer]
+ (let [[w h] (apply vector (map #(- % buffer) (grid-size state)))]
+ [[(- w) (- h)] [w h]]))
+
+(defn- ghost-incr [state]
+ (assoc state :ghost
+ (ghost/filter-active-nodes (ghost/incr (:ghost state) (mk-poss-fn state))
+ #(let [[minb maxb] (quil-bounds state 2)]
+ (in-bounds? minb maxb (:pos %1))))))
+
+(defn- ghost-expire-roots [state]
+ (if-not (< (:tail-length state) (:frame state)) state
+ (update-in state [:ghost] ghost/remove-roots)))
+
+(defn- maybe-exit [state]
+ (if (empty? (get-in state [:ghost :active-node-ids]))
+ (if (zero? (:exit-wait-frames state)) (new-state)
+ (update-in state [:exit-wait-frames] dec))
+ state))
+
+(defn update-state [state]
+ (-> state
+ (ghost-incr)
+ (ghost-expire-roots)
+ (update-in [:frame] inc)
+ (maybe-exit)))
+
+(defn- draw-ellipse [state pos size] ; size is [w h]
+ (let [scaled-pos (scale state pos)
+ scaled-size (map int (scale state size))]
+ (apply q/ellipse (concat scaled-pos scaled-size))))
+
+(defn- in-line? [& nodes]
+ (apply = (map #(apply map - %1)
+ (partition 2 1 (map :pos nodes)))))
+
+(defn draw-lines [state forest parent node]
+ "Draws the lines of all children leading from the node, recursively"
+ (q/stroke 0xFF000000)
+ (q/fill 0xFFFFFFFF)
+ (let [children (map #(forest/get-node forest %) (:child-ids node))]
+
+ (if-not parent
+ (doseq [child children] (draw-lines state forest node child))
+ (let [in-line-child (some #(if (in-line? parent node %) %) children)
+ ]
+ (doseq [child children]
+ (if (and in-line-child (= in-line-child child))
+ (draw-lines state forest parent child)
+ (draw-lines state forest node child)))
+ (when-not in-line-child
+ (apply q/line (apply concat
+ (map #(scale state %)
+ (map :pos (list parent node))))))
+ ))
+
+ ; we also take the opportunity to draw the leaves
+ (when (empty? children)
+ (draw-ellipse state (:pos node) [0.3 0.3]))
+
+ ))
+
+(defn draw-state [state]
+ ; Clear the sketch by filling it with light-grey color.
+ (q/background 0xFFFFFFFF)
+ (q/with-translation [(/ (window-size 0) 2)
+ (/ (window-size 1) 2)]
+ (let [lines (forest/lines (get-in state [:ghost :forest]))
+ leaves (forest/leaves (get-in state [:ghost :forest]))
+ active (ghost/active-nodes (:ghost state))
+ roots (forest/roots (get-in state [:ghost :forest]))
+ ]
+
+ (q/stroke 0xFF000000)
+ (doseq [root roots]
+ (draw-lines state (get-in state [:ghost :forest]) nil root))
+
+ (q/stroke 0xFF000000)
+ (q/fill 0xFF000000)
+ (doseq [active-node active]
+ (let [pos (:pos active-node)]
+ (draw-ellipse state pos [0.35 0.35])
+ ))
+
+ ))
+
+ ;(when-not (zero? (:gif-seconds state))
+ ; (let [anim-frames (* (:gif-seconds state) (:frame-rate state))]
+ ; (gil/save-animation "quil.gif" anim-frames 0)
+ ; (when (> (:frame state) anim-frames) (q/exit))))
+
+ ;(q/text (clojure.string/join
+ ; "\n"
+ ; (list
+ ; (gstring/format "frame:%d" (:frame state))
+ ; (gstring/format "second:%f" (curr-second state))
+ ; (gstring/format "spawn-chance:%d" (spawn-chance state))))
+ ; 30 30)
+ )
+
+(q/defsketch viz
+ :title ""
+ :host "viz"
+ :size window-size
+ ; setup function called only once, during sketch initialization.
+ :setup setup
+ ; update-state is called on each iteration before draw-state.
+ :update update-state
+ :draw draw-state
+ :features [:keep-on-top]
+ ; This sketch uses functional-mode middleware.
+ ; Check quil wiki for more info about middlewares and particularly
+ ; fun-mode.
+ :middleware [m/fun-mode])
diff --git a/srv/src/http/static/viz/1/viz/core.cljs.cache.edn b/srv/src/http/static/viz/1/viz/core.cljs.cache.edn
new file mode 100644
index 0000000..2156790
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/core.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :externs {console {log {}}, document {}}, :use-macros {}, :excludes #{}, :name viz.core, :imports nil, :requires {gstring goog.string, goog.string goog.string, q quil.core, viz.forest viz.forest, grid viz.grid, m quil.middleware, quil.core quil.core, quil.middleware quil.middleware, goog.string.format goog.string.format, viz.ghost viz.ghost, forest viz.forest, viz.grid viz.grid, ghost viz.ghost}, :uses nil, :defs {draw-state {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 153, :column 7, :end-line 153, :end-column 17, :arglists (quote ([state]))}, :name viz.core/draw-state, :variadic false, :file "src/viz/core.cljs", :end-column 17, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 153, :end-line 153, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, ghost-expire-roots {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 101, :column 8, :end-line 101, :end-column 26, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/ghost-expire-roots, :variadic false, :file "src/viz/core.cljs", :end-column 26, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 101, :end-line 101, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, viz {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 191, :column 14, :end-line 191, :end-column 17, :export true, :arglists (quote ([]))}, :name viz.core/viz, :variadic false, :file "src/viz/core.cljs", :end-column 17, :method-params ([]), :protocol-impl nil, :export true, :arglists-meta (nil nil), :column 1, :line 191, :end-line 191, :max-fixed-arity 0, :fn-var true, :arglists (quote ([]))}, update-state {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 111, :column 7, :end-line 111, :end-column 19, :arglists (quote ([state]))}, :name viz.core/update-state, :variadic false, :file "src/viz/core.cljs", :end-column 19, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 111, :end-line 111, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, maybe-exit {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 105, :column 8, :end-line 105, :end-column 18, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/maybe-exit, :variadic false, :file "src/viz/core.cljs", :end-column 18, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 105, :end-line 105, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, quil-bounds {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 91, :column 8, :end-line 91, :end-column 19, :private true, :arglists (quote ([state buffer]))}, :private true, :name viz.core/quil-bounds, :variadic false, :file "src/viz/core.cljs", :end-column 19, :method-params ([state buffer]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 91, :end-line 91, :max-fixed-arity 2, :fn-var true, :arglists (quote ([state buffer]))}, draw-ellipse {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 118, :column 8, :end-line 118, :end-column 20, :private true, :arglists (quote ([state pos size]))}, :private true, :name viz.core/draw-ellipse, :variadic false, :file "src/viz/core.cljs", :end-column 20, :method-params ([state pos size]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 118, :end-line 118, :max-fixed-arity 3, :fn-var true, :arglists (quote ([state pos size]))}, spawn-chance {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 47, :column 8, :end-line 47, :end-column 20, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/spawn-chance, :variadic false, :file "src/viz/core.cljs", :end-column 20, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 47, :end-line 47, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, window-partial {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 17, :column 8, :end-line 17, :end-column 22, :private true, :arglists (quote ([k]))}, :private true, :name viz.core/window-partial, :variadic false, :file "src/viz/core.cljs", :end-column 22, :method-params ([k]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 17, :end-line 17, :max-fixed-arity 1, :fn-var true, :arglists (quote ([k]))}, mk-poss-fn {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 71, :column 8, :end-line 71, :end-column 18, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/mk-poss-fn, :variadic false, :file "src/viz/core.cljs", :end-column 18, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 71, :end-line 71, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, new-state {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 25, :column 8, :end-line 25, :end-column 17, :private true, :arglists (quote ([]))}, :private true, :name viz.core/new-state, :variadic false, :file "src/viz/core.cljs", :end-column 17, :method-params ([]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 25, :end-line 25, :max-fixed-arity 0, :fn-var true, :arglists (quote ([]))}, window-half-size {:name viz.core/window-half-size, :file "src/viz/core.cljs", :line 23, :column 1, :end-line 23, :end-column 22, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 23, :column 6, :end-line 23, :end-column 22}, :tag any}, window-size {:name viz.core/window-size, :file "src/viz/core.cljs", :line 20, :column 1, :end-line 20, :end-column 17, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 20, :column 6, :end-line 20, :end-column 17}, :tag cljs.core/IVector}, scale {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 80, :column 8, :end-line 80, :end-column 13, :private true, :arglists (quote ([state xy]))}, :private true, :name viz.core/scale, :variadic false, :file "src/viz/core.cljs", :end-column 13, :method-params ([state xy]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 80, :end-line 80, :max-fixed-arity 2, :fn-var true, :arglists (quote ([state xy]))}, in-line? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 123, :column 8, :end-line 123, :end-column 16, :private true, :arglists (quote ([& nodes])), :top-fn {:variadic true, :max-fixed-arity 0, :method-params [(nodes)], :arglists ([& nodes]), :arglists-meta (nil)}}, :private true, :name viz.core/in-line?, :variadic true, :file "src/viz/core.cljs", :end-column 16, :top-fn {:variadic true, :max-fixed-arity 0, :method-params [(nodes)], :arglists ([& nodes]), :arglists-meta (nil)}, :method-params [(nodes)], :protocol-impl nil, :arglists-meta (nil), :column 1, :line 123, :end-line 123, :max-fixed-arity 0, :fn-var true, :arglists ([& nodes])}, positive {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 45, :column 8, :end-line 45, :end-column 16, :private true, :arglists (quote ([n]))}, :private true, :name viz.core/positive, :variadic false, :file "src/viz/core.cljs", :end-column 16, :method-params ([n]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 45, :end-line 45, :max-fixed-arity 1, :fn-var true, :arglists (quote ([n]))}, debug {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 12, :column 8, :end-line 12, :end-column 13, :private true, :arglists (quote ([& args])), :top-fn {:variadic true, :max-fixed-arity 0, :method-params [(args)], :arglists ([& args]), :arglists-meta (nil)}}, :private true, :name viz.core/debug, :variadic true, :file "src/viz/core.cljs", :end-column 13, :top-fn {:variadic true, :max-fixed-arity 0, :method-params [(args)], :arglists ([& args]), :arglists-meta (nil)}, :method-params [(args)], :protocol-impl nil, :arglists-meta (nil), :column 1, :line 12, :end-line 12, :max-fixed-arity 0, :fn-var true, :arglists ([& args])}, grid-size {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 40, :column 8, :end-line 40, :end-column 17, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/grid-size, :variadic false, :file "src/viz/core.cljs", :end-column 17, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 40, :end-line 40, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, setup {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 75, :column 7, :end-line 75, :end-column 12, :arglists (quote ([]))}, :name viz.core/setup, :variadic false, :file "src/viz/core.cljs", :end-column 12, :method-params ([]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 75, :end-line 75, :max-fixed-arity 0, :fn-var true, :arglists (quote ([]))}, in-bounds? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 85, :column 8, :end-line 85, :end-column 18, :private true, :arglists (quote ([min-bound max-bound pos]))}, :private true, :name viz.core/in-bounds?, :variadic false, :file "src/viz/core.cljs", :end-column 18, :method-params ([min-bound max-bound pos]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 85, :end-line 85, :max-fixed-arity 3, :fn-var true, :arglists (quote ([min-bound max-bound pos]))}, draw-lines {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 127, :column 7, :end-line 127, :end-column 17, :arglists (quote ([state forest parent node]))}, :name viz.core/draw-lines, :variadic false, :file "src/viz/core.cljs", :end-column 17, :method-params ([state forest parent node]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 127, :end-line 127, :max-fixed-arity 4, :fn-var true, :arglists (quote ([state forest parent node]))}, ghost-incr {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 95, :column 8, :end-line 95, :end-column 18, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/ghost-incr, :variadic false, :file "src/viz/core.cljs", :end-column 18, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 95, :end-line 95, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}, curr-second {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/core.cljs", :line 37, :column 8, :end-line 37, :end-column 19, :private true, :arglists (quote ([state]))}, :private true, :name viz.core/curr-second, :variadic false, :file "src/viz/core.cljs", :end-column 19, :method-params ([state]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 37, :end-line 37, :max-fixed-arity 1, :fn-var true, :arglists (quote ([state]))}}, :require-macros {q quil.core, quil.core quil.core}, :cljs.analyzer/constants {:seen #{:features :active-node-ids :grid-width :frame-rate :fn :frame :exit-wait-frames :pos :gif-seconds :update :size :title :tail-length :setup :middleware :host :forest :keep-on-top :host-id :no-start :ghost :draw :child-ids}, :order [:frame-rate :exit-wait-frames :tail-length :frame :gif-seconds :grid-width :ghost :pos :active-node-ids :child-ids :forest :host :features :keep-on-top :update :size :title :setup :middleware :draw :no-start :fn :host-id]}, :doc nil} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/core.js b/srv/src/http/static/viz/1/viz/core.js
new file mode 100644
index 0000000..ddc336c
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/core.js
@@ -0,0 +1,564 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('viz.core');
+goog.require('cljs.core');
+goog.require('quil.core');
+goog.require('quil.middleware');
+goog.require('viz.forest');
+goog.require('viz.grid');
+goog.require('viz.ghost');
+goog.require('goog.string');
+goog.require('goog.string.format');
+viz.core.debug = (function viz$core$debug(var_args){
+var args__7934__auto__ = [];
+var len__7927__auto___18287 = arguments.length;
+var i__7928__auto___18288 = (0);
+while(true){
+if((i__7928__auto___18288 < len__7927__auto___18287)){
+args__7934__auto__.push((arguments[i__7928__auto___18288]));
+
+var G__18289 = (i__7928__auto___18288 + (1));
+i__7928__auto___18288 = G__18289;
+continue;
+} else {
+}
+break;
+}
+
+var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
+return viz.core.debug.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
+});
+
+viz.core.debug.cljs$core$IFn$_invoke$arity$variadic = (function (args){
+return console.log(clojure.string.join.call(null," ",cljs.core.map.call(null,cljs.core.str,args)));
+});
+
+viz.core.debug.cljs$lang$maxFixedArity = (0);
+
+viz.core.debug.cljs$lang$applyTo = (function (seq18286){
+return viz.core.debug.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq18286));
+});
+
+viz.core.window_partial = (function viz$core$window_partial(k){
+return (((document["documentElement"][k]) * 0.95) | (0));
+});
+viz.core.window_size = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(function (){var x__7157__auto__ = (1025);
+var y__7158__auto__ = viz.core.window_partial.call(null,"clientWidth");
+return ((x__7157__auto__ < y__7158__auto__) ? x__7157__auto__ : y__7158__auto__);
+})(),((viz.core.window_partial.call(null,"clientHeight") * 0.75) | (0))], null);
+viz.core.window_half_size = cljs.core.apply.call(null,cljs.core.vector,cljs.core.map.call(null,(function (p1__18290_SHARP_){
+return (p1__18290_SHARP_ / (2));
+}),viz.core.window_size));
+viz.core.new_state = (function viz$core$new_state(){
+return new cljs.core.PersistentArrayMap(null, 7, [new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942),(15),new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098),(40),new cljs.core.Keyword(null,"tail-length","tail-length",-2007115089),(15),new cljs.core.Keyword(null,"frame","frame",-1711082588),(0),new cljs.core.Keyword(null,"gif-seconds","gif-seconds",1861397548),(0),new cljs.core.Keyword(null,"grid-width","grid-width",837583106),(30),new cljs.core.Keyword(null,"ghost","ghost",-1531157576),viz.ghost.new_active_node.call(null,viz.ghost.new_ghost.call(null,viz.grid.euclidean),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null))], null);
+});
+viz.core.curr_second = (function viz$core$curr_second(state){
+return (new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state) / new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state));
+});
+viz.core.grid_size = (function viz$core$grid_size(state){
+var h = ((viz.core.window_size.call(null,(1)) * (new cljs.core.Keyword(null,"grid-width","grid-width",837583106).cljs$core$IFn$_invoke$arity$1(state) / viz.core.window_size.call(null,(0)))) | (0));
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"grid-width","grid-width",837583106).cljs$core$IFn$_invoke$arity$1(state),h], null);
+});
+viz.core.positive = (function viz$core$positive(n){
+if(((0) > n)){
+return (- n);
+} else {
+return n;
+}
+});
+viz.core.spawn_chance = (function viz$core$spawn_chance(state){
+var period_seconds = (1);
+var period_frames = (new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state) * period_seconds);
+if((cljs.core.rem.call(null,new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state),period_frames) === (0))){
+return (1);
+} else {
+return (100);
+}
+});
+viz.core.mk_poss_fn = (function viz$core$mk_poss_fn(state){
+return (function (pos,adj_poss){
+return cljs.core.take.call(null,(2),cljs.core.random_sample.call(null,0.6,adj_poss));
+});
+});
+viz.core.setup = (function viz$core$setup(){
+var state = viz.core.new_state.call(null);
+quil.core.frame_rate.call(null,new cljs.core.Keyword(null,"frame-rate","frame-rate",-994918942).cljs$core$IFn$_invoke$arity$1(state));
+
+return state;
+});
+viz.core.scale = (function viz$core$scale(state,xy){
+return cljs.core.map_indexed.call(null,(function (p1__18292_SHARP_,p2__18291_SHARP_){
+return (p2__18291_SHARP_ * (viz.core.window_half_size.call(null,p1__18292_SHARP_) / viz.core.grid_size.call(null,state).call(null,p1__18292_SHARP_)));
+}),xy);
+});
+viz.core.in_bounds_QMARK_ = (function viz$core$in_bounds_QMARK_(min_bound,max_bound,pos){
+var pos_k = cljs.core.keep_indexed.call(null,(function (p1__18293_SHARP_,p2__18294_SHARP_){
+var mini = min_bound.call(null,p1__18293_SHARP_);
+var maxi = max_bound.call(null,p1__18293_SHARP_);
+if(((p2__18294_SHARP_ >= mini)) && ((p2__18294_SHARP_ <= maxi))){
+return p2__18294_SHARP_;
+} else {
+return null;
+}
+}),pos);
+return cljs.core._EQ_.call(null,cljs.core.count.call(null,pos),cljs.core.count.call(null,pos_k));
+});
+viz.core.quil_bounds = (function viz$core$quil_bounds(state,buffer){
+var vec__18299 = cljs.core.apply.call(null,cljs.core.vector,cljs.core.map.call(null,(function (p1__18295_SHARP_){
+return (p1__18295_SHARP_ - buffer);
+}),viz.core.grid_size.call(null,state)));
+var w = cljs.core.nth.call(null,vec__18299,(0),null);
+var h = cljs.core.nth.call(null,vec__18299,(1),null);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(- w),(- h)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [w,h], null)], null);
+});
+viz.core.ghost_incr = (function viz$core$ghost_incr(state){
+return cljs.core.assoc.call(null,state,new cljs.core.Keyword(null,"ghost","ghost",-1531157576),viz.ghost.filter_active_nodes.call(null,viz.ghost.incr.call(null,new cljs.core.Keyword(null,"ghost","ghost",-1531157576).cljs$core$IFn$_invoke$arity$1(state),viz.core.mk_poss_fn.call(null,state)),(function (p1__18302_SHARP_){
+var vec__18306 = viz.core.quil_bounds.call(null,state,(2));
+var minb = cljs.core.nth.call(null,vec__18306,(0),null);
+var maxb = cljs.core.nth.call(null,vec__18306,(1),null);
+return viz.core.in_bounds_QMARK_.call(null,minb,maxb,new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(p1__18302_SHARP_));
+})));
+});
+viz.core.ghost_expire_roots = (function viz$core$ghost_expire_roots(state){
+if(!((new cljs.core.Keyword(null,"tail-length","tail-length",-2007115089).cljs$core$IFn$_invoke$arity$1(state) < new cljs.core.Keyword(null,"frame","frame",-1711082588).cljs$core$IFn$_invoke$arity$1(state)))){
+return state;
+} else {
+return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576)], null),viz.ghost.remove_roots);
+}
+});
+viz.core.maybe_exit = (function viz$core$maybe_exit(state){
+if(cljs.core.empty_QMARK_.call(null,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751)], null)))){
+if((new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098).cljs$core$IFn$_invoke$arity$1(state) === (0))){
+return viz.core.new_state.call(null);
+} else {
+return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"exit-wait-frames","exit-wait-frames",1417213098)], null),cljs.core.dec);
+}
+} else {
+return state;
+}
+});
+viz.core.update_state = (function viz$core$update_state(state){
+return viz.core.maybe_exit.call(null,cljs.core.update_in.call(null,viz.core.ghost_expire_roots.call(null,viz.core.ghost_incr.call(null,state)),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"frame","frame",-1711082588)], null),cljs.core.inc));
+});
+viz.core.draw_ellipse = (function viz$core$draw_ellipse(state,pos,size){
+var scaled_pos = viz.core.scale.call(null,state,pos);
+var scaled_size = cljs.core.map.call(null,cljs.core.int$,viz.core.scale.call(null,state,size));
+return cljs.core.apply.call(null,quil.core.ellipse,cljs.core.concat.call(null,scaled_pos,scaled_size));
+});
+viz.core.in_line_QMARK_ = (function viz$core$in_line_QMARK_(var_args){
+var args__7934__auto__ = [];
+var len__7927__auto___18311 = arguments.length;
+var i__7928__auto___18312 = (0);
+while(true){
+if((i__7928__auto___18312 < len__7927__auto___18311)){
+args__7934__auto__.push((arguments[i__7928__auto___18312]));
+
+var G__18313 = (i__7928__auto___18312 + (1));
+i__7928__auto___18312 = G__18313;
+continue;
+} else {
+}
+break;
+}
+
+var argseq__7935__auto__ = ((((0) < args__7934__auto__.length))?(new cljs.core.IndexedSeq(args__7934__auto__.slice((0)),(0),null)):null);
+return viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic(argseq__7935__auto__);
+});
+
+viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic = (function (nodes){
+return cljs.core.apply.call(null,cljs.core._EQ_,cljs.core.map.call(null,(function (p1__18309_SHARP_){
+return cljs.core.apply.call(null,cljs.core.map,cljs.core._,p1__18309_SHARP_);
+}),cljs.core.partition.call(null,(2),(1),cljs.core.map.call(null,new cljs.core.Keyword(null,"pos","pos",-864607220),nodes))));
+});
+
+viz.core.in_line_QMARK_.cljs$lang$maxFixedArity = (0);
+
+viz.core.in_line_QMARK_.cljs$lang$applyTo = (function (seq18310){
+return viz.core.in_line_QMARK_.cljs$core$IFn$_invoke$arity$variadic(cljs.core.seq.call(null,seq18310));
+});
+
+viz.core.draw_lines = (function viz$core$draw_lines(state,forest,parent,node){
+
+quil.core.stroke.call(null,(4278190080));
+
+quil.core.fill.call(null,(4294967295));
+
+var children = cljs.core.map.call(null,(function (p1__18314_SHARP_){
+return viz.forest.get_node.call(null,forest,p1__18314_SHARP_);
+}),new cljs.core.Keyword(null,"child-ids","child-ids",-604525861).cljs$core$IFn$_invoke$arity$1(node));
+if(cljs.core.not.call(null,parent)){
+var seq__18325_18333 = cljs.core.seq.call(null,children);
+var chunk__18326_18334 = null;
+var count__18327_18335 = (0);
+var i__18328_18336 = (0);
+while(true){
+if((i__18328_18336 < count__18327_18335)){
+var child_18337 = cljs.core._nth.call(null,chunk__18326_18334,i__18328_18336);
+viz.core.draw_lines.call(null,state,forest,node,child_18337);
+
+var G__18338 = seq__18325_18333;
+var G__18339 = chunk__18326_18334;
+var G__18340 = count__18327_18335;
+var G__18341 = (i__18328_18336 + (1));
+seq__18325_18333 = G__18338;
+chunk__18326_18334 = G__18339;
+count__18327_18335 = G__18340;
+i__18328_18336 = G__18341;
+continue;
+} else {
+var temp__4657__auto___18342 = cljs.core.seq.call(null,seq__18325_18333);
+if(temp__4657__auto___18342){
+var seq__18325_18343__$1 = temp__4657__auto___18342;
+if(cljs.core.chunked_seq_QMARK_.call(null,seq__18325_18343__$1)){
+var c__7633__auto___18344 = cljs.core.chunk_first.call(null,seq__18325_18343__$1);
+var G__18345 = cljs.core.chunk_rest.call(null,seq__18325_18343__$1);
+var G__18346 = c__7633__auto___18344;
+var G__18347 = cljs.core.count.call(null,c__7633__auto___18344);
+var G__18348 = (0);
+seq__18325_18333 = G__18345;
+chunk__18326_18334 = G__18346;
+count__18327_18335 = G__18347;
+i__18328_18336 = G__18348;
+continue;
+} else {
+var child_18349 = cljs.core.first.call(null,seq__18325_18343__$1);
+viz.core.draw_lines.call(null,state,forest,node,child_18349);
+
+var G__18350 = cljs.core.next.call(null,seq__18325_18343__$1);
+var G__18351 = null;
+var G__18352 = (0);
+var G__18353 = (0);
+seq__18325_18333 = G__18350;
+chunk__18326_18334 = G__18351;
+count__18327_18335 = G__18352;
+i__18328_18336 = G__18353;
+continue;
+}
+} else {
+}
+}
+break;
+}
+} else {
+var in_line_child_18354 = cljs.core.some.call(null,((function (children){
+return (function (p1__18315_SHARP_){
+if(cljs.core.truth_(viz.core.in_line_QMARK_.call(null,parent,node,p1__18315_SHARP_))){
+return p1__18315_SHARP_;
+} else {
+return null;
+}
+});})(children))
+,children);
+var seq__18329_18355 = cljs.core.seq.call(null,children);
+var chunk__18330_18356 = null;
+var count__18331_18357 = (0);
+var i__18332_18358 = (0);
+while(true){
+if((i__18332_18358 < count__18331_18357)){
+var child_18359 = cljs.core._nth.call(null,chunk__18330_18356,i__18332_18358);
+if(cljs.core.truth_((function (){var and__6802__auto__ = in_line_child_18354;
+if(cljs.core.truth_(and__6802__auto__)){
+return cljs.core._EQ_.call(null,in_line_child_18354,child_18359);
+} else {
+return and__6802__auto__;
+}
+})())){
+viz.core.draw_lines.call(null,state,forest,parent,child_18359);
+} else {
+viz.core.draw_lines.call(null,state,forest,node,child_18359);
+}
+
+var G__18360 = seq__18329_18355;
+var G__18361 = chunk__18330_18356;
+var G__18362 = count__18331_18357;
+var G__18363 = (i__18332_18358 + (1));
+seq__18329_18355 = G__18360;
+chunk__18330_18356 = G__18361;
+count__18331_18357 = G__18362;
+i__18332_18358 = G__18363;
+continue;
+} else {
+var temp__4657__auto___18364 = cljs.core.seq.call(null,seq__18329_18355);
+if(temp__4657__auto___18364){
+var seq__18329_18365__$1 = temp__4657__auto___18364;
+if(cljs.core.chunked_seq_QMARK_.call(null,seq__18329_18365__$1)){
+var c__7633__auto___18366 = cljs.core.chunk_first.call(null,seq__18329_18365__$1);
+var G__18367 = cljs.core.chunk_rest.call(null,seq__18329_18365__$1);
+var G__18368 = c__7633__auto___18366;
+var G__18369 = cljs.core.count.call(null,c__7633__auto___18366);
+var G__18370 = (0);
+seq__18329_18355 = G__18367;
+chunk__18330_18356 = G__18368;
+count__18331_18357 = G__18369;
+i__18332_18358 = G__18370;
+continue;
+} else {
+var child_18371 = cljs.core.first.call(null,seq__18329_18365__$1);
+if(cljs.core.truth_((function (){var and__6802__auto__ = in_line_child_18354;
+if(cljs.core.truth_(and__6802__auto__)){
+return cljs.core._EQ_.call(null,in_line_child_18354,child_18371);
+} else {
+return and__6802__auto__;
+}
+})())){
+viz.core.draw_lines.call(null,state,forest,parent,child_18371);
+} else {
+viz.core.draw_lines.call(null,state,forest,node,child_18371);
+}
+
+var G__18372 = cljs.core.next.call(null,seq__18329_18365__$1);
+var G__18373 = null;
+var G__18374 = (0);
+var G__18375 = (0);
+seq__18329_18355 = G__18372;
+chunk__18330_18356 = G__18373;
+count__18331_18357 = G__18374;
+i__18332_18358 = G__18375;
+continue;
+}
+} else {
+}
+}
+break;
+}
+
+if(cljs.core.truth_(in_line_child_18354)){
+} else {
+cljs.core.apply.call(null,quil.core.line,cljs.core.apply.call(null,cljs.core.concat,cljs.core.map.call(null,((function (in_line_child_18354,children){
+return (function (p1__18316_SHARP_){
+return viz.core.scale.call(null,state,p1__18316_SHARP_);
+});})(in_line_child_18354,children))
+,cljs.core.map.call(null,new cljs.core.Keyword(null,"pos","pos",-864607220),(function (){var x__7656__auto__ = parent;
+return cljs.core._conj.call(null,(function (){var x__7656__auto____$1 = node;
+return cljs.core._conj.call(null,cljs.core.List.EMPTY,x__7656__auto____$1);
+})(),x__7656__auto__);
+})()))));
+}
+}
+
+if(cljs.core.empty_QMARK_.call(null,children)){
+return viz.core.draw_ellipse.call(null,state,new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(node),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.3,0.3], null));
+} else {
+return null;
+}
+});
+viz.core.draw_state = (function viz$core$draw_state(state){
+quil.core.background.call(null,(4294967295));
+
+var tr__8398__auto__ = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(viz.core.window_size.call(null,(0)) / (2)),(viz.core.window_size.call(null,(1)) / (2))], null);
+quil.core.push_matrix.call(null);
+
+try{quil.core.translate.call(null,tr__8398__auto__);
+
+var lines = viz.forest.lines.call(null,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"forest","forest",278860306)], null)));
+var leaves = viz.forest.leaves.call(null,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"forest","forest",278860306)], null)));
+var active = viz.ghost.active_nodes.call(null,new cljs.core.Keyword(null,"ghost","ghost",-1531157576).cljs$core$IFn$_invoke$arity$1(state));
+var roots = viz.forest.roots.call(null,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"forest","forest",278860306)], null)));
+quil.core.stroke.call(null,(4278190080));
+
+var seq__18384_18392 = cljs.core.seq.call(null,roots);
+var chunk__18385_18393 = null;
+var count__18386_18394 = (0);
+var i__18387_18395 = (0);
+while(true){
+if((i__18387_18395 < count__18386_18394)){
+var root_18396 = cljs.core._nth.call(null,chunk__18385_18393,i__18387_18395);
+viz.core.draw_lines.call(null,state,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"forest","forest",278860306)], null)),null,root_18396);
+
+var G__18397 = seq__18384_18392;
+var G__18398 = chunk__18385_18393;
+var G__18399 = count__18386_18394;
+var G__18400 = (i__18387_18395 + (1));
+seq__18384_18392 = G__18397;
+chunk__18385_18393 = G__18398;
+count__18386_18394 = G__18399;
+i__18387_18395 = G__18400;
+continue;
+} else {
+var temp__4657__auto___18401 = cljs.core.seq.call(null,seq__18384_18392);
+if(temp__4657__auto___18401){
+var seq__18384_18402__$1 = temp__4657__auto___18401;
+if(cljs.core.chunked_seq_QMARK_.call(null,seq__18384_18402__$1)){
+var c__7633__auto___18403 = cljs.core.chunk_first.call(null,seq__18384_18402__$1);
+var G__18404 = cljs.core.chunk_rest.call(null,seq__18384_18402__$1);
+var G__18405 = c__7633__auto___18403;
+var G__18406 = cljs.core.count.call(null,c__7633__auto___18403);
+var G__18407 = (0);
+seq__18384_18392 = G__18404;
+chunk__18385_18393 = G__18405;
+count__18386_18394 = G__18406;
+i__18387_18395 = G__18407;
+continue;
+} else {
+var root_18408 = cljs.core.first.call(null,seq__18384_18402__$1);
+viz.core.draw_lines.call(null,state,cljs.core.get_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"ghost","ghost",-1531157576),new cljs.core.Keyword(null,"forest","forest",278860306)], null)),null,root_18408);
+
+var G__18409 = cljs.core.next.call(null,seq__18384_18402__$1);
+var G__18410 = null;
+var G__18411 = (0);
+var G__18412 = (0);
+seq__18384_18392 = G__18409;
+chunk__18385_18393 = G__18410;
+count__18386_18394 = G__18411;
+i__18387_18395 = G__18412;
+continue;
+}
+} else {
+}
+}
+break;
+}
+
+quil.core.stroke.call(null,(4278190080));
+
+quil.core.fill.call(null,(4278190080));
+
+var seq__18388 = cljs.core.seq.call(null,active);
+var chunk__18389 = null;
+var count__18390 = (0);
+var i__18391 = (0);
+while(true){
+if((i__18391 < count__18390)){
+var active_node = cljs.core._nth.call(null,chunk__18389,i__18391);
+var pos_18413 = new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(active_node);
+viz.core.draw_ellipse.call(null,state,pos_18413,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.35,0.35], null));
+
+var G__18414 = seq__18388;
+var G__18415 = chunk__18389;
+var G__18416 = count__18390;
+var G__18417 = (i__18391 + (1));
+seq__18388 = G__18414;
+chunk__18389 = G__18415;
+count__18390 = G__18416;
+i__18391 = G__18417;
+continue;
+} else {
+var temp__4657__auto__ = cljs.core.seq.call(null,seq__18388);
+if(temp__4657__auto__){
+var seq__18388__$1 = temp__4657__auto__;
+if(cljs.core.chunked_seq_QMARK_.call(null,seq__18388__$1)){
+var c__7633__auto__ = cljs.core.chunk_first.call(null,seq__18388__$1);
+var G__18418 = cljs.core.chunk_rest.call(null,seq__18388__$1);
+var G__18419 = c__7633__auto__;
+var G__18420 = cljs.core.count.call(null,c__7633__auto__);
+var G__18421 = (0);
+seq__18388 = G__18418;
+chunk__18389 = G__18419;
+count__18390 = G__18420;
+i__18391 = G__18421;
+continue;
+} else {
+var active_node = cljs.core.first.call(null,seq__18388__$1);
+var pos_18422 = new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(active_node);
+viz.core.draw_ellipse.call(null,state,pos_18422,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [0.35,0.35], null));
+
+var G__18423 = cljs.core.next.call(null,seq__18388__$1);
+var G__18424 = null;
+var G__18425 = (0);
+var G__18426 = (0);
+seq__18388 = G__18423;
+chunk__18389 = G__18424;
+count__18390 = G__18425;
+i__18391 = G__18426;
+continue;
+}
+} else {
+return null;
+}
+}
+break;
+}
+}finally {quil.core.pop_matrix.call(null);
+}});
+viz.core.viz = (function viz$core$viz(){
+return quil.sketch.sketch.call(null,new cljs.core.Keyword(null,"host","host",-1558485167),"viz",new cljs.core.Keyword(null,"features","features",-1146962336),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"keep-on-top","keep-on-top",-970284267)], null),new cljs.core.Keyword(null,"update","update",1045576396),((cljs.core.fn_QMARK_.call(null,viz.core.update_state))?(function() {
+var G__18427__delegate = function (args){
+return cljs.core.apply.call(null,viz.core.update_state,args);
+};
+var G__18427 = function (var_args){
+var args = null;
+if (arguments.length > 0) {
+var G__18428__i = 0, G__18428__a = new Array(arguments.length - 0);
+while (G__18428__i < G__18428__a.length) {G__18428__a[G__18428__i] = arguments[G__18428__i + 0]; ++G__18428__i;}
+ args = new cljs.core.IndexedSeq(G__18428__a,0);
+}
+return G__18427__delegate.call(this,args);};
+G__18427.cljs$lang$maxFixedArity = 0;
+G__18427.cljs$lang$applyTo = (function (arglist__18429){
+var args = cljs.core.seq(arglist__18429);
+return G__18427__delegate(args);
+});
+G__18427.cljs$core$IFn$_invoke$arity$variadic = G__18427__delegate;
+return G__18427;
+})()
+:viz.core.update_state),new cljs.core.Keyword(null,"size","size",1098693007),((cljs.core.fn_QMARK_.call(null,viz.core.window_size))?(function() {
+var G__18430__delegate = function (args){
+return cljs.core.apply.call(null,viz.core.window_size,args);
+};
+var G__18430 = function (var_args){
+var args = null;
+if (arguments.length > 0) {
+var G__18431__i = 0, G__18431__a = new Array(arguments.length - 0);
+while (G__18431__i < G__18431__a.length) {G__18431__a[G__18431__i] = arguments[G__18431__i + 0]; ++G__18431__i;}
+ args = new cljs.core.IndexedSeq(G__18431__a,0);
+}
+return G__18430__delegate.call(this,args);};
+G__18430.cljs$lang$maxFixedArity = 0;
+G__18430.cljs$lang$applyTo = (function (arglist__18432){
+var args = cljs.core.seq(arglist__18432);
+return G__18430__delegate(args);
+});
+G__18430.cljs$core$IFn$_invoke$arity$variadic = G__18430__delegate;
+return G__18430;
+})()
+:viz.core.window_size),new cljs.core.Keyword(null,"title","title",636505583),"",new cljs.core.Keyword(null,"setup","setup",1987730512),((cljs.core.fn_QMARK_.call(null,viz.core.setup))?(function() {
+var G__18433__delegate = function (args){
+return cljs.core.apply.call(null,viz.core.setup,args);
+};
+var G__18433 = function (var_args){
+var args = null;
+if (arguments.length > 0) {
+var G__18434__i = 0, G__18434__a = new Array(arguments.length - 0);
+while (G__18434__i < G__18434__a.length) {G__18434__a[G__18434__i] = arguments[G__18434__i + 0]; ++G__18434__i;}
+ args = new cljs.core.IndexedSeq(G__18434__a,0);
+}
+return G__18433__delegate.call(this,args);};
+G__18433.cljs$lang$maxFixedArity = 0;
+G__18433.cljs$lang$applyTo = (function (arglist__18435){
+var args = cljs.core.seq(arglist__18435);
+return G__18433__delegate(args);
+});
+G__18433.cljs$core$IFn$_invoke$arity$variadic = G__18433__delegate;
+return G__18433;
+})()
+:viz.core.setup),new cljs.core.Keyword(null,"middleware","middleware",1462115504),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [quil.middleware.fun_mode], null),new cljs.core.Keyword(null,"draw","draw",1358331674),((cljs.core.fn_QMARK_.call(null,viz.core.draw_state))?(function() {
+var G__18436__delegate = function (args){
+return cljs.core.apply.call(null,viz.core.draw_state,args);
+};
+var G__18436 = function (var_args){
+var args = null;
+if (arguments.length > 0) {
+var G__18437__i = 0, G__18437__a = new Array(arguments.length - 0);
+while (G__18437__i < G__18437__a.length) {G__18437__a[G__18437__i] = arguments[G__18437__i + 0]; ++G__18437__i;}
+ args = new cljs.core.IndexedSeq(G__18437__a,0);
+}
+return G__18436__delegate.call(this,args);};
+G__18436.cljs$lang$maxFixedArity = 0;
+G__18436.cljs$lang$applyTo = (function (arglist__18438){
+var args = cljs.core.seq(arglist__18438);
+return G__18436__delegate(args);
+});
+G__18436.cljs$core$IFn$_invoke$arity$variadic = G__18436__delegate;
+return G__18436;
+})()
+:viz.core.draw_state));
+});
+goog.exportSymbol('viz.core.viz', viz.core.viz);
+
+if(cljs.core.truth_(cljs.core.some.call(null,(function (p1__8011__8012__auto__){
+return cljs.core._EQ_.call(null,new cljs.core.Keyword(null,"no-start","no-start",1381488856),p1__8011__8012__auto__);
+}),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"keep-on-top","keep-on-top",-970284267)], null)))){
+} else {
+quil.sketch.add_sketch_to_init_list.call(null,new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"fn","fn",-1175266204),viz.core.viz,new cljs.core.Keyword(null,"host-id","host-id",742376279),"viz"], null));
+}
+
+//# sourceMappingURL=core.js.map \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/core.js.map b/srv/src/http/static/viz/1/viz/core.js.map
new file mode 100644
index 0000000..3f7a997
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/core.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/viz\/core.js","sources":["core.cljs"],"lineCount":564,"mappings":";AAAA;;;;;;;;;AAWA,AAAA,iBAAA,yBAAAA,1CAAOM;AAAP,AAAA,IAAAL,qBAAA;AAAA,AAAA,IAAAC,0BAAA,AAAA;AAAA,AAAA,IAAAC,wBAAA;;AAAA,AAAA,GAAA,CAAAA,wBAAAD;AAAA,AAAA,AAAAD,wBAAA,CAAA,UAAAE;;AAAA,eAAA,CAAAA,wBAAA;;;;AAAA;;;;AAAA,IAAAC,uBAAA,EAAA,CAAA,MAAA,AAAAH,4BAAA,AAAA,KAAAI,qBAAA,AAAAJ,yBAAA,KAAA,IAAA,OAAA;AAAA,AAAA,OAAAK,oDAAAF;;;AAAA,AAAA,AAAA,AAAAE,sDAAA,WAAgBG;AAAhB,AACE,OAAMC,YAAW,8BAAA,9BAACC,kCAAwB,AAACC,wBAAIC,cAAIJ;;;AADrD,AAAA,AAAAH,yCAAA;;AAAA,AAAA,AAAAA,mCAAA,WAAAC;AAAA,AAAA,OAAAD,oDAAA,AAAAE,wBAAAD;;;AAAA,AAKA,0BAAA,1BAAOO,4DAAgBC;AAAvB,AACE,oDAAA,5CAAK,oCAAA,nCAAG,UAAA,TAAMC,4BAA8BD;;AAE9C,uBAAA,vBAAKE,0GAAc,iBAAAC,kBAAA;IAAAC,kBAAU,kCAAA,lCAACL;AAAX,AAAA,SAAAI,kBAAAC,mBAAAD,kBAAAC;KACA,8DAAA,7DAAK,qDAAA,pDAAG,kCAAA,lCAACL;AAE5B,AAAKM,4BAAiB,AAACC,0BAAMC,iBAAO,wBAAA,WAAAC,nCAACX;AAAD,AAAa,QAAAW,mBAAA;GAAUN;AAE3D,qBAAA,rBAAOO;AAAP,AAAA,kDAAA,iEAAA,KAAA,6EAAA,KAAA,oEAAA,KAAA,wDAAA,IAAA,mEAAA,IAAA,gEAAA,KAAA,4FAOc,AAACC,8BAAgBC,lEACjB,sFAAA,mFAAA,IAAA,7KAACC;;AAIf,uBAAA,vBAAOC,sDAAaC;AAApB,AACS,QAAG,AAAA,sFAAQA,SAAO,AAAA,+FAAaA;;AAExC,qBAAA,rBAAOC,kDAAWD;AAAlB,AACE,IAAME,IAAE,wLAAA,vLAAK,CAAG,+BAAA,\/BAACd,sCACM,CAAG,AAAA,8FAAaY,SAAO,+BAAA,\/BAACZ;AAD\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\/BAACrH,2CACJ,uCAAA,tCAAG,+BAAA,\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","names":["var_args","args__7934__auto__","len__7927__auto__","i__7928__auto__","argseq__7935__auto__","cljs.core\/IndexedSeq","viz.core\/debug","seq18286","cljs.core\/seq","args","js\/console","clojure.string\/join","cljs.core\/map","cljs.core\/str","viz.core\/window-partial","k","js\/document","viz.core\/window-size","x__7157__auto__","y__7158__auto__","viz.core\/window-half-size","cljs.core\/apply","cljs.core\/vector","p1__18290#","viz.core\/new-state","viz.ghost\/new-ghost","viz.grid\/euclidean","viz.ghost\/new-active-node","viz.core\/curr-second","state","viz.core\/grid-size","h","viz.core\/positive","n","viz.core\/spawn-chance","period-seconds","period-frames","cljs.core\/rem","viz.core\/mk-poss-fn","pos","adj-poss","cljs.core\/take","cljs.core\/random-sample","viz.core\/setup","quil.core\/frame-rate","viz.core\/scale","xy","p1__18292#","p2__18291#","cljs.core\/map-indexed","viz.core\/in-bounds?","min-bound","max-bound","pos-k","p1__18293#","p2__18294#","cljs.core\/keep-indexed","mini","maxi","cljs.core\/=","cljs.core\/count","viz.core\/quil-bounds","buffer","vec__18299","cljs.core\/nth","w","p1__18295#","viz.core\/ghost-incr","cljs.core\/assoc","p1__18302#","viz.ghost\/filter-active-nodes","viz.ghost\/incr","vec__18306","minb","maxb","viz.core\/ghost-expire-roots","cljs.core\/update-in","viz.ghost\/remove-roots","viz.core\/maybe-exit","cljs.core\/empty?","cljs.core\/get-in","cljs.core\/dec","viz.core\/update-state","cljs.core\/inc","viz.core\/draw-ellipse","size","scaled-pos","scaled-size","cljs.core\/int","quil.core\/ellipse","cljs.core\/concat","viz.core\/in-line?","seq18310","nodes","p1__18309#","cljs.core\/-","cljs.core\/partition","viz.core\/draw-lines","forest","parent","node","quil.core\/stroke","quil.core\/fill","children","p1__18314#","viz.forest\/get-node","cljs.core\/not","seq__18325","chunk__18326","count__18327","i__18328","cljs.core\/-nth","temp__4657__auto__","cljs.core\/chunked-seq?","c__7633__auto__","cljs.core\/chunk-first","cljs.core\/chunk-rest","cljs.core\/first","cljs.core\/next","child","in-line-child","p1__18315#","cljs.core\/some","seq__18329","chunk__18330","count__18331","i__18332","and__6802__auto__","quil.core\/line","p1__18316#","x__7656__auto__","cljs.core\/-conj","viz.core\/draw-state","quil.core\/background","tr__8398__auto__","quil.core\/push-matrix","quil.core\/translate","quil.core\/pop-matrix","lines","viz.forest\/lines","leaves","viz.forest\/leaves","active","viz.ghost\/active-nodes","roots","viz.forest\/roots","seq__18384","chunk__18385","count__18386","i__18387","root","seq__18388","chunk__18389","count__18390","i__18391","active-node","quil.sketch\/sketch","cljs.core\/fn?","p1__8011__8012__auto__","quil.sketch\/add-sketch-to-init-list","viz.core\/viz","quil.middleware\/fun-mode","cljs.core\/List"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/forest.cljs b/srv/src/http/static/viz/1/viz/forest.cljs
new file mode 100644
index 0000000..9810089
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/forest.cljs
@@ -0,0 +1,96 @@
+(ns viz.forest)
+
+(defn new-forest []
+ {:nodes {}
+ :roots #{}
+ :leaves #{}
+ :next-id 0})
+
+(defn- new-id [forest]
+ (let [id (:next-id forest)]
+ [(assoc forest :next-id (inc id))
+ id]))
+
+(defn- unset-parent [forest id parent-id]
+ (-> forest
+ (update-in [:nodes id] dissoc :parent-id :parent-pos)
+ (update-in [:nodes parent-id :child-ids] disj id)
+ (update-in [:roots] conj id)
+ (update-in [:leaves] conj parent-id)
+ ))
+
+(defn- set-parent [forest id parent-id]
+ (let [parent-pos (get-in forest [:nodes parent-id :pos])
+ prev-parent-id (get-in forest [:nodes id :parent-id])
+ ]
+ (-> forest
+ (assoc-in [:nodes id :parent-id] parent-id)
+ (assoc-in [:nodes id :parent-pos] parent-pos)
+ (update-in [:nodes parent-id :child-ids] #(if %1 (conj %1 id) #{id}))
+ (update-in [:roots] disj id)
+ (update-in [:leaves] disj parent-id)
+ ;; If there was a previous parent of the child, unset that shit
+ (#(if prev-parent-id (unset-parent %1 id prev-parent-id) %1))
+ )))
+
+(defn add-node [forest pos]
+ (let [[forest id] (new-id forest)
+ forest (-> forest
+ (assoc-in [:nodes id] {:id id :pos pos})
+ (update-in [:roots] conj id)
+ (update-in [:leaves] conj id)
+ )
+ ]
+ [forest id]))
+
+(defn remove-node [forest id]
+ (let [child-ids (get-in forest [:nodes id :child-ids])
+ parent-id (get-in forest [:nodes id :parent-id])]
+ (-> forest
+ ;; unset this node's parent, if it has one
+ (#(if parent-id (unset-parent %1 id parent-id) %1))
+ ;; unset this node's children, if it has any
+ ((fn [forest] (reduce #(unset-parent %1 %2 id) forest child-ids)))
+ ;; remove from all top-level sets
+ (update-in [:nodes] dissoc id)
+ (update-in [:roots] disj id)
+ (update-in [:leaves] disj id)
+ )))
+
+(defn get-node [forest id]
+ (get-in forest [:nodes id]))
+
+(defn spawn-child [forest parent-id pos]
+ (let [[forest id] (add-node forest pos)
+ forest (-> forest
+ (set-parent id parent-id)
+ )
+ ]
+ [forest id]))
+
+(defn roots [forest] (-> forest :nodes (select-keys (:roots forest)) (vals)))
+(defn root? [node] (not (boolean (:parent-id node))))
+
+(defn leaves [forest] (-> forest :nodes (select-keys (:leaves forest)) (vals)))
+(defn leaf? [node] (empty? (:child-ids node)))
+
+(defn lines [forest]
+ (->> forest
+ (:nodes)
+ (vals)
+ (remove #(empty? (:parent-pos %)))
+ (map #(vector (:pos %) (:parent-pos %)))
+ ))
+
+(def my-forest
+ (let [forest (new-forest)
+ [forest id0] (add-node forest [0 0])
+ [forest id1] (spawn-child forest id0 [1 1])
+ [forest id2] (spawn-child forest id0 [-1 -1])
+ [forest id3] (spawn-child forest id1 [2 2])
+ forest (remove-node forest id1)
+ ]
+ forest))
+
+(identity my-forest)
+(lines my-forest)
diff --git a/srv/src/http/static/viz/1/viz/forest.cljs.cache.edn b/srv/src/http/static/viz/1/viz/forest.cljs.cache.edn
new file mode 100644
index 0000000..61b1a40
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/forest.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :use-macros {}, :excludes #{}, :name viz.forest, :imports nil, :requires nil, :uses nil, :defs {get-node {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 60, :column 7, :end-line 60, :end-column 15, :arglists (quote ([forest id]))}, :name viz.forest/get-node, :variadic false, :file "src/viz/forest.cljs", :end-column 15, :method-params ([forest id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 60, :end-line 60, :max-fixed-arity 2, :fn-var true, :arglists (quote ([forest id]))}, add-node {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 36, :column 7, :end-line 36, :end-column 15, :arglists (quote ([forest pos]))}, :name viz.forest/add-node, :variadic false, :file "src/viz/forest.cljs", :end-column 15, :method-params ([forest pos]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 36, :end-line 36, :max-fixed-arity 2, :fn-var true, :arglists (quote ([forest pos]))}, set-parent {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 22, :column 8, :end-line 22, :end-column 18, :private true, :arglists (quote ([forest id parent-id]))}, :private true, :name viz.forest/set-parent, :variadic false, :file "src/viz/forest.cljs", :end-column 18, :method-params ([forest id parent-id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 22, :end-line 22, :max-fixed-arity 3, :fn-var true, :arglists (quote ([forest id parent-id]))}, new-id {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 9, :column 8, :end-line 9, :end-column 14, :private true, :arglists (quote ([forest]))}, :private true, :name viz.forest/new-id, :variadic false, :file "src/viz/forest.cljs", :end-column 14, :method-params ([forest]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 9, :end-line 9, :max-fixed-arity 1, :fn-var true, :arglists (quote ([forest]))}, root? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 72, :column 7, :end-line 72, :end-column 12, :arglists (quote ([node]))}, :name viz.forest/root?, :variadic false, :file "src/viz/forest.cljs", :end-column 12, :method-params ([node]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 72, :end-line 72, :max-fixed-arity 1, :fn-var true, :arglists (quote ([node]))}, my-forest {:name viz.forest/my-forest, :file "src/viz/forest.cljs", :line 85, :column 1, :end-line 85, :end-column 15, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 85, :column 6, :end-line 85, :end-column 15}, :tag any}, new-forest {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 3, :column 7, :end-line 3, :end-column 17, :arglists (quote ([]))}, :name viz.forest/new-forest, :variadic false, :file "src/viz/forest.cljs", :end-column 17, :method-params ([]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 3, :end-line 3, :max-fixed-arity 0, :fn-var true, :arglists (quote ([]))}, remove-node {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 46, :column 7, :end-line 46, :end-column 18, :arglists (quote ([forest id]))}, :name viz.forest/remove-node, :variadic false, :file "src/viz/forest.cljs", :end-column 18, :method-params ([forest id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 46, :end-line 46, :max-fixed-arity 2, :fn-var true, :arglists (quote ([forest id]))}, spawn-child {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 63, :column 7, :end-line 63, :end-column 18, :arglists (quote ([forest parent-id pos]))}, :name viz.forest/spawn-child, :variadic false, :file "src/viz/forest.cljs", :end-column 18, :method-params ([forest parent-id pos]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 63, :end-line 63, :max-fixed-arity 3, :fn-var true, :arglists (quote ([forest parent-id pos]))}, lines {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 77, :column 7, :end-line 77, :end-column 12, :arglists (quote ([forest]))}, :name viz.forest/lines, :variadic false, :file "src/viz/forest.cljs", :end-column 12, :method-params ([forest]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 77, :end-line 77, :max-fixed-arity 1, :fn-var true, :arglists (quote ([forest]))}, unset-parent {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 14, :column 8, :end-line 14, :end-column 20, :private true, :arglists (quote ([forest id parent-id]))}, :private true, :name viz.forest/unset-parent, :variadic false, :file "src/viz/forest.cljs", :end-column 20, :method-params ([forest id parent-id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 14, :end-line 14, :max-fixed-arity 3, :fn-var true, :arglists (quote ([forest id parent-id]))}, roots {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 71, :column 7, :end-line 71, :end-column 12, :arglists (quote ([forest]))}, :name viz.forest/roots, :variadic false, :file "src/viz/forest.cljs", :end-column 12, :method-params ([forest]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 71, :end-line 71, :max-fixed-arity 1, :fn-var true, :arglists (quote ([forest]))}, leaves {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 74, :column 7, :end-line 74, :end-column 13, :arglists (quote ([forest]))}, :name viz.forest/leaves, :variadic false, :file "src/viz/forest.cljs", :end-column 13, :method-params ([forest]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 74, :end-line 74, :max-fixed-arity 1, :fn-var true, :arglists (quote ([forest]))}, leaf? {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/forest.cljs", :line 75, :column 7, :end-line 75, :end-column 12, :arglists (quote ([node]))}, :name viz.forest/leaf?, :variadic false, :file "src/viz/forest.cljs", :end-column 12, :method-params ([node]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 75, :end-line 75, :max-fixed-arity 1, :fn-var true, :arglists (quote ([node]))}}, :require-macros nil, :cljs.analyzer/constants {:seen #{:next-id :parent-pos :pos :roots :leaves :nodes :id :parent-id :child-ids}, :order [:nodes :roots :leaves :next-id :parent-id :parent-pos :child-ids :pos :id]}, :doc nil} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/forest.js b/srv/src/http/static/viz/1/viz/forest.js
new file mode 100644
index 0000000..0eb043a
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/forest.js
@@ -0,0 +1,111 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('viz.forest');
+goog.require('cljs.core');
+viz.forest.new_forest = (function viz$forest$new_forest(){
+return new cljs.core.PersistentArrayMap(null, 4, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),cljs.core.PersistentArrayMap.EMPTY,new cljs.core.Keyword(null,"roots","roots",-1088919250),cljs.core.PersistentHashSet.EMPTY,new cljs.core.Keyword(null,"leaves","leaves",-2143630574),cljs.core.PersistentHashSet.EMPTY,new cljs.core.Keyword(null,"next-id","next-id",-224240762),(0)], null);
+});
+viz.forest.new_id = (function viz$forest$new_id(forest){
+var id = new cljs.core.Keyword(null,"next-id","next-id",-224240762).cljs$core$IFn$_invoke$arity$1(forest);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.assoc.call(null,forest,new cljs.core.Keyword(null,"next-id","next-id",-224240762),(id + (1))),id], null);
+});
+viz.forest.unset_parent = (function viz$forest$unset_parent(forest,id,parent_id){
+return cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,forest,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id], null),cljs.core.dissoc,new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131),new cljs.core.Keyword(null,"parent-pos","parent-pos",-282368566)),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),parent_id,new cljs.core.Keyword(null,"child-ids","child-ids",-604525861)], null),cljs.core.disj,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"roots","roots",-1088919250)], null),cljs.core.conj,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"leaves","leaves",-2143630574)], null),cljs.core.conj,parent_id);
+});
+viz.forest.set_parent = (function viz$forest$set_parent(forest,id,parent_id){
+var parent_pos = cljs.core.get_in.call(null,forest,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),parent_id,new cljs.core.Keyword(null,"pos","pos",-864607220)], null));
+var prev_parent_id = cljs.core.get_in.call(null,forest,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id,new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131)], null));
+return ((function (parent_pos,prev_parent_id){
+return (function (p1__7982_SHARP_){
+if(cljs.core.truth_(prev_parent_id)){
+return viz.forest.unset_parent.call(null,p1__7982_SHARP_,id,prev_parent_id);
+} else {
+return p1__7982_SHARP_;
+}
+});})(parent_pos,prev_parent_id))
+.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.assoc_in.call(null,cljs.core.assoc_in.call(null,forest,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id,new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131)], null),parent_id),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id,new cljs.core.Keyword(null,"parent-pos","parent-pos",-282368566)], null),parent_pos),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),parent_id,new cljs.core.Keyword(null,"child-ids","child-ids",-604525861)], null),((function (parent_pos,prev_parent_id){
+return (function (p1__7981_SHARP_){
+if(cljs.core.truth_(p1__7981_SHARP_)){
+return cljs.core.conj.call(null,p1__7981_SHARP_,id);
+} else {
+return cljs.core.PersistentHashSet.createAsIfByAssoc([id], true);
+}
+});})(parent_pos,prev_parent_id))
+),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"roots","roots",-1088919250)], null),cljs.core.disj,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"leaves","leaves",-2143630574)], null),cljs.core.disj,parent_id));
+});
+viz.forest.add_node = (function viz$forest$add_node(forest,pos){
+var vec__7986 = viz.forest.new_id.call(null,forest);
+var forest__$1 = cljs.core.nth.call(null,vec__7986,(0),null);
+var id = cljs.core.nth.call(null,vec__7986,(1),null);
+var forest__$2 = cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.assoc_in.call(null,forest__$1,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id], null),new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"id","id",-1388402092),id,new cljs.core.Keyword(null,"pos","pos",-864607220),pos], null)),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"roots","roots",-1088919250)], null),cljs.core.conj,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"leaves","leaves",-2143630574)], null),cljs.core.conj,id);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [forest__$2,id], null);
+});
+viz.forest.remove_node = (function viz$forest$remove_node(forest,id){
+var child_ids = cljs.core.get_in.call(null,forest,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id,new cljs.core.Keyword(null,"child-ids","child-ids",-604525861)], null));
+var parent_id = cljs.core.get_in.call(null,forest,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id,new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131)], null));
+return cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,((function (child_ids,parent_id){
+return (function (forest__$1){
+return cljs.core.reduce.call(null,((function (child_ids,parent_id){
+return (function (p1__7990_SHARP_,p2__7991_SHARP_){
+return viz.forest.unset_parent.call(null,p1__7990_SHARP_,p2__7991_SHARP_,id);
+});})(child_ids,parent_id))
+,forest__$1,child_ids);
+});})(child_ids,parent_id))
+.call(null,((function (child_ids,parent_id){
+return (function (p1__7989_SHARP_){
+if(cljs.core.truth_(parent_id)){
+return viz.forest.unset_parent.call(null,p1__7989_SHARP_,id,parent_id);
+} else {
+return p1__7989_SHARP_;
+}
+});})(child_ids,parent_id))
+.call(null,forest)),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805)], null),cljs.core.dissoc,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"roots","roots",-1088919250)], null),cljs.core.disj,id),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"leaves","leaves",-2143630574)], null),cljs.core.disj,id);
+});
+viz.forest.get_node = (function viz$forest$get_node(forest,id){
+return cljs.core.get_in.call(null,forest,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"nodes","nodes",-2099585805),id], null));
+});
+viz.forest.spawn_child = (function viz$forest$spawn_child(forest,parent_id,pos){
+var vec__7995 = viz.forest.add_node.call(null,forest,pos);
+var forest__$1 = cljs.core.nth.call(null,vec__7995,(0),null);
+var id = cljs.core.nth.call(null,vec__7995,(1),null);
+var forest__$2 = viz.forest.set_parent.call(null,forest__$1,id,parent_id);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [forest__$2,id], null);
+});
+viz.forest.roots = (function viz$forest$roots(forest){
+return cljs.core.vals.call(null,cljs.core.select_keys.call(null,new cljs.core.Keyword(null,"nodes","nodes",-2099585805).cljs$core$IFn$_invoke$arity$1(forest),new cljs.core.Keyword(null,"roots","roots",-1088919250).cljs$core$IFn$_invoke$arity$1(forest)));
+});
+viz.forest.root_QMARK_ = (function viz$forest$root_QMARK_(node){
+return !(cljs.core.boolean$.call(null,new cljs.core.Keyword(null,"parent-id","parent-id",-1400729131).cljs$core$IFn$_invoke$arity$1(node)));
+});
+viz.forest.leaves = (function viz$forest$leaves(forest){
+return cljs.core.vals.call(null,cljs.core.select_keys.call(null,new cljs.core.Keyword(null,"nodes","nodes",-2099585805).cljs$core$IFn$_invoke$arity$1(forest),new cljs.core.Keyword(null,"leaves","leaves",-2143630574).cljs$core$IFn$_invoke$arity$1(forest)));
+});
+viz.forest.leaf_QMARK_ = (function viz$forest$leaf_QMARK_(node){
+return cljs.core.empty_QMARK_.call(null,new cljs.core.Keyword(null,"child-ids","child-ids",-604525861).cljs$core$IFn$_invoke$arity$1(node));
+});
+viz.forest.lines = (function viz$forest$lines(forest){
+return cljs.core.map.call(null,(function (p1__7999_SHARP_){
+return (new cljs.core.PersistentVector(null,2,(5),cljs.core.PersistentVector.EMPTY_NODE,[new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(p1__7999_SHARP_),new cljs.core.Keyword(null,"parent-pos","parent-pos",-282368566).cljs$core$IFn$_invoke$arity$1(p1__7999_SHARP_)],null));
+}),cljs.core.remove.call(null,(function (p1__7998_SHARP_){
+return cljs.core.empty_QMARK_.call(null,new cljs.core.Keyword(null,"parent-pos","parent-pos",-282368566).cljs$core$IFn$_invoke$arity$1(p1__7998_SHARP_));
+}),cljs.core.vals.call(null,new cljs.core.Keyword(null,"nodes","nodes",-2099585805).cljs$core$IFn$_invoke$arity$1(forest))));
+});
+viz.forest.my_forest = (function (){var forest = viz.forest.new_forest.call(null);
+var vec__8000 = viz.forest.add_node.call(null,forest,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null));
+var forest__$1 = cljs.core.nth.call(null,vec__8000,(0),null);
+var id0 = cljs.core.nth.call(null,vec__8000,(1),null);
+var vec__8003 = viz.forest.spawn_child.call(null,forest__$1,id0,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(1),(1)], null));
+var forest__$2 = cljs.core.nth.call(null,vec__8003,(0),null);
+var id1 = cljs.core.nth.call(null,vec__8003,(1),null);
+var vec__8006 = viz.forest.spawn_child.call(null,forest__$2,id0,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(-1),(-1)], null));
+var forest__$3 = cljs.core.nth.call(null,vec__8006,(0),null);
+var id2 = cljs.core.nth.call(null,vec__8006,(1),null);
+var vec__8009 = viz.forest.spawn_child.call(null,forest__$3,id1,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(2),(2)], null));
+var forest__$4 = cljs.core.nth.call(null,vec__8009,(0),null);
+var id3 = cljs.core.nth.call(null,vec__8009,(1),null);
+var forest__$5 = viz.forest.remove_node.call(null,forest__$4,id1);
+return forest__$5;
+})();
+cljs.core.identity.call(null,viz.forest.my_forest);
+viz.forest.lines.call(null,viz.forest.my_forest);
+
+//# sourceMappingURL=forest.js.map \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/forest.js.map b/srv/src/http/static/viz/1/viz/forest.js.map
new file mode 100644
index 0000000..e531b5e
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/forest.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/viz\/forest.js","sources":["forest.cljs"],"lineCount":111,"mappings":";AAAA;;AAEA,wBAAA,xBAAMA;AAAN,AAAA,kDAAA,wDAAA,mCAAA,wDAAA,kCAAA,0DAAA,kCAAA,2DAAA;;AAMA,oBAAA,pBAAOC,gDAAQC;AAAf,AACE,IAAMC,KAAG,AAAA,yFAAUD;AAAnB,AAAA,0FACG,iCAAA,jCAACE,0BAAMF,kEAAgB,MAAA,LAAKC,WAC5BA;;AAEL,0BAAA,1BAAOE,4DAAcH,OAAOC,GAAGG;AAA\/B,+HACMJ,9BACA,qCAAA,mFAAA,oFAAA,gEAAA,5QAACK,gLAAkBJ,WAAIK,zNACvB,4WAAA,mFAAA,kEAAA,jgBAACD,ufAAkBD,iFAAsBG,eAAKN,rnBAC9C,ynBAAA,mFAAA,5sBAACI,4wBAAmBG,eAAKP,h0BACzB,o0BAAA,mFAAA,h5BAACI,k9BAAoBG,eAAKJ;;AAGhC,wBAAA,xBAAOK,wDAAYT,OAAOC,GAAGG;AAA7B,AACE,IAAMM,aAAW,kCAAA,mFAAA,kEAAA,vLAACC,2BAAOX,kJAAeI;IAClCQ,iBAAe,kCAAA,mFAAA,2DAAA,hLAACD,2BAAOX,kJAAeC;AAD5C,AAUM,OAAA;kBAAAc;AAAA,AAAE,oBAAIH;AAAe,yCAAAG,lCAACZ,kDAAgBF,GAAGW;;AAAvCG;;;+JAPFf,7BACA,oCAAA,mFAAA,2DAAA,lLAACa,+KAAiBZ,2EAAeG,vRACjC,kSAAA,mFAAA,2DAAA,hbAACS,6aAAiBZ,4EAAgBS,vhBAClC,miBAAA,mFAAA,kEAAA,uEAAA,\/vBAACL,8qBAAkBD,5sBACnB,AAACC,9BACD,AAACA;kBAFDS;AAAA,AAA0C,oBAAAA;AAAO,gCAAAA,zBAACN,yCAAQP;;AAAhB,sDAAsBA;;;EAChE,mFAAA,gEAAoBM,eAAKN,IACzB,mFAAA,kEAAqBM,eAAKH;;AAKlC,sBAAA,tBAAMY,oDAAUhB,OAAOiB;AAAvB,AACE,IAAAC,YAAkB,AAACnB,4BAAOC;iBAA1B,AAAAmB,wBAAAD,UAAA,IAAA,nDAAOlB;SAAP,AAAAmB,wBAAAD,UAAA,IAAA,3CAAcjB;IACRD,sGAAWA,7BACA,wCAAA,mFAAA,mEAAA,2CAAA,qDAAA,9RAACa,mLAAiBZ,wGAASA,sDAAQgB,\/WACnC,4XAAA,mFAAA,\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","names":["viz.forest\/new-forest","viz.forest\/new-id","forest","id","cljs.core\/assoc","viz.forest\/unset-parent","parent-id","cljs.core\/update-in","cljs.core\/dissoc","cljs.core\/disj","cljs.core\/conj","viz.forest\/set-parent","parent-pos","cljs.core\/get-in","prev-parent-id","cljs.core\/assoc-in","p1__7981#","p1__7982#","viz.forest\/add-node","pos","vec__7986","cljs.core\/nth","viz.forest\/remove-node","child-ids","p1__7989#","p1__7990#","p2__7991#","cljs.core\/reduce","viz.forest\/get-node","viz.forest\/spawn-child","vec__7995","viz.forest\/roots","cljs.core\/select-keys","cljs.core\/vals","viz.forest\/root?","node","cljs.core\/boolean","viz.forest\/leaves","viz.forest\/leaf?","cljs.core\/empty?","viz.forest\/lines","p1__7998#","cljs.core\/remove","p1__7999#","cljs.core\/map","cljs.core\/PersistentVector","viz.forest\/my-forest","vec__8000","vec__8003","vec__8006","vec__8009","id0","id1","id2","id3","cljs.core\/identity"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/ghost.cljs b/srv/src/http/static/viz/1/viz/ghost.cljs
new file mode 100644
index 0000000..ca6f86c
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/ghost.cljs
@@ -0,0 +1,72 @@
+(ns viz.ghost
+ (:require [viz.forest :as forest]
+ [viz.grid :as grid]
+ clojure.set))
+
+(defn new-ghost [grid-def]
+ { :grid (grid/new-grid grid-def)
+ :forest (forest/new-forest)
+ :active-node-ids #{}
+ })
+
+(defn new-active-node [ghost pos]
+ (let [[forest id] (forest/add-node (:forest ghost) pos)
+ grid (grid/add-point (:grid ghost) pos)]
+ (-> ghost
+ (assoc :grid grid :forest forest)
+ (update-in [:active-node-ids] conj id))))
+
+(defn- gen-new-poss [ghost poss-fn id]
+ "generates new positions branching from the given node"
+ (let [pos (:pos (forest/get-node (:forest ghost) id))
+ adj-poss (grid/empty-adjacent-points (:grid ghost) pos)]
+ (poss-fn pos adj-poss)))
+
+(defn- spawn-children [ghost poss-fn id]
+ (reduce (fn [[ghost new-ids] pos]
+ (let [[forest new-id] (forest/spawn-child (:forest ghost) id pos)
+ grid (grid/add-point (:grid ghost) pos)]
+ [(assoc ghost :forest forest :grid grid) (conj new-ids new-id)]))
+ [ghost #{}]
+ (gen-new-poss ghost poss-fn id)))
+
+(defn- spawn-children-multi [ghost poss-fn ids]
+ (reduce (fn [[ghost new-ids] id]
+ (let [[ghost this-new-ids] (spawn-children ghost poss-fn id)]
+ [ghost (clojure.set/union new-ids this-new-ids)]))
+ [ghost #{}]
+ ids))
+
+(defn incr [ghost poss-fn]
+ (let [[ghost new-ids] (spawn-children-multi ghost poss-fn (:active-node-ids ghost))]
+ (assoc ghost :active-node-ids new-ids)))
+
+(defn active-nodes [ghost]
+ (map #(get-in ghost [:forest :nodes %]) (:active-node-ids ghost)))
+
+(defn filter-active-nodes [ghost pred]
+ (assoc ghost :active-node-ids
+ (reduce #(if (pred %2) (conj %1 (:id %2)) %1) #{}
+ (active-nodes ghost))))
+
+(defn remove-roots [ghost]
+ (let [roots (forest/roots (:forest ghost))
+ root-ids (map :id roots)
+ root-poss (map :pos roots)
+ ]
+ (-> ghost
+ (update-in [:active-node-ids] #(reduce disj %1 root-ids))
+ (update-in [:forest] #(reduce forest/remove-node %1 root-ids))
+ (update-in [:grid] #(reduce grid/rm-point %1 root-poss))
+ )))
+
+(defn- eg-poss-fn [pos adj-poss]
+ (take 2 (random-sample 0.6 adj-poss)))
+
+(-> (new-ghost grid/euclidean)
+ (new-active-node [0 0])
+ (incr eg-poss-fn)
+ (incr eg-poss-fn)
+ (incr eg-poss-fn)
+ (remove-roots)
+ )
diff --git a/srv/src/http/static/viz/1/viz/ghost.cljs.cache.edn b/srv/src/http/static/viz/1/viz/ghost.cljs.cache.edn
new file mode 100644
index 0000000..5762f9a
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/ghost.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :use-macros {}, :excludes #{}, :name viz.ghost, :imports nil, :requires {forest viz.forest, viz.forest viz.forest, grid viz.grid, viz.grid viz.grid, clojure.set clojure.set}, :uses nil, :defs {active-nodes {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 44, :column 7, :end-line 44, :end-column 19, :arglists (quote ([ghost]))}, :name viz.ghost/active-nodes, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 19, :method-params ([ghost]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 44, :end-line 44, :max-fixed-arity 1, :fn-var true, :arglists (quote ([ghost]))}, filter-active-nodes {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 47, :column 7, :end-line 47, :end-column 26, :arglists (quote ([ghost pred]))}, :name viz.ghost/filter-active-nodes, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 26, :method-params ([ghost pred]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 47, :end-line 47, :max-fixed-arity 2, :fn-var true, :arglists (quote ([ghost pred]))}, spawn-children {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 25, :column 8, :end-line 25, :end-column 22, :private true, :arglists (quote ([ghost poss-fn id]))}, :private true, :name viz.ghost/spawn-children, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 22, :method-params ([ghost poss-fn id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 25, :end-line 25, :max-fixed-arity 3, :fn-var true, :arglists (quote ([ghost poss-fn id]))}, spawn-children-multi {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 33, :column 8, :end-line 33, :end-column 28, :private true, :arglists (quote ([ghost poss-fn ids]))}, :private true, :name viz.ghost/spawn-children-multi, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 28, :method-params ([ghost poss-fn ids]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 33, :end-line 33, :max-fixed-arity 3, :fn-var true, :arglists (quote ([ghost poss-fn ids]))}, incr {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 40, :column 7, :end-line 40, :end-column 11, :arglists (quote ([ghost poss-fn]))}, :name viz.ghost/incr, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 11, :method-params ([ghost poss-fn]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 40, :end-line 40, :max-fixed-arity 2, :fn-var true, :arglists (quote ([ghost poss-fn]))}, eg-poss-fn {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 63, :column 8, :end-line 63, :end-column 18, :private true, :arglists (quote ([pos adj-poss]))}, :private true, :name viz.ghost/eg-poss-fn, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 18, :method-params ([pos adj-poss]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 63, :end-line 63, :max-fixed-arity 2, :fn-var true, :arglists (quote ([pos adj-poss]))}, gen-new-poss {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 19, :column 8, :end-line 19, :end-column 20, :private true, :arglists (quote ([ghost poss-fn id]))}, :private true, :name viz.ghost/gen-new-poss, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 20, :method-params ([ghost poss-fn id]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 19, :end-line 19, :max-fixed-arity 3, :fn-var true, :arglists (quote ([ghost poss-fn id]))}, new-ghost {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 6, :column 7, :end-line 6, :end-column 16, :arglists (quote ([grid-def]))}, :name viz.ghost/new-ghost, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 16, :method-params ([grid-def]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 6, :end-line 6, :max-fixed-arity 1, :fn-var true, :arglists (quote ([grid-def]))}, remove-roots {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 52, :column 7, :end-line 52, :end-column 19, :arglists (quote ([ghost]))}, :name viz.ghost/remove-roots, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 19, :method-params ([ghost]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 52, :end-line 52, :max-fixed-arity 1, :fn-var true, :arglists (quote ([ghost]))}, new-active-node {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :line 12, :column 7, :end-line 12, :end-column 22, :arglists (quote ([ghost pos]))}, :name viz.ghost/new-active-node, :variadic false, :file "/home/mediocregopher/src/viz/src/viz/ghost.cljs", :end-column 22, :method-params ([ghost pos]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 12, :end-line 12, :max-fixed-arity 2, :fn-var true, :arglists (quote ([ghost pos]))}}, :require-macros nil, :cljs.analyzer/constants {:seen #{:active-node-ids :grid :pos :forest :nodes :id}, :order [:grid :forest :active-node-ids :pos :nodes :id]}, :doc nil} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/ghost.js b/srv/src/http/static/viz/1/viz/ghost.js
new file mode 100644
index 0000000..50b8157
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/ghost.js
@@ -0,0 +1,89 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('viz.ghost');
+goog.require('cljs.core');
+goog.require('viz.forest');
+goog.require('viz.grid');
+goog.require('clojure.set');
+viz.ghost.new_ghost = (function viz$ghost$new_ghost(grid_def){
+return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"grid","grid",402978600),viz.grid.new_grid.call(null,grid_def),new cljs.core.Keyword(null,"forest","forest",278860306),viz.forest.new_forest.call(null),new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751),cljs.core.PersistentHashSet.EMPTY], null);
+});
+viz.ghost.new_active_node = (function viz$ghost$new_active_node(ghost,pos){
+var vec__8057 = viz.forest.add_node.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(ghost),pos);
+var forest = cljs.core.nth.call(null,vec__8057,(0),null);
+var id = cljs.core.nth.call(null,vec__8057,(1),null);
+var grid = viz.grid.add_point.call(null,new cljs.core.Keyword(null,"grid","grid",402978600).cljs$core$IFn$_invoke$arity$1(ghost),pos);
+return cljs.core.update_in.call(null,cljs.core.assoc.call(null,ghost,new cljs.core.Keyword(null,"grid","grid",402978600),grid,new cljs.core.Keyword(null,"forest","forest",278860306),forest),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751)], null),cljs.core.conj,id);
+});
+viz.ghost.gen_new_poss = (function viz$ghost$gen_new_poss(ghost,poss_fn,id){
+
+var pos = new cljs.core.Keyword(null,"pos","pos",-864607220).cljs$core$IFn$_invoke$arity$1(viz.forest.get_node.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(ghost),id));
+var adj_poss = viz.grid.empty_adjacent_points.call(null,new cljs.core.Keyword(null,"grid","grid",402978600).cljs$core$IFn$_invoke$arity$1(ghost),pos);
+return poss_fn.call(null,pos,adj_poss);
+});
+viz.ghost.spawn_children = (function viz$ghost$spawn_children(ghost,poss_fn,id){
+return cljs.core.reduce.call(null,(function (p__8067,pos){
+var vec__8068 = p__8067;
+var ghost__$1 = cljs.core.nth.call(null,vec__8068,(0),null);
+var new_ids = cljs.core.nth.call(null,vec__8068,(1),null);
+var vec__8071 = viz.forest.spawn_child.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(ghost__$1),id,pos);
+var forest = cljs.core.nth.call(null,vec__8071,(0),null);
+var new_id = cljs.core.nth.call(null,vec__8071,(1),null);
+var grid = viz.grid.add_point.call(null,new cljs.core.Keyword(null,"grid","grid",402978600).cljs$core$IFn$_invoke$arity$1(ghost__$1),pos);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [cljs.core.assoc.call(null,ghost__$1,new cljs.core.Keyword(null,"forest","forest",278860306),forest,new cljs.core.Keyword(null,"grid","grid",402978600),grid),cljs.core.conj.call(null,new_ids,new_id)], null);
+}),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [ghost,cljs.core.PersistentHashSet.EMPTY], null),viz.ghost.gen_new_poss.call(null,ghost,poss_fn,id));
+});
+viz.ghost.spawn_children_multi = (function viz$ghost$spawn_children_multi(ghost,poss_fn,ids){
+return cljs.core.reduce.call(null,(function (p__8081,id){
+var vec__8082 = p__8081;
+var ghost__$1 = cljs.core.nth.call(null,vec__8082,(0),null);
+var new_ids = cljs.core.nth.call(null,vec__8082,(1),null);
+var vec__8085 = viz.ghost.spawn_children.call(null,ghost__$1,poss_fn,id);
+var ghost__$2 = cljs.core.nth.call(null,vec__8085,(0),null);
+var this_new_ids = cljs.core.nth.call(null,vec__8085,(1),null);
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [ghost__$2,clojure.set.union.call(null,new_ids,this_new_ids)], null);
+}),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [ghost,cljs.core.PersistentHashSet.EMPTY], null),ids);
+});
+viz.ghost.incr = (function viz$ghost$incr(ghost,poss_fn){
+var vec__8091 = viz.ghost.spawn_children_multi.call(null,ghost,poss_fn,new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751).cljs$core$IFn$_invoke$arity$1(ghost));
+var ghost__$1 = cljs.core.nth.call(null,vec__8091,(0),null);
+var new_ids = cljs.core.nth.call(null,vec__8091,(1),null);
+return cljs.core.assoc.call(null,ghost__$1,new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751),new_ids);
+});
+viz.ghost.active_nodes = (function viz$ghost$active_nodes(ghost){
+return cljs.core.map.call(null,(function (p1__8094_SHARP_){
+return cljs.core.get_in.call(null,ghost,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"forest","forest",278860306),new cljs.core.Keyword(null,"nodes","nodes",-2099585805),p1__8094_SHARP_], null));
+}),new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751).cljs$core$IFn$_invoke$arity$1(ghost));
+});
+viz.ghost.filter_active_nodes = (function viz$ghost$filter_active_nodes(ghost,pred){
+return cljs.core.assoc.call(null,ghost,new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751),cljs.core.reduce.call(null,(function (p1__8096_SHARP_,p2__8095_SHARP_){
+if(cljs.core.truth_(pred.call(null,p2__8095_SHARP_))){
+return cljs.core.conj.call(null,p1__8096_SHARP_,new cljs.core.Keyword(null,"id","id",-1388402092).cljs$core$IFn$_invoke$arity$1(p2__8095_SHARP_));
+} else {
+return p1__8096_SHARP_;
+}
+}),cljs.core.PersistentHashSet.EMPTY,viz.ghost.active_nodes.call(null,ghost)));
+});
+viz.ghost.remove_roots = (function viz$ghost$remove_roots(ghost){
+var roots = viz.forest.roots.call(null,new cljs.core.Keyword(null,"forest","forest",278860306).cljs$core$IFn$_invoke$arity$1(ghost));
+var root_ids = cljs.core.map.call(null,new cljs.core.Keyword(null,"id","id",-1388402092),roots);
+var root_poss = cljs.core.map.call(null,new cljs.core.Keyword(null,"pos","pos",-864607220),roots);
+return cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.update_in.call(null,ghost,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"active-node-ids","active-node-ids",-398210751)], null),((function (roots,root_ids,root_poss){
+return (function (p1__8097_SHARP_){
+return cljs.core.reduce.call(null,cljs.core.disj,p1__8097_SHARP_,root_ids);
+});})(roots,root_ids,root_poss))
+),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"forest","forest",278860306)], null),((function (roots,root_ids,root_poss){
+return (function (p1__8098_SHARP_){
+return cljs.core.reduce.call(null,viz.forest.remove_node,p1__8098_SHARP_,root_ids);
+});})(roots,root_ids,root_poss))
+),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"grid","grid",402978600)], null),((function (roots,root_ids,root_poss){
+return (function (p1__8099_SHARP_){
+return cljs.core.reduce.call(null,viz.grid.rm_point,p1__8099_SHARP_,root_poss);
+});})(roots,root_ids,root_poss))
+);
+});
+viz.ghost.eg_poss_fn = (function viz$ghost$eg_poss_fn(pos,adj_poss){
+return cljs.core.take.call(null,(2),cljs.core.random_sample.call(null,0.6,adj_poss));
+});
+viz.ghost.remove_roots.call(null,viz.ghost.incr.call(null,viz.ghost.incr.call(null,viz.ghost.incr.call(null,viz.ghost.new_active_node.call(null,viz.ghost.new_ghost.call(null,viz.grid.euclidean),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null)),viz.ghost.eg_poss_fn),viz.ghost.eg_poss_fn),viz.ghost.eg_poss_fn));
+
+//# sourceMappingURL=ghost.js.map \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/ghost.js.map b/srv/src/http/static/viz/1/viz/ghost.js.map
new file mode 100644
index 0000000..fa62e77
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/ghost.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/viz\/ghost.js","sources":["ghost.cljs"],"lineCount":89,"mappings":";AAAA;;;;;AAKA,sBAAA,tBAAMA,oDAAWC;AAAjB,AAAA,kDAAA,0FAAA,yFAAA,2EAAA,1MACU,AAACC,4BAAcD,kEACd,AAACE;;AAIZ,4BAAA,5BAAMC,gEAAiBC,MAAMC;AAA7B,AACE,IAAAC,YAAkB,AAACI,8BAAgB,AAAA,sFAASN,OAAOC;aAAnD,AAAAE,wBAAAD,UAAA,IAAA,\/CAAOE;SAAP,AAAAD,wBAAAD,UAAA,IAAA,3CAAcG;IACRE,OAAK,AAACC,6BAAe,AAAA,kFAAOR,OAAOC;AADzC,+DAEMD,1BACA,gCAAA,yDAAA,zFAACS,oFAAYF,6DAAaH,tLAC1B,8LAAA,mFAAA,1QAACM,6VAA6BC,eAAKN;;AAE3C,yBAAA,zBAAOO,0DAAcZ,MAAMa,QAAQR;AAAnC,AAAA;AAEE,IAAMJ,MAAI,AAAA,iFAAM,AAACa,8BAAgB,AAAA,sFAASd,OAAOK;IAC3CU,WAAS,AAACC,yCAA2B,AAAA,kFAAOhB,OAAOC;AADzD,AAEE,OAACY,kBAAQZ,IAAIc;;AAEjB,2BAAA,3BAAOE,8DAAgBjB,MAAMa,QAAQR;AAArC,AACE,OAACa,2BAAO,WAAAC,QAAqBlB;AAArB,AAAA,IAAAmB,YAAAD;gBAAA,AAAAhB,wBAAAiB,UAAA,IAAA,lDAAMpB;cAAN,AAAAG,wBAAAiB,UAAA,IAAA,hDAAYC;AAAZ,AACE,IAAAC,YAAsB,AAACE,iCAAmB,AAAA,sFAASxB,WAAOK,GAAGJ;aAA7D,AAAAE,wBAAAmB,UAAA,IAAA,\/CAAOlB;aAAP,AAAAD,wBAAAmB,UAAA,IAAA,\/CAAcC;IACRhB,OAAK,AAACC,6BAAe,AAAA,kFAAOR,WAAOC;AADzC,AAAA,0FAEG,oCAAA,+DAAA,nGAACQ,0BAAMT,kEAAcI,2DAAaG,MAAM,AAACI,yBAAKU,QAAQE;GAHnE,yFAAA,NAISvB,gDACD,AAACY,iCAAaZ,MAAMa,QAAQR;;AAEtC,iCAAA,jCAAOoB,0EAAsBzB,MAAMa,QAAQa;AAA3C,AACE,OAACR,2BAAO,WAAAS,QAAqBtB;AAArB,AAAA,IAAAuB,YAAAD;gBAAA,AAAAxB,wBAAAyB,UAAA,IAAA,lDAAM5B;cAAN,AAAAG,wBAAAyB,UAAA,IAAA,hDAAYP;AAAZ,AACE,IAAAQ,YAA2B,AAACZ,mCAAejB,UAAMa,QAAQR;gBAAzD,AAAAF,wBAAA0B,UAAA,IAAA,lDAAO7B;mBAAP,AAAAG,wBAAA0B,UAAA,IAAA,rDAAaC;AAAb,AAAA,0FACG9B,UAAM,AAAC+B,4BAAkBV,QAAQS;GAF9C,yFAAA,NAGS9B,gDACD0B;;AAEV,iBAAA,jBAAMM,0CAAMhC,MAAMa;AAAlB,AACE,IAAAoB,YAAsB,AAACR,yCAAqBzB,MAAMa,QAAQ,AAAA,yGAAkBb;gBAA5E,AAAAG,wBAAA8B,UAAA,IAAA,lDAAOjC;cAAP,AAAAG,wBAAA8B,UAAA,IAAA,hDAAaZ;AAAb,AACE,2CAAA,pCAACZ,0BAAMT,qFAAuBqB;;AAElC,yBAAA,zBAAMa,0DAAclC;AAApB,AACE,+BAAA,WAAAmC,nCAACC;AAAD,AAAM,wCAAA,mFAAA,wDAAA,wDAAAD,pOAACE,2BAAOrC;GAA0B,AAAA,yGAAkBA;;AAE5D,gCAAA,hCAAMsC,wEAAqBtC,MAAMuC;AAAjC,AACE,uCAAA,hCAAC9B,0BAAMT,iFACA,2BAAA,WAAAwC,gBAAAC,tDAACvB;AAAD,AAAS,oBAAI,eAAAuB,fAACF;AAAS,gCAAAC,zBAAC7B,yCAAQ,AAAA,gFAAA8B;;AAAvBD;;GAAT,kCACQ,AAACN,iCAAalC;;AAE\/B,yBAAA,zBAAM0C,0DAAc1C;AAApB,AACE,IAAM2C,QAAM,AAACC,2BAAa,AAAA,sFAAS5C;IAC7B6C,WAAS,wBAAA,xBAACT,0EAAQO;IAClBG,YAAU,wBAAA,xBAACV,2EAASO;AAF1B,iGAIM3C,9BACA,oCAAA,mFAAA,mFAAA,1MAACU,9BACD,AAACA,rCACD,OAACA;kBAFDqC;AAAA,AAA+B,iDAAAA,1CAAC7B,2BAAO8B,+BAAQH;;EAC\/C,mFAAA,gEAAA;kBAAAI;AAAA,AAAsB,yDAAAA,lDAAC\/B,2BAAOgC,uCAAsBL;;EACpD,mFAAA,4DAAA;kBAAAM;AAAA,AAAoB,oDAAAA,7CAACjC,2BAAOkC,kCAAiBN;;;;AAGrD,uBAAA,vBAAOO,sDAAYpD,IAAIc;AAAvB,AACE,gCAAA,zBAACuC,6BAAO,kCAAA,lCAACC,sCAAkBxC;;gJAEzB,AAACpB,8BAAU6D,lEACX,sFAAA,mFAAA,IAAA,7KAACzD,zBACD,AAACiC,mNAAKqB,5OACN,AAACrB,kQAAKqB,3RACN,AAACrB,iTAAKqB,lVACN,AAACX","names":["viz.ghost\/new-ghost","grid-def","viz.grid\/new-grid","viz.forest\/new-forest","viz.ghost\/new-active-node","ghost","pos","vec__8057","cljs.core\/nth","forest","id","viz.forest\/add-node","grid","viz.grid\/add-point","cljs.core\/assoc","cljs.core\/update-in","cljs.core\/conj","viz.ghost\/gen-new-poss","poss-fn","viz.forest\/get-node","adj-poss","viz.grid\/empty-adjacent-points","viz.ghost\/spawn-children","cljs.core\/reduce","p__8067","vec__8068","new-ids","vec__8071","new-id","viz.forest\/spawn-child","viz.ghost\/spawn-children-multi","ids","p__8081","vec__8082","vec__8085","this-new-ids","clojure.set\/union","viz.ghost\/incr","vec__8091","viz.ghost\/active-nodes","p1__8094#","cljs.core\/map","cljs.core\/get-in","viz.ghost\/filter-active-nodes","pred","p1__8096#","p2__8095#","viz.ghost\/remove-roots","roots","viz.forest\/roots","root-ids","root-poss","p1__8097#","cljs.core\/disj","p1__8098#","viz.forest\/remove-node","p1__8099#","viz.grid\/rm-point","viz.ghost\/eg-poss-fn","cljs.core\/take","cljs.core\/random-sample","viz.grid\/euclidean"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/grid.cljs b/srv/src/http/static/viz/1/viz/grid.cljs
new file mode 100644
index 0000000..6e31443
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/grid.cljs
@@ -0,0 +1,63 @@
+(ns viz.grid)
+
+;; grid set of points relative to a common origin
+
+(def euclidean [ [0 -1]
+ [-1 0] , [1 0]
+ [0 1] ])
+
+(def isometric [[-1 -1] [0 -2] [1 -1]
+ ,
+ [-1 1] [0 2] [1 1]])
+
+(def hexagonal [ [0 -1]
+ ,
+ [-1 1] [1 1]])
+
+(defn new-grid [grid-def]
+ { :grid-def grid-def
+ :points #{} })
+
+(defn add-point [grid point]
+ (update-in grid [:points] conj point))
+
+(def my-grid (-> (new-grid euclidean)
+ (add-point [0 1])))
+
+;; TODO this could be useful, but it's not needed now, as long as all points we
+;; use are generated from adjacent-points
+;;(defn valid-point? [grid point]
+;; (letfn [(ordered-dim-points [dim order]
+;; (->> (:grid-def grid)
+;; (map #(%1 dim))
+;; (sort (if (= order :asc) < > ))
+;; (filter (if (= order :asc) #(> %1 0) #(< %1 0)))
+;; ))
+;; (closest-in-dim [dim-i dim-jj]
+;; (reduce (fn [curr dim-j]
+;; (let [next (+ curr dim-j)]
+;; (reduce #(if (= ;; TODO wat
+;; (if (> 0 dim-i)
+;; (min dim-i next)
+;; (max dim-i next))))
+;; 0 dim-jj))
+;;
+;; ]
+;; (closest-in-dim 4 [1])))
+;; ;;(ordered-dim 1 :asc)))
+;;
+;;(valid-point? my-grid [0 1])
+
+(defn rm-point [grid point]
+ (update-in grid [:points] disj point))
+
+(defn adjacent-points [grid point]
+ (map #(map + %1 point) (:grid-def grid)))
+
+(defn empty-adjacent-points [grid point]
+ (remove (:points grid) (adjacent-points grid point)))
+
+(-> (new-grid isometric)
+ (add-point [0 0])
+ (add-point [0 1])
+ (empty-adjacent-points [0 1]))
diff --git a/srv/src/http/static/viz/1/viz/grid.cljs.cache.edn b/srv/src/http/static/viz/1/viz/grid.cljs.cache.edn
new file mode 100644
index 0000000..60052ff
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/grid.cljs.cache.edn
@@ -0,0 +1 @@
+{:rename-macros {}, :renames {}, :use-macros {}, :excludes #{}, :name viz.grid, :imports nil, :requires nil, :uses nil, :defs {euclidean {:name viz.grid/euclidean, :file "src/viz/grid.cljs", :line 5, :column 1, :end-line 5, :end-column 15, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 5, :column 6, :end-line 5, :end-column 15}, :tag cljs.core/IVector}, isometric {:name viz.grid/isometric, :file "src/viz/grid.cljs", :line 9, :column 1, :end-line 9, :end-column 15, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 9, :column 6, :end-line 9, :end-column 15}, :tag cljs.core/IVector}, hexagonal {:name viz.grid/hexagonal, :file "src/viz/grid.cljs", :line 13, :column 1, :end-line 13, :end-column 15, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 13, :column 6, :end-line 13, :end-column 15}, :tag cljs.core/IVector}, new-grid {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 17, :column 7, :end-line 17, :end-column 15, :arglists (quote ([grid-def]))}, :name viz.grid/new-grid, :variadic false, :file "src/viz/grid.cljs", :end-column 15, :method-params ([grid-def]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 17, :end-line 17, :max-fixed-arity 1, :fn-var true, :arglists (quote ([grid-def]))}, add-point {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 21, :column 7, :end-line 21, :end-column 16, :arglists (quote ([grid point]))}, :name viz.grid/add-point, :variadic false, :file "src/viz/grid.cljs", :end-column 16, :method-params ([grid point]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 21, :end-line 21, :max-fixed-arity 2, :fn-var true, :arglists (quote ([grid point]))}, my-grid {:name viz.grid/my-grid, :file "src/viz/grid.cljs", :line 24, :column 1, :end-line 24, :end-column 13, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 24, :column 6, :end-line 24, :end-column 13}, :tag any}, rm-point {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 51, :column 7, :end-line 51, :end-column 15, :arglists (quote ([grid point]))}, :name viz.grid/rm-point, :variadic false, :file "src/viz/grid.cljs", :end-column 15, :method-params ([grid point]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 51, :end-line 51, :max-fixed-arity 2, :fn-var true, :arglists (quote ([grid point]))}, adjacent-points {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 54, :column 7, :end-line 54, :end-column 22, :arglists (quote ([grid point]))}, :name viz.grid/adjacent-points, :variadic false, :file "src/viz/grid.cljs", :end-column 22, :method-params ([grid point]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 54, :end-line 54, :max-fixed-arity 2, :fn-var true, :arglists (quote ([grid point]))}, empty-adjacent-points {:protocol-inline nil, :meta {:file "/home/mediocregopher/src/viz/src/viz/grid.cljs", :line 57, :column 7, :end-line 57, :end-column 28, :arglists (quote ([grid point]))}, :name viz.grid/empty-adjacent-points, :variadic false, :file "src/viz/grid.cljs", :end-column 28, :method-params ([grid point]), :protocol-impl nil, :arglists-meta (nil nil), :column 1, :line 57, :end-line 57, :max-fixed-arity 2, :fn-var true, :arglists (quote ([grid point]))}}, :require-macros nil, :cljs.analyzer/constants {:seen #{:grid-def :points}, :order [:grid-def :points]}, :doc nil} \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/grid.js b/srv/src/http/static/viz/1/viz/grid.js
new file mode 100644
index 0000000..7bf4971
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/grid.js
@@ -0,0 +1,27 @@
+// Compiled by ClojureScript 1.9.473 {}
+goog.provide('viz.grid');
+goog.require('cljs.core');
+viz.grid.euclidean = new cljs.core.PersistentVector(null, 4, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(-1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(-1),(0)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(1),(0)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1)], null)], null);
+viz.grid.isometric = new cljs.core.PersistentVector(null, 6, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(-1),(-1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(-2)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(1),(-1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(-1),(1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(2)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(1),(1)], null)], null);
+viz.grid.hexagonal = new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(-1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(-1),(1)], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(1),(1)], null)], null);
+viz.grid.new_grid = (function viz$grid$new_grid(grid_def){
+return new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"grid-def","grid-def",-392588768),grid_def,new cljs.core.Keyword(null,"points","points",-1486596883),cljs.core.PersistentHashSet.EMPTY], null);
+});
+viz.grid.add_point = (function viz$grid$add_point(grid,point){
+return cljs.core.update_in.call(null,grid,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"points","points",-1486596883)], null),cljs.core.conj,point);
+});
+viz.grid.my_grid = viz.grid.add_point.call(null,viz.grid.new_grid.call(null,viz.grid.euclidean),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1)], null));
+viz.grid.rm_point = (function viz$grid$rm_point(grid,point){
+return cljs.core.update_in.call(null,grid,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"points","points",-1486596883)], null),cljs.core.disj,point);
+});
+viz.grid.adjacent_points = (function viz$grid$adjacent_points(grid,point){
+return cljs.core.map.call(null,(function (p1__9451_SHARP_){
+return cljs.core.map.call(null,cljs.core._PLUS_,p1__9451_SHARP_,point);
+}),new cljs.core.Keyword(null,"grid-def","grid-def",-392588768).cljs$core$IFn$_invoke$arity$1(grid));
+});
+viz.grid.empty_adjacent_points = (function viz$grid$empty_adjacent_points(grid,point){
+return cljs.core.remove.call(null,new cljs.core.Keyword(null,"points","points",-1486596883).cljs$core$IFn$_invoke$arity$1(grid),viz.grid.adjacent_points.call(null,grid,point));
+});
+viz.grid.empty_adjacent_points.call(null,viz.grid.add_point.call(null,viz.grid.add_point.call(null,viz.grid.new_grid.call(null,viz.grid.isometric),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0)], null)),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1)], null)),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1)], null));
+
+//# sourceMappingURL=grid.js.map \ No newline at end of file
diff --git a/srv/src/http/static/viz/1/viz/grid.js.map b/srv/src/http/static/viz/1/viz/grid.js.map
new file mode 100644
index 0000000..46886eb
--- /dev/null
+++ b/srv/src/http/static/viz/1/viz/grid.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/viz\/grid.js","sources":["grid.cljs"],"lineCount":27,"mappings":";AAAA;;AAIA,qBAAA,mFAAA,mFAAA,IAAA,aAAA,mFAAA,KAAA,YAAA,mFAAA,IAAA,YAAA,mFAAA,IAAA,1eAAKA;AAIL,qBAAA,mFAAA,mFAAA,KAAA,aAAA,mFAAA,IAAA,aAAA,mFAAA,IAAA,aAAA,mFAAA,KAAA,YAAA,mFAAA,IAAA,YAAA,mFAAA,IAAA,nrBAAKC;AAIL,qBAAA,mFAAA,mFAAA,IAAA,aAAA,mFAAA,KAAA,YAAA,mFAAA,IAAA,vYAAKC;AAIL,oBAAA,pBAAMC,gDAAUC;AAAhB,AAAA,kDAAA,sEAAA,0DAAA,nEACcA;;AAGd,qBAAA,rBAAMC,kDAAWC,KAAKC;AAAtB,AACE,0CAAA,mFAAA,tHAACC,8BAAUF,0JAAeG,eAAKF;;AAEjC,AAAKG,gDAAY,AAACP,4BAASH,zDACV,6EAAA,mFAAA,IAAA,pKAACK;AA0BlB,oBAAA,pBAAMM,gDAAUL,KAAKC;AAArB,AACE,0CAAA,mFAAA,tHAACC,8BAAUF,0JAAeM,eAAKL;;AAEjC,2BAAA,3BAAMM,8DAAiBP,KAAKC;AAA5B,AACE,+BAAA,WAAAO,nCAACC;AAAD,AAAM,gDAAAD,zCAACC,wBAAIC,iCAAKT;GAAO,AAAA,2FAAWD;;AAEpC,iCAAA,jCAAMW,0EAAuBX,KAAKC;AAAlC,AACE,OAACW,2BAAO,AAAA,wFAASZ,MAAM,AAACO,mCAAgBP,KAAKC;;mGAE3C,AAACJ,4BAASF,zDACV,6EAAA,mFAAA,IAAA,pKAACI,7BACD,8MAAA,mFAAA,IAAA,rSAACA,zCACD,2VAAA,mFAAA,IAAA,lbAACY","names":["viz.grid\/euclidean","viz.grid\/isometric","viz.grid\/hexagonal","viz.grid\/new-grid","grid-def","viz.grid\/add-point","grid","point","cljs.core\/update-in","cljs.core\/conj","viz.grid\/my-grid","viz.grid\/rm-point","cljs.core\/disj","viz.grid\/adjacent-points","p1__9451#","cljs.core\/map","cljs.core\/+","viz.grid\/empty-adjacent-points","cljs.core\/remove"]} \ No newline at end of file