Trying to connect the messaging dots (WIP)

Early morning poking around my message ns, trying to remember how the
pieces work and trying to decide how it would make sense for them to
fit.

--- src/clojure/frereth_cp/message.clj
+++ src/clojure/frereth_cp/message.clj
@@ -536,7 +536,17 @@
 (defn parent->
   "Receive a ByteBuf from parent

-;;;  411-435: try receiving messages: (DJB)
+  411-435: try receiving messages: (DJB)
+
+  It seems like this is probably inside-out now.
+
+  The parent is going to call this. It should trigger
+  the pieces that naturally fall downstream and lead
+  to writing the bytes to the child.
+
+  It's replacing one of the polling triggers that
+  set off the main() event loop. Need to adjust for
+  that fundamental strategic change
   "
   [{:keys [::specs/->child-buffer]
     :as state} buf]
@@ -544,6 +554,8 @@
 ;;;           417-433: for loop from 0-bytes read
 ;;;                    Copies bytes from incoming message buffer to message[][]
   (when (= 0 (.readableBytes buf))
+    ;; Yes, this is supposed to kill the entire process
+    ;; TODO: Be more graceful
     (throw (AssertionError. "Bad Message")))

   ;; Reference implementation is really reading bytes from
@@ -564,7 +576,7 @@
       (log/warn "Child buffer overflow")
       state)))

-(defn do-send-ack
+(defn send-ack!
   "Write ACK buffer to parent

 Line 608"
@@ -597,13 +609,44 @@
     ;; Don't want to ACK a pure-ACK message with no content
     state))

-(s/fdef read-from-parent!
+(s/fdef extract-message-from-parent
         :args (:state ::specs/state)
         :ret ::specs/state)
-(defn read-from-parent!
+(defn extract-message-from-parent
   "Lines 562-593"
-  [state]
-  (throw (RuntimeException. "Start here")))
+  [{:keys [::specs/buf]
+    :as state}]
+  ;; 562-574: calculate start/stop bytes
+  (let [D (read-short buf)
+        SF (bit-and D (+ k-2 k-4))
+        D (- D SF)]
+    (when (and (<= D 1024)
+               ;; In the reference implementation,
+               ;; len = 16 * (unsigned long long) messagelen[pos]
+               ;; (assigned at line 443)
+               ;; This next check looks like it really
+               ;; amounts to "have we read all the bytes
+               ;; in this block from the parent pipe?"
+               ;; It doesn't make a lot of sense in this
+               ;; approach
+               #_(> (+ 48 D) len))
+      (let [start-byte (read-long buf)
+            stop-byte (+ D start-byte)]
+        ;; of course, flow control would avoid this case -- DJB
+        ;; I've just totally painted receivebuf out of the picture.
+        ;; Q: How foolish was that?
+        (comment (when (<= stop-byte (+ receive-written (count receivebuf)))))
+        ;; 576-579: SF (StopFlag? deals w/ EOF)
+        (let [receive-eof (case SF
+                            0 false
+                            k-2 ::specs/normal
+                            k-4 ::specs/error)
+              receive-total-bytes (if (not= SF 0)
+                                    stop-byte)]
+          ;; 581-588: copy incoming into receivebuf
+          ;;          set the receivevalid flag
+
+          (throw (RuntimeException. "Translate this")))))))

 (defn read-long
   [bb]
@@ -617,10 +660,10 @@
   [bb]
   (.readShort bb))

-(s/fdef flag-acked-others
+(s/fdef flag-acked-others!
         :args (s/cat :state ::specs/state)
         :ret ::specs/state)
-(defn flag-acked-others
+(defn flag-acked-others!
   "Lines 544-560"
   [{:keys [::specs/buf]
     :as state}]
@@ -632,6 +675,8 @@
                      [read-short read-short]     ; 26-28
                      [read-short read-short]     ; 30-32
                      [read-short read-short])]   ; 34-36
+    ;; TODO: Desperately need to test this out to verify
+    ;; that it does what I think
     (reduce (fn [state [start stop]]
               (help/mark-acknowledged state start stop))
             state
@@ -819,12 +864,13 @@
             ;; Q: Isn't there?
             acked-blocks (filter #(= ack-id (::message-id %))
                                  blocks)
-            state (reduce (partial flag-acked state) acked-blocks)
-            ;; That takes us down to line 544
-            state (flag-acked-others state)
-            state (read-from-parent! state)
-            state (prep-send-ack state msg-id)]
-        (do-send-ack state)
+            state (-> (partial flag-acked state)
+                      (reduce acked-blocks)
+                      ;; That takes us down to line 544
+                      (flag-acked-others! state)
+                      (extract-message-from-parent state)
+                      (prep-send-ack state msg-id))]
+        (send-ack! state)
         state))))

 (s/fdef try-processing-message
@@ -881,8 +927,11 @@
   ;; pieces that feel silly.

   ;; At the very most, it seems as though this should amount to
-  ;; something like
-  (->child buf))
+  ;; something like:
+  (->child buf)
+  ;; But not quite. I *have* just finished a lot of work to
+  ;; extract the bits the child cares about
+  )

 ;;;
 ;;;
@@ -909,10 +958,6 @@
 ;;;                  Those are really the length at position 38 and initial
 ;;;                  offset at position 40, thanks to starting the send
 ;;;                  with length/16 at offset 7.
-;;;        562-574: calculate start/stop bytes
-;;;        576-579: SF (StopFlag? deals w/ EOF)
-;;;        581-588: copy incoming into receivebuf
-;;;                 set the receivevalid flag
 ;;;        589-593: increment the receivebytes count
 ;;;        595: never acknowledge a pure acknowledgment (DJB)
 ;;;             This short-circuits if something extracts to 0


ditch record-either layer

ditch record-either layer

--- src/er_cassandra/record_either.clj
+++ src/er_cassandra/record_either.clj
@@ -1,99 +0,0 @@
-(ns er-cassandra.record-either
-  (:refer-clojure :exclude [update])
-  (:require
-   [potemkin :refer [import-vars]]
-   [manifold.deferred :as d]
-   [cats.monad.either :as either]
-   [er-cassandra.record :as r])
-  (:import
-   [er_cassandra.session Session]))
-
-;; low-level record-based cassandra interface which
-;; puts responses into an Either monad Right value,
-;; and transforms Exceptions into Left values
-
-;; convert Manifold Deferred error handling to Either
-
-(defn either-deferred
-  "convert the Deferred error handling model to
-   an Either value"
-  ([d] (either-deferred d identity))
-  ([d error-transformer]
-   (let [ed (d/deferred)]
-     (d/on-realized
-      d
-      (fn [v] (d/success! ed (either/right v)))
-      (fn [x] (d/success! ed (either/left (error-transformer x)))))
-     ed)))
-
-(defn alia-error-transformer
-  "transforms an alia exception into an error map... doesn't
-   do much more than extract the ex-data map and set a message"
-  [x]
-  (let [data (if (instance? clojure.lang.ExceptionInfo x)
-               (ex-data x)
-               {:type (-> x type .getName keyword)})]
-    (merge {:message (.getMessage x)
-            :exception x}
-           data)))
-
-(import-vars [er-cassandra.record select-statement])
-
-(defn select
-  "select records : returns a Deferred[Either]"
-  ([^Session session table key record-or-key-value]
-   (select session table key record-or-key-value {}))
-
-  ([^Session session table key record-or-key-value opts]
-   (either-deferred
-    (r/select session table key record-or-key-value opts)
-    alia-error-transformer)))
-
-(defn select-one
-  "select a single record : returns a Deferred[Either]"
-  ([^Session session table key record-or-key-value]
-   (select-one session table key record-or-key-value {}))
-
-  ([^Session session table key record-or-key-value opts]
-   (either-deferred
-    (r/select-one session table key record-or-key-value opts)
-    alia-error-transformer)))
-
-(import-vars [er-cassandra.record insert-statement])
-
-(defn insert
-  "insert a single record - returns a Deferred[Either]"
-
-  ([^Session session table record]
-   (insert session table record {}))
-
-  ([^Session session table record opts]
-   (either-deferred
-    (r/insert session table record opts)
-    alia-error-transformer)))
-
-(import-vars [er-cassandra.record update-statement])
-
-(defn update
-  "update a single record - returns a Deferred[Either]"
-
-  ([^Session session table key record]
-   (update session table key record {}))
-
-  ([^Session session table key record opts]
-   (either-deferred
-    (r/update session table key record opts)
-    alia-error-transformer)))
-
-(import-vars [er-cassandra.record delete-statement])
-
-(defn delete
-  "delete a record - returns a Deferred[Either]"
-
-  ([^Session session table key record-or-key-value]
-   (delete session table key record-or-key-value {}))
-
-  ([^Session session table key record-or-key-value opts]
-   (either-deferred
-    (r/delete session table key record-or-key-value opts)
-    alia-error-transformer)))


better vis

better vis

--- src/consistent_hashing/animate.clj
+++ src/consistent_hashing/animate.clj
@@ -40,12 +40,22 @@
         mapped-caches (map vector
                            core/caches
                            (map core/map-to-unit-circle core/caches))
-        simulated (core/simulation)]
-    (reductions
-     (fn [acc x]
-       (merge-with
-        +'
-        acc
-        (frequencies x)))
-     {}
-     simulated)))
+        simulated (core/simulation)
+
+        load-pics
+        (reductions
+         (fn [acc x]
+           (reduce
+            (fn [acc [c is]]
+              (merge
+               acc
+               {c (distinct is)}))
+            {}
+            (reduce
+             (fn [acc [c is]]
+               (merge-with concat acc {c is}))
+             {}
+             (map vector x (map vector core/items)))))
+         {}
+         simulated)]
+    load-pics))


uname: include platform info

uname: include platform info

--- src/hello_lambda_jakarta/core.cljs
+++ src/hello_lambda_jakarta/core.cljs
@@ -6,7 +6,9 @@
 (def process (nodejs/require "process"))

 (defn uname []
-  (.arch os)
+  {:platform (.platform os)
+   :arch (.arch os)
+   }
 )

 (defn whoami []


store and index: return a path key for backward compat

--- src/io/cyanite/index/cassandra.clj
+++ src/io/cyanite/index/cassandra.clj
@@ -54,6 +54,7 @@
   [pattern-length [path length leaf]]
   {:text          (last (split path #"\."))
    :id            path
+   :path          path
    :allowChildren (not leaf)
    :expandable    (not leaf)
    :leaf          leaf})


refactor

refactor

--- src/zole/views.cljs
+++ src/zole/views.cljs
@@ -158,7 +158,7 @@
                        [:button.btn.btn-primary.btn-lg {:type "button" :on-click #(dispatch [:user-logout])} "Logout"]]]
        [:p])]))

-(defn play-page [state]
+(defn play-page []
   (let [state (subscribe [:play-page])]
     (fn []
       (let [{:keys [cards players username plays game-type points score total prompt last-game? last-game-player disconnected-player winner-player saved]} @state


CMR-309: Added code to handle float additional attributes.

--- src/cmr/search/data/query_to_elastic_converters/attribute.clj
+++ src/cmr/search/data/query_to_elastic_converters/attribute.clj
@@ -15,6 +15,10 @@
   [{:keys [value]}]
   {:term {:string-value value}})

+(defmethod value-condition->value-filter :float
+  [{:keys [value]}]
+  {:term {:float-value value}})
+
 (defmulti range-condition->range-filter
   "Converts an additional attribute range condition into the nested filter to use."
   (fn [condition]
@@ -22,11 +26,16 @@

 (defmethod range-condition->range-filter :string
   [{:keys [min-value max-value]}]
-  (let [r {:from (or min-value "")
-           :include_lower true
-           :include_upper true}
-        r (if max-value (assoc r :to max-value) r)]
+  (let [r {:gte (or min-value "")}
+        r (if max-value (assoc r :lte max-value) r)]
     {:range {:string-value r}}))
+
+(defmethod range-condition->range-filter :float
+  [{:keys [min-value max-value]}]
+  (let [r {:gte (or min-value Float/MIN_VALUE)}
+        r (if max-value (assoc r :lte max-value) r)]
+    {:range {:float-value r
+             :execution "fielddata"}}))

 (extend-protocol q2e/ConditionToElastic
   cmr.search.models.query.AttributeValueCondition


folder:inTree

folder:inTree

--- src/grafter/rdf/ontologies/pmd.clj
+++ src/grafter/rdf/ontologies/pmd.clj
@@ -18,3 +18,4 @@
 (def folder:defaultTree  (folder "defaultTree"))
 (def folder:parentFolder (folder "parentFolder"))
 (def folder:resourceLocation (folder "resourceLocation"))
+(def folder:inTree       (folder "inTree"))


make eastwood happy

make eastwood happy

--- src/oc/storage/resources/entry.clj
+++ src/oc/storage/resources/entry.clj
@@ -2,7 +2,6 @@
   (:require [clojure.walk :refer (keywordize-keys)]
             [if-let.core :refer (if-let* when-let*)]
             [schema.core :as schema]
-            [taoensso.timbre :as timbre]
             [oc.lib.schema :as lib-schema]
             [oc.lib.db.common :as db-common]
             [oc.lib.slugify :as slugify]


CMR-3203 Fix debug code in tests

CMR-3203 Fix debug code in tests

--- system-int-test/src/cmr/system_int_test/utils/search_util.clj
+++ system-int-test/src/cmr/system_int_test/utils/search_util.clj
@@ -616,10 +616,7 @@

 (defn get-humanizers-report
   []
-  (try
-   (let [response (client/get (url/humanizers-report-url) {:connection-manager (s/conn-mgr)})]
-     (if (= 200 (:status response))
-       (:body response)
-       response))
-   (catch Exception e
-     (proto-repl.saved-values/save 2))))
+  (let [response (client/get (url/humanizers-report-url) {:connection-manager (s/conn-mgr)})]
+   (if (= 200 (:status response))
+     (:body response)
+     response)))


Fix java.lang.Math/abs typo

Fix java.lang.Math/abs typo

--- src/kixi/hecuba/data/calculate.clj
+++ src/kixi/hecuba/data/calculate.clj
@@ -226,7 +226,7 @@

 (defn find-resolution [measurements]
   (let [differences (diff (map #(/ (.getTime (m/truncate-seconds (:timestamp %))) 1000) measurements))]
-    (Math/abs (mode differences))))
+    (java.lang.Math/abs (mode differences))))

 (defn resolution
   "Updates resolution if it's missing. Infers it from last 100 measurements.


Made tag-cloud template more configurable.

--- src/lambda_blog/templates/tags.clj
+++ src/lambda_blog/templates/tags.clj
@@ -4,10 +4,7 @@
             [lambda-blog.utils :refer [pathcat]]
             [s-html.tags :refer [a div h1 span]]))

-(def min-size 100)
-(def max-size 300)
-
-(defn tag-cloud [{:keys [entries path-to-root tags]}]
+(defn tag-cloud [min max {:keys [entries path-to-root tags]}]
   (let [counts (->> tags
                     ;; FIXME O(N_tags * N_entries) but could be O(N_entries)
                     (map #(->> entries
@@ -34,5 +31,5 @@
 (defn tags-index [ent]
   (page (fn [ent]
           [(-> "Tag cloud" h1 text-centered panel)
-           (tag-cloud ent)])
+           (tag-cloud 100 300 ent)])
         ent))


CMR-3860: Make robots.txt available as /search/robots.txt to support the NGAP load balancer

--- search-app/src/cmr/search/api/routes.clj
+++ search-app/src/cmr/search/api/routes.clj
@@ -315,13 +315,19 @@
      :headers {common-routes/CONTENT_TYPE_HEADER (mt/with-utf-8 mt/json)}
      :body results}))

+(def robots-txt-response
+  "Returns the robots.txt response."
+  {:status 200
+   :body (slurp (io/resource "public/robots.txt"))})
+
 (defn- build-routes [system]
   (let [relative-root-url (get-in system [:public-conf :relative-root-url])]
     (routes
-      (GET "/robots.txt" req {:status 200
-                              :body (slurp (io/resource "public/robots.txt"))})
+      ;; Return robots.txt from the root /robots.txt and at the context (e.g. /search/robots.txt)
+      (GET "/robots.txt" req robots-txt-response)

       (context relative-root-url []
+        (GET "/robots.txt" req robots-txt-response)

         ;; Add routes for tagging
         tags-api/tag-api-routes


Increase and decrese BPC to match resolution change.

--- sonic-jam/src/sonic_jam/core.cljs
+++ sonic-jam/src/sonic_jam/core.cljs
@@ -652,17 +652,26 @@
                                                  tracks)]
                           (om/transact! cursor (fn [c] (assoc cursor "tracks" (clj->js halved-tracks))))
                           (go (>! set-state-ch id)))
-            double-res #(let [tracks (get cursor "tracks")
-                              doubled-tracks (map (fn [t]
-                                                    (let [beats (get t "beats")
-                                                          doubled-beats (interleave (map (fn [b] (vector (* 2 (first b)))) beats)
-                                                                                (repeat [0]))]
-                                                      (assoc t "beats" doubled-beats)))
-                                                  tracks)]
-                          (om/transact! cursor (fn [c] (assoc c "tracks" (clj->js doubled-tracks))))
-                          (go (>! set-state-ch id)))
-            half-res #(let [tracks (get cursor "tracks")
-                            halved-tracks (map (fn [t]
+            bpc-list (om/observe owner (bpc-values))
+            double-res #(when-not (= (first bpc-list) (get cursor "bpc"))
+                          (let [current-bpc (get cursor "bpc")
+                                bpc (last (take-while (fn [v] (not (= current-bpc v))) bpc-list))
+                                tracks (get cursor "tracks")
+                                doubled-tracks (map (fn [t]
+                                                      (let [beats (get t "beats")
+                                                            doubled-beats (interleave (map (fn [b] (vector (* 2 (first b)))) beats)
+                                                                                (repeat [0]))]
+                                                        (assoc t "beats" doubled-beats)))
+                                                    tracks)]
+                            (om/transact! cursor (fn [c] (assoc c
+                                                                "tracks" (clj->js doubled-tracks)
+                                                                "bpc" bpc)))
+                            (go (>! set-state-ch id))))
+            half-res #(when-not (= (last bpc-list) (get cursor "bpc"))
+                        (let [current-bpc (get cursor "bpc")
+                              bpc (second (drop-while (fn [v] (not (= current-bpc v))) bpc-list))
+                              tracks (get cursor "tracks")
+                              halved-tracks (map (fn [t]
                                                  (let [beats (get t "beats")
                                                        halved-beats (filter some?
                                                                             (map-indexed (fn [i b] (if (even? i) (vector (if (= 0 (first b)) 0
@@ -670,8 +679,10 @@
                                                                                beats))]
                                                    (assoc t "beats" halved-beats)))
                                                tracks)]
-                        (om/transact! cursor (fn [c] (assoc c "tracks" (clj->js halved-tracks))))
-                        (go (>! set-state-ch id)))]
+                          (om/transact! cursor (fn [c] (assoc c
+                                                              "tracks" (clj->js halved-tracks)
+                                                              "bpc" bpc)))
+                          (go (>! set-state-ch id))))]
         (condp = (:state state)
           :init (dom/table nil
                            (dom/tbody nil


snapping, not snaped

snapping, not snaped

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -1051,6 +1051,7 @@
    "snap" {:synsem {:cat :verb
                     :sem {:pred :snap-pictures}}
            :english {:past "snapped"
+                     :participle "snapping"
                      :note "pictures"}}

    "some"


Make text areas and inputs have the same font as the body

Caution: had to change the search box from type="search" to type="text"
because type="search" restricts styling.

--- src/braid/ui/styles/body.cljs
+++ src/braid/ui/styles/body.cljs
@@ -6,4 +6,6 @@
     :padding 0
     :font-family "\"Open Sans\", Helvetica, Arial, sans-serif"
     :font-size "12px"
-    :background "#eee"}])
+    :background "#eee"}
+   [:textarea :input
+    {:font-family "inherit"}]])


Add missing argument to throw.

Add missing argument to throw.

--- src/buddy/auth/middleware.clj
+++ src/buddy/auth/middleware.clj
@@ -80,4 +80,4 @@
           (if (satisfies? proto/IAuthorizationdError e)
             (->> (proto/-get-error-data e)
                  (proto/-handle-unauthorized backend request))
-            (throw)))))))
+            (throw e)))))))


CLJS-749: Append CLJS version to browser repl-env working directory to prevent issues when changing versions in a project.

--- src/clj/cljs/repl/browser.clj
+++ src/clj/cljs/repl/browser.clj
@@ -11,6 +11,7 @@
   (:require [clojure.java.io :as io]
             [clojure.string :as string]
             [cljs.compiler :as comp]
+            [cljs.util :as util]
             [cljs.closure :as cljsc]
             [cljs.repl :as repl]
             [cljs.repl.server :as server])
@@ -229,7 +230,8 @@

   port:           The port on which the REPL server will run. Defaults to 9000.
   working-dir:    The directory where the compiled REPL client JavaScript will
-                  be stored. Defaults to \".repl\".
+                  be stored. Defaults to \".repl\" with a ClojureScript version
+                  suffix, eg. \".repl-0.0-2138\".
   serve-static:   Should the REPL server attempt to serve static content?
                   Defaults to true.
   static-dir:     List of directories to search for static content. Defaults to
@@ -247,7 +249,7 @@
         opts (merge (BrowserEnv.)
                     {:port          9000
                      :optimizations :simple
-                     :working-dir   ".repl"
+                     :working-dir   (->> [".repl" (util/clojurescript-version)] (remove empty?) (string/join "-"))
                      :serve-static  true
                      :static-dir    ["." "out/"]
                      :preloaded-libs   []


first crack at chunking fires.

first crack at chunking fires.

--- src/clj/forma/source/fire.clj
+++ src/clj/forma/source/fire.clj
@@ -1,13 +1,14 @@
 (ns forma.source.fire
   (:use cascalog.api
         [forma.date-time :only (periodize)]
-        [forma.matrix.utils :only (idx->colrow)]
+        [forma.matrix.utils :only (idx->colrow sparse-vector)]
         [forma.reproject :only (wgs84-index
                                 dimensions-at-res)]
         [forma.source.modis :only (latlon->modis
                                    pixels-at-res)]
         [clojure.string :only (split)])
-  (:require [cascalog.ops :as c]))
+  (:require [cascalog.ops :as c]
+            [forma.hadoop.predicate :as p]))

 (def fire-tap
   (memory-source-tap
@@ -60,98 +61,42 @@
         (c/max ?kelvin :> ?max-t)
         (c/count ?count))))

+(defn to-vector [x y]
+  [[x y]])
+
+;; TODO: Docs
+(defn sample-aggregator
+  "Takes a samples and line generator, and stitches lines back
+  together. "
+  [point-source]
+  (let [sample-agger (p/vals->sparsevec [0 0] 1200 1)]
+    (<- [?dataset ?mod-h ?mod-v ?tperiod ?line ?line-vec-col ?line-vec]
+        (point-source ?dataset ?mod-h ?mod-v ?sample ?line ?tperiod ?count ?max-t)
+        (to-vector ?count ?max-t :> ?values)
+        (sample-agger ?sample ?values :> ?line-vec-col ?line-vec))))
+
+;; Stitches lines together into a window!
+;; TODO: Docs
+(defn line-aggregator
+  "Stitches lines back together into little windows."
+  [point-source]
+  (let [line-source (sample-aggregator point-source)
+        line-agger (p/vals->sparsevec (-> (/ 1200 1)
+                                          (repeat [0 0])
+                                          vec)
+                                      1200 1)]
+    (<- [?dataset ?t-period ?tile-h ?tile-v ?chunkid ?chunk]
+        (line-source ?dataset ?tile-h ?tile-v ?t-period ?line ?window-col ?line-vec)
+        (line-agger ?line ?line-vec :> ?chunkid ?chunk))))
+
+(def prepath "/Users/sritchie/Desktop/FORMA/FIRE/")
+
 (defn run-rip
   "Rips apart fires!"
-  [count m-res t-res path]
-  (?- (stdout) (c/first-n (rip-fires m-res t-res path)
-                          count)))
-
-;; FOR LATER...
-;;
-;; ## ASCII Grid Sampling
-
-(defn liberate
-  "Takes a line with an index as the first value and numbers as the
-  rest, and converts it into a 2-tuple formatted as `[idx, row-vals]`,
-  where `row-vals` are sealed inside an `int-array`.
-
-Example usage:
-
-    (liberate \"1 12 13 14 15\")
-    ;=> [1 #<int[] [I@1b66e87>]"
-  [line]
-  (let [[idx & row-vals] (map #(Integer. %)
-                              (split line #" "))]
-    [idx (int-array row-vals)]))
-
-;; This guy splits apart some particular row, and returns a 2-tuple
-;; with the index within the row as the first item.
-(defmapcatop free-cols
-  [row]
-  (map-indexed vector row))
-
-(defn grid-source
-  "Takes some source of textlines -- (hfs-textline \"/some/file.csv\",
-  for example -- and generates tuples with `row`, `col` and `val` at
-  the specified location."
-  [source]
-  (<- [?row-idx ?col-idx ?val]
-      (source ?line)
-      (liberate ?line :> ?row-idx ?row-vec)
-      (free-cols ?row-vec :> ?col-idx ?val)))
-
-(defmapcatop
-  ^{:doc "Returns tuples containing modis coordinates, plus the
-  corresponding row and column of a value within a wgs84 grid at the
-  specified spatial resolution. ll-res is the step size of the ASCII
-  grid."}
-  [sample-modis [m-res ll-res]]
-  [mod-h mod-v]
-  (let [pix (pixels-at-res m-res)
-        [ll-width ll-height] (dimensions-at-res ll-res)]
-    (for [sample (range pix)
-          line   (range pix)
-          :let [idx (wgs84-index m-res ll-res mod-h
-                                 mod-v sample line)
-                [col row] (idx->colrow ll-width ll-height idx)]]
-      [sample line row col])))
-
-(defn sample-ascii
-  "Subquery to sample an ascii grid of information at the supplied
-  MODIS and wgs84 resolutions. `m-res` is \"1000\", \"500\" or
-  \"250\". `ll-res` is the step size on the latitude-longitude grid.
-
-Example usage:
-
-    (?- (stdout)
-        (sample-ascii \"1000\" 0.1 \"/path/to/ascii.csv\" [[8 6] [12 10]]))"
-  [m-res ll-res ascii-path tile-seq]
-  {:pre [()]}
-  (let [tile-source (memory-source-tap tile-seq)
-        ascii-source (grid-source (hfs-textline ascii-path))]
-    (<- [?mod-h ?mod-v ?sample ?line ?val]
-        (tile-source ?mod-h ?mod-v)
-        (sample-modis [m-res ll-res] ?mod-h ?mod-v :> ?sample ?line ?row ?col)
-        (ascii-source ?row ?col ?val))))
-
-(defn run-sample-ascii
-  "Runs the above subquery, as in `sample-ascii` example."
-  [m-res ll-res ascii-path tile-seq]
+  [count]
   (?- (stdout)
-      (sample-ascii m-res ll-res
-                    ascii-path tile-seq)))
-
-
-(def count-agg
-  (<- [?a :> ?count]
-      (c/count ?count)))
-
-(defn count-test []
-  (let [tap (memory-source-tap [[1 2]
-                                [1 3]
-                                [1 4]])]
-    (?<- (stdout)
-         [?a ?count ?max]
-         (tap ?a ?b)
-         (c/max ?b :> ?max)
-         (c/count ?count))))
+      (c/first-n (line-aggregator
+                  (rip-fires "1000"
+                             "32"
+                             (str prepath "MCD14DL.2011074.txt")))
+                 count)))


include edn support in import api

include edn support in import api

--- src/clj_money/api/imports.clj
+++ src/clj_money/api/imports.clj
@@ -12,6 +12,7 @@
             [clj-money.models.images :as images]
             [clj-money.import :refer [import-data]]
             [clj-money.import.gnucash]
+            [clj-money.import.edn]
             [clj-money.models.imports :as imports]))

 (def ^:private expected-record-types


Add additional cases to rand-weighted-nth

--- src/cljc/robinson/random.cljc
+++ src/cljc/robinson/random.cljc
@@ -147,9 +147,13 @@
     (rand-weighted-nth *rnd* m))
   ([rnd m]
    "Randomly select a value from a map of weights to values."
-   (if (= 1 (count m))
-     (-> m first val)
-     (let [[wm a]     (reduce (fn [[m a] [weight v]]
-                                [(conj m [a v]) (+ weight a)]) [[] 0] m)
-           n          (uniform-double rnd 0 a)]
-       (second (last (remove (fn [[wn _]] (> wn n)) wm)))))))
+   (cond
+     (empty? m)
+       nil
+     (= 1 (count m))
+       (-> m first val)
+     :else
+       (let [[wm a]     (reduce (fn [[m a] [weight v]]
+                                  [(conj m [a v]) (+ weight a)]) [[] 0] m)
+             n          (uniform-double rnd 0 a)]
+         (second (last (remove (fn [[wn _]] (> wn n)) wm)))))))


Remove an unexpected field in the server state structure

--- src/clojure/picard/server.clj
+++ src/clojure/picard/server.clj
@@ -36,7 +36,6 @@
     [ch
      keepalive?
      chunked?
-     streaming? ;; TODO: remove this
      responded?
      expects-100? ;; TODO: remove this
      request-id
@@ -71,7 +70,6 @@
   (State. ch                  ;; Netty channel
           true                ;; Is the exchange keepalive?
           nil                 ;; Is the request chunked?
-          nil                 ;; Is the response streaming?
           nil                 ;; Has the response been sent?
           false               ;; Does the exchange expect an 100 Continue?
           nil                 ;; Request ID
@@ -266,7 +264,6 @@
            :bytes-to-send  bytes-to-send
            :bytes-expected bytes-expected
            :responded?     (not= :chunked body)
-           :streaming?     (= :chunked body)
            :chunked?       (= (hdrs "transfer-encoding") "chunked")
            :next-dn-fn     (when (= :chunked body) stream-or-finalize-response)
            :keepalive?     (and (.keepalive? current-state)


Update en.cljs

Update en.cljs

Grammar fixes, consistency across contexts, and some good ol' content changes.

Some minor content changes for better, clearer explanations.
Lots of spelling and grammar changes.
Most of the grammar changes were to capitalised letters (which I have made at least consistent in different contexts) and whether or not the prompt ends with a full stop (again, context dependent)

status: ready

--- src/status_im/translations/en.cljs
+++ src/status_im/translations/en.cljs
@@ -22,8 +22,8 @@
    :yes                                   "Yes"
    :no                                    "No"

-   :camera-access-error                   "To grant the required camera permission, please, go to your system settings and make sure that Status > Camera is selected."
-   :photos-access-error                   "To grant the required photos permission, please, go to your system settings and make sure that Status > Photos is selected."
+   :camera-access-error                   "To grant the required camera permission, please go to your system settings and make sure that Status > Camera is selected."
+   :photos-access-error                   "To grant the required photos permission, please go to your system settings and make sure that Status > Photos is selected."

    ;;drawer
    :invite-friends                        "Invite friends"
@@ -93,7 +93,7 @@
    :email                                 "Email"
    :update-status                         "Update your status..."
    :add-a-status                          "Add a status..."
-   :status-prompt                         "Create a status to help people know about the things you are offering. You can use #hashtags too."
+   :status-prompt                         "Set your status. Using #hastags will help others discover you and talk about what's on your mind"
    :add-to-contacts                       "Add to contacts"
    :in-contacts                           "In contacts"
    :remove-from-contacts                  "Remove from contacts"
@@ -103,8 +103,8 @@
    :error-incorrect-name                  "Please select another name"
    :error-incorrect-email                 "Incorrect e-mail"
    :profile-testnet-icon                  "Testnet"
-   :testnet-text                          "You’re on the {{testnet}} Testnet. Do not send real ETH or SNT to your address."
-   :mainnet-text                          "You’re on the Mainnet. Real ETH will be send."
+   :testnet-text                          "You’re on the {{testnet}} Testnet. Do not send real ETH or SNT to your address"
+   :mainnet-text                          "You’re on the Mainnet. Real ETH will be sent"

    ;;make_photo
    :image-source-title                    "Profile image"
@@ -126,17 +126,17 @@
    :contacts-syncronized                  "Your contacts have been synchronized"
    :confirmation-code                     (str "Thanks! We've sent you a text message with a confirmation "
                                                "code. Please provide that code to confirm your phone number")
-   :incorrect-code                        (str "Sorry the code was incorrect, please enter again")
+   :incorrect-code                        (str "Sorry the code was incorrect, please enter it again")
    :generate-passphrase                   (str "I'll generate a passphrase for you so you can restore your "
-                                               "access or log in from another device")
-   :phew-here-is-your-passphrase          "*Phew* that was hard, here is your passphrase, *write this down and keep this safe!* You will need it to recover your account."
+                                               "account or log in from another device.")
+   :phew-here-is-your-passphrase          "Phew, that was hard. Here is your passphrase, *write this down and keep it safe!* You will need it to recover your account."
    :here-is-your-passphrase               "Here is your passphrase, *write this down and keep this safe!* You will need it to recover your account."
    :here-is-your-signing-phrase           "Here is your signing phrase. You will use it to verify your transactions. *Write it down and keep it safe!*"
-   :written-down                          "Make sure you had securely written it down"
-   :phone-number-required                 "Tap here to enter your phone number & I'll find your friends"
-   :shake-your-phone                      "Find a bug or have a suggestion? Just ~shake~ your phone!"
-   :intro-status                          "Chat with me to setup your account and change your settings!"
-   :intro-message1                        "Welcome to Status\nTap this message to set your password & get started!"
+   :written-down                          "Make sure you have written it down somewhere secure."
+   :phone-number-required                 "Tap here to validate your phone number & I'll find your friends."
+   :shake-your-phone                      "Found a bug or have a suggestion? Just ~shake~ your phone!"
+   :intro-status                          "Chat with me to setup your account and change your settings."
+   :intro-message1                        "Welcome to Status!\nTap this message to set your password and get started."
    :account-generation-message            "Gimmie a sec, I gotta do some crazy math to generate your account!"
    :move-to-internal-failure-message      "We need to move some important files from external to internal storage. To do this, we need your permission. We won't be using external storage in future versions."
    :debug-enabled                         "Debug server has been launched! You can now execute *status-dev-cli scan* to find the server from your computer on the same network."
@@ -163,7 +163,7 @@
    :discover                              "Discover"
    :none                                  "None"
    :search-tags                           "Type your search tags here"
-   :popular-tags                          "Popular hashtags"
+   :popular-tags                          "Popular #hashtags"
    :recent                                "Recent statuses"
    :no-statuses-found                     "No statuses found"
    :chat                                  "Chat"
@@ -171,12 +171,12 @@
    :public-chats                          "Public chats"
    :soon                                  "Soon"
    :public-chat-user-count                "{{count}} people"
-   :dapps                                 "DApps"
-   :dapp-profile                          "DApp Profile"
+   :dapps                                 "ÐApps"
+   :dapp-profile                          "ÐApp profile"
    :no-statuses-discovered                "No statuses discovered"
    :no-statuses-discovered-body           "When somebody posts\na status you will see it here."
-   :no-hashtags-discovered-title          "No hashtags discovered"
-   :no-hashtags-discovered-body           "When a hashtag becomes\npopular you will see it here."
+   :no-hashtags-discovered-title          "No #hashtags discovered"
+   :no-hashtags-discovered-body           "When a #hashtag becomes\npopular you will see it here."

    ;;settings
    :settings                              "Settings"
@@ -195,7 +195,7 @@
    :contacts-group-new-chat               "Start new chat"
    :choose-from-contacts                  "Choose from contacts"
    :no-contacts                           "No contacts yet"
-   :show-qr                               "Show QR"
+   :show-qr                               "Show QR code"
    :enter-address                         "Enter address"
    :more                                  "more"

@@ -251,8 +251,8 @@
    :group-name                            "Group name"
    :edit-group                            "Edit group"
    :delete-group                          "Delete group"
-   :delete-group-confirmation             "This group will be removed from your groups. This will not affect contacts"
-   :delete-group-prompt                   "This will not affect contacts"
+   :delete-group-confirmation             "This group will be removed from your groups. This will not affect your contacts"
+   :delete-group-prompt                   "This will not affect your contacts"
    :group-members                         "Group members"
    :contact-s                             {:one   "contact"
                                            :other "contacts"}
@@ -272,11 +272,10 @@
    ;;new-contact
    :add-new-contact                       "Add new contact"
    :import-qr                             "Import"
-   :scan-qr                               "Scan QR"
-   :swow-qr                               "Show QR"
+   :scan-qr                               "Scan QR code"
    :name                                  "Name"
    :whisper-identity                      "Whisper Identity"
-   :address-explication                   "Maybe here should be some text explaining what an address is and where to look for it"
+   :address-explication                   "Your address is what identifies you on Ethereum and is a series of numbers and letters beginning with '0x'"
    :enter-valid-address                   "Please enter a valid address or scan a QR code"
    :enter-valid-public-key                "Please enter a valid public key or scan a QR code"
    :contact-already-added                 "The contact has already been added"
@@ -295,7 +294,7 @@

    ;;recover
    :recover-from-passphrase               "Recover from passphrase"
-   :recover-explain                       "Please enter the passphrase for your password to recover access"
+   :recover-explain                       "Please enter the passphrase for your account to recover access"
    :passphrase                            "Passphrase"
    :recover                               "Recover"
    :enter-valid-passphrase                "Please enter a passphrase"
@@ -313,7 +312,7 @@
    ;;validation
    :invalid-phone                         "Invalid phone number"
    :amount                                "Amount"
-   :not-enough-eth                        (str "Not enough ETH on balance "
+   :not-enough-eth                        (str "Insufficient funds. Your balance is: "
                                                "({{balance}} ETH)")

    ;;transactions
@@ -341,42 +340,42 @@
    :from                                  "From"
    :data                                  "Data"
    :got-it                                "Got it"
-   :contract-creation                     "Contract Creation"
+   :contract-creation                     "Contract creation"
    :block                                 "Block"
    :hash                                  "Hash"
    :gas-limit                             "Gas limit"
    :gas-price                             "Gas price"
-   :gas-used                              "Gas Used"
+   :gas-used                              "Gas used"
    :cost-fee                              "Cost/Fee"
    :nonce                                 "Nonce"
-   :confirmations                         "confirmations"
-   :confirmations-helper-text             "If you want to be sure your transaction will not be compromise wait until it gets at least 10 blocks confirmations"
+   :confirmations                         "Confirmations"
+   :confirmations-helper-text             "If you want to be sure your transaction has been securely processed, wait for 12 confirmations"
    :copy-transaction-hash                 "Copy transaction hash"
-   :open-on-etherscan                     "Open on Etherscan"
+   :open-on-etherscan                     "Open on Etherscan.org"

    ;;webview
    :web-view-error                        "oops, error"

    ;;testfairy warning
    :testfairy-title                       "Warning!"
-   :testfairy-message                     "You are using app installed from a nightly build. For testing purposes this build includes session recording if wifi connection is used, so all your interaction with app is saved (as video and log) and might be used by development team to investigate possible issues. Saved video/log do not include your passwords. Recording is done only if app is installed from a nightly build. Nothing is recorded if app is installed from PlayStore or TestFlight."
+   :testfairy-message                     "You are using an app installed from a nightly build. For testing purposes this build includes session recording if wifi connection is used, so all your interactions with this app is saved (as video and logs) and might be used by our development team to investigate possible issues. Saved video/logs do not include your passwords. Recording is done only if the app is installed from a nightly build. Nothing is recorded if the app is installed from PlayStore or TestFlight."

    ;; wallet
    :wallet                                "Wallet"
    :wallets                               "Wallets"
    :your-wallets                          "Your wallets"
    :main-wallet                           "Main Wallet"
-   :wallet-error                          "Error Loading Data"
+   :wallet-error                          "Error loading data"
    :wallet-send                           "Send"
    :wallet-request                        "Request"
    :wallet-exchange                       "Exchange"
    :wallet-assets                         "Assets"
    :wallet-add-asset                      "Add asset"
    :wallet-total-value                    "Total value"
-   :wallet-settings                       "Wallet Settings"
+   :wallet-settings                       "Wallet settings"
    :signing-phrase-description            "Sign the transaction by entering your password. Make sure that the words above match your secret signing phrase"
    :wallet-insufficient-funds             "Insufficient funds"
-   :request-transaction                   "Request Transaction"
+   :request-transaction                   "Request transaction"
    :send-request                          "Send request"
    :share                                 "Share"
    :eth                                   "ETH"
@@ -384,30 +383,29 @@
    :usd-currency                          "USD"
    :transactions                          "Transactions"
    :transaction-details                   "Transaction details"
-   :transaction-failed                    "Transaction failed"
    :transactions-sign                     "Sign"
    :transactions-sign-all                 "Sign all"
-   :transactions-sign-transaction         "Sign Transaction"
-   :transactions-sign-later               "Sign Later"
-   :transactions-sign-all-text            "Sign the transaction by entering your password.\nMake sure that the words above match your secret signing phrase"
+   :transactions-sign-transaction         "Sign transaction"
+   :transactions-sign-later               "Sign later"
+   :transactions-sign-all-text            "Sign all transactions by entering your password.\nMake sure that the words above match your secret signing phrase"
    :transactions-sign-input-placeholder   "Enter your password"
    :transactions-delete                   "Delete transaction"
-   :transactions-delete-content           "Transaction will be removed from unsigned list"
+   :transactions-delete-content           "Transaction will be removed from 'Unsigned' list"
    :transactions-history                  "History"
    :transactions-unsigned                 "Unsigned"
-   :transactions-history-empty            "You don't have a history transactions"
-   :transactions-unsigned-empty           "You don't have unsigned transactions"
-   :transactions-filter-title             "Filter History"
+   :transactions-history-empty            "No transactions in your history yet"
+   :transactions-unsigned-empty           "You don't have any unsigned transactions"
+   :transactions-filter-title             "Filter history"
    :transactions-filter-tokens            "Tokens"
    :transactions-filter-type              "Type"
    :transactions-filter-select-all        "Select all"
-   :view-transaction-details              "View Transaction Details"
-   :transaction-description               "If you want to be sure you transaction will not be compromised wait until it gets at least 10 block confirmations"
-   :transaction-sent                      "Transaction Sent"
-   :transaction-moved-text                "The transaction has been successfully moved to “Unsigned”"
-   :transaction-moved-title               "Transaction Moved"
-   :sign-later-title                      "Sign Transaction Later?"
-   :sign-later-text                       "You will be able to sign in the transaction history"
+   :view-transaction-details              "View transaction details"
+   :transaction-description               "If you want to be sure your transaction has been securely processed, wait for 12 confirmations"
+   :transaction-sent                      "Transaction sent"
+   :transaction-moved-text                "The transaction has been moved to the 'Unsigned' list. It will be deleted after 5 minutes."
+   :transaction-moved-title               "Transaction moved"
+   :sign-later-title                      "Sign transaction later?"
+   :sign-later-text                       "Check the transaction history to sign this transaction"
    :not-applicable                        "Not applicable for unsigned transactions"

    ;; Wallet Send
@@ -444,5 +442,5 @@
    :edit-network-warning                  "Be careful, editing the network data may disable this network for you"
    :connecting-requires-login             "Connecting to another network requires login"
    :close-app-title                       "Warning!"
-   :close-app-content                     "App will be closed. When you restart it selected network will be used."
+   :close-app-content                     "The app will stop and close. When you reopen it, the selected network will be used"
    :close-app-button                      "Confirm"})


AB + CW | 22 | callback checks whether request came from authorise or denied app

--- src/stonecutter_client/handler.clj
+++ src/stonecutter_client/handler.clj
@@ -65,11 +65,11 @@
       (assoc :session nil)))

 (defn oauth-callback [request]
+  (if-let [auth-code (get-in request [:params :code])]
   (let [client-id (get-env :client-id)
         client-secret (get-env :client-secret)
         callback-uri (str (base-url) "/callback")
         oauth-token-path (str (auth-url) "/api/token")
-        auth-code (get-in request [:params :code])
         token-response (http/post oauth-token-path {:form-params {:grant_type    "authorization_code"
                                                                   :redirect_uri  callback-uri
                                                                   :code          auth-code
@@ -80,7 +80,8 @@
                        (json/parse-string keyword))]
     (-> (r/redirect (absolute-path :voting))
         (assoc :session {:access-token (:access_token token-body)
-                         :user (:user-email token-body)}))))
+                         :user (:user-email token-body)})))
+    (r/redirect (absolute-path :home))))

 (defn voting [request]
   (if (logged-in? request)


Fixes #11 by giving the add card a `gensym`ed key.

Need to understand why this makes a difference at some point. Are we holding on to the old component somehow?

--- src/unspun/screens/story_list.cljs
+++ src/unspun/screens/story_list.cljs
@@ -9,7 +9,7 @@
 (def palette-titles
   (mapv name (keys palettes)))

-(rum/defc icon-example [name]
+#_(rum/defc icon-example [name]
   (content {:theme (aget my-theme "default")}
            (n-icon {:name  name
                     :style {:color (:dark-primary (get-palette @palette-index))}})))
@@ -26,7 +26,7 @@
            :style {:color (:dark-primary palette)}
            }))

-(defn nnt-icon [palette]
+#_(defn nnt-icon [palette]
   (n-icon {:name  "md-keypad"
            :key   (gensym "nnt")
            :style {:color (:accent palette)}
@@ -34,7 +34,7 @@

 (defn show-icon [palette]
   (n-icon {:name  "ios-arrow-dropright-outline"
-           :key   (gensym "icon")
+           :key   (gensym "icon-foo")
            :style {:color     (:accent palette)
                    :transform [{:scale 1.67}]}
            }))
@@ -43,17 +43,15 @@
   (n-icon {:name  "ios-add-circle-outline"
            :key   (gensym "add")
            :style {:color     (:accent palette)
-                   :transform [{:scale 1.67}]}
-           }))
+                   :transform [{:scale 1.67}]}}))

-(defn bars-icon [palette]
+#_(defn bars-icon [palette]
   (n-icon {:name  "ios-stats"
            :key   (gensym "bars")
            :style {:width 9
                    ;:paddingRight 5
-                   :color (:accent palette)
-                   }}))
+                   :color (:accent palette)}}))

 (defn select-palette-item! [index]
   (n-list-item
@@ -63,17 +61,24 @@
             :selected (= @palette-index index)})
     (txt {:key 2} (palette-titles index))))

+(def card-style {:flex         1
+                 :marginLeft   15
+                 :marginRight  15
+                 :marginTop    5
+                 :marginBottom 0})
+
+(def card-item-style {:backgroundColor "white"
+                      :justifyContent  "flex-start"
+                      :flexDirection   "row"
+                      :alignItems      "center"
+                      :padding         10})
+
 (defn add-card! [navigator palette]
-  (card {:key   20
-         :style {:flex   1
-                 :margin 15}}
+  (card {:key   (gensym "add-card")
+         :style card-style}
         (card-item {:header true
                     :key    1
-                    :style  {:backgroundColor "white"
-                             :justifyContent  "flex-start"
-                             :flexDirection   "row"
-                             :alignItems      "center"
-                             }}
+                    :style  card-item-style}
                    (txt {:key   1
                          :style {:flex       4
                                  :marginLeft 34
@@ -82,28 +87,17 @@
                         "Add your own scenario")
                    (button {:key       2
                             :bordered  true
-                            ;:small     true
                             :textStyle {:color (:accent palette)}
                             :style     {:borderWidth 0}
-                            :onPress   #(do (.push navigator "not-yet"))}
-                           (add-icon palette)
-                           ;(txt "")
-                           ))
-        )
-
-  )
+                            :onPress   #(.push navigator "not-yet")}
+                           (add-icon palette)))))

 (defn story-card! [navigator palette index]
   (card {:key   (gensym "story-card")
-         :style {:flex   1
-                 :margin 15}}
+         :style card-style}
         (card-item {:header true
                     :key    1
-                    :style  {:backgroundColor "white"
-                             :justifyContent  "flex-start"
-                             :flexDirection   "row"
-                             :alignItems      "center"
-                             }}
+                    :style  card-item-style}
                    (story-icon palette (:icon (@stories index)))
                    (txt {:key   1
                          :style {:flex       4
@@ -112,17 +106,11 @@
                         (caps-tidy (story index)))
                    (button {:key       2
                             :bordered  true
-                            ;:small true
                             :textStyle {:color (:accent palette)}
                             :style     {:borderWidth 0}
                             :onPress   #(do (reset! story-index index)
                                             (.push navigator "tabs"))}
-                           (show-icon palette)
-                           ;(txt "")
-                           ))
-        ))
-
-
+                           (show-icon palette)))))

 (rum/defcs page < rum/reactive
                   (rum/local 0 ::selection) (add-page-title "Scenarios")
@@ -146,6 +134,5 @@
                (concat [{:key   1
                          :style {:flex 1}}]
                        [(add-card! navigator palette)]
-                       [(map (partial story-card! navigator palette) (range story-count))]))
-        )
-      )))+                       ;[(story-card! navigator palette 0)]
+                       [(map (partial story-card! navigator palette) (range story-count))]))))))


(maint) Remove unused dependency from export and cleanup syntax

This commit removes the unused specter dependency from export.clj and
also uses a doseq for adding tar items to the tar-writer instead of a
complicated reduce.

--- src/puppetlabs/puppetdb/export.clj
+++ src/puppetlabs/puppetdb/export.clj
@@ -9,7 +9,6 @@
             [puppetlabs.puppetdb.factsets :as factsets]
             [puppetlabs.puppetdb.reports :as reports]
             [puppetlabs.puppetdb.utils :as utils]
-            [com.rpl.specter :as sp]
             [clj-time.format :as time-fmt]
             [clj-time.coerce :as time-coerce]
             [puppetlabs.puppetdb.schema :as pls]
@@ -81,6 +80,10 @@
                  (-> data (dissoc :hash) json/generate-pretty-string)
                  (json/generate-pretty-string data))}))

+(defn add-tar-entries [tar-writer entries]
+  (doseq [entry entries]
+    (utils/add-tar-entry tar-writer entry)))
+
 (defn export!*
   [tar-writer query-fn]
   (doseq [[entity unexpanded-fields query->wire-fn]
@@ -92,7 +95,7 @@
                                          (complete-unexpanded-fields query-fn unexpanded-fields)
                                          query->wire-fn
                                          (map #(export-data->tar-item entity %))
-                                         (reduce #(utils/add-tar-entry tar-writer %2) nil)))]]
+                                         (add-tar-entries tar-writer)))]]
     (query-fn entity query-api-version nil nil query-callback-fn)))

 (defn export!


Add Om components for building a list of available sidekiqs

--- src/sidequarter_frontend/core.cljs
+++ src/sidequarter_frontend/core.cljs
@@ -1,6 +1,9 @@
 (ns ^:figwheel-always sidequarter-frontend.core
+    (:require-macros [cljs.core.async.macros :refer [go]])
     (:require[om.core :as om :include-macros true]
-              [om.dom :as dom :include-macros true]))
+             [om.dom :as dom :include-macros true]
+             [cljs.core.async :refer [<!]]
+             [sidequarter-frontend.api :as api]))

 (enable-console-print!)

@@ -8,13 +11,38 @@

 ;; define your app data so that it doesn't get over-written on reload

-(defonce app-state (atom {:text "Hello world!"}))
+(defonce app-state (atom {}))
+
+(defn sidekiq-view [data owner]
+  (om/component
+   (dom/div #js {:className "sidekiq" :id (data :id)}
+            (dom/h3 nil (data :namespace))
+            (dom/p nil (data :application))
+            (dom/p nil (data :redis_url)))))
+
+(defn sidekiq-list [data owner]
+  (om/component
+   (apply dom/div #js {:className "sidekiq-list"}
+          (om/build-all sidekiq-view (:sidekiqs data)))))
+
+(defn sidekiq-box [data owner]
+  (reify
+    om/IWillMount
+    (will-mount [_]
+      (om/transact! data [:sidekiqs] (fn [] []))
+      (go
+        (let [response ((<! (api/get-sidekiqs)) :body)]
+          (om/update! data [:sidekiqs] (:sidekiqs response)))))
+    om/IRender
+    (render [_]
+      (dom/h1 nil "Sidekiqs")
+      (om/build sidekiq-list data))))

 (om/root
   (fn [data owner]
     (reify om/IRender
       (render [_]
-        (dom/h1 nil (:text data)))))
+        (dom/div nil (om/build sidekiq-box data)))))
   app-state
   {:target (. js/document (getElementById "app"))})

@@ -24,4 +52,3 @@
   ;; your application
   ;; (swap! app-state update-in [:__figwheel_counter] inc)
 )
-


Prior to insert, Transaction checks for existing

--- src/swanson/models/transaction.clj
+++ src/swanson/models/transaction.clj
@@ -18,15 +18,32 @@
   (jdbc/query db-spec
               (sql/select * :transactions (sql/where {:id id}))))

-(defn create
+(defn- create-record
+  "Inserts database row"
   [{:keys [amount date description]}]
   (let [converted-date (date-converter date)
         matching-category (matcher/match-description description)
         c (category/id matching-category)]
     (jdbc/insert! db-spec
-      :transactions
-      [:amount :date :category_id :description]
-      [amount converted-date c description])))
+                  :transactions
+                  [:amount :date :category_id :description]
+                  [amount converted-date c description])))
+
+(defn exists
+  "checks if the transaction record already exists"
+  [{:keys [amount date description]}]
+  (let [result
+        (jdbc/query db-spec
+                    ["SELECT COUNT(*) FROM transactions WHERE
+                     amount = ? AND
+                     date = date(?) AND
+                     description = ?" amount date description])]
+    (pos? (:count (first result)))))
+
+(defn create
+  "checks for existing record and inserts"
+  [transaction]
+  (when-not (exists transaction) (create-record transaction)))

 (def week-grouping-query
   "SELECT date_trunc('week', t.date) AS Week,
@@ -38,17 +55,6 @@

 (defn by-week []
   (jdbc/query db-spec [week-grouping-query]))
-
-(defn exists
-  "checks if the transaction record already exists"
-  [{:keys [amount date description]}]
-  (let [result
-        (jdbc/query db-spec
-                    ["SELECT COUNT(*) FROM transactions WHERE
-                     amount = ? AND
-                     date = date(?) AND
-                     description = ?" amount date description])]
-    (pos? (:count (first result)))))

 (defn all
   [limit]


Remove unused code

Remove unused code

--- src/discuss/utils/common.cljs
+++ src/discuss/utils/common.cljs
@@ -381,17 +381,6 @@
   [arg]
   (.log js/console arg))

-{:api/last-call ""
- :search/results []
- :layout/add? false
- :layout/error nil
- :layout/error? false  ;; for legacy support
- :layout/loading? false
- :layout/sidebar? false
- :layout/title "discuss"
- :layout/view :default
- :layout/view-next nil}
-
 (defn filter-keys-by-namespace
   "Filter a collection of vectors by their namespaces.


Include location information with `assert`.

--- src/active/clojure/condition.cljc
+++ src/active/clojure/condition.cljc
@@ -306,6 +306,13 @@
   make-who-condition who-condition?
   (who condition-who))

+(define-condition-type &location &condition
+  make-location-condition location-condition?
+  ;; any of these can be nil
+  (namespace location-condition-namespace)
+  (file location-condition-file)
+  (line location-condition-line))
+
 (define-condition-type
   ^{:doc "Throwable value that's not a condition."} &throwable &serious
   make-throwable throwable?
@@ -362,16 +369,26 @@
   logical true."
   ([x]
      (when *assert*
-       `(when-not ~x
-          (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
-                               (str "Assertion failed")
-                               '~x))))
+       (let [?ns (str *ns*)
+             ?file  (let [f *file*] (when (not= f "NO_SOURCE_PATH") f))
+             ;; TODO Waiting on http://dev.clojure.org/jira/browse/CLJ-865:
+             ?line  (:line (meta &form))]
+         `(when-not ~x
+            (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
+                                 (str "Assertion failed")
+                                 (make-location-condition '~?ns ~?file ~?line)
+                                 '~x)))))
   ([x message]
      (when *assert*
-       `(when-not ~x
-          (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
-                               (str "Assert failed: " ~message)
-                               '~x))))))
+       (let [?ns (str *ns*)
+             ?file  (let [f *file*] (when (not= f "NO_SOURCE_PATH") f))
+             ;; TODO Waiting on http://dev.clojure.org/jira/browse/CLJ-865:
+             ?line  (:line (meta &form))]
+         `(when-not ~x
+            (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
+                                 (str "Assert failed: " ~message)
+                                 (make-location-condition '~?ns ~?file ~?line)
+                                 '~x)))))))

 #?(:clj


Unroll the options before passing them on.

--- src/fm/simrunner/gui/view.clj
+++ src/fm/simrunner/gui/view.clj
@@ -136,8 +136,9 @@
                 :console       console}}))

 (defn simrunner-frame [& {:as options}]
-  (let [frame (apply gui/frame options)
-        view  (simrunner-view)]
+  (let [options (apply concat options)
+        frame   (apply gui/frame options)
+        view    (simrunner-view)]
     (-> frame
         :widget
         .getContentPane


Add notes

Add notes

--- src/grimoire/api/web/read.clj
+++ src/grimoire/api/web/read.clj
@@ -53,11 +53,13 @@
   (do-thing-req "all" ->Def namespace-thing))

 (defmethod api/thing->prior-versions :web [config thing]
+  ;; FIXME: this is entirely common to fs/read's thing->versions
   {:pre [(#{:version :namespace :def} (:type thing))]}
   (let [thing    (ensure-thing thing)
         currentv (thing->version thing)               ; version handle
         current  (normalize-version (:name currentv)) ; version string
-        added    (-> (api/read-meta config thing)
+        added    (-> (api/read-meta config thing)      ; FIXME: can Fail
+                    result                            ; FIXME: can throw AssertionException
                     (get :added "0.0.0")
                     normalize-version)                ; version string
         versions (->> (:parent currentv)


Refactors

Refactors

--- src/hundred_pushups/core.cljc
+++ src/hundred_pushups/core.cljc
@@ -76,15 +76,12 @@
 (s/fdef day->log
         :args (s/cat :day :exr/day
                      :ts :exr/ts))
-;; TODO - not sure forming and unforming is helping at all here
 (defn day->log [day ts]
-  (let [[action circuits] (s/conform :exr/day day)]
-    (case action
-      :do-circuits
-      (repeat (:exr/sets circuits)
-              (assoc (s/unform :exr/suggested-circuit (:exr/suggested-circuit circuits))
-                     :exr/ts ts))
-      :do-test [])))
+  (if (= day :exr/do-test)
+    []
+    (repeat (:exr/sets day)
+            (assoc (:exr/suggested-circuit day)
+                   :exr/ts ts))))

 (defn but-last-day [circuit-log]
   (->> circuit-log


Add some spacing to web app tests

Add some spacing to web app tests

--- test/comic_reader/web_app_test.clj
+++ test/comic_reader/web_app_test.clj
@@ -52,6 +52,7 @@
                     (test-system {:sites '("site-one"
                                            "site-two"
                                            "site-three")}))]
+
         (is (= (handle (mock/request :get "/api/v1/sites"))
                {:status 200
                 :headers edn-content-type
@@ -66,6 +67,7 @@
                                             {:id "other_comic"
                                              :name "Other Comic"
                                              :url "another_url"}]}}))]
+
         (is (= (handle (mock/request :get "/api/v1/manga-here/comics"))
                {:status 200
                 :headers edn-content-type
@@ -81,6 +83,7 @@
                                                            {:name "The Gamer 2",
                                                             :url "http://www.mangahere.co/manga/the_gamer/c002/",
                                                             :ch-num 2}]}}}))]
+
         (is (= (handle (mock/request :get "/api/v1/manga-here/the_gamer/chapters"))
                {:status 200
                 :headers edn-content-type
@@ -98,6 +101,7 @@
                                           {{:name "The Gamer 2", :url "http://www.mangahere.co/manga/the_gamer/c002/", :ch-num 2}
                                            [{:name "1", :url  "http://www.mangahere.co/manga/the_gamer/c002/"}
                                             {:name "2", :url  "http://www.mangahere.co/manga/the_gamer/c002/2.html"}]}}}))]
+
         (is (= (handle (-> (mock/request :post "/api/v1/manga-here/pages"
                                          (str
                                           "{:comic-chapter"
@@ -119,6 +123,7 @@
                                              {:src (str "http://a.mhcdn.net/store/manga/13739/095.0/compressed"
                                                         "/rthe-gamer-5978533.jpg?v=1440085982")
                                               :alt "The Gamer 95 Page 1"}]}}}))]
+
         (is (= (handle (-> (mock/request :post "/api/v1/manga-here/image"
                                          (str "{:comic-page {:name \"1\", :url "
                                               "\"http://www.mangahere.co/manga/the_gamer/c095/\"}}"))


Factor out HTTP methods

Factor out HTTP methods

--- test/icecap/handlers/http_test.clj
+++ test/icecap/handlers/http_test.clj
@@ -7,6 +7,14 @@
             [icecap.test-data :refer [simple-http-step simple-https-step]]
             [aleph.http :as h]
             [clojure.test :refer :all]))
+
+(def http-methods
+  #{:DELETE
+    :HEAD
+    :GET
+    :PATCH
+    :POST
+    :PUT})

 (deftest schema-tests
   (testing "valid steps"
@@ -40,13 +48,7 @@

          {:url (:url simple-http-step)
           :method :BOGUS}
-         '{:method (not (#{:DELETE
-                           :HEAD
-                           :GET
-                           :PATCH
-                           :POST
-                           :PUT}
-                         :BOGUS))})))
+         '{:method (not (http-methods :BOGUS))}

 (def fake-response
   ::my-fake-response)


un-reverse idle and live layers

un-reverse idle and live layers

--- src-cljs/frontend/components/canvas.cljs
+++ src-cljs/frontend/components/canvas.cljs
@@ -417,7 +417,7 @@
                                                       :selected? selected?
                                                       :part-of-group? part-of-group?
                                                       :layer-id id}))
-                                                 (sort live-ids))
+                                                 (sort idle-ids))
                                {:key :layer-id}))
           (apply dom/g #js {:className "layers live"}
                  (om/build-all layer-group (mapv (fn [id]
@@ -428,7 +428,7 @@
                                                       :selected? selected?
                                                       :part-of-group? part-of-group?
                                                       :layer-id id}))
-                                                 (sort idle-ids))
+                                                 (sort live-ids))
                                {:key :layer-id})))))))

 (defn subscriber-cursor-icon [tool]


Remove v2 opt in from header

Remove v2 opt in from header

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -10,7 +10,6 @@
             [frontend.components.instrumentation :as instrumentation]
             [frontend.components.license :as license]
             [frontend.components.statuspage :as statuspage]
-            [frontend.components.opt-in :as opt-in]
             [frontend.models.project :as project-model]
             [frontend.models.feature :as feature]
             [frontend.routes :as routes]
@@ -40,15 +39,12 @@
     (let [navigation-data (:navigation-data app)]
       (cond (:repo navigation-data) [:a.settings.project-settings
                                      {:href (routes/v1-project-settings navigation-data) }
-                                     (if (feature/enabled? :ui-v2)
-                                       [:img.dashboard-icon {:src (common/icon-path "QuickLink-Settings")}]
-                                       (common/ico :settings-light))
+                                     [:img.dashboard-icon {:src (common/icon-path "QuickLink-Settings")}]
                                      "Project Settings"]
             (:org navigation-data) [:a.settings.org-settings
                                     {:href (routes/v1-org-settings navigation-data)}
-                                    (if (feature/enabled? :ui-v2)
                                       [:img.dashboard-icon {:src (common/icon-path "QuickLink-Settings")}]
-                                      (common/ico :settings-light)) "Organization Settings"]
+                                    "Organization Settings"]
             :else nil))))

 (defn head-user [app owner]
@@ -64,17 +60,7 @@
             vcs-url (:vcs_url project)]
         (html
           [:div.head-user
-           [:ol.breadcrumb
-            (when (and (not (feature/enabled? :ui-v2)) (seq crumbs-data))
-              [:li
-               [:a {:title "home", :href "/"} [:i.fa.fa-home] " "]])
-            (crumbs/crumbs crumbs-data)]
-           (when (and (#{:dashboard :account} (:navigation-point app))
-                      (not (-> app :navigation-data :repo))
-                      (not (-> app :navigation-data :org))
-                      (feature/enabled? :ui-v2-opt-in-banner)
-                      (feature/enabled-in-cookie? :ui-v2))
-             (om/build opt-in/ui-v2-opt-out-ui app))
+           [:ol.breadcrumb (crumbs/crumbs crumbs-data)]
            (when (show-follow-project-button? app)
              (forms/managed-button
                [:button#follow-project-button
@@ -82,10 +68,10 @@
                  :data-spinner true}
                 "follow the " (vcs-url/repo-name vcs-url) " project"]))
            (settings-link app owner)
-           (when (and (feature/enabled? :ui-v2) (= :project-settings (:navigation-point app)))
+           (when (= :project-settings (:navigation-point app))
              [:a.settings {:href (routes/v1-dashboard-path {:org project-user :repo project-name})}
               (str "View " project-name " »")])
-           (when (and (feature/enabled? :ui-v2) (= :build (:navigation-point app)))
+           (when (= :build (:navigation-point app))
              (om/build build-head/build-head-actions app))])))))

 (defn head-admin [app owner]


Fix incorrect capitalization on tabIndex attrs

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -146,22 +146,22 @@
               [:ul.dropdown-menu
                [:li {:role "presentation"}
                 [:a {:role "menuitem"
-                     :tabindex "-1"
+                     :tabIndex "-1"
                      :href "/features"}
                  "Features"]]
                [:li {:role "presentation"}
                 [:a {:role "menuitem"
-                     :tabindex "-1"
+                     :tabIndex "-1"
                      :href "/mobile"}
                  "Mobile"]]
                [:li {:role "presentation"}
                 [:a {:role "menuitem"
-                     :tabindex "-1"
+                     :tabIndex "-1"
                      :href "/integrations/docker"}
                  "Docker"]]
                [:li {:role "presentation"}
                 [:a {:role "menuitem"
-                     :tabindex "-1"
+                     :tabIndex "-1"
                      :href "/enterprise"}
                  "Enterprise"]]]]
              (when-not (config/enterprise?)


default is a non-very well defined lens

default is a non-very well defined lens

--- test/active/clojure/lens_test.cljc
+++ test/active/clojure/lens_test.cljc
@@ -196,8 +196,13 @@
 (deftest default
   (let [l (lens/default 42)]
     (lens-laws-hold l nil 3 7)
-    ;; default is not a proper lens
-    (lens-laws-hold l 42 3 7)
+
+    ;; default is not a "very well behaved" lens [1]
+    #_(lens-laws-hold l 42 3 7)
+    ;; but it's probably "well behaved" [1]
+    (law-1-holds l nil 3)
+    (law-2-holds l nil)
+
     (is (= 42
            (lens/yank nil l)))
     (is (= 13
@@ -542,3 +547,9 @@
                           :list [5]}
                          proj
                          {:flup {:shmup -1 :blub "abc"}}))))))
+
+;; [1] J. Nathan Foster, Michael B. Greenwald, Jonathan T. Moore,
+;; Benjamin C. Pierce, and Alan Schmitt. “Combinators for
+;; Bidirectional Tree Transformations: A Linguistic Approach to the
+;; View Update Problem”. In: Principles of Programming Languages. ACM
+;; Press, 2005, pages 233-246. doi: 10.1145/1040305.1040325.


Refactor VT tests

Refactor VT tests

--- test/asciinema_player/vt_test.cljs
+++ test/asciinema_player/vt_test.cljs
@@ -379,42 +379,24 @@
   (let [vt (vt/make-vt 4 3)]

     (testing "printing within single line"
-      (let [{:keys [lines cursor]} (-> vt
-                                       (vt/print 0x41)
-                                       (vt/print 0x42)
-                                       (vt/print 0x43))]
+      (let [{:keys [lines cursor]} (vt/feed vt [0x41 0x42 0x43])]
         (is (= lines [[[0x41 {}] [0x42 {}] [0x43 {}] [0x20 {}]]
                       [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]
                       [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]]))
         (is (= cursor {:x 3 :y 0 :visible true}))))

     (testing "printing on the right edge of the line"
-      (let [{:keys [lines cursor]} (-> vt
-                                       (vt/print 0x41)
-                                       (vt/print 0x42)
-                                       (vt/print 0x43)
-                                       (vt/print 0x44))]
+      (let [{:keys [lines cursor]} (vt/feed vt [0x41 0x42 0x43 0x44])]
         (is (= lines [[[0x41 {}] [0x42 {}] [0x43 {}] [0x44 {}]]
                       [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]
                       [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]]))
         (is (= cursor {:x 0 :y 1 :visible true}))))

     (testing "printing on the bottom right edge of the screen"
-      (let [{:keys [lines cursor]} (-> vt
-                                       (vt/print 0x41)
-                                       (vt/print 0x41)
-                                       (vt/print 0x41)
-                                       (vt/print 0x41)
-                                       (vt/print 0x42)
-                                       (vt/print 0x42)
-                                       (vt/print 0x42)
-                                       (vt/print 0x42)
-                                       (vt/print 0x43)
-                                       (vt/print 0x43)
-                                       (vt/print 0x43)
-                                       (vt/print 0x43)
-                                       (vt/print 0x44)
-                                       (vt/print 0x44))]
+      (let [{:keys [lines cursor]} (vt/feed vt [0x41 0x41 0x41 0x41
+                                                0x42 0x42 0x42 0x42
+                                                0x43 0x43 0x43 0x43
+                                                0x44 0x44])]
         (is (= lines [[[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                       [[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                       [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]]))
@@ -425,216 +407,179 @@
       (assoc-in [:cursor :x] x)
       (assoc-in [:cursor :y] y)))

-(defn test-ind [action]
+(defn test-ind [inputs]
   (let [vt (-> (vt/make-vt 4 3)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x44)
-               (vt/print 0x44))]
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 0) action)]
+               (vt/feed [0x41 0x41 0x41 0x41
+                         0x42 0x42 0x42 0x42
+                         0x43 0x43 0x43 0x43
+                         0x44 0x44]))]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/feed inputs))]
       (is (= lines [[[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                     [[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 0))
       (is (= y 1)))
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 1 1) action)]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 1 1) (vt/feed inputs))]
       (is (= lines [[[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                     [[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 1))
       (is (= y 2)))
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 2) action)]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 2) (vt/feed inputs))]
       (is (= lines [[[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]
                     [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 2))
       (is (= y 2)))))

-(defn test-nel [action]
+(defn test-nel [inputs]
   (let [vt (-> (vt/make-vt 4 3)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x43)
-               (vt/print 0x44)
-               (vt/print 0x44))]
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 0) action)]
+               (vt/feed [0x41 0x41 0x41 0x41
+                         0x42 0x42 0x42 0x42
+                         0x43 0x43 0x43 0x43
+                         0x44 0x44]))]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/feed inputs))]
       (is (= lines [[[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                     [[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 0))
       (is (= y 1)))
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 1 1) action)]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 1 1) (vt/feed inputs))]
       (is (= lines [[[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                     [[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 0))
       (is (= y 2)))
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 2) action)]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 2) (vt/feed inputs))]
       (is (= lines [[[0x43 {}] [0x43 {}] [0x43 {}] [0x43 {}]]
                     [[0x44 {}] [0x44 {}] [0x20 {}] [0x20 {}]]
                     [[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 0))
       (is (= y 2)))))

-(defn test-hts [action]
+(defn test-hts [inputs]
   (let [vt (vt/make-vt 20 3)]
-    (let [{tabs :tabs} (-> vt (move-cursor 0 0) action)]
+    (let [{tabs :tabs} (-> vt (move-cursor 0 0) (vt/feed inputs))]
       (is (= tabs #{8 16})))
-    (let [{tabs :tabs} (-> vt (move-cursor 1 0) action)]
+    (let [{tabs :tabs} (-> vt (move-cursor 1 0) (vt/feed inputs))]
       (is (= tabs #{1 8 16})))
-    (let [{tabs :tabs} (-> vt (move-cursor 11 0) action)]
+    (let [{tabs :tabs} (-> vt (move-cursor 11 0) (vt/feed inputs))]
       (is (= tabs #{8 11 16})))
-    (let [{tabs :tabs} (-> vt (move-cursor 19 0) action)]
+    (let [{tabs :tabs} (-> vt (move-cursor 19 0) (vt/feed inputs))]
       (is (= tabs #{8 16 19})))))

-(defn test-ri [action]
+(defn test-ri [inputs]
   (let [vt (-> (vt/make-vt 4 3)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x41)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x42)
-               (vt/print 0x43)
-               (vt/print 0x43))]
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 1) action)]
+               (vt/feed [0x41 0x41 0x41 0x41
+                         0x42 0x42 0x42 0x42
+                         0x43 0x43]))]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 1) (vt/feed inputs))]
       (is (= lines [[[0x41 {}] [0x41 {}] [0x41 {}] [0x41 {}]]
                     [[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]
                     [[0x43 {}] [0x43 {}] [0x20 {}] [0x20 {}]]]))
       (is (= x 2))
       (is (= y 0)))
-    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 0) action)]
+    (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 0) (vt/feed inputs))]
       (is (= lines [[[0x20 {}] [0x20 {}] [0x20 {}] [0x20 {}]]
                     [[0x41 {}] [0x41 {}] [0x41 {}] [0x41 {}]]
                     [[0x42 {}] [0x42 {}] [0x42 {}] [0x42 {}]]]))
       (is (= x 2))
       (is (= y 0)))))

-(deftest execute-test
+(deftest control-char-test
   (let [vt (vt/make-vt 4 3)]
     (testing "0x00 (NUL)"
-      (is (= vt (vt/execute vt 0x00))))
+      (is (= vt (vt/feed-one vt 0x00))))

     (testing "0x01 (SOH)"
-      (is (= vt (vt/execute vt 0x01))))
+      (is (= vt (vt/feed-one vt 0x01))))

     (testing "0x02 (STX)"
-      (is (= vt (vt/execute vt 0x02))))
+      (is (= vt (vt/feed-one vt 0x02))))

     (testing "0x03 (ETX)"
-      (is (= vt (vt/execute vt 0x03))))
+      (is (= vt (vt/feed-one vt 0x03))))

     (testing "0x04 (EOT)"
-      (is (= vt (vt/execute vt 0x04))))
+      (is (= vt (vt/feed-one vt 0x04))))

     (testing "0x05 (ENQ)"
-      (is (= vt (vt/execute vt 0x05))))
+      (is (= vt (vt/feed-one vt 0x05))))

     (testing "0x06 (ACK)"
-      (is (= vt (vt/execute vt 0x06))))
+      (is (= vt (vt/feed-one vt 0x06))))

     (testing "0x07 (BEL)"
-      (is (= vt (vt/execute vt 0x07))))
+      (is (= vt (vt/feed-one vt 0x07))))

     (testing "0x08 (BS)"
-      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/execute 0x08))]
+      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/feed-one 0x08))]
         (is (= x 0))
         (is (= y 0)))
-      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 2 0) (vt/execute 0x08))]
+      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 2 0) (vt/feed-one 0x08))]
         (is (= x 1))
         (is (= y 0)))
-      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 2) (vt/execute 0x08))]
+      (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 2) (vt/feed-one 0x08))]
         (is (= x 0))
         (is (= y 2))))

     (testing "0x09 (HT)"
       (let [vt (vt/make-vt 20 3)]
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 0 0) (vt/feed-one 0x09))]
           (is (= x 8))
           (is (= y 0)))
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 2 0) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 2 0) (vt/feed-one 0x09))]
           (is (= x 8))
           (is (= y 0)))
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 8 1) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 8 1) (vt/feed-one 0x09))]
           (is (= x 16))
           (is (= y 1)))
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 9 1) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 9 1) (vt/feed-one 0x09))]
           (is (= x 16))
           (is (= y 1)))
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 16 1) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 16 1) (vt/feed-one 0x09))]
           (is (= x 16))
           (is (= y 1)))
-        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 19 1) (vt/execute 0x09))]
+        (let [{{x :x y :y} :cursor} (-> vt (move-cursor 19 1) (vt/feed-one 0x09))]
           (is (= x 19))
           (is (= y 1)))))

     (testing "0x0a (LF), 0x85 (NEL)"
       (doseq [ch [0x0a 0x85]]
-        (test-nel #(vt/execute % ch))))
+        (test-nel [ch])))

     (testing "0x0b (VT), 0x0c (FF), 0x84 (IND)"
         (doseq [ch [0x0b 0x0c 0x84]]
-          (test-ind #(vt/execute % ch))))
+          (test-ind [ch])))

     (testing "0x0d (CR)"
-      (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 1) (vt/execute 0x0d))]
+      (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 0 1) (vt/feed-one 0x0d))]
         (is (= x 0))
         (is (= y 1)))
-      (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 1) (vt/execute 0x0d))]
+      (let [{lines :lines {x :x y :y} :cursor} (-> vt (move-cursor 2 1) (vt/feed-one 0x0d))]
         (is (= x 0))
         (is (= y 1))))

     (testing "0x88 (HTS)"
-      (test-hts #(vt/execute % 0x88)))
+      (test-hts [0x88]))

     (testing "0x8d (RI)"
-      (test-ri #(vt/execute % 0x8d)))))
-
-(deftest collect-test
-  (let [vt (vt/make-vt 4 3)]
-    (is (= (-> vt (vt/collect 0x21) :parser :collect-chars) [0x21]))
-    (is (= (-> vt (vt/collect 0x21) (vt/collect 0x22) :parser :collect-chars) [0x21 0x22]))))
-
-(deftest param-test
-  (let [vt (vt/make-vt 4 3)]
-    (is (= (-> vt (vt/param 0x31) :parser :param-chars) [0x31]))
-    (is (= (-> vt (vt/param 0x31) (vt/param 0x32) :parser :param-chars) [0x31 0x32]))))
-
-(deftest esc-dispatch-test
-  (testing "0x44 (IND)"
-    (test-ind #(vt/esc-dispatch % 0x44)))
-
-  (testing "0x45 (NEL)"
-    (test-nel #(vt/esc-dispatch % 0x45)))
-
-  (testing "0x48 (HTS)"
-    (test-hts #(vt/esc-dispatch % 0x48)))
-
-  (testing "0x4d (RI)"
-    (test-ri #(vt/esc-dispatch % 0x4d))))
-
-(deftest feed-random-rubbish-test
+      (test-ri [0x8d]))))
+
+(deftest esc-sequence-test
+  (testing "0x1b 0x44 (IND)"
+    (test-ind [0x1b 0x44]))
+
+  (testing "0x1b 0x45 (NEL)"
+    (test-nel [0x1b 0x45]))
+
+  (testing "0x1b 0x48 (HTS)"
+    (test-hts [0x1b 0x48]))
+
+  (testing "0x1b 0x4d (RI)"
+    (test-ri [0x1b 0x4d])))
+
+(deftest random-rubbish-test
   (let [vt (vt/make-vt 80 24)
         vt (vt/feed vt (take 1000 (repeatedly #(rand-int 0xff))))]
     (is (not= nil (-> vt :parser :state)))))


Second test for function start-server-on-regular-machine

--- test/emender_jenkins/core_test.clj
+++ test/emender_jenkins/core_test.clj
@@ -172,6 +172,16 @@
             (is (= {:port 1000}  (start-server-on-regular-machine app "1000")))
             (is (= {:port 65534} (start-server-on-regular-machine app "65534")))
             (is (= {:port 65535} (start-server-on-regular-machine app "65535"))))))
+
+(deftest test-start-server-on-regular-machine-positive-2
+    (testing "jenkinscat.core/start-server"
+        ; use mock instead of jetty/run-jetty
+        (with-redefs [jetty/run-jetty (fn [app port] app)]
+            (is (= app (start-server-on-regular-machine app "1")))
+            (is (= app (start-server-on-regular-machine app "2")))
+            (is (= app (start-server-on-regular-machine app "1000")))
+            (is (= app (start-server-on-regular-machine app "65534")))
+            (is (= app (start-server-on-regular-machine app "65535"))))))

 (deftest test-show-help
     "Check the function emender-jenkins.core/show-help."


Reduce stuck peer batch-timeout.

Reduce stuck peer batch-timeout.

--- test/onyx/peer/stuck_peer_test.clj
+++ test/onyx/peer/stuck_peer_test.clj
@@ -61,12 +61,14 @@
               catalog [{:onyx/name :inc
                         :onyx/fn ::my-inc
                         :onyx/type :function
+                        :onyx/batch-timeout 1
                         :onyx/batch-size batch-size}

                        {:onyx/name :out
                         :onyx/plugin :onyx.plugin.core-async/output
                         :onyx/type :output
                         :onyx/medium :core.async
+                        :onyx/batch-timeout 1
                         :onyx/batch-size batch-size
                         :onyx/max-peers 1
                         :onyx/doc "Writes segments to a core.async channel"}]


Fix indentation on row-row lyrics.

Fix indentation on row-row lyrics.

--- src/kolmogorov_music/talk.clj
+++ src/kolmogorov_music/talk.clj
@@ -73,19 +73,18 @@

 (def row-row
   "A simple melody built from durations and pitches."
-  ; Row, row, row  your boat,
+              ; Row, row, row  your boat,
   (->> (phrase [3/3  3/3  2/3  1/3  3/3]
                [  0    0    0    1    2])
        (then
-         ; Gent-ly  down the  stream,
+                ; Gent-ly   down the  stream,
          (phrase [2/3  1/3  2/3  1/3  6/3]
                  [  2    1    2    3    4]))
-       (then
-         ; Merrily, merrily, merrily, merrily,
+       (then    ; Merrily, merrily, merrily, merrily,
          (phrase (repeat 12 1/3)
                  (mapcat (partial repeat 3) [7 4 2 0])))
        (then
-         ; Life  is   but  a    dream!
+                ; Life is   but  a    dream!
          (phrase [2/3  1/3  2/3  1/3  6/3]
                  [  4    3    2    1    0]))
        (canon/canon (canon/simple 4))


require boot-garden from new coordinates + update it

--- src/leiningen/new/tenzing.clj
+++ src/leiningen/new/tenzing.clj
@@ -80,13 +80,13 @@
   (cond-> []
           (om?      opts) (conj "org.omcljs/om \"0.8.6\"")
           (reagent? opts) (conj "reagent \"0.5.0\"")
-          (garden?  opts) (conj "boot-garden \"1.2.5-1\" :scope \"test\"")
+          (garden?  opts) (conj "org.martinklepsch/boot-garden \"1.2.5-3\" :scope \"test\"")
           (sass?    opts) (conj "mathias/boot-sassc  \"0.1.1\" :scope \"test\"")
           (less?    opts) (conj "deraen/boot-less \"0.2.1\" :scope \"test\"")))

 (defn build-requires [opts]
   (cond-> []
-          (garden? opts) (conj "'[boot-garden.core    :refer [garden]]")
+          (garden? opts) (conj "'[org.martinklepsch.boot-garden :refer [garden]]")
           (sass?   opts) (conj "'[mathias.boot-sassc  :refer [sass]]")
           (less?   opts) (conj "'[deraen.boot-less    :refer [less]]")))


allow nimbus and supervisor to share local dir

--- src/clj/backtype/storm/config.clj
+++ src/clj/backtype/storm/config.clj
@@ -72,8 +72,14 @@
 (defn read-yaml-config [name]
   (clojurify-structure (Utils/findAndReadConfigFile name true)))

+(defn master-local-dir [conf]
+  (let [ret (str (conf STORM-LOCAL-DIR) "/nimbus")]
+    (FileUtils/forceMkdir (File. ret))
+    ret
+    ))
+
 (defn master-stormdist-root [conf storm-id]
-  (str (conf STORM-LOCAL-DIR) "/stormdist/" storm-id))
+  (str (master-local-dir conf) "/stormdist/" storm-id))

 (defn master-stormjar-path [stormroot]
   (str stormroot "/stormjar.jar"))
@@ -85,12 +91,18 @@
   (str stormroot "/stormconf.ser"))

 (defn master-inbox [conf]
-  (let [ret (str (conf STORM-LOCAL-DIR) "/inbox")]
+  (let [ret (str (master-local-dir conf) "/inbox")]
     (FileUtils/forceMkdir (File. ret))
     ret ))

+(defn supervisor-local-dir [conf]
+  (let [ret (str (conf STORM-LOCAL-DIR) "/supervisor")]
+    (FileUtils/forceMkdir (File. ret))
+    ret
+    ))
+
 (defn supervisor-stormdist-root
-  ([conf] (str (conf STORM-LOCAL-DIR) "/stormdist"))
+  ([conf] (str (supervisor-local-dir conf) "/stormdist"))
   ([conf storm-id]
       (str (supervisor-stormdist-root conf) "/" storm-id)))

@@ -104,7 +116,7 @@
   (str stormroot "/stormconf.ser"))

 (defn supervisor-tmp-dir [conf]
-  (let [ret (str (conf STORM-LOCAL-DIR) "/tmp")]
+  (let [ret (str (supervisor-local-dir conf) "/tmp")]
     (FileUtils/forceMkdir (File. ret))
     ret ))

@@ -112,7 +124,7 @@
   (str stormroot "/" RESOURCES-SUBDIR))

 (defn ^LocalState supervisor-state [conf]
-  (LocalState. (str (conf STORM-LOCAL-DIR) "/localstate")))
+  (LocalState. (str (supervisor-local-dir conf) "/localstate")))

 (defn worker-root


Support one item gracefully

Support one item gracefully

--- src/clj/chili_dog_night/views.clj
+++ src/clj/chili_dog_night/views.clj
@@ -42,9 +42,11 @@
   (concat [" "] (reduce #(apply vector [% ", " %2]) coll)))

 (defn comma-separate-str [coll]
-  (str (reduce #(str % ", " %2) (drop-last coll))
+  (if (= (count coll) 1)
+    (first coll)
+    (str (reduce #(str % ", " %2) (drop-last coll))
        ", and "
-       (last coll)))
+       (last coll))))

 (defn gathering-partial [data]
   [:section


fixed names; generalized number of features

--- src/clj/forma/source/logistic.clj
+++ src/clj/forma/source/logistic.clj
@@ -73,17 +73,17 @@
   "returns a vector of updates for the parameter vector; the
   ridge-constant is a very small scalar, used to ensure that the
   inverted information matrix is non-singular."
-  [beta-seq label-seq features rdg-cons]
+  [beta-seq label-seq feature-mat rdg-cons]
   (let [num-features (count beta-seq)
         info-adj (.addi
-                  (info-matrix beta-seq features)
+                  (info-matrix beta-seq feature-mat)
                   (.muli (DoubleMatrix/eye (int num-features))
                          (float rdg-cons)))]
     (vec (.toArray
           (.mmul (Solve/solve
                   info-adj
-                  (DoubleMatrix/eye (int 20)))
-                 (score-seq beta-seq label-seq features))))))
+                  (DoubleMatrix/eye (int num-features)))
+                 (score-seq beta-seq label-seq feature-mat))))))

 (defn logistic-beta-vector
   "return the estimated parameter vector; which is used, in turn, to


change Heritage Committee to use card targeting

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -235,7 +235,8 @@
    {:effect (effect (draw 3)
                     (resolve-ability
                       {:prompt "Choose a card in HQ to put on top of R&D"
-                       :choices (req (:hand corp)) :not-distinct true
+                       :choices {:req #(and (in-hand? %)
+                                            (= (:side %) "Corp"))}
                        :msg "draw 3 cards and add 1 card from HQ to the top of R&D"
                        :effect (effect (move target :deck {:front true}))}
                      card nil))}