Started work on compatibility math.

Started work on compatibility math.

--- src/simulacrum/bigfive.clj
+++ src/simulacrum/bigfive.clj
@@ -1,5 +1,17 @@
-(ns simulacrum.bigfive)
-
+(ns simulacrum.bigfive
+  (:require [clojure.core.matrix :as m]
+            [clojure.core.matrix.operators])
+  (:refer clojure.core.matrix.operators :rename
+          {/ div
+           * mult
+           ** pow
+           + add
+           - sub
+           == eql}))
+
+(def min-value 1)
+(def mid-value 3)
+(def max-value 5)

 (def domains
   {:O "Openness"
@@ -8,11 +20,45 @@
    :A "Agreeableness"
    :N "Neuroticism"})

+(def five-point-compatibility-matrix-model-1
+  "The columns in this matrix follow the OCEAN acronym:
+    1) Openness, 2) Conscientiousness, 3) Extraversion, 4) Agreeableness,
+    5) Neuroticism.
+  Similarly, the rows number the same.
+
+  For more informtaion, see docs/compat.rst."
+  (m/matrix [[5 3 4 4 2]
+             [3 5 2 4 3]
+             [4 2 5 3 2]
+             [3 4 4 5 3]
+             [3 2 1 3 5]]))
+
+(def five-point-compatibility-matrix-model-2
+  (m/matrix [[5 3 4 4 2]
+             [2 5 3 4 1]
+             [4 2 5 3 2]
+             [3 4 4 5 3]
+             [3 2 1 3 5]]))
+
+(def five-point-compatibility-matrix
+  five-point-compatibility-matrix-model-2)
+
+(def signed-compatibility-matrix
+  "Convert the compatibilty matrix to one whose values range from -2 to 2, with
+  the neurtal value being 0."
+  (sub five-point-compatibility-matrix mid-value))
+
+(def normalized-compatibility-matrix
+  "Convert the compatibilty matrix to one whose values have been normalized."
+  (m/emap
+    float
+    (div five-point-compatibility-matrix max-value)))
+
 (def questions-base
   {:instructions (str "Answer each question below by providing a number "
-                      "between 1 and 5. The values " \newline
-                      "of the integers have the following "
-                      "meanings:" \newline
+                      "between " min-value " and " max-value ". The values "
+                      \newline
+                      "of the integers have the following meanings:" \newline
                       \tab "* 5 is 'Agree Strongly'" \newline
                       \tab "* 4 is 'Agree a Little'" \newline
                       \tab "* 3 is 'Neutral'" \newline
@@ -27,34 +73,34 @@
     questions-base
     {:title "Five Factor Model (Big Five) Short Inventory"
      :questions [{:question "is reserved"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:question "is generally trusting"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:question "tends to be lazy"
-                  :type :C
+                  :domain-key :C
                   :reversed? true}
                  {:question "is relaxed, handles stress well"
-                  :type :N
+                  :domain-key :N
                   :reversed? true}
                  {:question "has few artistic interests"
-                  :type :O
+                  :domain-key :O
                   :reversed? true}
                  {:question "is outgoing, sociable"
-                  :type :E
+                  :domain-key :E
                   :reversed? false}
                  {:question "tends to find fault with others"
-                  :type :A
+                  :domain-key :A
                   :reversed? true}
                  {:question "does a thorough job"
-                  :type :C
+                  :domain-key :C
                   :reversed? false}
                  {:question "gets nervous easily"
-                  :type :N
+                  :domain-key :N
                   :reversed? false}
                  {:question "has an active imagination"
-                  :type :O
+                  :domain-key :O
                   :reversed? false}]}))

 (def questions-long
@@ -63,179 +109,179 @@
     {:title "Five Factor Model (Big Five) Long Inventory"
      :questions [{:number 1
                   :question "is talkative"
-                  :type :E
+                  :domain-key :E
                   :reversed? false}
                  {:number 2
                   :question "tends to find fault with others"
-                  :type :A
+                  :domain-key :A
                   :reversed? true}
                  {:number 3
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 4
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 5
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 6
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 7
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:number 8
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 9
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 10
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 11
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 12
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? true}
                  {:number 13
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 14
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 15
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 16
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 17
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:number 18
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 19
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 20
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 21
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 22
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:number 23
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 24
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 25
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 26
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 27
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? true}
                  {:number 28
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 29
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 30
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 31
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 32
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:number 33
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 34
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 35
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 36
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 37
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? true}
                  {:number 38
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 39
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 40
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 41
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 42
                   :question "XXX"
-                  :type :A
+                  :domain-key :A
                   :reversed? false}
                  {:number 43
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
                  {:number 44
                   :question "XXX"
-                  :type :E
+                  :domain-key :E
                   :reversed? true}
      ]}))


Don't fail deployment if the repl fails to start [IMMUTANT-592]

--- wildfly/src/immutant/wildfly/repl.clj
+++ wildfly/src/immutant/wildfly/repl.clj
@@ -54,16 +54,26 @@
     (when (and nrepl-middleware nrepl-handler)
       (throw (IllegalArgumentException.
                "Can only use one of :nrepl-handler or :nrepl-middleware")))
-    (let [handler (or (and nrepl-handler (iu/require-resolve nrepl-handler))
-                    (->> nrepl-middleware
-                      (map #(cond
-                              (var? %) %
-                              (symbol? %) (iu/require-resolve %)
-                              (list? %) (eval %)))
-                      (apply nrepl/default-handler)))
-          server (nrepl/start-server :port port :bind host :handler handler)]
-      (u/at-exit (partial stop server))
-      (let [[host bound-port] (nrepl-host-port server)]
-        (iu/info (format "nREPL bound to %s:%s" host bound-port))
-        (spit-nrepl-files bound-port port-file))
-      server)))
+    (try
+      (let [handler (or (and nrepl-handler (iu/require-resolve nrepl-handler))
+                      (->> nrepl-middleware
+                        (map #(cond
+                                (var? %) %
+                                (symbol? %) (iu/require-resolve %)
+                                (list? %) (eval %)))
+                        (apply nrepl/default-handler)))
+            server (nrepl/start-server :port port :bind host :handler handler)]
+        (u/at-exit (partial stop server))
+        (let [[host bound-port] (nrepl-host-port server)]
+          (iu/info (format "nREPL bound to %s:%s" host bound-port))
+          (spit-nrepl-files bound-port port-file))
+        server)
+      (catch Exception e
+        (iu/error "Failed to start nrepl, possibly due to nrepl middleware"
+          "that isn't compatible with WildFly" e)
+        (iu/error "nrepl settings were:"
+          (pr-str {:host host
+                   :port port
+                   :port-file port-file
+                   :nrepl-middleware nrepl-middleware
+                   :nrepl-handler nrepl-handler}))))))


add :src-files to event

add :src-files to event

--- src/tailrecursion/boot.clj
+++ src/tailrecursion/boot.clj
@@ -71,5 +71,12 @@
     (locking boot
       (swap! boot merge usr cfg deps dirs reqs repo tasks {:system sys})
       (swap! boot core/require-tasks))
-    ((core/create-app! boot) (core/make-event))
+    (let [app (core/create-app! boot)]
+      (app (->> (:src-paths @boot)
+                (map io/file)
+                (mapcat file-seq)
+                (filter #(.isFile %))
+                (remove (partial core/ignored? boot))
+                set
+                (assoc (core/make-event) :src-files))))
     (System/exit 0)))


fix consumer start call

fix consumer start call

--- src/vip/data_processor.clj
+++ src/vip/data_processor.clj
@@ -36,7 +36,7 @@
   (let [id (java.util.UUID/randomUUID)]
     (log/info "VIP Data Processor starting up. ID:" id)
     (psql/initialize)
-    (let [consumer-id (q/consume)]
+    (let [consumer-id (q/consume process-message)]
       (.addShutdownHook (Runtime/getRuntime)
                         (Thread. (fn []
                                    (log/info "VIP Data Processor shutting down...")


stage uses now create instead of reload

stage uses now create instead of reload

--- src/celestial/workflows.clj
+++ src/celestial/workflows.clj
@@ -122,14 +122,15 @@
   [type {:keys [machine] :as spec}]
     (info "starting to provision")
     (trace type spec)
+    (assert (= (.status (vconstruct spec)) "running")) ; might not match all providers
     (.apply- (pconstruct type spec))
     (info "done provisioning"))

 (defn stage
   "create and provision"
   [type {:keys [system-id] :as spec}]
-  (reload spec)
-  ; reload may change system properties like ip etc..
+  (create spec)
+  (start spec)
   (puppetize type (assoc (s/get-system system-id) :system-id system-id)))

 (deflow ^{:hook-args :run-info} run-action


Fixes based on GB review

Fixes based on GB review

--- src/cia/auth/threatgrid.clj
+++ src/cia/auth/threatgrid.clj
@@ -2,13 +2,20 @@
   (:require [cheshire.core :as json]
             [cia.auth :as auth]
             [cia.properties :refer [properties]]
+            [cia.schemas.identity :as id]
             [cia.store :as store]
             [clj-http.client :as http]
             [clojure.core.memoize :as memo]
             [clojure.set :as set]
-            [clojure.string :as str]))
+            [clojure.string :as str]
+            [schema.core :as s]))

 (def cache-ttl-ms (* 1000 60 5))
+
+(defn- as-set [x]
+  (cond (set? x) x
+        (keyword? x) #{x}
+        (sequential? x) (set x)))

 (defrecord Identity [role login capabilities]
   auth/IIdentity
@@ -20,9 +27,7 @@
     (some?
      (first
       (set/intersection
-       (cond (set? desired-capability) desired-capability
-             (keyword? desired-capability) #{desired-capability}
-             (sequential? desired-capability) (set desired-capability))
+       (as-set desired-capability)
        (auth/allowed-capabilities this))))))

 (defprotocol IWhoAmI
@@ -50,7 +55,8 @@
     (memo/ttl (make-whoami-fn url)
               :ttl/threshold cache-ttl-ms))))

-(defn lookup-stored-identity [login]
+(s/defn lookup-stored-identity :- (s/maybe id/Identity)
+  [login :- s/Str]
   (store/read-identity @store/identity-store login))

 (defrecord AuthService [whoami-service lookup-stored-identity-fn]


All +ive for PureCSS

All +ive for PureCSS

--- src/client/my_css/root.cljs
+++ src/client/my_css/root.cljs
@@ -31,13 +31,18 @@
 ;

 ;

 ;

+
+(defn tab-style [tab kw]
+  #js{:className (str "pure-menu-item" (if (= tab kw) " pure-menu-selected"))})
+
 (defui ^:once App
   static om/IQuery
   (query [this] [:ui/locale :ui/react-key {:current-tab (om/get-query ui/Tab)}])
   Object
   (render [this]
     (let [{:keys [current-tab ui/react-key] :or {ui/react-key "ROOT"} :as props} (om/props this)
-          tab (:tab/type current-tab)]
+          tab (:tab/type current-tab)
+          _ (println "tab is " tab)]
       (dom/div #js{:className "custom-wrapper pure-g"
                    :id "menu"}
                (dom/div #js{:className "pure-u-1 pure-u-md-1-3"}
@@ -51,12 +56,14 @@
                (dom/div #js{:className "pure-u-1 pure-u-md-1-3"}
                         (dom/div #js{:className "pure-menu pure-menu-horizontal custom-can-transform"}
                                  (dom/ul #js{:className "pure-menu-list"}
-                                         (dom/li #js{:className "pure-menu-item"}
+                                         (dom/li (tab-style tab :main)
                                                  (dom/a #js{:className "pure-menu-link"
-                                                            :href "#"} "Home"))
-                                         (dom/li #js{:className "pure-menu-item"}
+                                                            :href "#"
+                                                            :onClick #(om/transact! this '[(nav/change-tab {:target :main})])} "Main"))
+                                         (dom/li (tab-style tab :settings)
                                                  (dom/a #js{:className "pure-menu-link"
-                                                            :href "#"} "About"))
+                                                            :href "#"
+                                                            :onClick #(om/transact! this '[(nav/change-tab {:target :settings})])} "Settings"))
                                          (dom/li #js{:className "pure-menu-item"}
                                                  (dom/a #js{:className "pure-menu-link"
                                                             :href "#"} "Contact")))))
@@ -88,8 +95,6 @@
 ;

 ;
 ;
-(defn tab-style [tab]
-  #js{:className (str "one column button" (if (= tab :main) " active-tab"))})

 (comment (defui ^:once Root
            static om/IQuery


Change set angle protocol to set angles first and then run angles

--- src/clj/calc_angle/core.clj
+++ src/clj/calc_angle/core.clj
@@ -141,17 +141,25 @@

 (def ^:dynamic *serial-conn*)

+(defn set-count [cnt]
+  (let [count-str (format "s=%d," cnt)]
+    (println (str "--> " count-str))
+    (.writeString *serial-conn* count-str)
+    (println (str "<-- " (char (aget (.readBytes *serial-conn* 1) 0))))))
+
+(defn kick-action []
+  (let [draw-str "d"]
+    (println (str "--> " draw-str))
+    (.writeString *serial-conn* draw-str)
+    (println (str "<-- " (char (aget (.readBytes *serial-conn* 1) 0))))))
+
 (defn set-angle [base-angle first-angle second-angle]
   (let [serial-str (format "a=%.3f,b=%.3f,c=%.3f," base-angle first-angle second-angle)]
     (println (str "--> " serial-str))
     (.writeString *serial-conn* serial-str)
     (let [echo (char (aget (.readBytes *serial-conn* 1) 0))]
-      (when-not (= echo \0) (println (str echo " angle out of range"))))
-    (loop [reduce-str "<-- "
-           curr-char (char (aget (.readBytes *serial-conn* 1) 0))]
-      (if (= curr-char \newline)
-        (println reduce-str)
-        (recur (str reduce-str curr-char) (char (aget (.readBytes *serial-conn* 1) 0)))))))
+      (when-not (= echo \0) (println (str echo " angle out of range")))
+      (println (str "<-- " echo)))))

 (defn calc-angle-seq [input-str]
   (println input-str)
@@ -169,8 +177,10 @@
     (map (fn [[_ theta] [alpha beta]] (list (- theta) (- 90. beta) (+ alpha beta))) r-theta-list alpha-beta-degree-list)))

 (defn write-strokes [angles-seq]
+  (set-count (count angles-seq))
   (doseq [[base-angle first-angle second-angle] angles-seq]
     (set-angle base-angle first-angle second-angle))
+  (kick-action)
   "OK")

 (defroutes app


manually set *e in Rhino on JS exception

--- src/clj/cljs/repl/rhino.clj
+++ src/clj/cljs/repl/rhino.clj
@@ -76,11 +76,15 @@
        :value (eval-result (-eval js repl-env filename linenum))})
     (catch Throwable ex
       ;; manually set *e
-      ;; (ScriptableObject/putProperty scope "cljs.core._STAR_e"
-      ;;   (Context/javaToJS ex scope))
-      {:status :exception
-       :value (.toString ex)
-       :stacktrace (stacktrace ex)})))
+      (let [top-level (-> scope
+                        (ScriptableObject/getProperty "cljs")
+                        (ScriptableObject/getProperty "core"))]
+        (ScriptableObject/putProperty top-level "_STAR_e"
+          (Context/javaToJS ex scope))
+        (util/debug-prn top-level)
+        {:status :exception
+         :value (.toString ex)
+         :stacktrace (stacktrace ex)}))))

 (defn load-file
   "Load a JavaScript. This is needed to load JavaScript files before the Rhino


improve execution of kws

improve execution of kws

--- src/clj/com/rpl/specter.clj
+++ src/clj/com/rpl/specter.clj
@@ -159,11 +159,10 @@

 (extend-type clojure.lang.Keyword
   StructurePath
-  ;; faster to invoke keyword directly on structure rather than reuse key-select and key-update functions
-  (select* [^clojure.lang.Keyword kw structure next-fn]
-    (next-fn (kw structure)))
-  (update* [^clojure.lang.Keyword kw structure next-fn]
-    (assoc structure kw (next-fn (kw structure)))
+  (select* [kw structure next-fn]
+    (next-fn (get structure kw)))
+  (update* [kw structure next-fn]
+    (assoc structure kw (next-fn (get structure kw)))
     ))

 (extend-type clojure.lang.AFn


Remove a superfluous logging statement

Remove a superfluous logging statement

--- src/clj/mdr2/production.clj
+++ src/clj/mdr2/production.clj
@@ -44,7 +44,6 @@
   `production`. If there are no validation errors or no DAISY exports
   returns an empty list"
   [production]
-  (log/debugf "Validating production %s" (:id production))
   (if (not (manifest? production))
     ["No manifest found"]
     (->> (range (:volumes production))


Added block fn nil check

Added block fn nil check

--- src/clj/salava/admin/db.clj
+++ src/clj/salava/admin/db.clj
@@ -209,9 +209,9 @@

 (defn get-oauth-user-services [ctx user_id]
-  (let [fun (first (plugin-fun (get-plugins ctx) "block" "user-information"))]
-    (fun ctx user_id))
-  )
+  (if-let [fun (first (plugin-fun (get-plugins ctx) "block" "user-information"))]
+    (fun ctx user_id)
+    []))

 (defn get-user [ctx user_id]
   (let [user (u/user-information-with-registered-and-last-login ctx user_id)


Added OAuth HTTP request timeout, logging

--- src/clj/salava/oauth/db.clj
+++ src/clj/salava/oauth/db.clj
@@ -1,5 +1,6 @@
 (ns salava.oauth.db
-  (:require [yesql.core :refer [defqueries]]
+  (:require [clojure.tools.logging :as log]
+            [yesql.core :refer [defqueries]]
             [clojure.java.jdbc :as jdbc]
             [clojure.set :refer [rename-keys]]
             [clj-http.client :as http]
@@ -9,16 +10,19 @@
 (defqueries "sql/oauth/queries.sql")

 (defn oauth-request [method url opts]
-  (try+
+  (try
     (-> {:method       method
          :url          url
+         :socket-timeout 30000
+         :conn-timeout   30000
          :content-type :json
          :as           :json}
         (merge opts)
         (http/request)
         (get :body))
-    (catch Object _
-      ;TODO: (log "OAuth request failed" _)
+    (catch Exception ex
+      (log/error "OAuth request failed")
+      (log/error (.toString ex))
       (throw+ "oauth/Cannotconnecttoservice"))))

 (defn access-token [method url opts]


Change status of successful patch to 200

--- src/clj/todo_clj/server.clj
+++ src/clj/todo_clj/server.clj
@@ -46,7 +46,7 @@
   (PATCH "/todos/:id" {{id :id :as params} :params body :body}
     (-> id
         (#(todos/update-todo % body))
-        res-created))
+        res-ok))
   (DELETE "/todos" _
     (todos/delete-all)
     (res-no-content))


Kibit linting

Kibit linting

--- src/clj_fuzzy/lancaster.clj
+++ src/clj_fuzzy/lancaster.clj
@@ -57,7 +57,7 @@
       (cond (nil? (seq rule)) [false stem]
             (and (not intact)
                  (= kind :intact)) (recur (inc i))
-            (or (< breakpoint 0)
+            (or (neg? breakpoint)
                 (not= (subs stem breakpoint) match)) (recur (inc i))
             (= kind :protect) [false stem]
             :else (let [new-stem (str (subs stem 0 breakpoint) replacement)]


Minor formatting

Minor formatting


Tweaks to unit build menu stats code

Tweaks to unit build menu stats code

- Use more builtin Bootstrap CSS classes
- Replace ^{:key ...} with 'into's (personal preference)
- Replace overly clever map usage with case
- Pull out more unit-type values in row level let
- Make entire row clickable

--- src/cljs/zetawar/views.cljs
+++ src/cljs/zetawar/views.cljs
@@ -269,93 +269,101 @@
                 :on-click #(dispatch [::events.ui/configure-faction faction])
                 :title (translate :configure-faction-tip)}]]]))))

+(def armor-type-abbrevs
+  {:unit-type.armor-type/personnel "P"
+   :unit-type.armor-type/armored "A"})
+
 ;; TODO: cleanup unit-picker
 (defn unit-picker [{:as view-ctx :keys [conn dispatch translate]}]
   (let [unit-types @(subs/available-unit-types conn)
         cur-faction @(subs/current-faction conn)
         color (name (:faction/color cur-faction))
-        hide-picker (fn [ev]
-                      (when ev (.preventDefault ev))
-                      (dispatch [::events.ui/hide-unit-picker]))]
+        hide-picker #(dispatch [::events.ui/hide-unit-picker])]
     [:> js/ReactBootstrap.Modal {:show @(subs/picking-unit? conn)
                                  :on-hide hide-picker}
      [:> js/ReactBootstrap.Modal.Header {:close-button true}
       [:> js/ReactBootstrap.Modal.Title
        (translate :build-title)]]
      [:> js/ReactBootstrap.Modal.Body
-      [:> js/ReactBootstrap.Table
-       {:bordered true
-        :striped true
-        :condensed true
-        :hover true}
+      [:> js/ReactBootstrap.Table {:bordered true
+                                   :striped true
+                                   :condensed true
+                                   :hover true}
        [:thead>tr
         [:th ""]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Armor Type"]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Move- ment"]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Armor"]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Range"]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Attack"]
-        [:th {:style {:text-align "center" :width "12%"}}
-             "Field Repair?"]]
-       (for [{:keys [unit-type/id] :as unit-type} unit-types]
-         (let [;; TODO: replace with unit-type-image
-               color-or-grey (if (:affordable unit-type)
-                               color
-                               "unavailable")
-               image (->> (string/replace (:unit-type/image unit-type)
-                                          "COLOR" color-or-grey)
-                           (str "/images/game/"))
-               media-class (if (:affordable unit-type)
-                             "media clickable"
-                             "media clickable text-muted")]
-          ^{:key unit-type}
-          [:tbody>tr
-           {:style {:text-align "center"}}
-           [:td>div {:style {:text-align "left"}
-                     :class media-class
-                     :on-click #(when (:affordable unit-type)
+        [:th.text-center {:style {:width "12%"}}
+         "Armor Type"]
+        [:th.text-center {:style {:width "12%"}}
+         "Move- ment"]
+        [:th.text-center {:style {:width "12%"}}
+         "Armor"]
+        [:th.text-center {:style {:width "12%"}}
+         "Range"]
+        [:th.text-center {:style {:width "12%"}}
+         "Attack"]
+        [:th.text-center {:style {:width "12%"}}
+         "Field Repair?"]]
+       (into [:tbody]
+             (for [unit-type unit-types]
+               (let [;; TODO: replace with unit-type-image
+                     color-or-grey (if (:affordable unit-type)
+                                     color
+                                     "unavailable")
+                     image (->> (string/replace (:unit-type/image unit-type)
+                                                "COLOR" color-or-grey)
+                                (str "/images/game/"))
+                     media-class (if (:affordable unit-type)
+                                   "media text-left"
+                                   "media text-left text-muted")
+                     {:keys [unit-type/id
+                             unit-type/description
+                             unit-type/cost
+                             unit-type/movement
+                             unit-type/armor
+                             unit-type/armor-type
+                             unit-type/can-capture
+                             unit-type/capturing-armor
+                             unit-type/min-range
+                             unit-type/max-range]} unit-type
+                     armor-type-abbrev (armor-type-abbrevs armor-type)]
+                 [:tr.text-center.clickable
+                  {:on-click #(when (:affordable unit-type)
                                 (dispatch [::events.ui/hide-unit-picker])
                                 (dispatch [::events.ui/build-unit id]))}
-            [:div.media-left.media-middle
-             [:img {:src image}]]
-            [:div.media-body
-             [:h4.media-heading
-              (:unit-type/description unit-type)]
-             (str "Cost: " (:unit-type/cost unit-type))]]
-           [:td ({:unit-type.armor-type/personnel [:abbr {:title "Personnel"
-                                                          :style {:cursor "inherit"}}
-                                                          "P"]
-                  :unit-type.armor-type/armored [:abbr {:title "Armored"
-                                                        :style {:cursor "inherit"}}
-                                                        "A"]}
-                 (get-in unit-type [:unit-type/armor-type]))]
-           [:td (:unit-type/movement unit-type)]
-           [:td (if (:unit-type/can-capture unit-type)
-                  [:abbr {:title (str "While capturing: " (:unit-type/capturing-armor unit-type))
-                          :style {:cursor "inherit"}}
-                   (:unit-type/armor unit-type)]
-                  [:abbr {:title "Unit cannot capture bases"
-                          :style {:cursor "inherit"}}
-                   (:unit-type/armor unit-type)])]
-           [:td (:unit-type/min-range unit-type)
-                "-"
-                (:unit-type/max-range unit-type)]
-           [:td (for [strength-info (:unit-type/strengths unit-type)
-                      :let [atype ({"personnel" "P: " "armored" "A: "}
-                                   (name (:unit-strength/armor-type strength-info)))
-                            attackstrength (:unit-strength/attack strength-info)]]
-                  ^{:key strength-info}
-                  [:div (str atype attackstrength)])]
-           [:td (interpose ", "
-                  (for [can-repair-set (:unit-type/can-repair unit-type)]
-                    ({"personnel" "P" "armored" "A"} (name can-repair-set))))]]))]]
+                  [:td>div {:class media-class}
+                   [:div.media-left.media-middle
+                    [:img {:src image}]]
+                   [:div.media-body
+                    [:h4.media-heading description]
+                    (str "Cost: " cost)]]
+                  [:td (case armor-type
+                         :unit-type.armor-type/personnel
+                         [:abbr {:title "Personnel" :style {:cursor "inherit"}}
+                          armor-type-abbrev]
+
+                         :unit-type.armor-type/armored
+                         [:abbr {:title "Armored" :style {:cursor "inherit"}}
+                          armor-type-abbrev])]
+                  [:td movement]
+                  [:td (if can-capture
+                         [:abbr {:title (str "While capturing: " capturing-armor)
+                                 :style {:cursor "inherit"}}
+                          armor]
+                         [:abbr {:title "Unit cannot capture bases"
+                                 :style {:cursor "inherit"}}
+                          armor])]
+                  [:td min-range "-" max-range]
+                  (into [:td]
+                        (for [unit-strength (:unit-type/strengths unit-type)]
+                          (let [{:keys [unit-strength/armor-type
+                                        unit-strength/attack]} unit-strength
+                                armor-type-abbrev (armor-type-abbrevs armor-type)]
+                            [:div (str armor-type-abbrev ": " attack)])))
+                  [:td (string/join ", "
+                                    (for [can-repair (:unit-type/can-repair unit-type)]
+                                      (armor-type-abbrevs can-repair "")))]])))]]
      [:> js/ReactBootstrap.Modal.Footer
-      [:button.btn.btn-default {:on-click hide-picker}
+      [:div.btn.btn-default {:on-click hide-picker}
        "Cancel"]]]))

 (defn faction-settings [{:as views-ctx :keys [conn dispatch translate]}]


fixed spec for behavior

fixed spec for behavior

--- src/untangled_spec/core.clj
+++ src/untangled_spec/core.clj
@@ -31,7 +31,7 @@

 (s/def ::specification
   (s/cat
-    :name (s/or :string string? :symbol symbol?)
+    :name string?
     :opts (s/* keyword?)
     :body (s/* ::us/any)))

@@ -50,8 +50,12 @@
        (im/with-reporting {:type :specification :string ~name}
          ~@body))))

-(s/def ::behavior ::specification)
+(s/def ::behavior (s/cat
+                    :name (s/or :str string? :sym symbol?)
+                    :opts (s/* keyword?)
+                    :body (s/* ::us/any)))
 (s/fdef behavior :args ::behavior)
+
 (defmacro behavior
   "Adds a new string to the list of testing contexts.  May be nested,
    but must occur inside a specification. If the behavior is not machine
@@ -61,6 +65,7 @@
    (behavior \"blows up when the moon is full\" ::manual-test)"
   [& args]
   (let [{:keys [name opts body]} (us/conform! ::behavior args)
+        name (second name)
         typekw (if (contains? opts :manual-test)
                  :manual :behavior)
         prefix (if-cljs &env "cljs.test" "clojure.test")]


src elements are changed

src elements are changed

--- src_cljs/rrm/corecljs.cljs
+++ src_cljs/rrm/corecljs.cljs
@@ -390,17 +390,19 @@
                            [:b (str (first ((form-validator @data-set) id)))]])
                         [:div])]])))

-(defn dist-onchange [id]
+(defn dist-onchange [id val data-set]
   (let [res (fn [json]
               (let [dt (getdata json)]
                 (set-key-value :subdivisions dt)
                 (set-key-value :villages nil)))]
-    (http-get (str  "http://localhost:9000/districts/" id  "/subdivisions") res)))
+    (do (http-get (str  serverhost "districts/" val  "/subdivisions") res)
+        (swap! data-set assoc id val)
+        )))

 (defn dist-sel-tag [id data data-set]
   [:select.form-control {:id id
                          :value (@data-set id)
-                         :on-change #(dist-onchange (-> % .-target .-value)) }
+                         :on-change #(dist-onchange id (-> % .-target .-value) data-set) }
    [:option {:value 0} "--Select--"]
    (for [d  data]
      ^{:key (.-id d)}
@@ -412,16 +414,18 @@
    [:div.col-sm-6 [dist-sel-tag id opt-data data-set]]
    [:div.col-sm-3 [:div]]])

-(defn sub-onchange [id]
+(defn sub-onchange [id val data-set]
   (let [res (fn [json]
               (let [dt (getdata json)]
                 (set-key-value :villages dt)))]
-    (http-get (str  "http://localhost:9000/subdivisions/" id  "/villages") res)))
+    (do (http-get (str serverhost "subdivisions/" val  "/villages") res)
+        (swap! data-set assoc id val)
+        )))

 (defn sub-sel-tag [id data data-set]
   [:select.form-control {:id id
                          :value (@data-set id)
-                         :on-change #(sub-onchange (-> % .-target .-value))}
+                         :on-change #(sub-onchange  id (-> % .-target .-value) data-set)}
    [:option {:value 0} "--Select--"]
    (for [d  data]
      ^{:key (.-id d) }
@@ -520,17 +524,19 @@
 (defn add-form-onclick [data-set focus]
   (if (= nil (form-validator @data-set))
     (let [onres (fn[json]
-                  (secretary/dispatch! "/"))]
+                  (secretary/dispatch! "/"))
+          data (swap! data-set dissoc :districtid :subdivisionid)]
       (http-post (str serverhost "mutations")
-                     onres  (.serialize (Serializer.) (clj->js @data-set))))
+                     onres  (.serialize (Serializer.) (clj->js data))))
     (reset! focus "on")))

 (defn update-form-onclick [data-set focus]
   (if (= nil (form-validator @data-set))
      (let [onres (fn[data]
-                      (secretary/dispatch! "/"))]
+                   (secretary/dispatch! "/"))
+           data (swap! data-set dissoc :districtid :subdivisionid)]
           (http-put (str serverhost "mutations/" (:id @data-set))
-                    onres (.serialize (Serializer.) (clj->js @data-set)))))
+                    onres (.serialize (Serializer.) (clj->js data)))))
     (reset! focus "on"))

 (defn form-cancel [event]
@@ -560,19 +566,32 @@
     (http-get (str serverhost "mutations?pageIndex=0&pageSize=10") onres)))

+(defn src-dist-onchange [val]
+  (let [res (fn [json]
+              (let [dt (getdata json)]
+                (set-key-value :subdivisions dt)
+                (set-key-value :villages nil)))]
+    (http-get (str  serverhost "districts/" val  "/subdivisions") res)))
+
 (defn src-dist-sel-tag []
   [:select.form-control {:id :src-dist
                          :placeholder "District Name"
-                         :on-change #(dist-onchange (-> % .-target .-value)) }
+                         :on-change #(src-dist-onchange (-> % .-target .-value)) }
    [:option {:value 0} "--Select--"]
    (for [d  (@storage :districts)]
      ^{:key (.-id d)}
      [:option {:value (.-id d)} (.-name d)])])

+(defn src-sub-onchange [ val]
+  (let [res (fn [json]
+              (let [dt (getdata json)]
+                (set-key-value :villages dt)))]
+    (http-get (str serverhost "subdivisions/" val  "/villages") res)))
+
 (defn src-sub-sel-tag []
   [:select.form-control {:id :src-sub
                          :placeholder "Sub Division Name"
-                         :on-change  #(sub-onchange (-> % .-target .-value)) }
+                         :on-change  #(src-sub-onchange (-> % .-target .-value)) }
    [:option {:value 0} "--Select--"]
    (for [d  (@storage :subdivisions)]
      ^{:key (.-id d)}
@@ -587,45 +606,52 @@
      ^{:key (.-id d)}
      [:option {:value (.-id d)} (.-villagename d)])])

+(def button-tool-bar (r/adapt-react-class (aget js/ReactBootstrap "ButtonToolbar")))
+(def button (r/adapt-react-class (aget js/ReactBootstrap "Button")))

 (defn render-mutations [mutations]
   [:div
    [:div {:class "box"}
     [:div {:class "box-header"}
-     [:h3 "List of Mutations"]]
+     [:div.page-header [:h3 "List of Mutations"]]]
     [:div.col-md-12
      [:div.form-group
       [:div.row
        [:div.col-sm-2 "Mutation Number"
         [:input.form-control {:id "mutationnumber"
                               :type "text"
-                              :placeholder "Enter search by mutationnumber"}]]
-       [:div.col-sm-2 "Enter Search Text"
-        [:input.form-control {:id "dt" :type "text"
-                              :placeholder "Enter search text.."}]]]]
-
+                              :placeholder "Enter search by mutationnumber"}]]]]
      [:div.form-group
       [:div.row
-       [:div.col-sm-2 "Title"
-        [:input.form-control {:id "stitle"
-                              :type "text"
-                              :placeholder "Title"}]]
        [:div.col-sm-2 "District Name"
         [src-dist-sel-tag]]
        [:div.col-sm-2 "Sub Division Name"
         [src-sub-sel-tag]]
        [:div.col-sm-2 "Village Name"
         [src-vill-sel-tag]]
-       [:div.col-sm-2 "Name Of P.O"
-        [:input.form-control {:id "svillagename"
-                              :list "combo"
-                              :placeholder "Name Of P.O"}[datalist]]]]]
-     [:div.form-group
-      [:div.row
        [:div.col-sm-2 "O2 Number"
         [:input.form-control {:id "so2number"
                               :type "text"
                               :placeholder "O2 Number"}]]
+       [:div.col-sm-2 "Name of the First Party"
+        [:input.form-control {:id "snameofthefirstparty"
+                              :type "text"
+                              :placeholder "Name of the First Party"}]]]]
+
+     [:div.form-group
+      [:div.row
+       [:div.col-sm-2 "Name of the Second Party"
+        [:input.form-control {:id "snameofthesecondparty"
+                              :type "text"
+                              :placeholder "Name of the Second Party"}]]
+       [:div.col-sm-2 "Name Of P.O"
+        [:input.form-control {:id "svillagename"
+                              :list "combo"
+                              :placeholder "Name Of P.O"}[datalist]]]
+       [:div.col-sm-2 "Title"
+        [:input.form-control {:id "stitle"
+                              :type "text"
+                              :placeholder "Title"}]]
        [:div.col-sm-2 "Khasra Number"
         [:input.form-control {:id "skhasranumber"
                               :type "text"
@@ -633,21 +659,16 @@
        [:div.col-sm-2 "Khata khatuni Number"
         [:input.form-control {:id "skhatakhatuninumber"
                               :type "text"
-                              :placeholder "Khata Khatuni Number"}]]
-       [:div.col-sm-2 "Name of the First Party"
-        [:input.form-control {:id "snameofthefirstparty"
-                              :type "text"
-                              :placeholder "Name of the First Party"}]]
-       [:div.col-sm-2 "Name of the Second Party"
-        [:input.form-control {:id "snameofthesecondparty"
-                              :type "text"
-                              :placeholder "Name of the Second Party"}]]]]
+                              :placeholder "Khata Khatuni Number"}]]]]
+     [:hr]
      [:div.form-group
       [:div.row
-       [:div.col-sm-2.col-md-offset-5 {:style {:padding-top "20px"}}
-        [:input.btn.btn-primary {:type "button" :value "Search" :on-click search}]
-        [:input.btn.btn-primary {:type "button" :value "Add" :on-click add}]
-        [:input.btn.btn-primary {:id "getall" :type "button" :value "Refresh":on-click get-all-click}]]]]]
+       [:div.col-sm-8.col-md-offset-5
+        [button-tool-bar
+         [button {:bs-style "info" :on-click search } "Search"]
+         [button {:bs-style "primary"  :on-click add} "Add New"]
+         [button {:id "getall" :bs-style "primary" :on-click get-all-click} "Refresh"]]
+        ]]]]

     [:div {:class "box-body"}
      [:table {:class "table table-bordered table-striped dataTable"}


Reorder functions to avoid side-effect

Reorder functions to avoid side-effect

--- src/whisper2cyanite/cli.clj
+++ src/whisper2cyanite/cli.clj
@@ -12,7 +12,18 @@
 (def cli-commands #{"migrate" "validate" "calc-size" "list-files" "list-paths"
                     "info" "fetch" "help"})

-(declare parse-rollups check-rollups)
+(defn- check-rollups
+  "Check rollups."
+  [rollups]
+  (not-any? nil? rollups))
+
+(defn- parse-rollups
+  "Parse rollups."
+  [rollups]
+  (->> (str/split rollups #",")
+       (map #(re-matches #"^((\d+)(:(\d+))*)$" %))
+       (map #(if % [(Integer/parseInt (nth % 2))
+                    (Integer/parseInt (nth % 4))] %))))

 (def cli-options
   [["-f" "--from FROM" "From time (Unix epoch)"
@@ -67,19 +78,6 @@
    ["-S" "--stop-on-error" "Stop on first non-fatal error"]
    ["-P" "--disable-progress" "Disable progress bar"]
    ["-h" "--help" "Show this help"]])
-
-(defn- check-rollups
-  "Check rollups."
-  [rollups]
-  (not-any? nil? rollups))
-
-(defn- parse-rollups
-  "Parse rollups."
-  [rollups]
-  (->> (str/split rollups #",")
-       (map #(re-matches #"^((\d+)(:(\d+))*)$" %))
-       (map #(if % [(Integer/parseInt (nth % 2))
-                    (Integer/parseInt (nth % 4))] %))))

 (defn- usage
   "Construct usage message."


Some adjustments to get-trip-reports.

Some adjustments to get-trip-reports.

--- project/scrape-trs/src/scrape_trs/core.clj
+++ project/scrape-trs/src/scrape_trs/core.clj
@@ -1,23 +1,45 @@
 (ns scrape-trs.core
   (:require [scrape-trs.cascade-climbers.core :as cc]))

-(defn- get-implementation
-  [base-url]
-  (case base-url
-    cc/base-url (cc/->CCScrapeTripReport)))
+(comment
+  "TODO:
+   - add SPScrapeTripReport
+   - upgrade get-trip-reports to return [errors, trip-reports]
+     based on try-slurp that returns [error, contents]
+   - add docs and tests for get-trip-reports
+   - implement save-trip-reports!
+   - make scrape-wa-trs project that
+       retrieves cc.com tr list pages for each region in WA (POST)
+       retrieves sp.com tr list page for WA
+       get-trip-reports on each page and concat all together
+       save to csv"
+
+  (def cascade-climbers-washington-regions
+    #{"Alpine Lakes"
+      "Central/Eastern  Washington"
+      "Columbia River Gorge"
+      "Ice Climbing Forum"
+      "Mount Rainier NP"
+      "North Cascades"
+      "Olympic Peninsula"
+      "Rock Climbing Forum"
+      "Southern WA Cascades"
+      "the *freshiezone*"}))
+
+(defn get-implementation
+  [url]
+  (let [base-url (re-find #"https?://.*?/" url)]
+    (case base-url
+      "http://cascadeclimbers.com/" (cc/->CCScrapeTripReport))))

 (defn get-trip-reports
   ""
-  [list-page-url]
-  (let [base-url (re-find #"https?://.*?/" list-page-url)
-        implementation (get-implementation base-url)
-        list-page (slurp list-page)
-        pager-urls (.extract-pager-urls implementation list-page)
+  [implementation list-page]
+  (let [pager-urls (.extract-pager-urls implementation list-page)
         list-pages (map slurp pager-urls)
-        trip-report-urls (mapcat (partial .extract-trip-report-urls
-                                          implementation)
+        trip-report-urls (mapcat #(.extract-trip-report-urls implementation %)
                                  list-pages)
-        trip-reports (map (partial .extract-trip-report implementation)
+        trip-reports (map #(.extract-trip-report implementation %1 %2)
                           trip-report-urls
                           (map slurp trip-report-urls))]
     trip-reports))


use sentinel to make select-in work w/ falsey values

(select-in {:a false} [[:a]]) should return {:a false} instead of {}

--- src-cljs/frontend/utils/seq.cljs
+++ src-cljs/frontend/utils/seq.cljs
@@ -5,17 +5,19 @@
   [filter-fn coll]
   (first (keep-indexed (fn [i x] (when (filter-fn x) i)) coll)))

+(def sentinel (js-obj))
+
 (defn select-in
   "Returns a map containing only those entries in map whose keypath is in keypaths
    (select-in {:a {:b 1 :c 2}} [[:a :b]]) => {:a {:b 1}} "
   [map keypathseq]
     (loop [ret {} keypaths (seq keypathseq)]
       (if keypaths
-        (let [entry (get-in map (first keypaths))]
+        (let [entry (get-in map (first keypaths) sentinel)]
           (recur
-           (if entry
-             (assoc-in ret (first keypaths) entry)
-             ret)
+           (if (identical? entry sentinel)
+             ret
+             (assoc-in ret (first keypaths) entry))
            (next keypaths)))
         (with-meta ret (meta map)))))


add lot transaction test for selling a commodity

--- test/clj_money/trading_test.clj
+++ test/clj_money/trading_test.clj
@@ -234,8 +234,35 @@
                    :shares-owned 75M}]]
     (is (= expected lots) "The lot is updated to reflect the sale")))

+(deftest selling-a-commodity-creates-a-lot-transaction-record
+  (let [context (serialization/realize storage-spec sell-context)
+        ira (-> context :accounts first)
+        commodity (-> context :commodities first)
+        _ (trading/sell storage-spec {:commodity-id (:id commodity)
+                                      :account-id (:id ira)
+                                      :trade-date (t/local-date 2017 3 2)
+                                      :shares 25M
+                                      :value 375M})
+        lot-transactions (map #(dissoc % :id :created-at :updated-at)
+                              (lot-transactions/select
+                                storage-spec
+                                {:account-id (:id ira)
+                                 :commodity-id (:id commodity)}))
+        expected [{:trade-date (t/local-date 2016 3 2)
+                   :account-id (:id ira)
+                   :commodity-id (:id commodity)
+                   :action :buy
+                   :price 10M
+                   :shares 100M}
+                  {:trade-date (t/local-date 2017 3 2)
+                   :account-id (:id ira)
+                   :commodity-id (:id commodity)
+                   :action :sell
+                   :price 15M
+                   :shares 25M}]]
+    (is (= expected lot-transactions) "The lot transaction is created with proper data")))
+
 ; Selling a commodity updates a lot record (FILO updates the most recent, FIFO updates the oldest)
-; Selling a commodity creates a lot transaction record
 ; Selling a commodity creates a transaction record
 ; Selling a commodity for a profit credits the capital gains account
 ; Selling a commodity for a loss debits the capital gains account


Remove useless testing calls

Remove useless testing calls

--- test/cljc/reitit/ring_test.cljc
+++ test/cljc/reitit/ring_test.cljc
@@ -474,35 +474,34 @@
                            (ring/router
                              ["/*" (create nil)])
                            (ring/create-default-handler))]
-                 (testing test
-                   (testing "different file-types"
-                     (let [response (app (request "/hello.json"))]
-                       (is (= "application/json" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
-                     (let [response (app (request "/hello.xml"))]
-                       (is (= "text/xml" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
-
-                   (testing "index-files"
-                     (let [response (app (request "/docs"))]
-                       (is (= (redirect "/docs/index.html") response)))
-                     (let [response (app (request "/docs/"))]
-                       (is (= (redirect "/docs/index.html") response))))
-
-                   (testing "not found"
-                     (let [response (app (request "/not-found"))]
-                       (is (= 404 (:status response)))))
-
-                   (testing "3-arity"
-                     (let [result (atom nil)
-                           respond (partial reset! result)
-                           raise ::not-called]
-                       (app (request "/hello.xml") respond raise)
-                       (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
-                       (is (get-in @result [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))
+                 (testing "different file-types"
+                   (let [response (app (request "/hello.json"))]
+                     (is (= "application/json" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
+                   (let [response (app (request "/hello.xml"))]
+                     (is (= "text/xml" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
+
+                 (testing "index-files"
+                   (let [response (app (request "/docs"))]
+                     (is (= (redirect "/docs/index.html") response)))
+                   (let [response (app (request "/docs/"))]
+                     (is (= (redirect "/docs/index.html") response))))
+
+                 (testing "not found"
+                   (let [response (app (request "/not-found"))]
+                     (is (= 404 (:status response)))))
+
+                 (testing "3-arity"
+                   (let [result (atom nil)
+                         respond (partial reset! result)
+                         raise ::not-called]
+                     (app (request "/hello.xml") respond raise)
+                     (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
+                     (is (get-in @result [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result))))))))

              (testing "from path"
                (let [app (ring/ring-handler
@@ -511,35 +510,34 @@
                            (ring/create-default-handler))
                      request #(request (str "/files" %))
                      redirect #(redirect (str "/files" %))]
-                 (testing test
-                   (testing "different file-types"
-                     (let [response (app (request "/hello.json"))]
-                       (is (= "application/json" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
-                     (let [response (app (request "/hello.xml"))]
-                       (is (= "text/xml" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
-
-                   (testing "index-files"
-                     (let [response (app (request "/docs"))]
-                       (is (= (redirect "/docs/index.html") response)))
-                     (let [response (app (request "/docs/"))]
-                       (is (= (redirect "/docs/index.html") response))))
-
-                   (testing "not found"
-                     (let [response (app (request "/not-found"))]
-                       (is (= 404 (:status response)))))
-
-                   (testing "3-arity"
-                     (let [result (atom nil)
-                           respond (partial reset! result)
-                           raise ::not-called]
-                       (app (request "/hello.xml") respond raise)
-                       (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
-                       (is (get-in @result [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result))))))))))
+                 (testing "different file-types"
+                   (let [response (app (request "/hello.json"))]
+                     (is (= "application/json" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
+                   (let [response (app (request "/hello.xml"))]
+                     (is (= "text/xml" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
+
+                 (testing "index-files"
+                   (let [response (app (request "/docs"))]
+                     (is (= (redirect "/docs/index.html") response)))
+                   (let [response (app (request "/docs/"))]
+                     (is (= (redirect "/docs/index.html") response))))
+
+                 (testing "not found"
+                   (let [response (app (request "/not-found"))]
+                     (is (= 404 (:status response)))))
+
+                 (testing "3-arity"
+                   (let [result (atom nil)
+                         respond (partial reset! result)
+                         raise ::not-called]
+                     (app (request "/hello.xml") respond raise)
+                     (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
+                     (is (get-in @result [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))

            (testing "outside a router"

@@ -549,36 +547,35 @@
                            (ring/routes
                              (create {:path "/" :not-found-handler (fn [x] {:status 404 :body "resource-handler"})})
                              (ring/create-default-handler)))]
-                 (testing test
-                   (testing "different file-types"
-                     (let [response (app (request "/hello.json"))]
-                       (is (= "application/json" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
-                     (let [response (app (request "/hello.xml"))]
-                       (is (= "text/xml" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
-
-                   (testing "index-files"
-                     (let [response (app (request "/docs"))]
-                       (is (= (redirect "/docs/index.html") response)))
-                     (let [response (app (request "/docs/"))]
-                       (is (= (redirect "/docs/index.html") response))))
-
-                   (testing "not found"
-                     (let [response (app (request "/not-found"))]
-                       (is (= 404 (:status response)))
-                       (is (= "resource-handler" (:body response)))))
-
-                   (testing "3-arity"
-                     (let [result (atom nil)
-                           respond (partial reset! result)
-                           raise ::not-called]
-                       (app (request "/hello.xml") respond raise)
-                       (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
-                       (is (get-in @result [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))
+                 (testing "different file-types"
+                   (let [response (app (request "/hello.json"))]
+                     (is (= "application/json" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
+                   (let [response (app (request "/hello.xml"))]
+                     (is (= "text/xml" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
+
+                 (testing "index-files"
+                   (let [response (app (request "/docs"))]
+                     (is (= (redirect "/docs/index.html") response)))
+                   (let [response (app (request "/docs/"))]
+                     (is (= (redirect "/docs/index.html") response))))
+
+                 (testing "not found"
+                   (let [response (app (request "/not-found"))]
+                     (is (= 404 (:status response)))
+                     (is (= "resource-handler" (:body response)))))
+
+                 (testing "3-arity"
+                   (let [result (atom nil)
+                         respond (partial reset! result)
+                         raise ::not-called]
+                     (app (request "/hello.xml") respond raise)
+                     (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
+                     (is (get-in @result [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result))))))))

              (testing "from path"
                (let [app (ring/ring-handler
@@ -588,39 +585,38 @@
                              (ring/create-default-handler)))
                      request #(request (str "/files" %))
                      redirect #(redirect (str "/files" %))]
-                 (testing test
-                   (testing "different file-types"
-                     (let [response (app (request "/hello.json"))]
-                       (is (= "application/json" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
-                     (let [response (app (request "/hello.xml"))]
-                       (is (= "text/xml" (get-in response [:headers "Content-Type"])))
-                       (is (get-in response [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
-
-                   (testing "index-files"
-                     (let [response (app (request "/docs"))]
-                       (is (= (redirect "/docs/index.html") response)))
-                     (let [response (app (request "/docs/"))]
-                       (is (= (redirect "/docs/index.html") response))))
-
-                   (testing "not found"
-                     (let [response (app {:uri "/not-found" :request-method :get})]
-                       (is (= 404 (:status response)))
-                       (is (= "" (:body response))))
-                     (let [response (app {:uri "/files/not-found" :request-method :get})]
-                       (is (= 404 (:status response)))
-                       (is (= "resource-handler" (:body response)))))
-
-                   (testing "3-arity"
-                     (let [result (atom nil)
-                           respond (partial reset! result)
-                           raise ::not-called]
-                       (app (request "/hello.xml") respond raise)
-                       (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
-                       (is (get-in @result [:headers "Last-Modified"]))
-                       (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result)))))))))))))))
+                 (testing "different file-types"
+                   (let [response (app (request "/hello.json"))]
+                     (is (= "application/json" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
+                   (let [response (app (request "/hello.xml"))]
+                     (is (= "text/xml" (get-in response [:headers "Content-Type"])))
+                     (is (get-in response [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body response))))))
+
+                 (testing "index-files"
+                   (let [response (app (request "/docs"))]
+                     (is (= (redirect "/docs/index.html") response)))
+                   (let [response (app (request "/docs/"))]
+                     (is (= (redirect "/docs/index.html") response))))
+
+                 (testing "not found"
+                   (let [response (app {:uri "/not-found" :request-method :get})]
+                     (is (= 404 (:status response)))
+                     (is (= "" (:body response))))
+                   (let [response (app {:uri "/files/not-found" :request-method :get})]
+                     (is (= 404 (:status response)))
+                     (is (= "resource-handler" (:body response)))))
+
+                 (testing "3-arity"
+                   (let [result (atom nil)
+                         respond (partial reset! result)
+                         raise ::not-called]
+                     (app (request "/hello.xml") respond raise)
+                     (is (= "text/xml" (get-in @result [:headers "Content-Type"])))
+                     (is (get-in @result [:headers "Last-Modified"]))
+                     (is (= "<xml><hello>file</hello></xml>\n" (slurp (:body @result))))))))))))))

 (deftest router-available-in-default-branch
   (testing "1-arity"


Fix brittle test dependent on query param order

Key order in a hash-map is indeterminate

--- test/http/async/client/test.clj
+++ test/http/async/client/test.clj
@@ -809,9 +809,11 @@

 (deftest response-url
   (let [resp (GET *client* "http://localhost:8123/query" :query {:a "1?&" :b "+ ="})]
-    (are [exp real] (= exp real)
-         "http://localhost:8123/query?a=1?&&b=+ =" (raw-url resp)
-         "http://localhost:8123/query?a=1%3F%26&b=%2B%20%3D" (url resp))))
+    (are [exp real] (exp real)
+      #{"http://localhost:8123/query?a=1?&&b=+ =" "http://localhost:8123/query?b=+ =&a=1?&"}
+      (raw-url resp)
+      #{"http://localhost:8123/query?a=1%3F%26&b=%2B%20%3D" "http://localhost:8123/query?b=%2B%20%3D&a=1%3F%26"}
+      (url resp))))

 ;;(deftest profile-get-stream
 ;;  (let [gets (repeat (GET *client* "http://localhost:8123/stream"))


Cap revocation for e2e tests

Cap revocation for e2e tests

--- test/icecap/e2e/common.clj
+++ test/icecap/e2e/common.clj
@@ -27,3 +27,8 @@
   "Executes the capability with the given URL."
   [cap-url]
   (get cap-url))
+
+(defn revoke-cap
+  "Revokes the capability with the given URL."
+  [cap-url]
+  (delete cap-url))


Fix comment test

Fix comment test

--- test/jest/comment_test.clj
+++ test/jest/comment_test.clj
@@ -4,45 +4,53 @@

 (deftest comment-test-1
+  (test-code-eval
   "// COMMENT
-  10"
+  10;"
   ["10"]
-  10)
+  10))

 (deftest comment-test-2
+  (test-code-eval
   "/* COMMENT
   OTHER COMMENTS
   */
-  10"
+  10;"
   ["10"]
-  10)
+  10))
+

 (deftest comment-test-3
+  (test-code-eval
   "/*
   COMMENT
   OTHER COMMENTS
   STUFF */
-  10"
+  10;"
   ["10"]
-  10)
+  10))
+

 (deftest comment-test-4
+  (test-code-eval
   "10
   /*
   COMMENT
   OTHER COMMENTS
   STUFF */
-  "
+  ;"
   ["10"]
-  10)
+  10))
+

 (deftest comment-test-5
-  "10
+  (test-code-eval
+  "10;
   /* /*
   // COMMENT
   OTHER COMMENTS
   STUFF */
   "
   ["10"]
-  10)
+  10))


Fixed issue where test utils mock-kafka override wasn’t using log-dir parameter

--- test/onyx/plugin/test_utils.clj
+++ test/onyx/plugin/test_utils.clj
@@ -45,7 +45,7 @@
   ([topic zookeeper xs]
    (mock-kafka topic zookeeper xs (str "/tmp/embedded-kafka" (java.util.UUID/randomUUID))))
   ([topic zookeeper xs log-dir]
-   (mock-kafka topic zookeeper xs (str "/tmp/embedded-kafka" (java.util.UUID/randomUUID)) true))
+   (mock-kafka topic zookeeper xs log-dir true))
   ([topic zookeeper xs log-dir embedded-kafka?]
    (let [kafka-server (component/start
                        (ke/embedded-kafka {:advertised.host.name "127.0.0.1"


doc edit

doc edit

--- sidecar/src/figwheel_sidecar/repl_api.clj
+++ sidecar/src/figwheel_sidecar/repl_api.clj
@@ -4,8 +4,8 @@
    [figwheel-sidecar.config :as fc]))

 (defn start-figwheel!
-  "If you aren't connected to an env where fighweel is running already.
-  You this method will start the figwheel server with the passed build info."
+  "If you aren't connected to an env where fighweel is running already,
+  this method will start the figwheel server with the passed in build info."
   [{:keys [figwheel-options all-builds build-ids] :as autobuild-options}]
   (if-not fr/*autobuild-env*
     (let [env (fr/create-autobuild-env


Simplifying

Simplifying

--- jvm-runner/project.clj
+++ jvm-runner/project.clj
@@ -5,29 +5,14 @@
   :dependencies
   [[org.clojure/clojure "1.6.0"]
    [cheshire "5.3.1"] ; JSON
-   [korma "0.3.0"]    ; ORM
-   [com.h2database/h2 "1.3.170"] ; In Memory Database
-   [org.xerial/sqlite-jdbc "3.7.15-M1"] ; SQLite
-   [com.novemberain/monger "2.0.0"] ; Monger
-   [com.taoensso/carmine "2.7.0" :exclusions [org.clojure/clojure]] ; Carmine
-   [org.clojure/core.async "0.1.346.0-17112a-alpha"] ; Go-Routines
-   [org.clojure/test.check "0.5.9"] ; Generative Testing
-   [prismatic/schema "0.2.6"] ; Schema Verification
-   [instaparse "1.3.4"] ; BNF Parsers
-   [org.clojure/core.logic "0.8.8"] ; Logic Programming
-   [org.clojure/core.match "0.2.1"] ; Pattern Matching
-   [prismatic/plumbing "0.3.3"] ; Random Awesomeness
-   [clj-http "1.0.0"] ; HTTP Client
-   [enlive "1.1.5"] ; HTML templating
-   [hiccup "1.0.5"] ; Clojure HTML DSL
+   [org.clojure/core.async "0.1.346.0-17112a-alpha"] ; Go-like Threads
    [junit/junit "4.11"] ; JUnit
    [org.codehaus.groovy/groovy-all "2.3.6"] ; Groovy
    [environ "0.5.0"] ; Environment Variables
    [org.zeromq/jeromq "0.3.3"] ; ZMQ
    [org.zeromq/cljzmq "0.1.4" :exclusions [org.zeromq/jzmq]]
    ]
-  :ring {:handler codewars.rest.handler/app}
-  :plugins [[lein-environ "0.5.0"] [lein-ring "0.8.12"]]
+  :plugins [[lein-environ "0.5.0"]]
   :source-paths ["src/clojure"]
   :java-source-paths ["src/java"]
   :env {:timeout "10000"


Remove beta-availibable LD flag

Remove beta-availibable LD flag

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -445,9 +445,8 @@
              [:a {:href (routes/v1-account-subpage {:subpage "heroku"})} "Heroku Key"]]
             [:li#plans (active-class-if-active subpage :plans)
              [:a {:href (routes/v1-account-subpage {:subpage "plans"})} "Plan Pricing"]]
-            (when (feature/enabled? :beta-program-available)
-              [:li#beta (active-class-if-active subpage :beta)
-               [:a {:href (routes/v1-account-subpage {:subpage "beta"})} "Beta Program"]])]]
+            [:li#beta (active-class-if-active subpage :beta)
+             [:a {:href (routes/v1-account-subpage {:subpage "beta"})} "Beta Program"]]]]

           [:div.row (om/build common/flashes (get-in app state/error-message-path))]
           [:div.settings-item


uppercase "or" in secondary make button

uppercase "or" in secondary make button

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -184,7 +184,7 @@
                             (cast! :make-button-clicked))
            :on-mouse-enter #(om/set-state! owner :word-list (shuffle word-list))}
           [:div.make-prepend
-           {:data-before "or "}
+           {:data-before "Or "}
            "Make "]
           [:div.make-something
            [:div.something-default (when widths


add imgs back to mobile feature artwork

add imgs back to mobile feature artwork

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -200,25 +200,24 @@
        [:div.art-heading "Today"]
        [:div.art-doc
         [:div.art-doc-frame
-         ; [:img.art-doc-img {:src "https://prcrsr.com/document/17592196129062.svg"}]
-         ]]
+         [:img.art-doc-img
+          {:src "https://prcrsr.com/document/17592196129062.svg"}]]]
        [:div.art-doc.selected
         [:div.art-doc-frame
-         ; [:img.art-doc-img {:src "https://prcrsr.com/document/17592196129062.svg"}]
-         ]]
+         [:img.art-doc-img
+          {:src "https://prcrsr.com/document/17592196129062.svg"}]]]
        [:div.art-doc
         [:div.art-doc-frame
-         ; [:img.art-doc-img {:src "https://prcrsr.com/document/17592196129062.svg"}]
-         ]]
+         [:img.art-doc-img
+          {:src "https://prcrsr.com/document/17592196129062.svg"}]]]
        [:div.art-doc
         [:div.art-doc-frame
-         ; [:img.art-doc-img {:src "https://prcrsr.com/document/17592196129062.svg"}]
-         ]]]
+         [:img.art-doc-img
+          {:src "https://prcrsr.com/document/17592196129062.svg"}]]]]
       [:div.art-canvas
        [:div.art-doc-frame
         [:img.art-doc-img
-         ; {:src "https://prcrsr.com/document/17592196129062.svg"}
-         ]]]
+         {:src "https://prcrsr.com/document/17592196129062.svg"}]]]
       [:div.art-screen-select]]]
     [:div.art-mobile-foot
      [:div.art-mobile-button]]]])


Made a replace of newlines with br

Made a replace of newlines with br

--- src/ardoq/swagger/swagger_v2.clj
+++ src/ardoq/swagger/swagger_v2.clj
@@ -199,9 +199,13 @@
 (defn generate-security-description[data]
   (tpl/render-resource "securityTemplate.tpl" data))

+(defn replace-newlines [schema]
+  (replace schema #"\n" "<br>"))
+
 (defn create-param-model [wid _id parameters description model]
   (reduce
    (fn [acc [param schema]]
+     (replace-newlines schema)
      (assoc acc (keyword param)
             (assoc
              (api/->Component param (generate-param-description schema) (str wid) _id (api/type-id-by-name model "Parameters") nil)


create all needed rabbitmq structures in fsworker

fsworker may be started without esconnect already running. we would
loose messages in that case. so, we create everything needed in
fsworker.

we don't do this in manage, because manage doesn't know a thing about
the filesystems being synchronized. we might choose to route messages
along different queues.

--- src/brainbot/nozzle/fsworker.clj
+++ src/brainbot/nozzle/fsworker.clj
@@ -5,6 +5,7 @@
             [brainbot.nozzle.inihelper :as inihelper]
             [brainbot.nozzle.dynaload :as dynaload]
             [brainbot.nozzle.worker :as worker]
+            [brainbot.nozzle.routing-key :as rk]
             [brainbot.nozzle.sys :as sys])
   (:require [langohr.basic :as lb]
             [langohr.shutdown :as lshutdown]
@@ -88,17 +89,27 @@
   {"listdir" simple-listdir
    "get_permissions" simple-get_permissions})

+(let [all-commands ["listdir" "get_permissions" "update_directory" "import_file" "extract_content"]]
+  (defn- init-all-rmq-structures
+    "create all needed rabbitmq structures for the given filesystems"
+    [ch rmq-prefix filesystems]
+    (doseq [fs filesystems
+            c all-commands]
+      (mqhelper/initialize-rabbitmq-structures ch c rmq-prefix fs))))

 (defn build-handle-connection
   [filesystems rmq-prefix]
   (fn [conn]
     (logging/info "initializing connection")
+    (let [ch (lch/open conn)]
+      (init-all-rmq-structures ch rmq-prefix (map :fsid filesystems))
+      (lch/close ch))
     (doseq [{:keys [fsid] :as fs} filesystems
             [command handle-msg] (seq command->msg-handler)]
       (mqhelper/channel-loop
        conn
        (fn [ch]
-         (let [qname (mqhelper/initialize-rabbitmq-structures ch command rmq-prefix fsid)]
+         (let [qname (rk/routing-key-string rmq-prefix fsid command)]
            (logging/info "starting consumer for" qname)
            (lb/qos ch 1)
            (lcons/subscribe ch qname (mqhelper/make-handler (partial handle-msg fs)))))))))


Fix wrap-edn-body middleware

Fix wrap-edn-body middleware

The condition of when to turn :edn-body into :body was wrong...

--- src/clj/comic_reader/web_app.clj
+++ src/clj/comic_reader/web_app.clj
@@ -15,7 +15,7 @@
 (defn- wrap-edn-body [handler]
   (fn [request]
     (let [response (handler request)]
-      (if (and (nil? (:body response))
+      (if (and (nil? (seq (:body response)))
                (:edn-body response))
         (-> response
             (assoc :body (pr-str (:edn-body response)))


fire at Corp turn start too

fire at Corp turn start too

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -321,7 +321,10 @@
                                                            :effect (effect (gain :credit 1))} card nil)))))
     :events {:runner-turn-begins {:req (req (= (:credit runner) 0)) :msg "gain 1 [Credits]"
                                   :effect (req (gain state :runner :credit 1)
-                                               (swap! state assoc-in [:per-turn (:cid card)] true))}}
+                                               (swap! state assoc-in [:per-turn (:cid card)] true))}
+             :corp-turn-begins {:req (req (= (:credit runner) 0)) :msg "gain 1 [Credits]"
+                                :effect (req (gain state :runner :credit 1)
+                                             (swap! state assoc-in [:per-turn (:cid card)] true))}}
     :leave-play (req (remove-watch state :order-of-sol))}

    "Paige Piper"


Street Peddler takes Kate discount into consideration.

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -526,7 +526,7 @@
                    (host state side (get-card state card) c {:facedown true})))
     :abilities [{:prompt "Choose a card on Street Peddler to install"
                  :choices (req (filter #(and (not= (:type %) "Event")
-                                             (<= (:cost %) (inc (:credit runner))))
+                                             (can-pay? state side (modified-install-cost state side % [:credit -1])))
                                        (:hosted card)))
                  :msg (msg "install " (:title target) " lowering its install cost by 1 [Credits]")
                  :effect (effect


proper user url

proper user url

--- src/clj/hsm/controllers/user.clj
+++ src/clj/hsm/controllers/user.clj
@@ -100,7 +100,7 @@
           (layout {:website host :title (format "%s - %s " (:login user) (:name user))}
             [:div.row
                   [:div.col-lg-3
-                    (left-menu host platform "open-source")]
+                    (left-menu host platform (str "/user2/" id))]
                   [:div.col-lg-9
                     [:div.row
                       [:div.col-lg-4


Re-add exit/quit to default-init

Re-add exit/quit to default-init

--- src/clj/reply/initialization.clj
+++ src/clj/reply/initialization.clj
@@ -34,7 +34,9 @@
 (defn export-definition [s]
   (read-string (clojure.repl/source-fn s)))

-(defn default-init-code []
+(defn default-init-code
+  "Assumes cd-client will be on the classpath when this is evaluated."
+  []
   `(do
     (println "Welcome to REPL-y!")
     (println "Clojure" (clojure-version))
@@ -43,16 +45,20 @@
     (use '[clojure.pprint :only ~'[pp pprint]])

     ~(export-definition 'reply.initialization/help)
+    ~(export-definition 'reply.main/exit)
+    (def ~'quit ~'exit)

     (ns reply.exports)
     ~(export-definition 'reply.initialization/intern-with-meta)

+    (~'intern-with-meta '~'user '~'quit #'user/exit)
+
     (binding [*err* (java.io.StringWriter.)]
       ~(export-definition 'reply.initialization/repl-defn)
-      (~'intern-with-meta '~'user '~'defn #'repl-defn))
+      (~'intern-with-meta '~'user '~'defn ~'#'repl-defn))

     ~(export-definition 'reply.initialization/sourcery)
-    (~'intern-with-meta '~'user '~'sourcery #'sourcery)
+    (~'intern-with-meta '~'user '~'sourcery ~'#'sourcery)

     (in-ns '~'user)

@@ -60,7 +66,7 @@
     (require '[cd-client.core])
     (~'reply.exports/intern-with-meta '~'user '~'clojuredocs #'cd-client.core/pr-examples)

-    (help)
+    (~'help)
     nil))

 (defn eval-in-user-ns [code]


Autom. load voting page when v.opened

Autom. load voting page when v.opened

--- src/clj_gamification/handler.clj
+++ src/clj_gamification/handler.clj
@@ -161,6 +161,7 @@

 (defn page-await-vote [referer]
   (page "Awaiting voting..."
+        (include-changepoll-js :state)
         [:p "Do "
          [:a {:href "/"} "vote for the best idea"]
          " once voting is opened"]
@@ -233,7 +234,7 @@
       conj
       (fn [change-events]
         (let [new-events (new-events-filtered change-events last-event-id desired-events)]
-          (info (str "Notifying about new events;evts" new-events ",for lastId " last-event-id " and filter " (vec desired-events) "; all evts " change-events)) ;; TODO remove this log
+          (info (str "Notifying about new events;evts" new-events ",for lastId " last-event-id " and filter " (vec desired-events) "; las 10 evts " (take-last 10 change-events))) ;; TODO remove this log
          ;; check if match any of the desired ones, send them if true
           (if (seq new-events)
             (do
@@ -294,8 +295,8 @@
                 :status 201
                 :body (page "Voted" [:p "Thank you for voting for team " teamid "!"])})))
      (GET "/await-vote" [:as req]
-          (if (= :voting state)
-            (redirect "/vote")
+          (if (= :voting @state)
+            (redirect "/")
             (page-await-vote (get-in req [:headers "referer"]))))
      (GET "/vote" [] "Sorry, you can only POST to this page")
      (GET "/vote-results" [] (page-vote-results @teams @votes))
@@ -339,8 +340,8 @@
                              :voter-ips (atom #{})
                              :projector (atom :prestart)}
                             defaults)]
-               (add-watch (:projector result) :projector notify-change-listeners)
-               (add-watch (:teams result) :teams notify-change-listeners)
+               (doseq [[key atom] result :when (not (#{:session-atom :team-counter} key))]
+                 (add-watch atom key notify-change-listeners))
                result))

 (defn reset-state
@@ -356,7 +357,7 @@
   (reset! (:projector system) :prestart)
   (reset! (:session-atom system) {}))

-(def current-system-for-repl "Reference to the latest system created to have access to it from the REPL; don't use anywhere else" (atom nil))
+(defonce ^{:doc "Reference to the latest system created to have access to it from the REPL; don't use anywhere else"} current-system-for-repl (atom nil))

 (defn init
   "Init the current system, optionally with a default system, returning a Ring handler"
@@ -374,7 +375,7 @@
 ;; TIME USED: (time-in-hrs + 3.5 1.5 1 + 1) + (5h lørdag, 1t søndag)
 ;; incl.: learning and setting up heroku (1h), learning/troubleshooting (2+h)

-(def ^{:static true} server-stop-fn (atom nil))
+(defonce ^{:static true} server-stop-fn (atom nil))

 (defn -main [port] ;; entry point
   (let [port (Integer/parseInt port)
@@ -385,5 +386,4 @@
 (comment ;; for use in REPL
   (-main "5000")
   @current-system-for-repl
-  @tmp-sess-atm
   )


on empty line-suffix, don't get completions

--- src/cljs/snapshot/lumo/repl.cljs
+++ src/cljs/snapshot/lumo/repl.cljs
@@ -1445,12 +1445,14 @@
           ns-alias (second (re-find #"\(*(\b[a-zA-Z-.<>*=&?]+)/[a-zA-Z-]*$" line))
           line-match-suffix (first (re-find #":?([a-zA-Z-.<>*=&?]*|^\(/)$" line))
           line-prefix (subs line 0 (- (count line) (count line-match-suffix)))
-          completions (reduce (fn [ret item]
-                                (doto ret
-                                  (.push (str line-prefix item))))
+          completions (if (empty? line-match-suffix)
                         #js []
-                        (filter #(is-completion? line-match-suffix %)
-                          (completion-candidates top-level? ns-alias)))]
+                       (reduce (fn [ret item]
+                                  (doto ret
+                                    (.push (str line-prefix item))))
+                                #js []
+                                (filter #(is-completion? line-match-suffix %)
+                                        (completion-candidates top-level? ns-alias))))]
       (cb (doto completions
             .sort)))))


thomsky: Throw out update checking

thomsky: Throw out update checking

It doesn't work. Dave Dixon's bind doesn't work. See my comment on
https://gist.github.com/allgress/11348685 for what's wrong. Solve it the
easy way by querying the whole database instead of the transaction data.
This probably makes it slower, but everything else would be too
time-consuming to implement right now.

--- src/cljs/theatralia/thomsky.cljs
+++ src/cljs/theatralia/thomsky.cljs
@@ -7,19 +7,6 @@
             [re-frame.middleware :as middleware]
             [plumbing.core :refer [safe-get]]
             [reagent.core :as reagent]))
-
-(defn- single-valued?
-  "See http://docs.datomic.com/query.html#find-specifications and
-  http://docs.datomic.com/query.html#query."
-  [query]
-  (let [find-part (if (map? query)
-                    (safe-get query :find)
-                    (do
-                      (assert (= :find (first query)))
-                      (take-while #(not (keyword? %)) (rest query))))]
-    (or (and (vector? (first find-part))   ; single tuple
-             (not= '... (last (first find-part))))
-        (= '. (last find-part)))))         ; single scalar

 (defn set-up-datascript!
   "Swaps in a Datascript database with schema ?SCHEMA (default: Datascript
@@ -63,14 +50,11 @@
         state (reagent/atom nil)
         res (apply d/q q @conn q-args)]
     (reset! state res)
-    (d/listen!
-      conn
-      k
-      (fn [tx-report]
-        (let [novelty (apply d/q q (:tx-data tx-report) q-args)]
-          ;; Only update if query results actually changed.
-          (when (not-empty novelty)
-            (reset! state (apply d/q q (:db-after tx-report) q-args))))))
+    (d/listen! conn k
+               (fn [tx-report]
+                 (let [new-result (apply d/q q (:db-after tx-report) q-args)]
+                   (when (not= new-result @state)
+                     (reset! state new-result)))))
     (set! (.-__key state) k)
     state))


think about store local file features

think about store local file features

--- src/codeitlater/store_record.clj
+++ src/codeitlater/store_record.clj
@@ -1,3 +1,4 @@
+;;; this feature is not necessary, if need update manually everytime, why need this feature.
 (ns codeitlater.store-record
   )

@@ -8,4 +9,3 @@
 (defn read-from [path]
   "read lst back from local file")

-


Fixing error in workload when anding conditions.

--- search-app/src/cmr/search/services/acls/granule_acls.clj
+++ search-app/src/cmr/search/services/acls/granule_acls.clj
@@ -167,7 +167,7 @@
     (let [access-value-cond (some-> access-value access-value->query-condition)
           temporal-cond (some-> temporal temporal->query-condition)]
       (if (and access-value-cond temporal-cond)
-        (gc/and-conds access-value-cond temporal-cond)
+        (gc/and-conds [access-value-cond temporal-cond])
         (or access-value-cond temporal-cond)))))

 (defn acl->query-condition


Cljs client lib versions update

Cljs client lib versions update

--- client-cljs/project.clj
+++ client-cljs/project.clj
@@ -1,10 +1,11 @@
 (defproject client-cljs "0.1.0-SNAPSHOT"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure "1.5.1"]
-                 [org.clojure/clojurescript "0.0-2173"]
+  :dependencies [[org.clojure/clojure "1.7.0-alpha4"]
+                 [org.clojure/clojurescript "0.0-2371"]
+                 [jarohen/chord "0.4.2"]
                  [reagent "0.4.2"]
-                 [jayq "2.5.0"]]
+                 [jayq "2.5.2"]]

   :cljsbuild {
     :builds [{


Add dieter assets to page layout.

Add dieter assets to page layout.

--- src/incise/layouts/impl/page.clj
+++ src/incise/layouts/impl/page.clj
@@ -5,16 +5,19 @@
             (hiccup [page :refer :all]
                     [core :refer :all])))

-(defn page [{:keys [site-title]}
-            ^incise.parsers.core.Parse {:keys [title content]}]
+(defn page
+  "The default page/post layout."
+  [{:keys [site-title]}
+   ^incise.parsers.core.Parse {:keys [title content]}]
   (html5
     [:head
      [:title (str site-title (when title (str " - " title)))]
      [:meta {:name "viewport"
              :content "width=device-width, initial-scale=1.0"}]
-     (link-to-asset "stylesheets/app.css.dieter")]
+     (include-css (link-to-asset "stylesheets/app.css.dieter"))]
     [:body#page content
-     (link-to-asset "javascripts/app.js.dieter")]))
+     (include-js "http://code.jquery.com/jquery-2.0.3.min.js"
+                 (link-to-asset "javascripts/app.js.dieter"))]))

 (register :page page)
 (register :post page)


Add some debug logging to identify how request is matched to a resource handler function

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -40,7 +40,9 @@
             [clojure.set :as set]
             [io.aviso.tracker :as t]
             [io.aviso.rook.internals :as internals]
-            [clojure.string :as str]))
+            [clojure.string :as str]
+            [clojure.tools.logging :as l]
+            [io.aviso.rook.utils :as utils]))

 (def ^:private default-mappings

@@ -544,8 +546,15 @@
                                                            (-> request
                                                                (update-in [:context] str context)
                                                                middleware-applied))
-                                                         middleware-applied)]
-                       (add-dispatch-entries dispatch-map method pathvec context-maintaining-handler))))
+                                                         middleware-applied)
+
+                           logging-handler (fn [request]
+                                             (l/debugf "Matched %s to %s"
+                                                       (utils/summarize-request request)
+                                                       verb-fn-sym)
+                                             (context-maintaining-handler request))]
+
+                       (add-dispatch-entries dispatch-map method pathvec logging-handler))))
     {}
     routes))


Removes reflection from consume-request-stream (#269)

--- waiter/src/waiter/main.clj
+++ waiter/src/waiter/main.clj
@@ -50,7 +50,7 @@
   (fn [{:keys [body] :as request}]
     (let [resp (handler request)]
       (if (and (instance? ServletInputStream body)
-               (not (.isFinished body))
+               (not (.isFinished ^ServletInputStream body))
                (not (instance? ManyToManyChannel resp)))
         (try
           (slurp body)


Snapshot

Snapshot

--- src/net/sekao/nightcode/core.clj
+++ src/net/sekao/nightcode/core.clj
@@ -37,7 +37,7 @@
         content (.lookup scene "#content")]
     (swap! runtime-state assoc :stage stage)
     (doto stage
-      (.setTitle "Nightcode 2.0.0-alpha2")
+      (.setTitle "Nightcode 2.0.0-SNAPSHOT")
       (.setScene scene)
       (.show))
     (shortcuts/init-tabs! scene)


create orbiting planets

create orbiting planets


reset import results text on upload click

--- src/cljs/org/broadinstitute/firecloud_ui/page/import_data.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/import_data.cljs
@@ -21,6 +21,7 @@

 (defn- submit-entities [state workspaceName workspaceNamespace entityFile]
+  (swap! state assoc :message "")
   (utils/ajax-orch
     (str "/workspaces/" workspaceNamespace "/" workspaceName "/importEntities")
     {:method :post