Back one move button

Back one move button

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -330,12 +330,21 @@
 (defn is-ai? [player]
   (contains? @ai-players player))

+(defn cancel-last-move! []
+  (swap! app-state update-in [:games]
+    (fn [old-list]
+      (let [ai-turn? #(contains? (:ai-players %) (:player %))
+            new-list (drop-while ai-turn? (drop 1 old-list))]
+        (if (empty? new-list)
+          old-list new-list)))
+    ))
+

 ;; -----------------------------------------
 ;; GAME LOOP
 ;; -----------------------------------------

-(defn- handle-ai []
+(defn- handle-ai! []
   (let [ai-algo (get @ai-players @current-player)
         move (ai-algo @game @current-player)]
     (update-game! play-move move)))
@@ -355,7 +364,7 @@
         (alt!
           player-events ([coord] (update-game! play-move coord))
           game-events ([msg] (when (= msg :new-game) (new-game!)))
-          ai-events ([msg] (when (= msg :ai-play) (handle-ai)))
+          ai-events ([msg] (when (= msg :ai-play) (handle-ai!)))
           (async/timeout ai-move-delay) ([_] (put! ai-events :ai-play))
           )))

@@ -413,7 +422,8 @@
   [:div.scores
    [top-panel-button #(put! (:game-events game-loop) :new-game) (special-char "↻")]
    (show-scores scores player)
-   [top-panel-button #(swap! app-state update :help not) "?"]])
+   [top-panel-button #(swap! app-state update :help not) "?"]
+   [top-panel-button cancel-last-move! (special-char "←")]])

 (defn max-board-height []
   (- (-> (dom/getWindow) dom/getViewportSize .-height) 100))


Fix cigar parsing

Fix cigar parsing

--- src/clojure/cljam/cigar.clj
+++ src/clojure/cljam/cigar.clj
@@ -25,27 +25,19 @@

 (defn substantial-seq [cigar seq]
   (join
-   (loop [cursor  0
-          matches (re-seq #"([0-9]*)([MIDNSHP=X])" cigar)
+   (loop [matches (parse cigar)
+          cursor  0
           ret     []]
-     (if (first matches)
-       (let [n  (Integer/parseInt (second (first matches)))
-             op (last (first matches))]
-         (condp #(not (nil? (%1 %2))) op
-           #{"M" "=" "X"}
-           (recur (+ cursor n)
-                  (rest matches)
-                  (conj ret (subs seq cursor (+ cursor n))))
-
-           #{"D"}
-           (recur cursor
-                  (rest matches)
-                  (conj ret (join (repeat n "*"))))
-
-           #{"N"}
-           (recur cursor
-                  (rest matches)
-                  (conj ret (join (repeat n ">"))))
-
-           (recur cursor (rest matches) ret)))
+     (if-let [[n op]  (first matches)]
+       (let [[cursor* ret*] (condp #(not (nil? (%1 %2))) op
+                              #{\M \= \X} [(+ cursor n)
+                                           (conj ret (subs seq cursor (+ cursor n)))]
+                              #{\D}       [cursor
+                                           (conj ret (join (repeat n "*")))]
+                              #{\N}       [cursor
+                                           (conj ret (join (repeat n ">")))]
+                              #{\S \I}    [(+ cursor n)
+                                           ret]
+                              [cursor ret])]
+         (recur (rest matches) cursor* ret*))
        ret))))


<ruby> for emojis

<ruby> for emojis

--- src/clojure/nossal/data.clj
+++ src/clojure/nossal/data.clj
@@ -72,35 +72,35 @@
                              :title "Cabify"
                              :url "https://cabify.com/i/rodrigon361"
                              :description "💲 Ganhe R$15,00 de desconto na sua primeira viagem! ✅"
-                             :text [:p "Ganhe " [:span.value "R$15,00"] " de desconto na sua primeira corrida! 🎉"
+                             :text [:p "Ganhe " [:span.value "R$15,00"] " de desconto na sua primeira corrida!" [:ruby "🎉 " [:rt "ta-da!"]]
                                     [:small "Este cupom pode ser utilizado apenas uma vez por pessoa, em sua primeira viagem. Ganhe até " [:span.value "100%"] " de desconto na sua viagem."]]}
                    "uber"   {:code "ubernossal"
                              :title "Uber"
                              :url "https://www.uber.com/invite/ubernossal"
                              :description "💲 Ganhe R$20,00 de desconto em 2 primeiras viagens! ✅"
-                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas! 🎉 "
+                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas!" [:ruby "🎉 " [:rt "ta-da!"]]
                                     [:small "Este cupom pode ser utilizado duas vezes por pessoa, nas suas primeiras viagens. São " [:span.value "R$20,00"] " de desconto em duas viagens."]]}
                    "uber-1" {:code "0018f1"
                              :title "Uber"
                              :url "https://www.uber.com/invite/0018f1"
                              :description "💲 Ganhe R$20,00 de desconto em 2 primeiras viagens! ✅"
-                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas! 🎉 "
+                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas!" [:ruby "🎉 " [:rt "ta-da!"]]
                                      [:small "Este cupom pode ser utilizado duas vezes por pessoa, nas suas primeiras viagens. São " [:span.value "R$20,00"] " de desconto em duas viagens."]]}
                    "uber-2" {:code "rafaeln1002ue"
                              :title "Uber"
                              :url "https://www.uber.com/invite/rafaeln1002ue"
                              :description "💲 Ganhe R$20,00 de desconto em 2 primeiras viagens! ✅"
-                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas! 🎉 "
+                             :text [:p "Ganhe " [:span.value "R$10,00"]" de desconto nas suas " [:strong "2 primeiras"] " corridas!" [:ruby "🎉 " [:rt "ta-da!"]]
                                      [:small "Este cupom pode ser utilizado duas vezes por pessoa, nas suas primeiras viagens. São " [:span.value "R$20,00"] " de desconto em duas viagens."]]}
                    "99"     {:code "RODRIGONOSSAL"
                              :title "99"
                              :url "http://ssqt.co/mecBdsK"
                              :description "💲 Ganhe R$20,00 de desconto na primeira corrida 99! ✅"
-                             :text [:p "Ganhe " [:span.value "R$20,00"]" de desconto na sua " [:strong "primeira"] " corrida 99! 🎉 "
+                             :text [:p "Ganhe " [:span.value "R$20,00"]" de desconto na sua " [:strong "primeira"] " corrida 99!" [:ruby "🎉 " [:rt "ta-da!"]]
                                      [:small"Este cupom pode ser utilizado apenas uma vez por pessoa, em sua primeira corrida. Ganhe até " [:span.value "100%"] " de desconto na sua viagem."]]}
                    "99pop"  {:code "RhJemrf3mHV"
                              :title "99POP"
                              :url "https://d.99taxis.mobi/RhJemrf3mHV"
                              :description "💲 Ganhe R$15,00 de desconto na viagem corrida 99POP! ✅"
-                             :text [:p "Ganhe " [:span.value "R$15,00"]" de desconto na sua " [:strong "primeira"] " corrida 99POP! 🎉 "
+                             :text [:p "Ganhe " [:span.value "R$15,00"]" de desconto na sua " [:strong "primeira"] " corrida 99POP!" [:ruby "🎉 " [:rt "ta-da!"]]
                                      [:small"Aceite meu convite e experimente já o 99POP. <br>Ganhe até " [:span.value "100%"] " de desconto na sua viagem."]]}})


minor ex change

minor ex change

--- src/clojure_fabric/user.clj
+++ src/clojure_fabric/user.clj
@@ -382,7 +382,7 @@
             (proto/clj->proto)
             (.toByteArray)))))

-;;(tx-file->config-update "/home/jc/Work/clojure-fabric/resources/fixture/balance-transfer/artifacts/channel/mychannel.tx")
+;;(def cu (tx-file->config-update "/home/jc/Work/clojure-fabric/resources/fixture/balance-transfer/artifacts/channel/mychannel.tx"))
 ;;
 ;; (create-or-update-channel-from-nodes "mychannel"
 ;; (merge (first (core/get-nodes (core/get-user "Org1MSP" "user1") :orderers))


Add prefix-of?

Add prefix-of?

--- src/useful/seq.clj
+++ src/useful/seq.clj
@@ -210,3 +210,12 @@
            (cons items (lazy-recur [x] more))
            (lazy-recur (conj items x) more))
          [items])))))
+
+(defn prefix-of?
+  "Given needle is N elements long, are the first N elements of haystack equal to needle?"
+  [haystack needle]
+  (if-let [[n & ns] (seq needle)]
+    (when-let [[h & hs] (seq haystack)]
+      (and (= h (first needle))
+           (recur hs (rest needle))))
+    true))


Microcosmetics

Microcosmetics

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/layouts/base.clj
+++ src/conexp/layouts/base.clj
@@ -158,8 +158,7 @@
 (defn- verify-labels
   [positions upper-labels lower-labels]
   (check-labels positions upper-labels >=)
-  (check-labels positions lower-labels <=)
-  nil)
+  (check-labels positions lower-labels <=))

 ;;; checked construction


working on diagnostics for ratholes in (defn sentences)

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -150,11 +150,12 @@
               (let [specs (spec-fn)
                     expr (first (->> (lazy-seq specs)
                                      (map (fn [spec]
-                                            (generate spec :model model)))
-                                     (filter #(if (empty? (morph % :show-notes false))
+                                            (let [result (generate spec :model model)]
+                                              (if (empty? (morph result :show-notes false))
                                                 (do (log/info (str "failed to generate with spec: " spec))
-                                                    false)
-                                                true))
+                                                    nil)
+                                                result))))
+                                     (remove nil?)
                                      (take 1)))
                     fo (morph expr :show-notes false)]
                 (let [to-print


working on parameterizing max-total-depth

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -43,18 +43,14 @@
   ((:lookup medium) lexeme))

 (defn generate
-  ([]
-   (let [result (engine/generate :top medium)]
-     (if result
-       (conj {:surface (fo result)}
-             result))))
-  ([spec]
-   (let [result (engine/generate spec medium)]
-     (if result
-       (conj {:surface (fo result)}
-             result))))
-  ([spec model]
-   (let [result (engine/generate spec model)]
+  ([spec
+    & {:keys [max-total-depth model truncate-children]
+       :or {max-total-depth generate/max-total-depth
+            model medium
+            truncate-children true}}]
+   (let [result (engine/generate spec model
+                                 :max-total-depth max-total-depth
+                                 :truncate-children truncate-children)]
      (if result
        (conj {:surface (fo result)}
              result)))))


store ab-tests in state

store ab-tests in state

--- frontend/core.cljs
+++ frontend/core.cljs
@@ -59,8 +59,25 @@
   ws-ch
   (chan))

+(defn get-ab-tests []
+  (let [definitions (aget js/window "ab_test_definitions")
+        overrides (-> js/window
+                      (aget "renderContext")
+                      (aget "abOverrides"))
+        ABTests (-> js/window
+                    (aget "CI")
+                    (aget "ABTests"))
+        ko->js (-> js/window
+                   (aget "ko")
+                   (aget "toJS"))]
+    (-> (new ABTests definitions overrides)
+        (aget "ab_tests")
+        (ko->js)
+        (utils/js->clj-kw))))
+
 (defn app-state []
   (atom (assoc (state/initial-state)
+          :ab-tests (get-ab-tests)
           :current-user (-> js/window
                             (aget "renderContext")
                             (aget "current_user")


Add read/write short and byte for IBuffer protocol.

With corresponding implementation for Netty ByteBuff and
NIO ByteBuffer.

--- src/bytebuf/buffer.clj
+++ src/bytebuf/buffer.clj
@@ -6,10 +6,14 @@

 (defprotocol IBuffer
+  (read-short [_ pos] "Read short integer (16 bits) from buffer.")
+  (write-short [_ pos value] "Write a short integer to the buffer.")
   (read-int [_ pos] "Read an integer (32 bits) from buffer.")
   (write-int [_ pos value] "Write an integer to the buffer.")
   (read-long [_ pos] "Read an long (64 bits) from buffer.")
-  (write-long [_ pos value] "Write an long to the buffer.")
+  (write-long [_ pos value] "Write a long to the buffer.")
+  (read-byte [_ pos] "Read one byte from buffer.")
+  (write-byte [_ pos value] "Write one byte to the buffer.")
   (read-bytes [_ pos size] "Read a byte array.")
   (write-bytes [_ pos size data] "Write byte array."))

@@ -20,14 +24,22 @@

 (extend-protocol IBuffer
   ByteBuffer
+  (read-short [buff pos]
+    (.getShort buff pos))
+  (write-short [buff pos value]
+    (.putShort buff pos value))
   (read-int [buff pos]
     (.getInt buff pos))
+  (write-int [buff pos value]
+    (.putInt buff pos value))
   (read-long [buff pos]
     (.getLong buff pos))
-  (write-int [buff pos value]
-    (.putInt buff pos value))
   (write-long [buff pos value]
     (.putLong buff pos value))
+  (read-byte [buff pos]
+    (.get buff pos))
+  (write-byte [buff pos value]
+    (.put buff pos value))
   (read-bytes [buff pos size]
     (let [tmpbuf (byte-array size)
           oldpos (.position buff)]
@@ -42,14 +54,22 @@
       (.position buff oldpos)))

   ByteBuf
+  (read-short [buff pos]
+    (.getShort buff pos))
+  (write-short [buff pos value]
+    (.setShort buff pos value))
   (read-int [buff pos]
     (.getInt buff pos))
+  (write-int [buff pos value]
+    (.setInt buff pos value))
   (read-long [buff pos]
     (.getLong buff pos))
-  (write-int [buff pos value]
-    (.setInt buff pos value))
   (write-long [buff pos value]
     (.setLong buff pos value))
+  (read-byte [buff pos]
+    (.getByte buff pos))
+  (write-byte [buff pos value]
+    (.setByte buff pos value))
   (read-bytes [buff pos size]
     (let [tmpbuf (byte-array size)]
       (.getBytes buff tmpbuf)


add class directory recursively and debug env

--- src/cake/tasks/jar.clj
+++ src/cake/tasks/jar.clj
@@ -18,6 +18,8 @@
           "Built-By"   (System/getProperty "user.name")
           "Build-Jdk"  (System/getProperty "java.version")
           "Main-Class" (absorb (:main project) (.replaceAll "-" "_"))}))
+
+

 (defn add-file-mappings [task mappings]
   (doseq [mapping mappings]
@@ -42,7 +44,7 @@
          (add-manifest (manifest project))
          (add-zipfileset {:dir (file) :prefix maven :includes "pom.xml"})
          (add-zipfileset {:dir (file) :prefix cake  :includes "*.clj"})
-         (add-fileset    {:dir (file "classes")})
+         (add-fileset    {:dir (file "classes") :includes "**/*.clj"})
          (add-fileset    {:dir (file "src")})
          (add-file-mappings (:jar-files project)))))

@@ -83,7 +85,7 @@
         classes (str web "/classes")]
     (ant War {:dest-file (warfile project)}
          (add-zipfileset {:dir (file "src")       :prefix web     :includes "*web.xml"})
-         (add-zipfileset {:dir (file "classes")   :prefix classes :includes "*.class"})
+         (add-zipfileset {:dir (file "classes")   :prefix classes :includes "**/*.class"})
          (add-zipfileset {:dir (file "resources") :prefix classes :includes "*"})
          (add-fileset    {:dir (file "src" "html")})
          (add-file-mappings (:war-files project)))))


remove extra space

remove extra space

--- src/cake/tasks/jar.clj
+++ src/cake/tasks/jar.clj
@@ -126,7 +126,7 @@
         (map #(File. sshdir %) files)))))

 (defn release-to-clojars [jar]
-  (log "Releasing to clojars: " jar)
+  (log "Releasing to clojars:" jar)
   (ant Scp {:todir "clojars@clojars.org:" :trust true :keyfile (keyfile ["id_rsa" "id_dsa" "identity"])}
        (add-fileset {:file (file "pom.xml")})
        (add-fileset {:file jar})))


don't need wrapping array

don't need wrapping array

--- labs/architecture-examples/om/src/todomvc/app.cljs
+++ labs/architecture-examples/om/src/todomvc/app.cljs
@@ -116,16 +116,16 @@
             chans (dom/get-state owner :chans)]
         (dom/div nil
           (dom/header #js {:id "header"}
-            #js [(dom/h1 nil "todos")
-                  (dom/input
-                    #js {:ref "newField"
-                         :id "new-todo"
-                         :placeholder "What needs to be done?"
-                         :onKeyDown #(handle-new-todo-keydown % app owner)})
-                  (om/render main app [:todos] chans)
-                  (om/render footer app []
-                    {:active active :completed completed
-                     :chans chans :showing :all})]))))))
+            (dom/h1 nil "todos")
+            (dom/input
+              #js {:ref "newField"
+                    :id "new-todo"
+                    :placeholder "What needs to be done?"
+                    :onKeyDown #(handle-new-todo-keydown % app owner)})
+            (om/render main app [:todos] chans)
+            (om/render footer app []
+              {:active active :completed completed
+               :chans chans :showing :all})))))))

 (om/root app-state todo-app (.getElementById js/document "todoapp"))


Take snapshot only when world is stabilized (no pending msgs).

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -43,10 +43,13 @@

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

-(defn render-prog-frame [prog-frame owner]
-  (apply dom/ul nil
-         (map (fn [[k v]] (dom/li nil (str k ":" (count v))))
-              prog-frame)))
+(defn on-prog-frame-focus [ts label prog-frame]
+  (reset! prog-hover prog-frame)
+  (.add gdom/classes (gdom/getElement "prog-container") "hover"))
+
+(defn on-prog-frame-blur []
+  (reset! prog-hover nil)
+  (.remove gdom/classes (gdom/getElement "prog-container") "hover"))

 (defn on-prog-frame-restore [ts label prog-frame]
   ; Time-travel to the past if snapshot is available.
@@ -56,15 +59,15 @@
     ; TODO: This prog-frame deref is strange, as it turned into a
     ; om.core/MapCursor somehow during the event handler rather
     ; an the expected prog-frame dict.
-    (reset! prog-curr @prog-frame)))
-
-(defn on-prog-frame-focus [ts label prog-frame]
-  (reset! prog-hover prog-frame)
-  (.add gdom/classes (gdom/getElement "prog-container") "hover"))
-
-(defn on-prog-frame-blur []
-  (reset! prog-hover nil)
-  (.remove gdom/classes (gdom/getElement "prog-container") "hover"))
+    (reset! prog-curr @prog-frame)
+    (cbfg.world.base/render-client-hist (:reqs @prog-curr))))
+
+; -------------------------------------------------------------------
+
+(defn render-prog-frame [prog-frame owner]
+  (apply dom/ul nil
+         (map (fn [[k v]] (dom/li nil (str k ":" (count v))))
+              prog-frame)))

 (defn render-events [app owner]
   (apply dom/ul nil
@@ -121,7 +124,7 @@
             agw (make-ago-world num-worlds)
             get-agw (fn [] agw)
             event-ch (ago-chan agw)
-            event-run-ch (chan)
+            event-run-ch (ago-chan agw)
             make-timeout-ch (fn [actx delay] (ago-timeout agw delay))
             ; Init the top actx manually to avoid act recursion.
             w [{:gen-id gen-id
@@ -152,7 +155,6 @@
               prog-in (get-el-value "prog-in")
               prog-js (str "with (cbfg.world.t1) {" prog-in "}")
               prog-res (try (js/eval prog-js) (catch js/Object ex ex))]
-          (println :prog-res prog-res)
           (go-loop [num-requests 0 num-responses 0]
                     (let [[v ch] (alts! [req-ch res-ch])
                           ts (+ num-requests num-responses)]
@@ -192,41 +194,48 @@

 (defn wait-done [done]
   (loop []
-    (when (not @done)
+    (when (or (> (.-length cljs.core.async.impl.dispatch/tasks) 0)
+              (not @done))
       (cljs.core.async.impl.dispatch/process-messages)
       (recur))))

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

 (defn kv-server [server-addr & ports]
-  (let [world (:world @prog-base)
-        done (atom false)]
-    (act server-init world
-         (doseq [port ports]
+  (doseq [port ports]
+    (let [world (:world @prog-base)
+          done (atom false)]
+      (act server-init world
            (when-let [listen-result-ch (achan server-init)]
              (aput server-init (:net-listen-ch @prog-base)
                    [server-addr port listen-result-ch])
              (when-let [[accept-ch close-accept-ch]
                         (atake server-init listen-result-ch)]
                (cbfg.world.net/server-accept-loop world accept-ch close-accept-ch)
-               (prog-event world [:kv-server server-addr port]
-                           #(update-in % [:servers server-addr]
-                                       conj port)))))
-         (reset! done true))
-    (wait-done done)))
+           (reset! done true))
+      (wait-done done)
+      (prog-event world [:kv-server server-addr port]
+                  #(update-in % [:servers server-addr]
+                              conj port)))))))

 (defn kv-client [client-addr server-addr server-port]
   (let [world (:world @prog-base)
-        done (atom false)]
-    (act client-init world
-         (let [req-ch (cbfg.world.net/client-loop world (:net-connect-ch @prog-base)
-                                                  server-addr server-port
-                                                  client-addr (:res-ch @prog-base))]
-           (prog-event world [:kv-client client-addr server-addr server-port]
-                       #(assoc-in % [:clients client-addr]
-                                  {:client-addr client-addr
-                                   :server-addr server-addr
-                                   :server-port server-port
-                                   :req-ch req-ch})))
-         (reset! done true))
-    (wait-done done)))
+        ; req-ch (cbfg.world.net/client-loop world (:net-connect-ch @prog-base)
+        ;                                    server-addr server-port
+        ;                                    client-addr (:res-ch @prog-base))
+        req-ch (achan world)
+        ready (atom false)]
+    (act simple-client world
+         (reset! ready true)
+         (loop [n 0]
+           (let [req (atake simple-client req-ch)]
+             (aput simple-client (:res-ch @prog-base)
+                   (assoc req :result :FOO))
+             (recur (inc n)))))
+    (wait-done ready)
+    (prog-event world [:kv-client client-addr server-addr server-port]
+                #(assoc-in % [:clients client-addr]
+                           {:client-addr client-addr
+                            :server-addr server-addr
+                            :server-port server-port
+                            :req-ch req-ch}))))


Renamed on-event-xyz to on-prog-frame-xyz.

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -33,19 +33,19 @@
          (map (fn [[k v]] (dom/li nil (str k ":" (count v))))
               prog-frame)))

-(defn on-event-focus [ts label prog-frame]
+(defn on-prog-frame-focus [ts label prog-frame]
   (reset! prog-hover prog-frame)
   (.add gdom/classes (gdom/getElement "world-container") "hover"))

-(defn on-event-blur []
+(defn on-prog-frame-blur []
   (reset! prog-hover nil)
   (.remove gdom/classes (gdom/getElement "world-container") "hover"))

 (defn render-events [app owner]
   (apply dom/ul nil
          (map (fn [[ts label prog-frame]]
-                (dom/li #js {:onMouseEnter #(on-event-focus ts label prog-frame)
-                             :onMouseLeave #(on-event-blur)}
+                (dom/li #js {:onMouseEnter #(on-prog-frame-focus ts label prog-frame)
+                             :onMouseLeave #(on-prog-frame-blur)}
                         (str ts (apply str label) prog-frame)))
               app)))


First attempt at item-set.

First attempt at item-set.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -11,6 +11,11 @@
             [cbfg.world.base]
             [cbfg.world.net]))

+(defn rev-to-sq [rev]
+  (if (= rev "")
+    nil
+    (js/parseInt rev)))
+
 (defn coll-handler [actx coll-state m]
   (case (:op m)
     "coll-state"
@@ -25,7 +30,15 @@
         [coll-state nil])

     "item-set"
-    [coll-state (assoc m :status :not-implemented-yet)]
+    (do (act item-set actx
+             (aput item-set (:kvs-mgr-ch coll-state)
+                   (assoc m :op :multi-change
+                          :kvs-ident (:kvs-ident coll-state)
+                          :changes [(cbfg.kvs/mutate-entry
+                                     {:key (:key m)
+                                      :val (:val m)
+                                      :sq (rev-to-sq (:rev m))})])))
+        [coll-state nil])

     "item-del"
     [coll-state (assoc m :status :not-implemented-yet)]


If missing cred, then status is not-authenticated.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -29,7 +29,9 @@
         [server-state (assoc (dissoc m :pswd) :status :invalid)])
       [server-state (assoc (dissoc m :pswd) :status :invalid)])
     "realms-list"
-    [server-state (assoc m :result (keys (:realms server-state)))]
+    (if-let [cred (:cred m)]
+      [server-state (assoc m :status :ok :result (keys (:realms server-state)))]
+      [server-state (assoc m :status :not-authenticated)])
     nil))

 (defn rq-authenticate [actx m]


Multiple responses from realms-list.

Multiple responses from realms-list.

--- src/cbfg/world/t2.cljs
+++ src/cbfg/world/t2.cljs
@@ -22,6 +22,11 @@

 (defn fwd-put [actx ch-key m]
   (act fwd-put actx (aput fwd-put (ch-key m) m)))
+
+(defn fwd-put-out [actx ch-key m]
+  (let [out (achan actx)]
+    (act fwd-put-out actx (aput fwd-put-out (ch-key m) (assoc m :res-ch out)))
+    out))

 (defn fwd-req [actx ch-key m]
   (act fwd-req actx (areq fwd-req (ch-key m) m)))
@@ -50,7 +55,14 @@
       [server-state (assoc (dissoc m :pswd) :status :invalid)])
     "realms-list"
     (if-let [{:keys [realm user]} m]
-      [server-state (assoc m :status :ok :result (keys (:realms server-state)))]
+      (do (act-loop realms-list actx [realm-keys (keys (:realms server-state))]
+                    (if-let [realm-key (first realm-keys)]
+                      (do (aput realms-list (:res-ch m)
+                                (assoc m :status :ok :more true :value realm-key))
+                          (recur (rest realm-keys)))
+                      (aput-close realms-list (:res-ch m)
+                                  (assoc m :status :ok))))
+          [server-state nil])
       [server-state (assoc m :status :not-authenticated)])
     nil))

@@ -83,7 +95,7 @@
 (def rq-handlers
   {"authenticate" rq-authenticate
    "lane-state" #(fwd-req %1 :lane-state-ch %2)
-   "realms-list" #(fwd-req %1 :lane-state-ch %2)
+   "realms-list" #(fwd-put-out %1 :lane-state-ch %2)
    "add" cbfg.world.base/example-add
    "sub" cbfg.world.base/example-add
    "count" cbfg.world.base/example-count


removed unused require

removed unused require

--- src/cfpb/qu/loader.clj
+++ src/cfpb/qu/loader.clj
@@ -13,7 +13,6 @@
    [drake.core :as drake]
    [clj-time.core :refer [default-time-zone]]
    [clj-time.format :as time]
-   [lonocloud.synthread :as ->]
    [monger
     [core :as mongo :refer [with-db get-db]]
     [query :as q]


Editing autoencoder

Editing autoencoder

--- src/cortex/impl/layers.cljc
+++ src/cortex/impl/layers.cljc
@@ -390,16 +390,16 @@
       (m/assign! input-tmp input)
       ;; TODO: figure out how to apply noise
       ;; (m/emap! noise-fn input-tmp) ;; input-tmp contains input with noise
-      (let [noise-up (cp/calc up input-tmp)
-            _ (m/assign! output-tmp (cp/output noise-up)) ;; output-tmp contains noisy output from up
-            up (cp/forward up input)
+      (let [up (cp/forward up input)
+            _ (m/assign! output-tmp (cp/output up)) ;; output-tmp contains output from up
             down (cp/forward down output-tmp)
             ]
         (Autoencoder. up down input-tmp output-tmp)))

     (backward [this input output-gradient]
-      (let [down (cp/backward down output-tmp (m/sub (cp/output down) input))
-            _ (m/assign! output-tmp output-gradient)
+      (let [error (m/sub (cp/output down) input)
+            down (cp/backward down output-tmp error)
+            _ (m/assign! output-tmp output-gradient) ;; use output-tmp for gradient
             _ (m/add! output-tmp (cp/input-gradient down)) ;; output-tmp contains gradient
             up (cp/backward up input output-tmp)
             ]


Whitespace

Whitespace

--- library/test/clj/test/doo/core.clj
+++ library/test/clj/test/doo/core.clj
@@ -52,22 +52,9 @@
 (deftest js-env
   (testing "We know which js-envs we support"
     (are [js-env] (not (doo/valid-js-env? js-env))
-         :spidermonkey
-         :browser
-         :browsers
-         :v8
-         :d8
-         :something-else)
+         :spidermonkey :browser :browsers :v8 :d8 :something-else)
     (are [js-env] (doo/valid-js-env? js-env)
-         :rhino
-         :slimer
-         :phantom
-         :node
-         :chrome
-         :safari
-         :firefox
-         :opera
-         :ie))
+         :rhino :slimer :phantom :node :chrome :safari :firefox :opera :ie))
   (testing "We can resolve aliases"
     (are [alias js-envs] (= (doo/resolve-alias alias {}) js-envs)
          :phantom [:phantom]
@@ -76,20 +63,19 @@
          :rhino [:rhino]
          :headless [:slimer :phantom]
          :not-an-alias [])
-    (are [alias js-envs] (= (doo/resolve-alias alias
-                              {:browsers [:chrome :firefox]
-                               :engines [:rhino]
-                               :all [:browsers :engines]})
-                            js-envs)
-         :browsers [:chrome :firefox]
-         :engines [:rhino]
-         :all [:chrome :firefox :rhino]
-         :phantom [:phantom]
-         :slimer [:slimer]
-         :node [:node]
-         :rhino [:rhino]
-         :headless [:slimer :phantom]
-         :not-an-alias []))
+    (let [alias-map {:browsers [:chrome :firefox]
+                     :engines [:rhino]
+                     :all [:browsers :engines]}]
+      (are [alias js-envs] (= (doo/resolve-alias alias alias-map) js-envs)
+           :browsers [:chrome :firefox]
+           :engines [:rhino]
+           :all [:chrome :firefox :rhino]
+           :phantom [:phantom]
+           :slimer [:slimer]
+           :node [:node]
+           :rhino [:rhino]
+           :headless [:slimer :phantom]
+           :not-an-alias [])))
   (testing "we warn against circular dependencies"
     (is (thrown-with-msg? java.lang.Exception #"circular"
           (doo/resolve-alias :all {:browsers [:chrome :engines]


Add reload-observer

Add reload-observer

--- src/main/clojure/lazytest/loader.clj
+++ src/main/clojure/lazytest/loader.clj
@@ -1,9 +1,11 @@
 (ns lazytest.loader
   "Loading namespaces and managing dependencies."
-  (:use [lazytest.dependency :only (graph depend)]
+  (:use [lazytest.dependency :only (graph depend dependents remove-key)]
 	[lazytest.nsdeps :only (deps-from-ns-decl)]
+	[lazytest.reload :only (reload)]
 	[clojure.contrib.find-namespaces :only (find-clojure-sources-in-dir
 						read-file-ns-decl)]
+	[clojure.set :only (union)]
 	[clojure.java.io :only (file)]))

 (defn find-sources
@@ -12,20 +14,47 @@
 	 (every? (fn [d] (instance? java.io.File d)) dirs)]}
   (mapcat find-clojure-sources-in-dir dirs))

-(defn namespace-and-deps-for-file [f]
-  (let [decl (read-file-ns-decl f)]
-    (when decl
-      [(second decl)
-       (deps-from-ns-decl decl)])))
-
 (defn newer-sources [dirs timestamp]
   (filter #(> (.lastModified %) timestamp) (find-sources dirs)))

-(defn newer-namespaces [dirs timestamp]
-  (remove nil? (map namespace-and-deps-for-file (newer-sources dirs timestamp))))
+(defn newer-namespace-decls [dirs timestamp]
+  (remove nil? (map read-file-ns-decl (newer-sources dirs timestamp))))

-(defn dep-graph [names-and-deps]
-  (reduce (fn [g [n deps]] (if (seq deps)
-			     (apply depend g n deps)
-			     g))
-	  (graph) names-and-deps))
+(defn add-to-dep-graph [dep-graph namespace-decls]
+  (reduce (fn [g decl]
+	    (let [nn (second decl)
+		  deps (deps-from-ns-decl decl)]
+	      (if (seq deps)
+		(apply depend g nn deps)
+		g)))
+	  dep-graph namespace-decls))
+
+(defn remove-from-dep-graph [dep-graph new-decls]
+  (apply remove-key dep-graph (map second new-decls)))
+
+(defn update-dependency-graph [dep-graph new-decls]
+  (-> dep-graph
+      (remove-from-dep-graph new-decls)
+      (add-to-dep-graph new-decls)))
+
+(defn affected-namespaces [changed-namespaces old-dependency-graph]
+  (apply union (set changed-namespaces) (map #(dependents old-dependency-graph %)
+					     changed-namespaces)))
+
+(defn reload-observer [dirs initial-timestamp]
+  "Returns a no-arg function which, when called, returns a set of
+  namespaces that need to be reloaded, based on file modification
+  timestamps and the graph of namespace dependencies."
+  {:pre [(integer? initial-timestamp)
+	 (every? (fn [f] (instance? java.io.File f)) dirs)]}
+  (let [timestamp (atom initial-timestamp)
+	dependency-graph (atom (graph))]
+    (fn []
+      (let [then @timestamp
+	    now (System/currentTimeMillis)
+	    new-decls (newer-namespace-decls dirs then)
+	    new-names (map second new-decls)
+	    affected-names (affected-namespaces new-names @dependency-graph)]
+	(reset! timestamp now)
+	(swap! dependency-graph update-dependency-graph new-decls)
+	affected-names))))


Update tools-deps to 1.10.1.478

Update tools-deps to 1.10.1.478

--- src/docker_clojure/core.clj
+++ src/docker_clojure/core.clj
@@ -49,7 +49,7 @@
 (def build-tools
   {"lein"       "2.9.1"
    "boot"       "2.8.3"
-   "tools-deps" "1.10.1.469"})
+   "tools-deps" "1.10.1.478"})

 (def exclusions ; don't build these for whatever reason(s)
   #{{:jdk-version 8


drop conf logging to debug

drop conf logging to debug

--- src/clj/flambo/api.clj
+++ src/clj/flambo/api.clj
@@ -26,10 +26,10 @@

 (defn spark-context
   ([conf]
-     (log/warn "JavaSparkContext" (conf/to-string conf))
+     (log/debug "JavaSparkContext" (conf/to-string conf))
      (JavaSparkContext. conf))
   ([master app-name]
-     (log/warn "JavaSparkContext" master app-name)
+     (log/debug "JavaSparkContext" master app-name)
      (JavaSparkContext. master app-name)))

 (defn local-spark-context [app-name]


Shutdown reader with a hook to make exit saner

--- src/clj/reply/main.clj
+++ src/clj/reply/main.clj
@@ -38,7 +38,6 @@
   "Exits the REPL. This is fairly brutal, does (System/exit 0)."
   []
   (shutdown-agents)
-  (reader.jline/shutdown-reader)
   (println "Bye for now!")
   (System/exit 0))

@@ -92,6 +91,7 @@
 See -main for descriptions."
   [options]
   (try
+    (.addShutdownHook (Runtime/getRuntime) (Thread. #(reader.jline/shutdown-reader)))
     (concurrency/set-signal-handler! "CONT" handle-resume)
     (with-redefs [clojure.core/print-sequential hacks.printing/print-sequential
                   complete/resolve-class hacks.complete/resolve-class


Convert from using reagi to using mult

Convert from using reagi to using mult

--- src/ecregister/posts_ui.clj
+++ src/ecregister/posts_ui.clj
@@ -21,7 +21,7 @@
    :border (line-border :color "#ccc" :thickness 1)
    :minimum-size [400 :by 60]))

-(defn setup-events [form event-stream]
+(defn setup-events [form event-chan create-tap]
   (listen (select form [:#publish-btn])
           :mouse-clicked (fn [e]
                            (when-let [posts (config (select form [:#publish-btn]) :user-data)]
@@ -38,73 +38,69 @@
                                                (dialog :content
                                                        (str "Successfully sent " (:value res) " posts"))))))))))))

-  (let [fa-stream (r/filter #(= :fa-post (:id %)) event-stream)
-        fa-post-stream (r/filter #(map? (:value %)) fa-stream)
-        posts-ready-stream (r/filter #(= :posts-ready (:id %)) event-stream)
-        publish-request-stream (r/filter #(= :publish (:id %)) event-stream)
+  (let [fa-stream (create-tap #(= :fa-post (:id %)))
+        fa-post-stream (create-tap #(and (= :fa-post (:id %)) (map? (:value %))))
+        posts-ready-stream (create-tap #(= :posts-ready (:id %)))
         ]
     ;; setup 'latest post' label and progressbar
-    (r/map (fn [e]
-             ;; TODO use cond
-             (if (= :wait (:value e))
-               (config! (select form [:#faprog]) :indeterminate? true)
-               (let [author (:author (:value e))
-                     title (:title (:value e))]
-                 (config! (select form [:#latest-fa-post :> :#author]) :text author)
-                 (config! (select form [:#latest-fa-post :> :#title]) :text title)
-                 (config! (select form [:#faprog]) :visible? false)
-                 (config! (select form [:#latest-fa-post]) :visible? true)
-                 )))
-           fa-stream)
+    (async/go-loop []
+      (let [e (async/<! fa-stream)]
+        (prn "fa-stream =>" e)
+        ;; TODO use cond
+        (if (= :wait (:value e))
+          (config! (select form [:#faprog]) :indeterminate? true)
+          (let [author (:author (:value e))
+                title (:title (:value e))]
+            (config! (select form [:#latest-fa-post :> :#author]) :text author)
+            (config! (select form [:#latest-fa-post :> :#title]) :text title)
+            (config! (select form [:#faprog]) :visible? false)
+            (config! (select form [:#latest-fa-post]) :visible? true)
+            )))
+      (recur))
     ;; when fa post is retrived, start fetching aw posts
-    (r/map (fn [e]
-             (let [c (async/chan)
-                   content-chan (async/chan)
-                   fa-post (:value e)]
-               ;; FIXME if c will contain :error, dismiss all fetched so far and clear listbox
-               (posts/fetch-unpublished-aw-posts fa-post c)
-               ;; as posts arrive they get accumulated until it is known that there's no error.
-               ;; when :end is received, fetching of actual post content starts
-               (async/go-loop
-                [fetched []]
-                (let [post (async/<! c)]
-                  (cond
-                   (= :error post) (prn "ERROR!") ;; FIXME clear list from all fetched so far, do other cleanup stuff, disable buttons etc
-                   (not= :end post) (do
-                                      (add! (select form [:#aw-posts]) (make-post-widget post))
-                                      (recur (conj fetched post)))
-                   (= :end post) (posts/fetch-aw-posts-content fetched content-chan))))
-               ;; after above function started retrieving full content, let's wait for it to arrive and accumulate posts as they go
-               (async/go-loop
-                [full-posts []]
-                (let [post (async/<! content-chan)]
-                  (cond
-                   (= :error post) (prn "ERROR getting full post!")
-                   (not= :end post) (do
-                                      (prn "got full post fetched" (:title post) "by" (:author post))
-                                      (config! (select form [(str "#" (:id post))]) :border (line-border :color "#8e80e4" :thickness 1))
-                                      (recur (conj full-posts post)))
-                   (= :end post) (do
-                                   (prn "all posts fetched")
-                                   (config! (select form [:#publish-btn]) :enabled? (not (empty? full-posts)))
-                                   (config! (select form [:#publish-btn]) :user-data full-posts)
-                                   ))
-                  )
-                )
-               ))
-           fa-post-stream)
-    (r/map (fn [e]
-
-             )
-           publish-request-stream)
+    (async/go-loop []
+      (let [e (async/<! fa-post-stream)
+            c (async/chan)
+            content-chan (async/chan)
+            fa-post (:value e)]
+        (prn "fa-post-stream =>" e)
+        ;; FIXME if c will contain :error, dismiss all fetched so far and clear listbox
+        (posts/fetch-unpublished-aw-posts fa-post c)
+        ;; as posts arrive they get accumulated until it is known that there's no error.
+        ;; when :end is received, fetching of actual post content starts
+        (async/go-loop
+            [fetched []]
+          (let [post (async/<! c)]
+            (cond
+             (= :error post) (prn "ERROR!") ;; FIXME clear list from all fetched so far, do other cleanup stuff, disable buttons etc
+             (not= :end post) (do
+                                (add! (select form [:#aw-posts]) (make-post-widget post))
+                                (recur (conj fetched post)))
+             (= :end post) (posts/fetch-aw-posts-content fetched content-chan))))
+        ;; after above function started retrieving full content, let's wait for it to arrive and accumulate posts as they go
+        (async/go-loop
+            [full-posts []]
+          (let [post (async/<! content-chan)]
+            (cond
+             (= :error post) (prn "ERROR getting full post!")
+             (not= :end post) (do
+                                (prn "got full post fetched" (:title post) "by" (:author post))
+                                (config! (select form [(str "#" (:id post))]) :border (line-border :color "#8e80e4" :thickness 1))
+                                (recur (conj full-posts post)))
+             (= :end post) (do
+                             (prn "all posts fetched")
+                             (config! (select form [:#publish-btn]) :enabled? (not (empty? full-posts)))
+                             (config! (select form [:#publish-btn]) :user-data full-posts)
+                             )))))
+      (recur))
     ))

-(defn launch-tab [event-stream]
+(defn launch-tab [event-chan]
   (let [c (async/chan)]
-    (r/push! event-stream {:id :fa-post, :value :wait})
+    (async/put! event-chan {:id :fa-post, :value :wait})
     (posts/fetch-latest-fa-post c)
     (async/go
-     (r/push! event-stream {:id :fa-post, :value (async/<! c)}))))
+     (async/put! event-chan {:id :fa-post, :value (async/<! c)}))))

 (defn my-scrollable [& args]
   (let [s (apply scrollable args)]
@@ -123,7 +119,10 @@
                  [(button :id :publish-btn :text "Опубликовать" :enabled? false) "center"]
                  ]
          :constraints ["fill,gap 18px,hidemode 3"])
-        evs (r/events)]
-    (setup-events form evs)
-    (launch-tab evs)
+        ev-chan (async/chan)
+        ev-mult (async/mult ev-chan)
+        tap-creator (fn [predfn] (async/filter< predfn (async/tap ev-mult (async/chan))))
+        ]
+    (setup-events form ev-chan tap-creator)
+    (launch-tab ev-chan)
     form))


Fix arity error

Fix arity error

--- src/ecregister/posts_ui.clj
+++ src/ecregister/posts_ui.clj
@@ -82,7 +82,7 @@

 (defn setup-events [form event-chan map-stream]
   (listen (select form [:#publish-btn])
-          :mouse-clicked #(async/put! event-chan {:id :publish-now :value true}))
+          :mouse-clicked (fn [e] (async/put! event-chan {:id :publish-now :value true})))

   ;; setup 'latest post' label and progressbar
   (map-stream #(= :fa-post (:id %)) (partial update-fa-post-widget form))


added "circle.yml" distinction per Jared's message

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -110,7 +110,7 @@
                " or "
                [:a {:href "https://circleci.com/docs/skip-a-build/"
                     :target "_blank"}
-                "configuring your yml"]
+                "configuring your circle.yml"]
                ")"]
               [:p "NOTE: Showing queued builds can slow down the page."]]
              (button/link {:kind :secondary


Increase the default max buffer size for completions.

--- src/onyx/messaging/acking_daemon.clj
+++ src/onyx/messaging/acking_daemon.clj
@@ -1,5 +1,5 @@
 (ns ^:no-doc onyx.messaging.acking-daemon
-    (:require [clojure.core.async :refer [chan >!! close!]]
+    (:require [clojure.core.async :refer [chan >!! close! sliding-buffer]]
               [com.stuartsierra.component :as component]
               [taoensso.timbre :as timbre]))

@@ -8,8 +8,8 @@

   (start [component]
     (taoensso.timbre/info "Starting Acking Daemon")
-    (let [buffer-size (or (:onyx.messaging/completion-buffer-size opts) 1000)]
-      (assoc component :ack-state (atom {}) :completions-ch (chan buffer-size))))
+    (let [buffer-size (or (:onyx.messaging/completion-buffer-size opts) 50000)]
+      (assoc component :ack-state (atom {}) :completions-ch (chan (sliding-buffer buffer-size)))))

   (stop [component]
     (taoensso.timbre/info "Stopping Acking Daemon")


Revert "Revert acking code - fixes still required."

This reverts commit a3a3922535ec04ecd4bdecb8b6b7ac54c1c4f1d4.

--- src/onyx/messaging/acking_daemon.clj
+++ src/onyx/messaging/acking_daemon.clj
@@ -2,6 +2,7 @@
     (:require [clojure.core.async :refer [chan >!! close! sliding-buffer]]
               [com.stuartsierra.component :as component]
               [onyx.static.default-vals :refer [defaults]]
+              [onyx.types :refer [->Ack]]
               [taoensso.timbre :as timbre]))

 (defrecord AckingDaemon [opts]
@@ -24,18 +25,19 @@
 (defn ack-message [daemon message-id completion-id ack-val]
   (let [rets
         (swap!
-         (:ack-state daemon)
-         (fn [state]
-           (if-let [current-ack-val (get-in state [message-id :ack-val])]
-             (assoc-in state [message-id :ack-val] (bit-xor current-ack-val ack-val))
-             (assoc state message-id {:completion-id completion-id
-                                      :ack-val ack-val}))))]
-
-    (when-let [x (get rets message-id)]
-      (when (zero? (:ack-val x))
-        (swap! (:ack-state daemon) dissoc message-id)
-        (>!! (:completions-ch daemon) {:id message-id
-                                       :peer-id completion-id})))))
+          (:ack-state daemon)
+          (fn [state]
+            (if-let [ack (get state message-id)]
+              (let [updated-ack-val (bit-xor (:ack-val ack) ack-val)]
+                (if (zero? updated-ack-val)
+                  (dissoc state message-id)
+                  (assoc state message-id (assoc ack :ack-val updated-ack-val))))
+              (if (zero? ack-val)
+                state
+                (assoc state message-id (->Ack nil completion-id ack-val))))))]
+    (when (get rets message-id)
+      (>!! (:completions-ch daemon) {:id message-id
+                                     :peer-id completion-id}))))

 (defn gen-message-id
   "Generates a unique ID for a message - acts as the root id."
@@ -56,3 +58,5 @@
         (persistent! coll)
         (recur (inc n)
                (conj! coll (.nextLong rng)))))))
+
+


todos for myself

todos for myself

--- src/cljs/re_form/inputs/select_xhr_impl.cljs
+++ src/cljs/re_form/inputs/select_xhr_impl.cljs
@@ -48,12 +48,13 @@
   (println suggs)
   (swap! state assoc :suggestions suggs))

-(defn- on-change-update [state suggest-fn]
-  (swap! state update :active not)
-  (go (suggest-set-callback state (<! (suggest-fn "head")))))
+(defn- on-change-update [state suggest-fn query]
+  (go (suggest-set-callback state (<! (suggest-fn query)))))

 ;; TODO:
 ;; text input to query
+;; on component-did-mount do r/dom-node and .addEventListener 'input' to track
+;; contenteditable changes
 ;; debounce
 (defn select-xhr-input [_]
   (let [state (r/atom {:active false :suggestions []})]
@@ -65,12 +66,13 @@
                                       (filter #(= (value-fn %) v))
                                       first label-fn)))]
         [:div.re-select-xhr
-         {:on-click #(on-change-update state suggest-fn)}
+         {:on-click #(swap! state update :active not)}
          (if value
            [:span.value
             [:span.value (match-fn value) ]]
            [:span.choose-value
-            (or placeholder "Select...")])
+            {:contentEditable true
+             :on-input #(on-change-update state suggest-fn (.. % -target -value))}])
          (when (:active @state)
            [:div.options
             (for [i (:suggestions @state)] ^{:key (label-fn i)}


Small cosmetic change

Small cosmetic change

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/concept_approximation.clj
+++ src/conexp/contrib/concept_approximation.clj
@@ -23,7 +23,7 @@
             att-objs (ask (str "Which of the objs " new-objs " definitively has the attribute " new-att "? ")
                           #(read-string (str "#{" (read-line) "}"))
                           #(subset? % new-objs)
-                          "Please only enter objects mentioned: ")]
+                          "Please enter only objects mentioned: ")]
         (new-handler (map #(vector % new-att) att-objs))
         [result new-col]))))


[fix] show connecting to peers popup when no peers at startup

previously was only showing up when there was 0 peers after some
disconnection
but sometimes the app starts and user logs in without being
connected to any peer
this means the peers-summary is nil peers count is nil

--- src/status_im/ui/screens/events.cljs
+++ src/status_im/ui/screens/events.cljs
@@ -278,8 +278,8 @@
     :db          (assoc app-db
                         :contacts/contacts {}
                         :network-status network-status
-                        :peers-count peers-count
-                        :peers-summary peers-summary
+                        :peers-count (or peers-count 0)
+                        :peers-summary (or peers-summary [])
                         :status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?)
                         :status-node-started? status-node-started?
                         :network network


[PDOK-1021] generator support voor toplevel feature zonder geometry

--- src/main/clojure/pdok/featured/generator.clj
+++ src/main/clojure/pdok/featured/generator.clj
@@ -30,16 +30,16 @@
 (def attribute-generators [#(random-word 5) random-date random-moment])

 (defn random-new-feature
-  ([collection id validity attributes]
-   (let [base {:_action "new"
-              :_collection collection
-              :_id id
-              :_validity validity
-               :_geometry (random-geometry)}
+  ([collection id validity attributes & {:keys [geometry?] :or {geometry? true}}]
+   (let [feature (transient {:_action "new"
+                          :_collection collection
+                          :_id id
+                          :_validity validity})
+         feature (if geometry? (assoc! feature :_geometry (random-geometry)) feature)
          random-values (map (fn [[key gen]] (vector key (gen))) attributes)
-         feature (reduce (fn [acc val] ( apply assoc acc val)) base random-values)]
+         feature (reduce (fn [acc val] ( apply assoc! acc val)) feature random-values)]

-     feature)))
+     (persistent! feature))))

 (defn update-an-attribute [attributes update-fn exceptions]
   (let [valid-keys (keys (apply dissoc attributes exceptions))
@@ -91,11 +91,11 @@
       )))

 (defn random-json-features [out-stream dataset collection total & args]
-  (let [{:keys [:updates? :nested] :or {:updates? false :nested 0}} args
+  (let [{:keys [updates? nested] :or {updates? false nested 0}} args
         validity (tf/unparse date-time-formatter (local-now))
         attributes (create-attributes 3 nested)
         gens (transient [])
-        gens (conj! gens (fn [id] ( random-new-feature collection id validity attributes)))
+        gens (conj! gens (fn [id] (apply random-new-feature collection id validity attributes args)))
         gens (if updates? (conj! gens (fn [id] (random-change-feature collection id validity attributes))) gens)
         generator (apply juxt (persistent! gens))
         gen-fn #(generator (random-word 10))
@@ -134,3 +134,13 @@
   (doseq [c [3 33 333 3333 33333]]
     (with-open [w (clojure.java.io/writer (str ".test-files/new-features-nested-features-" c ".json"))]
       (random-json-features w "updateset" "collection1" c :nested 2))))
+
+(defn generate-test-files-with-nested-feature-no-top-geometry []
+  (doseq [c [5 50 500 5000 50000]]
+    (with-open [w (clojure.java.io/writer (str ".test-files/new-features-nested-feature-no-top-geometry-" c ".json"))]
+      (random-json-features w "updateset" "collection1" c :nested 1 :geometry? false))))
+
+(defn generate-test-files-with-nested-features-no-top-geometry []
+  (doseq [c [3 33 333 3333 33333]]
+    (with-open [w (clojure.java.io/writer (str ".test-files/new-features-nested-features-no-top-geometry-" c ".json"))]
+      (random-json-features w "updateset" "collection1" c :nested 2 :geometry? false))))


Add missing reference to transfer state fn on drawarea ns.

--- src/uxbox/ui/workspace/drawarea.cljs
+++ src/uxbox/ui/workspace/drawarea.cljs
@@ -45,14 +45,14 @@
   [own]
   (assoc own ::sub (watch-draw-actions)))

+(defn- draw-area-transfer-state
+  [oldown own]
+  (assoc own ::sub (::sub oldown)))
+
 (defn- draw-area-will-unmount
   [own]
   (.close (::sub own))
   (dissoc own ::sub))
-
-(defn- draw-area-transfer-state
-  [oldown own]
-  (assoc own ::sub (::sub oldown)))

 (def draw-area
   (mx/component
@@ -60,6 +60,7 @@
     :name "draw-area"
     :will-mount draw-area-will-mount
     :will-unmount draw-area-will-unmount
+    :transfer-state draw-area-transfer-state
     :mixins [mx/static rum/reactive]}))

 ;; --- Drawing Logic


Refactored world init into callback to keep vis-init clean.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -273,9 +273,8 @@

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

-(defn vis-init [cmd-ch cmd-handlers el-prefix]
-  (let [max-inflight (atom 10)
-        event-delay (atom 0)
+(defn vis-init [world-init-cb el-prefix]
+  (let [event-delay (atom 0)
         event-ch (chan)
         step-ch (chan (dropping-buffer 1))
         last-id (atom 0)
@@ -329,18 +328,7 @@
                  (when (not= vis-next-svg vis-last-svg)
                    (set-el-innerHTML (str el-prefix "-svg") vis-next-svg))
                  (recur vis-last vis-last-positions vis-last-html vis-next-svg)))))
-         (let [in-ch (achan-buf world 100)
-               out-ch (achan-buf world 0)]
-           (ago-loop user-in world [num-ins 0]
-                     (let [cmd (<! cmd-ch)
-                           cmd-handler ((get cmd-handlers (:op cmd)) cmd)]
-                       (aput user-in in-ch cmd-handler)
-                       (recur (inc num-ins))))
-           (ago-loop user-out world [num-outs 0]
-                     (let [result (atake user-out out-ch)]
-                       (set-el-innerHTML (str el-prefix "-output") result)
-                       (recur (inc num-outs))))
-           (make-fenced-pump world in-ch out-ch @max-inflight)))
+         (world-init-cb world))
     (let [toggle-ch (listen (gdom/getElement (str el-prefix "-html")) "click")]
       (go-loop []
         (let [actx-id (no-prefix (.-id (.-target (<! toggle-ch))))]
@@ -370,11 +358,30 @@
    "sub"  (fn [c] {:fence (:fence c) :rq #(example-sub % (:x c) (:y c) (:delay c))})
    "test" (fn [c] {:fence (:fence c) :rq #(cbfg.fence/test %)})})

-(vis-init (map< (fn [ev] {:op (.-id (.-target ev))
-                          :x (js/parseInt (get-el-value "x"))
-                          :y (js/parseInt (get-el-value "y"))
-                          :delay (js/parseInt (get-el-value "delay"))
-                          :fence (= (get-el-value "fence") "1")})
-                (merge (map #(listen (gdom/getElement %) "click")
-                            (keys example-cmd-handlers))))
-          example-cmd-handlers "vis")
+(def example-max-inflight (atom 10))
+
+(defn example-init [el-prefix]
+  (let [cmd-ch (map< (fn [ev] {:op (.-id (.-target ev))
+                               :x (js/parseInt (get-el-value "x"))
+                               :y (js/parseInt (get-el-value "y"))
+                               :delay (js/parseInt (get-el-value "delay"))
+                               :fence (= (get-el-value "fence") "1")})
+                     (merge (map #(listen (gdom/getElement %) "click")
+                                 (keys example-cmd-handlers))))]
+    (vis-init (fn [world]
+                (let [in-ch (achan-buf world 100)
+                      out-ch (achan-buf world 0)]
+                  (ago-loop user-in world [num-ins 0]
+                            (let [cmd (<! cmd-ch)
+                                  cmd-handler ((get example-cmd-handlers (:op cmd)) cmd)]
+                              (aput user-in in-ch cmd-handler)
+                              (recur (inc num-ins))))
+                  (ago-loop user-out world [num-outs 0]
+                            (let [result (atake user-out out-ch)]
+                              (set-el-innerHTML (str el-prefix "-output") result)
+                              (recur (inc num-outs))))
+                  (make-fenced-pump world in-ch out-ch @example-max-inflight)))
+              el-prefix)))
+
+(example-init "vis")
+


homepage is :url not :homepage in lein project.clj

--- src/clojars/db.clj
+++ src/clojars/db.clj
@@ -171,7 +171,7 @@
        :user       account
        :created    (Date.)
        :description (:description jarmap)
-       :homepage   (:homepage jarmap)
+       :homepage   (:url jarmap)
        :authors    (join ", " (map #(.replace % "," "")
                                    (:authors jarmap)))}))))


Removed useless custom contracted forms expansion

--- src/lemma/core.clj
+++ src/lemma/core.clj
@@ -7,23 +7,9 @@
 (defonce core-nlp (delay (StanfordLemmatizer.)))

-(defn expand-contractions [^String text]
-  (-> text
-      (s/replace #"([A-Z][a-z0-9]+)'s"   "$1")
-      (s/replace "let's"   "let")
-      (s/replace "'s"   " is")
-      (s/replace "'em"  " them")
-      (s/replace "'ve"  " have")
-      (s/replace "n't"  " not")
-      (s/replace "'ll"  " will")
-      (s/replace "'re"  " are")
-      (s/replace "'m"   " am")
-      (s/replace "'d"   " would")))
-
-
 (defn lemmatize [^String text]
   (let [^StanfordLemmatizer nlp @core-nlp]
-    (.lemmatize nlp (expand-contractions text))))
+    (.lemmatize nlp text)))

 (defn lemmatize-as-text [^String text]
@@ -38,4 +24,10 @@
        lemmatize-as-text))

-;(lemmatize "men")
+
+;;(lemmatize "That which doesn't kill us makes us stronger. Friedrich Nietzsche")
+;;=> [["that" "which" "do" "not" "kill" "we" "make" "we" "stronger" "."]
+;;    ["Friedrich" "Nietzsche"]]
+
+;;(lemmatize-as-text "That which doesn't kill us makes us stronger. Friedrich Nietzsche")
+;;=> "that which do not kill we make we stronger .\nFriedrich Nietzsche"


Don't automatically meter timers.

Don't automatically meter timers.

The problem with doing this in the Riemann layer is that we don't record the
initial "this thing happened" until we get the timing data, which is *after* the
thing has already been timed and finished.

Imagine something takes 10 seconds to run.  If it starts at 10:55:00 the old
method would record the "foo happened" event at 10:55:10 instead.  For many
things this won't matter, but for some it will, and it's especially important
when trying to determine cause/effect.

The solution is to stop doing it automatically in the Riemann layer and have the
clients manually send a Meter metric when something they're timing starts, then
send the time data later whenever they get around to it.

Looking at the timing percentiles in graphite is still going to be shifted into
the future based on when they end, but at least the *rate* metrics for Timers
will be accurate.

--- riemann.config.clj
+++ riemann.config.clj
@@ -43,9 +43,6 @@
                                          graph))

-      rateify #(with {:metric 1.0}
-                     (meterify))
-
       ; Streams that take events, look at their tags, and send them along to the
       ; appropriate metricizing stream(s).

@@ -59,8 +56,7 @@
                          (histogramify))

       timers #(where (tagged "timer")
-                     (histogramify)
-                     (rateify))
+                     (histogramify))

       ; Gauges are special -- they're super simple.


[#2491] Send to error-tracker internal app errors on auth

--- backend/src/akvo/lumen/auth/api_authorization.clj
+++ backend/src/akvo/lumen/auth/api_authorization.clj
@@ -31,11 +31,13 @@
                                 u/not-authorized)
         :else u/not-authorized))
     (catch Exception e
-      (let [wrap-info (fn [e v] (log/info (.getMessage e)) v)]
+      (let [wrap-error (fn [ex v]
+                        (log/error ex)
+                        (p/track error-tracker ex))]
         (case (-> e ex-data :response-code)
-          503 (wrap-info e u/service-unavailable)
+          503 (wrap-error e u/service-unavailable)
           401 u/not-authorized
-          (wrap-info e u/internal-server-error))))))
+          (wrap-error e u/internal-server-error))))))

 (defn wrap-api-authorization
   [deps]


Add search to sidebar

Add search to sidebar

--- src/discuss/views.cljs
+++ src/discuss/views.cljs
@@ -6,6 +6,7 @@
             [discuss.clipboard :as clipboard]
             [discuss.communication :as com]
             [discuss.extensions]
+            [discuss.find :as find]
             [discuss.history :as history]
             [discuss.integration :as integration]
             [discuss.utils.common :as lib]
@@ -217,4 +218,6 @@
       (dom/div nil
                (vlib/logo #(sidebar/toggle))
                (main-content-view data)
+               (om/build find/form-view {})
+               (om/build find/results-view data)
                (om/build clipboard/view data)))))


Add example for changing record equality for records that are inside set-based data structures.

--- test/active/clojure/record_test.cljc
+++ test/active/clojure/record_test.cljc
@@ -388,24 +388,19 @@
     b first-important-b]
   #?@(:clj
       [clojure.lang.IPersistentMap
-       (equiv [this other] (= (first-important-a this) (first-important-a other)))]
+       (equiv [this other] (= (first-important-a this) (first-important-a other)))
+       clojure.lang.IHashEq
+       (hasheq [this] (clojure.lang.APersistentMap/mapHasheq (-> this (dissoc :b))))]
       :cljs
       [IEquiv
        (-equiv [this other] (= (first-important-a this) (first-important-a other)))]))

 (deftest providing-own-equality-implementation-test
-  #?(:clj
-     (is (= (make-first-important 1 1) (make-first-important 1 1)))
-     :cljs
-     (is (= (make-first-important 1 1) (make-first-important 1 1))))
-  #?(:clj
-     (is (= (make-first-important 1 1) (make-first-important 1 0)))
-     :cljs
-     (is (= (make-first-important 1 1) (make-first-important 1 0))))
-  #?(:clj
-     (is (not (= (make-first-important 1 1) (make-first-important 0 1))))
-     :cljs
-     (is (not (= (make-first-important 1 1) (make-first-important 0 1))))))
+  (is (= (make-first-important 1 1) (make-first-important 1 1)))
+  (is (= (make-first-important 1 1) (make-first-important 1 0)))
+  (is (not (= (make-first-important 1 1) (make-first-important 0 1))))
+  (is (= #{(make-first-important 1 1)} #{(make-first-important 1 0)}))
+  (is (not (= #{(make-first-important 1 1)} #{(make-first-important 0 1)}))))

 ;;; Remove a (default) interface from record
 ;;; (This example, yields the same result as providing `:no-map-protocol? true` in the options map)


Enable re-try when aerospike server restarts.

--- src/forecast/parse.clj
+++ src/forecast/parse.clj
@@ -51,10 +51,14 @@

 (defn infinite-loop
   ([f] (infinite-loop f nil))
-  ([f delay]
+  ([f delay] (infinite-loop f delay nil)
+  ([f delay name]
    (go
      (loop []
-       (f)
+       (try
+         (f)
+         (catch Throwable e
+           (log/errorf e (str "error in infinite-loop " name))))
        (if delay (Thread/sleep delay))
        (when-not @stop-threads? (recur))
        ))))
@@ -71,9 +75,9 @@

 (defn daemon
   []
-  (infinite-loop process-new-ips 1000)
-  (infinite-loop process-new-locations 1000)
-  (infinite-loop print-metrics 15000)
+  (infinite-loop #'process-new-ips 1000 "process-new-ips")
+  (infinite-loop #'process-new-locations 1000 "process-new-location")
+  (infinite-loop #'print-metrics 15000 "print-metrics")
   (sleep-forever))

 (defn get-histogram


Minor naming improvements on promise abstraction.

--- src/futura/promise.clj
+++ src/futura/promise.clj
@@ -42,7 +42,8 @@
 (defprotocol IPromise
   "A promise abstraction."
   (^:private rejected* [_] "Returns true if a promise is rejected.")
-  (^:private fulfilled* [_] "Returns true if a promise is fulfiled.")
+  (^:private resolved* [_] "Returns true if a promise is resolved.")
+  (^:private done* [_] "Retutns true if a promise is already done.")
   (^:private pending* [_] "Retutns true if a promise is stil pending.")
   (^:private then* [_ callback] "Chain a promise.")
   (^:private error* [_ callback] "Catch a error in a promise."))
@@ -124,10 +125,13 @@
   (rejected* [_]
     (.isCompletedExceptionally cf))

-  (fulfilled* [_]
+  (resolved* [_]
     (and (not (.isCompletedExceptionally cf))
          (not (.isCancelled cf))
          (.isDone cf)))
+
+  (done* [_]
+    (.isDone cf))

   (pending* [_]
     (not (.isDone cf)))
@@ -222,17 +226,23 @@
   [p]
   (instance? Promise p))

-(defn fulfilled?
+(defn done?
   "Returns true if promise `p` is
   completed successfully."
   [p]
-  (fulfilled* p))
+  (done* p))

 (defn rejected?
   "Returns true if promise `p` is
   completed exceptionally."
   [p]
   (rejected* p))
+
+(defn resolved?
+  "Returns true if promise `p` is
+  already successfuly resolved."
+  [p]
+  (resolved* p))

 (defn pending?
   "Returns true if promise `p` is


added tests for stateless wrapper functions

--- moebius/test/moebius/core_test.clj
+++ moebius/test/moebius/core_test.clj
@@ -1,6 +1,42 @@
 (ns moebius.core-test
   (:require [moebius.core :refer :all])
   (:use midje.sweet))
+
+
+(facts "about `stateless`: stateless normalizes a function which
+        doesn't use state into a stateful one. In practice it
+        shouldn't alter the state in any way."
+
+       ;; stateless turns a function which takes only one param
+       ;; into one that takes two [state event] and applies the
+       ;; function to the event and return the state unchanged.
+       ((stateless identity) 1 {:a 1}) => [1 {:a 1}]
+
+       ((stateless #(assoc % :b 1)) 1 {:a 1}) => [1 {:a 1 :b 1}]
+
+       ((stateless #(assoc % :b 1)) nil {:a 1}) => [nil {:a 1 :b 1}]
+
+       ((stateless (constantly nil)) 1 {:a 1}) => [1 nil]
+       )
+
+
+
+(facts "about `stateless-pred`: stateless-pred normalizes a predicate
+        function which doesn't use state into a stateful one. In
+        practice it shouldn't alter the state in any way."
+
+       ;; stateless-pred turns a function which takes only one param
+       ;; into one that takes two [state event] and applies the
+       ;; function to the event
+       ((stateless-pred :a) 1 {:a 2}) => 2
+
+       ((stateless-pred :b) 1 {:a 1}) => nil
+
+       ((stateless-pred #(= 1 (:a %))) nil {:a 1}) => true
+
+       ((stateless-pred #(= 2 (:a %))) nil {:a 1}) => false
+
+       )

 (facts "about stateless `enricher`: results are normalised for the `cycler`"


master: Clean up and bug fixes from testing.

--- src/gmail_clj/core.clj
+++ src/gmail_clj/core.clj
@@ -100,7 +100,7 @@
                                       walk/keywordize-keys)]
                         (if (:error body)
                             (throw (Exception. (if (:message body) (:message body)
-                                                                   "Error or blank response from Beats Platform.")))
+                                                                   "Error or blank response from GMail.")))
                             body))
                 :raw @response
                 :url {:url (get-in @response [:opts :url])})
@@ -173,7 +173,7 @@
   [msg]
   (let [session (Session/getDefaultInstance (java.util.Properties.))]
     (doto (MimeMessage. session)
-          (.setFrom (address (:from msg)))
+          (.setFrom (address "me@gmail.com"))
           (.addRecipient Message$RecipientType/TO (address (:to msg)))
           ;(.addRecipient Message$RecipientType/CC (address (:cc msg)))
           ;(.addRecipient Message$RecipientType/BCC (address (:bcc msg)))
@@ -190,7 +190,7 @@
                 (.writeTo message os)
                 (.toByteArray os))
         b64 (str->b64 bytes)]
-    (api-request :post-json "/users/me/drafts" {:message {:raw (URLEncoder/encode b64 "UTF-8")}} :auth (get-token) :resp :raw)))
+    (api-request :post-json "/users/me/drafts" {:message {:raw (URLEncoder/encode b64 "UTF-8")}} :auth (get-token))))

 (defn draft-delete
   "Delete a draft by message-id."
@@ -223,8 +223,8 @@

 (defn history-list
   "Pull a list of items from a user's history."
-  [& {:keys [maxResults pageToken labelId startHistoryId]
-      :or {maxResults 10}}]
+  [startHistoryId & {:keys [maxResults pageToken labelId ]
+                     :or {maxResults 10}}]
   (let [params {:maxResults maxResults
                 :pageToken pageToken
                 :startHistoryId startHistoryId
@@ -295,14 +295,14 @@
   (api-request :get (str "/users/me/messages/" message-id) {:format (name format)} :auth (get-token)))

 (defn message-send
-  "Sends an email to a specified user."
+  "Sends an email to a specified user. Takse MIME obj or map with :to :subject :body"
   [message & {:keys [thread-id]}]
   (let [message (if (map? message) (map->mime message) message)
         bytes (with-open [os (java.io.ByteArrayOutputStream.)]
                 (.writeTo message os)
                 (.toByteArray os))
         b64 (str->b64 bytes)]
-    (api-request :post-json "/users/me/messages/send" {:raw (URLEncoder/encode b64 "UTF-8")} :auth (get-token) :resp :raw)))
+    (api-request :post-json "/users/me/messages/send" {:raw b64} :auth (get-token))))

 ; Users.threads


fixed forward declaration

fixed forward declaration

--- src/mapfs/core.clj
+++ src/mapfs/core.clj
@@ -78,6 +78,8 @@
        :. %1
        (conj %1 %2))
     @CURRENT_DIR path))
+
+(declare resolve-single-path)

 (defn- resolve-path
   [parts]


Improve the volume split ui

Improve the volume split ui

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -215,23 +215,39 @@

 (defn production-split-form [request id]
   (let [user (friend/current-authentication request)
-        production (prod/find id)]
+        production (prod/find id)] ; FIXME: the find could return nil
     (layout/common
      user
      [:h1 "Split Production"]
      (form/form-to
+      {:class "form-horizontal"}
       [:post (str "/production/" id "/split")]
       (anti-forgery-field)
       [:div.form-group
-       (form/label :volumes "Volumes:")
-       (form/drop-down {:class "form-control"} :volumes [1 2 3 4 5 6 7 8])]
-      [:div.form-group
-       (form/label :sample-rate "Sample Rate:")
-       (form/drop-down {:class "form-control"} :sample-rate [11025 22050 44100 48000])]
-      [:div.form-group
-       (form/label :bitrate "Bitrate:")
-       (form/drop-down {:class "form-control"} :bitrate [32 48 56 64 128])]
-      (form/submit-button {:class "btn btn-default"} "Encode")))))
+       (form/label {:class "col-sm-2 control-label"} :volumes "Volumes:")
+       [:div.col-sm-2
+        (form/drop-down {:class "form-control"} :volumes [1 2 3 4 5 6 7 8] 2)]]
+      [:div.form-group
+       (form/label {:class "col-sm-2 control-label"} :sample-rate "Sample Rate:")
+       [:div.col-sm-2
+        (form/drop-down {:class "form-control"} :sample-rate [11025 22050 44100 48000] 22050)]]
+      ;; [:div.form-group
+      ;;  (form/label {:class "col-sm-2 control-label"} :sample-rate "Sample Rate:")
+      ;;  [:label.radio-inline
+      ;;   (form/radio-button :sample-rate false 11025) 11025]
+      ;;  [:label.radio-inline
+      ;;   (form/radio-button :sample-rate true 22050) 22050]
+      ;;  [:label.radio-inline
+      ;;   (form/radio-button :sample-rate false 44100) 44100]
+      ;;  [:label.radio-inline
+      ;;   (form/radio-button :sample-rate false 48000) 48000]]
+      [:div.form-group
+       (form/label {:class "col-sm-2 control-label"} :bitrate "Bitrate:")
+       [:div.col-sm-2
+        (form/drop-down {:class "form-control"} :bitrate [32 48 56 64 128] 56)]]
+      [:div.form-group
+       [:div {:class "col-sm-offset-2 col-sm-2"}
+       (form/submit-button {:class "btn btn-default"} "Encode")]]))))

 (defn production-split [id volumes sample-rate bitrate]
   (let [production (prod/find id)]


cleanup

cleanup

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/communicator.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/communicator.cljs
@@ -78,18 +78,3 @@
 (go-loop [] (let [tid (<! c/tweet-missing-chan)]
               (chsk-send! [:cmd/missing {:id_str tid :uid (:uid @chsk-state)}])
               (recur)))
-
-(defn ^:export send-state
-  "helper function to send state to server (where it can be pretty printed for debugging)"
-  []
-  (chsk-send! [:some/state {:by-followers (into {} (:by-followers @state/app))
-                            :by-retweets  (into {} (:by-followers @state/app))
-                            :by-favorites  (into {} (:by-favorites @state/app))
-                            :by-rt-since-startup  (into {} (:by-rt-since-startup @state/app))
-                            :by-reach  (into {} (:by-reach @state/app))
-                            :by-id  (into {} (:by-id @state/app))}]))
-
-(defn send-ds
-  "helper function to send state to server (where it can be pretty printed for debugging)"
-  [ds]
-  (chsk-send! [:some/state ds]))


update channels sooner

update channels sooner

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

--- plugins/SlideExplorer2/src/slide_explorer/main.clj
+++ plugins/SlideExplorer2/src/slide_explorer/main.clj
@@ -172,12 +172,13 @@
                               {:nx 0 :ny 0 :nz (get-in image [:tags "SliceIndex"]) :nt 0
                                :nc (get-in image [:tags "Channel"])}
                               (image :proc)))
+    (swap! ss assoc :channels (initial-lut-objects first-seq))
     (doseq [image (acquire-at (inverse-transform (Point. 0 -512) affine-stage-to-pixel))]
       (add-to-available-tiles available-tiles
                               {:nx 0 :ny -1 :nz (get-in image [:tags "SliceIndex"]) :nt 0
                                :nc (get-in image [:tags "Channel"])}
                               (image :proc)))
-    (swap! ss assoc :channels (initial-lut-objects first-seq))))
+    ))


convert collision tests to use macro

convert collision tests to use macro

--- test/voke/system/collision_test.cljs
+++ test/voke/system/collision_test.cljs
@@ -19,156 +19,110 @@
                                   :center #:geometry{:x x
                                                      :y y}}}))

-(defn prepare-for-collision-test [entities collision-events-atom]
-  ; can't *completely* set up the state of the world, because with-redefs is a macro
-  ; if we wanted to really DRY up these tests, we'd have to write a clj-land macro.
-  ; putting that off for now.
-  (doseq [entity entities]
-    (collision-util/-track-entity entity))
-
-  (events/subscribe-to-event :contact
-                             (fn [event]
-                               (swap! collision-events-atom conj event)))
-
-  (assoc blank-game-state
-         :game-state/entities
-         (into {}
-               (map (juxt :entity/id identity) entities))))
-
 (deftest two-entities-moving-into-each-other-diagonally
   (let [entity-1 (make-entity 1 100 100)
         entity-2 (make-entity 2 115 115)]
     (with-collision-env [entity-1 entity-2] collision-events apply-movement-calls game-state
-                        ; Two 10x10 entities, moving diagonally into the same spot.
-                        (system/attempt-to-move! entity-1
-                                                 #:geometry{:x 105 :y 105}
-                                                 #:geometry{:x 5 :y 5}
-                                                 (vals (game-state :game-state/entities)))
-                        (system/attempt-to-move! entity-2
-                                                 #:geometry{:x 105 :y 105}
-                                                 #:geometry{:x 5 :y 5}
-                                                 (vals (game-state :game-state/entities)))
+      ; Two 10x10 entities, moving diagonally into the same spot.
+      (system/attempt-to-move! entity-1
+                               #:geometry{:x 105 :y 105}
+                               #:geometry{:x 5 :y 5}
+                               (vals (game-state :game-state/entities)))
+      (system/attempt-to-move! entity-2
+                               #:geometry{:x 105 :y 105}
+                               #:geometry{:x 5 :y 5}
+                               (vals (game-state :game-state/entities)))

-                        (testing "when two entities try to move into the same space, only one collision event should be fired"
-                          (is (= @collision-events
-                                 [{:event/type :contact
-                                   :entities   [entity-1 entity-2]}])))
+      (testing "when two entities try to move into the same space, only one collision event should be fired"
+        (is (= @collision-events
+               [{:event/type :contact
+                 :entities   [entity-1 entity-2]}])))

-                        (testing "diagonal collision resolution works correctly on corners"
-                          (is (= @apply-movement-calls
-                                 [[entity-1 #:geometry{:x 104.9 :y 104.9} #:geometry{:x 0 :y 0}]
-                                  [entity-2 #:geometry{:x 99.9 :y 99.9} #:geometry{:x 0 :y 0}]]))))))
+      (testing "diagonal collision resolution works correctly on corners"
+        (is (= @apply-movement-calls
+               [[entity-1 #:geometry{:x 104.9 :y 104.9} #:geometry{:x 0 :y 0}]
+                [entity-2 #:geometry{:x 99.9 :y 99.9} #:geometry{:x 0 :y 0}]]))))))

-#_(deftest two-entities-moving-into-each-other-diagonally
-    (let [entity-1 (make-entity 1 100 100)
-          entity-2 (make-entity 2 115 115)
-          collision-events (atom [])
-          apply-movement-calls (atom [])
-          game-state (prepare-for-collision-test [entity-1 entity-2] collision-events)]

-      )

-    (js/Collision.resetState))

 (deftest one-entity-moving-against-another
   (let [entity-1 (make-entity 1 100 100)
-        entity-2 (make-entity 2 111 100)
-        collision-events (atom [])
-        apply-movement-calls (atom [])
-        game-state (prepare-for-collision-test [entity-1 entity-2] collision-events)]
-
-    (with-redefs [state/contacts-fired (atom #{})
-                  collision-util/apply-movement (fn [& args]
-                                                  (swap! apply-movement-calls conj args))]
+        entity-2 (make-entity 2 111 100)]
+    (with-collision-env [entity-1 entity-2] collision-events apply-movement-calls game-state
       (system/attempt-to-move! entity-1
                                #:geometry{:x 105 :y 103}
                                #:geometry{:x 5 :y 3}
-                               (vals (game-state :game-state/entities))))
+                               (vals (game-state :game-state/entities)))

-    (is (= @collision-events
-           [{:event/type :contact
-             :entities   [entity-1 entity-2]}]))
+      (is (= @collision-events
+             [{:event/type :contact
+               :entities   [entity-1 entity-2]}]))

-    (testing "two entities next to each other, the left one moving up+right; it should be able to
+      (testing "two entities next to each other, the left one moving up+right; it should be able to
       move all the way up and a little bit to the right"
-      (is (= @apply-movement-calls
-             [[entity-1 #:geometry{:x 100.99 :y 103} #:geometry{:x 0 :y 3}]]))))
-
-  (js/Collision.resetState))
+        (is (= @apply-movement-calls
+               [[entity-1 #:geometry{:x 100.99 :y 103} #:geometry{:x 0 :y 3}]]))))))

 (deftest projectiles-and-collides-with
   (let [entity-1 (make-entity 1 100 100 #:collision{:type :projectile :collides-with #{:obstacle} :destroyed-on-contact true})
         entity-2 (make-entity 2 111 100 #:collision{:type :projectile :collides-with #{:obstacle} :destroyed-on-contact true})
         entity-3 (make-entity 3 122 100 #:collision{:type :obstacle})
-        collision-events (atom [])
-        apply-movement-calls (atom [])
-        remove-entity-calls (atom [])
-        game-state (prepare-for-collision-test [entity-1 entity-2 entity-3] collision-events)]
+        remove-entity-calls (atom [])]

-    (with-redefs [state/contacts-fired (atom #{})
-                  collision-util/apply-movement (fn [& args]
-                                                  (swap! apply-movement-calls conj args))
-                  collision-util/remove-entity! (fn [& args]
-                                                  (swap! remove-entity-calls conj args))]
-      (system/attempt-to-move! entity-1
-                               #:geometry{:x 105 :y 100}
-                               #:geometry{:x 5 :y 0}
-                               (vals (game-state :game-state/entities)))
+    (with-collision-env [entity-1 entity-2 entity-3] collision-events apply-movement-calls game-state
+      (with-redefs [collision-util/remove-entity! (fn [& args]
+                                                    (swap! remove-entity-calls conj args))]
+        (system/attempt-to-move! entity-1
+                                 #:geometry{:x 105 :y 100}
+                                 #:geometry{:x 5 :y 0}
+                                 (vals (game-state :game-state/entities)))

-      ; entities 1 and 2 are projectiles and shouldn't collide with one another
-      (is (= @collision-events []))
-      (is (= @remove-entity-calls []))
-      (is (= @apply-movement-calls
-             [[entity-1 #:geometry{:x 105 :y 100} #:geometry{:x 5 :y 0}]]))
+        ; entities 1 and 2 are projectiles and shouldn't collide with one another
+        (is (= @collision-events []))
+        (is (= @remove-entity-calls []))
+        (is (= @apply-movement-calls
+               [[entity-1 #:geometry{:x 105 :y 100} #:geometry{:x 5 :y 0}]]))

-      (reset! apply-movement-calls [])
+        (reset! apply-movement-calls [])

-      ; entity 3 is a wall, though, and so entity 1 should collide with it and be destroyed
-      (system/attempt-to-move! entity-1
-                               #:geometry{:x 120 :y 100}
-                               #:geometry{:x 15 :y 0}
-                               (vals (game-state :game-state/entities)))
+        ; entity 3 is a wall, though, and so entity 1 should collide with it and be destroyed
+        (system/attempt-to-move! entity-1
+                                 #:geometry{:x 120 :y 100}
+                                 #:geometry{:x 15 :y 0}
+                                 (vals (game-state :game-state/entities)))

-      (is (= @collision-events
-             [{:event/type :contact
-               :entities   [entity-1 entity-3]}]))
-      (is (= @apply-movement-calls []))
-      (is (= @remove-entity-calls
-             [[entity-1]]))))
-
-  (js/Collision.resetState))
+        (is (= @collision-events
+               [{:event/type :contact
+                 :entities   [entity-1 entity-3]}]))
+        (is (= @apply-movement-calls []))
+        (is (= @remove-entity-calls
+               [[entity-1]]))))))

 (deftest an-entity-moving-into-many-entities
   (let [entity-1 (make-entity 1 100 100)
         entity-2 (make-entity 2 111 101)
         entity-3 (make-entity 3 112 102)
         entity-4 (make-entity 4 111 102)
-        entity-5 (make-entity 5 111 100)
-        collision-events (atom [])
-        apply-movement-calls (atom [])
-        game-state (prepare-for-collision-test [entity-1 entity-2 entity-3 entity-4 entity-5] collision-events)]
+        entity-5 (make-entity 5 111 100)]
+    (with-collision-env [entity-1 entity-2 entity-3 entity-4 entity-5] collision-events apply-movement-calls game-state

-    (with-redefs [state/contacts-fired (atom #{})
-                  collision-util/apply-movement (fn [& args]
-                                                  (swap! apply-movement-calls conj args))]
       (system/attempt-to-move! entity-1
                                #:geometry{:x 105 :y 103}
                                #:geometry{:x 5 :y 3}
-                               (vals (game-state :game-state/entities))))
+                               (vals (game-state :game-state/entities)))

-    (is (= @collision-events
-           [{:event/type :contact
-             :entities   [entity-1 entity-2]}
-            {:event/type :contact
-             :entities   [entity-1 entity-3]}
-            {:event/type :contact
-             :entities   [entity-1 entity-4]}
-            {:event/type :contact
-             :entities   [entity-1 entity-5]}]))
+      (is (= @collision-events
+             [{:event/type :contact
+               :entities   [entity-1 entity-2]}
+              {:event/type :contact
+               :entities   [entity-1 entity-3]}
+              {:event/type :contact
+               :entities   [entity-1 entity-4]}
+              {:event/type :contact
+               :entities   [entity-1 entity-5]}]))

-    (testing "entity-1 should be moved so it's right up against entity-5"
-      (is (= @apply-movement-calls
-             [[entity-1 #:geometry{:x 100.99 :y 103} #:geometry{:x 0 :y 3}]]))))
-
-  (js/Collision.resetState))
+      (testing "entity-1 should be moved so it's right up against entity-5"
+        (is (= @apply-movement-calls
+               [[entity-1 #:geometry{:x 100.99 :y 103} #:geometry{:x 0 :y 3}]]))))))


Add input builder fn for use by plugins

Add input builder fn for use by plugins

--- src/onyx/types.clj
+++ src/onyx/types.clj
@@ -1,6 +1,9 @@
 (ns onyx.types)

 (defrecord Leaf [message id acker-id completion-id ack-val hash-group route])
+
+(defn input [id message]
+  (->Leaf message id nil nil nil nil nil))

 (defrecord Route [flow exclusions post-transformation action])


updates to fix that hive images was not notified when the hive-manager table changed.

--- src/hivewing_core/hive_manager.clj
+++ src/hivewing_core/hive_manager.clj
@@ -2,6 +2,7 @@
   (:require [hivewing-core.configuration :refer [sql-db]]
             [hivewing-core.core :refer [ensure-uuid]]
             [hivewing-core.public-key-notification :as pkn]
+            [hivewing-core.hive-image-notification :as hin]
             [clojure.java.jdbc :as jdbc]))

 (defn hive-manager-create
@@ -13,6 +14,7 @@
         parameters (into {:hive_uuid clean-hive :beekeeper_uuid clean-bk } roles-hsh)
         res (first (jdbc/insert! sql-db :hive_managers parameters))
         ]
+      (hin/hive-images-notification-send-beekeeper-update-message beekeeper-uuid)
       (pkn/public-keys-notify-of-hive-change hive-uuid)
       res
     ))
@@ -37,8 +39,10 @@
   "Delete a hive manager"
   [hive-manager-uuid]
   (let [hmu (ensure-uuid hive-manager-uuid)
-        hive-uuid (:hive_uuid (first (jdbc/query sql-db ["SELECT hive_uuid FROM hive_managers WHERE uuid = ?" (ensure-uuid hive-manager-uuid)])))
+        { hive-uuid :hive_uuid
+          beekeeper-uuid :beekeeper_uuid } (first (jdbc/query sql-db ["SELECT * FROM hive_managers WHERE uuid = ?" (ensure-uuid hive-manager-uuid)]))
         res (jdbc/delete! sql-db :hive_managers ["uuid = ?" hmu])
         ]
+      (hin/hive-images-notification-send-beekeeper-update-message beekeeper-uuid)
       (pkn/public-keys-notify-of-hive-change hive-uuid)
       res))


Add schema checks for :trigger/period and :trigger/threshold

--- src/onyx/schema.clj
+++ src/onyx/schema.clj
@@ -172,6 +172,12 @@
 (def TriggerRefinement
   (s/enum :accumulating :discarding))

+(def TriggerPeriod
+  (s/enum :milliseconds :seconds :minutes :hours :days))
+
+(def TriggerThreshold
+  (s/enum :elements))
+
 (def Trigger
   {:trigger/window-id s/Keyword
    :trigger/refinement TriggerRefinement
@@ -179,6 +185,10 @@
    :trigger/sync s/Keyword
    (s/optional-key :trigger/fire-all-extents?) s/Bool
    (s/optional-key :trigger/doc) s/Str
+   (s/optional-key :trigger/period) [(s/one PosInt "trigger period")
+                                     (s/one TriggerPeriod "threshold type")]
+   (s/optional-key :trigger/threshold) [(s/one PosInt "number elements")
+                                        (s/one TriggerThreshold "threshold type")]
    s/Keyword s/Any})

 (def StateAggregationCall


Rename function now that we aren't just doing html files

--- src/afrey/boot_asset_fingerprint.clj
+++ src/afrey/boot_asset_fingerprint.clj
@@ -5,7 +5,7 @@
             [clojure.java.io :as io]
             [afrey.boot-asset-fingerprint.impl :as impl]))

-(defn- fileset->html-files [fileset extensions]
+(defn- filter-by-extns [fileset extensions]
   (->> fileset
     (core/output-files)
     (core/by-ext extensions)))
@@ -31,12 +31,12 @@
     (core/with-pre-wrap fileset
       (core/empty-dir! tmp-dir)
       (let [diff        (core/fileset-diff @prev fileset)
-            html-files  (fileset->html-files diff extensions)
+            files       (filter-by-extns diff extensions)
             file-hashes (into {}
                           (map (juxt :path :hash))
                           (core/output-files fileset))]
         (reset! prev fileset)
-        (doseq [file html-files
+        (doseq [file files
                 :let [path (:path file)
                       input-path (-> file core/tmp-file .getPath)
                       output-path (-> (io/file tmp-dir path) .getPath)


add a better error message for insufficient funds

--- src/block_chain/message_handlers.clj
+++ src/block_chain/message_handlers.clj
@@ -76,13 +76,19 @@
    could use this endpoint to generate transactions that they could then sign
    and return to the full node for inclusion in the block chain."
   [msg sock-info]
-  {:message "unsigned_transaction"
-   :payload (txn/unsigned-payment
-             (:from-address (:payload msg))
-             (:to-address (:payload msg))
-             (:amount (:payload msg))
-             @db/db
-             (or (:fee (:payload msg)) 0))})
+  (let [p (:payload msg)
+        balance (q/balance (:from-address p)
+                           @db/db)]
+    (if (>= balance (:amount p))
+      {:message "unsigned_transaction"
+       :payload (txn/unsigned-payment
+                 (:from-address (:payload msg))
+                 (:to-address (:payload msg))
+                 (:amount (:payload msg))
+                 @db/db
+                 (or (:fee (:payload msg)) 0))}
+      {:message "insufficient_balance"
+       :payload (str "Found " balance " to fund " (:amount p))})))

 (defn submit-transaction [msg sock-info]
   (let [txn (:payload msg)


Add google site verification tag

Add google site verification tag

--- src/clj/clojuredocs/pages/common.clj
+++ src/clj/clojuredocs/pages/common.clj
@@ -140,6 +140,7 @@
     [:meta {:name "apple-mobile-web-app-capable" :content "yes"}]
     [:meta {:name "apple-mobile-web-app-status-bar-style" :content "default"}]
     [:meta {:name "apple-mobile-web-app-title" :content "ClojureDocs"}]
+    [:meta {:name "google-site-verification" :content "XjzqkjEPtcgtLjhnqAvtnVSeveEccs-O_unFGGlbk4g"}]
     [:title (or title "Community-Powered Clojure Documentation and Examples | ClojureDocs")]
     font-awesome-link
     bootstrap-link


Fix multiline examples coloring

Fix multiline examples coloring

--- src/cljs/cljs_repl_web/handlers.cljs
+++ src/cljs/cljs_repl_web/handlers.cljs
@@ -129,6 +129,7 @@
      ;; hack after hack: the set-prompt-text! function does not trigger
      ;; the syntax highlight, so we need to invoke it manually
      (highlight/highlight-prompt-line! (.-$prompt_left console) (atom "") )
+     (highlight/highlight-prompt-lines! (.-$prompt_before console))
      (console/focus-console! console)
      (assoc-in db [:consoles (name console-key) :interactive-examples] (rest lines)))))


Set IMac protocol methods as public.

Set IMac protocol methods as public.

--- src/clojure/buddy/core/mac/proto.clj
+++ src/clojure/buddy/core/mac/proto.clj
@@ -17,8 +17,9 @@
   low level protocol definition.")

 (defprotocol IMac
-  (^:private update [_ bytes offset length] "Update bytes in a current instance.")
-  (^:private end [_] "Return the computed mac and reset the engine."))
+  "Mac engine common interface definition."
+  (update [_ bytes offset length] "Update bytes in a current instance.")
+  (end [_] "Return the computed mac and reset the engine."))

 (defn update!
   ([engine input]


Fix docstrings code style son shmac ns.

Fix docstrings code style son shmac ns.

--- src/clojure/buddy/core/mac/shmac.clj
+++ src/clojure/buddy/core/mac/shmac.clj
@@ -33,15 +33,15 @@

 (defn shmac
   "Generic function that exposes a high level
-interface for salted variant of keyed-hash message
-authentication code algorithm."
+  interface for salted variant of keyed-hash message
+  authentication code algorithm."
   [input key salt ^Keyword alg]
   (make-salted-hmac input key salt alg))

 (defn verify
   "Generic function that exposes a high level
-interface for salted variant of keyed-hash message
-authentication code verification algorithm."
+  interface for salted variant of keyed-hash message
+  authentication code verification algorithm."
   [input ^bytes signature key salt ^Keyword alg]
   (verify-salted-hmac input signature key salt alg))


Log as reducer vs combiner.

Log as reducer vs combiner.

--- src/clojure/parkour/remote/basic.clj
+++ src/clojure/parkour/remote/basic.clj
@@ -53,7 +53,7 @@
         conf (doto (conf/ig context)
                (conf/assoc! "parkour.step" step))
         [v args] (step-v-args conf "reducer" id)]
-    (log/infof "reducer: var=%s, args=%s" (pr-str v) (pr-str args))
+    (log/infof "%sr: var=%s, args=%s" (name step) (pr-str v) (pr-str args))
     (conf/with-default conf
       (let [f (adapt mr/collfn v)
             g (apply f conf args)]


debug log-error

debug log-error

--- src/atom_finder/util/30_fs_util.clj
+++ src/atom_finder/util/30_fs_util.clj
@@ -3,7 +3,9 @@
 (defmacro log-err [msg ret x]
   `(try ~x
       (catch Exception e# (do (errln (str "-- exception parsing commit: \"" ~msg "\"\n")) ~ret))
-      (catch Error e#     (do (errln (str "-- error parsing commit: \""  ~msg "\"\n")) ~ret))))
+      (catch Error e#     (do (errln (str "-- error parsing commit: \""  ~msg "\"\n")) ~ret)))
+  #_x
+  )

 (defn c-file?
   [filename]


Return nil instead of empty sequence from test-seq-for-ns

--- src/main/clojure/lazytest/find.clj
+++ src/main/clojure/lazytest/find.clj
@@ -10,8 +10,9 @@
 	  value)))))

 (defn- test-seq-for-ns [this-ns]
-  (vary-meta (remove nil? (map find-tests-for-var (vals (ns-interns this-ns))))
-	     assoc :name (ns-name this-ns)))
+  (let [s (remove nil? (map find-tests-for-var (vals (ns-interns this-ns))))]
+    (when (seq s)
+      (vary-meta s assoc :name (ns-name this-ns)))))

 (defn- find-tests-in-namespace [this-ns]
   (when-not (= (the-ns 'clojure.core) this-ns)


fixed test wording

fixed test wording

--- test/push/instructions/base/integer_test.clj
+++ test/push/instructions/base/integer_test.clj
@@ -304,9 +304,9 @@

 (tabular
-  (fact ":integer-shove takes an pops an index from :integer, then MOVES
+  (fact ":integer-shove pops an index from :integer, then MOVES
     the next item to a new position specified by the index; uses
-    (mod arg (inc (count :integer))) to place it in range [0,(count stack)]"
+    `(mod arg (inc (count :integer)))` to place it in range [0,(count stack)]"
     (step-and-check-it ?set-stack ?items ?instruction ?get-stack) => ?expected)

     ?set-stack  ?items          ?instruction      ?get-stack     ?expected


Drop obsolete docwarn about property path limitations

--- src/grafter_2/rdf4j/sparql/path.clj
+++ src/grafter_2/rdf4j/sparql/path.clj
@@ -1,18 +1,5 @@
 (ns grafter-2.rdf4j.sparql.path
-  "A limited implementation of SPARQL Property Paths[1] for `grafter`/`rdf4j`.
-
-  Limitations:
-
-  Paths must start and end with a \"plain\" `uri`. Meaning, no prefix or suffix
-  modifiers.
-
-  This is due to the rdf4j implementation, and the hook used to shoehorn this
-  in.
-
-  Additionally, `group`s are not implemented for the same reason.
-
-  Therefore, this implementation will not be able to translate complex paths, but
-  simple paths, E.G., `x ^y{3} / z` will be possible.
+  "An implementation of SPARQL Property Paths[1] for `grafter`/`rdf4j`.

 [1] https://www.w3.org/TR/sparql11-property-paths/#path-language


Remove some dead code

Remove some dead code

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -149,8 +149,8 @@
       [:thead [:tr [:th "Title"] [:th "Author"] [:th "Product Number"] [:th "Library Number"] [:th "Total time"] [:th "Number of CDs"] [:th "Depth"] [:th "Narrator"] [:th "Date of Production"] [:th "Libary signature"]]]
       [:tbody
        (for [{:keys [id title creator product_number library_number
-                     total_time volumes depth narrator produced_date]
-              :as production} (prod/find-by-state "encoded")]
+                     total_time volumes depth narrator produced_date]}
+             (prod/find-by-state "encoded")]
          [:tr
           [:td (link-to (str "/production/" id) title)]
           [:td creator]