Add the ability to download the project zip with all pages in svg.

And improve the simple page svg download.

--- src/uxbox/main/ui/workspace/download.cljs
+++ src/uxbox/main/ui/workspace/download.cljs
@@ -6,17 +6,22 @@
 ;; Copyright (c) 2016 Juan de la Cruz <delacruzgarciajuan@gmail.com>

 (ns uxbox.main.ui.workspace.download
-  (:require [lentes.core :as l]
+  (:require [cuerdas.core :as str]
+            [promesa.core :as p]
+            [uxbox.main.data.lightbox :as udl]
+            [uxbox.main.exports :as exports]
             [uxbox.main.state :as st]
-            [uxbox.util.rstore :as rs]
-            [uxbox.main.data.lightbox :as udl]
             [uxbox.main.ui.icons :as i]
             [uxbox.main.ui.lightbox :as lbx]
-            [uxbox.main.exports :as exports]
+            [uxbox.main.ui.workspace.base :as wb]
             [uxbox.util.blob :as blob]
+            [uxbox.util.data :refer (read-string)]
+            [uxbox.util.datetime :as dt]
+            [uxbox.util.dom :as dom]
             [uxbox.util.mixins :as mx]
-            [uxbox.util.dom :as dom]
-            [uxbox.util.data :refer (read-string)]))
+            [uxbox.util.rstore :as rs]
+            [uxbox.util.zip :as zip]
+            [lentes.core :as l]))

 ;; --- Refs

@@ -38,18 +43,45 @@
 ;; --- Download Lightbox (Component)

 (defn- download-page-svg
-  [id]
-  (let [page (get-in @st/state [:pages-by-id id])
-        page-name (:name page)
-        content (exports/render-page id)
+  [{:keys [name id] :as page}]
+  (let [content (exports/render-page id)
         blob (blob/create content "image/svg+xml")
         uri  (blob/create-uri blob)
         link (.createElement js/document "a")
-        event (js/MouseEvent. "click")]
+        event (js/MouseEvent. "click")
+        now (dt/now)]

-    ;; FIXME: use str/slug for proper file naming
     (.setAttribute link "href" uri)
-    (.setAttribute link "download" (str page-name ".svg"))
+    (.setAttribute link "download" (str (str/uslug name) "_"
+                                        (dt/format now :unix)
+                                        ".svg"))
+
+    (.appendChild (.-body js/document) link)
+    (.dispatchEvent link event)
+    (blob/revoke-uri uri)
+    (.removeChild (.-body js/document) link)))
+
+(defn- generate-files
+  [pages]
+  (reduce (fn [acc {:keys [id name]}]
+            (let [content (exports/render-page id)]
+              (conj acc [(str (str/uslug name) ".svg")
+                         (blob/create content "image/svg+xml")])))
+          []
+          pages))
+
+(defn- download-project-zip
+  [{:keys [name] :as project} pages]
+  (p/alet [files (generate-files pages)
+           blob (p/await (zip/build files))
+           uri  (blob/create-uri blob)
+           link (.createElement js/document "a")
+           event (js/MouseEvent. "click")
+           now (dt/now)]
+    (.setAttribute link "href" uri)
+    (.setAttribute link "download" (str (str/uslug name) "_"
+                                        (dt/format now :unix)
+                                        ".zip"))

     (.appendChild (.-body js/document) link)
     (.dispatchEvent link event)
@@ -59,22 +91,28 @@
 (mx/defcs download-dialog
   {:mixins [mx/static mx/reactive]}
   [own]
-  (letfn [(on-close [event]
-            (dom/prevent-default event)
-            (udl/close!))
-          (download-page [event]
-            (dom/prevent-default event)
-            (let [id (-> (mx/ref-node own "page")
-                         (dom/get-value)
-                         (read-string))]
-              (download-page-svg id)
-              (udl/close!)))
-          (download-zip [event]
-            (dom/prevent-default event))
-          (download-html [event]
-            (dom/prevent-default event))]
-    (let [pages (mx/react pages-ref)
-          current (mx/react current-page-ref)]
+  (let [project (mx/react wb/project-ref)
+        pages (mx/react pages-ref)
+        current (mx/react current-page-ref)]
+    (letfn [(on-close [event]
+              (dom/prevent-default event)
+              (udl/close!))
+            (download-page [event]
+              (dom/prevent-default event)
+              (let [id (-> (mx/ref-node own "page")
+                           (dom/get-value)
+                           (read-string))
+                    page (->> pages
+                              (filter #(= id (:id %)))
+                              (first))]
+                (download-page-svg page)
+                (udl/close!)))
+            (download-zip [event]
+              (dom/prevent-default event)
+              (download-project-zip project pages)
+              (udl/close!))
+            (download-html [event]
+              (dom/prevent-default event))]
       [:div.lightbox-body.export-dialog
        [:h3 "Export options"]
        [:div.row-flex


duplicated sessions entry

duplicated sessions entry

--- src/celestial/api.clj
+++ src/celestial/api.clj
@@ -134,7 +134,7 @@
            (success {:msg "Deleted action" :id id})))

 (defroutes app-routes
-  system type environments sessions actions jobs sessions (friend/wrap-authorize users admin)
+  system type environments actions jobs sessions (friend/wrap-authorize users admin)
   (friend/wrap-authorize quotas admin) (route/not-found "Not Found"))

 (defn error-wrap


Fix docs for split

Fix docs for split

--- src/yetibot/core/commands/collections.clj
+++ src/yetibot/core/commands/collections.clj
@@ -121,9 +121,9 @@

 ; split
 (defn split
-  "split <string> # split string by provided character"
-  [{[_ split-str to-split] :match}]
-  (let [split-by (re-pattern split-str)]
+  "split <pattern> <string> # split string with <pattern>"
+  [{[_ split-by-str to-split] :match}]
+  (let [split-by (re-pattern split-by-str)]
     (s/split to-split split-by)))

 (cmd-hook #"split"


fix missed require

fix missed require

--- src_practitioner/practitioner/events.cljs
+++ src_practitioner/practitioner/events.cljs
@@ -2,6 +2,7 @@
   (:require-macros [reagent.ratom :refer [reaction]])
   (:require [reagent.core :as r]
             [re-frame.core :refer [dispatch subscribe reg-event-fx reg-event-db]]
+            [mobile-patient.lib.interceptor :refer [validate-spec]]
             [mobile-patient.ui :as ui]
             [clojure.string :as str]
             [mobile-patient.lib.services :as service]


CLJS-972: Node.js REPL eats errors in required ns when using require

Argh, stop eating ns errors. It is now the responsibility of REPLs to supply
semantics for `goog.require`

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -149,14 +149,13 @@

 (defn- display-error
   ([ret form]
-     (display-error ret form (constantly nil)))
+    (display-error ret form (constantly nil)))
   ([ret form f]
-     (when-not (and (seq? form) (= 'ns (first form)))
-       (f)
-       (println (:value ret))
-       (when-let [st (:stacktrace ret)]
-         (println st)
-         (flush)))))
+    (f)
+    (println (:value ret))
+    (when-let [st (:stacktrace ret)]
+      (println st)
+      (flush))))

 (defn evaluate-form
   "Evaluate a ClojureScript form in the JavaScript environment. Returns a


Remove extraneous `into`

Remove extraneous `into`

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -309,8 +309,7 @@
                          :major (.getMajor protocol-version)
                          :minor (.getMinor protocol-version)}
      :reason-phrase (.getReasonPhrase status)
-     :trace-redirects (mapv str
-                            (into [] (.getRedirectLocations context)))}))
+     :trace-redirects (mapv str (.getRedirectLocations context))}))

 (defn- get-conn-mgr
   [async? req]


Basic page template

Basic page template

--- src/cljs/ls/core.cljs
+++ src/cljs/ls/core.cljs
@@ -3,6 +3,8 @@
             [soda-ash.core :as sa]))

 (enable-console-print!)
+
+;; Let's see if we can trigger a proper deploy

 (defn menu []
   [:div.ui.large.secondary.inverted.pointing.menu


Add 'Workspace: ' to header

Add 'Workspace: ' to header

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspaces_list.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspaces_list.cljs
@@ -192,7 +192,7 @@
         [:div {:style {:padding "2em"}}
          [:span {:style {:fontSize "180%"}}
           (if selected-ws-id
-            (str (:namespace selected-ws-id) "/" (:name selected-ws-id))
+            (str "Workspace: " (:namespace selected-ws-id) "/" (:name selected-ws-id))
             "Workspaces")]]
         (if selected-ws-id
           ;; TODO: add 'back' function to nav


rename conflicting names

rename conflicting names

--- src/cljs/infinitelives/pixi/texture.cljs
+++ src/cljs/infinitelives/pixi/texture.cljs
@@ -3,13 +3,13 @@

 (defonce !texture-store (atom {}))

-(defn assoc!
+(defn add!
   "Add a texture object to the texture cache under
   the key `key`"
   [key texture]
   (swap! !texture-store assoc key texture))

-(defn dissoc!
+(defn remove!
   "Remove the texture keyed as `key` from the
   texture cache"
   [key]


adding delete document

adding delete document

--- src/clojure/my/company/superapp/main.clj
+++ src/clojure/my/company/superapp/main.clj
@@ -138,6 +138,10 @@
     )
 )

+;; document updater initator with dedicated update method for updating a document.
+;; update method handles the conflict error itself by re-reading the document,
+;; then calling your block again with the updated properties,
+;; and retrying the save. It will keep retrying until there is no conflict
 (defn document-updater
   []
   (let [updater (proxy [Document$DocumentUpdater] []
@@ -214,7 +218,6 @@

 ;; Create HTTPD-WSD instance
 (def httpd-wsd (new-httpd-wsd (int 5557) (int 5558) "0.0.0.0"))
-;; (def router (atom {}))

 ;; This is how an Activity is defined. We create one and specify its onCreate
 ;; method. Inside we create a user interface that consists of an edit and a
@@ -245,7 +248,7 @@

     ;; setup the couchbase database
     (log/i "creating manager")
-    ;; (*a) and "this" are the same
+    ;; should change (*a) "this" in production, this is easy for REPL
     (def manager (Manager. (AndroidContext. (*a)) (.get (.getField Manager "DEFAULT_OPTIONS") nil)))
     (.setStorageType manager "ForestDB")
     (log/i "creteing database")
@@ -265,6 +268,9 @@
     (log/i "updating data using update method hendler")
     (.update document (document-updater))
     (log/i (str "new data after using putProperties: " (.getProperties document)))
+
+    (log/i (str "deleting document: " (.delete document)))
+
     ;; starting servers
     ;; (toast "starting HTTPD-WSD servers" :long)
     (start-servers httpd-wsd)


Removed call to remove-alternation-padding

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -147,20 +147,19 @@
                            max-points maintain-ancestors] :as argmap}]
   (let [s1 (:genome parent1)
         s2 (:genome parent2)
-        new-genome (remove-alternation-padding
-                     (loop [i 0
-                            use-s1 (lrand-nth [true false])
-                            result-genome []]
-                       (if (or (>= i (count (if use-s1 s1 s2))) ;; finished current program
-                               (> (count result-genome) (* 2 max-points))) ;; runaway growth
-                         (seq result-genome);; Return, converting back into a sequence
-                         (if (< (lrand) alternation-rate)
-                           (recur (max 0 (+' i (Math/round (*' alignment-deviation (gaussian-noise-factor)))))
-                                  (not use-s1)
-                                  result-genome)
-                           (recur (inc i)
-                                  use-s1
-                                  (conj result-genome (nth (if use-s1 s1 s2) i)))))))]
+        new-genome (loop [i 0
+                          use-s1 (lrand-nth [true false])
+                          result-genome []]
+                     (if (or (>= i (count (if use-s1 s1 s2))) ;; finished current program
+                             (> (count result-genome) (* 2 max-points))) ;; runaway growth
+                       (seq result-genome);; Return, converting back into a sequence
+                       (if (< (lrand) alternation-rate)
+                         (recur (max 0 (+' i (Math/round (*' alignment-deviation (gaussian-noise-factor)))))
+                                (not use-s1)
+                                result-genome)
+                         (recur (inc i)
+                                use-s1
+                                (conj result-genome (nth (if use-s1 s1 s2) i))))))]
     (make-individual :genome new-genome
                      :history (:history parent1)
                      :ancestors (if maintain-ancestors


Added not-a-clone diversification test.

Added not-a-clone diversification test.

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -824,6 +824,12 @@
           {:genome (produce-child-genome-by-autoconstruction g g argmap)}
           argmap)))

+(defn not-a-clone-diversifying?
+  "Returns true iff genome g passes the diversification test."
+  [g {:keys [parent1-genome parent2-genome]}]
+  (and (not= g parent1-genome)
+       (not= g parent2-genome)))
+
 (defn three-gens-diff-diffs-diversifying?
   "Returns true iff genome g passes the diversification test."
   [g argmap]
@@ -1014,6 +1020,7 @@
      :use-mate-differently use-mate-differently-diversifying?
      :si-and-mate-use si-and-mate-use-diversifying?
      :no-clones no-clones-diversifying?
+     :not-a-clone not-a-clone-diversifying?
      :none (fn [genome argmap] true))
     g
     argmap))
@@ -1113,7 +1120,9 @@
                                              {:genome child-genome}
                                              argmap)))
                          nil)
-          variant (diversifying? child-genome argmap)
+          variant (diversifying? child-genome (-> argmap
+                                                  (assoc :parent1-genome parent1-genome)
+                                                  (assoc :parent2-genome parent2-genome)))
           use-child (or variant
                         (and autoconstructive-improve-or-diversify
                              (some (fn [[child-error parent1-error parent2-error]]


call to println fixed

call to println fixed

--- src/crawler/utils.clj
+++ src/crawler/utils.clj
@@ -216,4 +216,4 @@
   "println that prints to stderr"
   [& stuff]
   (binding [*out* *err*]
-    (println stuff)))
+    (apply println stuff)))


Remove redundant arg in apk install cmd

Remove redundant arg in apk install cmd

--- src/docker_clojure/dockerfile/shared.clj
+++ src/docker_clojure/dockerfile/shared.clj
@@ -31,7 +31,7 @@
          "rm -rf /var/lib/apt/lists/*"]

         :alpine
-        [(str/join " " (concat ["apk add --update --no-cache"] deps))]
+        [(str/join " " (concat ["apk add --no-cache"] deps))]

         nil))))


Load keystores from classpath rather than disk

This is due to IMMUTANT-606; app-relative doesn't work for non-dev wars

--- src/demo/web.clj
+++ src/demo/web.clj
@@ -2,7 +2,7 @@
   (:require [immutant.web                 :as web]
             [immutant.web.async           :as async]
             [immutant.web.middleware      :as mw]
-            [immutant.util                :as util]
+            [clojure.java.io              :as io]
             [demo.web.sse                 :as sse]
             [demo.web.http-kit-comparison :as hk]
             [compojure.route              :as route]
@@ -58,8 +58,8 @@
        "port" (env :demo-web-port 8080)
        "ssl-port" (env :ssl-port)
        "http2?" (env :http2?)
-       :keystore (util/app-relative "resources/server.keystore")
+       :keystore (io/resource "server.keystore")
        :key-password "password"
-       :truststore (util/app-relative "resources/server.truststore")
+       :truststore (io/resource "server.truststore")
        :trust-password "password"}
       args)))


Fix comment

Fix comment

--- src/fatlip/order.cljs
+++ src/fatlip/order.cljs
@@ -516,10 +516,10 @@
                   (rev graph)))))
      ;; This is sort of ugly, but once we order the nodes, we still have to
      ;; come up with a good subnode ordering. Conceptually, this belongs in
-     ;; SparseGraph->OrderedGraph, but it's also conceptually cromulent to have
-     ;; SparseGraph->OrderedGraph know nothing about the forward/reverse dance
+     ;; OrderedGraph->OrderedGraph, but it's also conceptually cromulent to have
+     ;; OrderedGraph->OrderedGraph know nothing about the forward/reverse dance
      ;; that we do here. However, subnode ordering is dependent on
-     ;; direction. My choice then, is to make SparseGraph->OrderedGraph
+     ;; direction. My choice then, is to make OrderedGraph->OrderedGraph
      ;; direction-aware, or pull the subnode ordering out and put it here,
      ;; where we're aware of the direction.  For now, I've chosen the latter.
      (map-indexed (fn [idx graph]


Cache JSON response

Cache JSON response

--- src/main/hbase_region_inspector/core.clj
+++ src/main/hbase_region_inspector/core.clj
@@ -1,10 +1,10 @@
 (ns hbase-region-inspector.core
   (:require [clojure.string :as str]
             [clojure.java.io :as io]
+            [cheshire.core :as json]
             [ring.adapter.jetty :refer [run-jetty]]
             [ring.util.response :refer [response content-type resource-response]]
             [ring.middleware.defaults :refer [wrap-defaults api-defaults site-defaults]]
-            [ring.middleware.json :refer [wrap-json-response]]
             [ring.middleware.gzip :refer [wrap-gzip]]
             [compojure.core :refer [defroutes GET PUT routes wrap-routes]]
             [compojure.route :as route]
@@ -25,7 +25,7 @@
 (defonce with-system? (atom true))

 ;;; Cache the result of previous inspection
-(defonce cached (atom {:updated-at nil :regions []}))
+(defonce cached (atom {:updated-at nil :regions [] :response {}}))

 ;;; Inspection interval
 (defonce update-interval (atom 10))
@@ -298,9 +298,10 @@
         servers (into {} (for [[k v] servers]
                            [k (assoc v :html (build-server-popover v))]))]
     (reset! cached {:updated-at now
-                    :regions new-regions
-                    :servers servers
-                    :tables  (group-by-tables new-regions)})))
+                    :regions    new-regions
+                    :servers    servers
+                    :tables     (group-by-tables new-regions)
+                    :response   {}})))

 (defn start-periodic-updater!
   "Starts a thread that periodically runs update-regions!"
@@ -313,6 +314,21 @@
         (catch Exception e
           (util/error e)))
       (recur))))
+
+(defn json-response
+  [data]
+  (-> data json/generate-string response))
+
+(defmacro cached-json-response
+  [[& keys] & forms]
+  (let [keys (vec keys)]
+    `(if-let [body# (get-in @cached [:response ~keys])]
+       (do
+         (util/debug (format "Returning cached JSON [%s]" (str ~keys)))
+         (response body#))
+       (let [json# (json/generate-string (do ~@forms))]
+         (swap! cached #(assoc-in % [:response ~keys] json#))
+         (response json#)))))

 ;;; Compojure route for web app
 (defroutes app-routes
@@ -337,7 +353,7 @@
        (util/debug (format "server_regions.json [%s]" remote))
        (let [tables (get params "tables[]" [])
              tables (if (instance? String tables) [tables] tables)]
-         (response
+         (cached-json-response ["server" sort metric tables]
            (regions-by-servers (merge (select-keys   @cached  [:regions :servers])
                                       {:metric       (keyword metric)
                                        :sort         (keyword sort)
@@ -351,7 +367,7 @@
        (util/debug (format "table_regions.json [%s]" remote))
        (let [tables (get params "tables[]" [])
              tables (if (instance? String tables) [tables] tables)]
-         (response
+         (cached-json-response ["table" sort metric tables]
            (regions-by-tables {:regions       (:regions @cached)
                                :table-summary (:tables @cached)
                                :metric        (keyword metric)
@@ -377,7 +393,7 @@
                    (recur (dec tries) "Region not yet moved")
                    (util/info "Region is moved")))))))
        (update-regions!)
-       (response {})))
+       (json-response {})))

 (defn wrap-exception [handler]
   (fn [request]
@@ -393,7 +409,6 @@
               (wrap-routes wrap-defaults site-defaults))
           (-> api-routes
               (wrap-routes wrap-defaults api-defaults)
-              wrap-json-response

               ;; Response middlewares
               wrap-gzip


Add a var to close over.

Add a var to close over.

--- test/benchmark_test/method_call_tests.clj
+++ test/benchmark_test/method_call_tests.clj
@@ -4,8 +4,9 @@

 (deftest fn-baseline-0
   (println "\nRunning: fn-baseline-0")
-  (let [f (fn [arg]
-            (str arg))]
+  (let [res "foo"
+        f (fn [arg]
+            (str res arg))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -13,9 +14,10 @@

 (deftest condp-benchmark-0
   (println "\nRunning: condp-benchmark-0")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -23,10 +25,11 @@

 (deftest condp-benchmark-1
   (println "\nRunning: condp-benchmark-1")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
               :foo_0 0
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -34,7 +37,8 @@

 (deftest condp-benchmark-2
   (println "\nRunning: condp-benchmark-2")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
               :foo_0 0
               :foo_1 1
@@ -46,7 +50,7 @@
               :foo_7 7
               :foo_8 8
               :foo_9 9
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -54,7 +58,8 @@

 (deftest condp-benchmark-3
   (println "\nRunning: condp-benchmark-3")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
               :foo_0 0
               :foo_1 1
@@ -76,7 +81,7 @@
               :foo_17 17
               :foo_18 18
               :foo_19 19
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -84,7 +89,8 @@

 (deftest condp-benchmark-4
   (println "\nRunning: condp-benchmark-4")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
               :foo_0 0
               :foo_1 1
@@ -116,7 +122,7 @@
               :foo_27 27
               :foo_28 28
               :foo_29 29
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -124,7 +130,8 @@

 (deftest condp-benchmark-5
   (println "\nRunning: condp-benchmark-5")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (condp = arg
               :foo_0 0
               :foo_1 1
@@ -166,7 +173,7 @@
               :foo_37 37
               :foo_38 38
               :foo_39 39
-              (str arg)))]
+              (str res arg)))]
     (cc/with-progress-reporting
       (cc/quick-bench
         (f "bar")
@@ -174,9 +181,10 @@

 (deftest if-condp-benchmark-0
   (println "\nRunning: if-condp-benchmark-0")
-  (let [f (fn [arg]
+  (let [res "foo"
+        f (fn [arg]
             (if (not (keyword? arg))
-              (str arg)
+              (str res arg)
               (condp = arg
                 :foo_0 0
                 :foo_1 1
@@ -225,7 +233,8 @@

 (deftest map-benchmark-0
   (println "\nRunning: map-benchmark-0")
-  (let [m {:bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -233,8 +242,9 @@

 (deftest map-benchmark-1
   (println "\nRunning: map-benchmark-1")
-  (let [m {:foo_0 0
-           :bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:foo_0 0
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -242,17 +252,18 @@

 (deftest map-benchmark-2
   (println "\nRunning: map-benchmark-2")
-  (let [m {:foo_0 0
-           :foo_1 1
-           :foo_2 2
-           :foo_3 3
-           :foo_4 4
-           :foo_5 5
-           :foo_6 6
-           :foo_7 7
-           :foo_8 8
-           :foo_9 9
-           :bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:foo_0 0
+           :foo_1 1
+           :foo_2 2
+           :foo_3 3
+           :foo_4 4
+           :foo_5 5
+           :foo_6 6
+           :foo_7 7
+           :foo_8 8
+           :foo_9 9
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -260,7 +271,8 @@

 (deftest map-benchmark-3
   (println "\nRunning: map-benchmark-3")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -280,7 +292,7 @@
            :foo_17 17
            :foo_18 18
            :foo_19 19
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -288,7 +300,8 @@

 (deftest map-benchmark-4
   (println "\nRunning: map-benchmark-4")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -318,7 +331,7 @@
            :foo_27 27
            :foo_28 28
            :foo_29 29
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -326,7 +339,8 @@

 (deftest map-benchmark-5
   (println "\nRunning: map-benchmark-5")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -366,7 +380,7 @@
            :foo_37 37
            :foo_38 38
            :foo_39 39
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((m :bar) "bar")
@@ -374,7 +388,8 @@

 (deftest map-cached-benchmark-0
   (println "\nRunning: map-cached-benchmark-0")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -414,7 +429,7 @@
            :foo_37 37
            :foo_38 38
            :foo_39 39
-           :bar (fn [arg] (str arg))}
+           :bar (fn [arg] (str res arg))}
         f (m :bar)]
     (cc/with-progress-reporting
       (cc/quick-bench
@@ -423,7 +438,8 @@

 (deftest map-rev-benchmark-0
   (println "\nRunning: map-rev-benchmark-0")
-  (let [m {:bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -431,8 +447,9 @@

 (deftest map-rev-benchmark-1
   (println "\nRunning: map-rev-benchmark-1")
-  (let [m {:foo_0 0
-           :bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:foo_0 0
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -440,17 +457,18 @@

 (deftest map-rev-benchmark-2
   (println "\nRunning: map-rev-benchmark-2")
-  (let [m {:foo_0 0
-           :foo_1 1
-           :foo_2 2
-           :foo_3 3
-           :foo_4 4
-           :foo_5 5
-           :foo_6 6
-           :foo_7 7
-           :foo_8 8
-           :foo_9 9
-           :bar (fn [arg] (str arg))}]
+  (let [res "foo"
+        m {:foo_0 0
+           :foo_1 1
+           :foo_2 2
+           :foo_3 3
+           :foo_4 4
+           :foo_5 5
+           :foo_6 6
+           :foo_7 7
+           :foo_8 8
+           :foo_9 9
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -458,7 +476,8 @@

 (deftest map-rev-benchmark-3
   (println "\nRunning: map-rev-benchmark-3")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -478,7 +497,7 @@
            :foo_17 17
            :foo_18 18
            :foo_19 19
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -486,7 +505,8 @@

 (deftest map-rev-benchmark-4
   (println "\nRunning: map-rev-benchmark-4")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -516,7 +536,7 @@
            :foo_27 27
            :foo_28 28
            :foo_29 29
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -524,7 +544,8 @@

 (deftest map-rev-benchmark-5
   (println "\nRunning: map-rev-benchmark-5")
-  (let [m {:foo_0 0
+  (let [res "foo"
+        m {:foo_0 0
            :foo_1 1
            :foo_2 2
            :foo_3 3
@@ -564,7 +585,7 @@
            :foo_37 37
            :foo_38 38
            :foo_39 39
-           :bar (fn [arg] (str arg))}]
+           :bar (fn [arg] (str res arg))}]
     (cc/with-progress-reporting
       (cc/quick-bench
         ((:bar m) "bar")
@@ -575,28 +596,28 @@
   (bar [_ arg]))

 (defrecord MyRec
-  []
+  [res]
   MyProt
   (foo [_] 0)
-  (bar [_ arg] (str arg)))
+  (bar [_ arg] (str res arg)))

 (deftest defrecord-benchmark-0
   (println "\nRunning: defrecord-benchmark-0")
-  (let [r (MyRec.)]
+  (let [r (MyRec. "foo")]
     (cc/with-progress-reporting
       (cc/quick-bench
         (.bar r "bar")
         :verbose))))

 (deftype MyType
-  []
+  [res]
   MyProt
   (foo [_] 0)
-  (bar [_ arg] (str arg)))
+  (bar [_ arg] (str res arg)))

 (deftest deftype-benchmark-0
   (println "\nRunning: deftype-benchmark-0")
-  (let [t (MyType.)]
+  (let [t (MyType. "foo")]
     (cc/with-progress-reporting
       (cc/quick-bench
         (.bar t "bar")


Update challenge_1_3_test.clj

Update challenge_1_3_test.clj

Small typo fix

--- test/workshop/jobs/challenge_1_3_test.clj
+++ test/workshop/jobs/challenge_1_3_test.clj
@@ -8,7 +8,7 @@
 ;; Function tasks aren't the only thing in workflows that can
 ;; branch. Inputs and outputs can branch, too. Let's try a more
 ;; complex workflow, shown below. We use single capital letters
-;; for tasks this time for concision in the exmaple. The graph
+;; for tasks this time for concision in the example. The graph
 ;; flows with inputs at the top and outputs at the bottom.
 ;;
 ;; A    B       C


call driver with source channel only

call driver with source channel only

--- cljx/plongeur-cljs/src/kierros/core.cljs
+++ cljx/plongeur-cljs/src/kierros/core.cljs
@@ -19,7 +19,9 @@
   (->> drivers
        (map (fn [[name driver]]
               (let [sink-proxy (sink-proxy-chans name)
-                    source     (driver sink-proxy name)]
+                    ;source     (driver sink-proxy name)
+                    source     (driver sink-proxy)
+                    ]
                 [name source])))
        (into {})))


OO: Call event.preventDefault on clicking language chooser

--- src/hatti/shared.cljs
+++ src/hatti/shared.cljs
@@ -102,7 +102,10 @@
     om/IRender
     (render [_]
       (let [{:keys [current all] :as ls} (om/observe owner (language-cursor))
-            update-current #(om/update! ls [:current] %)
+            get-update-handler (fn [language]
+                                 (fn [event]
+                                   (om/update! ls [:current] language)
+                                   (.preventDefault event)))
             stringify #(if (keyword? %) (name %) (str %))]
         (html
          [:div {:class "language-selector-inner"}
@@ -112,7 +115,7 @@
             (if (f/english? current) "EN" (stringify current))]
            [:i {:class "fa fa-angle-down" :style {:margin-left ".5em"}}]
            [:ul {:class "submenu"}
-            (for [l all]
-              [:li [:a {:href "#" :on-click #(update-current l)}
-                    (stringify l)]])]]
+            (for [language all]
+              [:li [:a {:href "#" :on-click (get-update-handler language)}
+                    (stringify language)]])]]
           [:div {:class "divider"}]])))))


Fix paginate implementation

Fix paginate implementation

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -838,15 +838,18 @@
    s sortby     SORTBY     code  "sort entries by function"
    c comparator COMPARATOR code  "sort by comparator function"
    m meta       META       edn   "metadata to set on each collection entry"]
-  (let [options (merge +paginate-defaults+ *opts*)
+  (let [{:keys [sortby comparator page-size prefix] :as options} (merge +paginate-defaults+ *opts*)
         grouper (fn [entries]
                   (->> entries
-                       (sort-by (:sortby options) (:comparator options))
-                       (partition-all (:page-size options))
-                       (map-indexed #(-> [(str (:prefix options) (inc %1) ".html")
+                       (sort-by sortby comparator)
+                       (partition-all page-size)
+                       (map-indexed #(-> [(str prefix (inc %1) ".html")
                                           {:entries %2}]))
                        (into {})))]
-    (assortment-impl "paginate" :io.perun/paginate grouper options)))
+    (assortment-pre-wrap {:task-name "paginate"
+                          :tracer :io.perun/paginate
+                          :grouper grouper
+                          :options options})))

 (deftask inject-scripts
   "Inject JavaScript scripts into html files.


Do not re-render the entries when assembling the board response since they already have everything they need.

--- src/oc/storage/representations/board.clj
+++ src/oc/storage/representations/board.clj
@@ -114,20 +114,10 @@
   {:user-id user-id
    :links (if (= access-level :author) [(remove-viewer-link org-slug slug user-id)] [])})

-(defn- comments
-  "Return a sequence of just the comments for an entry."
-  [{interactions :interactions}]
-  (filter :body interactions))
-
-(defn- reactions
-  "Return a sequence of just the reactions for an entry."
-  [{interactions :interactions}]
-  (filter :reaction interactions))
-
 (defn render-entry-for-collection
   "Create a map of the activity for use in a collection in the API"
   [org board entry access-level user-id]
-  (entry-rep/render-entry-for-collection org board entry (comments entry) (reactions entry) access-level user-id))
+  (entry-rep/render-entry-for-collection org board entry (entry-rep/comments entry) (entry-rep/reactions entry) access-level user-id))

 (defn render-board-for-collection
   "Create a map of the board for use in a collection in the REST API"
@@ -146,12 +136,9 @@
   (let [access-level (:access-level ctx)
         rep-props (if (or (= :author access-level) (= :viewer access-level))
                       representation-props
-                      public-representation-props)
-        fixed-entries (map #(render-entry-for-collection org board % access-level (-> ctx :user :user-id))
-                       (:entries board))]
+                      public-representation-props)]
     (json/generate-string
       (-> board
         (board-links (:slug org) sort-type access-level params)
-        (select-keys rep-props)
-        (assoc :entries fixed-entries))
+        (select-keys rep-props))
       {:pretty config/pretty?})))


finally understand creator bug and come up with elegant issue - a macro that unrolls args array in creator and calls e.g. Ocean. directly

--- dada-core/src/main/clojure/org/dada/core.clj
+++ dada-core/src/main/clojure/org/dada/core.clj
@@ -310,26 +310,32 @@

   )

+(defmacro defcreator [class-name field-names]
+  `(proxy [Creator] []
+     (^{:tag ~class-name} create [#^{:tag (type (into-array Object []))} args#]
+      (apply (fn [~@field-names] (~(symbol (str (name class-name) "." )) ~@field-names)) args#))))
+
+;; TODO - split out  defgetter and defattribute
 (defmacro def-record-metadata [var-name class-name fields & [version-comparator]]
   `(do
      (defrecord ~class-name ~fields)
      (def ^Metadata ~var-name
 	  (MetadataImpl.
-	   (record-creator ~class-name)
+	   (defcreator ~class-name ~fields)
 	   (list ~@(map keyword (filter (fn [field] (:primary-key (meta field))) fields)))
 	   (list ~@(map keyword (filter (fn [field] (:version-key (meta field))) fields)))
 	   (proxy [Metadata$VersionComparator] [] (compareTo [lhs# rhs#] (~version-comparator lhs# rhs#)))
 	   (list
 	    ~@(map
 	       (fn [field]
-		   (let [m (meta field)
-			 key (keyword field)
-			 tag (or (:tag m) Object)]
-		     `(Attribute.
-		       ~key
-		       ~tag
-		       ~(not (or (:primary-key m) (:immutable m)))
-		       (proxy [Getter] [] (^{:tag ~tag} get [^{:tag ~class-name} datum#] (~(symbol (str "." (name key))) datum#))))))
+		 (let [m (meta field)
+		       key (keyword field)
+		       tag (or (:tag m) Object)]
+		   `(Attribute.
+		     ~key
+		     ~tag
+		     ~(not (or (:primary-key m) (:immutable m)))
+		     (proxy [Getter] [] (^{:tag ~tag} get [^{:tag ~class-name} datum#] (~(symbol (str "." (name key))) datum#))))))
 	       fields))
 	   ))
      ))


Make "lein jar" trim :source-path from packed files, not simply "src"

--- src/leiningen/jar.clj
+++ src/leiningen/jar.clj
@@ -6,6 +6,7 @@
         [clojure.contrib.str-utils :only [str-join re-sub]]
         [clojure.contrib.java-utils :only [file]])
   (:import [java.util.jar Manifest JarEntry JarOutputStream]
+           [java.util.regex Pattern]
            [java.io BufferedOutputStream FileOutputStream
             ByteArrayInputStream]))

@@ -27,16 +28,20 @@

 (defmulti copy-to-jar (fn [project jar-os spec] (:type spec)))

+(defn- trim-leading-str [s to-trim]
+  (re-sub (re-pattern (str "^" (Pattern/quote to-trim))) "" s))
+
 (defmethod copy-to-jar :path [project jar-os spec]
   (doseq [child (file-seq (file (:path spec)))]
     (when-not (.isDirectory child)
-      (let [path (unix-path (str child))
-            path (re-sub (re-pattern (str "^" (unix-path (:root project))))
-                         "" path)
-            path (re-sub #"^/resources" "" path)
-            path (re-sub #"^/classes" "" path)
-            path (re-sub #"^/src" "" path)
-            path (re-sub #"^/" "" path)]
+      (let [path (reduce trim-leading-str
+                         (unix-path (str child))
+                         [(unix-path (:root project))
+                          "/"
+                          "resources"
+                          "classes"
+                          (:source-path project)
+                          "/"])]
         (.putNextEntry jar-os (JarEntry. path))
         (copy child jar-os)))))


Add conversion for energy units

Add conversion for energy units

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -39,6 +39,7 @@

 (defn convert-units-f [from to]
   (let [factors   {[:lb-per-cu-ft :kg-per-m3] 16.0185
+                   [:ft-lb :J]                1.35582
                    [:m :ft]                   3.28084
                    [:kg :lb]                  2.20462262185
                    [:psi :kPa]                6.894757293168361
@@ -47,6 +48,8 @@
                    [:m3 :bbl]                 6.28981077}
         converter {[:lb-per-cu-ft :kg-per-m3] #(* % (factors [:lb-per-cu-ft :kg-per-m3]))
                    [:kg-per-m3 :lb-per-cu-ft] #(/ % (factors [:lb-per-cu-ft :kg-per-m3]))
+                   [:ft-lb :J]                #(* % (factors [:ft-lb :J]))
+                   [:J :ft-lb]                #(/ % (factors [:ft-lb :J]))
                    [:ft :m]                   #(/ % (factors [:m :ft]))
                    [:m :ft]                   #(* % (factors [:m :ft]))
                    [:lb :kg]                  #(/ % (factors [:kg :lb]))


column resizing works

column resizing works

--- src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
@@ -67,7 +67,7 @@
           [:b {} (str left-num " - " right-num)] (str " of " (pluralize num-total " result"))]

          (style/create-unselectable :div {:style {:float "left" :display "inline-block" :width "50%"
-                                                 :padding "1.6em 0em" :verticalAlign "middle" :textAlign "center"}}
+                                                  :padding "1.6em 0em" :verticalAlign "middle" :textAlign "center"}}
           [:div {:style {:display "inline-block" :padding "0.55em 0.9em"
                          :color (if allow-prev (:button-blue style/colors) (:border-gray style/colors))
                          :cursor (when allow-prev "pointer")}
@@ -133,9 +133,11 @@

 (react/defc AdvancedTable
   {:get-initial-state
-   (fn []
+   (fn [{:keys [props]}]
      {:rows-per-page 10
-      :current-page 1})
+      :current-page 1
+      :column-widths (mapv #(:starting-width %) (:columns props))
+      :dragging? false})
    :render
    (fn [{:keys [state props]}]
      [:div {}
@@ -143,20 +145,38 @@
                   :parent-state state}]
       [:div {:style {:overflowX "auto"}}
        [:div {:style {:display "inline-block" :position "relative"
-                      :minWidth (reduce + (map #(:starting-width %) (:columns props)))}}
-        (map
-          (fn [column]
-            [:div {:style {:float "left" :width (:starting-width column)}} (:header-component column)])
-          (:columns props))
+                      :minWidth (reduce + (:column-widths @state))
+                      :cursor (when (:dragging? @state) "ew-resize")}
+              :onMouseUp (fn [e]
+                           (when (:dragging? @state)
+                             (swap! state assoc :dragging? false)
+                             (let [widths (:column-widths @state)
+                                   current-width (nth widths (:drag-column @state))
+                                   drag-amount (- (.-clientX e) (:drag-start @state))]
+                               (swap! state assoc :column-widths
+                                 (assoc widths (:drag-column @state) (+ current-width drag-amount))))))}
+        (style/create-unselectable :div {:style {:whiteSpace "nowrap" :overflow "hidden" :textOverflow "clip"}}
+          [:div {}
+           (map-indexed
+             (fn [col-num column]
+               (let [width (nth (:column-widths @state) col-num)]
+                 [:div {:style {:float "left" :position "relative" :width width}}
+                  (when (get column :resizable? true)
+                    [:div {:style {:float "right" :position "absolute" :width 4 :top 0 :bottom 0 :left (- width 4)
+                                   :cursor "ew-resize"}
+                           :onMouseDown (fn [e] (swap! state assoc
+                                                  :dragging? true :drag-start (.-clientX e) :drag-column col-num))}])
+                  (:header-component column)]))
+             (:columns props))])
         [:div {:style {:clear "both"}}]

         (map-indexed
           (fn [row-num row]
             [:div ((:row-props props) row-num row)
              (map-indexed (fn [col-num col]
-                    [:div {:style {:width (:starting-width col) :float "left"
-                                   :whiteSpace "nowrap" :overflow "hidden" :textOverflow "ellipsis"}}
-                     ((:cell-renderer col) row-num row)])
+                            [:div {:style {:width (nth (:column-widths @state) col-num) :float "left"
+                                           :whiteSpace "nowrap" :overflow "hidden" :textOverflow "ellipsis"}}
+                             ((:cell-renderer col) row-num row)])
                (:columns props))
              [:div {:style {:clear "both"}}]])
           (take (:rows-per-page @state)


unecessary to execute multiple times

unecessary to execute multiple times

--- src/clojure/test/leela/blackbox/storage/cassandra_test.clj
+++ src/clojure/test/leela/blackbox/storage/cassandra_test.clj
@@ -85,7 +85,5 @@
       (storage/putlink cluster "0x00" "0x03")

       (storage/dellink cluster "0x00")
-      (storage/dellink cluster "0x00")
-      (storage/dellink cluster "0x00")
       (is (= [] (storage/getlink cluster "0x00" "0x"))))
       ))


another benchmark case for map values transform

--- scripts/benchmarks.clj
+++ scripts/benchmarks.clj
@@ -88,10 +88,23 @@
     ))

+(defn- update-pair [[k v]]
+  [k (inc v)])
+
+(defn manual-similar-reduce-kv [data]
+  (reduce-kv
+    (fn [m k v]
+      (let [[newk newv] (update-pair [k v])]
+        (assoc m newk newv)))
+    {}
+    data
+    ))
+
 (let [data {:a 1 :b 2 :c 3 :d 4}]
   (run-benchmark "transform values of a map" 6 1000000
     (into {} (for [[k v] data] [k (inc v)]))
     (reduce-kv (fn [m k v] (assoc m k (inc v))) {} data)
+    (manual-similar-reduce-kv data)
     (transform [ALL LAST] inc data)
     ))


Rename c-program-state to c-app-state

Rename c-program-state to c-app-state

--- src/musicbox/one.cljs
+++ src/musicbox/one.cljs
@@ -112,7 +112,7 @@
 (let [canvas-id "canvas"
       draw-ctx (util/get-ctx canvas-id)
       instrument (update-size (create-instrument (scales/c-minor)) canvas-id)
-      c-program-state (chan)
+      c-app-state (chan)
       c-instrument (chan)
       c-orientation-change (util/listen js/window :orientation-change)
       c-touch-start (util/listen (dom/getElement canvas-id) :touchstart)
@@ -120,7 +120,7 @@

   (go
    (<! c-touch-start) (<! c-touch-end) ;; start after first touch so don't break sound
-   (>! c-program-state "start"))
+   (>! c-app-state "start"))

   (go
    (draw-start-screen draw-ctx)
@@ -132,7 +132,7 @@
              (recur instrument))))))

   (go
-   (<! c-program-state)
+   (<! c-app-state)
    (loop [instrument instrument]
      (>! c-instrument instrument)
      (let [[data c] (alts! [c-touch-start c-touch-end


Tweak nml-parse debugging code

Tweak nml-parse debugging code

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -103,10 +103,10 @@
   (let [result (parse s :start start :optimize :memory)]
 ;;   (let [parses (insta/parses parse s)]
 ;;     (binding [*out* *err*]
-;;       (println (count parses))
 ;;       (doseq [parse parses]
 ;;         (println parse)
-;;         (println))))
+;;         (println)))
+;;       (println (str "### " (count parses))))
     (if (insta/failure? result)
       (let [{t :text l :line c :column} result]
         (fail (str "Error parsing " src " at line " l " column " c ":")


Drop each of the collections rather than dropping the whole DB, speeds up test time

--- test/circle/backend/build/test_utils.clj
+++ test/circle/backend/build/test_utils.clj
@@ -254,7 +254,8 @@

 (defn clear-test-db []
   (mongo/with-mongo (test-db-connection)
-    (mongo/drop-database! :mongoid_test_test)))
+    (doseq [c (filter #(not= "system.indexes" %) (mongo/collections))]
+      (mongo/drop-coll! c))))

 (defn ensure-test-db []
   (clear-test-db)


Comment form-params

Comment form-params

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -261,7 +261,7 @@

 (defn extract-app [req] (first (ssplit ((:headers req) "host"))))

-(defn pipe-instance [req app]
+(defn pipe-instance [req app]
   (if-let [instances (get-in @router [:instances app])]
     (if (seq instances)
       (if-let [instance (rand-nth (vec (clojure.set/difference (set instances) (:unhealthy @router))))]
@@ -271,7 +271,7 @@
                       (let [q (:query-string req)] (if (clojure.string/blank? q) "" (str "?" q))))
             :method (:request-method req)
             :headers (:headers req)
-            :form-params (:form-params req)
+                                        ;:form-params (:form-params req)
             :body (:body req)
             :user-agent ((:headers req) "user-agent")}
            #(send! channel {:status (:status %)


Add full support for read/write to stream of byte buffers.

--- src/octet/buffer.cljx
+++ src/octet/buffer.cljx
@@ -140,7 +140,94 @@
       (.getBytes buff pos tmpbuf)
       tmpbuf))
   (write-bytes [buff pos size data]
-    (.setBytes buff pos data 0 size)))
+    (.setBytes buff pos data 0 size))
+
+  IBufferLimit
+  (get-capacity [buff]
+    (.capacity buff)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; A vector of buffers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn- stream-operation
+  [opfn buff pos]
+  (reduce (fn [pos buff]
+            (let [buffsize (get-capacity buff)]
+                (if (>= pos buffsize)
+                  (- pos buffsize)
+                  (reduced (opfn buff pos)))))
+            pos buff))
+
+(extend-type #+clj clojure.lang.IPersistentVector
+             #+cljs cljs.core.PersistentVector
+  IBufferShort
+  (read-short [buff pos]
+    (assert (every? #(satisfies? IBufferShort %) buff))
+    (stream-operation read-short buff pos))
+
+  (write-short [buff pos value]
+    (assert (every? #(satisfies? IBufferShort %) buff))
+    (stream-operation #(write-short %1 %2 value) buff pos))
+
+  IBufferInt
+  (read-int [buff pos]
+    (assert (every? #(satisfies? IBufferInt %) buff))
+    (stream-operation read-int buff pos))
+
+  (write-int [buff pos value]
+    (assert (every? #(satisfies? IBufferInt %) buff))
+    (stream-operation #(write-int %1 %2 value) buff pos))
+
+  IBufferLong
+  (read-long [buff pos]
+    (assert (every? #(satisfies? IBufferLong %) buff))
+    (stream-operation read-long buff pos))
+
+  (write-long [buff pos value]
+    (assert (every? #(satisfies? IBufferLong %) buff))
+    (stream-operation #(write-long %1 %2 value) buff pos))
+
+
+  IBufferFloat
+  (read-float [buff pos]
+    (assert (every? #(satisfies? IBufferFloat %) buff))
+    (stream-operation read-float buff pos))
+
+  (write-float [buff pos value]
+    (assert (every? #(satisfies? IBufferLong %) buff))
+    (stream-operation #(write-float %1 %2 value) buff pos))
+
+  IBufferDouble
+  (read-double [buff pos]
+    (assert (every? #(satisfies? IBufferDouble %) buff))
+    (stream-operation read-double buff pos))
+
+  (write-double [buff pos value]
+    (assert (every? #(satisfies? IBufferDouble %) buff))
+    (stream-operation #(write-double %1 %2 value) buff pos))
+
+  IBufferByte
+  (read-byte [buff pos]
+    (assert (every? #(satisfies? IBufferByte %) buff))
+    (stream-operation read-byte buff pos))
+
+  (write-byte [buff pos value]
+    (assert (every? #(satisfies? IBufferByte %) buff))
+    (stream-operation #(write-byte %1 %2 value) buff pos))
+
+  IBufferBytes
+  (read-bytes [buff pos size]
+    (assert (every? #(satisfies? IBufferBytes %) buff))
+    (stream-operation #(read-bytes %1 %2 size) buff pos))
+
+  (write-bytes [buff pos size data]
+    (assert (every? #(satisfies? IBufferByte %) buff))
+    (stream-operation #(write-bytes %1 %2 size data) buff pos))
+
+  IBufferLimit
+  (get-capacity [buff]
+    (reduce #(+ %1 (get-capacity %2)) 0 buff)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; ES6 Typed Arrays


Cleaned up color definitions

Cleaned up color definitions


Allow passing a custom error function for screens

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -106,21 +106,19 @@
   [n & {:keys [] :as options}]
   `(defonce ~n (defgame* ~options)))

-(defn set-screen!
-  "Creates a [Screen](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Screen.html)
-object, sets it as the screen for the `game`, and runs the functions from
-`screens` in the order they are provided in
-
-    (set-screen! hello-world main-screen text-screen)"
-  [^Game game & screens]
+(defn set-screen-with-options!
+  "Internal use only"
+  [^Game game screens error-fn]
   (let [add-inputs! (fn []
                       (input! :set-input-processor (InputMultiplexer.))
                       (doseq [{:keys [input-listeners]} screens]
                         (doseq [listener input-listeners]
                           (add-input! listener))))
         run-fn! (fn [k & args]
-                  (doseq [screen screens]
-                    (apply (get screen k) args)))]
+                  (try
+                    (doseq [screen screens]
+                      (apply (get screen k) args))
+                    (catch Exception e (error-fn e))))]
     (.setScreen game (reify Screen
                        (show [this] (add-inputs!) (run-fn! :show))
                        (render [this d] (run-fn! :render d))
@@ -130,6 +128,15 @@
                        (resume [this] (run-fn! :resume))
                        (dispose [this])))))

+(defn set-screen!
+  "Creates a [Screen](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Screen.html)
+object, sets it as the screen for the `game`, and runs the functions from
+`screens` in the order they are provided in
+
+    (set-screen! hello-world main-screen text-screen)"
+  [game & screens]
+  (set-screen-with-options! game screens #(throw %)))
+
 (defn update!
   "Runs the equivalent of `(swap! screen-atom assoc ...)`, where `screen-atom`
 is the atom storing the screen map behind the scenes, and returns the new screen


Add color-text helper function.

Add color-text helper function.

--- src/puget/printer.clj
+++ src/puget/printer.clj
@@ -54,10 +54,16 @@
       text)))

-(defn- delimiter
-  "Colors a delimiter apropriately."
-  [delim]
-  (color-doc :delimiter delim))
+(defn color-text
+  "Produces text colored according to the active color scheme. This is mostly
+  useful to clients which want to produce output which matches data printed by
+  Puget, but which is not directly printed by the library. Note that this
+  function still obeys the *colored-output* var."
+  [element text]
+  (let [codes (seq (*color-scheme* element))]
+    (if (and *colored-output* codes)
+      (str (ansi/esc codes) text (ansi/escape :none))
+      text)))

@@ -102,26 +108,26 @@
                          (map canonize (rest s)))
                    (map canonize s))]
     [:group
-     (delimiter "(")
+     (color-doc :delimiter "(")
      [:align (interpose :line elements)]
-     (delimiter ")")]))
+     (color-doc :delimiter ")")]))

 (defmethod canonize clojure.lang.IPersistentVector
   [v]
   [:group
-   (delimiter "[")
+   (color-doc :delimiter "[")
    [:align (interpose :line (map canonize v))]
-   (delimiter "]")])
+   (color-doc :delimiter "]")])

 (defmethod canonize clojure.lang.IPersistentSet
   [s]
   (let [entries (sort data/total-order (seq s))]
     [:group
-     (delimiter "#{")
+     (color-doc :delimiter "#{")
      [:align (interpose :line (map canonize entries))]
-     (delimiter "}")]))
+     (color-doc :delimiter "}")]))

 (defn- canonize-map
@@ -131,9 +137,9 @@
                      (sort-by first data/total-order)
                      (map canonize-kv))]
     [:group
-     (delimiter "{")
+     (color-doc :delimiter "{")
      [:align (interpose [:span "," :line] entries)]
-     (delimiter "}")]))
+     (color-doc :delimiter "}")]))

 (defmethod canonize clojure.lang.IPersistentMap
@@ -146,7 +152,7 @@
   (if *strict-mode*
     (throw (IllegalArgumentException.
              (str "No canonical representation for " (class r) ": " r)))
-    [:span (delimiter "#") (-> r class .getName) (canonize-map r)]))
+    [:span (color-doc :delimiter "#") (-> r class .getName) (canonize-map r)]))

 (prefer-method canonize clojure.lang.IRecord clojure.lang.IPersistentMap)


Simplify because clojure

Simplify because clojure

--- src/riemann/index.clj
+++ src/riemann/index.clj
@@ -77,9 +77,8 @@
       (search [this query-ast]
         "O(n) unless the query is for exactly a host and service"
         (if-let [[host service] (query-for-host-and-service query-ast)]
-          (if-let [e (.lookup this host service)]
-            (list e)
-            (list))
+          (when-let [e (.lookup this host service)]
+            (list e))
           (let [matching (query/fun query-ast)]
             (filter matching (.values hm)))))


added extended formatter for slack using attachments

--- src/riemann/slack.clj
+++ src/riemann/slack.clj
@@ -8,11 +8,41 @@
   "Escape message according to slack formatting spec."
   (escape message {\< "<" \> ">" \& "&"}))

-(defn- default-formatter [events]
+(defn default-formatter [events]
   {:text (str "*Host:* " (:host events)
               " *State:* " (:state events)
               " *Description:* " (:description events)
               " *Metric:* " (:metric events))})
+
+(defn extended-formatter [events]
+  {:text "This event requires your attention!",
+   :attachments
+   [{:fallback
+     (slack-escape
+       (str
+         "*Description:* "
+         (:description events)
+         " *Host:* "
+         (:host events)
+         " *Metric:* "
+         (:metric events)
+         " *State:* "
+         (:state events))),
+     :text (slack-escape (or (:description events) "")),
+     :pretext "Event properties:",
+     :color
+     (case (:state events) "ok" "good" "critical" "danger" "warning"),
+     :fields
+     [{:title "Host",
+       :value (slack-escape (or (:host events) "-")),
+       :short true}
+      {:title "Service",
+       :value (slack-escape (or (:service events) "-")),
+       :short true}
+      {:title "Metric", :value (or (:metric events) "-"), :short true}
+      {:title "State",
+       :value (slack-escape (or (:state events) "-")),
+       :short true}]}]})

 (defn slack
   "Posts events into a slack.com channel using Incoming Webhooks.


Address PR comments

Address PR comments

--- ingest-app/src/cmr/ingest/api/ingest.clj
+++ ingest-app/src/cmr/ingest/api/ingest.clj
@@ -90,9 +90,8 @@
    (update result
           :warnings
           (fn [warnings]
-            (if (coll? warnings)
-             (map #(str warning-context %) warnings)
-             (apply str warning-context warnings))))))
+            (when (seq warnings)
+              (map #(str warning-context %) warnings))))))

 (defmulti generate-ingest-response
   "Convert a result to a proper response format"
@@ -104,13 +103,13 @@
   ;; ring-json middleware will handle converting the body to json
   {:status (ingest-status-code result)
    :headers {"Content-Type" (mt/format->mime-type :json)}
-   :body (contextualize-warnings result)})
+   :body result})

 (defmethod generate-ingest-response :xml
   [headers result]
   {:status (ingest-status-code result)
    :headers {"Content-Type" (mt/format->mime-type :xml)}
-   :body (result-map->xml (contextualize-warnings result))})
+   :body (result-map->xml result)})

 (defmulti generate-validate-response
   "Convert a result to a proper response format"
@@ -123,7 +122,7 @@
   (if (seq result)
     {:status 200
      :headers {"Content-Type" (mt/format->mime-type :json)}
-     :body (contextualize-warnings result)}
+     :body result}
     {:status 200}))

 (defmethod generate-validate-response :xml
@@ -131,7 +130,7 @@
   (if (seq result)
    {:status 200
     :headers {"Content-Type" (mt/format->mime-type :xml)}
-    :body (result-map->xml (contextualize-warnings result))}
+    :body (result-map->xml result)}
    {:status 200}))

 (defn- invalid-revision-id-error
@@ -241,7 +240,7 @@
     (let [validate-response (ingest/validate-and-prepare-collection request-context
                                                                     concept
                                                                     validation-options)]
-      (generate-validate-response headers (util/remove-nil-keys (select-keys validate-response [:warnings]))))))
+      (generate-validate-response headers (util/remove-nil-keys (select-keys (contextualize-warnings validate-response) [:warnings]))))))

 (defn ingest-collection
   [provider-id native-id request]
@@ -252,10 +251,11 @@
           validation-options (get-validation-options headers)]
       (info (format "Ingesting collection %s from client %s"
                     (concept->loggable-string concept) (:client-id request-context)))
-      (generate-ingest-response headers (ingest/save-collection
+      (generate-ingest-response headers (contextualize-warnings
+                                         (ingest/save-collection
                                           request-context
                                           (set-user-id concept request-context headers)
-                                          validation-options)))))
+                                          validation-options))))))

 (defn delete-collection
   [provider-id native-id request]
@@ -269,7 +269,7 @@
     (acl/verify-ingest-management-permission request-context :update :provider-object provider-id)
     (info (format "Deleting collection %s from client %s"
                   (pr-str concept-attribs) (:client-id request-context)))
-    (generate-ingest-response headers (ingest/delete-concept request-context concept-attribs))))
+    (generate-ingest-response headers (contextualize-warnings (ingest/delete-concept request-context concept-attribs)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Granule API Functions


use defonce properly

use defonce properly

--- example/src/via/example/client/core.cljs
+++ example/src/via/example/client/core.cljs
@@ -9,7 +9,7 @@
 ;;   You must not remove this notice, or any others, from this software.

 (ns ^:figwheel-always via.example.client.core
-  (:require [via.example.client.system :refer [system]]
+  (:require [via.example.client.system :as app]
             [com.stuartsierra.component :as component]
             [taoensso.timbre :as log]))

@@ -17,6 +17,6 @@

 (defn start-system
   []
-  (component/start (system)))
+  (component/start (app/system)))

-(defonce (start-system))
+(defonce system (start-system))


:bug: Fix call to GoToPage in viewer

:bug: Fix call to GoToPage in viewer

--- frontend/src/uxbox/view/data/viewer.cljs
+++ frontend/src/uxbox/view/data/viewer.cljs
@@ -93,7 +93,7 @@

 (defn go-to-page
   [id]
-  (GoToPage id))
+  (GoToPage. id))

 ;; --- Toggle Flag


scheduler: tests: Fix a test that was incorrectly passing before.

(It was specifying incorrect behavior, where the head-of-considerable
WAS matched, yet matched-head? was false).

--- scheduler/test/cook/test/mesos/scheduler.clj
+++ scheduler/test/cook/test/mesos/scheduler.clj
@@ -258,8 +258,8 @@
           (is (zero? (count (:upgrade-backfill result))))
           (is (= 1 (count (:backfill-jobs result))))
           (is (not (:matched-head? result)))))
-      (testing "Match the tail, but the head isn't considerable" ;;TODO is this even correct?
-        (let [result (sched/process-matches-for-backfill [j1 j4] j4 [j4])]
+      (testing "Match the tail, but the head isn't considerable"
+        (let [result (sched/process-matches-for-backfill [j1 j4] j5 [j4])]
           (is (zero? (count (:fully-processed result))))
           (is (zero? (count (:upgrade-backfill result))))
           (is (= 1 (count (:backfill-jobs result))))


Add "Started:" to running builds.

Add "Started:" to running builds.

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -1351,11 +1351,23 @@
                                          :stop (or (:queued_at build) (:stop_time build))})
      " waiting for builds to finish"]))

-(defn build-finished-status [{stop-time :stop_time
-                              start-time :start_time
+(defn build-running-status [{start-time :start_time
+                             :as build}]
+  {:pre [(some? start-time)]}
+  [:div.summary-item
+   [:span.summary-label "Started: "]
+   [:span.start-time
+    {:title (datetime/full-datetime start-time)}
+    (om/build common/updating-duration
+              {:start start-time}
+              {:opts {:formatter datetime/time-ago-abbreviated}})
+    " ago"]])
+
+(defn build-finished-status [{start-time :start_time
+                              stop-time :stop_time
                               :as build}]
-  {:pre [(some? stop-time)
-         (some? start-time)]}
+  {:pre [(some? start-time)
+         (some? stop-time)]}
   [:div.summary-item
    [:span.summary-label "Finished: "]
    [:span.stop-time
@@ -1400,8 +1412,10 @@
             [:div.summary-items
              [:div.summary-item
               (builds-table/build-status-badge build)]
-             (when (:stop_time build)
-               (build-finished-status build))]
+             (when (:start_time build)
+               (if-not (:stop_time build)
+                 (build-running-status build)
+                 (build-finished-status build)))]
             [:div.summary-items
              (om/build previous-build-label build)
              [:div.summary-item
@@ -1415,7 +1429,7 @@
               [:div.summary-items
                [:div.summary-item
                 [:span.summary-label "Queued: "]
-                [:span  (queued-time build)]]])
+                [:span (queued-time build)]]])

             [:div.summary-build-contents
              [:div.summary-item


Remove pointless do form.

Remove pointless do form.

--- src/afterglow/controllers/ableton_push_2.clj
+++ src/afterglow/controllers/ableton_push_2.clj
@@ -1611,14 +1611,13 @@
             (.draw graphics (java.awt.geom.Line2D$Double.
                              (dec Wayang/DISPLAY_WIDTH) (- Wayang/DISPLAY_HEIGHT 9)
                              (- Wayang/DISPLAY_WIDTH 8) (- Wayang/DISPLAY_HEIGHT 2)))))
-      (do
-        (let [font  (get-display-font :condensed-light Font/ITALIC 36)
-              text  "No effects are active."
-              width (calculate-text-width graphics font text)]
-          (.setFont graphics font)
-          (.setPaint graphics no-effects-active-color)
-          (.drawString graphics text (int (math/round (- (/ Wayang/DISPLAY_WIDTH 2) (/ width 2))))
-                       (/ Wayang/DISPLAY_HEIGHT 2)))))))
+      (let [font  (get-display-font :condensed-light Font/ITALIC 36)
+            text  "No effects are active."
+            width (calculate-text-width graphics font text)]
+        (.setFont graphics font)
+        (.setPaint graphics no-effects-active-color)
+        (.drawString graphics text (int (math/round (- (/ Wayang/DISPLAY_WIDTH 2) (/ width 2))))
+                     (/ Wayang/DISPLAY_HEIGHT 2))))))

 (declare enter-stop-mode)


Add record def and protocol implementation

--- src/clj/jest/compiler/NativeJestCompiler.clj
+++ src/clj/jest/compiler/NativeJestCompiler.clj
@@ -390,12 +390,17 @@

 (defn -visitRecordDef
   [this ^JestParser$RecordDefContext ctx]
-  (throw (new NotImplementedException)))
+
+  `(defrecord ~(get-symbol ctx name)
+     [~@(map #(symbol (.. % getText)) (merge-items (. ctx first) (. ctx field)))]
+     ~@(apply concat (map #(.. this (visitImplementationDef %)) (. ctx implementationDef)))))

 (defn -visitImplementationDef
   [this ^JestParser$ImplementationDefContext ctx]
-  (throw (new NotImplementedException)))
+
+  (into [(get-symbol ctx protocol)]
+        (map #(.. this (visitMethodDef %)) (. ctx methodDef))))

 (defn -visitMethodParams
@@ -477,7 +482,6 @@
     `(let [~@bindings] ~@expressions)))

-
 (defn -visitConditional
   [this ^JestParser$ConditionalContext ctx]


Allow parentheses-altering instructions.

--- src/clojush/problems/classification/penn.clj
+++ src/clojush/problems/classification/penn.clj
@@ -25,15 +25,15 @@
   (let [f (slurp* (str "src/clojush/problems/classification/data/"  ;; todo?: allow command-line arg
                        ;"GAMETES_Epistasis_2-Way_20atts_0.4H_EDM-1_1.txt"
                        ;"a_5000s_2000her_0.1__maf_0.2_EDM-1_01.txt"
-                       "xor_2_a_20s_1600_EDM-1_01.txt"
-                       ;"xor_3_a_20s_1600_EDM-1_01.txt"
+                       ;"xor_2_a_20s_1600_EDM-1_01.txt"
+                       "xor_3_a_20s_1600_EDM-1_01.txt"
                        ;"xor_4_a_20s_1600_EDM-1_01.txt"
                        ))
         lines (csv/parse-csv f :delimiter \tab)]
     (println "Total number of data lines:" (count lines))
     (mapv #(mapv read-string %) lines)))

-(def training-proportion 0.1) ;; proportion of training cases to use each generation
+(def training-proportion 0.2) ;; proportion of training cases to use each generation

 (def resampling false)

@@ -135,7 +135,7 @@
                     (for [n (map inc
                                  (range (count (:inputs (first (:train @penn-fitness-cases))))))]
                       (symbol (str "in" n)))
-                    (concat (registered-for-stacks [:exec :integer :boolean])
+                    (concat (registered-for-stacks [:exec :integer :boolean :parentheses])
                             '(string_pop string_dup string_dup_times string_dup_items
                                          string_swap string_rot string_flush string_eq string_stackdepth
                                          string_yank string_yankdup string_shove string_empty))))
@@ -183,4 +183,3 @@
    ;:autoconstructive-entropy 0.1
    })

-


Change the namespace to match the new file name

--- spec/frereth_server/auth-socket_spec.clj
+++ spec/frereth_server/auth-socket_spec.clj
@@ -1,4 +1,4 @@
-(ns frereth-server.authentication-spec
+(ns frereth-server.auth-socket-spec
   (:require [frereth-server.authentication :as auth]
             [frereth-server.config :as config]
             [frereth-server.system :as sys]


Update deps

Update deps

--- src/leiningen/new/clanhr_service/project.clj
+++ src/leiningen/new/clanhr_service/project.clj
@@ -17,7 +17,7 @@
                  [clanhr/reply "0.5.0"]
                  [clanhr/validators "0.5.2"]
                  [clanhr/auth "0.4.0"]
-                 [clanhr/analytics "1.2.3"]
+                 [clanhr/analytics "1.4.0"]
                  [clanhr/ring-test-client "0.1.0"]
                  [clanhr/postgres-gateway "0.9.3"]
                  [clanhr/memory-gateway "0.8.0"]]


Don't run over state if volunteering for same task.

--- src/onyx/log/commands/volunteer_for_task.clj
+++ src/onyx/log/commands/volunteer_for_task.clj
@@ -75,26 +75,12 @@

 (defmethod select-job :onyx.job-scheduler/greedy
   [{:keys [args]} replica]
-  (let [job (first (universally-executable-jobs replica))]
+  (let [job (first (universally-executable-jobs replica))
+        allocation (common/peer->allocated-job (:allocations replica) (:id args))]
     (if job
       (if-let [task (select-task replica job (:id args))]
-        (-> replica
-            (common/remove-peers args)
-            (update-in [:allocations job task] conj (:id args))
-            (update-in [:allocations job task] vec)
-            (assoc-in [:peer-state (:id args)] :warming-up)
-            (offer-acker job task args))
-        replica)
-      replica)))
-
-(defmethod select-job :onyx.job-scheduler/round-robin
-  [{:keys [args]} replica]
-  (if-not (common/saturated-cluster? replica)
-    (let [candidates (universally-executable-jobs replica)
-          job (or (common/find-job-needing-peers replica candidates)
-                  (common/round-robin-next-job replica candidates))]
-      (if job
-        (if-let [task (select-task replica job (:id args))]
+        (if (or (not= task (:task allocation))
+                (not= job (:job allocation)))
           (-> replica
               (common/remove-peers args)
               (update-in [:allocations job task] conj (:id args))
@@ -102,6 +88,28 @@
               (assoc-in [:peer-state (:id args)] :warming-up)
               (offer-acker job task args))
           replica)
+        replica)
+      replica)))
+
+(defmethod select-job :onyx.job-scheduler/round-robin
+  [{:keys [args]} replica]
+  (if-not (common/saturated-cluster? replica)
+    (let [candidates (universally-executable-jobs replica)
+          allocation (common/peer->allocated-job (:allocations replica) (:id args))
+          job (or (common/find-job-needing-peers replica candidates)
+                  (common/round-robin-next-job replica candidates))]
+      (if job
+        (if-let [task (select-task replica job (:id args))]
+          (if (or (not= task (:task allocation))
+                  (not= job (:job allocation)))
+            (-> replica
+                (common/remove-peers args)
+                (update-in [:allocations job task] conj (:id args))
+                (update-in [:allocations job task] vec)
+                (assoc-in [:peer-state (:id args)] :warming-up)
+                (offer-acker job task args))
+            replica)
+          replica)
         replica))
     replica))

@@ -109,6 +117,7 @@
   [{:keys [args]} replica]
   (let [candidates (universally-executable-jobs replica)
         balanced (common/percentage-balanced-workload replica)
+        allocation (common/peer->allocated-job (:allocations replica) (:id args))
         job
         (reduce
          (fn [_ job]
@@ -120,12 +129,15 @@
          candidates)]
     (if job
       (if-let [task (select-task replica job (:id args))]
-        (-> replica
-            (common/remove-peers args)
-            (update-in [:allocations job task] conj (:id args))
-            (update-in [:allocations job task] vec)
-            (assoc-in [:peer-state (:id args)] :warming-up)
-            (offer-acker job task args))
+        (if (or (not= task (:task allocation))
+                (not= job (:job allocation)))
+          (-> replica
+              (common/remove-peers args)
+              (update-in [:allocations job task] conj (:id args))
+              (update-in [:allocations job task] vec)
+              (assoc-in [:peer-state (:id args)] :warming-up)
+              (offer-acker job task args))
+          replica)
         replica)
       replica)))


no need for defun

no need for defun

--- src/open_company/representations/company.clj
+++ src/open_company/representations/company.clj
@@ -52,7 +52,7 @@
           (links :delete)         (conj (delete-link company))
           (links :section-list)   (conj (section-list-link company)))))))

-(defun- company-links
+(defn- company-links
   "Add the HATEAOS links to the company"
   [company links]
   (assoc company :links (company-links* company links)))


tighten up; remove unnecessary things

tighten up; remove unnecessary things

--- src/tailrecursion/boot/middleware/hoplon.clj
+++ src/tailrecursion/boot/middleware/hoplon.clj
@@ -3,12 +3,9 @@
     [clojure.java.io                          :refer [file make-parents]]
     [tailrecursion.boot.deps                  :refer [deps]]
     [tailrecursion.boot.tmpregistry           :refer [mk mkdir exists? unmk]]
-    [tailrecursion.boot.middleware.cljsbuild  :refer [cljsbuild]]
     [tailrecursion.hoplon.compiler.compiler   :refer [install-deps compile-dir]]))

 (def dfl-opts     {:source-dir "src/html"})
-(def cljs         (-> identity cljsbuild))
-(def update-keys  #(into {} (map (fn [[k v]] [(apply %2 k %&) v]) %1)))
 (def update-vals  #(into {} (map (fn [[k v]] [k (apply %2 v %&)]) %1)))

 (defn hoplon [handler]


throw error if more than one match found for conjugations

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -650,9 +650,9 @@
       (if (empty? conjugations)
         (throw (Exception. (str "no conjugation found for infinitive: " infinitive))))
       (if (not (empty? (rest conjugations)))
-        (log/warn (str "more than one conjugation found for infinitive:'" infinitive "': "
-                       (string/join "," (vec (set conjugations)))
-                       "; word: " (dag_unify.core/strip-refs word))))
+        (throw (Exception. (str "more than one conjugation found for infinitive:'" infinitive "': "
+                                (string/join "," (vec (set conjugations)))
+                                "; word: " (dag_unify.core/strip-refs word)))))
       (first conjugations))))

 (defn irregular-imperfect-1sing? [word]


remove comment

remove comment

--- src/clj/infinitelives/pixi/pixelfont.clj
+++ src/clj/infinitelives/pixi/pixelfont.clj
@@ -38,7 +38,6 @@
                  (partition-by second)
                  (map count))
             )]
-    ;strip-sizes
     (partition 2 (for [n (range (count strip-sizes))]
                    (apply + (case dim :y y1 :x x1) (take (inc n) strip-sizes))))))


Adapt `blend` snippet. Issue #255.

Adapt `blend` snippet. Issue #255.

--- src/cljc/quil/snippets/image/pixels.cljc
+++ src/cljc/quil/snippets/image/pixels.cljc
@@ -7,34 +7,33 @@

 (defsnippet blend
   "blend"
-  {}
+  {:setup (q/no-loop)}

   (q/background 255 100 20 50)

-  (let [gr (q/create-graphics 50 50)
-        modes [:blend :add :subtract :darkest :lightest :difference :exclusion
-               :multiply :screen :overlay :hard-light :soft-light :dodge :burn]
+  (let [im (q/create-image 50 50 #?(:clj :rgb))
+        modes [#?(:cljs :replace) :blend :add #?(:clj :subtract) :darkest
+               :lightest :difference :exclusion :multiply :screen
+               :overlay :hard-light :soft-light :dodge :burn]
         splitted (partition-all 5 modes)]
-    (comment "draw 3 circles of different color on the graphics")
-    (q/with-graphics gr
-      (q/background 40 200 255 200)
-      (q/fill 255 0 0)
-      (q/ellipse 12 12 20 20)
-      (q/fill 0 255 0)
-      (q/ellipse 38 12 20 20)
-      (q/fill 0 0 255)
-      (q/ellipse 25 38 20 20))
-
-    (comment "all possible blended modes")
+    (comment "draw 3 squares of different color on the graphics")
+    (dotimes [x 10]
+      (dotimes [y 10]
+        (q/set-pixel im (+ x 10) (+ y 10) (q/color 255 0 0))
+        (q/set-pixel im (+ x 30) (+ y 10) (q/color 0 255 0))
+        (q/set-pixel im (+ x 20) (+ y 30) (q/color 0 0 255))))
+    #?(:cljs (q/update-pixels im))
+
+    (comment "draw all possible blended modes")
     (dotimes [row (count splitted)]
       (dotimes [col (count (nth splitted row))]
         (let [mode (nth (nth splitted row) col)]
           (comment "blend with sketch itself")
           (q/blend 400 0 50 50 (* col 55) (* row 55) 50 50 mode)
-          (comment "blend with graphics")
-          (q/blend gr 0 0 50 50 (* col 55) (+ 170 (* row 55)) 50 50 mode)
-          (comment "blend graphics to graphics")
-          (q/blend gr (q/current-graphics) 0 0 50 50 (* col 55) (+ 340 (* row 55)) 50 50 mode))))))
+          (comment "blend with image")
+          (q/blend im 0 0 50 50 (* col 55) (+ 170 (* row 55)) 50 50 mode)
+          (comment "blend image to image")
+          (q/blend im (q/current-graphics) 0 0 50 50 (* col 55) (+ 340 (* row 55)) 50 50 mode))))))

 (defsnippet copy
   "copy"


Minor changes on message format on ctrl channel on websocket handler.

--- src/clojure/catacumba/impl/websocket.clj
+++ src/clojure/catacumba/impl/websocket.clj
@@ -68,7 +68,7 @@
            (a/<! (send! ws (str value)))
            (recur))
          (do
-           (a/put! ctrl [:close])
+           (a/put! ctrl [:close nil])
            (hp/try-on (.close ws))
            (hp/try-on (.close this)))))
      (try
@@ -82,7 +82,7 @@
    (a/put! in (.getData msg) (fn [_] (.execute callback nil))))

   (^void onClose [this]
-   (a/put! ctrl [:close])
+   (a/put! ctrl [:close nil])
    (.close this)))

 (defn websocket


adding view map function to the couchbase tests

--- src/clojure/my/company/superapp/main.clj
+++ src/clojure/my/company/superapp/main.clj
@@ -23,6 +23,7 @@
              fi.iki.elonen.NanoWSD$WebSocket
              java.util.UUID
              com.couchbase.lite.Manager
+             com.couchbase.lite.Mapper
              com.couchbase.lite.Document$DocumentUpdater
              com.couchbase.lite.android.AndroidContext
              com.couchbase.lite.util.Log
@@ -152,13 +153,26 @@
                       (log/i "calling setUserProperties")
                       (.setUserProperties new-revision
                                           (assoc (into {}  properties)
-                                                 "hello" "using update" "itzik" "was here..."))
+                                                 "name" "loco" "phone" "03649556"))
                       true
                           )))]
     updater
     )
   )
-
+
+(defn document-mapper
+  []
+  (let [mapper (proxy [Mapper] []
+                 (map
+                   [document, emitter]
+                   (log/i "testing mapper view function")
+                   (log/i (str "mapper:" document))
+                   (.emit emitter (get document "phone") (get document "name"))
+                   ))]
+    mapper
+    )
+  )
+
 ;; --API-- ;;
 (defprotocol I-HTTPD-WSD
   "HTTPD and WSD APIs"
@@ -252,17 +266,20 @@
     (def manager (Manager. (AndroidContext. (*a)) (.get (.getField Manager "DEFAULT_OPTIONS") nil)))
     (.setStorageType manager "ForestDB")
     (log/i "creteing database")
-    (def db-name "player")
+    (def db-name "phones")
     (def database (.getDatabase manager db-name))
     (log/i "creating document")
     (def document (.createDocument database))
+    ;; Views and mappers
+    (def new-view (.getView database "test"))
+    (.setMap new-view (document-mapper) "1")
     (log/i "getting doc-id")
     (def doc-id (.getId document))
-    (.putProperties document {"hello" "[1] this is an hello test couchbase example"})
+    (.putProperties document {"name" "bizo" "phone" "0505919161"})
     (def data (.getProperties document))
     (log/i (str "first data: " data))
     (log/i "updating data using putProperties")
-    (.putProperties document (assoc (into {}  data) "hello" "test" "itzik" "there"))
+    (.putProperties document (assoc (into {}  data) "name" "itzik" "phone" "0528543649"))
     (log/i (str "new data after using putProperties: " (.getProperties document)))

     (log/i "updating data using update method hendler")
@@ -270,9 +287,17 @@
     (log/i (str "new data after using putProperties: " (.getProperties document)))

     (log/i (str "deleting document: " (.delete document)))
+    ;; this is how you get conflicts and revision histories
+    ;; (.getCurrentRevision document)
+    ;; (.getLeafRevisions document)
+    ;; (.putProperties document (assoc (into {} data) "bizo" "is here"))
+    ;; (.getProperties (.getDocument (first (.getConflictingRevisions document))))
+    ;; (.getRevisionHistory document)
+    ;; (def mapper (.getMap new-view))
+    ;; (.map mapper {} nil)

     ;; starting servers
-    ;; (toast "starting HTTPD-WSD servers" :long)
+    (toast "starting HTTPD-WSD servers" :long)
     (start-servers httpd-wsd)
     (def route ["/index.html" :index])
     (log/i (bidi/match-route route "/index.html"))


fix last line of tree string output

fix last line of tree string output

--- src/com/billpiel/sayid/string_output.clj
+++ src/com/billpiel/sayid/string_output.clj
@@ -330,8 +330,6 @@
        (clojure.string/join "")))

-
-
 (declare strings-agg-head)

 (defn map-agg-head
@@ -347,7 +345,8 @@

 (defn strings-agg-head
   [[agg-head & agg-tail :as agg] [next & tail :as items]]
-  (cond (empty? items) agg
+  (cond (empty? items) (concat [(apply str agg-head)]
+                                     agg-tail)
         (string? next) #(strings-agg-head (concat [(conj agg-head next)]
                                                   agg-tail)
                                           tail)
@@ -358,10 +357,8 @@
 (defn ->meta-string-pairs
   [v]
   (let [[head :as all] (util/$- ->> v
-                                (conj $ nil)
                                 (trampoline map-agg-head [])
                                 reverse
-                                drop-last
                                 (drop-while #{""}))]
     (partition-all 2 (if (string? head)
                        (concat [{}] all)


Fix widths

Fix widths

--- src/javascript_externs_generator/ui.cljs
+++ src/javascript_externs_generator/ui.cljs
@@ -133,7 +133,7 @@
       [rc/input-textarea
        :model extern
        :on-change #()
-       :width "700px"
+       :width "100%"
        :rows 25])))

 (defn loading-js []
@@ -211,6 +211,7 @@
   [rc/v-box
    :gap "10px"
    :margin "20px"
+   :width "50%"
    :children [[rc/title
                :label "JavaScript Externs Generator"
                :underline? true


DM + GR #49 - Ensure /api/v1/objectives returns empty list when no objectives

--- integration/objective8/api/objectives_integration_tests.clj
+++ integration/objective8/api/objectives_integration_tests.clj
@@ -50,7 +50,13 @@
                         parsed-response => list?
                         parsed-response => [(dissoc objective-1 :entity)
                                             (dissoc objective-2 :entity)
-                                            (dissoc objective-3 :entity)])))
+                                            (dissoc objective-3 :entity)]))
+
+                (fact "returns an empty list if there are no objectives"
+                      (do
+                        (helpers/truncate-tables)
+                        (helpers/peridot-response-json-body->map (p/request app "/api/v1/objectives")))
+                      => empty?))

          (facts "GET /api/v1/objectives/:id returns an objective"
                 (fact "can retrieve an objective using its id"


Fix javascript error when data is not ready

--- src/main/hbase_region_inspector/core.clj
+++ src/main/hbase_region_inspector/core.clj
@@ -133,7 +133,7 @@
                     nil)]
     ;; Build the result list
     {:servers (map #(assoc % :max group-max) grouped)
-     :tables all-tables}))
+     :tables (or all-tables [])}))

 (defn regions-by-tables
   "Generates output for /table_regions.json. Regions grouped by their tables."


(PDB-4808) Remove restriction against migrating multiple dbs

--- src/puppetlabs/puppetdb/cli/services.clj
+++ src/puppetlabs/puppetdb/cli/services.clj
@@ -761,13 +761,6 @@
                                         :shutdown-request (:shutdown-request context)}
                        :clean-lock (ReentrantLock.))]

-    (let [db-cfgs (conf/section-subsections database)]
-      (when (and (> (count db-cfgs) 1)
-                 (some :migrate (vals db-cfgs)))
-        (throw
-         (ex-info "Currently unable to migrate multiple databases (see config)"
-                  {:kind ::must-migrate-multiple-databases}))))
-
     (conf/reduce-section
      (fn [_ name settings]
        (init-with-db name settings))


Add physical quantities and random selector

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -321,6 +321,11 @@
                    [:C :F] #(+ (* % 1.8) 32)}]
     (converter [from to])))

+(def physical-quantities [:length :mass :pressure :volume :injection-rate :proppant-concentration])
+
+(defn rand-physical-quantity []
+  (rand-nth physical-quantities))
+
 (defn rand-unit [physical-quantity]
   (let [quantity-units-map {:length [:ft :m]
                             :mass [:lb :kg]


Adding a set-rollback-only test that I *thought* would trigger re-delivery

--- integration-tests/apps/tx/src/tx/listen.clj
+++ integration-tests/apps/tx/src/tx/listen.clj
@@ -2,6 +2,7 @@
   (:use clojure.test)
   (:require [immutant.cache :as ic]
             [immutant.messaging :as imsg]
+            [immutant.xa.transaction :as tx]
             [tx.core :as core]))

 (imsg/start "/queue/trigger")
@@ -10,24 +11,31 @@
   (imsg/publish "/queue/test" "kiwi")
   (imsg/publish "/queue/remote-test" "starfruit" :host "localhost" :port 5445)
   (ic/put core/cache :a 1)
-  (if (:throw? m) (throw (Exception. "rollback"))))
+  (if (:throw? m) (throw (Exception. "rollback")))
+  (if (:rollback? m) (tx/set-rollback-only)))

 (imsg/listen "/queue/trigger" listener)

 (defn trigger-listener
-  [throw?]
-  (imsg/publish "/queue/trigger" {:throw? throw?}))
+  [& {:as opts}]
+  (imsg/publish "/queue/trigger" opts))

 (use-fixtures :each core/cache-fixture)

 (deftest transactional-writes-in-listener-should-work
-  (trigger-listener false)
+  (trigger-listener)
   (is (= "kiwi" (imsg/receive "/queue/test" :timeout 2000)))
   (is (= "starfruit" (imsg/receive "/queue/remote-test")))
   (is (= 1 (:a core/cache))))

-(deftest transactional-writes-in-listener-should-fail-on-rollback
-  (trigger-listener true)
+(deftest transactional-writes-in-listener-should-fail-on-exception
+  (trigger-listener :throw? true)
   (is (nil? (imsg/receive "/queue/test" :timeout 2000)))
   (is (nil? (imsg/receive "/queue/remote-test" :timeout 2000)))
   (is (nil? (:a core/cache))))
+
+(deftest transactional-writes-in-listener-should-fail-on-rollback
+  (trigger-listener :rollback? true)
+  (is (nil? (imsg/receive "/queue/test" :timeout 2000)))
+  (is (nil? (imsg/receive "/queue/remote-test" :timeout 2000)))
+  (is (nil? (:a core/cache))))


Fix homepage test

Fix homepage test

--- test/servisne_info/features/homepage.clj
+++ test/servisne_info/features/homepage.clj
@@ -17,7 +17,7 @@
     (repo/create-news power-outage)
     (-> (session app)
         (visit "/")
-        (within [:.intro :h3]
-          (has (text? "Budite spremni za nestanak struje,  \n      vode ili grejanja")))
+        (within [:h2]
+          (has (text? "Budite spremni za nestanak struje,  \n    vode ili grejanja")))
         (within [:div.latest-info :li]
           (has (text? (:title power-outage)))))))


Refactored code.

Refactored code.

--- src/cmr/search/results_handlers/metadata_results_handler.clj
+++ src/cmr/search/results_handlers/metadata_results_handler.clj
@@ -89,17 +89,6 @@
      (cx/remove-xml-processing-instructions metadata)
      "</result>"]))

-(defn- fix-header-attributes
-  [result-format parsed]
-  (case result-format
-    :dif (cx/update-elements-at-path
-           parsed [:result :DIF]
-           assoc :attrs dif-c/dif-header-attributes)
-    :iso-mends (cx/update-elements-at-path
-                 parsed [:result :MI_Metadata]
-                 assoc :attrs iso-mends-c/iso-header-attributes)
-    parsed))
-
 (defn search-results->metadata-response
   [context query results]
   (let [{:keys [hits took items]} results
@@ -116,7 +105,11 @@
     (if (and pretty? (not (= :iso-mends result-format)))
       (let [parsed (x/parse-str response)
             ;; Fix for DIF emitting XML
-            parsed (fix-header-attributes result-format parsed)]
+            parsed (if (= :dif result-format)
+                     (cx/update-elements-at-path
+                       parsed [:result :DIF]
+                       assoc :attrs dif-c/dif-header-attributes)
+                     parsed)]
         (x/indent-str parsed))

       response)))


Remove unused cheshire from core.async

Remove unused cheshire from core.async

--- src/leiningen/new/onyx_app/src/onyx_app/tasks/core_async.clj
+++ src/leiningen/new/onyx_app/src/onyx_app/tasks/core_async.clj
@@ -2,8 +2,7 @@
     (:require [clojure.core.async :refer [chan sliding-buffer >!!]]
               [onyx.plugin.core-async :refer [take-segments!]]
               [taoensso.timbre :refer [info]]
-              [clojure.set :refer [join]]
-              [cheshire.core :as json]))
+              [clojure.set :refer [join]]))

 (def channels (atom {}))


more work on handling queries for bigquery

--- bigquery/src/gclouj/bigquery.clj
+++ bigquery/src/gclouj/bigquery.clj
@@ -1,6 +1,6 @@
 (ns gclouj.bigquery
   (:require [clojure.walk :as walk])
-  (:import [com.google.cloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption StandardTableDefinition TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode StandardTableDefinition$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute LoadConfiguration BigQuery$JobOption JobInfo$CreateDisposition JobInfo$WriteDisposition JobStatistics JobStatistics$LoadStatistics JobStatus JobStatus$State FormatOptions UserDefinedFunction JobInfo LoadJobConfiguration QueryJobConfiguration QueryJobConfiguration$Priority Table]
+  (:import [com.google.cloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption StandardTableDefinition TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode StandardTableDefinition$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute LoadConfiguration BigQuery$JobOption JobInfo$CreateDisposition JobInfo$WriteDisposition JobStatistics JobStatistics$LoadStatistics JobStatus JobStatus$State FormatOptions UserDefinedFunction JobInfo LoadJobConfiguration QueryJobConfiguration QueryJobConfiguration$Priority Table BigQuery$QueryResultsOption]
            [com.google.common.hash Hashing]
            [java.util List Collections]))

@@ -73,13 +73,17 @@
   Schema
   (to-clojure [x] (map to-clojure (.fields x)))
   QueryResponse
-  (to-clojure [x] {:completed? (.jobCompleted x)
-                   :errors     (->> (.executionErrors x) (map to-clojure) (seq))
-                   :job-id     (to-clojure (.jobId x))
-                   :results    (map (fn [fields] (map to-clojure fields))
-                                    (iterator-seq (.. x result iterateAll)))
-                   :schema     (to-clojure (.. x result schema))
-                   :cache-hit  (.. x result cacheHit)})
+  (to-clojure [x] (let [completed (.jobCompleted x)]
+                    {:completed? completed
+                     :errors     (->> (.executionErrors x) (map to-clojure) (seq))
+                     :job-id     (to-clojure (.jobId x))
+                     :results    (when completed
+                                   (map (fn [fields] (map to-clojure fields))
+                                        (iterator-seq (.. x result iterateAll))))
+                     :schema     (when completed
+                                   (to-clojure (.. x result schema)))
+                     :cache-hit  (when completed
+                                   (.. x result cacheHit))}))
   JobStatistics$LoadStatistics
   (to-clojure [x] {:input-bytes  (.inputBytes x)
                    :input-files  (.inputFiles x)
@@ -213,7 +217,13 @@

-(defn query [service query {:keys [max-results dry-run? max-wait-millis use-cache? default-dataset] :as query-opts}]
+(defn query
+  "Executes a query. BigQuery will create a Query Job and block for the
+  specified timeout. If the query returns within the time the results
+  will be returned. Otherwise, results need to be retrieved separately
+  using query-results. Status of the job can be checked using the job
+  function, and checking completed?"
+  [service query {:keys [max-results dry-run? max-wait-millis use-cache? default-dataset] :as query-opts}]
   (let [builder (QueryRequest/builder query)]
     (when default-dataset
       (let [{:keys [project-id dataset-id]} default-dataset]
@@ -230,8 +240,28 @@

+
+(defmulti query-option (fn [[type _]] type))
+(defmethod query-option :max-wait-millis [[_ val]] (BigQuery$QueryResultsOption/maxWaitTime val))
+(defmethod query-option :page-size [[_ val]] (BigQuery$QueryResultsOption/pageSize val))
+(defmethod query-option :page-token [[_ val]] (BigQuery$QueryResultsOption/pageToken val))
+
+(defn query-results
+  "Retrieves results for a Query job. Will throw exceptions unless Job
+  has completed successfully. Check using job and completed? functions."
+  [service {:keys [project-id job-id] :as job} & {:keys [max-wait-millis page-size page-token] :as opts}]
+  {:pre [(string? job-id) (string? project-id)]}
+  (to-clojure (.getQueryResults service
+                                (JobId/of project-id job-id)
+                                (->> opts (map query-option) (into-array BigQuery$QueryResultsOption)))))
+
+
 (defn job [service {:keys [project-id job-id] :as job}]
   (to-clojure (.getJob service (JobId/of project-id job-id) (into-array BigQuery$JobOption []))))
+
+(defn completed? [job]
+  (and (= :done (get-in job [:status :state]))
+       (empty? (get-in job [:status :errors]))))

 (def create-dispositions {:needed JobInfo$CreateDisposition/CREATE_IF_NEEDED
                           :never  JobInfo$CreateDisposition/CREATE_NEVER})