Remove lens related tests.

Remove lens related tests.

--- test/cats/labs/lens_spec.cljc
+++ test/cats/labs/lens_spec.cljc
@@ -1,384 +0,0 @@
-(ns cats.labs.lens-spec
-  #?(:cljs
-     (:require [cljs.test :as t]
-               [clojure.test.check]
-               [clojure.test.check.generators :as gen :include-macros true]
-               [clojure.test.check.properties :as prop :include-macros true]
-               [cats.core :as m]
-               [cats.labs.lens :as l]
-               [cats.labs.traversal :as tv])
-     :clj
-     (:require [clojure.test :as t]
-               [clojure.test.check]
-               [clojure.test.check.clojure-test :refer [defspec]]
-               [clojure.test.check.generators :as gen]
-               [clojure.test.check.properties :as prop]
-               [cats.core :as m]
-               [cats.labs.lens :as l]
-               [cats.labs.traversal :as tv]))
-  #?(:cljs
-     (:require-macros [clojure.test.check.clojure-test :refer (defspec)])))
-
-;; laws
-
-(defn first-lens-law [{:keys [gen lens xgen] :or {xgen gen/any}}]
-  (prop/for-all [s gen
-                 x xgen]
-    (= x
-       (l/focus lens (l/put lens x s)))))
-
-(defn second-lens-law [{:keys [gen lens]}]
-  (prop/for-all [s gen]
-    (= s
-       (l/put lens (l/focus lens s) s))))
-
-(defn third-lens-law [{:keys [gen lens xgen] :or {xgen gen/any}}]
-  (prop/for-all [s gen
-                 a xgen
-                 b xgen]
-    (= (l/put lens a s)
-       (l/put lens a (l/put lens b s)))))
-
-;; generators
-
-(def vector-gen
-  (gen/vector gen/any 10))
-
-(def nested-vector-gen
-  (gen/vector vector-gen 10))
-
-;; id
-
-(def id-lens
-  {:gen gen/any
-   :lens l/id})
-
-(defspec id-first-lens-law 10
-  (first-lens-law id-lens))
-
-(defspec id-second-lens-law 10
-  (second-lens-law id-lens))
-
-(defspec id-third-lens-law 10
-  (third-lens-law id-lens))
-
-;; passes
-
-(t/deftest passes
-  (let [odd (l/passes odd?)]
-    (t/testing "focus"
-      (t/is (= 3 (l/focus odd 3)))
-      (t/is (nil? (l/focus odd 2))))
-    (t/testing "put"
-      (t/is (= 42 (l/put odd 42 3)))
-      (t/is (= 2 (l/put odd 42 2))))
-    (t/testing "over"
-      (t/is (= 4 (l/over odd inc 3)))
-      (t/is (= 2 (l/over odd inc 2))))))
-
-(t/deftest passes-comp
-  (let [fstodd (comp l/fst (l/passes odd?))]
-    (t/testing "focus"
-      (t/is (= 1 (l/focus fstodd [1 2 3])))
-      (t/is (nil? (l/focus fstodd [2 3 4]))))
-    (t/testing "put"
-      (t/is (= [42 2 3] (l/put fstodd 42 [1 2 3])))
-      (t/is (= [2 3 4] (l/put fstodd 42 [2 3 4]))))
-    (t/testing "over"
-      (t/is (= [2 2 3] (l/over fstodd inc [1 2 3])))
-      (t/is (= [2 3 4] (l/over fstodd inc [2 3 4]))))))
-
-;; nth
-
-(defspec nth-first-lens-law 10
-  (first-lens-law {:gen vector-gen
-                   :lens (l/nth 0)}))
-
-(defspec nth-second-lens-law 10
-  (second-lens-law {:gen vector-gen
-                    :lens (l/nth 0)}))
-
-(defspec nth-third-lens-law 10
-  (third-lens-law {:gen vector-gen
-                    :lens (l/nth 0)}))
-
-;;; nth composition
-
-(def ffst (comp l/fst l/fst))
-
-(def ffst-lens
-  {:gen nested-vector-gen
-   :lens ffst})
-
-(defspec ffst-first-lens-law 10
-  (first-lens-law ffst-lens))
-
-(defspec ffst-second-lens-law 10
-  (second-lens-law ffst-lens))
-
-(defspec ffst-third-lens-law 10
-  (third-lens-law ffst-lens))
-
-;; tail
-
-(def tail-lens
-  {:gen vector-gen
-   :xgen vector-gen
-   :lens l/tail})
-
-(defspec tail-first-lens-law 10
-  (first-lens-law tail-lens))
-
-(defspec tail-second-lens-law 10
-  (second-lens-law tail-lens))
-
-(defspec tail-third-lens-law 10
-  (third-lens-law tail-lens))
-
-;; associative
-
-(defn with-key
-  [k]
-  (gen/fmap (fn [v]
-              {k v})
-            gen/any))
-
-(def key-lens
-  {:gen (with-key :foo)
-   :lens (l/key :foo)})
-
-(defspec key-first-lens-law 10
-  (first-lens-law key-lens))
-
-(defspec key-second-lens-law 10
-  (second-lens-law key-lens))
-
-(defspec key-third-lens-law 10
-  (third-lens-law key-lens))
-
-;; select-keys
-
-(defn with-keys
-  [ks]
-  (gen/fmap (fn [v]
-              (zipmap ks (repeat v)))
-            gen/any))
-
-(def select-keys-lens
-  {:gen (with-keys [:a :b])
-   :xgen (with-keys [:a :b])
-   :lens (l/select-keys [:a :b])})
-
-(defspec select-keys-first-lens-law 10
-  (first-lens-law select-keys-lens))
-
-(defspec select-keys-second-lens-law 10
-  (second-lens-law select-keys-lens))
-
-(defspec select-keys-third-lens-law 10
-  (third-lens-law select-keys-lens))
-
-;; in
-
-(def in-lens
-  {:gen (gen/fmap (fn [m]
-                    (merge m {:a {:b {:c 42}}}))
-                  (gen/map gen/keyword gen/any))
-   :lens (l/in [:a :b :c])})
-
-(defspec in-first-lens-law 10
-  (first-lens-law in-lens))
-
-(defspec in-second-lens-law 10
-  (second-lens-law in-lens))
-
-(defspec in-third-lens-law 10
-  (third-lens-law in-lens))
-
-;; derived lenses
-
-(defn sec->min
-  [sec]
-  (/ sec 60))
-
-(defn min->sec
-  [min]
-  (* min 60))
-
-(def min-lens
-  {:gen gen/int
-   :xgen gen/int
-   :lens (l/units sec->min min->sec)})
-
-(defspec min-first-lens-law 10
-  (first-lens-law min-lens))
-
-(defspec min-second-lens-law 10
-  (second-lens-law min-lens))
-
-(defspec min-third-lens-law 10
-  (third-lens-law min-lens))
-
-;; traversals
-
-(defn first-traversal-law [{:keys [gen trav]}]
-  (prop/for-all [s gen]
-    (coll? (tv/foci trav s))))
-
-;; it
-
-(def it-traversal
-  {:gen gen/any
-   :trav tv/it})
-
-(defspec it-first-traversal-law 10
-  (first-traversal-law it-traversal))
-
-;; each
-
-(def each-traversal
-  {:gen gen/any
-   :trav tv/each})
-
-(defspec each-first-traversal-law 10
-  (first-traversal-law each-traversal))
-
-;; filter
-
-(def filter-traversal
-  {:gen gen/any
-   :trav (tv/filter identity)})
-
-(defspec filter-first-traversal-law 10
-  (first-traversal-law filter-traversal))
-
-;; only
-
-(def only-traversal
-  {:gen gen/any
-   :trav (tv/only identity)})
-
-(defspec only-first-traversal-law 10
-  (first-traversal-law only-traversal))
-
-;; keys
-
-(def keys-traversal
-  {:gen (gen/map gen/keyword gen/any)
-   :trav tv/keys})
-
-(defspec keys-first-traversal-law 10
-  (first-traversal-law keys-traversal))
-
-;; vals
-
-(def vals-traversal
-  {:gen (gen/map gen/keyword gen/any)
-   :trav tv/vals})
-
-(defspec vals-first-traversal-law 10
-  (first-traversal-law vals-traversal))
-
-;; indexed
-
-(def indexed-traversal
-  {:gen (gen/vector gen/any)
-   :trav tv/indexed})
-
-(defspec indexed-first-traversal-law 10
-  (first-traversal-law indexed-traversal))
-
-;; nothing
-
-(def nothing-traversal
-  {:gen gen/any
-   :trav tv/nothing})
-
-(defspec nothing-first-traversal-law 10
-  (first-traversal-law nothing-traversal))
-
-;; both
-
-(def both-traversal
-  {:gen (gen/vector gen/int)
-   :trav (tv/both (filter odd?) (filter #(< % 5)))})
-
-(defspec both-first-traversal-law 10
-  (first-traversal-law both-traversal))
-
-;; lens->traversal
-
-(def lens->traversal
-  {:gen (with-key :a)
-   :trav (tv/lens->traversal (l/key :a))})
-
-(defspec lens->traversal-first-traversal-law 10
-  (first-traversal-law lens->traversal))
-
-;; interop
-
-(t/deftest focus-atom
-  (t/testing "Reflects an atoms focused value"
-    (let [source (atom [0 1 2 3 4])
-          fsource (l/focus-atom l/fst source)]
-      (t/is (= @fsource 0))
-
-      (swap! source #(subvec % 1))
-      (t/is (= @source [1 2 3 4]))
-      (t/is (= @fsource 1))
-
-      (reset! fsource 42)
-      (t/is (= @source [42 2 3 4]))
-      (t/is (= @fsource 42)))))
-
-(t/deftest focus-atom-watches
-  (t/testing "Supports watches"
-    (let [source (atom [0 1 2 3 4])
-          watched (volatile! nil)
-          fsource (l/focus-atom l/fst source)]
-      (add-watch fsource :test (fn [key ref old new]
-                                 (vreset! watched [ref old new])))
-
-      (swap! source #(subvec % 1))
-      (t/is (= @watched
-               [fsource 0 1]))
-
-      (swap! fsource inc)
-      (t/is (= @watched
-               [fsource 1 2]))
-
-      (remove-watch fsource :test))))
-
-(t/deftest foci-atom
-  (t/testing "Reflects an atoms focused values"
-    (let [source (atom [0 1 2 3 4 5])
-          fsource (tv/foci-atom (tv/only odd?) source)]
-      (t/is (= @fsource [1 3 5]))
-
-      (swap! source #(subvec % 2))
-      (t/is (= @source [2 3 4 5]))
-      (t/is (= @fsource [3 5]))
-
-      (reset! fsource 42)
-      (t/is (= @source [2 42 4 42]))
-      (t/is (= @fsource [])))))
-
-(t/deftest foci-atom-watches
-  (t/testing "Supports watches"
-    (let [source (atom [1 2 3 4 5])
-          watched (volatile! nil)
-          fsource (tv/foci-atom (tv/only odd?) source)]
-      (add-watch fsource :test (fn [key ref old new]
-                                 (vreset! watched [ref old new])))
-
-      (swap! source #(subvec % 2))
-      (t/is (= @watched
-               [fsource [1 3 5] [3 5]]))
-
-      (swap! fsource inc)
-      (t/is (= @watched
-               [fsource [3 5] []]))
-      (t/is (= @source
-               [4 4 6]))
-
-      (remove-watch fsource :test))))


Fix output for samples with input qs

Fix output for samples with input qs

--- src/clj/collect_earth_online/db/projects.clj
+++ src/clj/collect_earth_online/db/projects.clj
@@ -866,7 +866,8 @@
     (reduce (fn [acc [k v]]
               (let [{:keys [question answers]} (get survey-questions k)]
                 (merge acc {question
-                            (get-in answers [(str (:answerId v)) :answer])})))
+                            (or (:answer v)
+                                (get-in answers [(str (:answerId v)) :answer]))})))
             {}
             value)
     ""))


= is probably more idiomatic

= is probably more idiomatic

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -5,7 +5,7 @@

 (deftest infix->dsl-tests
   (is (= '(= (:ip x) "10.0.0.1")
-         (q/infix->dsl "ip(x) is 10.0.0.1"))))
+         (q/infix->dsl "ip(x) = 10.0.0.1"))))

 (def dsl->logic
   @#'desdemona.query/dsl->logic)


set defaultAccount when getting web3

set defaultAccount when getting web3

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/protocol/handlers.cljs
+++ src/status_im/protocol/handlers.cljs
@@ -9,13 +9,18 @@
             [status-im.utils.handlers :as handlers]
             [status-im.utils.handlers-macro :as handlers-macro]
             [status-im.utils.web3-provider :as web3-provider]
-            [status-im.transport.core :as transport]))
+            [status-im.transport.core :as transport]
+            [status-im.utils.ethereum.core :as ethereum]))

 ;;;; COFX
 (re-frame/reg-cofx
  ::get-web3
  (fn [coeffects _]
-   (assoc coeffects :web3 (web3-provider/make-web3))))
+   (let [web3 (web3-provider/make-web3)
+         address (get-in coeffects [:db :account/account :address])]
+     (set! (.-defaultAccount (.-eth web3))
+           (ethereum/normalized-address address))
+     (assoc coeffects :web3 web3))))

 (re-frame/reg-fx
  ::web3-get-syncing


add GIT_DIR option when constructing core.excludes matchers

--- src/tailrecursion/boot/gitignore.clj
+++ src/tailrecursion/boot/gitignore.clj
@@ -55,15 +55,15 @@
         lines (->> f slurp (#(split % #"\n")) (remove skip?) (map trim))]
     (map parse-gitignore1 lines (repeat base))))

-(defn core-excludes []
+(defn core-excludes [& [$GIT_DIR]]
   (let [git #(sh "git" "config" "core.excludesfile")
-        cwd (System/getProperty "user.dir")]
+        cwd (or $GIT_DIR (System/getProperty "user.dir"))]
     (try (-> (git) :out trim file (parse-gitignore cwd)) (catch Throwable _))))

 (defn make-gitignore-matcher [& [$GIT_DIR]]
   (let [cwd         (or $GIT_DIR (System/getProperty "user.dir"))
         gi-file?    #(= ".gitignore" (.getName %))
         gitignores  (->> (file cwd) file-seq (filter gi-file?))
-        core-excl   (vec (or (core-excludes) []))
+        core-excl   (vec (or (core-excludes $GIT_DIR) []))
         matchers    (into core-excl (mapcat parse-gitignore gitignores))]
     (partial matches? matchers)))


sort namelist statements

sort namelist statements

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -16,7 +16,7 @@
 ;;   (println (str "k=" k " v=" v))
     (apply str
            (case k
-             :s        (delegate v)
+             :s        (delegate (sort-by #(s (second %)) v))
              :array    [(sf v) (sl v)]
              :c        (sf v)
              :colon    ":"


reorder for clarity

reorder for clarity

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@8515 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- buildscripts/buildcheck/src/buildcheck/core.clj
+++ buildscripts/buildcheck/src/buildcheck/core.clj
@@ -175,13 +175,13 @@
         (report-segment "Outdated device adapter DLLs" outdated-dlls)
         (report-segment "Errors reported by java compiler" javac-errs)
         (report-segment "Outdated jar files" outdated-jars)
+        (when (= 32 bits)
+          (report-segment "Missing .vcproj files" missing-vcproj-files))
         (report-segment "Uncompiled device adapters" (missing-device-adapters bits))
         "\n\nIs installer download available on website?\n"
         (if installer-ok "Yes" "No. (build missing)\n")
         (when (= 32 bits)
-          (str
-            (report-segment "Missing device pages" (missing-device-pages))
-            (report-segment "Missing .vcproj files" missing-vcproj-files)))
+          (report-segment "Missing device pages" (missing-device-pages)))
       ))))

 (defn make-full-report [mode send?]


Use a channel to stream updates to the plot displays.

--- metlog-vault/src-client/metlog_client/metlog.cljs
+++ metlog-vault/src-client/metlog_client/metlog.cljs
@@ -26,6 +26,7 @@

 (defn ajax-get
   ([ url params callback ]
+   (watch url params)
    (ajax/GET url {:handler callback
                   :params params
                   :error-handler #(.log js/console (str "HTTP error, url: " url " resp: " %))}))
@@ -44,26 +45,28 @@
               cb)))

 (defn periodic-event-channel [ interval-ms ]
-  (let [ channel (chan (dropping-buffer 1)) ]
-    (js/setInterval #(put! channel (time/now))
-                    interval-ms)
+  (let [channel (chan (dropping-buffer 1))
+        put-now #(put! channel (time/now))]
+    (put-now)
+    (js/setInterval put-now interval-ms)
     channel))

 (defn range-ending-at [ end-t ]
   (let [begin-t (time/minus end-t (time/seconds @query-window-secs))]
-    {:begin-t begin-t :end-t end-t}))
+    {:begin-t (time-coerce/to-long begin-t)
+     :end-t (time-coerce/to-long end-t)}))

 (defn query-range-channel [ periodic-event-channel ]
   (let [ channel (chan) ]
     (pipeline 1 channel (map range-ending-at) periodic-event-channel)
     channel))

-#_(let [ channel (query-range-channel (periodic-event-channel 5000))]
+(defn series-data-channel [ series-name query-range-channel ]
+  (let [channel (chan)]
     (go-loop []
-      (let [range (<! channel)]
-        (when range
-          (watch range)
-          (recur)))))
+      (ajax-get (str "/data/" series-name) (<! query-range-channel) #(put! channel %))
+      (recur))
+    channel))

 (defn series-tsplot [ series qws-arg ]
   (let [dom-node (reagent/atom nil)
@@ -82,10 +85,14 @@
       :component-did-mount
       (fn [ this ]
         (reset! dom-node (reagent/dom-node this))
-        (go
-          (swap! series-state assoc :series-data
-                 (<! (<<< fetch-series-data series @query-window-secs)))))
-
+        (let [ channel (series-data-channel series (query-range-channel (periodic-event-channel 15000))) ]
+          (go-loop []
+            (let [ data (<! channel) ]
+              (when data
+                (watch (count data))
+                (swap! series-state assoc :series-data data)
+                (recur))))))
+
       :reagent-render
       (fn [ & rest ]
         @window-width


clojure: fixed signature mapping for new morphism function

--- clojure/org/gavrog/clojure/pgraph_morphisms.clj
+++ clojure/org/gavrog/clojure/pgraph_morphisms.clj
@@ -85,11 +85,10 @@
     (when (every? (fn [xs] (== 1 (count xs))) (vals nclass))
       (into {} (for [[key vals] nclass] [(first vals) key])))))

-(defn map-vv [f vv]
-  (into (vector) (map #(into (vector) (map f %)) vv)))
-
 (defn map-sig [M sig]
-  (map-vv #(.times % M) sig))
+  (into (vector)
+        (map (fn [s] (->> s (map #(.times % M)) sort (into (vector))))
+             sig)))

 (defn extend-matrix [M]
   (let [n (.numberOfRows M)


Fix language

Fix language

--- test/github_changelog/conventional_test.clj
+++ test/github_changelog/conventional_test.clj
@@ -53,7 +53,7 @@
       1
       2
       5))
-  (testing "with a correct formats"
+  (testing "with correct formats"
     (are [title] (not= nil (sut/parse-pull config (sample-pull {:title title})))
       "feat(scope): enhance this and that"
       "fix(scope): do not fail on invalid input"
@@ -62,7 +62,7 @@
     (are [title] (nil? (sut/parse-pull config (sample-pull {:title title})))
       "this is just a PR"
       "does not follow the rules"))
-  (testing "with a full test"
+  (testing "with full test"
     (let [pull (sample-pull {:title "feat(the scope): subject line" :body "Fixes #1, Closes JIRA-2"})
           change (sut/parse-pull config pull)]
       (is (= "feat" (:type change)))


Test function test-assoc-in-if-not-nil-1

--- test/emender_jenkins/config_test.clj
+++ test/emender_jenkins/config_test.clj
@@ -92,3 +92,18 @@
     (testing "if the emender-jenkins.config/pretty-print? definition exists."
         (is (callable? 'emender-jenkins.config/pretty-print?))))

+;
+; Test for function behaviours
+;
+
+(deftest test-assoc-in-if-not-nil-1
+    "Check the behaviour of function emender-jenkins.config/assoc-in-if-not-nil."
+    (testing "the behaviour of function emender-jenkins.config/assoc-in-if-not-nil."
+        (are [x y] (= x y)
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] 3)        {:first 1 :second 2 :third 3}
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] "string") {:first 1 :second 2 :third "string"}
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] '())      {:first 1 :second 2 :third ()}
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] [])       {:first 1 :second 2 :third []}
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] '(1 2 3)) {:first 1 :second 2 :third '(1 2 3)}
+            (assoc-in-if-not-nil {:first 1 :second 2} [:third] [1 2 3])  {:first 1 :second 2 :third [1 2 3]})))
+


remove old class import

remove old class import

--- elephantdb-cascading/test/elephantdb/cascading/integration_test.clj
+++ elephantdb-cascading/test/elephantdb/cascading/integration_test.clj
@@ -12,7 +12,7 @@
            [elephantdb DomainSpec]
            [elephantdb.document KeyValDocument]
            [elephantdb.cascading ElephantDBTap
-            ElephantDBTap$Args ElephantDBTap$TapMode KeyValTailAssembly KeyValGateway]
+            ElephantDBTap$Args ElephantDBTap$TapMode KeyValTailAssembly]
            [org.apache.hadoop.mapred JobConf]))

 ;; ## Global Vars


Adds docstring to run-all-tests-future

Adds docstring to run-all-tests-future

--- dev-system/dev/user.clj
+++ dev-system/dev/user.clj
@@ -71,6 +71,7 @@
     (vdd/data->viz {:cmd :reload})))

 (defn run-all-tests-future
+  "Runs all tests asynchronously, with :fail-fast? and :speak? enabled."
   []
   (future
     (tests/run-all-tests {:fail-fast? true :speak? true})))


Updated dependencies for the TFS crawler

--- tools/tfs-crawler/project.clj
+++ tools/tfs-crawler/project.clj
@@ -5,17 +5,17 @@
   :license {:name "Eclipse Public License"
             :url  "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.9.0"]
-                 [org.clojure/tools.logging "0.4.0"]
+                 [org.clojure/tools.logging "0.4.1"]
                  [log4j/log4j "1.2.17" :exclusions [javax.mail/mail
                                                     javax.jms/jms
                                                     com.sun.jdmk/jmxtools
                                                     com.sun.jmx/jmxri]]
                  [com.jcabi/jcabi-log "0.18"]
-                 [clj-http "3.8.0"]
+                 [clj-http "3.9.1"]
                  [cheshire "5.8.0"]
-                 [org.clojure/tools.cli "0.3.5"]
+                 [org.clojure/tools.cli "0.3.7"]
                  [kuona-core "0.0.2"]]
   :plugins [[lein-midje "3.2.1"]
             [lein-ancient "0.6.14"]]
-  :profiles {:dev     {:dependencies [[midje "1.9.1"]]}
+  :profiles {:dev     {:dependencies [[midje "1.9.2"]]}
              :uberjar {:aot :all}})


refactor common functions

refactor common functions

--- src/bløggr/common.clj
+++ src/bløggr/common.clj
@@ -10,8 +10,11 @@
 (defn parse-datestring [date-str]
   (tf/parse (tf/formatter "yyyy-MM-dd HH:mm:ssZ") date-str))

+(defn update-body [f post]
+  (assoc post :body (f (post :body))))
+
 (defn markdown [post]
-  (assoc post :body (md/to-html (post :body) cegdown-ext)))
+  (update-body #(md/to-html % cegdown-ext) post))

 (defn- highlight-node [n]
   (let [lang (:class (:attrs n))]
@@ -21,10 +24,9 @@
                                                                  (keyword lang)
                                                                  :html))))))
 (defn highlight [post]
-  (assoc post :body (html/at (post :body) [:pre :code] highlight-node)))
+  (update-body #(html/at % [:pre :code] highlight-node) post))

-(defn enliveify [post]
-  (assoc post :body (html/html-snippet (post :body))))
+(def enliveify (partial update-body html/html-snippet))

 (defn render [post]
-  (assoc post :body (apply str (html/emit* (post :body)))))
+  (update-body #(apply str (html/emit* %)) post))


use -Dcontext=... and CONTEXT=... so tools other than cake can support contexts

--- src/cake/tasks/jar.clj
+++ src/cake/tasks/jar.clj
@@ -61,8 +61,8 @@

 (def *project*
   (let [project '%s
-        context (symbol (or (System/getProperty \"cake.context\")
-                            (System/getenv \"CAKE_CONTEXT\")
+        context (symbol (or (System/getProperty \"context\")
+                            (System/getenv \"CONTEXT\")
                             (:context project)))]
     (merge-in project (assoc (context *context*)
                         :context context))))")


Modified 'new' to allow for multiple templates.

--- src/cake/tasks/new.clj
+++ src/cake/tasks/new.clj
@@ -6,12 +6,13 @@
   (:import [org.apache.tools.ant.taskdefs Mkdir Copy]))

 (def default-template
-"(defproject %s \"0.0.1-SNAPSHOT\"
+"(defproject +project+ \"0.0.1-SNAPSHOT\"
   :description \"TODO: add summary of your project\"
   :dependencies [[clojure \"1.2.0\"]])
 ")

-(def template-dir (file "~" ".cake" "template"))
+(def template-dir (file "~" ".cake" "templates"))
+(def default-template-dir (file template-dir "default"))

 (defn rename-dirs [root project]
   (log "Renaming directories with +project+ in their name")
@@ -21,39 +22,42 @@
           :when (not= name replaced)]
     (.renameTo old-file (file (.getParent old-file) replaced))))

-(defn template-new [project]
+(defn template-new [project template]
   (let [root (file *pwd* project)]
     (if (.exists root)
       (println "error:" project "already exists in this directory")
       (do
-        (log "Creating a new project based on ~/.cake/template")
-        (ant Copy {:todir root} (add-fileset {:dir (str (file "~" ".cake" "template"))}))
+        (log (str "Creating a new project based on ~/cake/templates/" template))
+        (ant Copy {:todir root} (add-fileset {:dir (str (file template-dir template))}))
         (rename-dirs root project)
         (let [files (file-seq root)]
           (log (str "Replacing +project+ with '" project "' in all files."))
           (doseq [f (filter #(.isFile %) files)]
             (spit f (.replace (slurp f) "+project+" project))))))))

-(defn create-default-template [project]
-  (log "Creating template directory: ~/.cake/template")
-  (ant Mkdir {:dir template-dir})
-  (ant Mkdir {:dir (file template-dir "src" "+project+")})
-  (spit (file template-dir "src" "+project+" "core.clj") "(ns +project+.core)")
+(defn create-default-template []
+  (log "Creating template directory: ~/.cake/templates/default")
+  (ant Mkdir {:dir default-template-dir})
+  (ant Mkdir {:dir (file default-template-dir "src" "+project+")})
+  (spit (file default-template-dir "src" "+project+" "core.clj") "(ns +project+.core)")
   (log "Created template file: src/+project+/core.clj")
-  (ant Mkdir {:dir (file template-dir "test")})
-  (spit (file template-dir "project.clj") (format default-template project))
+  (ant Mkdir {:dir (file default-template-dir "test")})
+  (spit (file default-template-dir "project.clj") default-template)
   (log "Created template file: project.clj")
-  (spit (file template-dir ".gitignore")
-        (apply str (interleave [".cake" "pom.xml" "*.jar" "*.war" "lib" "classes" "build" project] (repeat "\n"))))
+  (spit (file default-template-dir ".gitignore")
+        (apply str (interleave [".cake" "pom.xml" "*.jar" "*.war" "lib" "classes" "build" "+project+"] (repeat "\n"))))
   (log "Created template file: .gitignore")
-  (extract-resource "LICENSE" template-dir)
+  (extract-resource "LICENSE" default-template-dir)
   (log "Created template LICENSE file (Eclipse Public License)"))

 (deftask new
   "Create scaffolding for a new project."
-  "You can put a default project template in ~/.cake/template. Substitute +project+ anywhere
-   that you want your project name to be."
-  {[project] :new}
-  (when-not (.exists template-dir)
-    (create-default-template project))
-  (template-new project))
+  "You can put project templates in ~/.cake/templates. Each template is a directory with a default
+   template. You can specify which template to use for your project when you call this task. If
+   you don't specify which template to use, ~/.cake/templates will be used. It will be created if
+   it does not already exist.
+   Examples: cake new aproj, cake new mytemplate aproj"
+  {[one two] :new}
+  (when-not (.exists default-template-dir)
+    (create-default-template))
+  (apply template-new (or (and two [two one]) [one "default"])))


Remove debug println.

Remove debug println.

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -210,7 +210,6 @@
     (wait-done done)))

 (defn kv-client [client-addr server-addr server-port]
-  (println :kv-client client-addr server-addr server-port)
   (let [world (:world @curr-world)
         done (atom false)]
     (act client-init world


Each server has a kvs-mgr.

Each server has a kvs-mgr.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -5,6 +5,7 @@
             [cbfg.act-misc :refer [state-loop msg-req msg-put msg-put-res]]
             [cbfg.vis :refer [get-el-value get-el-checked get-el-className get-els]]
             [cbfg.fence]
+            [cbfg.kvs]
             [cbfg.world.t1 :refer [prog-base-now prog-curr-now prog-evt
                                    wait-done addr-override-xy]]
             [cbfg.world.base]
@@ -13,17 +14,19 @@
 (defn coll-handler [actx coll-state m]
   [coll-state nil])

-(defn make-coll [actx rev name]
+(defn make-coll [actx rev name kvs-mgr-ch]
   (let [coll-ch (achan actx)]
     (state-loop actx [:coll name] coll-handler {})
     {:rev rev
      :name name
-     :coll-ch coll-ch}))
+     :coll-ch coll-ch
+     :kvs-mgr-ch kvs-mgr-ch}))

 ; --------------------------------------------

 (defn make-initial-server-state [actx]
-  (let [c (make-coll actx 0 "default")]
+  (let [kvs-mgr-ch (cbfg.kvs/make-kvs-mgr actx)
+        default-coll (make-coll actx 0 "default" kvs-mgr-ch)]
     {:rev 0
      :realms {"_system" {:rev 0
                          :users {"admin" {:rev 0 :pswd "password"}}
@@ -31,7 +34,8 @@
               "_lobby" {:rev 0
                         :users {"_anon" {:rev 0 :pswd ""}}
                         :collsets {"default" {:rev 0
-                                              :colls {"default" c}}}}}}))
+                                              :colls {"default" default-coll}}}}}
+     :kvs-mgr-ch kvs-mgr-ch}))

 (defn server-handler [actx server-state m]
   (case (:op m)
@@ -91,7 +95,7 @@
                                              :colls])]
           (if (not (get (:key m) colls))
             (let [nrev (inc (:rev server-state))
-                  coll (make-coll actx nrev (:key m))]
+                  coll (make-coll actx nrev (:key m) (:kvs-mgr-ch server-state))]
               ; TODO: audit log on success and failure.
               [(-> server-state
                    (assoc-in [:realms (:cur-realm m)


changing host to hostname

changing host to hostname

--- src/celestial/jobs.clj
+++ src/celestial/jobs.clj
@@ -10,10 +10,10 @@
 (def workers (atom {}))

 (defn job-exec [f {:keys [machine] :as spec}]
-  {:pre [(machine :host)] }
+  {:pre [(machine :hostname)] }
   "Executes a job function tries to lock host first pulls lock info from redis"
-  (let [{:keys [host]} machine]
-    (with-lock host #(f spec) {:expiry half-hour :wait-time minute})))
+  (let [{:keys [hostname]} machine]
+    (with-lock hostname #(f spec) {:expiry half-hour :wait-time minute})))

 (def jobs {:machine [reload 2] :provision [puppetize 2] :stage [full-cycle 2]})


make parsing more efficient in terms of code and object-waste

--- src/cheshire/parse.clj
+++ src/cheshire/parse.clj
@@ -1,9 +1,9 @@
 (ns cheshire.parse
   (:import (org.codehaus.jackson JsonParser JsonToken)))

-(declare parse)
+(declare parse*)

-(definline parse-object [^JsonParser jp fst? keywords? eof array-coerce-fn]
+(definline parse-object [^JsonParser jp keywords? array-coerce-fn]
   `(do
      (.nextToken ~jp)
      (loop [mmap# (transient {})]
@@ -14,16 +14,13 @@
                key# (if ~keywords?
                       (keyword key-str#)
                       key-str#)
-               mmap# (assoc!
-                      mmap#
-                      key#
-                      (parse
-                       ~jp ~false ~keywords? ~eof ~array-coerce-fn))]
+               mmap# (assoc! mmap# key#
+                             (parse* ~jp ~keywords? ~array-coerce-fn))]
            (.nextToken ~jp)
            (recur mmap#))
          (persistent! mmap#)))))

-(definline parse-array [^JsonParser jp fst? keywords? eof array-coerce-fn]
+(definline parse-array [^JsonParser jp keywords? array-coerce-fn]
   `(let [array-field-name# (.getCurrentName ~jp)]
      (.nextToken ~jp)
      (loop [coll# (transient (if ~array-coerce-fn
@@ -31,51 +28,28 @@
                                []))]
        (if-not (= (.getCurrentToken ~jp)
                   JsonToken/END_ARRAY)
-         (let [coll# (conj!
-                      coll#
-                      (parse
-                       ~jp
-                       false
-                       ~keywords?
-                       ~eof
-                       ~array-coerce-fn))]
+         (let [coll# (conj! coll#(parse* ~jp ~keywords? ~array-coerce-fn))]
            (.nextToken ~jp)
            (recur coll#))
          (persistent! coll#)))))

+(defn parse* [^JsonParser jp keywords? array-coerce-fn]
+  (condp = (.getCurrentToken jp)
+    JsonToken/START_OBJECT (parse-object jp keywords? array-coerce-fn)
+    JsonToken/START_ARRAY (parse-array jp  keywords? array-coerce-fn)
+    JsonToken/VALUE_STRING (.getText jp)
+    JsonToken/VALUE_NUMBER_INT (.getNumberValue jp)
+    JsonToken/VALUE_NUMBER_FLOAT (.getDoubleValue jp)
+    JsonToken/VALUE_TRUE true
+    JsonToken/VALUE_FALSE false
+    JsonToken/VALUE_NULL nil
+    (throw
+     (Exception.
+      (str "Cannot parse " (pr-str (.getCurrentToken jp)))))))
+
 (defn parse [^JsonParser jp fst? keywords? eof array-coerce-fn]
-  (let [fst? (boolean fst?)
-        keywords? (boolean keywords?)]
-    (if fst?
-      (do
-        (.nextToken jp)
-        (if (nil? (.getCurrentToken jp))
-          eof
-          (condp = (.getCurrentToken jp)
-            JsonToken/START_OBJECT (parse-object jp fst? keywords?
-                                                 eof array-coerce-fn)
-            JsonToken/START_ARRAY (parse-array jp fst? keywords?
-                                               eof array-coerce-fn)
-            JsonToken/VALUE_STRING (.getText jp)
-            JsonToken/VALUE_NUMBER_INT (.getNumberValue jp)
-            JsonToken/VALUE_NUMBER_FLOAT (.getDoubleValue jp)
-            JsonToken/VALUE_TRUE true
-            JsonToken/VALUE_FALSE false
-            JsonToken/VALUE_NULL nil
-            (throw
-             (Exception.
-              (str "Cannot parse " (pr-str (.getCurrentToken jp))))))))
-      (condp = (.getCurrentToken jp)
-        JsonToken/START_OBJECT (parse-object jp fst? keywords?
-                                             eof array-coerce-fn)
-        JsonToken/START_ARRAY (parse-array jp fst? keywords?
-                                           eof array-coerce-fn)
-        JsonToken/VALUE_STRING (.getText jp)
-        JsonToken/VALUE_NUMBER_INT (.getNumberValue jp)
-        JsonToken/VALUE_NUMBER_FLOAT (.getDoubleValue jp)
-        JsonToken/VALUE_TRUE true
-        JsonToken/VALUE_FALSE false
-        JsonToken/VALUE_NULL nil
-        (throw
-         (Exception.
-          (str "Cannot parse " (pr-str (.getCurrentToken jp)))))))))
+  (let [keywords? (boolean keywords?)]
+    (.nextToken jp)
+    (if (nil? (.getCurrentToken jp))
+      eof
+      (parse* jp keywords? array-coerce-fn))))


Use new path for index.html.

Use new path for index.html.

--- src/clj/sptcg/core.clj
+++ src/clj/sptcg/core.clj
@@ -18,7 +18,7 @@
    [sptcg.util :as util]))

 (defn index [{db :db :as req}]
-  (assoc (file-response "public/html/index.html" {:root "resources"})
+  (assoc (file-response "public/index.html" {:root "resources"})
     :session (assoc (:session req) :uid (java.util.UUID/randomUUID))))

 (defn register [{db :db {:keys [name pwd email]} :params :as req}]


Shorter long lines

Shorter long lines

--- src/clj/ufo/server.clj
+++ src/clj/ufo/server.clj
@@ -24,14 +24,12 @@
     #_(p/exp-transformer (p/parse $ p/exp-parser))
     (p/title-content-transformer (p/parse $ p/title-content-parser))
     (map (fn [hm]
-           (update hm :title (fn [val]
-                               (let [r (p/exp-transformer (p/parse val p/exp-parser))]
-                                 r))))
+           (update hm :title
+                   (fn [v] (p/exp-transformer (p/parse v p/exp-parser)))))
          $)
     (map (fn [hm]
-           (update hm :content (fn [val]
-                               (let [r (p/exp-transformer (p/parse val p/exp-parser))]
-                                 r))))
+           (update hm :content
+                   (fn [v] (p/exp-transformer (p/parse v p/exp-parser)))))
          $)
     {:data $}
     (end-response $)))


correct old function references

correct old function references

--- src/clj_money/seed.clj
+++ src/clj_money/seed.clj
@@ -40,8 +40,8 @@
       context
       (update-in context
                  [:accounts]
-                 (fnil #(concat (accounts/select-by-entity-id storage-spec
-                                                              (:id entity))
+                 (fnil #(concat (accounts/search storage-spec
+                                                 {:entity-id (:id entity)})
                                 %)
                        [])))))

@@ -98,7 +98,7 @@
     (let [user (users/find-by-email s email)
           entity (entities/find-by-name s user entity-name)
           start-date (parse-local-date start-date)
-          all-accounts (accounts/select-by-entity-id s (:id entity))
+          all-accounts (accounts/search s {:entity-id (:id entity)})
           accounts (->> ["Salary"
                          "FIT"
                          "Social Security"


Cleanup

Cleanup

--- src/cljs/app/core.cljs
+++ src/cljs/app/core.cljs
@@ -1,5 +1,6 @@
 (ns app.core
-  (:require [cljs.core.async :as async :refer [<!]]
+  (:require [clojure.string :as str]
+            [cljs.core.async :as async :refer [<!]]
             [reagent.core :as reagent]
             [kioo.reagent :as kioo]
             [cljs-http.client :as http]
@@ -49,55 +50,71 @@

 ;; Templating
 (def icon-files
-  {"Windows" "images/windows.svg",
-   "Linux" "images/linux.svg",
-   "Mac OS X" "images/apple.svg",
-   "Other" "",
-   "Installer" "images/monitor.svg",
-   "Portable" "images/archive.svg",
+  {"Windows" "images/windows.svg"
+   "Linux" "images/linux.svg"
+   "Mac OS X" "images/apple.svg"
+   "Other" ""
+   "Installer" "images/monitor.svg"
+   "Portable" "images/archive.svg"
    "Disk Image" "images/disc.svg"})

-(def themes ["default", "green", "red", "blue"])
+(def themes ["default" "green" "red" "blue"])

-(defsnippet kryvos-download-item "templates/download.html" [:.download-item]
+(defsnippet kryvos-download-item
+  "templates/download.html"
+  [:.download-item]
   [{url :url word-size :word-size file-type :file-type}]
   {[:a] (kioo/do-> (kioo/set-class "align vertical button-outline")
                    (kioo/set-attr :href url)
                    (kioo/set-attr :download "")
-                   (kioo/content [:img {:src (get icon-files file-type)}]
+                   (kioo/content [:img {:src (get icon-files
+                                                  file-type)}]
                                  [:span
-                                   (if (clojure.string/blank? word-size)
+                                   (if (str/blank? word-size)
                                      file-type
-                                     (str file-type " / " word-size))]))})
+                                     (str file-type
+                                          " / "
+                                          word-size))]))})

-(defsnippet kryvos-download "templates/download.html" [:.download]
+(defsnippet kryvos-download
+  "templates/download.html"
+  [:.download]
   [category files]
   {[:span] (kioo/content [:h3 {:class "inline-heading"} category]
-                         [:img {:class "os-icon",
+                         [:img {:class "os-icon"
                                 :src (get icon-files category)}])
    [:ul] (kioo/do->
            (kioo/set-class "align horizontal link-list")
            (kioo/content (map kryvos-download-item files)))})

-(deftemplate kryvos-downloads "templates/download.html" []
+(deftemplate kryvos-downloads
+  "templates/download.html"
+  []
   {[:.downloads] (kioo/content (for [[k v] @downloads]
                                  ^{:key k}
                                  (kryvos-download k v)))})

-(defsnippet theme-bar "templates/theme-bar.html" [:.link-item] [theme]
+(defsnippet theme-bar
+  "templates/theme-bar.html"
+  [:.link-item]
+  [theme]
   {[:a] (kioo/do->
-          (kioo/content [:img {:src (str "images/" theme ".svg"),
+          (kioo/content [:img {:src (str "images/" theme ".svg")
                                :alt (str theme " Theme")}])
           (kioo/listen :on-click #(swap! prefs assoc :theme theme)))})

-(deftemplate page "index.html" []
-  {[:#background] (kioo/set-class (if (clojure.string/blank? (:theme @prefs))
-                                    "background-image default"
-                                    (str "background-image " (:theme @prefs))))
+(deftemplate page
+  "index.html"
+  []
+  {[:#background
+     (kioo/set-class (if (str/blank? (:theme @prefs))
+                       "background-image default"
+                       (str "background-image " (:theme @prefs))))]
    [:.kryvos-downloads] (kioo/content (kryvos-downloads))
    [:footer :ul] (kioo/content (map theme-bar themes))})

 (defn init []
-  (let [json-url "https://api.github.com/repos/adolby/Kryvos/releases/latest"]
+  (let [json-url
+        "https://api.github.com/repos/adolby/Kryvos/releases/latest"]
     (download-json json-url))
   (reagent/render-component [page] (.-body js/document)))


restructure s3-logs test (deflake) (#1537)

--- waiter/integration/waiter/kubernetes_scheduler_integration_test.clj
+++ waiter/integration/waiter/kubernetes_scheduler_integration_test.clj
@@ -118,9 +118,7 @@
     (when (using-k8s? waiter-url)
       (when-let [log-bucket-url (-> waiter-url get-kubernetes-scheduler-settings :log-bucket-url)]
         (let [router-url (-> waiter-url routers first val)
-              headers {:x-waiter-concurrency-level 1
-                       :x-waiter-distribution-scheme "simple"
-                       :x-waiter-max-instances 2
+              headers {:x-waiter-max-instances 2
                        :x-waiter-min-instances 1
                        :x-waiter-name (rand-name)
                        :x-waiter-scale-down-factor 0.99
@@ -153,29 +151,36 @@
                   (assert-response-status (make-request-fn file-link) http-200-ok)
                   (log/warn "test-s3-logs did not verify file link:" file-link))))

-            ;; Get a service with at least one killed instance.
-            (log/info "starting parallel requests")
-            ;; expect that second instance should be healthy inside 10 minutes
-            (let [async-create-headers (merge headers {:x-kitchen-delay-ms 600000
-                                                       :x-waiter-async-request-timeout 615000})
-                  async-request-fn (fn [] (->> #(make-kitchen-request waiter-url % :method :get :path "/async/request")
-                                               (make-request-with-debug-info async-create-headers)))
-                  async-responses (->> async-request-fn (repeatedly 2) vec)
-                  instance-ids (->> async-responses (map :instance-id) set)]
-              (assert-response-status (first async-responses) http-202-accepted)
-              (assert-response-status (second async-responses) http-202-accepted)
-              (is (> (count instance-ids) 1)
-                  (str "async requests not handled by separate instances, instance id: " instance-ids))
-              ;; Canceling both of the async requests should scale down to 1 by killing 1 instance.
-              (doseq [async-response async-responses]
-                (let [status-endpoint (response->location async-response)
-                      cancel-response (make-kitchen-request waiter-url headers :method :delete :path status-endpoint)]
-                  (assert-response-status cancel-response http-204-no-content))))
-
-            (log/info "waiting for at least one killed instance on target router")
-            (is (wait-for #(seq (killed-instances router-url service-id :cookies cookies))
-                          :interval 2 :timeout 45)
-                (str "no killed instances found for " service-id))
+            ;; get a killed instance by scaling up to 2 and back down to 1
+            (log/info "creating min-instances=2 override")
+            (let [override-path (str "/apps/" service-id "/override")
+                  post-override-response (make-request waiter-url override-path
+                                                       :body (utils/clj->json {:min-instances 2})
+                                                       :cookies cookies
+                                                       :method :post
+                                                       :verbose true)]
+              (assert-response-status post-override-response http-200-ok)
+
+              ;; wait for scale up
+              (is (wait-for #(let [healthy-instance-count (->> (active-instances router-url service-id :cookies cookies)
+                                                               (filter :healthy?)
+                                                               (count))]
+                               (>= healthy-instance-count 2))
+                            :interval 2 :timeout 300)
+                  (str service-id " never scaled to at least 2 healthy instances"))
+
+              (log/info "deleting min-instances=2 override")
+              (let [delete-override-response (make-request waiter-url override-path
+                                                           :cookies cookies
+                                                           :method :delete
+                                                           :verbose true)]
+                (assert-response-status delete-override-response http-200-ok))
+
+              ;; wait for scale down
+              (log/info "waiting for at least one killed instance on target router")
+              (is (wait-for #(seq (killed-instances router-url service-id :cookies cookies))
+                            :interval 2 :timeout 45)
+                  (str "no killed instances found for " service-id)))

             ;; Test that the killed instance's logs were persisted to S3.
             ;; This portion of the test logic was modified from the active-instances tests above.


cleaner gol code

cleaner gol code

--- spinning/src/app/core.cljs
+++ spinning/src/app/core.cljs
@@ -183,7 +183,9 @@
   (swap! state assoc-in [:soe :channel] (chan-of-primes)))

 (defn teardown-soe! []
-  (swap! state assoc-in [:soe :channel] nil))
+  (swap! state assoc-in [:soe :channel] nil)
+  (swap! state assoc-in [:soe :max-prime] nil)
+  (swap! state assoc-in [:soe :prime-count] 0))

 (defn update-soe! [primes-ch]
   (swap! state update-in [:soe :prime-count] inc)
@@ -222,6 +224,9 @@
        ((juxt inc      inc identity dec dec      dec identity inc) x)
        ((juxt identity inc inc      inc identity dec dec      dec) y)))

+(defn living-neighbors [cells k]
+  (keep #(get cells %1) (neighbors k)))
+
 (defn create-cell
   ([]
    (create-cell {:r (rand-int 256) :g (rand-int 256) :b (rand-int 256)}))
@@ -231,16 +236,19 @@
 (defn create-cells [seed]
   (into {} (for [k seed] [k (create-cell)])))

-(defn create-color-blend [cells k]
-  "Return a newborn cell color as a blend of colors of its 3 living neighbors."
-  (let [[c1 c2 c3] (map :color (keep #(get cells %1) (neighbors k)))]
-    {:r (:r c1) :g (:g c2) :b (:b c3)}))
+(defn color-blend [c1 c2 c3]
+  {:r (:r c1) :g (:g c2) :b (:b c3)})
+
+(defn newborn [cells k]
+  "Return a newborn cell with a blend of colors of its 3 living neighbors."
+  (create-cell (apply color-blend (map :color (living-neighbors cells k)))))

 (defn cell-fate [cells [k n]]
+  "Determine if a cell will be part of the next generation."
   (when (or (= n 3) (and (= n 2) (contains? cells k)))
-    (let [cell (or (get cells k)
-                   (create-cell (create-color-blend cells k)))]
-      [k (update-in cell [:age] inc)])))
+    (let [cell (or (get cells k) (newborn cells k))
+          cell (update-in cell [:age] inc)]
+      [k cell])))

 (defn step-chan [cells]
   "Returns a channel containing a single map of the next generation of cells."
@@ -257,7 +265,8 @@

 (defn teardown-gol! []
   (swap! state assoc-in [:gol :busy?] false)
-  (swap! state assoc-in [:gol :cells] nil))
+  (swap! state assoc-in [:gol :cells] nil)
+  (swap! state assoc-in [:gol :generation] 0))

 (defn swap-gol! [cells]
   (swap! state assoc-in [:gol :cells] cells)
@@ -327,7 +336,7 @@
   (setup-gol!)
   (setup-soe!)
   (start-rendering!)
-  (start-soe!)
+;  (start-soe!)
   (start-gol!)
   )


Add basic chunks functionality

Add basic chunks functionality

--- src/clj_simple_chart/ssb/data/sal_av_petroleumsprodukt_11174.clj
+++ src/clj_simple_chart/ssb/data/sal_av_petroleumsprodukt_11174.clj
@@ -1,24 +1,74 @@
 (ns clj-simple-chart.ssb.data.sal-av-petroleumsprodukt-11174
   (:require [clj-simple-chart.ssb.data.ssb-api :as ssb]
             [clojure.test :as test]
-            [clj-simple-chart.csv.csvmap :as csv]))
+            [clj-simple-chart.csv.csvmap :as csv]
+            [clojure.string :as str]))

 ; 11174: Salg av petroleumsprodukter, etter kjøpegruppe og produkttype (mill. liter). Foreløpige tall (F) 2010M01 - 2017M12
 ;
 ; https://www.ssb.no/statbank/table/11174?rxid=49a52ff4-5d3c-4264-aa49-95134312070d

-(def raw-data (ssb/fetch 11174 {"ContentsCode" "Salg"
-                                "Region" "Hele landet"
+(def raw-data (ssb/fetch 11174 {"ContentsCode"  "Salg"
+                                "Region"        "Hele landet"
                                 "PetroleumProd" ["Autodiesel" "Bilbensin"]
-                                "Kjopegrupper" "Alle kjøpegrupper"
-                                "Tid" "*"}))
+                                "Kjopegrupper"  "Alle kjøpegrupper"
+                                "Tid"           "*"}))

 (test/is (= [:kjøpegruppe :petroleumsprodukt :region :salg] (:columns raw-data)))

+(defn column-value->column [column row]
+  {:pre [(map? row)
+         (keyword? column)]}
+  (when-not (= 1 (count (filter number? (vals row))))
+    (throw (ex-info "Expected a single value with type number" {:row    row
+                                                                :column column})))
+  (reduce (fn [o [k v]]
+            (cond (= k column) o
+                  (number? v) (assoc o (keyword (str/lower-case (get row column))) v)
+                  :else (assoc o k v)))
+          {}
+          row))
+
+(defn contract-by-column [column rows]
+  (->> rows
+       (group-by column)
+       (vals)
+       (map #(reduce merge {} %))
+       (sort-by column)))
+
+(defn prev-indexes [idx n]
+  {:pre [(not (neg? idx)) (pos-int? n)]}
+  (vec (remove neg? (range (inc (- idx n))
+                           (inc idx)))))
+
+(test/is (= [0] (prev-indexes 0 1)))
+(test/is (= [1] (prev-indexes 1 1)))
+(test/is (= [2] (prev-indexes 2 1)))
+
+(test/is (= [0] (prev-indexes 0 3)))
+(test/is (= [0 1] (prev-indexes 1 3)))
+(test/is (= [0 1 2] (prev-indexes 2 3)))
+(test/is (= [1 2 3] (prev-indexes 3 3)))
+(test/is (= [2 3 4] (prev-indexes 4 3)))
+
+(defn chunks [rows n]
+  {:pre (indexed? rows)}
+  (remove nil?
+          (for [i (range 0 (count rows))]
+            (let [indexes (prev-indexes i n)
+                  items (map #(nth rows %) indexes)]
+              (when (= (count indexes) n)
+                items)))))
+
+(test/is (= '((:a) (:b) (:c) (:d) (:e)) (chunks [:a :b :c :d :e] 1)))
+(test/is (= '((:a :b) (:b :c) (:c :d) (:d :e)) (chunks [:a :b :c :d :e] 2)))
+(test/is (= '((:a :b :c) (:b :c :d) (:c :d :e)) (chunks [:a :b :c :d :e] 3)))
+
 (def data (->> (:data raw-data)
-               (sort-by :dato)
+               (map #(dissoc % :kjøpegruppe))
+               (map #(dissoc % :region))
                (csv/number-or-throw-columns [:salg])
-               (map #(dissoc % :kjøpegruppe))
-               (map #(dissoc % :region))))
+               (map (partial column-value->column :petroleumsprodukt))
+               (contract-by-column :dato)))

 (test/is (= "2010-01" (:dato (first data))))


Optimize empty-selection detection

Optimize empty-selection detection

--- src/discuss/views.cljs
+++ src/discuss/views.cljs
@@ -137,17 +137,18 @@
 (defn- show-selection
   "Shows selected text from website if available."
   []
-  (when-let [selection (lib/get-selection)]
-    (dom/div #js {:className "input-group"}
-             (dom/span #js {:className "input-group-addon"}
-                       (vlib/fa-icon "fa-quote-left"))
-             (dom/input #js {:className "form-control"
-                             :value     selection})
-             (dom/span #js {:className "input-group-addon"}
-                       (vlib/fa-icon "fa-quote-right"))
-             (dom/span #js {:className "input-group-addon pointer"
-                            :onClick   lib/remove-selection}
-                       (vlib/fa-icon "fa-times")))))
+  (let [selection (lib/get-selection)]
+    (when (> (count selection) 1)
+      (dom/div #js {:className "input-group"}
+               (dom/span #js {:className "input-group-addon"}
+                         (vlib/fa-icon "fa-quote-left"))
+               (dom/input #js {:className "form-control"
+                               :value     selection})
+               (dom/span #js {:className "input-group-addon"}
+                         (vlib/fa-icon "fa-quote-right"))
+               (dom/span #js {:className "input-group-addon pointer"
+                              :onClick   lib/remove-selection}
+                         (vlib/fa-icon "fa-times"))))))

 (defn add-element
   "Show form to add a new statement."


Refactors

Refactors

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -645,8 +645,10 @@
   (let [{:keys [sym spec failure] :or {sym '<unknown>}} check-result
         ret #?(:clj (:clojure.spec.test.check/ret check-result)
                :cljs (:clojure.test.check/ret check-result))
-        bad-args (first (:fail ret))
         explain-data (ex-data failure)
+        bad-args (or #?(:clj (:clojure.spec.test.alpha/args explain-data)
+                        :cljs (:cljs.spec.test.alpha/args explain-data))
+                     (first (:fail ret)))
         failure-reason (::s/failure explain-data)
         sym (or sym '<unknown>)]
     (str
@@ -699,8 +701,7 @@
                            #(map
                              (fn [p]
                                (assoc p :expound/check-fn-call (concat (list sym)
-                                                                       #?(:clj (:clojure.spec.test.alpha/args explain-data)
-                                                                          :cljs (:cljs.spec.test.alpha/args explain-data)))))
+                                                                       bad-args)))
                              %))))

        failure


More tests for scaling and equality

More tests for scaling and equality

--- src/test/clj/clojure/core/matrix/test_complex.clj
+++ src/test/clj/clojure/core/matrix/test_complex.clj
@@ -27,6 +27,12 @@
   (is (not (cm/complex? [1 2 3])))
   (is (cm/complex? (cm/complex-array [1 2 3]))))

+(deftest test-complex-equality
+  (is (m/e= (c/complex-number 1 2) (cm/complex-array 1 2))))
+
 (deftest test-scaling
-  (is (= (c/complex-number 3 6) (m/scale (c/complex-number 1 2) 3))))
+  (is (= (c/complex-number 3 6) (m/scale (c/complex-number 1 2) 3)))
+  (is (= (c/complex-number 3 6) (m/scale 3 (c/complex-number 1 2))))
+  (is (= (c/complex-number 3 6) (m/mul (c/complex-number 1 2) 3)))
+  (is (= (c/complex-number 3 6) (m/mul 3 (c/complex-number 1 2)))))


day 20

day 20

--- src/adventofcode/day20.clj
+++ src/adventofcode/day20.clj
@@ -9,8 +9,25 @@
                   [divisor multiple]))))
           (range 1 (inc (int (Math/sqrt (int number)))))))

-(def part-one (->> (range)
-                   (map #(vector % (apply + (divisors %))))
-                   (drop-while #(> 2900000 (second %)))
-                   first
-                   first))
+(defn presents-one [number]
+  (* 10 (apply + (divisors number))))
+
+(defn presents-two [number]
+  (->> (divisors number)
+       (filter #(<= (/ number %) 50))
+       (map #(* 11 %))
+       (apply +)))
+
+(defn part-one []
+  (->> (range)
+       (map #(vector % (presents-one %)))
+       (drop-while #(> 29000000 (second %)))
+       first
+       first))
+
+(defn part-two []
+  (->> (range)
+       (map #(vector % (presents-two %)))
+       (drop-while #(> 29000000 (second %)))
+       first
+       first))


Capture idea.

Capture idea.

--- src/afterglow/examples.clj
+++ src/afterglow/examples.clj
@@ -598,6 +598,11 @@
                                     :color :cyan :effect-name "Hypnotic Rotate Clockwise" :level 50))

     ;; What else?
+    ;; TODO: Refine this and make a cue
+    #_(show/add-effect! :torrent-focus (afterglow.effects.channel/function-effect
+                                        "F" :focus (params/build-oscillated-param (oscillators/sine-bar)
+                                                                                :min 20 :max 200)
+                                        (show/fixtures-named "torrent")))
     ))

 (defn use-push


(maint) Remove unused namespace

(maint) Remove unused namespace

--- test/integration/puppetlabs/puppetserver/bootstrap_testutils.clj
+++ test/integration/puppetlabs/puppetserver/bootstrap_testutils.clj
@@ -1,7 +1,6 @@
 (ns puppetlabs.puppetserver.bootstrap-testutils
   (:require [puppetlabs.trapperkeeper.config :as tk-config]
             [puppetlabs.trapperkeeper.bootstrap :as tk-bootstrap]
-            [puppetlabs.trapperkeeper.services :as tk-services]
             [puppetlabs.trapperkeeper.testutils.bootstrap :as tk-testutils]
             [puppetlabs.kitchensink.core :as ks]
             [me.raynes.fs :as fs]


clear out data-uploaded when file is successfully uploaded

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -100,7 +100,8 @@
       (.on blob-stream "end"
         (fn []
           (println "Upload successful!")
-          (swap! app-state assoc :upload-progress nil)))
+          (swap! app-state assoc :upload-progress nil)
+          (swap! app-state assoc :data-uploaded 0)))

       (.emit (js/ss socket) "file" stream)
       (.pipe blob-stream stream))))


Updated sandbox code to include maximize opt.

--- src/fx_clj/sandbox.clj
+++ src/fx_clj/sandbox.clj
@@ -21,7 +21,7 @@
   ;; By binding to a var,  my-refresh-fn can be  easily updated and reloaded
   ;; at the REPL"

-  [refresh-fn & {:keys [title] :or {title (str "Sandbox" (swap! auto-inc inc))}}]
+  [refresh-fn & {:keys [title maximized] :or {title (str "Sandbox" (swap! auto-inc inc))}}]
   (run<!!
     (let [scene (fx/scene (refresh-fn))
           stage (fx/stage)]
@@ -33,5 +33,6 @@
       (.setScene stage scene)
       (.initModality stage Modality/NONE)
       (pset! stage {:title title})
+      (when maximized (.setMaximized stage true))
       (.show stage)
       stage)))


~(defn basecamp): removing binding for generate/use-spec-cache? : no longer in use

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -50,8 +50,7 @@
                                                      :rest []}}}}}}}]]
     (repeatedly #(println
                   (let [spec (first (shuffle specs))]
-                    (let [result (morph (time (binding [babel.generate/truncate? true
-                                                        babel.generate/use-spec-cache? true]
+                    (let [result (morph (time (binding [babel.generate/truncate? true]
                                                 (wait wait-ms-for-generation (fn [] (generate spec model))))))]
                       (or (and (not (empty? result)) result)
                           "TIMEOUT.")))))))


Can select nodes from zoomed out view

Can select nodes from zoomed out view

--- src/graphito/core.cljs
+++ src/graphito/core.cljs
@@ -595,16 +595,6 @@
   (.map (gesture-observable manager "tap")
         (fn [e] (v/create (-> e .-center .-x) (-> e .-center .-y)))))

-(defn zoom-in-on-tap! [manager
-                       current-state
-                       animation-observable]
-  (let [taps (tap-observable manager)]
-    (.subscribe
-      taps
-      #(if (= (:projection @current-state) :zoom-out)
-         (zoom-in-to-pos! current-state
-                          (zoom-out->world-pos @current-state %))))))
-
 (defn svg-element-position [svg elem]
   (let [box (.getBoundingClientRect elem)
         center-x (+ (.-left box) (/ (.-width box) 2))
@@ -634,15 +624,21 @@
     {:node @closest-node
      :distance (js/Math.sqrt @closest-distance-sq)}))

-(defn select-node-on-tap! [manager current-state animation-observable]
-  (let [taps (tap-observable manager)]
-    (-> taps
-        (suppress-while-animating animation-observable)
-        (.map #(closest-node @current-state %))
-        (.filter #(< (:distance %) (/ hitbox-size 2)))
-        (.subscribe (fn [{:keys [node]}]
-                      (if (= (:projection @current-state) :fisheye)
-                        (select-and-zoom-to-node! current-state node)))))))
+(defn zoom-and-select-on-tap! [manager current-state animation-observable]
+  (let [taps (tap-observable manager)
+        partitions (-> taps
+            (suppress-while-animating animation-observable)
+            (.map #(closest-node @current-state %))
+            (.partition #(< (:distance %) (/ hitbox-size 2))))
+        node-taps (aget partitions 0)
+        space-taps (aget partitions 1)]
+        (.subscribe node-taps
+                    (fn [{:keys [node]}]
+                        (select-and-zoom-to-node! current-state node)))
+        (.subscribe space-taps
+                    #(if (= (:projection @current-state) :zoom-out)
+                       (zoom-in-to-pos! current-state
+                                        (zoom-out->world-pos @current-state %))))))

 ;; Exported function to do magic

@@ -666,5 +662,4 @@
     (move-camera-on-swipe! gesture-manager current-state animation-subject)
     (switch-zoom-on-spacebar! current-state animation-subject)
     (zoom-on-pinch! gesture-manager current-state animation-subject)
-    (zoom-in-on-tap! gesture-manager current-state animation-subject)
-    (select-node-on-tap! gesture-manager current-state animation-subject)))
+    (zoom-and-select-on-tap! gesture-manager current-state animation-subject)))


Move private key serialization to key-to-str function

--- src/bitcoin/miniwallet.clj
+++ src/bitcoin/miniwallet.clj
@@ -28,13 +28,17 @@
 (defn minikey-to-private [minikey]
   (ECKey/fromPrivate (BigInteger. (sha256 minikey) 16) false))

+;; Format given ECKey to "dumpprivkey" format
+(defn key-to-str [key] (.toString (.getPrivateKeyEncoded key (NetworkParameters/prodNet))))
+
+;; Bitcoin wallet with mini private key (https://en.bitcoin.it/wiki/Mini_private_key_format)
 (defn gen-miniwallet []
   (let [key-str (gen-minikey)
         key (minikey-to-private key-str)]
     (println key-str (.getPublicKeyAsHex key) (private-to-address key))))

+;; Encrypted bitcoin wallet (https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki)
 (defn gen-bip38 [passphrase]
   (let [key (ECKey.)
-        plain-key (.toString (.getPrivateKeyEncoded key (NetworkParameters/prodNet)))
-        key-str (com.fruitcat.bitcoin.BIP38/encryptNoEC passphrase plain-key true)]
+        key-str (com.fruitcat.bitcoin.BIP38/encryptNoEC passphrase (key-to-str key) true)]
     (println key-str (.getPublicKeyAsHex key) (private-to-address key) passphrase)))


try example with decoding pub key from string


Add integration tests for batch-ops.

Add integration tests for batch-ops.

--- src/blocks/store/tests.clj
+++ src/blocks/store/tests.clj
@@ -102,6 +102,26 @@
                  (pr-str {:after after, :limit limit})))))))

+(defn test-batch-ops
+  "Tests the batch functionality of a store."
+  [store]
+  (let [blocks (take 10 (random-blocks 512))]
+    (testing "put-batch!"
+      (let [block-batch (block/put-batch! store blocks)]
+        (is (= (count blocks) (count block-batch)))
+        (is (every? (set (map :id block-batch)) (map :id blocks)))))
+    (testing "get-batch"
+      (let [block-batch (block/get-batch store (cons (multihash/sha1 "foo")
+                                                     (map :id blocks)))]
+        (is (= (count blocks) (count block-batch)))
+        (is (every? (set (map :id block-batch)) (map :id blocks)))))
+    (testing "delete-batch!"
+      (let [deleted-ids (block/delete-batch! store (cons (multihash/sha1 "foo")
+                                                         (map :id blocks)))]
+        (is (= (count blocks) (count deleted-ids)))
+        (is (every? (set deleted-ids) (map :id blocks)))))))
+
+
 (defmacro ^:private test-section
   [title & body]
   `(do (printf "    * %s\n" ~title)
@@ -137,6 +157,8 @@
           (is (true? (block/delete! store (:id block))))))
       (test-section "put attributes"
         (test-put-attributes store))
+      (test-section "batch operations"
+        (test-batch-ops store))
       (let [stored-content (test-section (str "populating " blocks " blocks")
                              (populate-blocks! store blocks max-size))]
         (test-section "list stats"


improve verbose message for skipping to load unspecified config files

--- src/bract/core/inducer.clj
+++ src/bract/core/inducer.clj
@@ -104,7 +104,9 @@
       (->> config-files
         (kdef/resolve-config context)
         (assoc context (key kdef/ctx-config)))
-      context)))
+      (do
+        (echo/echo (format "No config files specified at %s for reading, skipping" (key kdef/ctx-config-files)))
+        context))))

 (defn run-context-inducers


Document and simplify fop invocation

Document and simplify fop invocation

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -1,14 +1,12 @@
 (ns catalog.layout.fop
   (:require [catalog.layout.common :as layout]
             [clojure.data.xml :as xml]
-            [clojure.java
-             [io :as io]
-             [shell :as shell]]
+            [clojure.java.io :as io]
             [clojure.string :as string])
-  (:import [java.io BufferedOutputStream FileOutputStream StringReader]
-           javax.xml.transform.TransformerFactory
+  (:import java.io.StringReader
            javax.xml.transform.sax.SAXResult
            javax.xml.transform.stream.StreamSource
+           javax.xml.transform.TransformerFactory
            [org.apache.fop.apps FopFactory MimeConstants]))

 (def ^:private region-body-margin-top 15)
@@ -371,9 +369,17 @@
         (xml/indent out))))

 (defn generate-pdf [document out]
-  (with-open [out (BufferedOutputStream. (FileOutputStream. out))]
-    (.transform (.newTransformer (TransformerFactory/newInstance))
-                (StreamSource. (StringReader. (xml/emit-str document)))
-                (SAXResult. (.getDefaultHandler
-                             (.newFop (FopFactory/newInstance (io/file (io/resource "fop.xconf")))
-                                      MimeConstants/MIME_PDF out))))))
+  ;; generate PDF according to https://xmlgraphics.apache.org/fop/2.0/embedding.html#basics
+  (with-open [out (io/output-stream out)]
+    (let [;; Construct a FopFactory by specifying a reference to the configuration file
+          factory (FopFactory/newInstance (io/file (io/resource "fop.xconf")))
+          ;; Construct fop with desired output format
+          fop (.newFop factory MimeConstants/MIME_PDF out)
+          ;; Setup JAXP using identity transformer
+          transformer (.newTransformer (TransformerFactory/newInstance))
+          ;; Setup input and output for XSLT transformation
+          source (StreamSource. (StringReader. (xml/emit-str document)))
+          ;; Resulting SAX events (the generated FO) must be piped through to FOP
+          saxresult (SAXResult. (.getDefaultHandler fop))]
+      ;; Start XSLT transformation and FOP processing
+      (.transform transformer source saxresult))))


Find fop.xconf properly inside a application server container

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -825,25 +825,30 @@

 (defn generate-pdf! [document out]
   ;; generate PDF according to https://xmlgraphics.apache.org/fop/2.0/embedding.html#basics
-  (with-open [out (io/output-stream out)]
-    (let [;; Construct a FopFactory by specifying a reference to the configuration file
-          factory (FopFactory/newInstance (.toURI (io/resource "fop.xconf")))
-          ;; get a user agent and add a listener to it that logs events
-          user-agent (.newFOUserAgent factory)
-          broadcaster (.getEventBroadcaster user-agent)
-          _ (.addEventListener broadcaster
-                               (reify EventListener
-                                 (processEvent [this event]
-                                   (let [id (.getEventID event)]
-                                     (when (not= id "org.apache.fop.render.RendererEventProducer.endPage")
-                                       (println (EventFormatter/format event)))))))
-          ;; Construct fop with desired output format
-          fop (.newFop factory MimeConstants/MIME_PDF user-agent out)
-          ;; Setup JAXP using identity transformer
-          transformer (.newTransformer (TransformerFactory/newInstance))
-          ;; Setup input and output for XSLT transformation
-          source (StreamSource. (StringReader. (xml/emit-str document)))
-          ;; Resulting SAX events (the generated FO) must be piped through to FOP
-          saxresult (SAXResult. (.getDefaultHandler fop))]
-      ;; Start XSLT transformation and FOP processing
-      (.transform transformer source saxresult))))
+  (let [config-url (io/resource "fop.xconf")]
+    (with-open [out (io/output-stream out)
+                conf-stream (io/input-stream config-url)]
+      (let [;; get the base uri to resolve resource URIs against
+            base-uri (.toURI config-url)
+            ;; Construct a FopFactory by specifying a base-uri and an
+            ;; input stream containing the configuration
+            factory (FopFactory/newInstance base-uri conf-stream)
+            ;; get a user agent and add a listener to it that logs events
+            user-agent (.newFOUserAgent factory)
+            broadcaster (.getEventBroadcaster user-agent)
+            ;; _ (.addEventListener broadcaster
+            ;;                      (reify EventListener
+            ;;                        (processEvent [this event]
+            ;;                          (let [id (.getEventID event)]
+            ;;                            (when (not= id "org.apache.fop.render.RendererEventProducer.endPage")
+            ;;                              (println (EventFormatter/format event)))))))
+            ;; Construct fop with desired output format
+            fop (.newFop factory MimeConstants/MIME_PDF user-agent out)
+            ;; Setup JAXP using identity transformer
+            transformer (.newTransformer (TransformerFactory/newInstance))
+            ;; Setup input and output for XSLT transformation
+            source (StreamSource. (StringReader. (xml/emit-str document)))
+            ;; Resulting SAX events (the generated FO) must be piped through to FOP
+            saxresult (SAXResult. (.getDefaultHandler fop))]
+        ;; Start XSLT transformation and FOP processing
+        (.transform transformer source saxresult)))))


Pass path and path to number mapping to the md handling code

So that markdown can properly look up section numbers and create correct
link targets to the headings

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -299,7 +299,8 @@
     (set-marker (layout/translations genre))
     (cond
       ;; handle the special case where the editorial or the recommendations are passed in the tree
-      (#{:editorial :recommendations :recommendation} genre) (md-to-fop items)
+      (#{:editorial :recommendations :recommendation} genre) (md-to-fop items
+                                                                        [fmt genre] path-to-numbers)
       (#{:kinder-und-jugendbücher} genre) (subgenres-sexp items fmt genre (inc level) path-to-numbers)
       (#{:hörbuch} fmt) (subgenres-sexp items fmt genre (inc level) path-to-numbers)
       :else (entries-sexp items))]))
@@ -313,7 +314,7 @@
     (set-marker (layout/translations fmt))
     (case fmt
       ;; handle the special case where the editorial or the recommendations are passed in the tree
-      (:editorial :recommendations :recommendation) (md-to-fop items)
+      (:editorial :recommendations :recommendation) (md-to-fop items [fmt] path-to-numbers)
       (:hörfilm :ludo) (entries-sexp items)
       (mapcat #(genre-sexp (get items %) fmt % (inc level) path-to-numbers) (order (keys items))))]))

@@ -391,36 +392,40 @@
     {:start-indent "body-start()"}
     (block body)]])

-(defmulti to-fop (fn [{:keys [tag attrs content]}] tag))
-(defmethod to-fop :p [{content :content}] (block {:space-before "17pt"} content))
-(defmethod to-fop :a [{content :content {href :href} :attrs}]
+(defmulti to-fop (fn [{:keys [tag attrs content]} _ _] tag))
+(defmethod to-fop :p [{content :content} _ _] (block {:space-before "17pt"} content))
+(defmethod to-fop :a [{content :content {href :href} :attrs} _ _]
   (if (not-empty content)
     (apply #(external-link href %) content)
     (external-link href href)))
-(defmethod to-fop :h1 [{content :content}] [:fo:block (style :h1) content])
-(defmethod to-fop :h2 [{content :content}] [:fo:block (style :h2) content])
-(defmethod to-fop :h3 [{content :content}] [:fo:block (style :h3) content])
-(defmethod to-fop :ul [{content :content}] [:fo:list-block content])
-(defmethod to-fop :li [{content :content}] (bullet-list content))
-(defmethod to-fop :em [{content :content}] (inline {:font-style "italic"} content))
-(defmethod to-fop :strong [{content :content}] (inline {:font-weight "bold"} content))
-(defmethod to-fop :br [_] [:fo:block ])
-(defmethod to-fop :default [{content :content}] (apply block content)) ; just assume :p
+(defmethod to-fop :h1 [{content :content} path path-to-numbers]
+  (heading :h1 (conj path (string/join content)) path-to-numbers))
+(defmethod to-fop :h2 [{content :content} path path-to-numbers]
+  (heading :h2 (conj path (string/join content)) path-to-numbers))
+(defmethod to-fop :h3 [{content :content} path path-to-numbers]
+  (heading :h3 (conj path (string/join content)) path-to-numbers))
+(defmethod to-fop :ul [{content :content} _ _] [:fo:list-block content])
+(defmethod to-fop :li [{content :content} _ _] (bullet-list content))
+(defmethod to-fop :em [{content :content} _ _] (inline {:font-style "italic"} content))
+(defmethod to-fop :strong [{content :content} _ _] (inline {:font-weight "bold"} content))
+(defmethod to-fop :br [_ _ _] [:fo:block ])
+(defmethod to-fop :default [{content :content} _ _] (apply block content)) ; just assume :p

 (defn- node? [node]
   (and (map? node) (or (set/subset? #{:tag :content} (set (keys node))) (= (:tag node) :br))))

-(defn- visitor [node]
+(defn- visitor [node path path-to-numbers]
   (if (node? node)
-    (to-fop node)
+    (to-fop node path path-to-numbers)
     node))

-(defn md-to-fop [markdown]
+(defn md-to-fop [markdown path path-to-numbers]
   (->>
    markdown
    endophile/mp
    endophile/to-clj
-   (walk/postwalk visitor)))
+   (walk/postwalk #(visitor % path path-to-numbers))))
+

 (defn- branch? [node]
   (when-let [ks (and (map? node) (keys node))]


Fix cljs support for channel monad.

Fix cljs support for channel monad.

--- src/cats/labs/channel.cljc
+++ src/cats/labs/channel.cljc
@@ -24,14 +24,17 @@
 ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 (ns cats.labs.channel
-  #?(:cljs (:require-macros [cljs.core.async.macros :refer [go]]))
-  (:require #?(:clj  [clojure.core.async :refer [go] :as a]
-               :cljs [cljs.core.async :as a])
-            [clojure.core.async.impl.dispatch :as dispatch]
-            [clojure.core.async.impl.protocols :as impl]
-            [cats.context :as ctx]
-            [cats.core :as m]
-            [cats.protocols :as p]))
+  #?(:cljs (:require-macros [cljs.core.async.macros :refer [go go-loop]]))
+  #?(:cljs (:require [cljs.core.async :as a]
+                     [cljs.core.async.impl.protocols :as impl]
+                     [cats.context :as ctx]
+                     [cats.core :as m]
+                     [cats.protocols :as p])
+     :clj  (:require [clojure.core.async :refer [go go-loop] :as a]
+                     [clojure.core.async.impl.protocols :as impl]
+                     [cats.context :as ctx]
+                     [cats.core :as m]
+                     [cats.protocols :as p])))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Monad definition
@@ -56,10 +59,7 @@
   (reify
     p/Functor
     (fmap [_ f mv]
-      (let [ctx ctx/*context*
-            c (a/chan 1 (map (fn [v]
-                               (binding [ctx/*context* ctx]
-                                 (f v)))))]
+      (let [c (a/chan 1 (map f))]
         (a/pipe mv c)
         c))

@@ -81,23 +81,26 @@

     p/Monad
     (mreturn [_ v]
-      (let [c (a/chan)]
+      (let [c (a/chan 1)]
         (a/put! c v)
+        (a/close! c)
         c))

     (mbind [it mv f]
       (let [ctx ctx/*context*
             c (a/chan 1)]
-        (a/go-loop []
+        (go-loop []
           (if-let [v (a/<! mv)]
             (do
               (if (channel? v)
                 (let [result (a/<! v)
-                      result (f result)]
+                      result (binding [ctx/*context* ctx]
+                               (f result))]
                   (if (channel? result)
                     (a/>! c (a/<! result))
                     (a/>! c result)))
-                (let [result (f v)]
+                (let [result (binding [ctx/*context* ctx]
+                               (f v))]
                   (if (channel? result)
                     (a/>! c (a/<! result))
                     (a/>! c result))))


add store fns to add/remove groups

add store fns to add/remove groups

--- src/chat/client/store.cljs
+++ src/chat/client/store.cljs
@@ -1,4 +1,5 @@
-(ns chat.client.store)
+(ns chat.client.store
+  (:require [cljs-utils.core :refer [flip]]))

 (def app-state (atom {:threads {}
                       :users {}
@@ -126,3 +127,9 @@

 (defn set-user-joined-groups! [groups]
   (transact! [:groups] (constantly (key-by-id groups))))
+
+(defn add-group! [group]
+  (transact! [:groups] (flip assoc (group :id) group)))
+
+(defn remove-group! [group]
+  (transact! [:groups] (flip dissoc (group :id))))


Fix release ports

Fix release ports

--- src/cider_ci/ex/trials.clj
+++ src/cider_ci/ex/trials.clj
@@ -102,7 +102,7 @@
            ports)
     (doseq [script-atom (get-scripts-atoms trial)]
       (swap! script-atom #(conj %1 {:ports %2}) ports))
-    ))
+    ports))

 (defn put-attachments [trial]
   (let [params-atom (get-params-atom trial)


Updated Burke Bugs' trace :msg

Updated Burke Bugs' trace :msg

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -95,7 +95,7 @@
    {:abilities [{:label "Trace 0 - Force the Runner to trash a program"
                  :trace (assoc trash-program :base 0 :not-distinct true
                                              :player :runner
-                                             :msg (msg "force the Runner to trash " (:title target)))}]}
+                                             :msg "force the Runner to trash a program")}]}

    "Caduceus"
    {:abilities [{:label "Trace 3 - Gain 3 [Credits]"


clean up'

clean up'

--- src/clj/hit_wl/handler.clj
+++ src/clj/hit_wl/handler.clj
@@ -51,8 +51,7 @@
             :uri (if (= env :prod) heroku-mongo-connection-uri nil)}))

 (defn get-userdata [username]
-  (println "AA " username )
-  (->> (db/get-all "flatdata")
+    (->> (db/get-all "flatdata")
        (filter #(= (:first-name %) username))
        (map #(dissoc % :_id))))


Added some interfaces to the assem classes I forgot

--- src/clj/minijava/assem.clj
+++ src/clj/minijava/assem.clj
@@ -8,18 +8,24 @@
   (format [this]))

 (deftype AssemOper [fmt, dsts, srcs, jmps]
+  clojure.lang.IPersistentMap
+  Instr
   (use [] srcs)
   (def [] dsts)
   (jumps [] jmps)
   (format [] "unimplemented"))

 (deftype AssemMove [fmt, dst, src]
+  clojure.lang.IPersistentMap
+  Instr
   (use [] (list src))
   (def [] (list dst))
   (jumps [] '())
   (format [] "unimplemented"))

 (deftype AssemLabel [fmt, lbl]
+  clojure.lang.IPersistentMap
+  Instr
   (use [] '())
   (def [] '())
   (jumps [] '())


Re-fixed nil bug in munch.

Re-fixed nil bug in munch.

--- src/clj/minijava/munch.clj
+++ src/clj/minijava/munch.clj
@@ -59,7 +59,7 @@
 (defmethod munchMap [:minijava.ir/Move :minijava.exp/expression :minijava.ir/Mem]
   [x src dst]
   (cond
-   ;; Move(Mem(Binop(Plus(Const(i),e1)),e2) -> movl $i[e1] e2
+   ;; Move(e2 Mem(Binop(Plus(Const(i),e1))) -> movl e2  $i[e1]
    (and (isit? (:adr dst) :minijava.ir/BinaryOp) (= (:op (:adr dst)) :+)
         (isit? (:exp1 (:adr dst)) :minijava.ir/Const))
      (let [offset (:val (:exp1 (:adr dst)))
@@ -67,15 +67,15 @@
            e2 (munch src) ]
        (emit (movl  e2 (MEMORY e1 offset))))
        ;; AFTER munching these two statements, emit the code.
-       ;; Move(Mem(Binop(Plus(e1, Const(i))),e2) -> movl $i[e1] e2
+       ;; Move(e2 Mem(Binop(Plus(e1, Const(i)))) -> movl e2  $i[e1]
    (and (isit? (:adr dst) :minijava.ir/BinaryOp) (= (:op (:adr dst)) :+)
         (isit? (:exp2 (:adr dst)) :minijava.ir/Const))
      (let [offset (:val (:exp2 (:adr dst)))
            e1 (munch (:exp1 (:adr dst)))
            e2 (munch src) ]
-       (emit  e2 (movl (MEMORY e1 offset))))
+       (emit  (movl  e2 (MEMORY e1 offset))))
        ;; AFTER munching these two statements, emit the code.
-       ;; Move(Mem(e1),e2) -> movl [e1] e2
+       ;; Move(Mem(e1),e2) -> movl e2 [e1]

    :else
      (let [adr (munch (:adr dst))


Added sound file loading.

Added sound file loading.

--- src/clj/osmosis/server.clj
+++ src/clj/osmosis/server.clj
@@ -6,6 +6,12 @@
             [net.cgrand.enlive-html :as en]
             [net.cgrand.reload]
             [ring.adapter.jetty :refer [run-jetty]]))
+
+(defn sound-filenames []
+  (for [f (map #(.getName %)
+               (.listFiles (io/file (io/resource "sound/processed"))))]
+    (let [base (last (re-find #"(.*)\.mp3" f))]
+      {:base base :full (str "sound/" f)})))

 (en/deftemplate page (io/resource "public/index.html") []
   [:body]
@@ -20,7 +26,14 @@
                        :href "css/bootstrap.css"}]))

     (en/append
-      (en/html [:script {:type "text/javascript" :src "js/react.js"}]))))
+      (en/html [:script {:type "text/javascript" :src "js/react.js"}]))
+
+    (en/append
+      (en/html
+        (for [f (sound-filenames)]
+          [:audio {:src (:full f)
+                   :preload "auto"
+                   :id (str "sample-" (:base f))}])))))

 (defroutes routes
   (resources "/css" {:root "public/css"})
@@ -32,6 +45,8 @@
   (resources "/fonts" {:root "vendor/bootstrap/fonts"})
   (resources "/css" {:root "vendor/bootstrap/css"})

+  (resources "/sound" {:root "sound/processed"})
+
   (GET "/*" req (page)))

 (defn run [create-http-handler]


Whitespace changes

Whitespace changes

--- src/cljc/precept/util.cljc
+++ src/cljc/precept/util.cljc
@@ -223,7 +223,7 @@
   Returns `[bool...]` indicating successful removal from each indexed location."
   ([fact] (remove-fact-from-index! fact (fact-index-paths fact)))
   ([fact paths]
-   (if (= paths :one-to-many) ; Nothing to be done
+   (if (= paths :one-to-many)
      [true]
      (mapv
        (fn [ks]
@@ -519,5 +519,3 @@
                     (filter #(= (:ns %) ns-sym)
                       (vals @state/rules)))]
     (set rule-syms)))
-
-


Fix wait-for implementation

Fix wait-for implementation

--- src/cljs/common/async.cljs
+++ src/cljs/common/async.cljs
@@ -1,5 +1,5 @@
 (ns common.async
-  (:refer-clojure :exclude [map mapcat filter remove distinct concat take-while drop-while complement keep reduce])
+  (:refer-clojure :exclude [map mapcat filter remove distinct concat take-while drop-while complement keep reduce delay])
   (:require-macros [cljs.core.async.macros :refer [go alt! go-loop]]
                    [common.async :refer [dochan go-catch <? <!expand]])
   (:require [goog.net.Jsonp]
@@ -61,6 +61,11 @@
       c ([x] x)
       (async/timeout msec) (ex-info (str "Timeout " msec "ms") {::timeout msec}))))

+(defn delay [ms]
+  (let [c (chan)]
+    (js/setTimeout #(close! c) ms)
+    c))
+
 (defn wait-for
   ([f] (wait-for f 100))
   ([f interval]
@@ -69,6 +74,6 @@
        (if (f)
          (async/close! c)
          (do
-           (<! (async/timeout interval))
+           (<! (delay interval))
            (recur))))
      c)))


Minor fix for notebook rendering.

Minor fix for notebook rendering.

--- src/cljs/website/core.cljs
+++ src/cljs/website/core.cljs
@@ -143,9 +143,12 @@
 (secretary/defroute "/notebook/:id" [id]
   (session/put! :page :notebook)
   (.getJSON js/jQuery (str (js/atob id)) (fn [data]
-    (.appendChild
-      (.getElementById js/document "notebook")
-        (.render (.parse js/nb data))
+    (js/setTimeout
+      (fn[] (.appendChild
+        (.getElementById js/document "notebook")
+          (.render (.parse js/nb data))
+        )
+      ) 150
     )
   ))
 )


Change cruiser's state-map to :move-attack-twice

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -483,7 +483,7 @@
                :armor-type :naval
                :armor 15
                :repair 1
-               :state-map :move-attack
+               :state-map :move-attack-twice
                :buildable-at #{:seaport}
                :image "tilesets/elite-command/units/cruiser-COLOR.png"
                :terrain-effects


ensure data/ directory exists when running migrations

--- src/clojars/db/migrate.clj
+++ src/clojars/db/migrate.clj
@@ -1,5 +1,6 @@
 (ns clojars.db.migrate
   (:require [clojure.java.jdbc :as sql]
+            [clojure.java.io :as io]
             [clojars.config :refer [config]])
   (:import (java.sql Timestamp)))

@@ -22,7 +23,12 @@
                      [(str (:name (meta migration)))
                       (Timestamp. (System/currentTimeMillis))]))

+(defn- ensure-db-directory-exists [db]
+  (when-not (.exists (io/file db))
+    (.mkdirs (.getParentFile (io/file db)))))
+
 (defn migrate [& migrations]
+  (ensure-db-directory-exists (:subname (config :db)))
   (sql/with-connection (config :db)
     (try (sql/create-table "migrations"
                            [:name :varchar "NOT NULL"]
@@ -38,4 +44,4 @@

 (defn -main []
   (migrate #'initial-schema
-           #'add-promoted-field))+           #'add-promoted-field))


some light refactoring

some light refactoring

--- src/co/nclk/linen/core.clj
+++ src/co/nclk/linen/core.clj
@@ -138,6 +138,28 @@
               (-> config :node-manager (invoke checkpoint :local) (assert-checkpoint config {})))))
     ))

+(defn checkpoint-env
+  [env checkpoint]
+  (let [out-arr (-> checkpoint :out :keys first keyword)
+        err-arr (-> checkpoint :err :keys first keyword)
+        exit-arr (-> checkpoint :exit :keys first keyword)
+        success-arr (-> checkpoint :success :keys first keyword)
+        out (-> checkpoint :out :value)
+        err (-> checkpoint :err :value)
+        exit (-> checkpoint :exit :value)
+        success (-> checkpoint :success :value)]
+    (reduce (fn [env [k v]]
+              (if-not (nil? k)
+                (assoc env k v) env))
+            env
+            [[out-arr (conj (get env out-arr) out)]
+             [(-> checkpoint :out :keys second keyword) out]
+             [err-arr (conj (get env err-arr) err)]
+             [(-> checkpoint :err :keys second keyword) err]
+             [exit-arr (conj (get env exit-arr) exit)]
+             [(-> checkpoint :exit :keys second keyword) exit]
+             [success-arr (conj (get env success-arr) success)]
+             [(-> checkpoint :success :keys second keyword) success]])))

 (defn run-module
   [m c]
@@ -151,25 +173,23 @@
                    (-> m :requires))
         missing (remove #(-> % second true?)
                         (map (fn [v]
-                               [v (or ;; Is it both boolean and true, signifying a default value exists?
+                               [v (or ;; Is it both boolean and true, signifying a
+                                      ;; default value exists?
                                       (and (bool? v)
                                            (true? v))
-                                      ;; Or is it a keyword and found in the current env?
+                                      ;; Or is it a keyword and found in the current
+                                      ;; env?
                                       (and (keyword? v)
                                            (not (nil? (-> env v)))))])
                              vars))]
     (if-not (empty? missing)
-      ;; If some of the `requires` interfaces are missing, don't bother running it, and
-      ;; return nil.
-      (throw (AssertionError. (format "Some required inputs are missing for module `%s`.\nMissing: %s\n\n"
-                (:name m)
-                (into [] (map first missing))
-                )))
-      #_(log :error
-        (format "Some required inputs are missing for module `%s`.\nMissing: %s\n\nEnvironment:\n%s"
-                (:name m)
-                (into [] (map first missing))
-                env))
+      ;; If some of the `requires` interfaces are missing, don't bother running it,
+      ;; and throw assertion error.
+      (throw
+        (AssertionError.
+          (format "Some required inputs are missing for module `%s`.\nMissing: %s\n\n"
+                  (:name m)
+                  (into [] (map first missing)))))
       ;; All `requires` interfaces exist, so we're a "go."
       ;; Run the checkpoints. Each checkpoint run will return its return code and
       ;; the vars that should be added to the env.
@@ -192,34 +212,12 @@
           ;; it with any more comprehensive environment before running code that
           ;; depends on the these values.
           {:returns returns
-           :env (reduce (fn [env return]
-                          (merge env
-                            (reduce (fn [env checkpoint]
-                                      (let [out-arr (-> checkpoint :out :keys first keyword)
-                                            err-arr (-> checkpoint :err :keys first keyword)
-                                            exit-arr (-> checkpoint :exit :keys first keyword)
-                                            success-arr (-> checkpoint :success :keys first keyword)
-                                            out (-> checkpoint :out :value)
-                                            err (-> checkpoint :err :value)
-                                            exit (-> checkpoint :exit :value)
-                                            success (-> checkpoint :success :value)]
-                                        (reduce (fn [env [k v]]
-                                                  (if-not (nil? k)
-                                                    (assoc env k v) env))
-                                                env
-                                                [[out-arr (conj (get env out-arr) out)]
-                                                 [(-> checkpoint :out :keys second keyword) out]
-                                                 [err-arr (conj (get env err-arr) err)]
-                                                 [(-> checkpoint :err :keys second keyword) err]
-                                                 [exit-arr (conj (get env exit-arr) exit)]
-                                                 [(-> checkpoint :exit :keys second keyword) exit]
-                                                 [success-arr (conj (get env success-arr) success)]
-                                                 [(-> checkpoint :success :keys second keyword) success]])))
-                                    env
-                                    return)))
-                        {}
-                        returns)}
-          )))))
+           :env (->> returns
+                     (reduce
+                       (fn [env return]
+                         (merge env
+                           (reduce checkpoint-env env return)))
+                       {}))})))))

 (defn extract-env
@@ -363,10 +361,12 @@
   (let [program (if (map? (:program config))
                   (:program config)
                   (try
-                    (resolve-program (:data-connector config) (evaluate (:program config) config))
+                    (resolve-program (:data-connector config)
+                                     (evaluate (:program config) config))
                     (catch Exception e
                       (die
-                        "The configuration must have a program property, which must resolve to a valid yaml document:"
+                        (str "The configuration must have a program property, "
+                             "which must resolve to a valid yaml document:")
                         (.getMessage e)))))
         config (assoc config :env (evaluate (:env config) config))
         exit (try
@@ -407,10 +407,18 @@
     ;; use the built-in FileDataConnector.
     (let [data-connector (if (:data-connector config)
                            (let [dc-ctor (do (-> config :data-connector symbol require)
-                                             (-> config :data-connector (str "/connector") symbol resolve))]
+                                             (-> config
+                                               :data-connector
+                                               (str "/connector")
+                                               symbol
+                                               resolve))]
                              (if-not dc-ctor
-                               ;; we can't proceed without any way of resolving the location of the program
-                               (die (format "Constructor for data connector `%s` not found" (:data-connector config)))
+                               ;; we can't proceed without any way of resolving the
+                               ;; location of the program
+                               (die
+                                 (format
+                                   "Constructor for data connector `%s` not found"
+                                   (:data-connector config)))
                                (dc-ctor)))
                            (FileDataConnector.))
           effective (let [effective (java.util.Date.
@@ -418,18 +426,22 @@
                                           (-> (java.util.Date.) .getTime)))]
                       (log :info (str "Seed: " (.getTime effective)))
                       effective)
-          result (run-program (assoc config ;; This timestamp is also intended to be used (via .getTime)
-                                            ;; as a seed for any pseudorandom number generation, so that
-                                            ;; randomized testing can be retested as deterministically
-                                            ;; as possible.
+          result (run-program (assoc config ;; This timestamp is also intended to be
+                                            ;; used (via .getTime) as a seed for any
+                                            ;; pseudorandom number generation, so that
+                                            ;; randomized testing can be retested as
+                                            ;; deterministically as possible.
                                             :effective effective
-                                            ;; Instantiate a node manager with an empty node map as an atom.
+                                            ;; Instantiate a node manager with an empty
+                                            ;; node map as an atom.
                                             ;; Takes a seed.
                                             :node-manager (node-manager effective)
-                                            ;; The data connector is for resolving literal
-                                            ;; representations of particular resources. In the future,
-                                            ;; database persistence should be supported, with
-                                            ;; continued support for file based configuration, too.
+                                            ;; The data connector is for resolving
+                                            ;; literal representations of particular
+                                            ;; resources. In the future, database
+                                            ;; persistence should be supported, with
+                                            ;; continued support for file based
+                                            ;; configuration, too.
                                             :data-connector data-connector
                                             :genv (or (:genv config) (atom {}))))]
       (log :info (str "Seed: " (.getTime effective)))


align big int/dec api names with clojure.core

--- src/cognitect/transit.cljs
+++ src/cognitect/transit.cljs
@@ -233,22 +233,22 @@
   [x]
   (ty/isInteger x))

-(defn big-int
+(defn bigint
   "Construct a big decimal from a string."
   [s]
   (ty/bigInteger s))

-(defn big-int?
+(defn bigint?
   "Returns true if x is a transit big decimal value, false otherwise."
   [x]
   (ty/isBigInteger x))

-(defn big-dec
+(defn bigdec
   "Construct a big decimal from a string."
   [s]
   (ty/bigDecimalValue s))

-(defn big-dec?
+(defn bigdec?
   "Returns true if x is a transit big decimal value, false otherwise."
   [x]
   (ty/isBigDecimal x))


WASD movement

WASD movement

--- src/kindness/core.cljs
+++ src/kindness/core.cljs
@@ -15,7 +15,12 @@
   {37 :left
    39 :right
    38 :up
-   40 :down})
+   40 :down
+   87 :up ;; W
+   65 :left ;; A
+   83 :down ;; S
+   68 :right ;; D
+   })
 (def move-speed 20)

 (def styles
@@ -405,9 +410,9 @@
 (defn boot-game
   []
   (let [canvas (game-surface)
-        _ (println "at boot, canvas is:" canvas)
+        ;; _ (println "at boot, canvas is:" canvas)
         surface (.getContext canvas "2d")
-        _ (println "at boot, 2d surface is:" surface)
+        ;; _ (println "at boot, 2d surface is:" surface)
         ;; TODO: listening on js/window might break LD pages!!!
         [keyboard-event-key kbd-chan] (utils/events->chan js/window
                                                           EventType.KEYDOWN


Fix bug where 'dirty-repo? check looks for non-local shas.

We want to see if our commits are up stream but this means we need the
upstream commits locally to check related ancestry.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -141,6 +141,7 @@

 (defn dirty-repo?
   [gitdir]
+  (git {:gitdir gitdir} "fetch")
   (let [g {:gitdir gitdir}
         dirty (:lines (git g "status" "--short"))
         stashes (:lines (git g "stash" "list"))


Remove unneeded 'git-tuples

Remove unneeded 'git-tuples

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -1049,24 +1049,6 @@
   (assert (<= 4 (count s)))
   (BytesSha. (.toByteArray (java.math.BigInteger. s 16))))

-;; [:commit/node <commit-sha> <ctime> <tree-sha>]
-;; [:commit/parent <commit-sha> <parent-commit-sha>]
-;; [:tree/node <tree-sha> :blob/:tree <filename> <object-sha>]
-(defn git-tuples
-  [gitdir]
-  (let [commits (git-commits gitdir "origin/master")]
-    (concat
-     (mapcat seq
-             (for [{:keys [sha ctime tree parents]} commits
-                   :let [bsha (str->sha sha)]]
-               (into [[:commit/node bsha ctime (str->sha tree)]]
-                     (for [p parents]
-                       [:commit/parent bsha (str->sha p)]))))
-     (for [tree-sha (all-git-trees gitdir)
-           :let [tree-bsha (str->sha tree-sha)]
-           [fname {:keys [sha ftype]}] (git-tree gitdir tree-sha)]
-       [:tree/node tree-bsha ftype fname (str->sha sha)]))))
-
 (pldb/db-rel r-branch name sha)
 (pldb/db-rel r-commit ^:index sha ctime tree-sha)
 (pldb/db-rel r-commit-parent ^:index sha ^:index parent-sha)