Fixed timing attack in signature verification in the cookie session store by replacing = with secure-compare. Adapted from http://codahale.com/a-lesson-in-timing-attacks/ Not using Java's MessageDigest.isEqual since that had a vulnerability until recently

--- ring-core/src/ring/middleware/session/cookie.clj
+++ ring-core/src/ring/middleware/session/cookie.clj
@@ -77,13 +77,22 @@
   (let [data (encrypt key (.getBytes (pr-str data)))]
     (str (codec/base64-encode data) "--" (hmac key data))))

+(defn- secure-compare [a b]
+  (if (and a b (= (.length a) (.length b)))
+      (= 0
+         (reduce bit-or
+                 (map bit-xor
+                      (.getBytes a)
+                      (.getBytes b))))
+      false))
+
 (defn- unseal
   "Retrieve a sealed Clojure data structure from a string"
   [key ^String string]
   (let [[data mac] (.split string "--")
         data (codec/base64-decode data)]
-    (if (= mac (hmac key data))
-      (read-string (decrypt key data)))))
+    (if (secure-compare mac (hmac key data))
+        (read-string (decrypt key data)))))

 (deftype CookieStore [secret-key]
   SessionStore


Add some logging statements

Add some logging statements

--- src/time_tracker/timers/pubsub.clj
+++ src/time_tracker/timers/pubsub.clj
@@ -7,7 +7,8 @@
             [time-tracker.util :as util]
             [clojure.spec :as s]
             [time-tracker.timers.spec]
-            [clojure.algo.generic.functor :refer [fmap]]))
+            [clojure.algo.generic.functor :refer [fmap]]
+            [time-tracker.logging :as log]))

 ;; Connection management -------

@@ -25,13 +26,19 @@
 (defn add-channel!
   "Adds a channel to the map of active connections."
   [channel google-id]
-  (swap! active-connections update google-id conj-to-set channel))
+  (swap! active-connections update google-id conj-to-set channel)
+  (log/info {:event     ::added-websockets-connection
+             :google-id google-id}))

 (defn on-close!
   "Called when a channel is closed."
   [channel google-id status]
-  ;; TODO: Use status in logging
-  (swap! active-connections update google-id disj channel))
+  ;; See https://github.com/http-kit/http-kit/blob/protocol-api/src/org/httpkit/server.clj#L61
+  ;; for the possible values of status
+  (swap! active-connections update google-id disj channel)
+  (log/info {:event     ::removed-websockets-connection
+             :google-id google-id
+             :status    status}))

 ;; Utils ----------------------

@@ -56,7 +63,7 @@
   [spec args]
   (when-not (s/valid? spec args)
     (throw (ex-info "Invalid args"
-                    {:error "Invalid args"}))))
+                    {::validation-error "Invalid args"}))))

 ;; Commands -----

@@ -121,14 +128,23 @@

 ;; Middleware ----

+(defn- wrap-exception
+  [func]
+  (fn [channel google-id args]
+    (try
+      (func channel google-id args)
+      (catch Exception ex
+        (log/error ex {:event     ::message-handler-failed
+                       :google-id google-id
+                       :args      args})))))
+
 (defn- wrap-validator
   [func]
   (fn [channel google-id args]
     (try
       (func channel google-id args)
       (catch Exception e
-        (if-let [{:keys [error]} (ex-data e)]
-          ;; TODO: Add logging
+        (if-let [error (::validation-error (ex-data e))]
           (send-invalid-args! channel)
           (throw e))))))

@@ -144,7 +160,11 @@
     (if-let [timer-id (:timer-id args)] ;; Necessary b/c validation hasn't happened yet
       (if (timers.db/owns? connection google-id timer-id)
         (func channel google-id connection args)
-        (send-error! channel "Unauthorized"))
+        (do
+          (log/warn {:event     ::unauthorized-timer-action
+                     :google-id google-id
+                     :timer-id  timer-id})
+          (send-error! channel "Unauthorized")))
       (send-invalid-args! channel))))

 (defn- wrap-can-create-timer
@@ -153,7 +173,11 @@
     (if-let [project-id (:project-id args)]
       (if (timers.db/has-timing-access? connection google-id project-id)
         (func channel google-id connection args)
-        (send-error! channel "Unauthorized"))
+        (do
+          (log/warn {:event      ::unauthorized-timer-creation
+                     :google-id  google-id
+                     :project-id project-id})
+          (send-error! channel "Unauthorized")))
       (send-invalid-args! channel))))

 ;; Routes --
@@ -166,7 +190,7 @@

 (def command-map
   (wrap-middlewares
-   [wrap-validator wrap-transaction]
+   [wrap-exception wrap-validator wrap-transaction]
    (merge {"create-and-start-timer" (wrap-can-create-timer
                                      create-and-start-timer-command!)}
           (wrap-middlewares
@@ -183,6 +207,5 @@
   [channel google-id command-data]
   (if-let [command-fn (command-map (get command-data :command))]
     (command-fn channel google-id (dissoc command-data :command))
-    ;; TODO: Add error logging
     (send! channel (json/encode
                     {:error "Invalid command"}))))


AB + DM - Add blockchain-accounts to wallet record definition

--- src/freecoin/wallet.clj
+++ src/freecoin/wallet.clj
@@ -89,7 +89,7 @@

 (defrecord wallet
     [_id name email public-key private-key
-     blockchains blockchain-secrets])
+     blockchains blockchain-accounts blockchain-secrets])

 (defn new [name email]
   (wallet. (:string (rand/create 20)) ;; unique id


array of arrays needs recur

array of arrays needs recur

--- src/harnocode/core.cljs
+++ src/harnocode/core.cljs
@@ -223,8 +223,7 @@

 (defn array-to-arrays [src w acc]
   (let [[h t] (split-at w src)]
-    (if (empty? t) h (array-to-arrays t w (assoc acc (count acc) h)))
-  ))
+    (if (empty? h) acc (array-to-arrays t w (conj acc h)))))

 (defn black-and-white [context canvas]
   (let [pixels (get-pixels context canvas)


NE | 0 | Fixed error in config value for activities per page - changed 8 to 50

--- src/mooncake/config.clj
+++ src/mooncake/config.clj
@@ -61,4 +61,4 @@
     (get-env config-m :mongo-uri)
     "mongodb://localhost:27017/mooncake"))

-(def activities-per-page 8)
+(def activities-per-page 50)


acesss to upgrades in central servers

acesss to upgrades in central servers

--- src/node/game/core.cljs
+++ src/node/game/core.cljs
@@ -382,15 +382,17 @@

 (defmethod access :hq [state side server]
   (let [n (+ (get-in @state [:runner :hq-access]) (get-in @state [:run :access-bonus]))]
-    (take n (shuffle (get-in @state [:corp :hand])))))
+    (concat (take n (shuffle (get-in @state [:corp :hand])))
+            (get-in @state [:corp :servers :hq :content]))))

 (defmethod access :rd [state side server]
   (let [n (+ (get-in @state [:runner :rd-access]) (get-in @state [:run :access-bonus]))]
-    (take n (get-in @state [:corp :deck]))))
+    (concat (take n (get-in @state [:corp :deck]))
+            (get-in @state [:corp :servers :rd :content]))))

 (defmethod access :archives [state side server]
   (swap! state update-in [:corp :discard] #(map (fn [c] (assoc c :seen true)) %))
-  (get-in @state [:corp :discard]))
+  (concat (get-in @state [:corp :discard]) (get-in @state [:corp :servers :archives :content])))

 (defmethod access :remote [state side server]
   (get-in @state [:corp :servers :remote (js/parseInt (last server)) :content]))


Doc string and clearer schema

Doc string and clearer schema

--- src/parmenides/core.clj
+++ src/parmenides/core.clj
@@ -99,8 +99,8 @@
     :db.install/_attribute :db.part/db
     :db/id #db/id[:db.part/db]}

-   {:db/id #db/id [:db.part/user]
-    :db/ident :parmenides.resolution/continuous
+   {:db/ident :parmenides.resolution/continuous
+    :db/id #db/id [:db.part/user]
     :db/fn #db/fn {:lang "clojure"
                    :params [conn]
                    :requires [[clojure.core.async :refer [go-loop]]
@@ -110,9 +110,10 @@
                              (seq (:tx-data (.poll queue)))
                              (println "Got Data")))}}])

-(defn continous-resolution [conn]
-  (-> conn
-      d/db
-      (d/entity :parmenides.resolution/continuous)
-      :db/fn
-      (.invoke conn)))
+(defn continous-resolution
+  "Given a datomic connection, this will automatically fire the resolution
+  process every time new datoms are put into the database and update
+  accordingly."
+  [conn] ;;N.B. The actual work is done by the database function
+  (-> conn d/db (d/entity :parmenides.resolution/continuous)
+      :db/fn (.invoke conn)))


Remove duplication in gutter api

Remove duplication in gutter api

--- src/lt/objs/editor.cljs
+++ src/lt/objs/editor.cljs
@@ -373,29 +373,29 @@

 (defn add-gutter [e class-name width]
   (let [gutter-classes (set (conj (js->clj (option e "gutters")) class-name))
-        gutter-div (dom/$ :div.CodeMirror-gutters (object/->content e))
-        gutter-divs (dom/$$ :div.CodeMirror-gutter gutter-div)
-        current-widths (reduce (fn [res gutter]
-                                 (let [gutter-class (clojure.string/replace-first (dom/attr gutter "class") "CodeMirror-gutter " "")]
-                                   (assoc res gutter-class (dom/width gutter)))
-                                 ) {} gutter-divs)
+        current-widths (gutter-widths e)
         new-gutter-widths (assoc current-widths class-name width)]
-    (operation e (fn[]
-                   (set-options e {:gutters (clj->js gutter-classes)})
-                   (doseq [[k v] new-gutter-widths]
-                     (dom/set-css (dom/$ (str "div." k) gutter-div) {"width" (str v "px")}))))))
+    (update-gutters e gutter-classes new-gutter-widths)))

 (defn remove-gutter [e class-name]
   (let [gutter-classes (remove #{class-name} (js->clj (option e "gutters")))
-        gutter-div (dom/$ :div.CodeMirror-gutters (object/->content e))
+        current-widths (gutter-widths e)]
+    (update-gutters e gutter-classes current-widths)))
+
+(defn gutter-widths [e]
+  (let [gutter-div (dom/$ :div.CodeMirror-gutters (object/->content e))
         gutter-divs (dom/$$ :div.CodeMirror-gutter gutter-div)
         current-widths (reduce (fn [res gutter]
                                  (let [gutter-class (clojure.string/replace-first (dom/attr gutter "class") "CodeMirror-gutter " "")]
                                    (assoc res gutter-class (dom/width gutter)))
                                  ) {} gutter-divs)]
+    current-widths))
+
+(defn update-gutters [e class-names class-widths]
+  (let [gutter-div (dom/$ :div.CodeMirror-gutters (object/->content e))]
     (operation e (fn[]
-                   (set-options e {:gutters (clj->js gutter-classes)})
-                   (doseq [[k v] new-gutter-widths]
+                   (set-options e {:gutters (clj->js class-names)})
+                   (doseq [[k v] class-widths]
                      (if-let [gutter (dom/$ (str "div." k) gutter-div)]
                        (dom/set-css gutter {"width" (str v "px")})))))))


Add some extra comments explaining how Oracle tests work :pencil:

--- test/metabase/test/data/oracle.clj
+++ test/metabase/test/data/oracle.clj
@@ -20,7 +20,16 @@
       (throw (Exception. (format "In order to test Oracle, you must specify the env var MB_ORACLE_%s."
                                  (s/upper-case (name env-var)))))))

-;; Similar to SQL Server, Oracle on AWS doesn't let you create different databases; like Redshift, we'll create a series of schemas for each DB, with a unique prefix for this "session"
+;; Similar to SQL Server, Oracle on AWS doesn't let you create different databases;
+;; We'll create a unique schema (the same as a "User" in Oracle-land) for each test run and use that to keep
+;; tests from clobbering over one another; we'll also qualify the names of tables to include their DB name
+;;
+;; e.g.
+;; H2 Tests                   | Oracle Tests
+;; ---------------------------+------------------------------------------------
+;; PUBLIC.VENUES.ID           | CAM_195.test_data_venues.id
+;; PUBLIC.CHECKINS.USER_ID    | CAM_195.test_data_checkins.user_id
+;; PUBLIC.INCIDENTS.TIMESTAMP | CAM_195.sad_toucan_incidents.incident_timestamp
 (defonce ^:private ^:const session-schema-number (rand-int 200))
 (defonce ^:private ^:const session-schema        (str "CAM_" session-schema-number))
 (defonce ^:private ^:const session-password      (apply str (repeatedly 16 #(rand-nth (map char (range (int \a) (inc (int \z))))))))


Serve public resources

Serve public resources

--- src/pericles/routes.clj
+++ src/pericles/routes.clj
@@ -19,6 +19,6 @@
   (route/not-found "Not found!"))

 (def app (-> #'api-routes
-             (wrap-defaults api-defaults)
+             (wrap-defaults (assoc api-defaults :static {:resources "public"}))
              handlers/wrap-catch-exceptions
              handlers/wrap-log-request))


Back out of JGroups test. Can't support both cluster types at the moment.

--- test/onyx/hornetq/jgroups_test.clj
+++ test/onyx/hornetq/jgroups_test.clj
@@ -1,113 +0,0 @@
-(ns onyx.hornetq.jgroups-test
-  (:require [midje.sweet :refer :all]
-            [onyx.queue.hornetq-utils :as hq-util]
-            [onyx.api]))
-
-(def n-messages 15000)
-
-(def batch-size 1320)
-
-(def echo 1000)
-
-(def in-queue (str (java.util.UUID/randomUUID)))
-
-(def out-queue (str (java.util.UUID/randomUUID)))
-
-(def hornetq-host "localhost")
-
-(def hornetq-port 5446)
-
-(def hornetq-cluster-name "onyx-cluster")
-
-(def jgroups-file "onyx-jgroups.xml")
-
-(def jgroups-channel "onyx-broadcast-channel")
-
-(def hornetq-refresh-timeout 5000)
-
-(def hornetq-discovery-timeout 5000)
-
-(def hq-config {"host" hornetq-host "port" hornetq-port})
-
-(hq-util/create-queue! hq-config in-queue)
-(hq-util/create-queue! hq-config out-queue)
-
-(hq-util/write-and-cap! hq-config in-queue (map (fn [x] {:n x}) (range n-messages)) echo)
-
-(defn my-inc [{:keys [n] :as segment}]
-  (assoc segment :n (inc n)))
-
-(def catalog
-  [{:onyx/name :in
-    :onyx/ident :hornetq/read-segments
-    :onyx/type :input
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name in-queue
-    :hornetq/host hornetq-host
-    :hornetq/port hornetq-port
-    :onyx/batch-size batch-size}
-
-   {:onyx/name :inc
-    :onyx/fn :onyx.hornetq.jgroups-test/my-inc
-    :onyx/type :transformer
-    :onyx/consumption :concurrent
-    :onyx/batch-size batch-size}
-
-   {:onyx/name :out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name out-queue
-    :hornetq/host hornetq-host
-    :hornetq/port hornetq-port
-    :onyx/batch-size batch-size}])
-
-(def workflow {:in {:inc :out}})
-
-(def id (str (java.util.UUID/randomUUID)))
-
-(def coord-opts {:hornetq/mode :jgroups
-                 :hornetq.jgroups/cluster-name hornetq-cluster-name
-                 :hornetq.jgroups/file jgroups-file
-                 :hornetq.jgroups/channel-name jgroups-channel
-                 :hornetq.jgroups/refresh-timeout hornetq-refresh-timeout
-                 :hornetq.jgroups/discovery-timeout hornetq-discovery-timeout
-                 :zookeeper/address "127.0.0.1:2181"
-                 :onyx/id id
-                 :onyx.coordinator/revoke-delay 5000})
-
-(def conn (onyx.api/connect (str "onyx:memory//localhost/" id) coord-opts))
-
-(def peer-opts {:hornetq/mode :jgroups
-                :hornetq.jgroups/cluster-name hornetq-cluster-name
-                :hornetq.jgroups/file jgroups-file
-                :hornetq.jgroups/channel-name jgroups-channel
-                :hornetq.jgroups/refresh-timeout hornetq-refresh-timeout
-                :hornetq.jgroups/discovery-timeout hornetq-discovery-timeout
-
-                :zookeeper/address "127.0.0.1:2181"
-                :onyx/id id})
-
-(def v-peers (onyx.api/start-peers conn 1 peer-opts))
-
-(onyx.api/submit-job conn {:catalog catalog :workflow workflow})
-
-(def results (hq-util/read! hq-config out-queue (inc n-messages) echo))
-
-(try
-  ;; (dorun (map deref (map :runner v-peers)))
-  (finally
-   (doseq [v-peer v-peers]
-     (try
-       ((:shutdown-fn v-peer))
-       (catch Exception e (prn e))))
-   (try
-     (onyx.api/shutdown conn)
-     (catch Exception e (prn e)))))
-
-(let [expected (set (map (fn [x] {:n (inc x)}) (range n-messages)))]
-  (fact (set (butlast results)) => expected)
-  (fact (last results) => :done))
-


More dox indentation fixes :poop:

More dox indentation fixes :poop:

--- src/metabase/driver.clj
+++ src/metabase/driver.clj
@@ -121,8 +121,8 @@
     "Return a lazy sequence of all values of FIELD.
      This is used to implement some methods of the database sync process which require rows of data during execution.

-     The lazy sequence should not return more than `max-sync-lazy-seq-results`, which is currently `10000`.
-     For drivers that provide a chunked implementation, a recommended chunk size is `field-values-lazy-seq-chunk-size`, which is currently `500`.")
+  The lazy sequence should not return more than `max-sync-lazy-seq-results`, which is currently `10000`.
+  For drivers that provide a chunked implementation, a recommended chunk size is `field-values-lazy-seq-chunk-size`, which is currently `500`.")

   (humanize-connection-error-message ^String [this, ^String message]
     "*OPTIONAL*. Return a humanized (user-facing) version of an connection error message string.


Fix tests

Fix tests

--- test/subman/sources/t_addicted.clj
+++ test/subman/sources/t_addicted.clj
@@ -1,6 +1,7 @@
 (ns subman.sources.t-addicted
   (:use midje.sweet)
   (:require [subman.sources.addicted :as addicted]
+            [subman.helpers :as helpers]
             [net.cgrand.enlive-html :as html]))

 (defn- get-from-file
@@ -23,32 +24,32 @@
 (facts "shows list parser"
        (fact "return all shows"
              (count (addicted/get-shows)) => 2741
-             (provided (addicted/fetch anything) => (get-shows)))
+             (provided (helpers/fetch anything) => (get-shows)))
        (fact "return correct show maps"
              (-> (addicted/get-shows)
                  first
                  (#(and (contains? % :name)
                         (contains? % :url)))) => true
-             (provided (addicted/fetch anything) => (get-shows))))
+             (provided (helpers/fetch anything) => (get-shows))))

 (facts "single show parser"
        (fact "return all seasons"
              (count (addicted/get-episodes {:url ""})) => 9
-             (provided (addicted/fetch anything) => (get-single-show)))
+             (provided (helpers/fetch anything) => (get-single-show)))
        (fact "return all episodes"
              (-> (addicted/get-episodes {:url ""})
                  first
                  :episodes
                  count) => 10
-             (provided (addicted/fetch anything) => (get-single-show))))
+             (provided (helpers/fetch anything) => (get-single-show))))

 (facts "single episode parser"
        (fact "return all versions"
              (count (addicted/get-versions {:url ""})) => 2
-             (provided (addicted/fetch anything) => (get-single-episode)))
+             (provided (helpers/fetch anything) => (get-single-episode)))
        (fact "return all languages"
              (-> (addicted/get-versions {:url ""})
                  first
                  :langs
                  count) => 3
-             (provided (addicted/fetch anything) => (get-single-episode))))
+             (provided (helpers/fetch anything) => (get-single-episode))))


Factor out heavily repeated code.

Factor out heavily repeated code.

--- src/re_demo/layout.cljs
+++ src/re_demo/layout.cljs
@@ -3,7 +3,56 @@
             [re-demo.utils :refer [panel-title title2]]))

-(defn flex-box
+
+(defn components-section
+  []
+  [v-box
+   :children [[title :level :level2 :label "The Components"]
+              [p "Re-com has layout components which are not themselves visible -
+              they just arrange other components."]
+              [p "The key components are " [:span.bold "h-box"] " and " [:span.bold "v-box"] " which arange
+               their children horizontally and vertically respectively. Because they are
+               mutually nestable, you can combine them to create arbitrarily complex layouts."]]])
+
+(defn example-section
+  []
+  [v-box
+   :children [[title :level :level2 :label "Simple Example"]
+              [h-box
+               ;:gap "40px"
+               :children [
+                          [v-box
+                           :children [
+                                      [p "This code ..."]
+                                      [:pre
+                                       {:style {:width "460px"}}
+                                       "[v-box
+  :children [[box :child \"Header\"]
+             [h-box
+              :height \"100px\"
+              :children [[box :size \"70px\" :child \"Nav\"]
+                         [box :size \"1\" :child \"Content\"]]
+             [box :child \"Footer\"]]]"]]]
+                          [box
+                           :size "100px"
+                           :align-self  :center
+                           :justify :center
+                           :child  [:div {:class "md-forward rc-icon-larger"
+                                          :style {:color "lightgrey"}}]]
+                          [v-box
+                           :children [[p "... results in:"]
+                                      [v-box
+                                       :gap      "1px"
+                                       :children [[box :style {:background-color "lightgrey"} :child "Header"]
+                                                  [h-box
+                                                   :gap "1px"
+                                                   :height "100px"
+                                                   :children [[box :size "70px" :style {:background-color "lightgrey"} :child "Nav"]
+                                                              [box :size "1" :style {:background-color "lightgrey"} :child "Content"]]]
+                                                  [box :style {:background-color "lightgrey"} :child "Footer"]]]
+                                      [gap :size "15px"]]]]]]])
+
+(defn flex-box-section
   []
   [v-box
    :gap "10px"
@@ -42,7 +91,7 @@
                                         :href "http://i.stanford.edu/pub/cstr/reports/csl/tr/88/358/CSL-TR-88-358.pdf"
                                         :target "_blank"]
                                        ", and yet HTML5 only has a weak, half-arsed version?"]
-                                      [p {:style {:width "250px"}} "Talk about regression."]]]]]
+                                      ]]]]
               [v-box
                :children [[title :level :level2 :label "Warning: Be All In"]
                           [p "Flexbox works via the interplay of styles present on a " [:span.bold "container"] " (parent) and its " [:span.bold "items"] " (children).
@@ -57,7 +106,7 @@
                ]]]])

-(defn the-key-style
+(defn key-style-section
   []
   [v-box
    :children [[title :level :level2 :label "The Key Style"]
@@ -90,11 +139,23 @@
               [p "Sure, use the shortcuts. But it is only by understanding triples that you become a power user of flexbox (or re-com layouts)."]
               [gap :size "10px"]]])

-(defn size-table
-  []
+
+(defn table-row
+  [size gsb description header?]
   (let [col1 "80px"
         col2 "130px"
-        col3 "500px"]
+        col3 "500px"
+        col3-style {:style {:width col3}}]
+  [h-box
+   :class (if header? "rc-div-table-header" "rc-div-table-row")
+   :children [[label :width col1 :label size]
+              [label :width col2 :label gsb]
+              (if header?
+                [label :width col3 :label description]
+                [:span col3-style description])]]))
+
+(defn size-table
+  []
     [v-box
      :children [[title :level :level2 :label ":size is flex"]
                 [p "Both " [:span.bold "v-box"] " and " [:span.bold "h-box"] " take a " [:span.bold ":size"] " parameter which "
@@ -110,129 +171,77 @@
                 [v-box
                  :class "rc-div-table"
                  :align-self :start
-                 :children [[h-box
-                             :class "rc-div-table-header"
-                             :children [[label :width col1 :label ":size"]
-                                        [label :width col2 :label "G S B"]
-                                        [label :width col3 :label "Description"]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "initial"]
-                                        [label :width col2 :label "0 1 auto"]
-                                        [:span {:style {:width col3}} "Use the item's length. Never grow. Shrink if necessary.
-                                                                       Good for creating items with a natural maximum size, which can
-                                                                       shrink to some smaller size, typically given by min-width/height, if space becomes tight. "]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "auto"]
-                                        [label :width col2 :label "1 1 auto"]
-                                        [:span {:style {:width col3}} "Use the item's length. Grow if necessary. Shrink (to min-size) if necessary.
-                                                                       Good for creating items that happily take as much
-                                                                       space as they are allowed, or can shrink as much as they are forced to.
-                                                                       If necessary, use min-width/height to provide limits."]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "none"]
-                                        [label :width col2 :label "0 0 auto"]
-                                        [:span {:style {:width col3}} "Use the item's length. Never grow. Never shrink.
-                                                                      Good for creating rigid items that stick to their width/height if specified, otherwise their content size."]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "100px"]
-                                        [label :width col2 :label "0 0 100px"]
-                                        [:span {:style {:width col3}} "Item is given a fixed length of 100px (in the flex direction).
-                                                                      Good for headers/footers of fixed size, or LHS nav columns."]]]
-
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "60"]
-                                        [label :width col2 :label "60 1 0px"]
-                                        [:span {:style {:width col3}} "Set the item's default length to be 60 proportional units.
-                                        Allow it to streach. And it can shrink to nothing."]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "g s b"]
-                                        [label :width col2 :label "grow shrink basis"]
-                                        [:span {:style {:width col3}} "If none of the shortcut values above meet your needs,
-                                        you can always provide the triple yourself, to gain precise control. For example, the following item ..."]]]
-                            [h-box
-                             :class "rc-div-table-row"
-                             :children [[label :width col1 :label "1 0 auto"]
-                                        [label :width col2 :label "1 0 auto"]
-                                        [:span {:style {:width col3}} "In this very app, the light grey part of the LHS nav has this " [:span.bold ":size"] ". The light
-                                        grey background colour must always strech to the bottom of the page, hence
-                                        the streach.  The basis comes from its child nav items, hence the auto.
-                                        But it can't go smaller than its children, hence shrink of 0."]]]
-                            ]]]]))
-
-
-
-
-(defn example
-  []
-  [v-box
-   :children [[title :level :level2 :label "Example"]
-              [h-box
-               ;:gap "40px"
-               :children [
-                          [v-box
-                           :children [
-                                      [p "Some code:"]
-                                      [:pre
-                                       {:style {:width "460px"}}
-                                       "[v-box
-  :children [[box :child \"Header\"]
-             [h-box
-              :height \"100px\"
-              :children [[box :size \"70px\" :child \"Nav\"]
-                         [box :size \"100\" :child \"Content\"]]
-             [box :child \"Footer\"]]]"]]]
-                          [box
-                           :size "100px"
-                           :align-self  :center
-                           :justify :center
-                           :child  [:div {:class "md-forward rc-icon-larger"
-                                          :style {:color "lightgrey"}}]]
-                          [v-box
-                           :children [[p "will result in:"]
-                                      [v-box
-                                       :gap      "1px"
-                                       :children [[box :style {:background-color "lightgrey"} :child "Header"]
-                                                  [h-box
-                                                   :gap "1px"
-                                                   :height "100px"
-                                                   :children [[box :size "70px" :style {:background-color "lightgrey"} :child "Nav"]
-                                                              [box :size "100" :style {:background-color "lightgrey"} :child "Content"]]]
-                                                  [box :style {:background-color "lightgrey"} :child "Footer"]]]
-                                      [gap :size "15px"]]]]]]])
-
-(defn components
-  []
-  [v-box
-   :children [[title :level :level2 :label "The Components"]
-              [p "Re-com has layout components which are not themselves visible -
-              they just arrange other components."]
-              [p "The two key components are " [:span.bold "h-box"] " and " [:span.bold "v-box"] " which arange
-               their children horizontally and vertically respectively. Because they are
-               mutually nestable, they combine to create arbitrarily complex layouts."]]])
+                 :children [[table-row
+                             ":size"
+                             "G S B"
+                             "Description"
+                             true]
+                            [table-row
+                             "initial"
+                             "0 1 auto"
+                             "Use the item's length. Never grow. Shrink if necessary.
+                             Good for creating items with a natural maximum size, which can
+                             shrink to some smaller size, typically given by min-width/height, if space becomes tight. "]
+                            [table-row
+                             "auto"
+                             "1 1 auto"
+                             "Use the item's length. Grow if necessary. Shrink (to min-size) if necessary.
+                             Good for creating items that happily take as much
+                             space as they are allowed, or can shrink as much as they are forced to.
+                             If necessary, use min-width/height to provide limits."]
+                            [table-row
+                             "none"
+                             "0 0 auto"
+                             "Use the item's length. Never grow. Never shrink.
+                             Good for creating rigid items that stick to their width/height if specified, otherwise their content size."]
+                            [table-row
+                             "100px"
+                             "0 0 100px"
+                             "Item is given a fixed length of 100px (in the flex direction).
+                                                           Good for headers/footers of fixed size, or LHS nav columns."]
+
+                            [table-row
+                             "60"
+                             "60 1 0px"
+                             [:span "Set the item's default length to be 60 sibling-proportional units.
+                                    Allow it to streach. And it can shrink to nothing."
+                                    [:br]
+                                    "Look back at the \"Sample Example\" up the
+                                     top.  Notice that the \"content\" part has a :size of \"1\". Because the other child had a fixed
+                                     size of 70px, the Content streaches to fill all available space. No other sibling is making claims for space, so \"1\" might as well be \"100%\"."]]
+                            [table-row
+                             "g s b"
+                             "grow shrink basis"
+                             "If none of the shortcut values above meet your needs,
+                             you can always provide the triple yourself, to gain precise control. For example, the following item ..."]
+                            [table-row
+                             "1 0 auto"
+                             "1 0 auto"
+                             [:span "In this very app, the light grey part of the LHS nav has this " [:span.bold ":size"] ". The light
+                             grey background colour must always strech to the bottom of the page, hence
+                             the streach.  The basis comes from its child nav items, hence the auto.
+                             But it can't go smaller than its children, hence shrink of 0."]]
+                            ]]]])
+
+
+
+
 (defn panel2
   []
   [v-box
    :gap "10px"
    :children [[panel-title "Layout"]
-              [components]
-              [example]
-              [line]
-              [flex-box]
-              [line]
-              [gap :size "15px"]
+              [components-section]
+              [example-section]
+              [gap :size "10px"] [line]
+              [flex-box-section]
+              [gap :size "10px"] [line]
               [h-box
                :gap      "100px"
-               :children [[the-key-style]
-                          [size-table]]]]])
-
-
-
+               :children [[key-style-section]
+                          [size-table]]]
+
+              [gap :size "20px"]]])

 ;; core holds a reference to panel, so need one level of indirection to get figwheel updates


Send email from company slug @ opencompany.com

--- src/oc/email/mailer.clj
+++ src/oc/email/mailer.clj
@@ -12,17 +12,17 @@
    :secret-key c/aws-secret-access-key
    :endpoint   c/aws-endpoint})

-(def source (str "snapshot@" c/email-from-domain))
+(def default-reply-to (str "hello@" c/email-from-domain))

-(defn- send-email [to reply-to subject body]
+(defn- send-email [to reply-to subject company-slug body]
   "Send emails to all to recipients in parallel."
   (doall (pmap
     #(do
       (timbre/info "Sending email: " %)
       (ses/send-email creds
         :destination {:to-addresses [%]}
-        :source source
-        :reply-to-addresses [(if (s/blank? reply-to) source reply-to)]
+        :source (str company-slug "@" c/email-from-domain)
+        :reply-to-addresses [(if (s/blank? reply-to) default-reply-to reply-to)]
         :message {:subject subject
                   :body {:html body}}))
       (s/split to #","))))
@@ -34,7 +34,7 @@
     (try
       (spit html-file (content/html (assoc snapshot :note note))) ; create the email in a tmp file
       (shell/sh "juice" html-file inline-file) ; inline the CSS
-      (send-email to reply-to subject (slurp inline-file)) ; email it to the recipients
+      (send-email to reply-to subject (:company-slug snapshot) (slurp inline-file)) ; email it to the recipients
       (finally
         ; remove the tmp files
         (io/delete-file html-file true)
@@ -51,13 +51,13 @@
                          :reply-to "change@me.com"
                          :subject "[Buffer] Latest Update"
                          :note "Enjoy this groovy update!"
-                         :snapshot snapshot})
+                         :snapshot (assoc snapshot :company-slug "buffer")})

   (def snapshot (json/decode (slurp "./resources/snapshots/open.json")))
   (mailer/send-snapshot {:to "change@me.com,change+1@me.com,change+2@me.com"
                          :reply-to "change@me.com"
                          :subject "[OpenCompany] Check it"
                          :note "Hot diggity!"
-                         :snapshot snapshot})
+                         :snapshot (assoc snapshot :company-slug "open")})

 )


finnish notation in km/h pace

finnish notation in km/h pace

--- src/ontrail/formats.clj
+++ src/ontrail/formats.clj
@@ -32,7 +32,7 @@

 (defn to-human-pace-kmh [duration distance]
   (let [speed (+ 0.05 (/ (/ distance 1000.0) (/ duration 360000.0)))]
-    (format "%1.1f km/h" speed)))
+    (string/replace (format "%1.1f km/h" speed) #"\." ",")))

 (defn pace-conversion-fun [^String sport]
   (case sport


atomize mean-over-time

atomize mean-over-time

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -881,15 +881,14 @@
   Passes on each event received, but with metric adjusted to the moving
   average. Does not take the time between events into account."
   [r & children]
-  (let [m (ref 0)
+  (let [m (atom 0)
         c-existing (- 1 r)
         c-new r]
     (fn stream [event]
       ; Compute new ewma
       (let [m (when-let [metric-new (:metric event)]
-                (dosync
-                  (ref-set m (+ (* c-existing (deref m))
-                                (* c-new metric-new)))))]
+                (swap! m (comp (partial + (* c-new metric-new))
+                               (partial * c-existing))))]
         (call-rescue (assoc event :metric m) children)))))

 (defn- top-update


actions have end_time instead of stop_time

--- frontend/components/build_steps.cljs
+++ frontend/components/build_steps.cljs
@@ -89,7 +89,7 @@
                [:span.time {:title (str (:start_time action) " to "
                                         (:end_time action))}
                 (om/build common/updating-duration {:start (:start_time action)
-                                                    :stop (:stop_time action)})
+                                                    :stop (:end_time action)})
                 (when (:timedout action) " (timed out)")]
                [:span.action-source
                 [:span.action-source-inner {:title (source-title (:source action))}


prs pricable? enhacement

prs pricable? enhacement

--- jar-placement-lib/src/sixsq/slipstream/placement/core.clj
+++ jar-placement-lib/src/sixsq/slipstream/placement/core.clj
@@ -108,12 +108,12 @@
             nil))))))

 (defn- priceable?
-  [service-offer]
-  (every? (set (keys service-offer))
-          [:price:billingUnitCode
-           :price:unitCost
-           :price:currency
-           :price:unitCode]))
+       [service-offer]
+       (every? #(get service-offer %)
+               [:price:billingUnitCode
+                :price:unitCost
+                :price:currency
+                :price:unitCode]))

 (defn- compute-price
   [service-offer timecode]


Steam: return games as maps for eventual consistency with backloggery

--- src/steamtools/core.clj
+++ src/steamtools/core.clj
@@ -19,7 +19,8 @@
   (let [url (str "http://steamcommunity.com/id/" name "/games?tab=all&xml=1")]
     (->> url http/get :body xml/parse-str xml-seq (filter #(= :game (:tag %)))
       (map (comp :name xml-to-map))
-      sort)))
+      sort
+      (map (fn [name] { :name name :platform "Steam" :progress "unplayed" })))))

 (defn- bl-login
   "Make a login request to Backloggery, and return the authentication cookies."


update source and resource keys

update source and resource keys

--- resources/leiningen/new/tenzing/build.boot
+++ resources/leiningen/new/tenzing/build.boot
@@ -1,6 +1,6 @@
 (set-env!
- :src-paths    {{{source-paths}}}
- :rsc-paths    #{"resources"}
+ :source-paths    {{{source-paths}}}
+ :resource-paths  #{"resources"}
  :dependencies '[[adzerk/boot-cljs      "0.0-2411-3" :scope "test"]
                  [adzerk/boot-cljs-repl "0.1.7"       :scope "test"]
                  [adzerk/boot-reload    "0.2.0"       :scope "test"]{{{deps}}}])


Fix typo

Fix typo

--- src/robinson/combat.clj
+++ src/robinson/combat.clj
@@ -76,7 +76,7 @@
               [:human :*       :punch         :neck     :dead] (format "You %s the %s in the neck snapping it and it dies." (rand-punch-verb) defender-name)
               [:human :*       :punch         :body     :dead] (format "You %s the %s in the body damaging internal organs. It dies." (rand-punch-verb) defender-name)
               [:human :*       :punch         :leg      :dead] (format "You %s the %s in the leg severing it and it dies." (rand-punch-verb) defender-name)
-              [:human :*       :punch         :face     :dead] (format "You %s the %s in the face. Peices of face fly everywhere and it dies." (rand-punch-verb) defender-name)
+              [:human :*       :punch         :face     :dead] (format "You %s the %s in the face. Pieces of face fly everywhere and it dies." (rand-punch-verb) defender-name)
               [:human :*       :punch         :abdomen  :dead] (format "You %s the %s in the abdomen. Internal organs fly everywhere and it dies." (rand-punch-verb) defender-name)
               [:human :*       :punch         :claw     :dead] (format "You %s the %s in the claw and it dies." (rand-punch-verb) defender-name)
               [:human :*       :punch         :tail     :dead] (format "You %s the %s in the tail causing massive injuries and it dies." (rand-punch-verb) defender-name)
@@ -108,7 +108,7 @@
               [:human :*       sharp-weapon?  :neck     :dead] (format "You %s the %s in the neck snapping it and it dies." (rand-axe-verb) defender-name)
               [:human :*       sharp-weapon?  :body     :dead] (format "You %s the %s in the body damaging internal organs. It dies." (rand-axe-verb) defender-name)
               [:human :*       sharp-weapon?  :leg      :dead] (format "You %s the %s in the leg severing it and it dies." (rand-axe-verb) defender-name)
-              [:human :*       sharp-weapon?  :face     :dead] (format "You %s the %s in the face. Peices of face fly everywhere and it dies." (rand-axe-verb) defender-name)
+              [:human :*       sharp-weapon?  :face     :dead] (format "You %s the %s in the face. Pieces of face fly everywhere and it dies." (rand-axe-verb) defender-name)
               [:human :*       sharp-weapon?  :abdomen  :dead] (format "You %s the %s in the abdomen. Internal organs fly everywhere and it dies." (rand-axe-verb) defender-name)
               [:human :*       sharp-weapon?  :claw     :dead] (format "You %s the %s in the claw and it dies." (rand-axe-verb) defender-name)
               [:human :*       sharp-weapon?  :tail     :dead] (format "You %s the %s in the tail causing massive injuries and it dies." (rand-axe-verb) defender-name)
@@ -140,7 +140,7 @@
               [:human :*       ranged-weapon? :neck     :dead] (format "You %s the %s in the neck snapping it and it dies." (rand-ranged-hit-verb) defender-name)
               [:human :*       ranged-weapon? :body     :dead] (format "You %s the %s in the body damaging internal organs. It dies." (rand-ranged-hit-verb) defender-name)
               [:human :*       ranged-weapon? :leg      :dead] (format "You %s the %s in the leg severing it and it dies." (rand-ranged-hit-verb) defender-name)
-              [:human :*       ranged-weapon? :face     :dead] (format "You %s the %s in the face. Peices of face fly everywhere and it dies." (rand-ranged-hit-verb) defender-name)
+              [:human :*       ranged-weapon? :face     :dead] (format "You %s the %s in the face. Pieces of face fly everywhere and it dies." (rand-ranged-hit-verb) defender-name)
               [:human :*       ranged-weapon? :abdomen  :dead] (format "You %s the %s in the abdomen. Internal organs fly everywhere and it dies." (rand-ranged-hit-verb) defender-name)
               [:human :*       ranged-weapon? :claw     :dead] (format "You %s the %s in the claw and it dies." (rand-ranged-hit-verb) defender-name)
               [:human :*       ranged-weapon? :tail     :dead] (format "You %s the %s in the tail causing massive injuries and it dies." (rand-ranged-hit-verb) defender-name)


import typo timbre

import typo timbre

--- src/shale/resources.clj
+++ src/shale/resources.clj
@@ -1,7 +1,7 @@
 (ns shale.resources
   (:require shale.sessions
             clojure.walk
-            [taoensso.timbre :as timblre :refer [error]]
+            [taoensso.timbre :as timbre :refer [error]]
             [clj-json [core :as json]]
             [clojure.java.io :as io]
             [camel-snake-kebab.core :refer :all]


indentation

indentation

--- src/tictactoe/core.cljs
+++ src/tictactoe/core.cljs
@@ -20,8 +20,8 @@
 (defn free-spots [board]
   (for  [i (range board-size)
          j (range board-size)
-        :when (= (get-in board [i j]) "B")]
-        [i j]))
+         :when (= (get-in board [i j]) "B")]
+    [i j]))

 (defn draw? [board]
   (empty? (free-spots board)))
@@ -40,14 +40,14 @@

 (defn all-lines-coords []
   (concat  [(diagonal-down-coords) (diagonal-up-coords)]
-    (for [i (range board-size)] (horizontal-coords i))
-    (for [i (range board-size)] (vertical-coords i))))
+           (for [i (range board-size)] (horizontal-coords i))
+           (for [i (range board-size)] (vertical-coords i))))

 (defn get-coords [board coords]
   (map #(get-in board %) coords))

 (defn all-lines [board]
-   (map #(get-coords board %)  (all-lines-coords)))
+  (map #(get-coords board %)  (all-lines-coords)))

 (defn winning-by? [player line]
   (every? #(= % player) (take winning-k line)))
@@ -57,7 +57,7 @@

 (defn threat-by? [from to line]
   (and (= 0 (count (filter #(= % to) line)))
-   (= (dec winning-k) (count (filter #(= % from) line)))))
+       (= (dec winning-k) (count (filter #(= % from) line)))))

 (defn threat-lines [from to board]
   (filter #(threat-by? from to (get-coords board %)) (all-lines-coords)))
@@ -76,68 +76,68 @@
   (let [move (or
               (not-empty (free-spot board  (first (threat-lines "O" "X" board))))
               (not-empty (free-spot board  (first (threat-lines "X" "O" board))))
-              (not-empty (free-spot board (first-occupied-line board)))
+              (not-empty (free-spot board (first-occupied-lines board)))
               (rand-nth (free-spots board)))]
     (assoc-in board move "O")))

 (defn game-status []
   (let [board (:board @app-state)]
-  (cond
-    (winning? board "O") :computer-win
-    (winning? board "X") :player-win
-    (draw? board ) :draw
-    :else :in-progress)))
+    (cond
+     (winning? board "O") :computer-win
+     (winning? board "X") :player-win
+     (draw? board ) :draw
+     :else :in-progress)))

 (defn blank [i j]
-      [:rect {:width 0.95
-              :height 0.95
-              :x i
-              :y j
-              :fill (if (= "B" (get-in @app-state [:board i j]))
-                        "lightgray")
-              :on-click
-              (fn rect-click [e]
-                (swap! app-state assoc-in [:board i j] "X" )
-                (swap! app-state assoc :status (game-status))
-                (if (= (:status @app-state) :in-progress)
-                  ((swap! app-state assoc :board (computer-move (:board @app-state)))
-                  (swap! app-state assoc :status (game-status)))))}])
+  [:rect {:width 0.95
+          :height 0.95
+          :x i
+          :y j
+          :fill (if (= "B" (get-in @app-state [:board i j]))
+                  "lightgray")
+          :on-click
+          (fn rect-click [e]
+            (swap! app-state assoc-in [:board i j] "X" )
+            (swap! app-state assoc :status (game-status))
+            (if (= (:status @app-state) :in-progress)
+              ((swap! app-state assoc :board (computer-move (:board @app-state)))
+               (swap! app-state assoc :status (game-status)))))}])

 (defn circle [i j]
   [:circle {:r 0.40 :fill "none" :stroke-width 0.05 :stroke "darkred"
-    :cx (+ 0.5 i) :cy (+ 0.5 j)}])
+            :cx (+ 0.5 i) :cy (+ 0.5 j)}])

 (defn cross [i j]
   [:g
-    {:stroke "green" :stroke-width 0.1 :stroke-linecap "round"
+   {:stroke "green" :stroke-width 0.1 :stroke-linecap "round"
     :transform (str "translate(" (+ 0.5 i) "," (+ 0.5 j) ") " "scale(0.33)")}
-    [:line {:x1 -1 :y1 -1 :x2 1 :y2 1}]
-    [:line {:x1 1 :y1 -1 :x2 -1 :y2 1}]])
+   [:line {:x1 -1 :y1 -1 :x2 1 :y2 1}]
+   [:line {:x1 1 :y1 -1 :x2 -1 :y2 1}]])

 (defn tic-tac-toe []
   [:center
-    [:h1 (:text @app-state)]
-    [:h3 (case (:status @app-state)
-                :in-progress "Your move"
-                :player-win "You win"
-                :computer-win "You lose"
-                :draw "Draw"
-                "")]
-    [:svg
-      {:view-box ( str "0 0 " board-size " " board-size) :width 500 :height 500}
-      (for [i (range board-size)
-            j (range board-size)]
-            (case (get-in @app-state [:board i j])
-              "B" [blank i j]
-              "O" [circle i j]
-              "X" [cross i j]))]
-    [:p
-      [:button
-        {:on-click
-          (fn new-game-click [e]
-            (swap! app-state assoc :board (new-board board-size))
-            (swap! app-state assoc :status :in-progress))}
-        "New Game"]]])
+   [:h1 (:text @app-state)]
+   [:h3 (case (:status @app-state)
+          :in-progress "Your move"
+          :player-win "You win"
+          :computer-win "You lose"
+          :draw "Draw"
+          "")]
+   [:svg
+    {:view-box ( str "0 0 " board-size " " board-size) :width 500 :height 500}
+    (for [i (range board-size)
+          j (range board-size)]
+      (case (get-in @app-state [:board i j])
+        "B" [blank i j]
+        "O" [circle i j]
+        "X" [cross i j]))]
+   [:p
+    [:button
+     {:on-click
+      (fn new-game-click [e]
+        (swap! app-state assoc :board (new-board board-size))
+        (swap! app-state assoc :status :in-progress))}
+     "New Game"]]])

 (reagent/render-component [tic-tac-toe]
                           (. js/document (getElementById "app")))


Refactor code

Refactor code

--- src/spectrace/core.cljc
+++ src/spectrace/core.cljc
@@ -167,43 +167,45 @@
 (def ^:private regex-ops
   `#{s/cat s/& s/alt s/? s/* s/+})

-(defn- regex-postprocess [{:keys [spec path val in pred reason] :as state}]
-  (if (or (and (seq? spec) (contains? regex-ops (first spec)))
-          (empty? in))
-    (if (and (empty? path) (= reason "Insufficient input"))
-      (assoc state :spec pred)
-      state)
-    (let [[key & in] in]
-      (assoc state :val (nth val key) :in in))))
-
-(defn- with-regex-processing [{:keys [path reason] :as state} f]
+(defn- with-regex-processing [{:keys [path reason pred] :as state} f
+                              & {:keys [insufficient?]
+                                 :or {insufficient? empty?}}]
   (when-not (and (empty? path) (= reason "Extra input"))
-    (f state)))
-
-(defmethod step `s/cat [{:keys [path pred] :as state}]
+    (let [{:keys [spec path val in] :as state'} (f state)]
+      (cond (and (seq? spec) (contains? regex-ops (first spec)))
+            state'
+
+            (and (insufficient? path) (= reason "Insufficient input"))
+            (assoc state' :spec pred)
+
+            (empty? in)
+            state'
+
+            :else
+            (assoc state' :val (nth val (first in)) :in (rest in))))))
+
+(defmethod step `s/cat [state]
   (with-regex-processing state
-    #(regex-postprocess (step-forward %))))
+    step-forward
+    :insufficient? #(= (count %) 1)))

 (defmethod step `s/& [state]
   (interleave-specs (rest (:spec state)) state))

 (defmethod step `s/alt [state]
-  (with-regex-processing state
-    #(regex-postprocess (step-forward %))))
-
-(defn- step-for-rep [{:keys [val in] :as state}]
-  (-> state
-      (update :spec second)
-      regex-postprocess))
+  (with-regex-processing state step-forward))
+
+(defn- step-for-rep [state]
+  (update state :spec second))

 (defmethod step `s/? [state]
   (with-regex-processing state step-for-rep))

 (defmethod step `s/* [state]
-  (step-for-rep state))
+  (with-regex-processing state step-for-rep))

 (defmethod step `s/+ [state]
-  (step-for-rep state))
+  (with-regex-processing state step-for-rep))

 (defmethod step `s/fspec [{:keys [path pred] :as state}]
   (if (empty? path)


Fix other nonexistant import

Fix other nonexistant import

--- src/todomvc/events.cljs
+++ src/todomvc/events.cljs
@@ -1,6 +1,6 @@
 (ns todomvc.events
   (:require
-    [todomvc.db :refer [default-value todos->local-store]]
+    [todomvc.db :refer [todos->local-store]]
     [re-frame.core :refer [reg-event-db reg-event-fx inject-cofx path trim-v
                            after debug]]
     [todomvc.rules :refer [find-showing


Fix clj kondo warnings in subs.cljs

Fix clj kondo warnings in subs.cljs

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -688,7 +688,7 @@
  :account-by-address
  :<- [:multiaccount/accounts]
  (fn [accounts [_ address]]
-   (when (and (string? address))
+   (when (string? address)
      (some #(when (= (string/lower-case (:address %))
                      (string/lower-case address)) %) accounts))))

@@ -1234,7 +1234,7 @@
  :<- [:chats/edit-message]
  (fn [[disconnected? {:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit]]
    (let [sending-image (seq sending-image)]
-     {:send          (and (not (or processing disconnected?)))
+     {:send          (not (or processing disconnected?))
       :stickers      (and mainnet?
                           (not sending-image)
                           (not reply))


index genes first

index genes first

--- src/wb_es/bulk/core.clj
+++ src/wb_es/bulk/core.clj
@@ -144,6 +144,10 @@
         (do
           ;; add jobs to scheduler in sequence

+          (let [eids (get-eids-by-type db :gene/id)
+                jobs (make-batches 100 :gene eids)]  ; smaller batch for slower ones
+            (doseq [job jobs]
+              (>!! scheduler job)))
           (let [eids (get-eids-by-type db :analysis/id)
                 jobs (make-batches 1000 :analysis eids)]
             (doseq [job jobs]
@@ -186,10 +190,6 @@
               (>!! scheduler job)))
           (let [eids (get-eids-by-type db :feature/id)
                 jobs (make-batches 1000 :feature eids)]
-            (doseq [job jobs]
-              (>!! scheduler job)))
-          (let [eids (get-eids-by-type db :gene/id)
-                jobs (make-batches 100 :gene eids)]  ; smaller batch for slower ones
             (doseq [job jobs]
               (>!! scheduler job)))
           (let [eids (get-eids-by-type db :gene-class/id)


No beaming when you already have double-ships

--- desktop/src-common/ds3/enemy.clj
+++ desktop/src-common/ds3/enemy.clj
@@ -276,9 +276,10 @@
                           capturers (filter #(= (:movement-state %) :capturing) non-drifters)
                           master (filter #(:master? %) enemies)
                           ghost (filter #(:ghost? %) non-enemies)
+                          doppel (filter #(:doppel? %) non-enemies)
                           entity (first drifters)
                           attacker (cond entity
-                                         (if (and (:boss? entity) (empty? capturers) (empty? master) (empty? ghost))
+                                         (if (and (:boss? entity) (empty? capturers) (empty? master) (empty? ghost) (empty? doppel))
                                            (let [n-m-s :capturing]
                                              (assoc entity :movement-state n-m-s :current-time 0
                                                :spline (splines/calibrate-spline (assoc entity :movement-state n-m-s))))


Fixes editing of title

Fixes editing of title

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -32,8 +32,7 @@

 (defn handle-title-change [event app]
   (let [new-title (.. event -target -value)]
-    (when-not (= "" new-title)
-      (om/update! app :title new-title))))
+    (om/update! app :title new-title)))

 (defn title-field [app owner]
   (reify
@@ -41,7 +40,7 @@
     (render [_]
       (dom/div #js {:id "title-field"}
         (dom/input #js {:type "text"
-                        :onBlur #(handle-title-change % app)
+                        :onChange #(handle-title-change % app)
                         :value (:title app)})))))

 ;; Left menu


Removed unnecessary ring-core dep from ring-servlet

Fixes #128

--- ring-servlet/project.clj
+++ ring-servlet/project.clj
@@ -3,7 +3,7 @@
   :url "https://github.com/ring-clojure/ring"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
-  :dependencies [[ring/ring-core "1.2.2"]]
+  :dependencies [[org.clojure/clojure "1.3.0"]]
   :profiles
   {:provided {:dependencies [[javax.servlet/servlet-api "2.5"]]}
    :dev {:dependencies [[javax.servlet/servlet-api "2.5"]]}


record only tile movements, not directions

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -21,9 +21,12 @@
 (defn slide! [arg]
   (let [{:keys [board moves]} @app-state]
     (when (b/legal-move? board arg)
-      (swap! app-state assoc
-             :board (b/slide board arg)
-             :moves (conj moves arg))))) ; note this appends direction or tile
+      (let [tile (if (b/direction? arg)
+                   (b/direction->tile board arg)
+                   arg)]
+        (swap! app-state assoc
+               :board (b/slide board tile)
+               :moves (conj moves tile))))))

 (defn board-size-slider [size command]
   [:div


fix merge conflict

fix merge conflict

--- src/tranjlator/core.clj
+++ src/tranjlator/core.clj
@@ -1,5 +1,7 @@
 (ns tranjlator.core
+  (:require [org.httpit.server :refer [run-server]])
   (:gen-class))
+

 (defn -main
   "I don't do a whole lot."


Make event callbacks optional

Make event callbacks optional

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -131,7 +131,10 @@
   (str (utils/uri-to-relative (unexterned-prop build "build_url"))
        "#build-timing"))

-(defn visualize-insights-bar! [plot-info el builds {:keys [on-focus-build on-mouse-move] :as events}]
+(defn visualize-insights-bar! [plot-info el builds {:keys [on-focus-build on-mouse-move]
+                                                    :or {on-focus-build (constantly nil)
+                                                         on-mouse-move (constantly nil)}
+                                                    :as events}]
   (let [[y-pos-max y-neg-max] (->> [:build_time_millis :queued_time_millis]
                                    (map #(->> builds
                                               (map %)


Minor edit of servlet-name docstring [IMMUTANT-515]

--- web/src/immutant/web.clj
+++ web/src/immutant/web.clj
@@ -35,10 +35,9 @@
      * :path          Maps the handler to a prefix of the url path [\"/\"]
      * :virtual-host  Virtual host name[s] (a String or a List of Strings) [nil]
      * :dispatch?     Invoke handlers in worker thread pool [true]
-
-   for servlets only:
-
-     * :servlet-name  The name to register the servlet under (gets passed to ServletInfo) [simple class name]
+     * :servlet-name  The name to register the servlet under (gets passed to
+                      ServletInfo, valid for servlets only)
+                      [The simple class name of the servlet]

    Note the web server only binds to the loopback interface, by
    default. To expose your handler to the network, set :host to an


Simplify

Simplify

--- demo/sitetools/core.cljs
+++ demo/sitetools/core.cljs
@@ -20,7 +20,7 @@
     (do (-> (or a.rswapfs
                 (set! a.rswapfs (array)))
             (.push #(apply f % args)))
-        nil)
+        (swap! a identity))
     (do (set! a.rswapping true)
         (try (swap! a (fn [state]
                         (loop [s (apply f state args)]
@@ -86,10 +86,9 @@

 ;;; History

-(defn init-history []
+(defn init-history [page]
   (when-not history
-    (let [page (:page-name @config)
-          html5 (and page
+    (let [html5 (and page
                      (.isSupported Html5History)
                      (#{"http:" "https:"} js/location.protocol))]
       (doto (set! history
@@ -162,26 +161,26 @@
                                :page-conf {:page-name page-name}
                                :body-html bhtml)))))

+(defn fs [] (js/require "fs"))
+(defn path [] (js/require "path"))
+
 (defn mkdirs [f]
-  (let [fs (js/require "fs")
-        path (js/require "path")
-        items (as-> f _
-                (.' path dirname _)
-                (.' path normalize _)
+  (let [items (as-> f _
+                (.' (path) normalize _)
                 (string/split _ #"/"))]
     (doseq [d (reductions #(str %1 "/" %2) items)]
-      (when-not (.' fs existsSync d)
-        (.' fs mkdirSync d)))))
+      (when-not (.' (fs) existsSync d)
+        (.' (fs) mkdirSync d)))))

 (defn write-file [f content]
-  (mkdirs f)
-  (.' (js/require "fs") writeFileSync f content))
+  (mkdirs (.' (path) dirname f))
+  (.' (fs) writeFileSync f content))

 (defn read-file [f]
-  (.' (js/require "fs") readFileSync f))
+  (.' (fs) readFileSync f))

 (defn path-join [& paths]
-  (apply (.' (js/require "path") :join) paths))
+  (apply (.' (path) :join) paths))

 (defn read-files [files]
   (string/join "\n" (map read-file files)))
@@ -195,9 +194,9 @@

 (defn ^:export genpages [opts]
   (log "Generating site")
-  (swap! config merge (js->clj opts :keywordize-keys true))
-  (let [{:keys [site-dir pages] :as state} @config
-        conf (assoc state :timestamp (str "?" (js/Date.now)))]
+  (let [conf (swap! config merge (js->clj opts :keywordize-keys true))
+        conf (assoc conf :timestamp (str "?" (js/Date.now)))
+        {:keys [site-dir pages]} conf]
     (doseq [f pages]
       (write-file (->> f to-relative (path-join site-dir))
                   (gen-page f conf)))
@@ -207,9 +206,9 @@
 (defn start! [site-config]
   (swap! config merge site-config)
   (when r/is-client
-    (let [conf (when (exists? js/pageConfig)
-                 (js->clj js/pageConfig :keywordize-keys true))]
-      (swap! config merge conf)
-      (init-history)
-      (r/render-component (:body @config)
-                          (js/document.getElementById (:main-div @config))))))
+    (let [page-conf (when (exists? js/pageConfig)
+                      (js->clj js/pageConfig :keywordize-keys true))
+          conf (swap! config merge page-conf)]
+      (init-history (:page-name conf))
+      (r/render-component (:body conf)
+                          (js/document.getElementById (:main-div conf))))))


Adds update-many!

Adds update-many!

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -162,13 +162,16 @@

 ;; The main app

+(defn update-many!
+  "Sequentially updates multiple keys on Om cursor to the given value."
+  [app ks v]
+  (doseq [k ks]
+    (om/update! app k v)))
+
 (defn reset-document-state!
   "Sets the document related keys in the app state to a 'clean' state."
   [app]
-  (om/update! app :input "")
-  (om/update! app :title "")
-  (om/update! app :last-title "")
-  (om/update! app :last-input ""))
+  (update-many! app [:input :title :last-title :last-input] ""))

 (defn new-document
   "A new document simply means resetting the document state."
@@ -181,10 +184,8 @@
    to the new document state."
   [app title]
   (let [input (p/get-document title)]
-    (om/update! app :input input)
-    (om/update! app :title title)
-    (om/update! app :last-title title)
-    (om/update! app :last-input input)))
+    (update-many! app [:input :last-input] input)
+    (update-many! app [:title :last-title] title)))

 (defn save-document
   "If title is the same as last-title it renames the document. Then


Fix up stub-sp correspondence in pair-stub1

--- src/angelic/search/implicit/dash_astar.clj
+++ src/angelic/search/implicit/dash_astar.clj
@@ -157,11 +157,12 @@

 ;; TODO: set stub to -inf here, simplify other code?
 ;; TODO: efficiency?
-(defn- set-stub-output! [stub sp]
-  (assert (empty? (get-outputs stub)))
-  (let [b  (summaries/get-bound stub)
-        ts (tree-summarizer stub)]
-    (summaries/summary-changed-local! stub)
+(defn- set-stub-output! [stb sp]
+  (assert (empty? (get-outputs stb)))
+  (assert (identical? (stub sp) stb))
+  (let [b  (summaries/get-bound stb)
+        ts (tree-summarizer stb)]
+    (summaries/summary-changed-local! stb)
     (summaries/connect-subsumed! ts sp)
     (connect-and-watch! ts sp
        (fn [child-sp]
@@ -170,10 +171,10 @@
            (summaries/connect! ts child-ts)
            (summaries/connect-subsumed! ts child-ts)
            (summaries/summary-changed! ts))))
-;    (println "SO" stub b (summary/max-reward (summaries/summary sp)))
+;    (println "SO" stb b (summary/max-reward (summaries/summary sp)))
     (summaries/add-bound! ts b) ;; TODO: ???
     (summaries/summary-changed! ts)
-    (add-output! stub sp)))
+    (add-output! stb sp)))

 (defn- set-derived-stub-output! [stub sp]
   (assert (empty? (get-outputs stub)))
@@ -507,8 +508,19 @@
           #(set-stub-output! ret (make-pair-subproblem ret left-sp %)))
         ret))))

-;; Note, potential to learn about additioan lsubsumption here, however, must be taken into account.
+
+;; Note: this allows us to assert stub-sp matching.
+;; TODO: get rido f this
+(defn make-echo-subproblem [stb sp]
+  (let [ret (make-simple-subproblem stb (output-set sp) (terminal? sp) summaries/or-summary
+                                    (fn [s ri] (refine-input sp ri)))]
+    (connect-and-watch! ret sp #(add-sp-child-stub! ret (stub %) false))
+    ret))
+
+
+;; TODO: remove extra level of indirection?
 ;; TODO: name does not match wrapping names.
+
 (defn- make-pair-stub1 [nm left-stub right-stub-fn]
   (if-let [left-sp (get-stub-output left-stub)]
     (make-pair-stub2 left-sp (right-stub-fn (output-set left-sp)))
@@ -518,7 +530,7 @@
           (connect-and-watch-stub! ret
             (make-pair-stub2 lo (right-stub-fn (output-set lo)))
             true
-            #(set-stub-output! ret %))))
+            #(set-stub-output! ret (make-echo-subproblem ret %))))) ;; eek!
       ret)))

 (defmethod get-stub :Pair [[_ left-name right-name :as n] inp]


Fix react key error by working around reagent bug

--- src/braid/core/client/ui/views/thread.cljs
+++ src/braid/core/client/ui/views/thread.cljs
@@ -162,8 +162,10 @@
                                 (not (helpers/contains-urls? (prev-message :content)))))))))]
             (doall
               (for [message sorted-messages]
-                 ^{:key (message :id)}
-                [:<>
+                ;; [BUG] Reagent 0.8.1 has a bug where metadata doesn't get
+                ;; applied to fragments properly, so we need to set
+                ;; the key in this way instead
+                [:<> {:key (message :id)}
                  (when (message :show-date-divider?)
                    [:div.divider
                     [:div.date (helpers/format-date "yyyy-MM-dd" (message :created-at))]])


Removed useless parameter from a function.

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -19,12 +19,12 @@
   (rest (map str (file-seq (clojure.java.io/file dir)))))

 (defn example-listing
-  [req]
+  []
   (let [filelist (files-as-list "resources/public/examples/")]
     {:body (zipmap (map filename-as-text filelist) filelist)}))

 (defroutes api-routes
-  (GET "/api/examples" [] example-listing))
+  (GET "/api/examples" [] (example-listing)))

 (defn index
   [req]


rename calls with !

rename calls with !

--- src/cljs/infinitelives/pixi/resources.cljs
+++ src/cljs/infinitelives/pixi/resources.cljs
@@ -79,7 +79,7 @@
   (scale (get @!textures key)))

 ;; setup a pixi texture keyed by the tail of its filename
-(defn- register-texture
+(defn- register-texture!
   [url img]
   (when (string/ends-with? url ".png")
     (swap! !textures
@@ -106,10 +106,10 @@
   [url obj]
   (case (identify-file url)
     :image
-    (register-texture url obj)
+    (register-texture! url obj)

     :sound
-    (sound/register-sound url obj)
+    (sound/register-sound! url obj)

     :default
     ))
@@ -199,7 +199,7 @@
       (<! (apply (partial load-urls urls b) options))

       ;; load is done. return message
-      (>! c true)
+      ;(>! c true)

       ;; delay a tiny bit
       (<! (timeout 300))


Fix experimental urls in export code

Fix experimental urls in export code

--- src/com/puppetlabs/puppetdb/cli/export.clj
+++ src/com/puppetlabs/puppetdb/cli/export.clj
@@ -34,7 +34,7 @@
    :post [((some-fn string? nil?) %)]}
   (let [{:keys [status body]} (client/get
                                  (format
-                                   "http://%s:%s/experimental/catalog/%s"
+                                   "http://%s:%s/v3/catalog/%s"
                                    host port node)
                                  { :accept :json})]
     (when (= status 200) body)))
@@ -48,7 +48,7 @@
    :post [vector? %]}
   (let [{:keys [status body]} (client/get
                                  (format
-                                   "http://%s:%s/experimental/events?query=%s"
+                                   "http://%s:%s/v3/events?query=%s"
                                    host port (url-encode (format "[\"=\",\"report\",\"%s\"]" report-hash))))]
     (when
       (= status 200)
@@ -67,7 +67,7 @@
    :post [seq? %]}
   (let [{:keys [status body]} (client/get
                                  (format
-                                   "http://%s:%s/experimental/reports?query=%s"
+                                   "http://%s:%s/v3/reports?query=%s"
                                    host port (url-encode (format "[\"=\",\"certname\",\"%s\"]" node)))
                                  { :accept :json})]
     (when


Improve pre/postconditions for node query

--- src/com/puppetlabs/puppetdb/query/node.clj
+++ src/com/puppetlabs/puppetdb/query/node.clj
@@ -33,7 +33,7 @@
   "Converts a vector-structured `query` to a corresponding SQL query which will
   return nodes matching the `query`."
   [query]
-  {:pre  [(some-fn nil? sequential? query)]
+  {:pre  [((some-fn nil? sequential?) query)]
    :post [(vector? %)
           (string? (first %))
           (every? (complement coll?) (rest %))]}
@@ -66,7 +66,7 @@
 (defmethod compile-term "="
   [[op path value :as term]]
   {:post [(map? %)
-          (:where %)]}
+          (string? (:where %))]}
   (let [count (count term)]
     (if (not= 3 count)
       (throw (IllegalArgumentException.
@@ -84,7 +84,7 @@
 (defmethod compile-term :numeric-comparison
   [[op path value :as term]]
   {:post [(map? %)
-          (:where %)]}
+          (string? (:where %))]}
   (let [count (count term)]
     (if (not= 3 count)
       (throw (IllegalArgumentException.


update version

update version

--- storm-kafka/project.clj
+++ storm-kafka/project.clj
@@ -1,4 +1,4 @@
-(defproject storm/storm-kafka "0.7.3-dynamic-storm8-SNAPSHOT"
+(defproject storm/storm-kafka "0.8.0-wip1"
   :source-path "src/clj"
   :java-source-path "src/jvm"
   :javac-options {:debug "true" :fork "true"}
@@ -7,7 +7,7 @@
   :dependencies [[storm/kafka "0.7.0-incubating"
                    :exclusions [org.apache.zookeeper/zookeeper
                                 log4j/log4j]]]
-  :dev-dependencies [[storm "0.8.0-SNAPSHOT"]
+  :dev-dependencies [[storm "0.8.0"]
                      [org.clojure/clojure "1.4.0"]]
   :jvm-opts ["-Djava.library.path=/usr/local/lib:/opt/local/lib:/usr/lib"]
 )


diagnostics

diagnostics

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -221,7 +221,9 @@
       ;; else: fail:
       (do
         (log/trace (str "moreover-comp: fail: " result))
-        (log/trace (str "moreover-comp: fail at: " (fail-path result)))
+        (log/debug (str "moreover-comp: fail-path-between:"
+                        (fail-path-between parent {:comp child})))
+
         (log/debug (str "moreover-comp: fail:     "
                         "[" (get-in parent [:surface]) "];" " child ["
                         (get-in child [:surface]) "]"))


Update eval-soup

Update eval-soup

--- build.boot
+++ build.boot
@@ -12,7 +12,7 @@
                   [leiningen "2.7.0" :exclusions [leiningen.search]]
                   [ring "1.4.0"]
                   [play-cljs/lein-template "0.6.4"]
-                  [eval-soup "1.0.1" :exclusions [org.clojure/core.async]]])
+                  [eval-soup "1.0.2" :exclusions [org.clojure/core.async]]])

 (require
   '[adzerk.boot-cljs :refer [cljs]])


use latest clojure

use latest clojure

Signed-off-by: Gregg Reynolds <d0f77bc71a9867acdcb4f62f012b858edad79160@norc.org>

--- build.boot
+++ build.boot
@@ -7,7 +7,7 @@
  ;; :asset-paths #{"src"}
  :repositories #(conj % ["maven-central" {:url "https://mvnrepository.com"}]
                       ["central" "https://repo1.maven.org/maven2/"])
- :dependencies   '[[org.clojure/clojure "1.10.0" :scope "provided"]
+ :dependencies   '[[org.clojure/clojure "1.10.1" :scope "provided"]
                    [boot/core "2.8.3" :scope "provided"]
                    [boot/pod "2.8.3" :scope "provided"]
                    [me.raynes/fs "1.4.6"]


define github-url var in build.boot

define github-url var in build.boot

--- build.boot
+++ build.boot
@@ -7,19 +7,20 @@
                  [pandeiro/boot-http        "0.7.3"      :scope "test"]
                  [boot-codox                "0.10.3"     :scope "test"]
                  [org.clojure/clojure       "1.9.0-alpha14" :scope "provided"]
-                 [org.clojure/clojurescript "1.9.293"     :scope "provided"]
+                 [org.clojure/clojurescript "1.9.946"     :scope "provided"]
                  [com.stuartsierra/dependency "0.2.0"]
                  [rum "0.10.8"]
                  [cljsjs/prop-types "15.5.10-1"]])

 (def +version+ "0.2.0")
+(def github "https://github.com/martinklepsch/derivatives")

 (task-options!
  pom {:project     'org.martinklepsch/derivatives
       :version     +version+
       :description "Chains of derived values"
-      :url         "https://github.com/martinklepsch/derivatives"
-      :scm         {:url "https://github.com/martinklepsch/derivatives"}})
+      :url         github
+      :scm         {:url github}})

 ;; Example app stuff ============================================================


Fixing Codox build

Fixing Codox build

--- build.boot
+++ build.boot
@@ -169,7 +169,6 @@
   (comp (build-cljs)
         (build-html :metadata-file (str "perun.base." environment ".edn"))
         (build-css)
-        (codox :name "Zetawar" :language :clojurescript)
         (gzip :regex #{#"\.html$" #"\.css$" #"\.js$"})
         (sift :move {#"^(.*)\.html$" "$1.html.orig"
                      #"^(.*)\.css$" "$1.css.orig"
@@ -178,4 +177,5 @@
         (sift :move {#"^(.*)\.html\.gz$" "$1.html"
                      #"^(.*)\.css\.gz$" "$1.css"
                      #"^(.*)\.js\.gz$" "$1.js"})
+        (codox :name "Zetawar" :language :clojurescript)
         (target)))


Update deps

Update deps

--- build.boot
+++ build.boot
@@ -3,29 +3,30 @@
   :resource-paths #{"src/clj" "src/cljc"}
   :dependencies '[[org.clojure/clojure    "1.7.0"]
                   [org.clojure/clojurescript "1.7.48"]
+
                   [adzerk/boot-cljs       "1.7.48-5"   :scope "test"]
                   [adzerk/boot-cljs-repl  "0.2.0"      :scope "test"]
                   [adzerk/boot-reload     "0.4.0"      :scope "test"]
-                  [deraen/boot-less       "0.4.1"      :scope "test"]
-                  [deraen/boot-sass       "0.1.0"      :scope "test"]
+                  [deraen/boot-less       "0.4.2"      :scope "test"]
+                  [deraen/boot-sass       "0.1.1"      :scope "test"]
                   [deraen/boot-ctn        "0.1.0"      :scope "test"]

                   ; Backend
                   [http-kit "2.1.19"]
-                  [org.clojure/tools.namespace "0.2.10"]
-                  [reloaded.repl "0.1.0"]
-                  [com.stuartsierra/component "0.2.3"]
-                  [metosin/ring-http-response "0.6.3"]
-                  [prismatic/om-tools "0.3.11"]
-                  [prismatic/plumbing "0.4.4"]
-                  [prismatic/schema "0.4.3"]
-                  [ring "1.3.2"]
-                  [compojure "1.3.4"]
+                  [org.clojure/tools.namespace "0.2.11"]
+                  [reloaded.repl "0.2.0"]
+                  [com.stuartsierra/component "0.3.0"]
+                  [metosin/ring-http-response "0.6.5"]
+                  [prismatic/om-tools "0.4.0"]
+                  [prismatic/plumbing "0.5.0"]
+                  [prismatic/schema "1.0.1"]
+                  [ring "1.4.0"]
+                  [compojure "1.4.0"]
                   [hiccup "1.0.5"]

                   ; Frontend
                   [org.omcljs/om "0.8.8"]
-                  [sablono "0.3.4"]
+                  [sablono "0.3.6"]

                   ; LESS
                   [org.webjars/bootstrap "3.3.4"]
@@ -68,7 +69,7 @@
     (reload :open-file "vim --servername saapas --remote-silent +norm%sG%s| %s"
             :ids #{"js/main"})
     ; This starts a repl server with piggieback middleware
-    (cljs-repl :ids #{"js/main"})
+    (cljs-repl :ids #{"main"})
     (cljs :ids #{"js/main"})
     (start-app :port port)
     (if speak (boot.task.built-in/speak) identity)))


Ensure project is rebuilt after cljs-repl starts (when auto-rebuild is disabled).

--- build.boot
+++ build.boot
@@ -27,7 +27,7 @@
 (require '[adzerk.boot-cljs :refer [cljs]]
          '[pandeiro.boot-http :refer [serve]]
          '[adzerk.boot-reload :refer [reload]]
-         '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
+         '[adzerk.boot-cljs-repl :refer [cljs-repl] :as boot-cljs-repl]
          '[adzerk.boot-template :as boot-template])

 (def dev-output-dir "dev-www")
@@ -36,14 +36,11 @@

 (deftask dev
   "Launch Immediate Feedback Development Environment"
-  [r no-reload bool "Disable live-reloading"]
+  [r no-rebuild bool "Disable automatic re-building"]
   (comp
    (serve :dir dev-output-dir :port 1812)
-   (if no-reload
-     (wait) ;; Needed so that the command doesn't exit if we are not
-     ;; watching.
-     (comp (watch)
-           (reload :port 1813 :ws-port 1813)))
+   (watch :manual no-rebuild)
+   (reload :port 1813 :ws-port 1813)
    ;; cljs-repl must be before cljs task
    (cljs-repl :port 1814 :ip "0.0.0.0"
               :nrepl-opts {:port 1815 :bind "0.0.0.0"})
@@ -77,3 +74,12 @@
          (with-pre-wrap fileset
            (println (str "New composition created in: " dir-name))
            fileset))))))
+
+(defn start-repl
+  []
+  ;; Manually rebuild after 5 seconds, to allow time for start-repl to
+  ;; update files. This only applies if the dev task was started with
+  ;; -r for no automatic reloading.
+  (future (Thread/sleep 5000)
+          (rebuild!))
+  (boot-cljs-repl/start-repl))


remove short-circuit to determine whether to generate complements with lexemes or phrases first: now, always choose lexemes first

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -132,12 +132,13 @@
         bolts-at (if (< depth max-depth)
                    (lazy-seq (generate-all (get-in bolt path) model
                                            (+ 1 depth) max-depth)))
-        lexemes-before-phrases
-        (or true (lexemes-before-phrases depth max-depth))]
+        lexemes-before-phrases true]
     (cond (nil? bolts-at)
           (lazy-seq lexemes)
+
           lexemes-before-phrases
           (lazy-cat lexemes bolts-at)
+
           true
           (lazy-cat bolts-at lexemes))))


cleanup

cleanup

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -307,10 +307,6 @@
   #?(:cljs
      (throw (js/Error. error-string))))

-(defn current-time []
-  #?(:clj (System/currentTimeMillis))
-  #?(:cljs (.getTime (js/Date.))))
-
 ;; Thanks to http://clojurian.blogspot.com.br/2012/11/beware-of-mapcat.html
 (defn lazy-mapcat  [f coll]
   (lazy-seq


Update Om to 1.0.0-beta1

Update Om to 1.0.0-beta1

--- build.boot
+++ build.boot
@@ -14,7 +14,7 @@
                  [buddy/buddy-auth "1.2.0"]
                  [buddy/buddy-hashers "1.0.0"]
                  [org.postgresql/postgresql "9.4.1208"]
-                 [org.omcljs/om "1.0.0-alpha48"]
+                 [org.omcljs/om "1.0.0-beta1"]
                  [org.clojure/clojure "1.9.0-alpha17"]
                  [org.clojure/clojurescript "1.9.562"]
                  [org.clojure/core.async "0.3.443"]


onto 0.1.14-SNAPSHOT

onto 0.1.14-SNAPSHOT

--- build.boot
+++ build.boot
@@ -1,4 +1,4 @@
-(def +version+ "0.1.13")
+(def +version+ "0.1.14-SNAPSHOT")

 (set-env!
   :source-paths #{"src"}


Add support for CLJS REPLs in Cider; start a REPL server with dev

--- build.boot
+++ build.boot
@@ -9,6 +9,7 @@
                  [adzerk/bootlaces "0.1.13"]
                  [pandeiro/boot-http "0.7.3"]
                  [crisptrutski/boot-cljs-test "0.2.1"]
+                 [com.cemerick/piggieback "0.2.1"]

                  ;; Testing
                  [org.clojure/test.check "0.9.0" :scope "test"]
@@ -56,7 +57,8 @@
             :url "https://github.com/workfloapp/macros"
             :scm {:url "https://github.com/workfloapp/macros"}
             :license {"MIT License"
-                      "https://opensource.org/licenses/MIT"}})
+                      "https://opensource.org/licenses/MIT"}}
+ repl      {:middleware '[cemerick.piggieback/wrap-cljs-repl]})

 (deftask developing
   []
@@ -86,7 +88,8 @@
     (reload :on-jsload 'workflo.macros.examples.screen-app/reload)
     (build-dev)
     (target)
-    (serve :dir "target")))
+    (serve :dir "target")
+    (repl :server true)))

 (deftask docs
   []


Remove logic to force java 1.7 from build.boot

Hopefully this dosen't break building the release.

--- build.boot
+++ build.boot
@@ -31,13 +31,8 @@
 (bootlaces! +version+)

 (task-options!
-  javac   {:options (let [jdk8-bootclasspath (System/getenv "JDK7_BOOTCLASSPATH")]
-                      (concat
-                        []
-                        (when-not (empty? jdk8-bootclasspath)
-                          ["-source" "1.8"
-                           "-target" "1.8"
-                           "-bootclasspath" jdk8-bootclasspath])))}
+ javac   {:options ["-source" "1.8"
+                    "-target" "1.8"]}

   pom     {:project 'alda/client-java
            :version +version+
@@ -88,26 +83,25 @@
                (into-array String
                  (str-to-argv/split-args (or ~args ""))))))))

-(deftask assert-jdk8-bootclasspath
-  "Ensures that the JDK7_BOOTCLASSPATH environment variable is set, as required
-   to compile a final jar file that supports Java 1.7+."
-  []
-  (with-pre-wrap fileset
-    (assert (not (empty? (System/getenv "JDK7_BOOTCLASSPATH")))
-            (str "Alda requires JDK7 in order to build its uberjar, in order "
-                 "to provide out-of-the-box support for users who may have "
-                 "older versions of Java. Please install JDK7 and set the "
-                 "environment variable JDK7_BOOTCLASSPATH to the path to your "
-                 "JDK7 classpath jar, e.g. (OS X example) "
-                 "/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/"
-                 "Home/jre/lib/rt.jar"))
-    fileset))
+;; (deftask assert-jdk7-bootclasspath
+;;   "Ensures that the JDK7_BOOTCLASSPATH environment variable is set, as required
+;;    to compile a final jar file that supports Java 1.7+."
+;;   []
+;;   (with-pre-wrap fileset
+;;     (assert (not (empty? (System/getenv "JDK7_BOOTCLASSPATH")))
+;;             (str "Alda requires JDK7 in order to build its uberjar, in order "
+;;                  "to provide out-of-the-box support for users who may have "
+;;                  "older versions of Java. Please install JDK7 and set the "
+;;                  "environment variable JDK7_BOOTCLASSPATH to the path to your "
+;;                  "JDK7 classpath jar, e.g. (OS X example) "
+;;                  "/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/"
+;;                  "Home/jre/lib/rt.jar"))
+;;     fileset))

 (deftask package
   "Builds jar file."
   []
-  (comp (assert-jdk8-bootclasspath)
-        (javac)
+  (comp (javac)
         (pom)
         (jar)))


Bump cljs version; refactor cljs build

Bump cljs version; refactor cljs build

--- build.boot
+++ build.boot
@@ -1,7 +1,7 @@
 (set-env!
   :resource-paths #{"src/main/cljc" "src/spec/cljc" "src/main/js/foreign"}
   :dependencies   '[[org.clojure/clojure         "1.9.0-alpha17"]
-                    [org.clojure/clojurescript   "1.9.660"]
+                    [org.clojure/clojurescript   "1.9.671"]

                     [adzerk/boot-test            "1.2.0"  :scope "test"]
                     [adzerk/boot-reload          "0.5.1"  :scope "test"]
@@ -107,6 +107,11 @@
   (comp (testing)
         (boot-test/test :namespaces ['mikron.test.core])))

+(def cljs-compiler-opts
+  {:static-fns       true
+   :fn-invoke-direct true
+   :parallel-build   true})
+
 (deftask test-node
   "Runs the tests in a Node.js environment."
   [o opt          VAL kw   "The optimization level for the cljs compiler."
@@ -119,7 +124,8 @@
                 "target/mikron/test_runner/node.cljs")
           (boot-cljs-test/test-cljs :js-env        :node
                                     :namespaces    '[mikron.test.core]
-                                    :optimizations (or opt :none)))))
+                                    :optimizations (or opt :none)
+                                    :cljs-otps     cljs-compiler-opts))))

 (deftask test-browser
   "Runs the tests in a browser environment."
@@ -128,7 +134,8 @@
   (comp (testing)
         (boot-cljs-test/test-cljs :js-env        (or js-env :slimer)
                                   :namespaces    '[mikron.test.core]
-                                  :optimizations (or opt :none))))
+                                  :optimizations (or opt :none)
+                                  :cljs-otps     cljs-compiler-opts)))

 (deftask test
   "Runs the specified tests."
@@ -150,9 +157,8 @@
    i id  VAL str "The id of the build."]
   (boot-cljs/cljs
     :ids              [(fix-slashes (or id "browser/index"))]
-    :compiler-options {:static-fns       true
-                       :fn-invoke-direct true
-                       :optimizations    (or opt :none)}))
+    :compiler-options (assoc cljs-compiler-opts
+                        :optimizations (or opt :none))))

 (deftask run-browser-repl
   "Compiles the cljs sources, serves them on localhost:3000, and sets up


Use pre-wrap for run-system

Use pre-wrap for run-system

Previously used post-wrap, which didn't do anything in combination with wait as
the wait would never end & trigger the post condition.

I believe this was designed as such for enforcing that the assets are build
before starting the system. I'd recommend this was instead achieved by moving
the run-system task further down the pipeline.

--- build.boot
+++ build.boot
@@ -153,7 +153,7 @@
   [p profile VAL kw "Profile to start system with"]
   (require 'edge.system)
   (let [new-system (resolve 'edge.system/new-system)]
-    (with-post-wrap fileset
+    (with-pre-wrap fileset
       (let [system (new-system profile)]
         (component/start system)
         (intern 'user 'system system)


update perun

update perun

--- build.boot
+++ build.boot
@@ -1,13 +1,12 @@
 (set-env!
   :source-paths #{"src"}
   :resource-paths #{"resources"}
-  :dependencies '[[org.clojure/clojure "1.6.0"]
-                  [hiccup "1.0.5"]
-                  [perun "0.1.0-SNAPSHOT"]
+  :dependencies '[[hiccup "1.0.5"]
+                  [perun "0.1.3-SNAPSHOT"]
+                  [hashobject/boot-s3 "0.1.2-SNAPSHOT"]
                   [clj-time "0.9.0"]
-                  [pandeiro/boot-http "0.6.2"]
-                  [hashobject/boot-s3 "0.1.0-SNAPSHOT"]
-                  [jeluard/boot-notify "0.1.2" :scope "test"]])
+                  [pandeiro/boot-http "0.6.3-SNAPSHOT"]
+                  [org.martinklepsch/boot-gzip "0.1.1"]])

 (require '[os.hashobject.projects :refer :all])
 (require '[os.hashobject.views.index :as index-view])
@@ -20,7 +19,6 @@

 (require '[hashobject.boot-s3 :refer :all])
 (require '[pandeiro.boot-http :refer :all])
-(require '[jeluard.boot-notify :refer [notify]])

 (task-options!
@@ -34,21 +32,31 @@
     :secret-key (System/getenv "AWS_SECRET_KEY")
     :options {"Cache-Control" "max-age=315360000, no-transform, public"}})

-(defn lib-filename
-  "Default implementation for the `create-filename` task option"
-  [file]
-  "index.html")
+
+(deftask build-dev
+  "Build dev version"
+  []
+  (comp (global-metadata)
+        (markdown)
+        (draft)
+        (ttr)
+        (slug)
+        (permalink)
+        (canonical-url)
+        (render :renderer 'os.hashobject.views.lib/render)
+        (collection :renderer 'os.hashobject.views.index/render :page "index.html")))

 (deftask build
-  "Build site"
+  "Build prod version."
   []
-  (comp (projects)
-        (permalink)
-        (render :renderer project-view/render)
-        (collection :renderer index-view/render :page "index.html")
+  (comp (build-dev)
         (sitemap :filename "sitemap.xml")
-        ;(rss :title "Hashobject" :description "Hashobject open source corner" :link "http://os.hashobject.com")
-        (s3-sync)
-        (notify)))
+        (rss :title "Hashobject" :description "Hashobject open source corner" :link "http://os.hashobject.com")
+        (gzip :regex [#".html$" #".css$" #".js$"])
+        (s3-sync)))

-
+(deftask dev
+  []
+  (comp (watch)
+        (build-dev)
+        (serve :resource-root "public")))


Disable lumo cache

Disable lumo cache

--- build.boot
+++ build.boot
@@ -134,7 +134,7 @@
           (if self-hosted?
             (proc "lumo"
                   "-c" (str "\"" (System/getProperty "fake.class.path") "\"")
-                  "-k" "lumo_cache"
+                  ;"-k" "lumo_cache"
                   "-v"
                   "src/test/cljs/mikron/test_runner/node.cljs")
             (boot-cljs-test/test-cljs :js-env        :node


[boot]: nulling out "ensure-branch" for publishing

--- build.boot
+++ build.boot
@@ -98,7 +98,7 @@
     (cljs :optimizations :advanced :ids #{"mount"})))

 (task-options!
-  push #(-> (into {} %) (assoc :ensure-branch nil))
+  push {:ensure-branch nil}
   pom {:project     'mount
        :version     +version+
        :description "managing Clojure and ClojureScript app state since (reset)"


Update dependencies

Update dependencies

--- build.boot
+++ build.boot
@@ -14,8 +14,8 @@
                   [adzerk/boot-reload "0.2.4" :scope "test"]
                   [pandeiro/boot-http "0.6.2" :scope "test"]
                   [deraen/boot-cljx "0.2.2" :scope "test"]
-                  [cljsjs/boot-cljsjs "0.4.6"]
-                  [allgress/boot-tasks "0.1.11" :scope "test"]
+                  [cljsjs/boot-cljsjs "0.4.6" :scope "test"]
+                  [allgress/boot-tasks "0.1.12" :scope "test"]
                   #_[adzerk/bootlaces "0.1.8" :scope "test"]
                   [com.datomic/datomic-pro "0.9.5130" :scope "test" :exclusions [org.apache.httpcomponents/httpclient]]])


Update paren-soup again

Update paren-soup again

--- build.boot
+++ build.boot
@@ -43,7 +43,7 @@
   (set-env! :dependencies
     (conj (get-env :dependencies)
       '[org.clojure/clojurescript "1.9.225"]
-      '[paren-soup "2.6.3"]
+      '[paren-soup "2.6.4"]
       '[cljsjs/codemirror "5.19.0-0"]))
   (comp (cljs :optimizations :advanced) (target)))


Fix format-commands #3

Fix format-commands #3

--- build.boot
+++ build.boot
@@ -51,6 +51,8 @@

 (defn run-commands
   [& commands]
+  (util/info (str "Running command: ")
+             (apply str (apply format-commands commands)))
   (->> commands
        (apply format-commands)
        (apply util/dosh)))


Make dev-env a task, change Clojure to provided scope

--- build.boot
+++ build.boot
@@ -7,7 +7,7 @@
                           [adzerk/bootlaces "0.1.13" :scope "test"]
                           [org.clojure/test.check "0.9.0" :scope "test"]

-                          [org.clojure/clojure "1.9.0-alpha15"]])
+                          [org.clojure/clojure "1.9.0-alpha15" :scope "provided"]])

 (require '[adzerk.boot-test :refer [test]]
          '[adzerk.bootlaces :refer :all])
@@ -23,26 +23,27 @@
        :license     {"Eclipse Public License"
                      "http://www.eclipse.org/legal/epl-v10.html"}})

-(defn dev-env!
-  []
-  (set-env!
-    :repositories #(conj %
-                         ["datomic" {:url      "https://my.datomic.com/repo"
-                                     :username (System/getenv "DATOMIC_USERNAME")
-                                     :password (System/getenv "DATOMIC_PASSWORD")}])
-    :dependencies #(conj % '[com.datomic/datomic-pro "0.9.5561"])))
+(deftask dev-env
+         []
+         (set-env!
+           :repositories #(conj %
+                                ["datomic" {:url      "https://my.datomic.com/repo"
+                                            :username (System/getenv "DATOMIC_USERNAME")
+                                            :password (System/getenv "DATOMIC_PASSWORD")}])
+           :dependencies #(conj % '[com.datomic/datomic-pro "0.9.5561"]))
+         identity)

 (replace-task!
   [r repl]
   (fn [& xs]
-    (dev-env!)
+    (dev-env)
     (apply r xs)))

 (when (resolve 'lein-generate)
   (replace-task!
     [g lein-generate]
     (fn [& xs]
-      (dev-env!)
+      (dev-env)
       (apply g xs))))

 (deftask deploy


Swap out boot-test with boot-alt-test

Swap out boot-test with boot-alt-test

It's faster and has better output

--- build.boot
+++ build.boot
@@ -3,11 +3,11 @@
   :dependencies '[[org.clojure/clojure "1.8.0"  :scope "provided"]
                   [boot/core           "2.1.0"  :scope "provided"]
                   [adzerk/bootlaces    "0.1.13" :scope "test"]
-                  [adzerk/boot-test    "1.1.2"  :scope "test"]])
+                  [metosin/boot-alt-test "0.2.1" :scope "test"]])

 (require
   '[adzerk.bootlaces :as deploy]
-  '[adzerk.boot-test :as boot-test])
+  '[metosin.boot-alt-test :as boot-test])

 (def +version+ "1.1.0-SNAPSHOT")

@@ -26,16 +26,11 @@
     (watch)
     (deploy/build-jar)))

-(deftask development []
-  (merge-env! :source-paths ["test"])
-  identity)
-
 (ns-unmap 'boot.user 'test)

 (deftask test []
-  (comp
-    (development)
-    (boot-test/test)))
+  (merge-env! :source-paths ["test"])
+  (boot-test/alt-test))

 (deftask push-release []
   (comp


Update clj-jgit

Update clj-jgit

--- build.boot
+++ build.boot
@@ -4,7 +4,7 @@
  :source-paths #{"src/"}
  :dependencies
  '[[org.clojure/clojure "1.8.0"]
-   [clj-jgit "0.8.8"]
+   [clj-jgit "0.8.9"]
    [clj-http "3.0.0"]
    [cheshire "5.5.0"]
    [throttler "1.0.0"]


Fix test dependency for markdown task

Fix test dependency for markdown task

--- build.boot
+++ build.boot
@@ -4,7 +4,7 @@
   :dependencies '[[boot/core "2.1.2" :scope "provided"]
                   [adzerk/bootlaces "0.1.9" :scope "test"]
                   [jeluard/boot-notify "0.1.2" :scope "test"]
-                  [markdown-clj "0.9.40" :scope "test"]
+                  [endophile "0.1.2" :scope "test"]
                   [circleci/clj-yaml "0.5.3" :scope "test"]
                   [time-to-read "0.1.0" :scope "test"]
                   [sitemap "0.2.4" :scope "test"]


first pass at websocket browser repl

first pass at websocket browser repl

--- build.boot
+++ build.boot
@@ -2,6 +2,9 @@
  :resource-paths #{"resources"}
  :source-paths #{"src" "cljs"}
  :dependencies '[[org.clojure/clojure "1.8.0"]
+                 [com.cemerick/piggieback "0.2.1"]
+                 [org.clojure/tools.nrepl "0.2.12"]
+                 [weasel "0.7.0" :exclusions [org.clojure/clojurescript]]
                  [green-tags "0.3.0-alpha"]
                  [hiccup "1.0.5"]
                  [boot-deps "0.1.6"]
@@ -14,6 +17,8 @@
                  [juxt/dirwatch "0.2.3"]])

 (require '[sledge.boot-build :refer :all])
+(require '[weasel.repl.websocket])
+(require '[cemerick.piggieback])

 (task-options!
  pom {:project 'sledge
@@ -25,6 +30,9 @@
        :output-file "assets/js/main.js"}
  target {:dir #{"target/"}})

+(defn wait-for-browser-repl []
+  (cemerick.piggieback/cljs-repl
+   (weasel.repl.websocket/repl-env :ip "0.0.0.0" :port 9001)))

 (deftask build []
   (comp