Add quick keyboard input to demo

Add quick keyboard input to demo

--- src/clj/robinson/glterminal.clj
+++ src/clj/robinson/glterminal.clj
@@ -9,7 +9,6 @@
             [clojure-watch.core :as cwc]
             [clojure.core.async :as async])
   (:import
-    (javax.imageio ImageIO)
     (java.lang.reflect Field)
     (java.awt Color
               BorderLayout
@@ -17,18 +16,17 @@
               Color
               Font
               FontMetrics
-              Graphics2D
               Graphics
               RenderingHints Toolkit)
     (java.awt.event InputEvent
                     KeyListener
                     KeyEvent)
-    (javax.swing JFrame)
     (org.lwjgl BufferUtils)
     (java.nio FloatBuffer ByteBuffer)
     (org.lwjgl.opengl Display ContextAttribs
                       PixelFormat DisplayMode
-                      GL11 GL12 GL13 GL15 GL20 GL21)
+                      GL11 GL12 GL13 GL15 GL20)
+    (org.lwjgl.input Keyboard)
     (org.lwjgl.util.vector Matrix4f Vector3f)
     (java.io File)
     (java.awt.image BufferedImage DataBufferByte)
@@ -38,6 +36,7 @@
 (def char-height 16)

 (set! *warn-on-reflection* true)
+(set! *unchecked-math* true)

 (defn convert-key-code [e on-key-fn]
   (let [numpad? (= (.getKeyLocation e) KeyEvent/KEY_LOCATION_NUMPAD)]
@@ -330,7 +329,7 @@
                                             0.0, vy  0.0
                                             vx   0.0 0.0
                                             0.0  0.0 0.0,])
-        texture-coords        (float-array [0.0 1.0
+        texture-coords        (float-array [1.0 1.0
                                             0.0 1.0
                                             1.0 0.0
                                             0.0 0.0])
@@ -368,10 +367,10 @@
    :bg-color  bg-color
    :style     style})

-(defrecord OpenGlTerminal [columns
-                           rows
-                           texture-columns
-                           texture-rows
+(defrecord OpenGlTerminal [^int columns
+                           ^int rows
+                           ^int texture-columns
+                           ^int texture-rows
                            character-map-cleared
                            character-map
                            cursor-xy
@@ -417,8 +416,14 @@
            program-id :program-id
            {:keys [u-MVMatrix u-PMatrix u-font u-glyphs u-fg u-bg font-size term-dim font-tex-dim
             font-texture-width font-texture-height glyph-tex-dim glyph-texture-width glyph-texture-height ]} :uniforms
-           {:keys [glyph-image-data fg-image-data bg-image-data vertex-pos-data vertex-texture-coords-data]} :data
-           :keys [p-matrix-buffer mv-matrix-buffer]} gl]
+           {:keys [^ByteBuffer glyph-image-data
+                   ^ByteBuffer fg-image-data
+                   ^ByteBuffer bg-image-data]} :data
+           :keys [p-matrix-buffer mv-matrix-buffer]} gl
+          glyph-image-data glyph-image-data
+          fg-image-data fg-image-data
+          bg-image-data bg-image-data]
+
       (GL20/glUseProgram program-id)
       (GL20/glUniformMatrix4 u-PMatrix false p-matrix-buffer)
       (GL20/glUniformMatrix4 u-MVMatrix false mv-matrix-buffer)
@@ -463,6 +468,9 @@
       #_#_fg-data          (.-data fg-image-data)
       #_#_bg-data          (.-data bg-image-data)
       ;; Update glyph texture in memory
+      (.clear glyph-image-data)
+      (.clear fg-image-data)
+      (.clear bg-image-data)
       (doseq [row (range rows)
               col (range columns)]
         (let [c         (get-in @character-map [row col])
@@ -479,18 +487,28 @@
               i         (* 4 (+ (* texture-columns row) col))
               [x y]     (get character->col-row [chr (contains? style :underline)])]
           ;(log/info "Drawing at col row" col row "character from atlas col row" x y c "(index=" i ")")
-          (.put glyph-image-data (+ i 0) x)
-          (.put glyph-image-data (+ i 1) y)
-          (.put glyph-image-data (+ i 2) 0)
-          (.put glyph-image-data (+ i 3) 0)
-          (.put fg-image-data    (+ i 0) fg-r)
-          (.put fg-image-data    (+ i 1) fg-g)
-          (.put fg-image-data    (+ i 2) fg-b)
-          (.put fg-image-data    (+ i 3) 0)
-          (.put bg-image-data    (+ i 0) bg-r)
-          (.put bg-image-data    (+ i 1) bg-g)
-          (.put bg-image-data    (+ i 2) bg-b)
-          (.put bg-image-data    (+ i 3) 0)))
+          (when (zero? col)
+            (.position glyph-image-data i)
+            (.position fg-image-data i)
+            (.position bg-image-data i))
+          (.put glyph-image-data (unchecked-byte x))
+          (.put glyph-image-data (unchecked-byte y))
+          (.put glyph-image-data (unchecked-byte 0))
+          (.put glyph-image-data (unchecked-byte 0))
+          (.put fg-image-data    (unchecked-byte fg-r))
+          (.put fg-image-data    (unchecked-byte fg-g))
+          (.put fg-image-data    (unchecked-byte fg-b))
+          (.put fg-image-data    (unchecked-byte 0))
+          (.put bg-image-data    (unchecked-byte bg-r))
+          (.put bg-image-data    (unchecked-byte bg-g))
+          (.put bg-image-data    (unchecked-byte bg-b))
+          (.put bg-image-data    (unchecked-byte 0))))
+      (.position glyph-image-data (.limit glyph-image-data))
+      (.position fg-image-data (.limit fg-image-data))
+      (.position bg-image-data (.limit bg-image-data))
+      (.flip glyph-image-data)
+      (.flip fg-image-data)
+      (.flip bg-image-data)
       ; Send updated glyph texture to gl
       (GL13/glActiveTexture GL13/GL_TEXTURE1)
       (GL11/glBindTexture GL11/GL_TEXTURE_2D glyph-texture)
@@ -574,10 +592,10 @@
                                (.setIgnoreRepaint true))
           pixel-format       (PixelFormat.)
           context-attributes (ContextAttribs. 2 1)
-          _                  (Display/setDisplayMode (DisplayMode. screen-width screen-height));
+          _                  (Display/setDisplayMode (DisplayMode. screen-width screen-height))
           _                  (Display/setTitle title)
           _                  (Display/create pixel-format context-attributes)
-          _                  (GL11/glViewport 0 0 screen-width screen-height);
+          _                  (GL11/glViewport 0 0 screen-width screen-height)

           #_#__                (doto (JFrame. title)
                              (.. (getContentPane) (setLayout (BorderLayout.)))
@@ -650,6 +668,13 @@
                                      (reset! normal-font
                                              (make-font filename Font/PLAIN font-size)))
                          :options {:recursive true}}])
+      ;; Poll keyboard in background thread and offer input to key-chan
+      (future (go-loop []
+                (Display/processMessages)
+                (when (Keyboard/next)
+                  (when (Keyboard/getEventKeyState)
+                    (async/>! key-chan (Keyboard/getEventCharacter))))
+                (recur)))
       ;; Create and return terminal
       (OpenGlTerminal. columns
                        rows
@@ -659,7 +684,7 @@
                        character-map
                        cursor-xy
                        {:p-matrix-buffer (ortho-matrix-buffer screen-width screen-height)
-                        :mv-matrix-buffer (position-matrix-buffer [0 0 -1.0 0.0])
+                        :mv-matrix-buffer (position-matrix-buffer [(- (/ screen-width 2)) (- (/ screen-height 2)) -1.0 0.0])
                         :buffers {:vao-id vao-id
                                   :vertices-vbo-id vertices-vbo-id
                                   :vertices-count vertices-count
@@ -724,7 +749,7 @@
         (rat/refresh! terminal)
         (recur terminal))
       (when (not (Display/isCloseRequested))
-        (let [key-in \n #_(async/<!! (rat/get-key-chan terminal))]
+        (let [key-in (async/<!! (rat/get-key-chan terminal))]
         ;(let [key-in (rat/wait-for-key terminal)]
           (log/info "got key" key-in)
           (rat/clear! terminal)
@@ -735,7 +760,6 @@
           (put-string terminal 60 19 "Hello world 0 19")
           (put-string terminal 5 10 (str key-in))
           (rat/refresh! terminal)
-          (Display/processMessages)
           (recur terminal)))))
   (Display/destroy)
   (System/exit 0))


return map is badge is not url

return map is badge is not url

--- src/clj/salava/badge/verify.clj
+++ src/clj/salava/badge/verify.clj
@@ -79,7 +79,7 @@
                             :asr asr
                             :message (:message asr-response))
           200 (let [asr-data (:body asr-response)
-                    badge-data (fetch-json-data (:badge asr-data))
+                    badge-data (if (url? (:badge asr-data)) (fetch-json-data (:badge asr-data)) (:badge asr-data))
                     badge-image (if (map? (:image badge-data)) (fetch-image (get-in badge-data [:image :id])) (fetch-image (:image badge-data)))
                     badge-criteria (if (and (map? (:criteria badge-data))(contains? (:criteria badge-data) :id))
                                      (fetch-url (get-in badge-data [:criteria :id]))


update Djinn and Progenitor tests to work with card targeting

--- src/clj/test/cards-programs.clj
+++ src/clj/test/cards-programs.clj
@@ -12,7 +12,7 @@
           agenda (get-in @state [:corp :servers :remote1 :content 0])]
       (is agenda "Agenda was installed")
       (card-ability state :runner djinn 1)
-      (prompt-card :runner (find-card "Chakana" (:hand (get-runner))))
+      (prompt-select :runner (find-card "Chakana" (:hand (get-runner))))
       (let [chak (first (:hosted (refresh djinn)))]
         (is (= "Chakana" (:title chak)) "Djinn has a hosted Chakana")
         (core/add-prop state :runner (first (:hosted (refresh djinn))) :counter 3) ; manually add 3 counters
@@ -30,7 +30,7 @@
     (is (= 3 (:memory (get-runner))))
     (let [djinn (get-in @state [:runner :rig :program 0])]
       (card-ability state :runner djinn 1)
-      (prompt-card :runner (find-card "Chakana" (:hand (get-runner))))
+      (prompt-select :runner (find-card "Chakana" (:hand (get-runner))))
       (is (= 3 (:memory (get-runner))) "No memory used to host on Djinn")
       (is (= "Chakana" (:title (first (:hosted (refresh djinn))))) "Djinn has a hosted Chakana")
       (is (= 1 (:credit (get-runner))) "Full cost to host on Djinn"))))
@@ -76,7 +76,7 @@
     (let [prog (get-in @state [:runner :rig :program 0])
           vbg (get-in @state [:runner :rig :resource 0])]
       (card-ability state :runner prog 0)
-      (prompt-card :runner (find-card "Hivemind" (:hand (get-runner))))
+      (prompt-select :runner (find-card "Hivemind" (:hand (get-runner))))
       (is (= 4 (:memory (get-runner))) "No memory used to host on Progenitor")
       (let [hive (first (:hosted (refresh prog)))]
         (is (= "Hivemind" (:title hive)) "Hivemind is hosted on Progenitor")


More progress on tuple macro

More progress on tuple macro

--- src/clj/todomvc/tuple_rule.cljc
+++ src/clj/todomvc/tuple_rule.cljc
@@ -50,27 +50,34 @@
 ;       (not (empty? env)) (assoc :env matching-env)))))
 (defn is-binding? [x]
   ;(println "Is a binding?" x)
+  ;TODO. Long cannot be cast to Named
   (= (first (name x)) \?))

 (defn rewrite-lhs [forms]
   (println "Forms" forms)
-  (map (fn main-one [form]
+  (mapv (fn main-one [form]
          ;(println "Form" form)
          ;(println "Type" (type form))
-         ;(println "is op" (dsl/ops (first form)))
+         (println "is op" (dsl/ops (first form)))
          (if (dsl/ops (first form))
            form
-           (let [bindings (filter
-                            (juxt (comp identity second)
-                                  (comp is-binding? second))
-                            {:e (first form)
-                             :a (second form)
-                             :v (last form)})
-                 attribute (or (keyword? (:a bindings)) :all)]
+           (let [bindings (into {}
+                            (filter
+                              (fn [[k v]]
+                                (and (not= \_ v)
+                                     (identity v)
+                                     (is-binding? v)))
+                              ;(juxt (comp identity second)
+                              ;      (partial (not= \_)) second
+                              ;      (comp is-binding? second)))
+                              {:e (first form)
+                               :a (second form)
+                               :v (last form)}))
+                 attribute (if (keyword? (second form)) (second form) :all)]
              (prn "Bindigs are" bindings)
              ;(println "attribute is" attribute)
             (vector
-              attribute
+              attribute (vector ['e 'a 'v])
               (map (fn last-one [[k v]]
                        (println "k v bindings" k v)
                        (list '= v (symbol (name k)))) bindings)))))
@@ -99,14 +106,14 @@
              properties (if (map? (first body)) (first body) nil)
              definition (if properties (rest body) body)
              {:keys [lhs rhs]} (dsl/split-lhs-rhs definition)
-             lhs-new    (rewrite-lhs lhs)]
-         (println "LHS" lhs)
+             lhs-new    (rewrite-lhs (first lhs))]
+         (println "LHS" lhs-new)
          (println "RHS" rhs)
          (when-not rhs
            (throw (ex-info (str "Invalid rule " name ". No RHS (missing =>?).")
                     {})))
          `(def ~(vary-meta name assoc :rule true :doc doc)
-            (cond-> ~(dsl/parse-rule* lhs rhs properties {} (meta &form))
+            (cond-> ~(dsl/parse-rule* lhs-new rhs properties {} (meta &form))
               ~name (assoc :name ~(str (clojure.core/name (ns-name *ns*)) "/" (clojure.core/name name)))
               ~doc (assoc :doc ~doc)))))))

@@ -121,7 +128,7 @@
 (macroexpand
   '(def-tuple-rule my-tuple-rule
      "Docstring!!"
-     [[?e :todo/title _] (> ?e 1)]
+     [[?e :todo/title _]]
      [:exists [:todo/done]]
      =>
      (println "Hello!")))


Remove unused handler function

Remove unused handler function

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -42,9 +42,6 @@
  app-state
  {:target (. js/document (getElementById "main-area"))})

-(defn handler [response]
-  (.log js/console (str response)))
-
 (defn error-handler [{:keys [status status-text]}]
   (.log js/console (str "something bad happened: " status " " status-text)))


formatting

formatting

--- src/cljs/russyll/text_test.cljs
+++ src/cljs/russyll/text_test.cljs
@@ -1,12 +1,10 @@
 (ns text-test
-
-
-         (:require-macros [cemerick.cljs.test
-                           :refer (is deftest with-test run-tests testing test-var)])
-         (:require [cemerick.cljs.test :as t])
+  (:require-macros [cemerick.cljs.test
+                    :refer (is deftest with-test run-tests testing test-var)])
+  (:require [cemerick.cljs.test :as t])
   (:use [text :only [tokenize set-of-vals text-by-model]]
         [orphoep :only [++ --]]
-    ))
+        ))

 (def bef "`Игорь.б`ублики`> <!(декабр`я,) !+_)всегд`а!@#$%^&*()_[при`ятно]; пол`учит н`овый автомоб`иль хоть и нанед`елю ун`ового.")
 (def aft "*Игорь,.,б*ублики*,>, ,<,!,(,декабр*я,,,), ,!,+,_,),всегд*а,!,@,#,$,%,^,&,*,(,),_,[,при*ятно,],;, ,пол*учит, ,н*овый, ,автомоб*иль, ,хоть, ,и, ,нанед*елю, ,ун*ового,.")
@@ -14,12 +12,12 @@
 (def aft-set #{"*Игорь" "б*ублики*" "хоть" "декабр*я" "всегд*а" "при*ятно" "пол*учит" "н*овый" "автомоб*иль" "нанед*елю" "ун*ового"})

 (deftest find-tokens
-(testing "Regex find all tokens"
-  (let [res (++ "," (tokenize bef "`"))]
-    (do (println res)
-        (is (= res aft))
-    (dorun (map #(is (= %1 %2)) res aft))
-    ))))
+  (testing "Regex find all tokens"
+    (let [res (++ "," (tokenize bef "`"))]
+      (do (println res)
+          (is (= res aft))
+          (dorun (map #(is (= %1 %2)) res aft))
+          ))))

 (deftest set-of-text
   (testing "Test if fn builds properly a set of words with more than two vowels"
@@ -29,14 +27,14 @@
   (testing "Test if text is syllabized according to a model and put together properly"
     (let [t (tokenize bef "`")
           s (set-of-vals t)]
-    (dorun (map #(is (= %1 %2)) aft-sm3 (++ (text-by-model t s 2)))))))
+      (dorun (map #(is (= %1 %2)) aft-sm3 (++ (text-by-model t s 2)))))))

-       (enable-console-print!)
+(enable-console-print!)

 (defn every-true [v f]
   (every? true? (map
-                  (fn [[start end]]
-                    (is (= (f start) end))) v)))
+                 (fn [[start end]]
+                   (is (= (f start) end))) v)))

 ;;;;;;;;;;;; This file autogenerated from test/cljx/text_test.cljx


Fix wrong verify call on salted hmac functions.

--- src/clojure/buddy/core/hmac.clj
+++ src/clojure/buddy/core/hmac.clj
@@ -93,19 +93,19 @@
   (make-hmac [^java.io.File data ^String key ^String algorithm]
     (make-hmac-for-stream (io/input-stream data) key algorithm))
   (verify-hmac [^java.io.File data ^bytes signature ^String key ^String algorithm]
-    (verify-hmac-for-stream data signature key algorithm))
+    (verify-hmac-for-stream (io/input-stream data) signature key algorithm))

   java.net.URL
   (make-hmac [^java.net.URL data ^String key ^String algorithm]
     (make-hmac-for-stream (io/input-stream data) key algorithm))
   (verify-hmac [^java.net.URL data ^bytes signature ^String key ^String algorithm]
-    (verify-hmac-for-stream data signature key algorithm))
+    (verify-hmac-for-stream (io/input-stream data) signature key algorithm))

   java.net.URI
   (make-hmac [^java.net.URI data ^String key ^String algorithm]
     (make-hmac-for-stream (io/input-stream data) key algorithm))
   (verify-hmac [^java.net.URI data ^bytes signature ^String key ^String algorithm]
-    (verify-hmac-for-stream data signature key algorithm)))
+    (verify-hmac-for-stream (io/input-stream data) signature key algorithm)))

 (defn- make-salted-hmac
   "Generic function that implement salted variant
@@ -146,7 +146,7 @@
 interface for salted variant of keyed-hash message
 authentication code verification algorithm."
   [data ^bytes signature ^String key ^String salt ^String algorithm]
-  (verify-salted-hmac data signature signature key algorithm))
+  (verify-salted-hmac data signature key salt algorithm))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Most used aliases


clean up function classes generation

clean up function classes generation

--- src/clojure/flambo/function.clj
+++ src/clojure/flambo/function.clj
@@ -23,14 +23,6 @@
   [f]
   [[] f])

-(defn -call [this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
 ;; ## Functions
 (defn mk-sym
   [fmt sym-name]
@@ -41,8 +33,6 @@
   (let [new-class-sym (mk-sym "flambo.function.%s" clazz)
         prefix-sym (mk-sym "%s-" clazz)]
     `(do
-       (def ~(mk-sym "%s-init" clazz) -init)
-       (def ~(mk-sym "%s-call" clazz) -call)
        (gen-class
         :name ~new-class-sym
         :extends flambo.function.AbstractFlamboFunction
@@ -51,6 +41,15 @@
         :init ~'init
         :state ~'state
         :constructors {[Object] []})
+       (def ~(mk-sym "%s-init" clazz) -init)
+       (defn ~(mk-sym "%s-call" clazz)
+         [~(vary-meta 'this assoc :tag new-class-sym) & ~'xs]
+         (let [fn-or-serfn# (.state ~'this)
+               f# (if (instance? array-of-bytes-type fn-or-serfn#)
+                    (binding [sfn/*deserialize* kryo/deserialize]
+                      (deserialize-fn fn-or-serfn#))
+                    fn-or-serfn#)]
+           (apply f# ~'xs)))
        (defn ~wrapper-name [f#]
          (new ~new-class-sym
               (if (serfn? f#)
@@ -69,93 +68,3 @@
 (gen-function DoubleFunction double-function)
 (gen-function DoubleFlatMapFunction double-flat-map-function)

-;; This sucks, but I need to do it to type hint the call to .state
-;; and I don't think I can do that from the generic -call I used above.
-
-(defn Function-call [^flambo.function.Function this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn Function2-call [^flambo.function.Function2 this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn Function3-call [^flambo.function.Function2 this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn VoidFunction-call [^flambo.function.VoidFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn VoidFunction2-call [^flambo.function.VoidFunction2 this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn FlatMapFunction-call [^flambo.function.FlatMapFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn FlatMapFunction2-call [^flambo.function.FlatMapFunction2 this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn PairFlatMapFunction-call [^flambo.function.PairFlatMapFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn PairFunction-call [^flambo.function.PairFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn DoubleFunction-call [^flambo.function.DoubleFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))
-
-(defn DoubleFlatMapFunction-call [^flambo.function.DoubleFlatMapFunction this & xs]
-  (let [fn-or-serfn (.state this)
-        f (if (instance? array-of-bytes-type fn-or-serfn)
-            (binding [sfn/*deserialize* kryo/deserialize]
-              (deserialize-fn fn-or-serfn))
-            fn-or-serfn)]
-    (apply f xs)))


Make start and stop-systems a public API

--- systems/core/src/containium/systems.clj
+++ systems/core/src/containium/systems.clj
@@ -23,7 +23,7 @@
   (stop [this]))

-(defn- start-systems
+(defn start-systems
   [system-components]
   (loop [to-start system-components
          started nil]
@@ -40,10 +40,10 @@
           (do (println "Exception while starting system component" name "-" result)
               (.printStackTrace ^Throwable result)
               [started result])))
-      [started nil])))
+      [(into {} started) nil])))

-(defn- stop-systems
+(defn stop-systems
   [started-components]
   (doseq [[name system] started-components]
     (when (satisfies? Stoppable system)


improve entity tests

improve entity tests

--- test/clj_money/models/entities_test.clj
+++ test/clj_money/models/entities_test.clj
@@ -41,85 +41,93 @@
           (is (number? (:id other-entity))))))))

 (deftest attempt-to-create-an-invalid-entity
-  (testing "Name is required"
-    (assert-validation-error
-      :name
-      "Name is required"
-      (entities/create storage-spec (dissoc attributes :name))))
-  (testing "Name must be unique"
-    (entities/create storage-spec attributes)
-    (assert-validation-error
-      :name
-      "Name is already in use"
-      (entities/create storage-spec attributes))))
+  (let [context (serialization/realize storage-spec entity-context)
+        user (-> context :users first)]
+    (testing "Name is required"
+      (assert-validation-error
+        :name
+        "Name is required"
+        (entities/create storage-spec (dissoc (attributes context) :name))))
+    (testing "Name must be unique"
+      (entities/create storage-spec (attributes context))
+      (assert-validation-error
+        :name
+        "Name is already in use"
+        (entities/create storage-spec (attributes context))))))

-;(deftest select-entities-for-a-user
-;  (let [other-entity (entities/create storage-spec {:name "Other entity"
-;                                                    :user-id (:id other-user)})
-;        _ (dorun (map #(entities/create storage-spec {:name %
-;                                                      :user-id (:id user)})
-;                      ["Personal"
-;                       "Business"]))
-;        actual (entities/select storage-spec (:id user))
-;        expected [{:name "Business"
-;                   :user-id (:id user)}
-;                  {:name "Personal"
-;                   :user-id (:id user)}]]
-;    (is (= expected
-;           (map #(select-keys % [:name :user-id]) actual)) "The returned list should contain the correct items")
-;    (is (not-any? #(= "Other entity" (:name %)) actual) "The returned list should not contain other users entities")))
-;
-;(deftest find-an-entity-by-id
-;  (let [entity (entities/create storage-spec {:name "Personal"
-;                                              :user-id (:id user)})
-;        retrieved (entities/find-by-id storage-spec (:id entity))]
-;    (is (= entity retrieved))))
-;
-;(deftest update-an-entity
-;  (let [entity (entities/create storage-spec {:name "Entity X"
-;                                              :user-id (:id user)})
-;        updated (-> entity
-;                    (assoc :name "Entity Y")
-;                    (assoc-in [:settings :monitored-account-ids] [1 2]))
-;        result (entities/update storage-spec updated)
-;        retrieved (entities/find-by-id storage-spec (:id entity))
-;        expected {:id (:id entity)
-;                  :name "Entity Y"
-;                  :user-id (:id user)
-;                  :settings {:monitored-account-ids [1 2]}}
-;        actual (dissoc retrieved :updated-at :created-at)]
-;
-;    (if (validation/has-error? result)
-;      (pprint {:result result}))
-;
-;    (is (= "Entity Y" (:name result)) "The result contains the correct values")
-;
-;    (if-not (= expected actual)
-;      (pprint {:expected expected
-;               :actual actual
-;               :diff (diff expected actual)}))
-;
-;    (is (= expected actual) "The retreived value has the correct values")))
-;
-;(deftest delete-an-entity
-;  (let [entity (entities/create storage-spec {:name "Entity X"
-;                                              :user-id (:id user)})
-;        _ (entities/delete storage-spec (:id entity))
-;        retrieved (entities/find-by-id storage-spec (:id entity))]
-;    (is (nil? retrieved) "The entity is not returned after delete")))
-;
-;(deftest inventory-method-can-be-lifo
-;  (let [entity (entities/create storage-spec
-;                                {:name "Personal"
-;                                 :user-id (:id user)
-;                                 :settings {:inventory-method :lifo}})]
-;    (is (empty? (validation/error-messages entity)) "The entity is valid")))
-;
-;(deftest inventory-method-cannot-be-something-other-than-fifo-or-lifo
-;  (let [entity (entities/create storage-spec
-;                                {:name "Personal"
-;                                 :user-id (:id user)
-;                                 :settings {:inventory-method :not-valid}})]
-;    (is (= {:inventory-method ["Inventory method must be one of: fifo, lifo"]}
-;           (validation/error-messages entity :settings))
-;        "There is an error message for the attributes")))
+(deftest select-entities-for-a-user
+  (let [context (serialization/realize storage-spec entity-context)
+        [user other-user] (:users context)
+        other-entity (entities/create storage-spec {:name "Other entity"
+                                                    :user-id (:id other-user)})
+        _ (mapv #(entities/create storage-spec {:name %
+                                                :user-id (:id user)})
+                ["Personal"
+                 "Business"])
+        actual (entities/select storage-spec (:id user))
+        expected [{:name "Business"
+                   :user-id (:id user)}
+                  {:name "Personal"
+                   :user-id (:id user)}]]
+    (is (= expected
+           (map #(select-keys % [:name :user-id]) actual)) "The returned list should contain the correct items")
+    (is (not-any? #(= "Other entity" (:name %)) actual) "The returned list should not contain other users entities")))
+
+(deftest find-an-entity-by-id
+  (let [context (serialization/realize storage-spec entity-context)
+        entity (entities/create storage-spec (attributes context))
+        retrieved (entities/find-by-id storage-spec (:id entity))]
+    (is (= entity retrieved))))
+
+(deftest update-an-entity
+  (let [context (serialization/realize storage-spec entity-context)
+        user (-> context :users first)
+        entity (entities/create storage-spec {:name "Entity X"
+                                              :user-id (:id user)})
+        updated (-> entity
+                    (assoc :name "Entity Y")
+                    (assoc-in [:settings :monitored-account-ids] [1 2]))
+        result (entities/update storage-spec updated)
+        retrieved (entities/find-by-id storage-spec (:id entity))
+        expected {:id (:id entity)
+                  :name "Entity Y"
+                  :user-id (:id user)
+                  :settings {:monitored-account-ids [1 2]}}
+        actual (dissoc retrieved :updated-at :created-at)]
+
+    (if (validation/has-error? result)
+      (pprint {:result result}))
+
+    (is (= "Entity Y" (:name result)) "The result contains the correct values")
+
+    (if-not (= expected actual)
+      (pprint {:expected expected
+               :actual actual
+               :diff (diff expected actual)}))
+
+    (is (= expected actual) "The retreived value has the correct values")))
+
+(deftest delete-an-entity
+  (let [context (serialization/realize storage-spec entity-context)
+        entity (entities/create storage-spec (attributes context))
+        _ (entities/delete storage-spec (:id entity))
+        retrieved (entities/find-by-id storage-spec (:id entity))]
+    (is (nil? retrieved) "The entity is not returned after delete")))
+
+(deftest inventory-method-can-be-lifo
+  (let [context (serialization/realize storage-spec entity-context)
+        entity (entities/create storage-spec
+                                (-> context
+                                    attributes
+                                    (assoc :settings {:inventory-method :lifo})))]
+    (is (empty? (validation/error-messages entity)) "The entity is valid")))
+
+(deftest inventory-method-cannot-be-something-other-than-fifo-or-lifo
+  (let [context (serialization/realize storage-spec entity-context)
+        entity (entities/create storage-spec
+                                (-> context
+                                    attributes
+                                    (assoc :settings {:inventory-method :not-valid})))]
+    (is (= {:inventory-method ["Inventory method must be one of: fifo, lifo"]}
+           (validation/error-messages entity :settings))
+        "There is an error message for the attributes")))


fix failed test cases

fix failed test cases

--- test/graphql_clj/introspection_test.clj
+++ test/graphql_clj/introspection_test.clj
@@ -33,19 +33,11 @@
             {"__schema"
              {"types"
               (list {"name" 'QueryRoot, "kind" :OBJECT}
-                    {"name" '__EnumValue, "kind" :OBJECT}
                     {"name" 'String, "kind" :SCALAR}
                     {"name" 'Boolean, "kind" :SCALAR}
-                    {"name" '__Field, "kind" :OBJECT}
-                    {"name" '__Directive, "kind" :OBJECT}
-                    {"name" '__Type, "kind" :OBJECT}
-                    {"name" '__TypeKind, "kind" :ENUM}
                     {"name" 'User, "kind" :OBJECT}
                     {"name" 'Float, "kind" :SCALAR}
-                    {"name" '__DirectiveLocation, "kind" :ENUM}
-                    {"name" 'Int, "kind" :SCALAR}
-                    {"name" '__InputValue, "kind" :OBJECT}
-                    {"name" '__Schema, "kind" :OBJECT})}}}))))
+                    {"name" 'Int, "kind" :SCALAR})}}}))))

 ;; (deftest schema-introspection-without-user-schema
 ;;   (let [intro-schema (-> intro/introspection-schema sv/validate-schema)
@@ -91,10 +83,7 @@
    {"__type"
     {"name" "QueryRoot",
      "fields"
-     [{"name" '__typename}
-      {"name" 'name}
-      {"name" '__schema}
-      {"name" '__type}]}}})
+     [{"name" 'name}]}}})

 ;; ;; FIXME: name has no field of args, should return error
 ;; (deftest-valid-introspection query-type-fields-args-invalid
@@ -122,27 +111,13 @@
  {"__type"
   {"name" "QueryRoot",
    "fields"
-   [{"name" '__typename,
-     "args" [],
-     "type"
-     {"name" nil,
-      "kind" :NON_NULL,
-      "ofType" {"name" 'String, "kind" :SCALAR}}}
-    {"name" 'name,
+   [{"name" 'name,
      "args" [{"name" 'id, "defaultValue" nil}],
      "type" {"name" 'String, "kind" :SCALAR, "ofType" nil}}
     {"name" 'fieldArgWithDefault,
      "args" [{"name" 'abc, "defaultValue" "Default abc"}],
      "type" {"name" 'String, "kind" :SCALAR, "ofType" nil}}
-    {"name" '__schema,
-     "args" [],
-     "type"
-     {"name" nil,
-      "kind" :NON_NULL,
-      "ofType" {"name" '__Schema, "kind" :OBJECT}}}
-    {"name" '__type,
-     "args" [{"name" 'name, "defaultValue" nil}],
-     "type" {"name" '__Type, "kind" :OBJECT, "ofType" nil}}]}}})
+    ]}}})

 (deftest-valid-introspection query-type-fields-args-list-type
   "# QueryRoot sample description
@@ -156,13 +131,7 @@
    {"__type"
     {"name" "QueryRoot",
      "fields"
-     [{"name" '__typename,
-       "type"
-       {"name" nil,
-        "kind" :NON_NULL,
-        "ofType" {"name" 'String, "kind" :SCALAR}},
-       "args" []}
-      {"name" 'name,
+     [{"name" 'name,
        "type" {"name" 'String, "kind" :SCALAR, "ofType" nil},
        "args"
        [{"name" 'id,
@@ -175,20 +144,7 @@
          {"name" nil,
           "kind" :LIST,
           "ofType" {"name" 'String, "kind" :SCALAR}}}]}
-      {"name" '__schema,
-       "type"
-       {"name" nil,
-        "kind" :NON_NULL,
-        "ofType" {"name" '__Schema, "kind" :OBJECT}},
-       "args" []}
-      {"name" '__type,
-       "type" {"name" '__Type, "kind" :OBJECT, "ofType" nil},
-       "args"
-       [{"name" 'name,
-         "type"
-         {"name" nil,
-          "kind" :NON_NULL,
-          "ofType" {"name" 'String, "kind" :SCALAR}}}]}]}}})
+      ]}}})

 (deftest-valid-introspection query-type-enum
   "# Enum description


Remove superfluous function

Remove superfluous function

--- clstreams/src/clstreams/examples/count_words/pipelines.clj
+++ clstreams/src/clstreams/examples/count_words/pipelines.clj
@@ -19,16 +19,6 @@
     (.put "buffer.memory" (int 33554432))
     (.put "key.serializer" "org.apache.kafka.common.serialization.StringSerializer")
     (.put "value.serializer" "org.apache.kafka.common.serialization.StringSerializer")))
-
-(defn produce-numbered-messages
-  [& args]
-  (let [topic "my-topic"
-        producer (KafkaProducer. client-props)]
-    (doseq
-        [n (range 100)]
-      (.send producer
-             (ProducerRecord. topic (format "msg%04d" n) (format "This is message %d" n))))
-    (.close producer)))

 (defn produce-words
   [& lines]


Add project list accordions.

Add project list accordions.

--- web-server/src/cljs/hatnik/web/client/project-list.cljs
+++ web-server/src/cljs/hatnik/web/client/project-list.cljs
@@ -5,27 +5,32 @@
             [hatnik.web.client.components :as widget]))

 (def app-state
-  (atom {:num 0
-         :projects []}))
-
-
-(defn click-handler []
-  (swap! app-state
-         assoc :num
-         (+ 1 (:num @app-state))))
+  (atom {:projects []}))

 (defn project-list-widget [data owner]
   (reify
     om/IRender
     (render [this]
-      (widget/accordion-panel
-       :header "FOO project"
-       :body (dom/p nil "Foo project is good.")
-       :body-id "iFooProject"))))
+      (apply dom/div nil
+       (map
+        (fn [prj]
+          (widget/accordion-panel
+           :header (get prj "name")
+           :body (dom/p nil "This project is good.")
+           :body-id (str "__" (get prj "name"))))
+        (:projects data))))))

 (om/root project-list-widget app-state
          {:target (. js/document (getElementById "iProjectList"))})

+(defn update-projects-list [reply]
+  (let [json (.getResponseJson (.-target reply))
+        data (js->clj json)]
+    (when (= "ok" (get data "result"))
+      (swap! app-state
+             assoc :projects
+             (get data "projects")))))

+(.send goog.net.XhrIo "/api/projects" update-projects-list)


CMR-3873: Fixed typo

CMR-3873: Fixed typo

--- bootstrap-app/src/cmr/bootstrap/services/bootstrap_service.clj
+++ bootstrap-app/src/cmr/bootstrap/services/bootstrap_service.clj
@@ -115,10 +115,10 @@
     (bulk/delete-concepts-by-id (:system context) provider-id concept-type concept-ids)
     (let [channel (get-in context [:system :concept-id-channel])]
       (info "Adding bulk delete reqeust to concept-id channel.")
-      (go (>! channel {:provider-id provider-id}
-                      :concept-type concept-type
-                      :request :delete
-                      :concept-ids concept-ids)))))
+      (go (>! channel {:provider-id provider-id
+                       :concept-type concept-type
+                       :request :delete
+                       :concept-ids concept-ids})))))))))

 (defn bootstrap-virtual-products
   "Initializes virtual products."


Don't allow dep resolution to be memoized when we're in a bootstrap context [IMMUTANT-328]

--- modules/bootstrap/src/main/clojure/immutant/runtime/bootstrap.clj
+++ modules/bootstrap/src/main/clojure/immutant/runtime/bootstrap.clj
@@ -54,10 +54,21 @@
         cl))))

 (defn ^:private add-classpath-to-immediate-cl
+  ;; Pomegranate defaults to adding dependencies to the highest
+  ;; dynamic CL it can find, which will be above the cl we want it to
+  ;; use. This hook forces it to add to the tccl
   ([f artifact cl]
      (f artifact cl))
   ([f artifact]
      (f artifact (tccl))))
+
+(defn ^:private resolve-dependencies-without-memoization
+  ;; leiningen.core.classpath/resolve-dependencies is memoized, but we
+  ;; need to be able to invoke multiple times. This hook breaks the
+  ;; memoization.
+  [f key project & rest]
+  (apply f key project
+         (conj rest :timestamp (System/nanoTime))))

 (defmacro ^:private in-dedicated-classloader [project-or-app-root & body]
   `(let [orig-cl# (tccl)]
@@ -66,6 +77,8 @@
        (hooke/with-scope
          (hooke/add-hook #'cemerick.pomegranate/add-classpath
                          #'add-classpath-to-immediate-cl)
+         (hooke/add-hook #'leiningen.core.classpath/resolve-dependencies
+                         #'resolve-dependencies-without-memoization)
          ~@body)
        (finally
          (tccl orig-cl#)))))


Memoize the local connection factory instead of storing in a top-level var [IMMUTANT-305]

This prevents AOT code from always being considered outside of the
container.

--- modules/messaging/src/main/clojure/immutant/messaging/core.clj
+++ modules/messaging/src/main/clojure/immutant/messaging/core.clj
@@ -44,20 +44,24 @@
 (defn ^{:private true} connection-key [opts]
   (map #(% opts) [:host :port :username :password]))

-(let [local-connection-factory
-      (if-let [reference-factory (registry/get factory-name)]
-        (let [reference (.getReference reference-factory)]
-          (try
-            (.getInstance reference)
-            (finally (at-exit #(.release reference)))))
-        (do
-          (log/warn "Unable to obtain JMS Connection Factory - assuming we are outside the container")
-          (hornetq/connection-factory)))]
-  (defn connection-factory
-    [opts]
-    (if (remote-connection? opts)
-      (hornetq/connection-factory opts)
-      local-connection-factory)))
+
+(def ^:private local-connection-factory
+  (memoize
+   (fn []
+     (if-let [reference-factory (registry/get factory-name)]
+       (let [reference (.getReference reference-factory)]
+         (try
+           (.getInstance reference)
+           (finally (at-exit #(.release reference)))))
+       (do
+         (log/warn "Unable to obtain JMS Connection Factory - assuming we are outside the container")
+         (hornetq/connection-factory))))))
+
+(defn connection-factory
+                   [opts]
+                   (if (remote-connection? opts)
+                     (hornetq/connection-factory opts)
+                     (local-connection-factory)))

 (defn destination-name-error [name]
   (IllegalArgumentException.


More tests of macroexpansion.

More tests of macroexpansion.


Better formatting.

Better formatting.

--- src/asid/trust_pool.clj
+++ src/asid/trust_pool.clj
@@ -20,4 +20,7 @@

 (facts "about adding to a trust pool"
   (fact "should add with complete challenge"
-    (-> (add-to-pool (TrustPool. [:name] []) (new-wallet) {:identity "id" :url "url"} ["blah"]) :trustees count) => 1))
+    (-> (add-to-pool (TrustPool. [:name] [])
+                     (new-wallet)
+                     {:identity "id" :url "url"}
+                     ["blah"]) :trustees count) => 1))


fix bug where winning type always returned supplied type

--- sidecar/src/figwheel_sidecar/config_check/type_check.clj
+++ sidecar/src/figwheel_sidecar/config_check/type_check.clj
@@ -492,7 +492,10 @@
 (defn which-type-wins? [parent-type types]
   (let [type-map (into {} (filter (comp pos? second)
                                   (frequencies-to-pct (cons parent-type types))))]
-    (if ((set (keys type-map)) parent-type)
+    ;; TODO this states all we need is one representation of the type
+    ;; this is probably better done outside the function
+    ;; or we have a helper function
+    (if ((set types) parent-type)
       parent-type
       (first (max-val type-map)))))


adding click handlers to pirates and cards

--- cartagena-web/src/cartagena_web/main.cljs
+++ cartagena-web/src/cartagena_web/main.cljs
@@ -158,13 +158,34 @@

 (defn static-board []
   [;; board
-   [:rect {:x 0 :y 0 :width (to-scale 500) :height (to-scale 300) :stroke "black" :stroke-width "0.5" :fill "burlywood"}]
+   [:rect
+    {:x 0
+     :y 0
+     :width (to-scale 500)
+     :height (to-scale 300)
+     :stroke "black"
+     :stroke-width "0.5"
+     :fill "burlywood"}]
    ;; jail
-   [:rect {:x 0 :y 0 :width (to-scale 50) :height (to-scale 90) :stroke "black" :fill "darkgray"}]
-   [:g {:dangerouslySetInnerHTML {:__html (str "<image xlink:href=\"img/jail.png\" x=0 y=0 width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}]
+   [:rect
+    {:x 0
+     :y 0
+     :width (to-scale 50)
+     :height (to-scale 90)
+     :stroke "black"
+     :fill "darkgray"}]
+   [:g
+    {:dangerouslySetInnerHTML {:__html (str "<image xlink:href=\"img/jail.png\" x=0 y=0 width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}]
    ;; ship
-   [:rect {:x (to-scale 400) :y (to-scale 240) :width (to-scale 90) :height (to-scale 50) :stroke "black" :fill "sienna"}]
-   [:g {:dangerouslySetInnerHTML {:__html (str "<image xlink:href=\"img/ship.png\" x=\"" (to-scale 400) "\" y=\"" (to-scale 240) "\" width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}]
+   [:rect
+    {:x (to-scale 400)
+     :y (to-scale 240)
+     :width (to-scale 90)
+     :height (to-scale 50)
+     :stroke "black"
+     :fill "sienna"}]
+   [:g
+    {:dangerouslySetInnerHTML {:__html (str "<image xlink:href=\"img/ship.png\" x=\"" (to-scale 400) "\" y=\"" (to-scale 240) "\" width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}]
    ])

 (def piece-positions
@@ -217,6 +238,9 @@
    {:x 400 :y 240}
  ])

+(defn pirate-click [game-state color from-space-index]
+  (println "clicked pirate:" color from-space-index))
+
 (defn jail []
   (when-let [jail (get-in @app-state [:board 0])]
     (apply concat
@@ -229,7 +253,13 @@
                      x (to-scale (+ 5 (* 10 player-index)))]
                  (for [pirate-index (range pirate-count)]
                    (let [y (to-scale (+ 35 (* 10 pirate-index)))]
-                     [:circle {:cx x :cy y :r (to-scale 4) :fill color-name}]))))))))
+                     [:circle
+                      {:cx x
+                       :cy y
+                       :r (to-scale 4)
+                       :fill color-name
+                       :on-click (fn jail-click [e]
+                                   (pirate-click @app-state pirate-color 0))}]))))))))

 ;; TODO: this looks almost exactly like jail
 (defn ship []
@@ -244,14 +274,28 @@
                      x (to-scale (+ 445 (* 10 player-index)))]
                  (for [pirate-index (range pirate-count)]
                    (let [y (to-scale (+ 245 (* 10 pirate-index)))]
-                     [:circle {:cx x :cy y :r (to-scale 4) :fill color-name}]))))))))
+                     [:circle
+                      {:cx x
+                       :cy y
+                       :r (to-scale 4)
+                       :fill color-name
+                       :on-click (fn ship-click [e]
+                                   (pirate-click @app-state pirate-color 37))}]))))))))

 (defn normal-space [x y]
-  [:rect {:x (to-scale x) :y (to-scale y) :width (to-scale 40) :height (to-scale 30) :stroke "black" :stroke-width "0.5" :fill "lightgray"}])
+  [:rect
+   {:x (to-scale x)
+    :y (to-scale y)
+    :width (to-scale 40)
+    :height (to-scale 30)
+    :stroke "black"
+    :stroke-width "0.5"
+    :fill "lightgray"}])

 (defn space-image [x y icon]
-  [:g {:dangerouslySetInnerHTML {:__html (str "<image xlink:href=\"" (icon icon-images) "\" x=\"" (to-scale x) "\" y=\"" (to-scale y) "\" width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}]
-  )
+  [:g
+   {:dangerouslySetInnerHTML
+    {:__html (str "<image xlink:href=\"" (icon icon-images) "\" x=\"" (to-scale x) "\" y=\"" (to-scale y) "\" width=\"" (to-scale 30) "\" height=\"" (to-scale 30) "\" />")}}])

 (defn normal-spaces []
   (apply concat
@@ -263,10 +307,14 @@
                [space image]
                )))))

+;; TODO: duplicated from server code
 (defn active-player
   "Returns the active player from the players collection by name."
   [game-state]
   (first (filter #(= (:current-player game-state) (:name %)) (:players game-state))))
+
+(defn card-click [game-state card]
+  (println "card-click" card))

 (defn main-view []
   [:center
@@ -291,8 +339,14 @@
         [:tr
          [:td "Color"]
          [:td
-          [:svg {:width (to-scale 20) :height (to-scale 20)}
-           [:circle {:cx (to-scale 10) :cy (to-scale 10) :r (to-scale 7) :fill (name color)}]]
+          [:svg
+           {:width (to-scale 20)
+            :height (to-scale 20)}
+           [:circle
+            {:cx (to-scale 10)
+             :cy (to-scale 10)
+             :r (to-scale 7)
+             :fill (name color)}]]
           [:span {:style {:color (name color)}} (name color)]]]
         [:tr
          [:td "Cards"]
@@ -300,7 +354,12 @@
                 ^{:key card}
                 [:span {:style {:float "left"}}
                  [:figure
-                  [:img {:src (card icon-images) :width (to-scale 30) :height (to-scale 30)}]
+                  [:img
+                   {:src (card icon-images)
+                    :width (to-scale 30)
+                    :height (to-scale 30)
+                    :on-click (fn ship-click [e]
+                                   (card-click @app-state card))}]
                   [:center [:figcaption num]]]])]]]])]])

 (defn on-error [{:keys [status status-text]}]


cleanup + fix problem if missing disconnect method

--- ccw.core/src/ccw/editors/antlrbased/StacktraceHyperlink.clj
+++ ccw.core/src/ccw/editors/antlrbased/StacktraceHyperlink.clj
@@ -15,14 +15,15 @@
   (:gen-class
     :init init
     :state state
-    :implements [org.eclipse.ui.console.IPatternMatchListenerDelegate]
-    :methods [[doStuff [String] clojure.lang.PersistentArrayMap]]))
+    :implements [org.eclipse.ui.console.IPatternMatchListenerDelegate]))

 (defn -init []
-  [[] (ref {})])
+  [[] (ref nil)])

 (defn -connect [this console]
-  (dosync (alter (.state this) assoc :console console)))
+  (dosync (ref-set (.state this) console)))
+
+(defn -disconnect [this])

 (defn- find-datas [s]
   {:line (Integer/valueOf (second (re-find #":([0-9]+)" s)))
@@ -37,7 +38,7 @@
   (map + [1 0] (map count (s/split s #"\("))))

 (defn -matchFound [this event]
-  (let [console (@(.state this) :console)
+  (let [console @(.state this)
         offset (.getOffset event)
         s (.get (.getDocument console) offset (.getLength event))
         [o l] (offset-and-length s)


Need to close over *connection* as sync will be invoked in different thread

--- modules/messaging/src/main/clojure/immutant/messaging/core.clj
+++ modules/messaging/src/main/clojure/immutant/messaging/core.clj
@@ -129,9 +129,10 @@
       (try
         (f)
         (finally
-         (if (tx/active?)
-           (tx/after-completion #(.close *connection*))
-           (.close *connection*)))))))
+         (let [conn *connection*]
+           (if (tx/active?)
+             (tx/after-completion #(.close conn))
+             (.close conn))))))))

 (defmacro with-connection [& body]
   `(with-connection* (fn [] ~@body)))


remove unnecessary do-defaults

remove unnecessary do-defaults

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -168,10 +168,10 @@
   (log/debug (str "generate2: spec: " spec))
   (let [depth 0
         max-depth max-total-depth]
-    (mapfn #(do-defaults % model)
-           (flatten
-            (mapfn #(add-bolt-at % % [] % model depth max-depth)
-                   (lightning-bolts model spec 0 max-total-depth))))))
+    (flatten
+     (mapfn #(add-bolt-at % % [] % model depth max-depth)
+            (lightning-bolts model spec 0 max-total-depth)))))
+
 (defn generate-n
   "Returns all possible expressions generated by the given language model, constrained by the given spec.
    Depending on the grammar in the language model, could be an infinite number of expressions."


s|log/info|log/debug|

s|log/info|log/debug|

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -159,7 +159,7 @@
 (defn comp-path-to-complements
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."
   [bolt path model depth max-depth]
-  (log/info (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
+  (log/debug (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
   (let [spec (get-in bolt path)
         lexemes (shufflefn (get-lexemes model spec))
         bolts-at (if (< depth max-depth)


improve log/warn message

improve log/warn message

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -118,7 +118,7 @@
                  (log/debug (str "lightning-bolts: (optimizeme) size of subset of candidate heads: " (count subset) " with spec: " (strip-refs spec) " and parent:  " (:rule parent)))
                  (let [result (over/overh parent (lazy-shuffle subset))]
                    (log/debug (str "lightning-bolts: (optimizeme) surviving candidate heads: " (count result)))
-                   (if (empty? result)
+                   (if (and (not (empty? subset)) (empty? result))
                      (log/warn (str "tried: " (count subset) " lexical candidates with spec:" ( strip-refs spec) " and all of them failed as heads of parent:" (:rule parent))))
                    result)))
              parents))


CMR-4558: Remove OBE test

CMR-4558: Remove OBE test

--- system-int-test/test/cmr/system_int_test/search/sitemaps_test.clj
+++ system-int-test/test/cmr/system_int_test/search/sitemaps_test.clj
@@ -192,12 +192,3 @@
     (testing "the collections not tagged with eosdis shouldn't show up"
       (is (not (string/includes?
                 body (format "%s.html</loc>" (first colls))))))))
-
-(deftest regeneration-permissions
-  (site/assert-search-directory-regen-permissions
-   "master sitemap" "sitemap.xml?regenerate=true")
-  (site/assert-search-directory-regen-permissions
-   "content sitemap" "site/sitemap.xml?regenerate=true")
-  (site/assert-search-directory-regen-permissions
-   "provider/tag sitemap"
-   "site/collections/directory/PROV1/gov.nasa.eosdis/sitemap.xml?regenerate=true"))


reducing verbosity and adjusting to latest model

--- src/celestial/tasks.clj
+++ src/celestial/tasks.clj
@@ -2,15 +2,15 @@
   "misc development tasks"
   (:use
     [celestial.common :only (slurp-edn)]
-    [taoensso.timbre :only (debug info error warn)])
+    [taoensso.timbre :only (debug info trace)])
   (:import
     [celestial.puppet_standalone Standalone]
     [proxmox.provider Container]))

-(defn reload [{:keys [system]}]
+(defn reload [{:keys [machine]}]
   "Sets up a clean machine from scratch"
-  (let [{:keys [hypervisor]} system ct (Container. hypervisor system)]
-    (info "setting up" system "on" hypervisor)
+  (let [{:keys [hypervisor]} machine ct (Container. hypervisor machine)]
+    (info "setting up" machine "on" hypervisor)
     (.stop ct)
     (.delete ct)
     (.create ct)
@@ -18,10 +18,11 @@
     (assert (= (.status ct) "running"))
     (info "done system setup")))

-(defn puppetize [{:keys [server module] :as provision} ]
-  (info "starting to provision" provision)
-  (.apply- (Standalone. server module) )
-  (info "done provisioning" provision))
+(defn puppetize [{:keys [module machine] :as provision} ]
+  (info "starting to provision" )
+  (trace provision)
+  (.apply- (Standalone. machine module))
+  (info "done provisioning"))

 (defn full-cycle
   ([{:keys [system hypervisor provision]}] (full-cycle system hypervisor))


Add match3

Add match3

--- src/chapter3/match.cljs
+++ src/chapter3/match.cljs
@@ -9,3 +9,10 @@
     (empty? p) (empty? s)
     (match2 (first p) (first s)) (match2 (rest p) (rest s))
     :else false))
+(defn match3 [p s]
+  (cond
+    (or (atom? p) (atom? s)) false
+    (empty? p) (empty? s)
+    (= (first p) (first s)) (match3 (rest p) (rest s))
+    (= (first p) '?) (match3 (rest p) (rest s))
+    :else false))


(MAINT) changed locale-negotiator parens

removed parens around locale-negotiator

--- src/clj/puppetlabs/services/puppet_admin/puppet_admin_core.clj
+++ src/clj/puppetlabs/services/puppet_admin/puppet_admin_core.clj
@@ -132,7 +132,7 @@
       ;; of the 'wrap-with-trapperkeeper-or-client-whitelist-authorization'
       ;; function and replace with a line chaining the handler into a call to
       ;; 'authorization-fn'.
-      (i18n/locale-negotiator)
+      i18n/locale-negotiator
       (ringutils/wrap-with-trapperkeeper-or-client-whitelist-authorization
         authorization-fn
         path


fix for incorrect display of timeseries chart labels

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/charts/ts_chart.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/charts/ts_chart.cljs
@@ -30,7 +30,7 @@
   [bars mx cnt w label]
   (when-not (empty? @label)
     (let [idx (:idx @label)
-          [k v] (get bars idx)
+          [k v] (get (vec bars) idx)
           top (- ts-h (* (/ v mx) ts-h))
           lr (if (< (/ idx cnt) 0.6) "left" "right")]
       [:div.detail {:style {:left (* idx w)}}


Better logging of event push notification responses.

--- src/forces_assemble/handler.clj
+++ src/forces_assemble/handler.clj
@@ -54,6 +54,16 @@
       (dissoc notification :notification)
       notification)))

+(defn handle-push-response
+  [response]
+  (let [body (parse-json-body (:body response))]
+    (cond
+      (> (:failure body) 0) (log/error (str "Push failed: "
+                                            (:status response) " "
+                                            (:error (first (:results body)))) )
+      (> (:success body) 0) (log/info "Successfully pushed event")
+      :else (log/info "No events pushed"))))
+
 (defn push-event
   [channel-id event]
   (let [cm (make-reusable-conn-manager {:threads 4 :timeout 10 :default-per-route 5})
@@ -61,15 +71,17 @@
     (doall (map (fn [client-token]
                   (log/info (str "Pushing to: " client-token))
                   (log/info (str "Message: " (pr-str event)))
-                  (http/post firebase-send-uri
-                             {:content-type :json
-                              :headers {"Authorization" api-key}
-                              :form-params (build-notification event client-token)
-                              :connection-manager cm}))
+                  (try
+                    (handle-push-response (http/post firebase-send-uri
+                                                     {:content-type :json
+                                                      :headers {"Authorization" api-key}
+                                                      :form-params (build-notification event client-token)
+                                                      :connection-manager cm}))
+                    (catch Exception e
+                      (log/error e "Push exception"))))
                 (db/get-user-notification-tokens-on-channel channel-id)))
     (log/info "Finished pushing events")
-    (shutdown-manager cm)
-    (log/info "Shutdown connection manager")))
+    (shutdown-manager cm)))

 (defn add-event-to-channel
   [channel-id event]


Adapt `rect-mode` for use with p5js. Issue #255.

--- src/cljc/quil/core.cljc
+++ src/cljc/quil/core.cljc
@@ -3225,7 +3225,7 @@

   [mode]
   (let [mode (u/resolve-constant-key mode rect-modes)]
-    (.rectMode (current-graphics) (int mode))))
+    (.rectMode (current-graphics) mode)))

 (defn
   ^{:requires-bindings true


Aggressively comment the CLJS layout ns for now.

--- src/cljs/c2/layout.cljs
+++ src/cljs/c2/layout.cljs
@@ -1,10 +1,11 @@
+(comment
+
 (ns c2.layout
   (:refer-clojure :exclude [+ - =])
   (:use-macros [c2.util :only [p half]])
   (:use [c2.core :only [translate children select select-all]]
         [cassowary.core :only [+ - = cvar constrain! stay! simplex-solver]]))

-(comment
   (defn distribute! [selector]
     (let [solver (simplex-solver)
           spacing  (cvar 0)


move some basic predicates higher up

move some basic predicates higher up

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -59,9 +59,16 @@
 (defn ^boolean array? [x]
   (cljs.core/array? x))

+(defn ^boolean number? [n]
+  (cljs.core/number? n))
+
 (defn ^boolean not
   "Returns true if x is logical false, false otherwise."
   [x] (if x false true))
+
+(defn ^boolean string? [x]
+  (and ^boolean (goog/isString x)
+    (not (identical? (.charAt x 0) \uFDD0))))

 (set! *unchecked-if* true)
 (defn ^boolean type_satisfies_
@@ -328,7 +335,13 @@

 ;;;;;;;;;;;;;;;;;;; symbols ;;;;;;;;;;;;;;;

-(declare list instance? symbol? hash-combine hash)
+(declare list hash-combine hash Symbol)
+
+(defn ^boolean instance? [t o]
+  (cljs.core/instance? t o))
+
+(defn ^boolean symbol? [x]
+  (instance? Symbol x))

 (deftype Symbol [ns name str ^:mutable _hash _meta]
   Object
@@ -373,11 +386,7 @@

 ;;;;;;;;;;;;;;;;;;; fundamentals ;;;;;;;;;;;;;;;

-(declare array-seq prim-seq keyword? IndexedSeq)
-
-(defn ^boolean string? [x]
-  (and ^boolean (goog/isString x)
-    (not (identical? (.charAt x 0) \uFDD0))))
+(declare array-seq prim-seq IndexedSeq)

 (defn ^seq seq
   "Returns a seq on the collection. If the collection is
@@ -443,9 +452,6 @@
          (recur y (first more) (next more))
          (= y (first more)))
        false)))
-
-(defn ^boolean instance? [t o]
-  (cljs.core/instance? t o))

 ;;;;;;;;;;;;;;;;;;; protocols on primitives ;;;;;;;;
 (declare hash-map list equiv-sequential)
@@ -914,7 +920,8 @@
          (recur ret (first ks) (next ks))
          ret))))

-(declare fn?)
+(defn ^boolean fn? [f]
+  (or ^boolean (goog/isFunction f) (satisfies? Fn f)))

 (defn with-meta
   "Returns an object of the same type and value as obj, with
@@ -971,8 +978,6 @@
     (set! string-hash-cache-count (inc string-hash-cache-count))
     h))

-(declare number?)
-
 (defn check-string-hash-cache [k]
   (when (> string-hash-cache-count 255)
     (set! string-hash-cache (js-obj))
@@ -1103,15 +1108,6 @@
 (defn ^boolean keyword? [x]
   (and ^boolean (goog/isString x)
        (identical? (.charAt x 0) \uFDD0)))
-
-(defn ^boolean symbol? [x]
-  (instance? Symbol x))
-
-(defn ^boolean number? [n]
-  (cljs.core/number? n))
-
-(defn ^boolean fn? [f]
-  (or ^boolean (goog/isFunction f) (satisfies? Fn f)))

 (defn ^boolean ifn? [f]
   (or (fn? f) (satisfies? IFn f)))


CLJS-332: have UUID's = impl check that the other object is also a UUID instance

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -6935,7 +6935,7 @@

   IEquiv
   (-equiv [_ other]
-    (identical? uuid (.-uuid other)))
+    (and (instance? UUID other) (identical? uuid (.-uuid other))))

   IPrintable
   (-pr-seq [_ _]


Fixed streaming search

Fixed streaming search

--- src/edu/berkeley/ai/angelic/hierarchies/offline_algorithms.clj
+++ src/edu/berkeley/ai/angelic/hierarchies/offline_algorithms.clj
@@ -234,12 +234,11 @@
    Returns a lazy seq of result actions, but no final cost.
    The user may want to call seque on the resulting sequence, to realize it in the background."
   ([node]
-    (apply concat
-    (for [result (alts/decompose-plan node)]
-      (let [next (ahss-et-search result (search/lower-reward-bound result))]
-	(if (isa? (:class next) ::search/Node)
- 	    (streaming-search next)
-	  (first next)))))))
+    (if (isa? (:class node) ::search/Node)
+        (apply concat
+	  (for [result (alts/decompose-plan node)]
+	    (streaming-search (ahss-et-search result (search/lower-reward-bound result)))))
+      (first node))))


Don't attempt to add a places visit list of (nil).

--- src/datomish/places/import.cljc
+++ src/datomish/places/import.cljc
@@ -59,7 +59,8 @@
         required {:db/id (db/id-literal :db.part/user)
                   :page/url (:url (first rows))
                   :page/guid (:guid (first rows))}
-        visits (map :visit_date rows)]
+        visits (keep :visit_date rows)]
+
     (assoc-if required
               :page/title title
               :page/visitAt visits)))


Use getBrowserEvent method instead of _event property

--- modules/reitit-frontend/src/reitit/frontend/history.cljs
+++ modules/reitit-frontend/src/reitit/frontend/history.cljs
@@ -62,7 +62,7 @@
 (defn- event-target [event]
   "Read event's target from composed path to get shadow dom working,
    fallback to target property if not available"
-  (let [original-event (.-event_ event)]
+  (let [original-event (.getBrowserEvent event)]
     (if (exists? (.-composedPath original-event))
       (first (.composedPath original-event))
       (.-target event))))


cleanup devices.clj

cleanup devices.clj

--- src/kixi/hecuba/api/devices.clj
+++ src/kixi/hecuba/api/devices.clj
@@ -15,7 +15,7 @@
         method       (:request-method request)
         route-params (:route-params request)
         entity-id    (:entity-id route-params)
-        entity       (hecuba/item querier :entity entity-id)]
+        entity       (hecuba/item querier :entity entity-id)]
     (case method
       :post (not (nil? entity))
       :get (let [items (hecuba/items querier :device [[= :entity-id entity-id]])]
@@ -41,7 +41,7 @@
         entity-id     (-> request :route-params :entity-id)
         [username _]  (sec/get-username-password request querier)
         user-id       (-> (hecuba/items querier :user [[= :username username]]) first :id)]
-
+
     (when-not (empty? (first (hecuba/items querier :entity [[= :id entity-id]])))
       (let [device    (-> body
                           (assoc :user-id user-id)
@@ -98,7 +98,7 @@
                   (dissoc :id))}
       false)))

-;; Should be device-response etc and it should do the delete in delete!,
+;; Should be device-response etc and it should do the delete in delete!,
 ;; that should put something in the context which is then checked here.
 (defn resource-delete-enacted? [commander ctx]
   (let [{item ::item} ctx


Add stereo panning.

Add stereo panning.

--- src/klangmeister/synthesis.cljs
+++ src/klangmeister/synthesis.cljs
@@ -91,6 +91,11 @@
 (def low-pass (partial biquad-filter "lowpass"))
 (def high-pass (partial biquad-filter "highpass"))

+(defn stereo-panner [pan]
+  (fn [context at duration]
+    (doto (.createStereoPanner context)
+      (-> .-pan (plug pan context at duration)))))
+
 (defn destination [context at duration]
   (.-destination context))


CMR-2316: Removed redundant function implementation

--- umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
+++ umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
@@ -49,7 +49,7 @@
 (defn- generate-and-validate-xml
   "Returns a vector of errors (empty if none) from attempting to convert the given UMM record
   to valid XML in the given format."
-  [record metadata-format concept-type]
+  [concept-type metadata-format record]
   (let [metadata-xml (core/generate-metadata concept-type metadata-format record)]
     (core/validate-xml concept-type metadata-format metadata-xml)))

@@ -60,7 +60,7 @@
           dest-format collection-destination-formats
           :when (not= origin-format dest-format)]
     (testing (str origin-format " to " dest-format)
-      (is (empty? (generate-and-validate-xml umm-c-record dest-format :collection))))))
+      (is (empty? (generate-and-validate-xml :collection dest-format umm-c-record))))))

 (deftest roundtrip-example-record
   (doseq [metadata-format tested-formats]
@@ -91,13 +91,6 @@
       (is (= expected-projects-keywords
              (parse-iso19115-projects-keywords metadata-xml))))))

-(defn- generate-and-validate-xml
-  "Generates collection XML for the given format based on the provided UMM record. Performs
-  schema validation against the generated XML and returns any validation errors."
-  [format record]
-  (core/validate-xml :collection format
-                     (core/generate-metadata :collection format record)))
-
 (def minimal-umm-c
   "UMM-C with the bare minimum number of fields. It does not include all required fields because
   there is existing data in the system which does not contain all of the required UMM-C fields. We
@@ -106,7 +99,7 @@
   (js/parse-umm-c {:ShortName "foo" :Version "bar"}))

 (deftest minimal-dif10
-  (is (empty? (generate-and-validate-xml :dif10 minimal-umm-c))))
+  (is (empty? (generate-and-validate-xml :collection :dif10 minimal-umm-c))))

 (comment


refactor join code

refactor join code


Report an error when a file is missing

Report an error when a file is missing

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

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -27,7 +27,8 @@
            [java.awt.event ItemEvent ItemListener KeyAdapter MouseAdapter
                            WindowAdapter WindowListener]
            [com.swtdesigner SwingResourceManager]
-           [org.micromanager.acquisition ImageStorageListener MMImageCache])
+           [org.micromanager.acquisition ImageStorageListener MMImageCache]
+           [org.micromanager.utils.ReportingUtils])
   (:use [org.micromanager.browser.utils
             :only (gen-map constrain-to-parent create-button create-icon-button
                    attach-action-key remove-borders choose-directory
@@ -126,9 +127,11 @@
 (defn open-selected-files [table]
   (let [path-column (.indexOf tags "Path")]
     (doseq [i (.getSelectedRows table)]
-      (.openAcquisitionData gui
-        (.. table getModel
-            (getValueAt (.convertRowIndexToModel table i) path-column))))))
+      (let [f (.. table getModel
+                  (getValueAt (.convertRowIndexToModel table i) path-column))]
+        (if (.exists (File. f))
+          (.openAcquisitionData gui f)
+          (ReportingUtils/showError "File not found."))))))

 (defn listen-to-open [table]
   (.addMouseListener table


CMR-1246: Fix bug with stopping system.

CMR-1246: Fix bug with stopping system.

--- dev-system/src/cmr/dev_system/control.clj
+++ dev-system/src/cmr/dev_system/control.clj
@@ -34,7 +34,7 @@
   ([function-str]
    ((var-get (find-var (symbol (str "cmr.dev-system.system/" function-str))))))
   ([function-str & args]
-   ((var-get (find-var (symbol (str "cmr.dev-system.system/" function-str)))) args)))
+   (apply (var-get (find-var (symbol (str "cmr.dev-system.system/" function-str)))) args)))

 (defn get-acl-state
   [system]


generate site namespace pages

generate site namespace pages

--- src/main/cljs_api_gen/write.clj
+++ src/main/cljs_api_gen/write.clj
@@ -691,10 +691,24 @@
         data (-> (index-file-data result)
                  (update-in [:library-api :ns-symbols] change-ns-links :library)
                  (update-in [:compiler-api :ns-symbols] change-ns-links :compiler))]
+
     (spit (str *output-dir* "/index.md")
           (stencil/render-string
             (slurp "templates/site/index.md")
-            data))))
+            data))
+
+    (doseq [[prefix api-type] [["/library" :library-api]
+                               ["/compiler" :compiler-api]
+                               ["" :syntax-api]]]
+
+      (mkdirs (str *output-dir* prefix))
+
+      (doseq [ns-data (get-in data [api-type :ns-symbols])]
+        (spit (str *output-dir* prefix "/" (:ns ns-data) ".html")
+              (stencil/render-string
+                (slurp "templates/site/ns.md")
+                ns-data))))
+    ))

 (defn dump-site-pages! [result]
   (binding [*result* result


Update evaluate-model to use predict multimethod and return a confusion matrix instead of percent correct.

--- project/analyze-data/src/analyze_data/evaluate_model.clj
+++ project/analyze-data/src/analyze_data/evaluate_model.clj
@@ -1,50 +1,71 @@
 (ns analyze-data.evaluate-model
   (:require [clojure.java.io :as io]
             [analyze-data.csv-to-map :refer [csv-to-map]]
-            [analyze-data.find-knn :refer [find-knn]]
+            [analyze-data.predict :refer [predict]]
             [analyze-data.serialize :refer [read-object]]))

 (defn get-predictions
-  "Make a prediction for each row of test-data using given model.
+  "Make a prediction for each row of test-corpus using given model.

-  tf-idf-data: map produced by corpus-to-tf-idf-data
-  test-data: sequence of maps with 'document-label' and 'document-text' keys
+  model: map produced by analyze-data.naive-bayes.train/train
+  test-corpus: sequence of maps with 'document-label' and 'document-text' keys
+  options: passed through to analyze-data/predict

   Return a sequence of the form:
-  [[test-label [predicted-label distance]]
+  [[label predicted-label]
     ...]"
-  [tf-idf-data test-data]
-  (let [test-corpus (map #(get % "document-text") test-data)
-        test-labels (map #(get % "document-label") test-data)
-        predictions (map (partial find-knn tf-idf-data) test-corpus)]
-    (map #(vector %1 (first %2)) test-labels predictions)))
+  [model test-corpus & options]
+  (let [document-texts (map #(get % "document-text") test-corpus)
+        labels (map #(get % "document-label") test-corpus)
+        predicted-labels (map #(apply predict model % options)
+                              document-texts)]
+    (map vector labels predicted-labels)))

-(defn- correct-prediction?
-  "Given a prediction of the form [test-label [predicted-label distance]],
-  return (= test-label predicted-label)."
-  [prediction]
-  (let [[test-label [predicted-label distance]] prediction]
-    (= test-label predicted-label)))
+(defn- empty-confusion-matrix
+  "Create confusion matrix with all 0 values.
+  For example, if classes = [:a :b], returns
+  {:a {:a 0
+       :b 0}
+   :b {:a 0
+       :b 0}}"
+  [classes]
+  (let [entries (zipmap classes (repeat 0))]
+    (zipmap classes (repeat entries))))

 (defn evaluate-model
-  "Make a prediction for each row of test-data using given model and return (#
-  correct predictions / # total predictions).
+  "Make a prediction for each row of test-corpus using given model and return
+  a confusion matrix.

-  tf-idf-data: map produced by corpus-to-tf-idf-data
-  test-data: sequence of maps with 'document-label' and 'document-text' keys"
-  [tf-idf-data test-data]
-  (let [predictions (get-predictions tf-idf-data test-data)
-        correct-predictions (filter correct-prediction? predictions)]
-    (float (/ (count correct-predictions) (count predictions)))))
+  model: model produced by train-model
+  test-corpus: sequence of maps with 'document-label' and 'document-text'
+               keys
+  options: passed through to analyze-data/predict
+
+  Return a confusion matrix as a nested map. For example, if the labels of
+  the model are :a and :b, returns
+  {:a {:a <number of documents classified as :a that were predicted :a>
+       :b <number of documents classified as :a that were predicted :b>}
+   :b {:a <number of documents classified as :b that were predicted :a>
+       :b <number of documents classified as :b that were predicted :b>}}
+
+  Note that if any counts are 0 then that entry will not exist."
+  [model test-corpus & options]
+  (let [predictions (apply get-predictions model test-corpus options)
+        classes (-> model :dataset :labels)
+        inc-prediction-count (fn [m [label predicted-label]]
+                               (update-in m [label predicted-label] inc))]
+    (reduce inc-prediction-count
+            (empty-confusion-matrix classes)
+            predictions)))

 (defn evaluate-model-file
   "Like evaluate-model, but take file path arguments for both model and test
   data.

-  tf-idf-data-file: path to a file containing serialized tf-idf-data
+  model-file: path to a file containing serialized model
   test-file: path to a csv with 'document-label' and 'document-text' headers"
-  [tf-idf-data-file test-file]
+  [model-file test-file]
   (with-open [in (io/reader test-file)]
-    (let [model (read-object tf-idf-data-file)
-          test-data (csv-to-map in)]
-      (evaluate-model model test-data))))
+    (let [model (read-object model-file)
+          test-corpus (csv-to-map in)]
+      (evaluate-model model test-corpus))))


code-anchor-id multi method

code-anchor-id multi method

--- src/me/panzoo/story.clj
+++ src/me/panzoo/story.clj
@@ -29,10 +29,6 @@
 ; expressions that match the beginning of lines, SyntaxHighlighter options, a
 ; PegDownProcessor, and a modified LinkRenderer.

-(def clojure-form
-  "A regular expression matching the beginning of a clojure form."
-  #"^\(")
-

 ; ### Settings
 ;
@@ -59,7 +55,7 @@

 (def ^:dynamic *language*
   "A language string for use with SyntaxHighlighter."
-  "clojure")
+  :clojure)

 (def ^:dynamic *path*
   "The path of the file currently being processed."
@@ -84,58 +80,69 @@
 (def languages
   "A map of language names to a pairs of comment syntax and SyntaxHighlighter
   brush file names."
-  {"clojure" [";" "shBrushClojure.js"]
-   "clj" [";" "shBrushClojure.js"]
-   "cljs" [";" "shBrushClojure.js"]
-   "applescript" ["--" "shBrushAppleScript.js"]
-   "actionscript3" ["//" "shBrushAS3.js"]
-   "as3" ["//" "shBrushAS3.js"]
-   "bash" ["#" "shBrushBash.js"]
-   "shell" ["#" "shBrushBash.js"]
-   "sh" ["#" "shBrushBash.js"]
-   ;"coldfusion" "shBrushColdFusion.js"
-   "cpp" ["//" "shBrushCpp.js"]
-   "c++" ["//" "shBrushCpp.js"]
-   "cxx" ["//" "shBrushCpp.js"]
-   "c" ["//" "shBrushCpp.js"]
-   "c#" ["//" "shBrushCSharp.js"]
-   "c-sharp" ["//" "shBrushCSharp.js"]
-   "csharp" ["//" "shBrushCSharp.js"]
-   "delphi" ["//" "shBrushDelphi.js"]
-   "pascal" ["//" "shBrushDelphi.js"]
-   ;"diff" "shBrushDiff.js"
-   ;"patch" "shBrushDiff.js"
-   "erlang" ["%" "shBrushErlang.js"]
-   "erl" ["%" "shBrushErlang.js"]
-   "groovy" ["//" "shBrushGroovy.js"]
-   "java" ["//" "shBrushJava.js"]
-   "javafx" ["//" "shBrushJavaFX.js"]
-   "jfx" ["//" "shBrushJavaFX.js"]
-   "javascript" ["//" "shBrushJScript.js"]
-   "js" ["//" "shBrushJScript.js"]
-   "perl" ["#" "shBrushPerl.js"]
-   "pl" ["#" "shBrushPerl.js"]
-   "php" ["#" "shBrushPhp.js"]
-   ;"text" "shBrushPlain.js"
-   ;"txt" "shBrushPlain.js"
-   ;"plain" "shBrushPlain.js"
-   "python" ["#" "shBrushPython.js"]
-   "py" ["#" "shBrushPython.js"]
-   "ruby" ["#" "shBrushRuby.js"]
-   "rb" ["#" "shBrushRuby.js"]
-   "sass" ["//" "shBrushSass.js"]
-   "scss" ["//" "shBrushSass.js"]
-   "scala" ["//" "shBrushScala.js"]
-   "sql" ["--" "shBrushSql.js"]
-   "vim" ["\"" "shBrushVimscript.js"]
-   "vimscript" ["\"" "shBrushVimscript.js"]
-   "vb" ["'" "shBrushVb.js"]
-   "vbnet" ["'" "shBrushVb.js"]
-   ;"xml" "shBrushXml.js"
-   ;"xhtml" "shBrushXml.js"
-   ;"xslt" "shBrushXml.js"
-   ;"html" "shBrushXml.js"
+  {:clojure [";" "shBrushClojure.js"]
+   :clj [";" "shBrushClojure.js"]
+   :cljs [";" "shBrushClojure.js"]
+   :applescript ["--" "shBrushAppleScript.js"]
+   :actionscript3 ["//" "shBrushAS3.js"]
+   :as3 ["//" "shBrushAS3.js"]
+   :bash ["#" "shBrushBash.js"]
+   :shell ["#" "shBrushBash.js"]
+   :sh ["#" "shBrushBash.js"]
+   :cpp ["//" "shBrushCpp.js"]
+   :c++ ["//" "shBrushCpp.js"]
+   :cxx ["//" "shBrushCpp.js"]
+   :c ["//" "shBrushCpp.js"]
+   :c# ["//" "shBrushCSharp.js"]
+   :c-sharp ["//" "shBrushCSharp.js"]
+   :csharp ["//" "shBrushCSharp.js"]
+   :delphi ["//" "shBrushDelphi.js"]
+   :pascal ["//" "shBrushDelphi.js"]
+   :erlang ["%" "shBrushErlang.js"]
+   :erl ["%" "shBrushErlang.js"]
+   :groovy ["//" "shBrushGroovy.js"]
+   :java ["//" "shBrushJava.js"]
+   :javafx ["//" "shBrushJavaFX.js"]
+   :jfx ["//" "shBrushJavaFX.js"]
+   :javascript ["//" "shBrushJScript.js"]
+   :js ["//" "shBrushJScript.js"]
+   :perl ["#" "shBrushPerl.js"]
+   :pl ["#" "shBrushPerl.js"]
+   :php ["#" "shBrushPhp.js"]
+   :python ["#" "shBrushPython.js"]
+   :py ["#" "shBrushPython.js"]
+   :ruby ["#" "shBrushRuby.js"]
+   :rb ["#" "shBrushRuby.js"]
+   :sass ["//" "shBrushSass.js"]
+   :scss ["//" "shBrushSass.js"]
+   :scala ["//" "shBrushScala.js"]
+   :sql ["--" "shBrushSql.js"]
+   :vim ["\"" "shBrushVimscript.js"]
+   :vimscript ["\"" "shBrushVimscript.js"]
+   :vb ["'" "shBrushVb.js"]
+   :vbnet ["'" "shBrushVb.js"]
    })
+
+(def language-aliases
+  "A map of aliases to canonical language names."
+  {:clj :clojure
+   :cljs :clojure
+   :sh :bash
+   :shell :bash
+   :c :cpp
+   :c++ :cpp
+   :cxx :cpp
+   :c# :csharp
+   :c-sharp :csharp
+   :erl :erlang
+   :jfx :javafx
+   :js :javascript
+   :pl :perl
+   :py :python
+   :rb :ruby
+   :sass :scss
+   :vimscript :vim
+   :vbnet :vb})

 ; ### Pegdown instances
@@ -251,6 +258,23 @@
      (binding [*out* w#]
        ~@body)))

+(defn canonical-lang
+  [l]
+  (let [k (keyword l)]
+    (get language-aliases k k)))
+
+(defn lang-info
+  [l]
+  (languages (canonical-lang l)))
+
+(defn lang-comment
+  [l]
+  (first (lang-info l)))
+
+(defn lang-brush
+  [l]
+  (second (lang-info l)))
+

 ; ### Regular expression helpers

@@ -297,14 +321,23 @@
                        (rest ll)))
              (if c (int c) -1))))))))

-(defn clojure-anchor? [lines]
-  (when (and (#{"clojure" "clj" "cljs"} *language*)
-             (re-find clojure-form (first lines)))
-    (with-open [r (lines-reader lines)]
-      (let [code (read r)]
-        (when-let [sym (and (re-find #"^def" (str (first code)))
-                            (second code))]
-          [[:anchor (str *path* "_" sym)]])))))
+(defmulti code-anchor-id (fn [_ _] *language*) :default :default)
+
+(defmethod code-anchor-id :clojure [line reader]
+  (when (re-find #"^\(" line)
+    (let [code (read reader)]
+      (and (re-find #"^def" (str (first code)))
+           (second code)))))
+
+(defmethod code-anchor-id :vim [line reader]
+  (second (re-find #"^function!?\s+([a-zA-Z_][a-zA-Z_0-9]+)" line)))
+
+(defmethod code-anchor-id :default [_ _] nil)
+
+(defn maybe-code-anchor [line reader]
+  (if-let [id (code-anchor-id line reader)]
+    [[:anchor (str *path* "/" id)]]
+    []))

 ; Each line of a source file will be either code, comment, anchor, or include.
 ; Headings are treated as both anchors and comments.
@@ -321,7 +354,8 @@
                         [:comment (.substring
                                     line (count (match? comment)))]]
       (match? comment) [[:comment (.substring line (count match))]]
-      :else (conj (vec (clojure-anchor? lines)) [:code line]))))
+      :else (conj (maybe-code-anchor line (lines-reader lines))
+                  [:code line]))))

 (defn classify-lines
   "Classify a line as :code or :comment. Return a pair of the classification
@@ -359,7 +393,7 @@
 ; SyntaxHighlighter brushes are associated with files if the language is
 ; supplied or can be worked out from the file suffix.
 (defn maybe-associate-brush [path lang]
-  (when-let [b (and lang (second (languages lang)))]
+  (when-let [b (and lang (lang-brush lang))]
     (when-not (@*brushes* b)
       (message "Associating "path " with brush " b)
       (swap! *brushes* conj b))))
@@ -379,15 +413,16 @@
 ; from the `path` suffix, and if that fails they are set to the values they
 ; have in the enclsing dynamic scope (i.e., from the commandline or the
 ; including file).
-  (binding [*language* (or lang
-                           (re-find #"(?<=\.)[^.]+$" path)
-                           *language*)]
+  (binding [*language* (canonical-lang
+                         (or lang
+                             (re-find #"(?<=\.)[^.]+$" path)
+                             *language*))]
     (binding [*single-comment* (or token
-                                   (first (languages *language*))
+                                   (lang-comment *language*)
                                    *single-comment*)]
       (binding [*path* path]
         (wrap-in-tags tag
-          (if (#{"markdown" "md"} *language*)
+          (if (#{:markdown :md} *language*)

 ; A markdown file is a special case. It is treated as a single comment block.
             (html<- [:comment (slurp path)])
@@ -409,7 +444,7 @@

 (defmethod html<- :code [[_ text]]
   (when-not (string/blank? text)
-    (println (str "
"
+    (println (str "
"
                   (string/escape
                     text
                     {\< "<"
@@ -584,7 +619,7 @@
                             :static-brushes (:brush amap)
                             :verbose? (:verbose amap)}
                 *single-comment* (:comment amap)
-                *language* (or (:language amap) *language*)]
+                *language* (canonical-lang (or (:language amap) *language*))]

 ; When no output file is given, the program renders to standard-out.
         (if (= 1 (count tail))


Fix event info model.

Fix event info model.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -806,12 +806,6 @@
                        :onyx.core/batch {:type [:segment]
                                          :optional? true
                                          :doc "The sequence of segments read by this peer"}
-                       :onyx.core/write-batch {:type :results
-                                               :optional? true
-                                               :doc "A sequence of segments to be written by this peer."}
-                       :onyx.core/triggered {:type [:segment]
-                                             :optional? true
-                                             :doc "A sequential containing segments emitted by `:trigger/emit`."}
                        :onyx.core/results {:type :results
                                            :optional? true
                                            :deprecated-version "0.12.0"
@@ -820,6 +814,9 @@
                        :onyx.core/transformed {:type :results
                                                :optional? true
                                                :doc "A sequence of sequences containing the segments that `:onyx/fn` produced for each segment in `:onyx.core/batch`. For example, if `:onyx.core/batch` contains `[{:n 1}]`, `:onyx.core/transformed` may contain `[[{:n 2 :type :incremented}]]`."}
+                       :onyx.core/triggered {:type [:segment]
+                                             :optional? true
+                                             :doc "A sequential containing segments emitted by `:trigger/emit`."}
                        :onyx.core/write-batch {:type :results
                                                :optional? true
                                                :doc "A sequence of segments containing the results of `:onyx.core/transformed` and `:onyx.core/triggered`."}
@@ -2070,9 +2067,10 @@
                :onyx.core/fn
                :onyx.core/params
                :onyx.core/metadata
-               :onyx.core/results
+               :onyx.core/batch
+               :onyx.core/write-batch
+               :onyx.core/transformed
                :onyx.core/triggered
-               :onyx.core/batch
                :onyx.core/id
                :onyx.core/job-id
                :onyx.core/task
@@ -2094,7 +2092,8 @@
                :onyx.core/storage
                :onyx.core/input-plugin
                :onyx.core/output-plugin
-               :onyx.core/monitoring]
+               :onyx.core/monitoring
+               :onyx.core/results]
    :env-config
    [:onyx/tenancy-id
     :zookeeper/server?


Use [] if no params found.

Use [] if no params found.

--- src/onyx/peer/task_pipeline.clj
+++ src/onyx/peer/task_pipeline.clj
@@ -265,7 +265,7 @@
                          :peer-version (extensions/version sync (:peer (:nodes payload)))
                          :payload-ch payload-ch
                          :complete-ch complete-ch
-                         :params (get fn-params task)
+                         :params (or (get fn-params task) [])
                          :queue queue
                          :sync sync}
           pipeline-data (merge pipeline-data (p-ext/inject-pipeline-resources pipeline-data))]


Update docstrings for encode! and decode!.

--- src/multicodec/core.clj
+++ src/multicodec/core.clj
@@ -52,7 +52,8 @@
   (encode!
     [codec ^java.io.OutputStream output value]
     "Write the value as a sequence of bytes to the output stream. Returns the
-    number of bytes written."))
+    number of bytes written. Throws an exception if the value cannot be
+    encoded."))

 (defn encode
@@ -72,7 +73,9 @@

   (decode!
     [codec ^java.io.InputStream input]
-    "Reads bytes from the input stream and returns the read value."))
+    "Reads bytes from the input stream and returns the read value. May not fully
+    consume the stream if multiple items are present. Throws an exception if the
+    input is malformed or incomplete."))

 (defn decode


Change email digest subject to reflect the email title.

--- src/oc/email/mailer.clj
+++ src/oc/email/mailer.clj
@@ -130,7 +130,13 @@
         org-name (:org-name msg)
         daily? (= (keyword (:digest-frequency msg)) :daily)
         frequency (if daily? "Daily" "Weekly")
-        digest-email-subject (if daily? "Your daily brief" "Your weekly brief")]
+        digest-email-subject (if daily?
+                              (if org-name
+                                (str "Yesterday at " org-name)
+                                (str "Yesterday in Carrot"))
+                              (if org-name
+                                (str "Last week at " org-name)
+                                (str "Last week in Carrot")))]
     (try
       (spit html-file (content/digest-html msg)) ; create the email in a tmp file
       (inline-css html-file inline-file) ; inline the CSS


Properly pass through checkpointing S3 encryption setting.

--- src/onyx/storage/s3.clj
+++ src/onyx/storage/s3.clj
@@ -21,6 +21,8 @@
            [java.util.concurrent TimeUnit]
            [java.util.concurrent.atomic AtomicLong]))

+
+
 (defn new-client ^AmazonS3Client [peer-config]
    (case (arg-or-default :onyx.peer/storage.s3.auth-type peer-config)
      :provider-chain (let [credentials (DefaultAWSCredentialsProviderChain.)]
@@ -60,10 +62,8 @@
         metadata (doto (ObjectMetadata.)
                    (.setContentLength size)
                    (.setContentMD5 md5))
-        _ (some->> content-type
-                   (.setContentType metadata))
-        _ (some->> encryption-setting
-                   (.setSSEAlgorithm metadata))
+        _ (some->> content-type (.setContentType metadata))
+        _ (some->> encryption-setting (.setSSEAlgorithm metadata))
         put-request (PutObjectRequest. bucket
                                        key
                                        (ByteArrayInputStream. serialized)
@@ -116,15 +116,16 @@
         (recur (.listObjects client bucket prefix) new-ks)
         new-ks))))

-(defrecord CheckpointManager [id monitoring client transfer-manager bucket transfers timeout-ns])
+(defrecord CheckpointManager [id monitoring client transfer-manager bucket encryption transfers timeout-ns])
+

 (defmethod onyx.checkpoint/storage :s3 [peer-config monitoring]
   (let [id (java.util.UUID/randomUUID)
         region (:onyx.peer/storage.s3.region peer-config)
         endpoint (:onyx.peer/storage.s3.endpoint peer-config)
         accelerate? (:onyx.peer/storage.s3.accelerate? peer-config)
+        encryption (arg-or-default :onyx.peer/storage.s3.encryption peer-config)
         timeout-ns (ms->ns (arg-or-default :onyx.peer/storage.timeout peer-config))
-
         bucket (or (:onyx.peer/storage.s3.bucket peer-config)
                    (throw (Exception. ":onyx.peer/storage.s3.bucket must be supplied via peer-config when using :onyx.peer/storage = :s3.")))
         client (new-client peer-config)
@@ -138,7 +139,7 @@
       (.setMultipartCopyPartSize configuration (long v)))
     (when-let [v (:onyx.peer/storage.s3.multipart-upload-threshold peer-config)]
       (.setMultipartUploadThreshold configuration (long v)))
-    (->CheckpointManager id monitoring client transfer-manager bucket (atom []) timeout-ns)))
+    (->CheckpointManager id monitoring client transfer-manager bucket encryption (atom []) timeout-ns)))

 (defn checkpoint-task-key [tenancy-id job-id replica-version epoch task-id slot-id checkpoint-type]
   ;; We need to prefix the checkpoint key in a random way to partition keys for
@@ -152,7 +153,7 @@
          (name checkpoint-type))))

 (defmethod checkpoint/write-checkpoint onyx.storage.s3.CheckpointManager
-  [{:keys [transfer-manager transfers bucket] :as storage} tenancy-id job-id replica-version epoch
+  [{:keys [transfer-manager transfers bucket encryption] :as storage} tenancy-id job-id replica-version epoch
    task-id slot-id checkpoint-type ^bytes checkpoint-bytes]
   (let [k (checkpoint-task-key tenancy-id job-id replica-version epoch task-id
                                slot-id checkpoint-type)
@@ -162,7 +163,7 @@
                                            k
                                            checkpoint-bytes
                                            "application/octet-stream"
-                                           :none)]
+                                           encryption)]
     (swap! transfers conj {:key k
                            :upload up
                            :size-bytes (alength checkpoint-bytes)


Remove lazyness in s3 transfer checker.

Remove lazyness in s3 transfer checker.

--- src/onyx/storage/s3.clj
+++ src/onyx/storage/s3.clj
@@ -167,23 +167,24 @@
   (empty?
    (swap! transfers
           (fn [tfers]
-            (keep (fn [transfer]
-                    (let [{:keys [key upload size-bytes start-time]} transfer
-                          state (.getState ^Upload upload)]
-                      (cond (= (Transfer$TransferState/Failed) state)
-                            (throw (.waitForException ^Upload upload))
-
-                            (= (Transfer$TransferState/Completed) state)
-                            (let [{:keys [checkpoint-store-latency
-                                          checkpoint-written-bytes]} monitoring]
-                             (info "Completed checkpoint to s3 under key" key)
-                             (m/update-timer-ns! checkpoint-store-latency (- (System/nanoTime) start-time))
-                             (.addAndGet ^AtomicLong checkpoint-written-bytes size-bytes)
-                             nil)
-
-                            :else
-                            transfer)))
-                  tfers)))))
+            (doall
+             (keep (fn [transfer]
+                     (let [{:keys [key upload size-bytes start-time]} transfer
+                           state (.getState ^Upload upload)]
+                       (cond (= (Transfer$TransferState/Failed) state)
+                             (throw (.waitForException ^Upload upload))
+
+                             (= (Transfer$TransferState/Completed) state)
+                             (let [{:keys [checkpoint-store-latency
+                                           checkpoint-written-bytes]} monitoring]
+                               (info "Completed checkpoint to s3 under key" key)
+                               (m/update-timer-ns! checkpoint-store-latency (- (System/nanoTime) start-time))
+                               (.addAndGet ^AtomicLong checkpoint-written-bytes size-bytes)
+                               nil)
+
+                             :else
+                             transfer)))
+                   tfers))))))

 (defmethod checkpoint/cancel! onyx.storage.s3.CheckpointManager
   [{:keys [transfers]}]


flash message when schedule is assigned

flash message when schedule is assigned

--- src/cljs/early_vote_site/early_vote_site_detail/events.cljs
+++ src/cljs/early_vote_site/early_vote_site_detail/events.cljs
@@ -140,7 +140,8 @@
 (defn assign-schedule-success
   [{:keys [db]} [_ result]]
   {:db db
-   :dispatch [:schedules-list/get]})
+   :dispatch-n [[:flash/message "Schedule assigned"]
+                [:schedules-list/get]]})

 ;; Unassign Schedule


Enhanced comments.

Enhanced comments.

--- src/overtunes/pitch.clj
+++ src/overtunes/pitch.clj
@@ -66,7 +66,7 @@
 (def raise #(+ % octave))
 (def lower #(- % octave))

-; Transformations
+; Transformations on chords
 (def suspended-second #(assoc % :iii (:ii major-scale)))
 (def suspended-fourth #(assoc % :iii (:iv major-scale)))
 (def sixth #(assoc % :vi (:vi major-scale)))
@@ -78,7 +78,7 @@
 (def first-inversion #(update-values % (keys-except % [:i]) lower))
 (def second-inversion #(update-values % (keys-except % [:i :iii]) lower))

-; Paramatisesd transformations
+; Paramatisesd transformations on chords
 (defn flattened [key] #(update-in % [key] flat))
 (defn sharpened [key] #(update-in % [key] sharp))
 (defn raised [key] #(update-in % [key] raise))


distance new format

distance new format

--- src/picsou/time/api.clj
+++ src/picsou/time/api.clj
@@ -44,6 +44,9 @@
       :temperature (merge {:type "value" :value value}
                           (select-keys token [:unit]))

+      :distance (merge {:type "value" :value value}
+                          (select-keys token [:unit]))
+
       :quantity (select-keys token [:value :unit :product])

 	    value))) ; keep value as is for other dims


content fixes

content fixes

--- src/prais2/content.cljs
+++ src/prais2/content.cljs
@@ -378,7 +378,7 @@
                     }

                    {:title "When looking at ALL hospitals simultaneously , what does it mean if any of the hospitals have an observed survival rate outside their predicted range?"
-                    :short-answer "When looking at many hospitals at once, we expect at least one hospital’s observed survival rate to be outside its predicted range about 8 times in 20. "
+                    :short-answer "When looking at all 14 hospitals at once, we expect at least one hospital’s observed survival rate to be outside its predicted range about 8 times in 20. "
                     :glossary [:chance-factors :survival-rate]
                     :body [:div


prevent some unnecessary cljs repl reconnection attempts

suggested improvement noted in https://github.com/tomjakubowski/weasel/issues/24

--- src/leiningen/new/yawt/src-cljs/root_ns/client/main.cljs
+++ src/leiningen/new/yawt/src-cljs/root_ns/client/main.cljs
@@ -23,7 +23,8 @@
 (defn init-app []
   (when (dev?)
     (enable-console-print!)
-    (if (supports-ws?)
+    (if (and (supports-ws?)
+             (not (ws-repl/alive?)))
       (ws-repl/connect "ws://localhost:9001" :verbose true)))
   (secretary/set-config! :prefix "#")
   (hook-browser-navigation!))


Fixup docstring for starting-trace

Fixup docstring for starting-trace

--- src/re_frame/trace.cljc
+++ src/re_frame/trace.cljc
@@ -107,8 +107,8 @@

           Common keys for trace-opts
           :op-type - what kind of operation is this? e.g. :sub/create, :render.
-          :operation - identifier for the operation, for an subscription it would be the subscription keyword
-          tags - a map of arbitrary kv pairs"
+          :operation - identifier for the operation, for a subscription it would be the subscription keyword
+          :tags - a map of arbitrary kv pairs"
      [{:keys [operation op-type tags child-of] :as trace-opts} & body]
      `(if (is-trace-enabled?)
         (binding [*current-trace* (start-trace ~trace-opts)]