CMR-3441 PR fix

CMR-3441 PR fix

--- bootstrap-app/src/cmr/bootstrap/data/util.clj
+++ bootstrap-app/src/cmr/bootstrap/data/util.clj
@@ -6,48 +6,36 @@
    [cmr.common.log :refer (debug info warn error)]
    [cmr.indexer.services.index-service :as index-service]
    [cmr.metadata-db.services.concept-service :as concept-service]
-   [cmr.metadata-db.services.provider-service :as provider-service]
-   [cmr.umm-spec.umm-spec-core :as umm-spec]
-   [cmr.umm.umm-core :as umm-legacy]))
-
-(defn- parse-concept
- "If the concept is a collection, use umm-spec to parse to UMM-C collection. Else, use
- umm."
- [concept]
- (if (= (:concept-type concept) :collection)
-  (umm-spec/parse-metadata concept)
-  (umm-legacy/parse-concept concept)))
+   [cmr.metadata-db.services.provider-service :as provider-service]))

 (defn save-and-index-concept
   "Saves the concept to the Metadata DB and indexes it using the indexer"
-  ([system concept]
-   (save-and-index-concept system concept (parse-concept concept)))
-  ([system concept umm-record]
-   ;; This is going to copy the item to metadata db. If it was never added to MDB in the first place
-   ;; and was deleted in Catalog REST in the mean time Ingest would return a 404 from the delete
-   ;; and Catalog REST would ignore it. This would end up saving the item in Metadata DB making them
-   ;; out of sync. The delete processing should happen after this step and put it back in sync.
-   (let [mdb-context {:system (helper/get-metadata-db system)}
-         indexer-context {:system (helper/get-indexer system)}
-         concept-str (fn [] (pr-str (dissoc concept :metadata)))]
-     (try
-       (let [{:keys [concept-id revision-id]} (concept-service/save-concept-revision
-                                                mdb-context concept)
-             concept (assoc concept :concept-id concept-id :revision-id revision-id)]
-         (index-service/index-concept indexer-context concept umm-record
-                                      {:ignore-conflict? true :all-revisions-index? false})
-         (index-service/index-concept indexer-context concept umm-record
-                                      {:ignore-conflict? true :all-revisions-index? true}))
-       (catch clojure.lang.ExceptionInfo e
-         (let [data (ex-data e)]
-           (if (= (:type data) :conflict)
-             (warn (format "Ignoring conflict saving revision for %s: %s"
-                           (concept-str) (pr-str (:errors data))))
-             (error e (format "Error saving or indexing concept %s. Message: %s"
-                              (concept-str) (.getMessage e))))))
-       (catch Throwable e
-         (error e (format "Error saving or indexing concept %s. Message: %s"
-                          (concept-str) (.getMessage e))))))))
+  [system concept umm-record]
+  ;; This is going to copy the item to metadata db. If it was never added to MDB in the first place
+  ;; and was deleted in Catalog REST in the mean time Ingest would return a 404 from the delete
+  ;; and Catalog REST would ignore it. This would end up saving the item in Metadata DB making them
+  ;; out of sync. The delete processing should happen after this step and put it back in sync.
+  (let [mdb-context {:system (helper/get-metadata-db system)}
+        indexer-context {:system (helper/get-indexer system)}
+        concept-str (fn [] (pr-str (dissoc concept :metadata)))]
+    (try
+      (let [{:keys [concept-id revision-id]} (concept-service/save-concept-revision
+                                               mdb-context concept)
+            concept (assoc concept :concept-id concept-id :revision-id revision-id)]
+        (index-service/index-concept indexer-context concept umm-record
+                                     {:ignore-conflict? true :all-revisions-index? false})
+        (index-service/index-concept indexer-context concept umm-record
+                                     {:ignore-conflict? true :all-revisions-index? true}))
+      (catch clojure.lang.ExceptionInfo e
+        (let [data (ex-data e)]
+          (if (= (:type data) :conflict)
+            (warn (format "Ignoring conflict saving revision for %s: %s"
+                          (concept-str) (pr-str (:errors data))))
+            (error e (format "Error saving or indexing concept %s. Message: %s"
+                             (concept-str) (.getMessage e))))))
+      (catch Throwable e
+        (error e (format "Error saving or indexing concept %s. Message: %s"
+                         (concept-str) (.getMessage e)))))))

 (defn create-tombstone-and-unindex-concept
   "Creates a tombstone with the given concept id and revision id and unindexes the concept."


Cleaned up conv-update tests, and added tests for empty votes

--- test/conversation_test.clj
+++ test/conversation_test.clj
@@ -8,26 +8,48 @@
   (named-matrix [:a :b] [:x :y] [[1 0] [-1 1]]))

-(deftest init-conversation-test
-  (let [single-vote [{:created 500 :pid :a, :tid :x, :vote 3}]
-        several-votes
-                  (conj single-vote
-                     {:created 600 :pid :b, :tid :x, :vote 0}
-                     {:created 700 :pid :a, :tid :y, :vote 1})
-        full-votes (for [pid [:a :b :c] tid [:x :y :z]]
-                    {:created 100 :pid pid :tid tid :vote (rand)})]
-    (testing "should work on empty matrix and one vote"
-      (is (small-conv-update {:conv {:rating-mat (named-matrix)} :opts {} :votes single-vote})))
-    (testing "should work on a wonky matrix"
-      (is (small-conv-update {:conv {:rating-mat (named-matrix)} :opts {} :votes
-                              [{:created 800 :pid :a :tid :x :vote  1}
-                               {:created 900 :pid :b :tid :y :vote -1}]})))
-    (testing "should work on empty matrix and several votes"
-      (is (small-conv-update {:conv {:rating-mat (named-matrix)} :opts {} :votes several-votes})))
-    (testing "should work on ful matrix"
-      (is (small-conv-update {:conv {:rating-mat (named-matrix)} :opts {} :votes full-votes})))
-    (testing "should work on an existing matrix and several votes"
-      (is (small-conv-update {:conv {:rating-mat rat-mat} :opts {} :votes several-votes})))))
+(let [empty-conv {:rating-mat (named-matrix)}
+      small-conv {:rating-mat rat-mat}
+
+      single-vote   [{:created 500 :pid :a, :tid :x, :vote 3}]
+      wonky-votes   [{:created 600 :pid :b, :tid :x, :vote 0}
+                     {:created 700 :pid :a, :tid :y, :vote 1}]
+      several-votes (concat single-vote wonky-votes)
+      full-votes    (for [pid [:a :b :c] tid [:x :y :z]]
+                     {:created 100 :pid pid :tid tid :vote (rand)})]
+
+  (deftest init-conv-update-test
+    (testing "empty matrix and one vote"
+      (is (conv-update empty-conv single-vote)))
+    (testing "empty matrix and no vote"
+      (is (conv-update empty-conv [])))
+    (testing "empty matrix and several votes"
+      (is (conv-update empty-conv several-votes)))
+    (testing "empty matrix and full votes"
+      (is (conv-update empty-conv full-votes)))
+    (testing "empty matrix and wonky votes"
+      (is (conv-update empty-conv wonky-votes))))
+
+  ; Note that this assumes that a small conversation will actually use the small-conv-update implementation
+  (deftest small-conv-update-test
+    (testing "small matrix and one vote"
+      (is (conv-update small-conv single-vote)))
+    (testing "small matrix and no vote"
+      (is (conv-update small-conv [])))
+    (testing "small matrix and several votes"
+      (is (conv-update small-conv several-votes)))
+    (testing "small matrix and full votes"
+      (is (conv-update small-conv full-votes)))
+    (testing "small matrix and wonky votes"
+      (is (conv-update small-conv wonky-votes))))
+
+  ; Test that iterating on previous pca/clustering results makes sense
+  (deftest small-conv-iterative-test
+    (let [fleshed-conv (conv-update small-conv single-vote)]
+      (testing "fleshed conv and full matrix"
+        (is (conv-update fleshed-conv full-votes)))
+      (testing "fleshed conv and wonky vote"
+        (is (conv-update fleshed-conv [{:created 999 :pid :j :tid :k :vote -1}]))))))

 (deftest large-conv-update-test


Add another public API to playback spec error reporting

--- src/pinpointer/core.cljc
+++ src/pinpointer/core.cljc
@@ -139,6 +139,8 @@
          (println (pad-left "Spec" 9))
          (print-spec "Applied" (:spec (peek chunk))))))))

+(defonce ^:private last-explain-data (atom nil))
+
 (defn pinpoint-out
   ([ed] (pinpoint-out ed {}))
   ([ed {:keys [width colorize fallback-on-error]
@@ -151,13 +153,15 @@
                       (trace/traces ed'))
                     (catch #?(:clj Throwable :cljs :default) e e))]
        (cond (vector? traces)
-             (binding [*colorize-fn* (choose-colorize-fn colorize)]
-               (print-headline nproblems)
-               (hline width)
-               (doseq [t (map vector (range) problems traces)]
-                 (print-error nproblems value t {:width (max (- width 11) 0)})
-                 (newline)
-                 (hline width)))
+             (do (reset! last-explain-data ed)
+                 (binding [*colorize-fn* (choose-colorize-fn colorize)]
+                   (print-headline nproblems)
+                   (hline width)
+                   (doseq [t (map vector (range) problems traces)]
+                     (print-error nproblems value t
+                                  {:width (max (- width 11) 0)})
+                     (newline)
+                     (hline width))))

              fallback-on-error
              (do (println "[PINPOINTER] Failed to analyze the spec errors, and will fall back to s/explain-printer\n")
@@ -170,6 +174,11 @@
   ([spec x] (pinpoint spec x {}))
   ([spec x opts]
    (pinpoint-out (s/explain-data spec x) opts)))
+
+(defn playback
+  ([] (playback {}))
+  ([opts]
+   (pinpoint-out @last-explain-data opts)))

 #?(:clj
    (defn- find-spec-error [^Throwable t]


Fix bookmarks check.

Fix bookmarks check.

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -164,7 +164,7 @@
                         (take config/inline-comment-count (reverse (sort-by :created-at comments))))
         bookmarks-links (if (= access-level :public)
                          []
-                         (if ((:bookmarks entry) user-id)
+                         (if ((set (:bookmarks entry)) user-id)
                            [(remove-bookmark-link org-slug board-slug entry-uuid)]
                            [(add-bookmark-link org-slug board-slug entry-uuid)]))
         links (if secure-access?


removing common

removing common

--- src/ppl/views/common.clj
+++ src/ppl/views/common.clj
@@ -1,12 +0,0 @@
-(ns ppl.views.common
-  (:use [noir.core :only [defpartial]]
-        [hiccup.page-helpers :only [include-css html5]]))
-
-(defpartial layout [& content]
-            (html5
-              [:head
-               [:title "ppl"]
-               (include-css "/css/reset.css")]
-              [:body
-               [:div#wrapper
-                content]]))


Remove webapp requires

Remove webapp requires

--- src/puppeteer/system.clj
+++ src/puppeteer/system.clj
@@ -17,8 +17,6 @@
             [puppeteer.domain.usecase.message :refer [message-usecase-component]]
             [puppeteer.domain.usecase.conf :refer [configuration-usecase-component]]
             [puppeteer.domain.usecase.job :refer [job-usecase-component]]
-            [puppeteer.app.webapp.handler :refer [webapp-handler-component]]
-            [puppeteer.app.webapp.endpoint :refer [webapp-endpoint-component]]
             [puppeteer.app.slackbot.alice :refer [alice-component]])
   (:gen-class))


Use an approach that is slightly more conventional with the rest of the code

--- src/re_com/validate.cljs
+++ src/re_com/validate.cljs
@@ -191,6 +191,10 @@
                   :on-drag-over :on-drag-start :on-drop :on-focus :on-input :on-key-down :on-key-press :on-key-up :on-mouse-down :on-mouse-enter
                   :on-mouse-leave :on-mouse-move :on-mouse-out :on-mouse-over :on-mouse-up :on-paste :on-scroll :on-submit :on-touch-cancel
                   :on-touch-end :on-touch-move :on-touch-start :on-wheel})
+
+;; Reference: http://facebook.github.io/react/docs/tags-and-attributes.html#supported-attributes
+
+(def extension-attrs #{:data :aria})

 ;; Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

@@ -264,14 +268,12 @@
                   :message (str "Unknown CSS style(s): " (remove css-styles arg-keys))}))))))

 (defn extension-attribute?
-  "Returns true if the attribute name is an extension attribute, that is data-* or aria-*, otherwise false."
-  ([attr prefix]
-   (let [attr (name attr)]
-     (and (= (.indexOf attr prefix) 0)
-          (> (count attr) (count prefix)))))
+  "Returns truthy if the attribute name is an extension attribute, that is data-* or aria-*, otherwise falsey."
   ([attr]
-   (or (extension-attribute? attr "data-")
-       (extension-attribute? attr "aria-"))))
+   (let [attr (name attr)
+         ext? #(and (= (.indexOf attr %) 0)
+                       (> (count attr) (count %)))]
+     (some (comp ext? #(str % "-") name) extension-attrs))))

 (defn invalid-html-attrs
   "Returns the subset of HTML attributes contained in the passed argument that are not valid HTML attributes."


Lower the threshold for the new node test.

--- test/shale/test/client.clj
+++ test/shale/test/client.clj
@@ -84,11 +84,11 @@
                         first
                         :id)]

-        (dotimes [_ 4]
+        (dotimes [_ 3]
           (shale.client/get-or-create-session!
             {:browser-name "phantomjs"
              :node {:id node-id}}))
-        (is (= 4 (count
+        (is (= 3 (count
                    (filter #(= (:id %) node-id)
                            (shale.client/nodes)))))))))


Made added tab to be the selected one

Made added tab to be the selected one

i.e. when you add a tab, it will automatically be selected.

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

--- src/conexp/gui/util.clj
+++ src/conexp/gui/util.clj
@@ -262,7 +262,8 @@
        (let [#^JTabbedPane tabpane (get-tabpane frame)]
 	 (.add tabpane pane)
 	 (let [index (.indexOfComponent tabpane pane)]
-	   (.setTabComponentAt tabpane index (make-tab-head tabpane pane title))))
+	   (.setTabComponentAt tabpane index (make-tab-head tabpane pane title))
+	   (.setSelectedIndex tabpane index)))
        (.validate frame)))
   ([frame pane]
      (add-tab frame pane "")))


Tweak documentation

Tweak documentation

--- src/io/aviso/twixt.clj
+++ src/io/aviso/twixt.clj
@@ -99,7 +99,7 @@
   (keys :asset-path, :checksum, and  :modified-at)

   :attachments
-  : _optional_ - map of string name to attachment (with contains :content, :size, and :content-type)"
+  : _optional_ - map of string name to attachment (with keys :content, :size, and :content-type)"
   [{:keys [content-types]}]
   (fn [asset-path _]
     (let [resource-path (str "META-INF/assets/" asset-path)]


Ping to unlock worker once its ready

Ping to unlock worker once its ready

--- src/lazubot/docker.clj
+++ src/lazubot/docker.clj
@@ -58,6 +58,14 @@
   (dosync
    (commute workers assoc (:id worker-doc) worker-doc)))

+(defn ping-worker-for-unlock!
+  "Send a ping to a newly created worker. When a response is received,
+  unlock the worker for use."
+  [worker-doc]
+  (go (>! (:in worker-doc) "(str \"PING\")")
+      (<! (:out worker-doc))
+      (unlock-worker! worker-doc)))
+
 (defn add-worker! []
   "Start a new lazubot-worker container and add its worker-doc to the
   workers ref."
@@ -66,10 +74,11 @@
         socket-address (str "tcp://" container-address ":" (:expose-port config))
         [request-in request-out] (repeatedly 2 #(chan (sliding-buffer 64)))
         worker-doc {:id container-id :in request-in :out request-out
-                    :address socket-address :locked false}]
+                    :address socket-address :locked true}]
     (register-socket! {:in request-in :out request-out :socket-type :req
                        :configurator (fn [socket] (.connect socket socket-address))})
-    (register-worker! worker-doc)))
+    (register-worker! worker-doc)
+    (ping-worker-for-unlock! worker-doc)))

 (defn replace-worker!
   "Remove the given worker from the workers ref, kill and remove it in


Suppress hook-loading warning if lib dir is empty.

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -81,8 +81,8 @@
           :when (re-find #"^leiningen\.hooks\." (name n))]
     (try (require n)
          (catch Exception e
-           ;; TODO: suppress exception message if running deps task
-           (println "Problem loading hooks:" n (.getMessage e))))))
+           (when-not (empty? (.list (File. "lib")))
+             (println "Problem loading hooks:" n (.getMessage e)))))))

 (defn ns->path [n]
   (str (.. (str n)


Unify terminology: there are no commands, just tasks.

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -35,28 +35,28 @@

 (def no-project-needed #{"new" "help"})

-(defn command-not-found [command project & _]
-  (println command "is not a command. Use \"help\" to list all commands.")
+(defn task-not-found [task project & _]
+  (println task "is not a task. Use \"help\" to list all task.")
   (System/exit 1))

-(defn resolve-command [command]
-  (let [command-ns (symbol (str "leiningen." command))
-        command (symbol command)]
+(defn resolve-task [task]
+  (let [task-ns (symbol (str "leiningen." task))
+        task (symbol task)]
     (try
-     (require command-ns)
-     (ns-resolve command-ns command)
+     (require task-ns)
+     (ns-resolve task-ns task)
      (catch java.io.FileNotFoundException e
-       (partial command-not-found command)))))
+       (partial task-not-found task)))))

 (defn main [args-string]
-  (let [[command & args] (.split args-string " ")
-        command (or (aliases command) command)
-        project (if (no-project-needed command)
+  (let [[task & args] (.split args-string " ")
+        task (or (aliases task) task)
+        project (if (no-project-needed task)
                   (first args)
                   (read-project))
         compile-path (:compile-path project)]
     (when compile-path (.mkdirs (File. compile-path)))
     (binding [*compile-path* compile-path]
-      (apply (resolve-command command) project args))
+      (apply (resolve-task task) project args))
     ;; In case tests or some other task started any:
     (shutdown-agents)))


Extend wait-for to keep 100 callbacks in flight

--- src/lens/event_bus.clj
+++ src/lens/event_bus.clj
@@ -84,7 +84,11 @@
       (async/unsub (:publication bus) topic ch))))

 (defn wait-for
-  ""
+  "Waits for resources on res-bus/res-topic before invoking the callback with
+  messages from bus/topic.
+
+  The callback has to return a channel which closes after the callback has
+  finished."
   [res-bus bus res-topic topic callback]
   {:pre [(:publication bus)]}
   (let [ch (async/chan)
@@ -93,14 +97,35 @@
     (async/sub (:publication bus) topic ch)
     (async/sub (:publication bus) res-topic reset-ch)
     (async/sub (:publication res-bus) res-topic res-ch)
+    (log/debug "wait-for" topic "enter")
     (go-loop [res nil
-              ports [reset-ch]]
-      (let [[{:keys [msg]} port] (async/alts! ports)]
-        (when msg
+              ports [reset-ch]
+              callbacks (list)]
+      (log/trace "wait-for" topic "select on"
+                 (mapv {ch 'ch reset-ch 'reset-ch res-ch 'res-ch} ports)
+                 "and" (count callbacks) "callback(s)")
+      (let [[{:keys [msg] :as val} port] (async/alts! (into ports callbacks))]
+        (if val
           (condp = port
-            ch (do (<! (callback res msg)) (recur res [ch reset-ch]))
-            reset-ch (recur nil [res-ch])
-            res-ch (recur msg [ch reset-ch])))))
+            ch
+            (do
+              (log/trace "wait-for" topic "callback" (:id (:data res)) (:id msg))
+              (let [callback (callback res msg)]
+                (recur res
+                       (if (< (count callbacks) 100)
+                         [ch reset-ch]
+                         [reset-ch])
+                       (conj callbacks callback))))
+
+            reset-ch
+            (do (doseq [callback callbacks]
+                  (<! callback))
+                (recur nil [res-ch] (list)))
+
+            res-ch (recur msg [ch reset-ch] (list))
+
+            (recur res [ch reset-ch] (remove #{port} callbacks)))
+          (log/debug "wait-for" topic "exit"))))
     #(do
       (async/unsub (:publication bus) topic ch)
       (async/unsub (:publication bus) res-topic reset-ch)


An example of what I'd like to achieve with extra properties from katja

--- src/riemann/influxdb.clj
+++ src/riemann/influxdb.clj
@@ -8,10 +8,13 @@
   missing a metric or service."
   [event]
   (when (and (:metric event) (:service event))
-    {:name (:service event)
-     :host (or (:host event) "")
-     :state (:state event)
-     :value (:metric event)}))
+    (merge
+      {:name (:service event)
+       :host (or (:host event) "")
+       :state (:state event)
+       :value (:metric event)
+       }
+      (apply dissoc event [:service :host :state :metric :tags :time ]))))

 (defn events->points
   "Takes a series fn that finds the series for a given event, and a sequence of


Updated influxdb.clj

Updated influxdb.clj

--- src/riemann/influxdb.clj
+++ src/riemann/influxdb.clj
@@ -3,12 +3,17 @@
   (:require [capacitor.core :as influx])
   (:use [clojure.string :only [join split]]))

+(defn influxdb-series
+  "Constructs a series name for an event."
+  [opts event]
+  (if (nil? ((:series opts) event)) "riemann-events" ((:series opts) event)))
+
 (defn influxdb
   "Returns a function which accepts an event and sends it to InfluxDB.

   ;; For giving series name as the concatenation of :host and :service fields with dot separator.

-  (influxdb {:host \"play.influxdb.org\" :port 8086 :series \"host.service\"})
+  (influxdb {:host \"play.influxdb.org\" :port 8086 :series #(str (:host %) \".\" (:service %))})

   Options:

@@ -28,14 +33,12 @@
                      :username "root"
                      :password "root"
                      :db "riemann"
-                     :series "service"} opts)
+                     :series :service} opts)
         client (influx/make-client opts)]
     (fn [event]
-      (let [series (join "." (map (fn [e] (e event)) (vec (map (fn [k] (keyword k)) (split (:series opts) #"\.")))))]
-        (when (:metric event)
-          (when (:service event)
-            (when (:host event)
-              (influx/post-points client series [{ :name (:service event)
-                                                   :host (:host event)
-                                                   :state (:state event)
-                                                   :value (:metric event) }]))))))))
+      (when (:metric event)
+        (when (:service event)
+          (influx/post-points client (influxdb-series opts event) [{ :name (:service event)
+                                                                     :host (if (nil? (:host event)) "" (:host event))
+                                                                     :state (:state event)
+                                                                     :value (:metric event) }]))))))


Change function to reflect 3-item density

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -84,7 +84,9 @@
       [from-unit to-unit] [(* magnitude factor) to]
       [to-unit from-unit] [(/ magnitude factor) to])))

-(def density-as (as-f :lb-per-cu-ft :kg-per-m3 16.0185))
+(defn density-as [[from-magnitude from-unit substance] to-unit]
+  (let [[target-magnitude _] ((as-f :lb-per-cu-ft :kg-per-m3 16.0185) [from-magnitude from-unit] to-unit)]
+    [target-magnitude to-unit substance]))
 (def force-as (as-f :lbf :N 4.44822))
 (def power-as (as-f :hp :W 745.69987158227022))
 (def proppant-concentration-as (as-f :lb-per-gal :kg-per-m3 119.826))
@@ -659,4 +661,3 @@
     [measurement (measurement-as-f measurement (first (remove (partial = unit) units)))]))

 (generate-pair #{:lb-per-cu-ft :kg-per-m3} rand-density-unit typical-density density-as)
-;; => [[0.01952863782737629 :lb-per-cu-ft :metal] [0.3128194850378271 :kg-per-m3]]


Coerce to clojure vector the result of `get-bind-values`.

--- src/suricatta/format.clj
+++ src/suricatta/format.clj
@@ -53,7 +53,7 @@
   (-get-bind-values [q]
     (let [^Configuration conf (DefaultConfiguration.)
           ^DSLContext context (DSL/using conf)]
-      (.extractBindValues context q)))
+      (into [] (.extractBindValues context q))))

   suricatta.types.Deferred
   (-get-sql [self type dialect]


Update core.clj

Update core.clj

--- src/swagger_gen/core.clj
+++ src/swagger_gen/core.clj
@@ -81,7 +81,9 @@
 (defn keywordize-all-but-paths
   "Paths prevent an exeptional case where they may be in the form
    :/path as a keyword which won't parse correctly using Clojure's internal
-   AST rules"
+   AST rules. This is a fundamental issue with YAML and Clojure keywords.
+   By treating it as a string we can avoid the issue by mapping it into a
+   nicer form {:path \"foo\"}"
   [m]
   (into {}
     (for [[k v] m]


presentation rounds should not be counted in completed rounds

--- src/tango/cljs/main.cljs
+++ src/tango/cljs/main.cljs
@@ -460,9 +460,9 @@
   )

 (defn make-round-presentation-new [rounds]
-;;  (log round-status)
-
-  (let [completed-rounds (filter #(= (:round/status %) :completed) rounds)]
+  ;; Only count rounds that are completed and that are not presentation rounds
+  (let [completed-rounds (filter #(and (= (:round/status %) :completed)
+                                       (not= (:round/type %) :presentation)) rounds)]
     (str
      (count completed-rounds) " - "
      (if (seq completed-rounds)


Add rate-limiting `merge-more` TODO

Add rate-limiting `merge-more` TODO

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -568,6 +568,8 @@
 (defn- merge-more
   "Enables auto paging for batch batch-get/write and query/scan requests.
   Particularly useful for throughput limitations."
+  ;; TODO Add rate-limiting opt merge-more rate-limiting http://goo.gl/i9YxM
+  ;; Perhaps change :max-reqs opt to -> :multi-reqs {:max _ :throttle-ms _}?
   [more-f max-idx last-result]
   (loop [{:keys [unprocessed last-prim-kvs] :as last-result} last-result idx 1]
     (let [more (or unprocessed last-prim-kvs)]
@@ -676,11 +678,14 @@
     :index         - Name of a secondary index to query.
     :order         - Index scaning order e/o #{:asc :desc}.
     :limit         - Max num >=1 of items to eval (≠ num of matching items).
+                     Useful to prevent harmful sudden bursts of read activity.
     :consistent?   - Use strongly (rather than eventually) consistent reads?

   comparison-operators e/o #{:eq :le :lt :ge :gt :begins-with :between}.

-  For unindexed item retrievel see `scan`."
+  For unindexed item retrievel see `scan`.
+
+  Ref. http://goo.gl/XfGKW for query+scan best practices."
   [creds table prim-key-conds
    & [{:keys [last-prim-kvs max-reqs return index order limit consistent?
               return-cc?] :as opts
@@ -708,6 +713,7 @@
   "Retrieves items from a table (unindexed) with options:
     :attr-conds     - {<attr> [<comparison-operator> <values>] ...}.
     :limit          - Max num >=1 of items to eval (≠ num of matching items).
+                      Useful to prevent harmful sudden bursts of read activity.
     :last-prim-kvs  - Primary key-val from which to eval, useful for paging.
     :max-reqs       - Max number of requests to automatically stitch together.
     :return         - e/o #{:all-attributes :all-projected-attributes :count
@@ -719,7 +725,9 @@
                              :not-null :null :contains :not-contains :in}.

   For automatic parallelization & segment control see `scan-parallel`.
-  For indexed item retrievel see `query`."
+  For indexed item retrievel see `query`.
+
+  Ref. http://goo.gl/XfGKW for query+scan best practices."
   [creds table
    & [{:keys [attr-conds last-prim-kvs max-reqs return limit total-segments
               segment return-cc?] :as opts
@@ -755,8 +763,6 @@

 ;;;; Misc. helpers

-;; TODO Automatic throughput adjustment tools
-
 (defn items-by-attrs
   "Groups one or more items by one or more attributes, returning a map of form
   {<attr-val> <item> ...} or {{<attr> <val> ...} <item>}.


Remove a duplicate definition of context->sql-string.

--- src/datomish/query.cljc
+++ src/datomish/query.cljc
@@ -49,11 +49,11 @@
      :modifiers [:distinct]}
     (clauses/cc->partial-subquery (:cc context))))

-(defn context->sql-string [context]
+(defn context->sql-string [context args]
   (->
     context
     context->sql-clause
-    (sql/format :quoting sql-quoting-style)))
+    (sql/format args :quoting sql-quoting-style)))

 (defn- validate-with [with]
   (when-not (nil? with)
@@ -96,12 +96,6 @@
              :elements (:elements find)
              :cc (clauses/patterns->cc (:default-source context) where external-bindings)))))

-(defn context->sql-string
-  [context args]
-  (-> context
-    context->sql-clause
-    (sql/format args :quoting sql-quoting-style)))
-
 (defn find->sql-clause
   "Take a parsed `find` expression and turn it into a structured SQL
    expression that can be formatted by honeysql."


Make the test pass

Make the test pass

--- src/desdemona/query.clj
+++ src/desdemona/query.clj
@@ -2,16 +2,6 @@
   (:require [clojure.core.logic :as l]
             [clojure.core.match :as m]
             [clojure.core.logic.fd :as fd]))
-
-(defn ^:private dsl->logic
-  "Given a DSL query, compile it to the underlying logic (miniKanren)
-  expressions."
-  [dsl-query]
-  (m/match
-   [dsl-query]
-
-   [((= ([attr lvar] :seq) value) :seq)]
-   ['l/featurec lvar {attr value}]))

 (defn ^:private generate-logic-query
   "Expands a query and events to a core.logic program that executes
@@ -34,3 +24,17 @@
        (eval (generate-logic-query n-answers logic-query events))
        (finally
          (in-ns (ns-name old-ns)))))))
+
+(defn ^:private dsl->logic
+  "Given a DSL query, compile it to the underlying logic (miniKanren)
+  expressions."
+  [dsl-query]
+  (m/match
+   [dsl-query]
+
+   [((= ([attr lvar] :seq) value) :seq)]
+   `(l/featurec ~lvar {~attr ~value})))
+
+(defn run-dsl-query
+  [dsl-query events]
+  (run-logic-query (dsl->logic dsl-query) events))


deftag based Either

deftag based Either

--- src/grimoire/either.clj
+++ src/grimoire/either.clj
@@ -1,27 +1,17 @@
 (ns grimoire.either
   "Quick and dirty implementation of something like Haskell's Either[Success,
   Failure] for Clojure. Not the nicest thing in the world, but it'll do the
-  job. Used to indicate success and failure throughout the lib-grimoire API.")
+  job. Used to indicate success and failure throughout the lib-grimoire API."
+  (:require [detritus.variants :as v]))

-(defn succeed
+(v/deftag succeed
   "λ [t] → Succeed[t]

   Type constructor. Returns a pair [:succeed x] for all x.

   ∀x (succeed? (succeed x)) == true
   ∀x (result (succeed x)) == x"
-  [x]
-  [:succeed x])
-
-(defn succeed?
-  "λ [t] → Bool
-
-  Type predicate. Matches only two-vectors [:succeed x] as documented in the
-  succeed constructor."
-  [x]
-  {:pre [(vector? x)
-         (= 2 (count x))]}
-  (= :succeed (first x)))
+  [result])

 (defn result
   "λ [Succeed[t]] → t
@@ -30,27 +20,16 @@
   succeed. Otherwise encounters an assertion failure (type error)."
   [x]
   {:pre [(succeed? x)]}
-  (second x))
+  (:result x))

-(defn fail
+(v/deftag fail
   "λ [t] → Fail[x]

   Type constructor. Returns a pair [:fail x] for all x.

   ∀x (fail? (fail x)) == true
   ∀x (message (fail x)) == x"
-  [x]
-  [:fail x])
-
-(defn fail?
-  "λ [t] → Bool
-
-  Type predicate. Matches only two-vectors [:fail x] as documented in
-  the fail constructor."
-  [x]
-  {:pre [(vector? x)
-         (= 2 (count x))]}
-  (= :fail (first x)))
+  [message])

 (defn message
   "λ [Fail[t]] → t
@@ -59,7 +38,7 @@
   failure. Otherwise encounters an assertion failure (type error)."
   [x]
   {:pre [(fail? x)]}
-  (second x))
+  (:message x))

 (defn either?
   "λ [t] → Bool


rename load-map -> load-v

rename load-map -> load-v

--- src/kbilling/plans.cljs
+++ src/kbilling/plans.cljs
@@ -4,18 +4,17 @@
 (def reflect-fn (js/require "function-to-string"))

 (defn load-cost-fn [f path]
-  (let [params (vec (map keyword (.-params (reflect-fn f))))]     ;TODO prefix local params with cycle key
-    (fn [vars] (apply f (map #(vars %) params)))))                ;TODO test
+  (let [params (vec (map keyword (.-params (reflect-fn f))))] ;TODO prefix local params with cycle key
+    (fn [vars] (apply f (map #(vars %) params)))))          ;TODO test

-(defn load-map [x path]
+(defn load-v [x path]
   (cond
     (map? x)
-    (into {}
-          (for [[k v] x]
-            [k (case k
-                 :$begin (set (map keyword v))
-                 :$cost (load-cost-fn v path)
-                 (load-map v (conj path k)))]))
+    (into {} (for [[k v] x]
+               [k (case k
+                    :$begin (set (map keyword v))
+                    :$cost (load-cost-fn v path)
+                    (load-v v (conj path k)))]))

     :else x))

@@ -23,4 +22,4 @@
   (js/require (str (.cwd js/process) "/" path)))

 (def load-plan
-  (memoize #(load-map (js->clj (root-require %) :keywordize-keys true) [])))
+  (memoize #(load-v (js->clj (root-require %) :keywordize-keys true) [])))


Make large chunk of code in fn dolly into its own function

--- src/leiningen/dolly.clj
+++ src/leiningen/dolly.clj
@@ -114,6 +114,16 @@
          (println (str (seq nonexistent-paths))))})))

+(defn handle-errwarn [info]
+  (when (:warn info)
+    (print (:warn-msg info))
+    (flush))
+  (when (:err info)
+    (print (:err-msg info))
+    (flush)
+    (System/exit 1)))
+
+
 (defn calc-ns-opts
   [project cmd-opts]
   (let [paths (or (:paths cmd-opts) [:source-paths])]
@@ -126,20 +136,64 @@
        (or
         (non-string-paths paths)
         (nonexistent-paths paths)
-        (merge
-         {:namespace-show-opts [{:exclude ns/clojure-core-namespaces}]}
-         cmd-opts
-         {:err nil, :paths paths}))))))
-
-
-(defn handle-errwarn [info]
-  (when (:warn info)
-    (print (:warn-msg info))
-    (flush))
-  (when (:err info)
-    (print (:err-msg info))
-    (flush)
-    (System/exit 1)))
+        (merge {:namespace-show-opts [{:exclude ns/clojure-core-namespaces}]}
+               cmd-opts
+               {:err nil, :paths paths}))))))
+
+
+(defn dolly-ns
+  [project cmdline-args]
+  (let [cmd-opts (if-let [s (first cmdline-args)]
+                   (edn/read-string s)
+                   {})
+        ns-opts (calc-ns-opts project cmd-opts)
+        _ (handle-errwarn ns-opts)
+        ns-info (ns/namespaces-in-dirs ns-opts)
+        _ (handle-errwarn ns-info)
+;;        _ (println "jafinger-dbg: ns-info")
+;;        _ (pp/pprint ns-info)
+        graph-args (ns/ns-info->graph-args ns-info)]
+    (if (contains? #{nil :text :dot} (:format ns-info))
+      ;; Then don't require rhizome.viz, since by default it pops
+      ;; up another JVM GUI-related icon in the Dock on Mac OS X.
+      (case (:format ns-info)
+        (nil :text) (do
+                      (println "Dependencies:")
+                      (ns/print-ns-deps-text ns-info))
+        :dot (let [dot-fname "nsdeps.dot"]
+               (spit dot-fname (apply dot/graph->dot graph-args))
+               (println "Wrote file" dot-fname)))
+      (do
+        (require 'rhizome.viz)
+        (let [graph->svg (ns-resolve 'rhizome.viz 'graph->svg)
+              graph->image (ns-resolve 'rhizome.viz 'graph->image)
+              save-image (ns-resolve 'rhizome.viz 'save-image)
+              view-graph (ns-resolve 'rhizome.viz 'view-graph)]
+          (try
+            (case (:format ns-info)
+              :svg (let [svg-fname "nsdeps.svg"]
+                     (spit svg-fname (apply graph->svg graph-args))
+                     (println "Wrote file" svg-fname))
+              :png (let [png-fname "nsdeps.png"]
+                     (save-image (apply graph->image graph-args) png-fname)
+                     (println "Wrote file" png-fname))
+              :window (do
+                        (apply view-graph graph-args)
+                        ;; TBD: If I don't do something to delay the
+                        ;; program exiting here, the window is shown
+                        ;; but then is closed immediately.  Is there a
+                        ;; way to make this program end only when
+                        ;; someone closes the new window?
+                        (println "Delaying quitting until you press return, otherwise the new window will close:")
+                        (read-line)))
+            (catch java.io.IOException e
+              (let [msg (.getMessage e)]
+                (if (re-find #"Cannot run program \"dot\".* No such file" msg)
+                  (binding [*out* *err*]
+                    (println (format "Could not find program 'dot'.
+Output format %s requires installing Graphviz (http://www.graphviz.org)"
+                                     (:format ns-info))))
+                  (throw e))))))))))

 (defn dolly
@@ -155,57 +209,7 @@
       (dolly-help args)

       ("ns" "namespaces")
-      (let [cmd-opts (if-let [s (first args)]
-                       (edn/read-string s)
-                       {})
-            ns-opts (calc-ns-opts project cmd-opts)
-            _ (handle-errwarn ns-opts)
-            ns-info (ns/namespaces-in-dirs ns-opts)
-            _ (handle-errwarn ns-info)
-;;            _ (println "jafinger-dbg: ns-info")
-;;            _ (pp/pprint ns-info)
-            graph-args (ns/ns-info->graph-args ns-info)]
-        (if (contains? #{nil :text :dot} (:format ns-info))
-          ;; Then don't require rhizome.viz, since by default it pops
-          ;; up another JVM GUI-related icon in the Dock on Mac OS X.
-          (case (:format ns-info)
-            (nil :text) (do
-                          (println "Dependencies:")
-                          (ns/print-ns-deps-text ns-info))
-            :dot (let [dot-fname "nsdeps.dot"]
-                   (spit dot-fname (apply dot/graph->dot graph-args))
-                   (println "Wrote file" dot-fname)))
-          (do
-            (require 'rhizome.viz)
-            (let [graph->svg (ns-resolve 'rhizome.viz 'graph->svg)
-                  graph->image (ns-resolve 'rhizome.viz 'graph->image)
-                  save-image (ns-resolve 'rhizome.viz 'save-image)
-                  view-graph (ns-resolve 'rhizome.viz 'view-graph)]
-              (try
-                (case (:format ns-info)
-                  :svg (let [svg-fname "nsdeps.svg"]
-                         (spit svg-fname (apply graph->svg graph-args))
-                         (println "Wrote file" svg-fname))
-                  :png (let [png-fname "nsdeps.png"]
-                         (save-image (apply graph->image graph-args) png-fname)
-                         (println "Wrote file" png-fname))
-                  :window (do
-                            (apply view-graph graph-args)
-                            ;; TBD: If I don't do something to delay the
-                            ;; program exiting here, the window is shown
-                            ;; but then is closed immediately.  Is there a
-                            ;; way to make this program end only when
-                            ;; someone closes the new window?
-                            (println "Delaying quitting until you press return, otherwise the new window will close:")
-                            (read-line)))
-                (catch java.io.IOException e
-                  (let [msg (.getMessage e)]
-                    (if (re-find #"Cannot run program \"dot\".* No such file" msg)
-                      (binding [*out* *err*]
-                        (println (format "Could not find program 'dot'.
-Output format %s requires installing Graphviz (http://www.graphviz.org)"
-                                         (:format ns-info))))
-                      (throw e)))))))))
+      (dolly-ns project args)

       ("ls" "list-clones")
       (println "list-clones not implemented yet")


set a random number of steps to run each rocket for


Add buttons

Add buttons

--- src/nightcode/core.clj
+++ src/nightcode/core.clj
@@ -3,9 +3,13 @@
                             frame
                             native!
                             show!
+                            horizontal-panel
+                            vertical-panel
                             left-right-split
                             top-bottom-split
                             scrollable
+                            button
+                            text
                             tree
                             tabbed-panel]]
         [clojure.java.io :only [resource
@@ -13,30 +17,77 @@
         [nightcode.utils :only [get-tree-model]])
   (:gen-class))

-(defn get-window-content []
+(defn get-project-pane
+  []
+  (let [project-tree (tree)]
+    (doto project-tree
+          (.setRootVisible false)
+          (.setShowsRootHandles true)
+          (.setModel (get-tree-model project-tree)))
+    (vertical-panel
+      :items [(horizontal-panel
+                :items [(button :text "New Project")
+                        (button :text "New File")
+                        (button :text "Import")
+                        (button :text "Remove")
+                        :fill-h])
+              (scrollable project-tree)])))
+
+(defn get-tool-pane
+  []
+  (let [run-tab (vertical-panel
+                  :items [(horizontal-panel
+                            :items [(button :text "Run")
+                                    (button :text "Build")
+                                    (button :text "Test")
+                                    (button :text "Halt")
+                                    (button :text "Clean")
+                                    :fill-h])])
+        repl-tab (vertical-panel
+                  :items [(horizontal-panel
+                            :items [(button :text "Restart")
+                                    (button :text "Clear")
+                                    :fill-h])])
+        help-tab (vertical-panel
+                  :items [(horizontal-panel
+                            :items [])])]
+    (tabbed-panel :placement :top
+                  :overflow :scroll
+                  :tabs [{:title "Run"
+                          :content run-tab}
+                         {:title "REPL"
+                          :content repl-tab}
+                         {:title "Help"
+                          :content help-tab}])))
+
+(defn get-editor-pane
+  []
   (let [text-area (org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.)
-        text-area-scroll (org.fife.ui.rtextarea.RTextScrollPane. text-area)
-        project-tree (tree)]
-    ; load dark theme
+        text-area-scroll (org.fife.ui.rtextarea.RTextScrollPane. text-area)]
     (-> (resource "dark.xml")
         (input-stream)
         (org.fife.ui.rsyntaxtextarea.Theme/load)
         (.apply text-area))
-    ; create project tree
-    (doto project-tree
-          (.setRootVisible false)
-          (.setShowsRootHandles true)
-          (.setModel (get-tree-model project-tree)))
-    ; create entire window
-    (left-right-split
-      (top-bottom-split
-        (scrollable project-tree)
-        (tabbed-panel :placement :top
-                      :overflow :scroll
-                      :tabs [])
-        :divider-location 0.5)
-      text-area-scroll
-      :divider-location 0.4)))
+    (vertical-panel
+      :items [(horizontal-panel
+                :items [(button :text "Save"
+                                :enabled? false)
+                        (button :text "Move/Rename")
+                        (button :text "Undo"
+                                :enabled? false)
+                        (button :text "Redo"
+                                :enabled? false)
+                        :fill-h])
+              text-area-scroll])))
+
+(defn get-window-content []
+  (left-right-split
+    (top-bottom-split
+      (get-project-pane)
+      (get-tool-pane)
+      :divider-location 0.5)
+    (get-editor-pane)
+    :divider-location 0.4))

 (defn -main
   "Launches the main window."


support multiple instructors of a section

--- src/oarlock/schema.clj
+++ src/oarlock/schema.clj
@@ -26,7 +26,7 @@
     :dbfns [(constraints/unique :perf-asmt :id-sk :id-sk-origin)]}
    {:namespace :section
     :attrs [[:id-sk :string]
-            [:instructor :ref]
+            [:instructors :ref :many]
             [:perf-asmts :ref :many]
             [:status :enum [:active :archived :preactive]]]}
    {:namespace :user2perf-asmt ;; TODO: rename to student2perf-asmt


Made vars private

Made vars private

--- src/obb_rules/unit.clj
+++ src/obb_rules/unit.clj
@@ -8,12 +8,12 @@
   [obb-rules.units.rain/metadata
    obb-rules.units.crusader/metadata])

-(defn build-units
+(defn- build-units
   [units, selector]
   (reduce #(conj %1 [(%2 selector) %2]) {} units))

-(def units-by-name (delay (build-units (get-units) :name)))
-(def units-by-code (delay (build-units (get-units) :code)))
+(def ^{:private true} units-by-name (delay (build-units (get-units) :name)))
+(def ^{:private true} units-by-code (delay (build-units (get-units) :code)))

 (defn get-unit-by-code
   "Gets a unit info given it's code"


Fix Issue Issue 391 - paredit failure on (+), (-)


Typo.

Typo.

--- demos/plugboard/demos/forms/webfunctions.clj
+++ demos/plugboard/demos/forms/webfunctions.clj
@@ -42,5 +42,5 @@

 (defn ^{web/uri "/forms/new-resource.html"}
   new-resource-html []
-  "This is your new resource. TODO: let's add it to memory in submit.html so we can display it here"
+  "This is your new resource. TODO: let's add it to memory in submit.html so we can display it here."
   )


fix issue with destroyer ability

fix issue with destroyer ability

--- src/node/game/core.cljs
+++ src/node/game/core.cljs
@@ -291,7 +291,7 @@
 (defn trash [state side {:keys [zone] :as card}]
   (let [c (assoc card :counter nil :advance-counter nil :current-strength nil)
         cdef (card-def c)
-        moved-card (move state side c :discard)]
+        moved-card (move state (to-keyword (:side card)) c :discard)]
     (when (#{:servers :rig} (first zone))
       (when-let [leave-effect (:leave-play cdef)]
         (leave-effect state side moved-card nil))


Made the inversions more robust and capable of handling extra tones.

--- src/overtunes/pitch.clj
+++ src/overtunes/pitch.clj
@@ -22,6 +22,9 @@
                    (rest ks)
                    f)
                  m))
+
+
+(defn keys-except [m ks] (clojure.set/difference (set (keys m)) ks))

 ; Basic intervals
 (def semitone 1)
@@ -74,5 +77,5 @@
 (def ninth #(assoc (seventh %) :ix (raise (:ii major-scale))))
 (def eleventh #(assoc (ninth %) :xi (raise (:iv major-scale))))
 (def thirteenth #(assoc (eleventh %) :xi (raise (:vi major-scale))))
-(def second-inversion #(update-values % [:iii :v] lower))
-(def first-inversion #(update-values % [:v] lower))
+(def first-inversion #(update-values % (keys-except % [:i]) lower))
+(def second-inversion #(update-values % (keys-except % [:i :iii]) lower))


Use correct route for OPTIONS on status

Use correct route for OPTIONS on status

--- server/src/clinicico/server/handler.clj
+++ server/src/clinicico/server/handler.clj
@@ -147,9 +147,9 @@
                             (resp/header "Content-Length" (.getLength record))))))
                (ANY ["/:id" :id match-uuid] [id] result-resource))
       (context "/tasks" []
+               (OPTIONS ["/:method/:id/status" :id match-uuid] [] (http/options #{:options :get}))
+               (GET ["/:method/:id/status" :id match-uuid] [method id] task-status)
                (ANY "/:method" [method] tasks-resource)
-               (GET ["/:method/:id/status" :id match-uuid] [method id] task-status)
-               (OPTIONS ":/method/:id/status" [] (http/options #{:options :get}))
                (ANY ["/:method/:id" :id match-uuid] [method id] task-resource))
       (GET "/" [] (resp/resource-response "index.html" {:root "public"}))
       (ANY "/*" [] static))))


Use sut idiom in base test too

Use sut idiom in base test too

--- test/cljs/comic_reader/ui/base_test.cljs
+++ test/cljs/comic_reader/ui/base_test.cljs
@@ -1,15 +1,15 @@
 (ns comic-reader.ui.base-test
   (:require [devcards.core :refer-macros [defcard-rg]]
-            [comic-reader.ui.base :as ui-base]))
+            [comic-reader.ui.base :as sut]))

 (defcard-rg loading
   "## Loading
    This is the loading svg used everywhere on the site."
   [:div {:style {"width" "4em"}}
-   [ui-base/loading]])
+   [sut/loading]])

 (defcard-rg four-oh-four
-  [ui-base/four-oh-four])
+  [sut/four-oh-four])

 (defcard-rg large-button
-  [ui-base/large-button "Button"])
+  [sut/large-button "Button"])


Subscription cache needed elsewhere,  so no longer private

--- src/re_frame/subs.cljc
+++ src/re_frame/subs.cljc
@@ -22,7 +22,7 @@
 ;; De-duplicate subscriptions. If two or more equal subscriptions
 ;; are concurrently active, we want only one handler running.
 ;; Two subscriptions are "equal" if their query vectors test "=".
-(def ^:private query->reaction (atom {}))
+(def query->reaction (atom {}))

 (defn clear-all-handlers!
   "Unregisters all existing subscription handlers"


Make enter to move selection to cell under in addition to disabling edit-mode

--- src/reabledit/util.cljs
+++ src/reabledit/util.cljs
@@ -59,11 +59,14 @@
                        (min cols (inc current-col))
                        state))

-      ;; Enter in editing mode disables editing
+      ;; Enter in editing mode disables it and moves selection to cell under
       (and (:edit @state) (= keycode 13))
       (do
         (.preventDefault e)
-        (move-to-cell! row-change-fn current-row current-col state))
+        (move-to-cell! row-change-fn
+                       (min rows (inc current-row))
+                       current-col
+                       state))

       ;; Arrow keys in navigation mode change the selected cell
       ;; Enter and F2 in navigation mode enable editing mode


Document streams/tagged

Document streams/tagged

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -699,7 +699,7 @@
   (fn [event]
     (when (set/subset? (set tags) (set (:tags event)))
       (call-rescue event children))))
-(def tagged tagged-all)
+(def tagged "Alias for tagged-all" tagged-all)

 (defn tagged-any
   "Passes on events where any of tags are present.


Extract predicate functions from the stream tagged-* fns

Lets the tagged tests be used in where test expressions
without duplicating logic.

Also removes a branch from the stream tagged-* functions
by coercing single tags into a collection before calling
the predicate.

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1077,6 +1077,12 @@
       (call-rescue event children)
       true)))

+(defn tagged-all?
+  "Predicate function to check if a collection of tags is
+  present in the tags of event."
+  [tags event]
+  (set/subset? (set tags) (set (:tags event))))
+
 (defn tagged-all
   "Passes on events where all tags are present. This stream returns true if an
   event it receives matches those tags, nil otherwise.
@@ -1087,16 +1093,17 @@
   (tagged-all \"foo\" prn)
   (tagged-all [\"foo\" \"bar\"] prn)"
   [tags & children]
-  (if (coll? tags)
+  (let [tag-coll (flatten [tags])]
     (fn stream [event]
-      (when (set/subset? (set tags) (set (:tags event)))
-        (call-rescue event children)
-        true))
-
-    (fn stream [event]
-      (when (member? tags (:tags event))
+      (when (tagged-all? tag-coll event)
         (call-rescue event children)
         true))))
+
+(defn tagged-any?
+  "Predicate function to check if any of a collection of tags
+  are present in the tags of event."
+  [tags event]
+  (some (set tags) (:tags event)))

 (defn tagged-any
   "Passes on events where any of tags are present. This stream returns true if
@@ -1108,15 +1115,9 @@
   (tagged-any \"foo\" prn)
   (tagged-all [\"foo\" \"bar\"] prn)"
   [tags & children]
-  (if (coll? tags)
-    (let [required (set tags)]
-      (fn stream [event]
-        (when (some required (:tags event))
-          (call-rescue event children)
-          true)))
-
+  (let [tag-coll (flatten [tags])]
     (fn stream [event]
-      (when (member? tags (:tags event))
+      (when (tagged-any? tag-coll event)
         (call-rescue event children)
         true))))


perf: Create tags match set only once

perf: Create tags match set only once

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1298,7 +1298,7 @@
   (tagged-all [\"foo\" \"bar\"] prn)
   ```"
   [tags & children]
-  (let [tag-coll (flatten [tags])]
+  (let [tag-coll (set (flatten [tags]))]
     (fn stream [event]
       (when (tagged-all? tag-coll event)
         (call-rescue event children)
@@ -1321,7 +1321,7 @@
   (tagged-any [\"foo\" \"bar\"] prn)
   ```"
   [tags & children]
-  (let [tag-coll (flatten [tags])]
+  (let [tag-coll (set (flatten [tags]))]
     (fn stream [event]
       (when (tagged-any? tag-coll event)
         (call-rescue event children)


reorder functions

reorder functions

--- src/riffmuse/scales.clj
+++ src/riffmuse/scales.clj
@@ -24,6 +24,12 @@
                     :a :e :b :f-sharp :c-sharp :g-sharp :d-sharp :a-sharp])
           (range -7 8)))

+(defn key-signature [pitch major-or-minor]
+  (let [n ((circle-of-fifths major-or-minor) pitch)]
+    (conj {}
+          (when (pos? n) {:sharps (set (take n "FCGDAEB"))})
+          (when (neg? n) {:flats  (set (take (Math/abs n) "BEADGCF"))}))))
+
 (defn sanitize [pitch major-or-minor]
   "For the sake of simplicity, Riffmuse does not support the use of more than
    one accidental; e.g., double sharps and double flats. For this reason,
@@ -37,12 +43,6 @@
                  :g-flat :f-sharp, :a-flat :g-sharp, :b-sharp :c})
        pitch
        pitch))
-
-(defn key-signature [pitch major-or-minor]
-  (let [n ((circle-of-fifths major-or-minor) pitch)]
-    (conj {}
-          (when (pos? n) {:sharps (set (take n "FCGDAEB"))})
-          (when (neg? n) {:flats  (set (take (Math/abs n) "BEADGCF"))}))))

 (defn- diatonic-scale [pitch major-or-minor]
   (let [pitch          (sanitize pitch major-or-minor)


Added 'header' function to ring.util.response

--- ring-core/src/ring/util/response.clj
+++ ring-core/src/ring/util/response.clj
@@ -59,8 +59,13 @@
   [resp status]
   (assoc resp :status status))

+(defn header
+  "Returns an updated Ring response with the specified header added."
+  [resp name value]
+  (assoc-in resp [:headers name] (str value)))
+
 (defn content-type
   "Returns an updated Ring response with the a Content-Type header corresponding
   to the given content-type."
   [resp content-type]
-  (assoc-in resp [:headers "Content-Type"] content-type))
+  (header resp "Content-Type" content-type))


minor cleanup

minor cleanup

--- src/selmer/filters.clj
+++ src/selmer/filters.clj
@@ -138,9 +138,7 @@
      :default-if-empty
      (fn [coll default]
        (throw-when-expecting-seqable coll)
-       (if (empty? coll)
-         default
-         coll))
+       (or (not-empty coll) default))

      ;;; With no decimal places it rounds to 1 decimal place
      :double-format


Add table defn code to blockly view

Add table defn code to blockly view

So that we can insert code for the blockly view

--- idecode/myappshare/mainapp.cljs
+++ idecode/myappshare/mainapp.cljs
@@ -51,8 +51,8 @@
                     ]]))
 (defn-ui-component     default-component   [app] (div nil))
                     (def table-defns (atom []))
-                    (swap! table-defns conj \"ooo\")
-                    (swap! table-defns conj \"ooo22\")
+"))
+(defn end [] "(webapp.framework.client.system-globals.touch [:ui])\n
                     (defn get-tables []
                     (remote \"!update-tables\"
                     {:session-id      (:session-id @webapp.framework.client.system-globals.client-session-atom)
@@ -62,8 +62,6 @@
                     (reset! webapp.framework.client.system-globals/app-state (assoc-in @webapp.framework.client.system-globals/app-state [:ui :table-list] result2))))
                     )
                     (get-tables)
-"))
-(defn end [] "(webapp.framework.client.system-globals.touch [:ui])\n
   (reset! webapp.framework.client.system-globals/start-component  main)")

@@ -94,10 +92,20 @@

                       return-val))))
                               (webapp.framework.client.coreclient/get-tables)
+                    (def table-defns (atom []))
 "))

 (defn end-optimized [] "(webapp.framework.client.system-globals.touch [:ui])\n
+                    (defn get-tables []\n
+                    (webapp.framework.client.coreclient/remote-fn \"!update-tables\"\n
+                    {:session-id      (:session-id @webapp.framework.client.system-globals.client-session-atom)\n
+                    :table-defns @table-defns\n
+                    }\n
+                    (fn [result2]\n
+                    (reset! webapp.framework.client.system-globals/app-state (assoc-in @webapp.framework.client.system-globals/app-state [:ui :table-list] result2))))\n
+                    )\n
+                    (get-tables)\n
   (reset! webapp.framework.client.system-globals/start-component  main)")


No longer test Safari on Windows (#385)

No longer test Safari on Windows (#385)

Closes #383

--- test/etaoin/api_test.clj
+++ test/etaoin/api_test.clj
@@ -27,7 +27,7 @@
   (case (first (str/split (System/getProperty "os.name") #"\s+"))
     "Linux"   [:firefox :chrome :phantom]
     "Mac"     [:chrome :edge :firefox :phantom :safari]
-    "Windows" [:firefox :chrome :edge :phantom :safari]
+    "Windows" [:firefox :chrome :edge :phantom]
     nil))

 (defn get-default-drivers []


typed

typed

--- vif-navigator2/project.clj
+++ vif-navigator2/project.clj
@@ -52,6 +52,7 @@
                                                  :aot-exclude-ns      [cljs.core.typed.async
                                                                        clojure.core.typed.async
                                                                        clojure.core.typed.all-envs
+                                                                       clojure.core.typed.contract-utils
                                                                        ]
                                                  }}]


Fix Error when opening 1-1 chat in Activity center for blocked user

Signed-off-by: Brian Sztamfater <760e7dab2836853c63805033e514668301fa9c47@status.im>

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -1802,12 +1802,15 @@
 (re-frame/reg-sub
  :activity.center/notifications-grouped-by-date
  :<- [:activity.center/notifications]
- (fn [{:keys [notifications]}]
-   (let [supported-notifications (filter (fn [{:keys [type]}]
-                                           (or (= constants/activity-center-notification-type-mention type)
-                                               (= constants/activity-center-notification-type-one-to-one-chat type)
-                                               (= constants/activity-center-notification-type-private-group-chat type)
-                                               (= constants/activity-center-notification-type-reply type))) notifications)]
+ :<- [::chats]
+ (fn [[{:keys [notifications]} chats]]
+   (let [supported-notifications (filter (fn [{:keys [type chat-id]}]
+                                           (and
+                                            (or (= constants/activity-center-notification-type-mention type)
+                                                (= constants/activity-center-notification-type-one-to-one-chat type)
+                                                (= constants/activity-center-notification-type-private-group-chat type)
+                                                (= constants/activity-center-notification-type-reply type))
+                                            (get chats chat-id))) notifications)]
      (group-notifications-by-date (map #(assoc % :timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %))))) supported-notifications)))))

 ;;WALLET TRANSACTIONS ==================================================================================================


Change copyright email on async ns.

Change copyright email on async ns.

--- src/suricatta/async.clj
+++ src/suricatta/async.clj
@@ -1,4 +1,4 @@
-;; Copyright (c) 2014-2015, Andrey Antukh <niwi@niwi.be>
+;; Copyright (c) 2014-2015, Andrey Antukh <niwi@niwi.nz>
 ;; All rights reserved.
 ;;
 ;; Redistribution and use in source and binary forms, with or without


Further fixes to ugen arg checking code

Further fixes to ugen arg checking code

--- src/overtone/sc/machinery/ugen/check.clj
+++ src/overtone/sc/machinery/ugen/check.clj
@@ -2,24 +2,25 @@
   ^{:doc "UGen argument validation functions."
      :author "Jeff Rose & Christophe McKeon"}
   overtone.sc.machinery.ugen.check
-  (:use [overtone.sc.machinery.ugen defaults]))
+  (:use [overtone.sc.machinery.ugen defaults]
+        [overtone.util.lib :only [overtone-ugen-name]]))

-(defn rate-of [obj]
-  (:rate-name obj))
+(defn rate-name= [obj rate]
+  (= (:rate-name obj) rate))

-(defn rate-of? [obj rate]
-  (= (rate-of obj) rate))
+(defn rate= [ug rate-int]
+  (= (:rate ug) rate-int))

 (defn name-of [obj]
-  (:name obj))
+  (overtone-ugen-name (:name obj)))

 (defn name-of? [obj name]
   (= (name-of obj) name))

-(defn ar? [obj] (= (rate-of obj) :ar))
-(defn kr? [obj] (= (rate-of obj) :kr))
-(defn ir? [obj] (= (rate-of obj) :ir))
-(defn dr? [obj] (= (rate-of obj) :dr))
+(defn ar? [obj] (= (:rate-name obj) :ar))
+(defn kr? [obj] (= (:rate-name obj) :kr))
+(defn ir? [obj] (= (:rate-name obj) :ir))
+(defn dr? [obj] (= (:rate-name obj) :dr))

 (defmacro defcheck [name params default-message expr]
   (let [message (gensym "message")
@@ -33,8 +34,8 @@
           (when-not ~expr ~message))))))

 (defcheck same-rate-as-first-input []
-  (str (name-of (first inputs)) "must be same rate as called ugen, i.e. " rate)
-  (= (rate-of (first inputs)) rate))
+  (str "Rate mismatch: "(name-of (first inputs)) " is at rate " (:rate-name (first inputs))  " yet the containing ugen is at " (REVERSE-RATES rate))
+  (= (:rate (first inputs)) rate))

 (defcheck first-input-ar []
   (str "The first input must be audio rate. Got " (:rate-name (first inputs)))
@@ -49,7 +50,7 @@
   (every? ar? (take n inputs)))

 (defcheck after-n-inputs-rest-ar [n]
-  (str "all but the first " n " inputs must be audio rate")
+  (str "All but the first " n " inputs must be audio rate")
   (every? ar? (drop n inputs)))

 (defcheck all-but-first-input-ar []
@@ -61,7 +62,7 @@
   (ar? (nth inputs index)))

 (defcheck num-outs-greater-than [n]
-  (str "must have " (+ n 1) " or more output channels")
+  (str "Must have " (+ n 1) " or more output channels")
           true)

 (defn- mk-check-all


return 404 at root context when not matching any route

--- src/wb_es/web/index.clj
+++ src/wb_es/web/index.clj
@@ -69,7 +69,8 @@
            (context "/lite" []
                     (-> api-lite-routes
                         (wrap-routes web-integration/wrap-params)))
-  (route/not-found (response {:message "endpoint not found"}))))
+           (route/not-found (response {:message "endpoint not found"})))
+  (route/not-found (response {:message "endpoint not found"})))

 (defn handler [request]


Maps om/value over titles in app state

Maps om/value over titles in app state

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -133,7 +133,7 @@
                   (dom/span #js {:className "left-menu-title"
                                  :onClick (fn [e] (change-current e app))}
                     (om/value %)))
-               (:titles app)))))))
+               (map om/value (:titles app))))))))

 ;; Editor


Update utils.cljs

Update utils.cljs

--- src/zirconia/utils.cljs
+++ src/zirconia/utils.cljs
@@ -12,7 +12,7 @@
        (catch js/Error _ (str x))))

 (defn camel->lisp
-  "Converts a camelCase string into a lisp-case keyword"
+  "Transforms a camelCase string into a lisp-case keyword"
   [x]
   (-> (name x)
       (.replace #"([a-z])([A-Z])" "$1-$2")


Fix byte array to string fn

Fix byte array to string fn

--- src/zoo_live/events.clj
+++ src/zoo_live/events.clj
@@ -58,7 +58,8 @@
 (defn- kafka-json-string-to-map
   [msg]
   (->> (:value msg)
-       (map char) (apply str)
+       (map #(char (bit-and % 255)))
+       (apply str)
        parse-string))

 (defn kafka-stream


add tests for "davanti il tavolo" and "davanti lo studente" (not passing yet)

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -400,3 +400,29 @@
                (map (fn [parse]
                       (get-in parse [:synsem :sem]))
                     (mapcat :parses result))))))))
+
+(deftest davanti-il-tavolo
+  (let [parse-result (mapcat :parses (parse "davanti il tavolo"))
+        gen-result (generate {:synsem {:cat :prep
+                                       :sem {:pred :in-front-of
+                                             :obj {:pred :table
+                                                   :number :sing
+                                                   :mod '()
+                                                   :spec {:def :def}}}}
+                              :comp {:synsem {:cat :noun}}})]
+    (is (not (empty? parse-result)))
+    (is (= "davanti il tavolo"
+           (fo gen-result)))))
+
+(deftest davanti-lo-studente
+  (let [parse-result (mapcat :parses (parse "davanti lo studente"))
+        gen-result (generate {:synsem {:cat :prep
+                                       :sem {:pred :in-front-of
+                                             :obj {:pred :student
+                                                   :number :sing
+                                                   :mod '()
+                                                   :spec {:def :def}}}}
+                              :comp {:synsem {:cat :noun}}})]
+    (is (not (empty? parse-result)))
+    (is (= "davanti lo studente"
+           (fo gen-result)))))


Prove that sitemap locations within records may start with a /

--- test/irobot/t_parse.clj
+++ test/irobot/t_parse.clj
@@ -191,11 +191,11 @@

 (fact "Sitemap directives may be mixed amongst other directives"
-  (parse "User-agent:foo\nSitemap:barbar.xml\nAllow:/a/b/c")
-  => [:records
-      [:record
-       [:agent "User-agent:" "foo"]
-       [:sitemap "Sitemap:" "barbar.xml"]
+  (parse "User-agent:foo\nSitemap:/barbar.xml\nAllow:/a/b/c")
+  => [:records
+      [:record
+       [:agent "User-agent:" "foo"]
+       [:sitemap "Sitemap:" "/barbar.xml"]
        [:allow "Allow:" "/a/b/c"]]])


Fix toolset.clj get-primes typo

Fix toolset.clj get-primes typo

--- euler_clojure/src/euler/toolset.clj
+++ euler_clojure/src/euler/toolset.clj
@@ -13,7 +13,7 @@

 (defn get-primes
   ([]
-   (get-primes 3))
+   (get-primes 2))
   ([start]
    (filter prime? (iterate inc start)))
   ([start end]


Fix api docstring typos

Fix api docstring typos

--- src/onyx/api.clj
+++ src/onyx/api.clj
@@ -304,7 +304,7 @@
 (defn ^{:added "0.6.0"} shutdown-peer
   "Shuts down the virtual peer, which releases all of its resources
    and removes it from the execution of any tasks. This peer will
-   not longer volunteer for tasks. Returns nil."
+   no longer volunteer for tasks. Returns nil."
   [peer]
   (>!! (:shutdown-ch peer) true)
   (<!! (:ack-ch peer))
@@ -319,7 +319,7 @@
     (shutdown-peer p)))

 (defn ^{:added "0.6.0"} start-env
-  "Starts a development environment using an in-memory implementation ZooKeeper."
+  "Starts a development environment using an in-memory implementation of ZooKeeper."
   ([env-config]
    (start-env env-config {:monitoring :no-op}))
   ([env-config monitoring-config]


Fix typo in lein/profiles.clj

Fix typo in lein/profiles.clj

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -44,7 +44,7 @@
                        ;; Q: Is there any point to this next one?
                        #_[ritz/ritz-nrepl-middleware "0.7.0"]
                        ;; This approach is long deprecated.
-                       ;; See its README and put it into :aliases insted
+                       ;; See its README and put it into :aliases instead
                        #_[slamhound "1.5.5"]
                        [slingshot "0.12.2" :exclusions [org.clojure/clojure]]]
         :injections [(require '[vinyasa.inject :as inject])


[CS] Move and docstring `output.ballot/candidates`

--- src/vip/data_processor/output/ballot.clj
+++ src/vip/data_processor/output/ballot.clj
@@ -1,6 +1,19 @@
 (ns vip.data-processor.output.ballot
   (:require [vip.data-processor.output.xml-helpers :refer :all]
             [korma.core :as korma]))
+
+(defn candidates
+  "Find candidates belonging to a ballot. Goes through the
+  ballot_candidates table to grab their `id` and `sort_order` columns,
+  which is all that's needed for the ballot's XML representation."
+  [ctx ballot]
+  (let [ballot-candidates-table (get-in ctx [:tables :ballot-candidates])
+        candidates-table (get-in ctx [:tables :candidates])]
+    (korma/select ballot-candidates-table
+                  (korma/fields :candidates.id :candidates.sort_order)
+                  (korma/join candidates-table
+                              (= :candidates.id :candidate_id))
+                  (korma/where {:ballot_id (:id ballot)}))))

 (defn candidate->xml [candidate]
   (let [xml {:tag :candidate_id
@@ -23,15 +36,6 @@
                          (map candidate->xml candidates))]
     (simple-xml :ballot id children)))

-(defn candidates [ctx ballot]
-  (let [ballot-candidates-table (get-in ctx [:tables :ballot-candidates])
-        candidates-table (get-in ctx [:tables :candidates])]
-    (korma/select ballot-candidates-table
-                  (korma/fields :candidates.id :candidates.sort_order)
-                  (korma/join candidates-table
-                              (= :candidates.id :candidate_id))
-                  (korma/where {:ballot_id (:id ballot)}))))
-
 (defn xml-nodes [ctx]
   (let [ballots-table (get-in ctx [:tables :ballots])
         ballots (korma/select ballots-table)]


prefer *-subpages for sets of routes, backport insights

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -408,12 +408,12 @@
   ((om/get-shared owner :track-event) {:event-type event-name
                                        :properties {:component "left-nav"}}))

-(def light-builds? #{:dashboard :build})
-
-(def light-workflows? #{:route/project-workflows
-                        :route/project-branch-workflows
-                        :route/org-workflows
-                        :route/run})
+(def insights-subpages #{:build-insights :project-insights})
+(def dashboard-subpages #{:dashboard :build})
+(def workflows-subpages #{:route/project-workflows
+                          :route/project-branch-workflows
+                          :route/org-workflows
+                          :route/run})

 (defn aside-nav-original [{:keys [user current-route owner]}]
@@ -429,7 +429,7 @@
       [:div.logomark
        (common/ico :logo)]]

-     [:a.aside-item {:class (when (light-builds? current-route) "current")
+     [:a.aside-item {:class (when (dashboard-subpages current-route) "current")
                      :data-placement "right"
                      :data-trigger "hover"
                      :title "Builds"
@@ -439,7 +439,7 @@
       [:div.nav-label "Builds"]]

      (when (feature/enabled? :workflows-poc)
-       [:a.aside-item {:class (when (light-workflows? current-route) "current")
+       [:a.aside-item {:class (when (workflows-subpages current-route) "current")
                        :data-placement "right"
                        :data-trigger "hover"
                        :title "Workflows"
@@ -447,7 +447,8 @@
         (icon/workflows)
         [:div.nav-label "Workflows"]])

-     [:a.aside-item {:class (when (= :build-insights current-route) "current")
+     [:a.aside-item {:class (when (insights-subpages current-route)
+                              "current")
                      :data-placement "right"
                      :data-trigger "hover"
                      :title "Insights"
@@ -542,14 +543,11 @@
       [:i.material-icons "power_settings_new"]
       [:div.nav-label "Log Out"]]]))

-(def insights-subpages #{:build-insights :project-insights})
-(def dashboard-subpages #{:dashboard :build})
-
 (defn aside-nav-new [{:keys [current-route org owner]}]
   "New side nav, to be used in conjunction with the top bar"
   (html
     [:nav.aside-left-nav
-     [:a.aside-item {:class (when (light-builds? current-route)
+     [:a.aside-item {:class (when (dashboard-subpages current-route)
                               "current")
                      :data-placement "right"
                      :data-trigger "hover"
@@ -560,7 +558,7 @@
       [:div.nav-label "Builds"]]

      (when (feature/enabled? "workflows-poc")
-       [:a.aside-item {:class (when (light-workflows? current-route)
+       [:a.aside-item {:class (when (workflows-subpages current-route)
                                 "current")
                        :data-placement "right"
                        :data-trigger "hover"


ad for circle.yml

ad for circle.yml

--- frontend/components/build_head.cljs
+++ frontend/components/build_head.cljs
@@ -239,12 +239,19 @@
                             [:li (test-model/format-test-name test)])
                           (sort-by test-model/format-test-name tests))]]))]))])))))

+(defn circle-yml-ad []
+  [:div
+   [:p "We didn't find a circle.yml for this build. You can specify deployment or override our inferred test steps from a circle.yml checked in to your repo's root directory."]
+   [:p "More information " [:a {:href (routes/v1-doc-subpage {:subpage "configuration"})} "in our docs"] "."]])
+
 (defn build-config [{:keys [config-string]} owner opts]
   (reify
     om/IRender
     (render [_]
       (html
-       [:div.build-config-string [:pre config-string]]))))
+       (if (seq config-string)
+         [:div.build-config-string [:pre config-string]]
+         (circle-yml-ad))))))

 (defn expected-duration
   [{:keys [start stop build]} owner opts]
@@ -304,10 +311,9 @@
                [:a {:on-click #(raise! owner [:build-header-tab-clicked {:tab :commits}])}
                 "Commit Log"]])

-            (when (build-model/config-string? build)
-              [:li {:class (when (= :config selected-tab) "active")}
-               [:a {:on-click #(raise! owner [:build-header-tab-clicked {:tab :config}])}
-                "circle.yml"]])
+            [:li {:class (when (= :config selected-tab) "active")}
+             [:a {:on-click #(raise! owner [:build-header-tab-clicked {:tab :config}])}
+              "circle.yml"]]

             (when logged-in?
               [:li {:class (when (= :usage-queue selected-tab) "active")}


Make whistle envelope more accurate for long notes.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -308,7 +308,7 @@
       (+ (* 1/8 (sin-osc (* 7.01 freq))))
       (clip2 0.8)
       (rlpf (line:kr (* 2 freq) (* 7 freq) 0.8))
-      (* (env-gen (adsr 0.2 0.4 0.15 0.2) (line:kr 1 0 dur) :action FREE))
+      (* (env-gen (adsr 0.2 0.1 0.25 0.2) (line:kr 1 0 dur) :action FREE))
       (pan2 pan)
       (* vol)))


Remove unecessary sorts

Remove unecessary sorts

--- src/cljs/koeeoadi/components/codedisplay.cljs
+++ src/cljs/koeeoadi/components/codedisplay.cljs
@@ -56,14 +56,13 @@
 (def code-chunk (om/factory CodeChunk {:keyfn :code-chunk/line-chunk}))

 (defn code-line [line]
-  (let [code-chunks (sort-by :line-chunk line)]
-    (apply dom/div #js {:className "code-line"}
-      (map code-chunk code-chunks))))
+  (apply dom/div #js {:className "code-line"}
+    (map code-chunk line)))

 (defn group-lines [code-chunks]
-  (sort-by first (sort-by first
-                   (group-by #(.floor js/Math (/ (:code-chunk/line-chunk %) 1000))
-                     code-chunks))))
+  (sort-by first (group-by #(.floor js/Math (/ (:code-chunk/line-chunk %) 1000))
+                   code-chunks)))
+

 (defui CodeDisplay
   static om/IQuery


Fixed flickering of canvas.

Fixed flickering of canvas.

--- src/cljs/wombats_web_client/panels/game_play.cljs
+++ src/cljs/wombats_web_client/panels/game_play.cljs
@@ -50,7 +50,7 @@
   (resize-canvas arena))

 (defn- component-did-update [arena]
-  (resize-canvas arena))
+  (arena/arena @arena canvas-id))

 (defn- component-will-mount [game-id]
   (ws/send-message :join-game {:game-id game-id}))
@@ -160,7 +160,6 @@
               winner (:game/winner game)]

           (arena/arena @arena canvas-id)
-
           [:div {:class-name root-class}
            [:div.left-game-play-panel {:id "wombat-arena"
                                        :class (when winner "game-over")}


Cleaned up some code.

Cleaned up some code.

--- src/cljs/wombats_web_client/panels/game_play.cljs
+++ src/cljs/wombats_web_client/panels/game_play.cljs
@@ -44,10 +44,12 @@

 (defn- component-did-mount [arena cmpnt-state]
   ;; Add resize listener
-  (let [resize-fn (:resize-fn @cmpnt-state)]
-    (.addEventListener js/window
-                       "resize"
-                       resize-fn))
+  (.addEventListener js/window
+                     "resize"
+                     (:resize-fn @cmpnt-state))
+  (resize-canvas arena))
+
+(defn- component-did-update [arena]
   (resize-canvas arena))

 (defn- component-will-mount [game-id]
@@ -148,6 +150,7 @@

     (reagent/create-class
      {:component-did-mount #(component-did-mount arena cmpnt-state)
+      :component-did-update #(component-did-update arena)
       :component-will-mount #(component-will-mount game-id)
       :component-will-unmount #(component-will-unmount game-id cmpnt-state)
       :display-name "game-play-panel"
@@ -155,7 +158,7 @@
       (fn [{:keys [game-id]}]
         (let [game (get @games game-id)
               winner (:game/winner game)]
-          (arena/arena @arena canvas-id)
+
           [:div {:class-name root-class}
            [:div.left-game-play-panel {:id "wombat-arena"
                                        :class (when winner "game-over")}


Formatting

Formatting

--- src/leiningen/new/onyx_app/src/onyx_app/utils.clj
+++ src/leiningen/new/onyx_app/src/onyx_app/utils.clj
@@ -4,56 +4,57 @@
 ;;;; Test utils ;;;;

 (defn find-task-by-key
-      "Finds the catalog entry where the key correspond to the value
-      TODO: make this as robust as find-task"
-      [catalog k value]
-      (let [matches (filter #(= value (k %)) catalog)]
-           (first matches)))
+  "Finds the catalog entry where the key correspond to the value
+  TODO: make this as robust as find-task"
+  [catalog k value]
+  (let [matches (filter #(= value (k %)) catalog)]
+    (first matches)))

 (defn find-task
-      "Finds the catalog entry where the :onyx/name key equals task-name"
-      [catalog task-name]
-      (let [matches (filter #(= task-name (:onyx/name %)) catalog)]
-           (when-not (seq matches)
-                     (throw (ex-info (format "Couldn't find task %s in catalog" task-name)
-                                     {:catalog catalog :task-name task-name})))
-           (first matches)))
+  "Finds the catalog entry where the :onyx/name key equals task-name"
+  [catalog task-name]
+  (let [matches (filter #(= task-name (:onyx/name %)) catalog)]
+    (when-not (seq matches)
+      (throw (ex-info (format "Couldn't find task %s in catalog" task-name)
+                      {:catalog catalog :task-name task-name})))
+    (first matches)))

 (defn update-task
-      "Finds the catalog entry with :onyx/name task-name
-      and applies f to it, returning the full catalog with the
-      transformed catalog entry"
-      [catalog task-name f]
-      (mapv (fn [entry]
-                (if (= task-name (:onyx/name entry))
-                  (f entry)
-                  entry))
-            catalog))
+  "Finds the catalog entry with :onyx/name task-name
+  and applies f to it, returning the full catalog with the
+  transformed catalog entry"
+  [catalog task-name f]
+  (mapv (fn [entry]
+          (if (= task-name (:onyx/name entry))
+            (f entry)
+            entry))
+        catalog))

 (defn add-to-job
-      "Adds to the catalog and lifecycles of a job in form
-      {:workflow ...
-       :catalog ...
-       :lifecycles ...}"
-      [job {:keys [catalog lifecycles]}]
-      (-> job
-          (update :catalog into catalog)
-          (update :lifecycles into lifecycles)))
+  "Adds to the catalog and lifecycles of a job in form
+  {:workflow ...
+  :catalog ...
+  :lifecycles ...}"
+  [job {:keys [catalog lifecycles workflow]}]
+  (-> job
+      (update :workflow into workflow)
+      (update :catalog into catalog)
+      (update :lifecycles into lifecycles)))

 (defn n-peers
-      "Takes a workflow and catalog, returns the minimum number of peers
-       needed to execute this job."
-      [catalog workflow]
-      (let [task-set (into #{} (apply concat workflow))]
-           (reduce
-             (fn [sum t]
-                 (+ sum (or (:onyx/min-peers (find-task catalog t)) 1)))
-             0 task-set)))
+  "Takes a workflow and catalog, returns the minimum number of peers
+  needed to execute this job."
+  [catalog workflow]
+  (let [task-set (into #{} (apply concat workflow))]
+    (reduce
+      (fn [sum t]
+        (+ sum (or (:onyx/min-peers (find-task catalog t)) 1)))
+      0 task-set)))

 (defn segments-equal?
-      "Onyx is a parallel, distributed system - so ordering isn't guaranteed.
-       Does an unordered comparison of segments to check for equality."
-      [expected actual]
-      (is (= (into #{} expected) (into #{} (remove (partial = :done) actual))))
-      (is (= :done (last actual)))
-      (is (= (dec (count actual)) (count expected))))
+  "Onyx is a parallel, distributed system - so ordering isn't guaranteed.
+  Does an unordered comparison of segments to check for equality."
+  [expected actual]
+  (is (= (into #{} expected) (into #{} (remove (partial = :done) actual))))
+  (is (= :done (last actual)))
+  (is (= (dec (count actual)) (count expected))))


Fix up utils/stringify-elements behavior (#340)

--- waiter/src/waiter/util/utils.clj
+++ waiter/src/waiter/util/utils.clj
@@ -116,19 +116,18 @@

 (defn stringify-elements
   [k v]
-  (if (vector? v)
-    (map (partial stringify-elements k) v)
-    (cond
-      (instance? DateTime v) (du/date-to-str v)
-      (instance? UUID v) (str v)
-      (instance? Pattern v) (str v)
-      (instance? PersistentQueue v) (vec v)
-      (instance? ManyToManyChannel v) (str v)
-      (instance? Process v) (str v)
-      (instance? ValidationError v) (str v)
-      (= k :time) (str v)
-      (symbol? v) (str/join "/" ((juxt namespace name) v))
-      :else v)))
+  (cond
+    (vector? v) (mapv (partial stringify-elements k) v)
+    (instance? DateTime v) (du/date-to-str v)
+    (instance? UUID v) (str v)
+    (instance? Pattern v) (str v)
+    (instance? PersistentQueue v) (vec v)
+    (instance? ManyToManyChannel v) (str v)
+    (instance? Process v) (str v)
+    (instance? ValidationError v) (str v)
+    (= k :time) (str v)
+    (symbol? v) (str/join "/" ((juxt namespace name) v))
+    :else v))

 (defn map->json
   "Convert the input data into a json string."
@@ -152,6 +151,9 @@
              (let [writer (OutputStreamWriter. (.getOutputStream resp))]
                (try
                  (json/write data-map writer :value-fn stringify-elements)
+                 (catch Exception e
+                   (log/error e "Exception creating streaming json response")
+                   (throw e))
                  (finally
                    (.flush writer)))))}))


Collector: Metrics are not send if the user has no credentials for the Cloud or if collection returned an error.

--- jar-async/src/slipstream/async/collector.clj
+++ jar-async/src/slipstream/async/collector.clj
@@ -88,19 +88,6 @@
   [user connector elapsed v]
   (log/log-info (build-msg user connector elapsed "Number of VMs collected = " v)))

-(defn collect!
-  [user connector]
-  (let [ch (chan 1) start-ts (System/currentTimeMillis)]
-    (go
-      (let [ [v _] (alts! [ch (timeout timeout-collect-reader-release)])
-             elapsed (- (System/currentTimeMillis) start-ts) ]
-        (swap! busy free [(get-name user) connector])
-        (cond
-          (nil? v) (log-timeout user connector elapsed)
-          (< v -1) (log-failure user connector elapsed)
-          :else (log-collected user connector elapsed v))))
-    (go (>! ch (Collector/collect user connector (msecs-in-seconds timeout-collect))))))
-
 (defn update-metric!
   [user]
   (let [ch (chan 1)]
@@ -112,6 +99,22 @@
             (get-name user))
           (log/log-info (str "executed update-metric request for " (get-name user))))))
     (go (>! ch (updator/update user)))))
+
+(defn collect!
+  [user connector]
+  (let [ch (chan 1) start-ts (System/currentTimeMillis)]
+    (go
+      (let [ [v _] (alts! [ch (timeout timeout-collect-reader-release)])
+             elapsed (- (System/currentTimeMillis) start-ts) ]
+        (swap! busy free [(get-name user) connector])
+        (cond
+          (nil? v) (log-timeout user connector elapsed)
+          (< v -1) (log-failure user connector elapsed)
+          :else (log-collected user connector elapsed v))
+        (if (and (updator/metering-enabled?) (>= v 0))
+          (update-metric! user))
+        ))
+    (go (>! ch (Collector/collect user connector (msecs-in-seconds timeout-collect))))))

 (def not-nil? (complement nil?))

@@ -128,8 +131,6 @@
             (try
               (log/log-info (str "executing collect request for " (get-name user) " and " (.getConnectorInstanceName connector)))
               (collect! user connector)
-              (if (updator/metering-enabled?)
-                 (update-metric! user))
               (catch Exception e (log/log-warn "caught exception executing collect request: " (.getMessage e))))))))))

 (defonce ^:dynamic *online-collect-processor* (collect-readers online-collector-chan))


fix NPE

fix NPE

--- src/main/shadow/cljs/devtools/server/compiler.clj
+++ src/main/shadow/cljs/devtools/server/compiler.clj
@@ -62,6 +62,12 @@

 (defn deep-merge [a b]
   (cond
+    (nil? a)
+    b
+
+    (nil? b)
+    a
+
     (and (map? a) (map? b))
     (merge-with deep-merge a b)

@@ -86,7 +92,9 @@
 (defn config-merge [config mode]
   (let [mode-opts (get config mode)]
     (-> config
-        (deep-merge mode-opts)
+        (cond->
+          mode-opts
+          (deep-merge mode-opts))
         (dissoc :release :dev))))

 (defn get-target-fn [target]


for purposes of conjugating regular future and conditional, the stem is simply the infinitive

--- src/babel/espanol/morphology/verbs.cljc
+++ src/babel/espanol/morphology/verbs.cljc
@@ -34,7 +34,8 @@
                        (exception (str "Can't regex-find on non-string: " infinitive " from word: " word))))
         er-type (re-find #"er$" infinitive)
         ir-type (re-find #"ir$" infinitive)
-        stem (string/replace infinitive #"[iae]r$" "")
+        stem infinitive ;; stem is simply the same as the infinitive for conditional.
+
         ;; conditional shares usage of :futuro-stem with future.
         stem (if (get-in word [:futuro-stem])
                (get-in word [:futuro-stem])
@@ -143,7 +144,7 @@
                        (exception (str "Can't regex-find on non-string: " infinitive " from word: " word))))
         er-type (re-find #"er$" infinitive)
         ir-type (re-find #"ir$" infinitive)
-        stem (string/replace infinitive #"[iae]r$" "")
+        stem infinitive ;; stem is simply the same as the infinitive for future.
         stem (if (get-in word [:futuro-stem])
                (get-in word [:futuro-stem])
                stem)


Refactor save-theme-file function

Refactor save-theme-file function

--- src/cljs/koeeoadi/components/theme.cljs
+++ src/cljs/koeeoadi/components/theme.cljs
@@ -23,22 +23,20 @@
 (defn new-theme [comp]
   (om/transact! comp `[(theme/new) :theme/map]))

-;; TODO consider saving a compressed file
+(defn encode-props [props]
+  (str "data:text/plain;charset=utf-8;base64,"
+    (.btoa js/window
+      (pr-str props))))
+
 (defn save-theme-file [comp current-theme]
   (let [link (gdom/getElement "download-link")]
     (aset link "download" (str current-theme ".koee"))
-    ;; TODO cleanup
-    (aset link "href" (str
-                        "data:text/plain;charset=utf-8;base64,"
-                        (.btoa js/window
-                          (pr-str
-                            (select-keys @reconciler [:theme/name
-                                                      :colors/by-id
-                                                      :colors/list
-                                                      :faces/by-name
-                                                      :faces/list
-                                                      :user-faces/list
-                                                      :user-faces/by-name])))))
+    (aset link "href" (encode-props
+                        (select-keys @reconciler
+                          [:theme/name  :colors/by-id
+                           :colors/list :faces/by-name
+                           :faces/list  :user-faces/list
+                           :user-faces/by-name])))
     (.click link)))

 (defn export-theme-file [current-theme editor]


small ui changes

small ui changes

--- src-cljs/tranjlator/master_view.cljs
+++ src-cljs/tranjlator/master_view.cljs
@@ -31,9 +31,12 @@
   (reify
     om/IRenderState
     (render-state [this state]
-      (let [label (om/get-state owner :label)]
+      (let [label (om/get-state owner :label)
+            glyph (om/get-state owner :glyph)]
         (dom/div #js {:className "col-md-5"}
-                 (dom/h4 nil label)
+                 (dom/h4 nil
+                         (dom/span #js {:className glyph})
+                         label)
                  (apply dom/ul nil
                         (map (fn [item] (dom/li nil (format-chat item))) app)))))))

@@ -47,8 +50,10 @@
       (let [sender-ch (:sender-ch app)]
         (dom/div nil
                  (om/build users-view (:users app))
-                 (om/build chat-view (:original app) {:init-state {:label "Original"}})
-                 (om/build chat-view (:translated app) {:init-state {:label "Translated"}})
+                 (om/build chat-view (:original app) {:init-state {:label " Original"
+                                                                   :glyph "glyphicon glyphicon-globe"}})
+                 (om/build chat-view (:translated app) {:init-state {:label " Translated"
+                                                                     :glyph "glyphicon glyphicon-home"}})
                  (dom/div #js {:className "form-group col-md-8 col-md-offset-2"}
                           (dom/input #js {:className "form-control" :type "text"
                                           :value text
@@ -57,4 +62,4 @@
                  (dom/div #js {:className "col-xs-offset-2 col-xs-10"}
                           (dom/button #js {:type "button" :className "button"
                                            :onClick (fn [e] (send-message-click sender-ch text owner app))}
-                                      "Enter")))))))
+                                      (dom/span #js {:className "glyphicon glyphicon-leaf"}) " Enter")))))))


if you have dups, replace them both

if you have dups, replace them both

--- src-cljs/tranjlator/master_view.cljs
+++ src-cljs/tranjlator/master_view.cljs
@@ -42,10 +42,11 @@
                       :content-sha sha)))
     (clear-text owner)))

-(defn replacer [col key val new-val]
+(defn replacer [col key val new-val ex-key ex-val]
   (loop [src col acc []]
     (cond (empty? src) (conj acc new-val)
-          (= (key (first src)) val) (concat acc [new-val] (rest src))
+          (and (= (key (first src)) val)
+               (not (= (ex-key (first src)) ex-val))) (concat acc [new-val] (rest src))
           :default (recur (rest src) (conj acc (first src))))))

 (defn users-view [app owner]
@@ -100,8 +101,8 @@
     om/IDidUpdate
     (did-update [_ _ _]
       (let [panel (.getElementById js/document "translated-panel")]
-        (set! (.-scrollTop panel) (.-scrollHeight panel)))))
-  )
+        (set! (.-scrollTop panel) (.-scrollHeight panel))))))
+
 (defn master-view [app owner]
   (reify
     om/IWillMount
@@ -118,7 +119,9 @@
                    (= :original topic) (om/transact! app :original (fn [col] (conj col msg)))
                    (= :user-join topic) (om/transact! app :users (fn [col] (conj col (:user-name msg []))))
                    (= :user-part topic) (om/transact! app :users (fn [col] (remove (fn [x] (= x (:user-name msg))) col)))
-                   (= (keyword lang) topic) (om/transact! app :translated (fn [col] (replacer col :original-sha (:original-sha msg) msg)))
+                   (= (keyword lang) topic) (om/transact! app :translated
+                                                          (fn [col] (replacer col :original-sha
+                                                                             (:original-sha msg) msg :topic topic)))
                    (= :ping topic) (when (= (:target msg) (:user-name @app)) (ping))
                    (= :error topic) (do (let [name (:user-name @app)]
                                           (put! socket-ctrl "Doh")


Only consider drop deltas of fns and not of output fn, for now.

--- src/dsbdp/local_dpp_self_adaptivity.clj
+++ src/dsbdp/local_dpp_self_adaptivity.clj
@@ -78,10 +78,11 @@
 (defn create-mapping-updater
   []
   (fn [orig-mapping drop-det-vec]
+    (let [fn-drops (subvec drop-det-vec 0 (dec (count drop-det-vec)))]
     (cond
-      (every? #(= false %) drop-det-vec) orig-mapping
+      (every? #(= false %) fn-drops) orig-mapping
       :default nil
-      )
+      ))
     )
   )


Fix last commit

Fix last commit

--- src/edu/berkeley/ai/scripts/cluster.clj
+++ src/edu/berkeley/ai/scripts/cluster.clj
@@ -24,8 +24,8 @@
 	(apply util/sh
 	 (concat ["qsub"
 		  "-N" name
-		  "-o" (str (util/file-stem f ".out"))
-		  "-e" (str (util/file-stem f ".err"))]
+		  "-o" (str (util/file-stem f) ".out")
+		  "-e" (str (util/file-stem f) ".err")]
 		*default-qsub-options*
 		[:in (str *default-clj* " "f) :dir (util/dirname f)]))))))


Fix a broken scf/storage assertion

Fix a broken scf/storage assertion

This was trying to assert that the result of a query was equal to a
specific value, but the expected value was outside the (= ...) call,
rather directly inside the (is ...). So the test didn't fail, but it
didn't test what it was intended to.

--- test/com/puppetlabs/puppetdb/test/scf/storage.clj
+++ test/com/puppetlabs/puppetdb/test/scf/storage.clj
@@ -137,8 +137,8 @@
                   {:certname certname :fact "kernel" :value "Linux"}
                   {:certname certname :fact "operatingsystem" :value "Debian"}])))
         (testing "should add the certname if necessary"
-          (is (= (query-to-vec "SELECT name FROM certnames"))
-                 [{:name certname}]))
+          (is (= (query-to-vec "SELECT name FROM certnames")
+                 [{:name certname}])))
         (testing "replacing facts"
           (let [new-facts {"domain" "mynewdomain.com"
                            "fqdn" "myhost.mynewdomain.com"


add uniqueness to file name

add uniqueness to file name


cleanup

cleanup

--- src/frontend/cljs/alibi/entry_page.cljs
+++ src/frontend/cljs/alibi/entry_page.cljs
@@ -182,13 +182,8 @@
   {:target (js/document.getElementById "entry-form-react-container")})

 (defn build-activity-graphic-state [for-state]
-  (let [selected-entry (-> (input-entry for-state)
-                           (post-entry-form/additional-entry)
-                           (input-entry->data-entry))]
-    {:dispatch! (partial dispatch! state)
-
-     :on-change-date on-change-date
-     }))
+  {:dispatch! (partial dispatch! state)
+   :on-change-date on-change-date})

 (om/root
   (fn [for-state owner]


Add production support for MongoDB

Add production support for MongoDB

--- src/clj/battlebots/services/mongodb.clj
+++ src/clj/battlebots/services/mongodb.clj
@@ -5,7 +5,19 @@
             [monger.operators :refer :all])
   (:import org.bson.types.ObjectId))

-(def connection-uri "mongodb://127.0.0.1/battlebots")
+(def is-production? (= (System/getenv "CLJ_ENV") "production"))
+(def db-username (System/getenv "WT_BATTLEBOTS_MONGOD_USER_NAME"))
+(def db-password (System/getenv "WT_BATTLEBOTS_MONGOD_USER_PW"))
+(def db-host (System/getenv "WT_BATTLEBOTS_MONGOD_HOST_LIST"))
+
+;; Throw Exception if running in Prod with no database environment variables
+(if is-production?
+  (if (not (and db-username db-password db-host))
+    (throw (Exception. "Missing Database Environment Variable"))))
+
+(def connection-uri (if is-production?
+                      (str "mongodb://" db-username ":" db-password "@" db-host "/battlebots")
+                      "mongodb://127.0.0.1/battlebots"))

 (defn setup-db
   "Ensures collection indexes exist"