fix typos, capitalization, singular/plural errors

Adding consistency
* uniform capitalization of Runner, Corp, Grip, Stack, etc
* space between an amount and [Credits]

Made a few small wording changes in messages to match card abilities, some several singular/plural corrections, a few subject/verb agreement corrections, and inserted some missing words.

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -47,7 +47,7 @@

    "Aggressive Secretary"
    {:advanceable :always
-    :access {:optional {:req (req installed) :prompt "Pay 2[Credits] to use Aggresive Secretary ability?"
+    :access {:optional {:req (req installed) :prompt "Pay 2 [Credits] to use Aggressive Secretary ability?"
                         :cost [:credit 2] :msg (msg "trash " (:advance-counter card) " programs")}}}

    "Akamatsu Mem Chip"
@@ -96,7 +96,7 @@
    "Argus Security: Protection Guaranteed"
    {:events {:agenda-stolen
              {:prompt "Take 1 tag or suffer 2 meat damage?"
-              :choices ["1 tag" "2 meat damages"] :player :runner
+              :choices ["1 tag" "2 meat damage"] :player :runner
               :msg "make the Runner take 1 tag or suffer 2 meat damage"
               :effect (req (if (= target "1 tag")
                              (do (gain state :runner :tag 1) (system-msg state side "takes 1 tag"))
@@ -202,7 +202,7 @@
    "Cerebral Overwriter"
    {:advanceable :always
     :access {:optional {:req (req installed)
-                        :prompt "Pay 3[Credits] to use Cerebral Overwriter ability?"
+                        :prompt "Pay 3 [Credits] to use Cerebral Overwriter ability?"
                         :cost [:credit 3] :msg (msg "do " (:advance-counter card) " brain damage")
                         :effect (effect (damage :brain (:advance-counter card)))}}}

@@ -276,7 +276,7 @@

    "Crash Space"
    {:recurring 2
-    :abilities [{:msg "prevent 3 meat damages" :effect (effect (trash card))}]}
+    :abilities [{:msg "prevent 3 meat damage" :effect (effect (trash card))}]}

    "Cybsoft MacroDrive"
    {:recurring 1}
@@ -336,7 +336,7 @@
    {:additional-cost [:click 3] :effect (effect (gain :credit 10))}

    "Dedicated Response Team"
-   {:events {:successful-run-ends {:req (req tagged) :msg "do 2 meat damages"
+   {:events {:successful-run-ends {:req (req tagged) :msg "do 2 meat damage"
                                    :effect (effect (damage :meat 2))}}}

    "Dedicated Server"
@@ -376,7 +376,7 @@
                                            :effect (effect (gain :credit 5))}} card))}

    "Djinn"
-   {:abilities [{:prompt "Choose an Virus" :msg (msg "adds " (:title target) "to his grip")
+   {:abilities [{:prompt "Choose a Virus" :msg (msg "adds " (:title target) "to his Grip")
                  :choices (req (filter #(has? % :subtype "Virus") (:deck runner)))
                  :cost [:click 1 :credit 1] :effect (effect (move target :hand) (shuffle! :deck))}]}

@@ -403,7 +403,7 @@
                                                  :effect (effect (run target))} card targets))}}}}

    "Duggars"
-   {:abilities [{:cost [:click 4] :effect (effect (draw 10)) :msg "draw 10 card"}]}
+   {:abilities [{:cost [:click 4] :effect (effect (draw 10)) :msg "draw 10 cards"}]}

    "Dyson Fractal Generator"
    {:recurring 1}
@@ -429,7 +429,7 @@
    "Edge of World"
    {:access {:optional
              {:req (req installed) :cost [:credit 3]
-              :prompt "Pay 3[Credits] to use Edge of World ability?"
+              :prompt "Pay 3 [Credits] to use Edge of World ability?"
               :msg (msg "do " (count (get-in corp [:servers :remote (last (:server run)) :ices]))
                         " brain damage")
               :effect (req (damage state side :brain
@@ -484,7 +484,7 @@

    "Expert Schedule Analyzer"
    {:abilities
-    [{:cost [:click 1] :msg "make run on HQ"
+    [{:cost [:click 1] :msg "make a run on HQ"
       :effect (effect (run :hq {:replace-access
                                 {:msg (msg "reveal cards in HQ: " (map :title (:hand corp)))}} card))}]}

@@ -506,12 +506,12 @@
                 {:effect (effect (trash card)) :msg "prevent 2 brain damage"}]}

    "Fetal AI"
-   {:access {:req (req (not= (first (:zone card)) :discard)) :msg "do 2 net damages"
+   {:access {:req (req (not= (first (:zone card)) :discard)) :msg "do 2 net damage"
              :effect (effect (damage :net 2))}
     :steal-cost [:credit 2]}

    "Fester"
-   {:events {:purge {:msg "force the corp to lose 2 [Credits] if able"
+   {:events {:purge {:msg "force the Corp to lose 2 [Credits] if able"
                      :effect (effect (pay :corp card :credit 2))}}}

    "Firmware Updates"
@@ -580,7 +580,7 @@
    {:events {:runner-turn-ends
              {:effect #(let [ab (if (get-in @%1 [:runner :register :successful-run])
                                   {:effect (effect (gain [:credit 1])) :msg "gain 1 [Credits]"}
-                                  {:effect (effect (trash %3)) :msg "trash Gifter"})]
+                                  {:effect (effect (trash %3)) :msg "trash Grifter"})]
                          (resolve-ability %1 %2 ab %3 nil))}}}

    "Grimoire"
@@ -671,10 +671,10 @@
    "Iain Stirling: Retired Spook"
    {:effect (effect (gain :link 1))
     :events {:runner-turn-begins {:req (req (> (:agenda-point corp) (:agenda-point runner)))
-                                  :msg "to gain 2[Credits]" :effect (effect (gain :credit 2))}}}
+                                  :msg "to gain 2 [Credits]" :effect (effect (gain :credit 2))}}}

    "Ice Analyzer"
-   {:events {:rez {:req (req (= (:type target) "ICE")) :msg "place 1 [Credits] on ICE Analyzer"
+   {:events {:rez {:req (req (= (:type target) "ICE")) :msg "place 1 [Credits] on Ice Analyzer"
                    :effect (effect (add-prop card :counter 1))}}
     :abilities [{:counter-cost 1 :effect (effect (gain :credit 1))
                  :msg "take 1 [Credits] to install programs"}]}
@@ -768,7 +768,7 @@
                           :msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}}}

    "Keyhole"
-   {:abilities [{:cost [:click 1] :msg "make run on R&D"
+   {:abilities [{:cost [:click 1] :msg "make a run on R&D"
                  :effect (effect (run :rd
                                    {:replace-access
                                     {:prompt "Choose a card to trash" :not-distinct true
@@ -892,7 +892,7 @@

    "Monolith"
    {:effect (effect (gain :memory 3)) :leave-play (effect (lose :memory 3))
-    :abilities [{:msg (msg "prevent 1 damage by trashing " (:title target))
+    :abilities [{:msg (msg "prevent 1 brain or net damage by trashing " (:title target))
                  :choices (req (filter #(= (:type %) "Program") (:hand runner)))
                  :prompt "Choose a program to trash" :effect (effect (trash target))}]}

@@ -940,7 +940,7 @@

    "Networking"
    {:effect (effect (lose :tag 1))
-    :optional {:cost [:credit 1] :prompt "Pay 1[Credits] to add Networking to Grip?"
+    :optional {:cost [:credit 1] :prompt "Pay 1 [Credits] to add Networking to Grip?"
                :msg "add it to his Grip" :effect (effect (move (first (:discard runner)) :hand))}}

    "Neural EMP"
@@ -973,7 +973,7 @@
                             (system-msg %1 %2 (str "uses Oracle May, names " (first %4)
                                                    " and reveals " (:title c)))
                             (if (= (:type c) (first %4))
-                              (do (system-msg %1 %2 (str "gains 2 [Credits] and draw " (:title c)))
+                              (do (system-msg %1 %2 (str "gains 2 [Credits] and draws " (:title c)))
                                   (gain %1 %2 :credit 2) (draw %1 %2))
                               (do (system-msg %1 %2 (str "trashes " (:title c))) (mill %1 %2))))}]}

@@ -1033,7 +1033,7 @@
                                   0 (flatten (seq (:servers corp))))))}

    "Philotic Entanglement"
-   {:msg (msg "do " (count (:scored runner)) " net damages")
+   {:msg (msg "do " (count (:scored runner)) " net damage")
     :effect (effect (damage :net (count (:scored runner))))}

    "Plan B"
@@ -1083,7 +1083,7 @@

    "Project Junebug"
    {:advanceable :always
-    :access {:optional {:prompt "Pay 1[Credits] to use Project Junebug ability?" :cost [:credit 1]
+    :access {:optional {:prompt "Pay 1 [Credits] to use Project Junebug ability?" :cost [:credit 1]
                         :req (req installed) :msg (msg "do " (* 2 (:advance-counter card)) " net damage")
                         :effect (effect (damage :net (* 2 (:advance-counter card))))}}}

@@ -1124,7 +1124,7 @@
                  :msg "gain 1 [Credits] and draw 1 card"}]}

    "Punitive Counterstrike"
-   {:trace {:base 5 :msg (msg "do " (:stole-agenda runner-reg) " meat damages")
+   {:trace {:base 5 :msg (msg "do " (:stole-agenda runner-reg) " meat damage")
             :effect (effect (damage :meat (get-in runner [:register :stole-agenda])))}}

    "Q-Coherence Chip"
@@ -1186,8 +1186,8 @@
     :effect (effect (gain :max-hand-size 2)) :leave-play (effect (lose :max-hand-size 2))}

    "Restoring Face"
-   {:prompt "Choose a sysops, executive or clone to trash"
-    :msg (msg "trash " (:title target) " to remove 2 bad publicities")
+   {:prompt "Choose a Sysop, Executive or Clone to trash"
+    :msg (msg "trash " (:title target) " to remove 2 bad publicity")
     :choices (req (filter #(and (:rezzed %)
                                 (or (has? % :subtype "Clone") (has? % :subtype "Executive")
                                     (has? % :subtype "Sysop")))
@@ -1249,7 +1249,7 @@
                               (lose state side :credit :all :tag :all))}]}

    "Sacrificial Construct"
-   {:abilities [{:msg "prevent an installed program or hardware from being trash"
+   {:abilities [{:msg "prevent an installed program or hardware from being trashed"
                  :effect (effect (trash card))}]}

    "Sahasrara"
@@ -1257,7 +1257,7 @@

    "Same Old Thing"
    {:abilities [{:cost [:click 2]
-                 :prompt "Choose an event to install" :msg (msg "play " (:title target))
+                 :prompt "Choose an event to play" :msg (msg "play " (:title target))
                  :choices (req (filter #(and (has? % :type "Event")
                                              (<= (:cost %) (:credit runner))) (:discard runner)))
                  :effect (effect (play-instant target) (trash card))}]}
@@ -1306,12 +1306,12 @@
    {:events {:corp-turn-begins {:effect (effect (gain :credit 2)) :msg "gain 2 [Credits]"}
              :corp-install {:req (req (has? target :type "ICE"))
                             :effect (effect (trash card)
-                                            (system-msg "trashes Server Diagnostic"))}}}
+                                            (system-msg "trashes Server Diagnostics"))}}}

    "Shattered Remains"
    {:advanceable :always
     :access {:optional {:req (req installed)
-                        :prompt "Pay 1[Credits] to use Shaterred Remains ability?" :cost [:credit 1]
+                        :prompt "Pay 1 [Credits] to use Shattered Remains ability?" :cost [:credit 1]
                         :msg (msg "trash " (:advance-counter card) " pieces of hardware")}}}

    "Shell Corporation"
@@ -1350,12 +1350,12 @@
    {:prompt "Choose a server" :choices (req remotes)
     :effect (effect (run target
                       {:replace-access
-                       {:msg "destroy all in the server at no cost"
+                       {:msg "trash all cards in the server at no cost"
                         :effect (req (doseq [c (get-in (:servers corp) (conj (:server run) :content))]
                                        (trash state side c)))}} card))}

    "Sneakdoor Beta"
-   {:abilities [{:cost [:click 1] :msg "make run on Archives"
+   {:abilities [{:cost [:click 1] :msg "make a run on Archives"
                  :effect (effect (run :archives
                                    {:successful-run
                                     {:msg "make a successful run on HQ"
@@ -1363,13 +1363,13 @@

    "Snare!"
    {:access {:optional {:req (req (not= (first (:zone card)) :discard))
-                        :prompt "Pay 4[Credits] to use Snare! ability?" :cost [:credit 4]
+                        :prompt "Pay 4 [Credits] to use Snare! ability?" :cost [:credit 4]
                         :msg (msg "do 3 net damage and give the Runner 1 tag")
                         :effect (effect (damage :net 3) (gain :runner :tag 1))}}}

    "Special Order"
    {:prompt "Choose an Icebreaker"
-    :effect (effect (system-msg (str "adds " (:title target) " to his grip and shuffle his stack"))
+    :effect (effect (system-msg (str "adds " (:title target) " to his Grip and shuffles his Stack"))
                     (move target :hand) (shuffle! :deck))
     :choices (req (filter #(has? % :subtype "Icebreaker") (:deck runner)))}

@@ -1497,7 +1497,7 @@
     :effect (effect (trash target) (gain [:credit (quot (:cost target) 2)])
                     (resolve-ability {:prompt "Choose a Hardware to add to Grip from Stack"
                                       :choices (req (filter #(= (:type %) "Hardware") (:deck runner)))
-                                      :msg (msg "adds " (:title target) " to his grip")
+                                      :msg (msg "adds " (:title target) " to his Grip")
                                       :effect (effect (move target :hand))} card nil))}

    "Traffic Accident"
@@ -1548,7 +1548,7 @@
                                   :msg "draw 1 card" :effect (effect (draw 1))}}}

    "Vulcan Coverup"
-   {:msg "do 2 meat damages" :effect (effect (damage :meat 2))
+   {:msg "do 2 meat damage" :effect (effect (damage :meat 2))
     :stolen {:msg "force the Corp to take 1 bad publicity"
              :effect (effect (gain :corp :bad-publicity 1))}}

@@ -1624,7 +1624,7 @@

    "Breach"
    {:abilities [{:cost [:credit 2] :req (req (#{:hq :rd :archives} (first (:server run))))
-                 :msg "break 3 barrier subroutine"}
+                 :msg "break 3 barrier subroutines"}
                 {:cost [:credit 2] :msg "add 4 strength" :effect (effect (pump card 4))}]}

    "Cerberus \"Cuj.0\" H3"
@@ -1672,16 +1672,16 @@
     :abilities [{:cost [:credit 2] :msg "break ICE subroutine"}]}

    "Deus X"
-   {:abilities [{:msg "break any number of AP subroutine" :effect (effect (trash card))}
-                {:msg "Prevent any number of net damage" :effect (effect (trash card))}]}
+   {:abilities [{:msg "break any number of AP subroutines" :effect (effect (trash card))}
+                {:msg "prevent any amount of net damage" :effect (effect (trash card))}]}

    "Eater"
-   {:abilities [{:cost [:credit 1] :msg "break ICE subroutine and access 0 card this run"
+   {:abilities [{:cost [:credit 1] :msg "break ICE subroutine and access 0 cards this run"
                  :effect (effect (max-access 0))}
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}

    "Faerie"
-   {:abilities [{:msg "break any number of sentry subroutine" :effect (effect (trash card))}
+   {:abilities [{:msg "break any number of sentry subroutines" :effect (effect (trash card))}
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}

    "Femme Fatale"
@@ -1693,7 +1693,7 @@
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}

    "Garrote"
-   {:abilities [{:cost [:credit 1] :msg "break 1 sentry subroutines"}
+   {:abilities [{:cost [:credit 1] :msg "break 1 sentry subroutine"}
                 {:cost [:credit 1] :msg "add 1 strength" :effect (effect (pump card 1))}]}

    "Gordian Blade"
@@ -1774,7 +1774,7 @@
                 {:cost [:credit 1] :msg "add 2 strength" :effect (effect (pump card 2))}]}

    "Switchblade"
-   {:abilities [{:cost [:credit 1] :msg "break any number sentry subroutines"}
+   {:abilities [{:cost [:credit 1] :msg "break any number of sentry subroutines"}
                 {:cost [:credit 1] :msg "add 7 strength" :effect (effect (pump card 7))}]}

    "Torch"
@@ -1868,7 +1868,7 @@
    {:abilities [{:msg "do 1 net damage" :effect (effect (trash card) (damage :net 1))}]}

    "Datapike"
-   {:abilities [{:msg "force the runner to pay 2 [Credits] if able"
+   {:abilities [{:msg "force the Runner to pay 2 [Credits] if able"
                  :effect (effect (pay :runner card :credit 2))}
                 {:msg "end the run" :effect (effect (end-run))}]}

@@ -1890,7 +1890,7 @@
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]}

    "Enigma"
-   {:abilities [{:msg "force the runner to lose 1 [Click] if able"
+   {:abilities [{:msg "force the Runner to lose 1 [Click] if able"
                  :effect (effect (lose :runner :click 1))}
                 {:msg "end the run" :effect (effect (end-run))}]}

@@ -1972,7 +1972,7 @@
    {:abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
                  :label "Trash a program" :choices (req (get-in runner [:rig :program]))
                  :effect (effect (trash target))}
-                {:label "Trace 1 - Give ther Runner 1 tag and do 1 brain damage"
+                {:label "Trace 1 - Give the Runner 1 tag and do 1 brain damage"
                  :trace {:base 1 :msg "give the Runner 1 tag and do 1 brain damage"
                          :effect (effect (damage :brain 1) (gain :runner :tag 1))}}]}

@@ -1980,7 +1980,7 @@
    {:abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
                  :label "Trash a program" :choices (req (get-in runner [:rig :program]))
                  :effect (effect (trash target))}
-                {:label "Trace 3 - Give ther Runner 1 tag and do 1 brain damage"
+                {:label "Trace 3 - Give the Runner 1 tag and do 1 brain damage"
                  :trace {:base 3 :msg "give the Runner 1 tag and do 1 brain damage"
                          :effect (effect (damage :brain 1) (gain :runner :tag 1))}}]}

@@ -2029,7 +2029,7 @@
                                    :effect (effect (add-prop :runner card :counter 1))}}}]}

    "Markus 1.0"
-   {:abilities [{:msg "force the runner to trash a card"}
+   {:abilities [{:msg "force the Runner to trash a card"}
                 {:msg "end the run" :effect (effect (end-run))}]}

    "Matrix Analyzer"
@@ -2056,7 +2056,7 @@
                  :trace {:base 2 :msg "give the Runner 1 tag" :effect (effect (gain :runner :tag 1))}}
                 {:label "Trace 3 - Give the Runner 1 tag"
                  :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (gain :runner :tag 1))}}
-                {:msg "end the run if the runner is tagged" :req (req tagged)
+                {:msg "end the run if the Runner is tagged" :req (req tagged)
                  :effect (effect (end-run))}]}

    "Nebula"
@@ -2180,13 +2180,13 @@
     :abilities [{:msg "end the run" :effect (effect (end-run))}]}

    "Tollbooth"
-   {:abilities [{:msg "force the runner to lose 3 [Credits]"
+   {:abilities [{:msg "force the Runner to lose 3 [Credits]"
                  :effect (effect (lose :runner :credit 3))}
                 {:msg "end the run" :effect (effect (end-run))}]}

    "Troll"
    {:abilities [{:player :runner :prompt "Choose one" :choices ["Lose [Click]" "End the run"]
-                 :label "Force the runner to lose [Click] or end the run"
+                 :label "Force the Runner to lose [Click] or end the run"
                  :effect (req (if-not (and (= target "Lose [Click]") (pay state side card :click 1))
                              (do (end-run state side) (system-msg state side "ends the run"))
                              (system-msg state side "loses [Click]")))}]}
@@ -2222,7 +2222,7 @@

    "Viper"
    {:abilities [{:label "Trace 3 - The Runner loses 1 [Click] if able"
-                 :trace {:base 3 :msg  "force the runner to lose 1 [Click] if able"
+                 :trace {:base 3 :msg  "force the Runner to lose 1 [Click] if able"
                          :effect (effect (lose :runner :click 1))}}
                 {:label "Trace 3 - End the run"
                  :trace {:base 3 :msg "end the run" :effect (effect (end-run))}}]}


stretching order

stretching order

--- src/ontrail/races.clj
+++ src/ontrail/races.clj
@@ -37,7 +37,7 @@
   (totals-by (total "YHTEENSÄ") :nduration year))

 (def sort-keys
-  {"Leuanveto" :repeats})
+  {"Leuanveto" :repeats "Venyttely" :nduration})

 (defn totals-by-sport [sport year]
   (totals-by (total sport) (sort-keys sport :ndistance) year))


Ability to change mouse cusror #42; Clipboard paste event; Textfield bugfixes;

--- src/flatgui/samples/forms/layoutdemopanel2.clj
+++ src/flatgui/samples/forms/layoutdemopanel2.clj
@@ -77,13 +77,6 @@
         (catch Exception e (do (println "Config invalid: " (.getMessage e)) false)))
       false)))

-;;; Allow entering only what's releavant for this sample layout config
-(defn sample-only-text-suplier [component]
-  (let [key (textfield/textfield-dflt-text-suplier component)]
-    (if (#{"a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "m" "n" "o" "p"
-           " " "[" "]"
-           ":" "-" "|" "<" ">" "'" "."} key) key "")))
-
 (def layout-window
   (fg/defcomponent
     window/window
@@ -112,7 +105,6 @@
                                                             :auto-size true
                                                             :paint-border false
                                                             :model text-model
-                                                            :text-supplier sample-only-text-suplier
                                                             :text (:text text-model)})}})}})

     (fg/defcomponent label/label :validity-indicator


memoize the right function

memoize the right function

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -673,7 +673,7 @@
     (update-in [:tx-data] vec)
     (dissoc :transaction/document)))

-(defonce memo-frontend-tx-data (memo/lru memo-frontend-tx-data
+(defonce memo-frontend-tx-data (memo/lru memo-frontend-tx-data*
                                          :lru/threshold 10000))

 (defn frontend-tx-data [db tx-id]


minor formating

minor formating

--- src/overtone/sc/ugen.clj
+++ src/overtone/sc/ugen.clj
@@ -335,16 +335,16 @@
   If an init function is already present it will get called after doing the
   mapping and mode transformations."
   [spec]
-  (let [defaulter (partial add-default-args spec)
-        mapper    (partial map-ugen-args spec)
-        init-fn   (if (contains? spec :init)
-                    (:init spec)
-                    placebo-ugen-init-fn)
-        initer    (partial with-ugen-metadata-init spec init-fn)
-        n-outputer (partial with-num-outs-mode spec)
-        floater   (partial with-floated-args spec)
-        appender  (partial append-seq-args spec)
-        auto-rater (partial auto-rate-setter spec)
+  (let [defaulter    (partial add-default-args spec)
+        mapper       (partial map-ugen-args spec)
+        init-fn      (if (contains? spec :init)
+                       (:init spec)
+                       placebo-ugen-init-fn)
+        initer       (partial with-ugen-metadata-init spec init-fn)
+        n-outputer   (partial with-num-outs-mode spec)
+        floater      (partial with-floated-args spec)
+        appender     (partial append-seq-args spec)
+        auto-rater   (partial auto-rate-setter spec)
         rate-checker (partial check-arg-rates spec)]

     (assoc spec :init


Fix problematic code for CLJS

Fix problematic code for CLJS

--- src/pinpointer/core.cljc
+++ src/pinpointer/core.cljc
@@ -100,14 +100,15 @@
    (if ed
      (let [{:keys [::s/problems ::s/value] :as ed} (correct-paths ed)
            nproblems (count problems)]
-       (if-let [traces (try (trace/traces ed) (catch Throwable _ nil))]
+       (if-let [traces (try (trace/traces ed)
+                            (catch #?(:clj Throwable :cljs js/Error) _))]
          (binding [*colorize-fn* (choose-colorize-fn colorize)]
            (newline)
            (print-headline nproblems)
            (hline)
            (doseq [[i problem trace] (map vector (range) problems traces)
                    :let [[line & lines] (format-data value trace)]]
-             (printf " (%d/%d)\n\n" (inc i) nproblems)
+             (println (str " (" (inc i) "/" nproblems ")\n"))
              (println "     Input:" line)
              (doseq [line lines]
                (println "          :" line))
@@ -131,12 +132,19 @@
   ([spec x opts]
    (pinpoint-out (s/explain-data spec x) opts)))

+#?(:clj
+   (defn- find-spec-error [^Throwable t]
+     (when t
+       (let [data (ex-data t)]
+         (if (and data (::s/problems data))
+           t
+           (recur (.getCause t))))))
+
+   :cljs
+   (defn- find-spec-error [e]
+     (when (some-> e ex-data ::s/problems)
+       e)))
+
 (defn ppt []
-  (letfn [(find-spec-error [^Throwable t]
-            (when t
-              (let [data (ex-data t)]
-                (if (and data (::s/problems data))
-                  t
-                  (recur (.getCause t))))))]
-    (when-let [e (find-spec-error *e)]
-      (pinpoint-out (ex-data e)))))
+  (when-let [e (find-spec-error *e)]
+    (pinpoint-out (ex-data e))))


Make var for frame delay

Make var for frame delay

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -198,13 +198,14 @@
 (let [canvas-id "canvas"
       c-instrument (chan)
       c-orientation-change (util/listen js/window :orientation-change)
-      c-touch (create-touch-input-channel canvas-id)]
+      c-touch (create-touch-input-channel canvas-id)
+      frame-delay 30]

   (go
    (let [draw-ctx (util/get-ctx canvas-id)]
      (util/set-canvas-size! canvas-id (util/get-window-size))
      (loop [instrument (<! c-instrument)]
-       (let [[data c] (alts! [c-instrument (timeout 16)])]
+       (let [[data c] (alts! [c-instrument (timeout frame-delay)])]
          (condp = c
            c-instrument (recur data)
            (do (draw-instrument draw-ctx instrument)
@@ -213,7 +214,7 @@
   (go
    (loop [instrument (update-size (create-instrument (scales/c-minor)) canvas-id)]
      (>! c-instrument instrument)
-     (let [[data c] (alts! [c-touch c-orientation-change (timeout 16)])]
+     (let [[data c] (alts! [c-touch c-orientation-change (timeout frame-delay)])]
        (condp = c
          c-orientation-change (recur (update-size instrument canvas-id))
          c-touch (recur (fire-touch-data-on-instrument instrument data))


Test commit to get git-flow going?

Test commit to get git-flow going?

--- src/re_com/dropdown.cljs
+++ src/re_com/dropdown.cljs
@@ -332,6 +332,9 @@
                                  35 (when @drop-showing?  ;; End key
                                       (reset! tmp-model (move-to-new-option filtered-options @tmp-model :end)))
                                  true))]
+
+        ;; TODO: Remove this comment
+
         [:div
          {:class (str "chosen-container chosen-container-single" (when @drop-showing? " chosen-container-active chosen-with-drop"))
           :style (if width


Remove login box.

Remove login box.

--- backend/src/circle/web/views/common.clj
+++ backend/src/circle/web/views/common.clj
@@ -10,7 +10,7 @@
 (defn css [path & {:keys [rel type media title] :as opts}]
   [:link (merge {:href (resolve-uri path)} opts)])

-(defn center-vertically
+(defn center-vertically
   "Take the provided div and center it vertically, by adding classes and
   wrapping it's contents in more divs. It relies on additional.css having
   .vcenter{1,2,3} defined."
@@ -21,7 +21,7 @@
     [tag property-map [:div.vcenter2 (apply vector :div.vcenter3 inner-tags)]]))

-(defn center-vertically-span
+(defn center-vertically-span
   "Take the provided div and center it vertically, by adding classes and
   wrapping it's contents in more divs. It relies on additional.css having
   .vcenter{1,2,3} defined."
@@ -87,7 +87,8 @@
        (unordered-list {:id "nav"}
                        [(link-to {:class "current_page"}
                                  "/" "Signup")
-                        (login-box)])
+;                        (login-box)
+                        ])
        [:div.clear]]]
      content
      [:div.clear]


src/riemann/xymon.clj: * xymon-batch: minor docstring updates

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -176,8 +176,9 @@

 (defn xymon-batch
   "
-  Returns a function which accepts multiple events and send them to
-  xymon as 'combo' messages. Filters events with nil :state
+
+  Returns a function which accepts a vector of events and which sends
+  them to Xymon as 'combo' messages. Filters events with nil :state
   or :service.
   "
   [opts]


fixed issue #21

fixed issue #21

--- src/server/rooms.cljs
+++ src/server/rooms.cljs
@@ -279,11 +279,11 @@
                     (change-to-track-num current-track-num))))
               (get-num-of-tracks room
                 (fn [num-of-tracks]
-                  (if (>= current-track-num num-of-tracks)
-                    (callback nil)
-                  (.incr redis-client (str "room:" room ":current-track")
-                    (fn [err track-num]
-                      (change-to-track-num track-num)))))))))))))
+                  (if (>= current-track-num (- num-of-tracks 1))
+                    (callback nil nil)
+                    (.incr redis-client (str "room:" room ":current-track")
+                      (fn [err track-num]
+                        (change-to-track-num track-num)))))))))))))

 (defn get-all-music-info [room-id callback]
   (.hgetall redis-client (str "room:" room-id ":music-info")


Fix typo

Fix typo

--- src/subman/models.clj
+++ src/subman/models.clj
@@ -30,7 +30,7 @@
 (defn search
   "Search for documents"
   [query] (->> (esd/search index "subtitle"
-                           :query (q/fuzzy-like-this :like_text "1")
+                           :query (q/fuzzy-like-this :like_text query)
                            :size 100)
                :hits
                :hits


Explicit foreign keys on korma models.

Explicit foreign keys on korma models.

--- src/swartz/models.clj
+++ src/swartz/models.clj
@@ -9,14 +9,14 @@
 (declare users posts comments)

 (defentity users
-  (has-many posts))
+  (has-many posts {:fk :user_id}))

 (defentity posts
-  (belongs-to users)
-  (has-many comments))
+  (belongs-to users {:fk :user_id})
+  (has-many comments {:fk :post_id}))

 (defentity comments
-  (belongs-to users)
-  (belongs-to posts)
-  (belongs-to comments)
-  (has-many comments))
+  (belongs-to users {:fk :user_id})
+  (belongs-to posts {:fk :post_id})
+  (belongs-to comments {:fk :comment_id})
+  (has-many comments {:fk :comment_id}))


Update doc strings to fix Marginalia formatting issues.

--- src/leiningen/git_deps.clj
+++ src/leiningen/git_deps.clj
@@ -5,7 +5,14 @@
             [clojure.java.io :as io]
             [clojure.string :as string]))

-(def ^:private git-deps-dir ".lein-git-deps")
+;; Why, you might ask, are we using str here instead of simply def'ing
+;; the var to a string directly? The answer is that we are working
+;; around a bug in marginalia where it can't tell the difference
+;; between the string that's the value for a def and a docstring. It
+;; will hopefully be fixed RSN, because this makes us feel dirty.
+(def ^{:private true
+       :doc "The directory into which dependencies will be cloned."}
+  git-deps-dir (str ".lein-git-deps"))

 (defn- directory-exists?
   "Return true if the specified directory exists."
@@ -74,19 +81,21 @@

   Dependencies should be listed in project.clj under the
   :git-dependencies key in one of these three forms:
-  :git-dependencies [;; First form: just a URL.
-                     [\"https://github.com/foo/bar.git\"]

-                     ;; Second form: A URL and a ref, which can be anything
-                     ;; you can specify for 'git checkout', like a commit ide
-                     ;; or a branch name.
-                     [\"https://github.com/foo/baz.git\"
-                      \"329708b\"]
+    :git-dependencies [;; First form: just a URL.
+                       [\"https://github.com/foo/bar.git\"]

-                     ;; Third form: A URL, a commit, and a map
-                     [\"https://github.com/foo/quux.git\"
-                      \"some-branch\"
-                      {:dir \"alternate-directory\"}]]"
+                       ;; Second form: A URL and a ref, which can be anything
+                       ;; you can specify for 'git checkout', like a commit id
+                       ;; or a branch name.
+                       [\"https://github.com/foo/baz.git\"
+                        \"329708b\"]
+
+                       ;; Third form: A URL, a commit, and a map
+                       [\"https://github.com/foo/quux.git\"
+                        \"some-branch\"
+                        {:dir \"alternate-directory\"}]]
+"
   [project]
   (when-not (directory-exists? git-deps-dir)
     (.mkdir (io/file git-deps-dir)))


docstring: Better rendering by using

 for the documentation.

--- ccw.util/src/clj/ccw/util/doc_utils.clj
+++ ccw.util/src/clj/ccw/util/doc_utils.clj
@@ -66,7 +66,7 @@
   (when-not (str/blank? doc)
     (render-section renderer
                     "Documentation"
-                    doc)))
+                    (str "<pre>" doc "</pre>"))))

 (defn var-doc-info [renderer m]
   (let [sections [(header-doc renderer m)


CMR-2840 Change ISO processor path

CMR-2840 Change ISO processor path

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2/data_contact.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2/data_contact.clj
@@ -18,7 +18,7 @@

 (def processor-xpath
  (str "/gmi:MI_Metadata/gmd:dataQualityInfo/gmd:DQ_DataQuality/gmd:lineage/gmd:LI_Lineage/gmd:processStep/"
-      "gmd:LI_ProcessStep/gmd:processor/gmd:CI_ResponsibleParty"))
+      "gmi:LE_ProcessStep/gmd:processor/gmd:CI_ResponsibleParty"))

 (def iso-data-center-role->umm-role
  {"custodian" "ARCHIVER"


fix(editor-support): :ccw.editor.saved event posts the filesystem path

--- ccw.core/src/clj/ccw/editors/clojure/editor_support.clj
+++ ccw.core/src/clj/ccw/editors/clojure/editor_support.clj
@@ -126,7 +126,7 @@
 (defn editor-saved [editor]
   (evt/post-event :ccw.editor.saved
     {:namespace     (.findDeclaringNamespace editor)
-     :absolute-path (some-> editor .getEditorInput e/resource e/path .toOSString)
+     :absolute-path (some-> editor .getEditorInput e/resource .getLocation .toOSString)
      :repl          (-> editor .getCorrespondingREPL)}))

 (defn source-viewer


fix call to project fn

fix call to project fn

--- clientlib/src/clj/ow/factum/logicdb.clj
+++ clientlib/src/clj/ow/factum/logicdb.clj
@@ -15,7 +15,8 @@
   ;;; TODO: if timestamp is set and not in the future (minus last update),
   ;;;       we don't need to always recalculate the resulting data, but can
   ;;;       instead cache it:
-  (->> (cs/project (:clientstorage this))
+  (->> (cs/project (:clientstorage this)
+                   (:timestamp this))
        (into [] (map #(vec (cons fact %))))
        (apply lp/db)))


`update-table` now allows desired throughput to be specified with _just_ :read or :write units

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -398,11 +398,13 @@
   delivered. Deref this promise to block until update (all steps) complete."
   [creds table throughput & [{:keys [span-reqs]
                               :or   {span-reqs {:max 5}}}]]
-  (let [{max-reqs :max} span-reqs
-        {read* :read write* :write} throughput
+  (let [throughput* throughput
+        {read* :read write* :write} throughput*
         {:keys [status throughput]} (describe-table creds table)
         {:keys [read write num-decreases-today]} throughput
-
+        read*  (or read*  read)
+        write* (or write* write)
+        {max-reqs :max} span-reqs
         decreasing? (or (< read* read) (< write* write))
         steps  (throughput-steps [read write] [read* write*])
         nsteps (count steps)]


as-map method missing for objects of Projection type

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -247,6 +247,10 @@
   UpdateTableResult   (as-map [r] (as-map (.getTableDescription r)))
   DeleteTableResult   (as-map [r] (as-map (.getTableDescription r)))

+  Projection
+  (as-map [p] {:projection-type    (.getProjectionType p)
+               :non-key-attributes (.getNonKeyAttributes p)})
+
   LocalSecondaryIndexDescription
   (as-map [d] {:name       (keyword (.getIndexName d))
                :size       (.getIndexSizeBytes d)


Tightened channel and readers

Tightened channel and readers

--- jar-async/src/slipstream/async/launcher.clj
+++ jar-async/src/slipstream/async/launcher.clj
@@ -16,8 +16,8 @@
   [minutes]
   (* 1000 60 minutes))

-(def launcher-chan-size 1000)
-(def number-of-readers 100)
+(def launcher-chan-size 10)
+(def number-of-readers 10)
 (def timeout-processing-loop (minutes-in-msecs 1))
 (def timeout-launch (minutes-in-msecs 5))


parse int added

parse int added

--- src/word_keeper/core.clj
+++ src/word_keeper/core.clj
@@ -32,7 +32,7 @@

 (defroutes routes
   (GET "/" [] action-index)
-  (POST "/api/translations/:uid/create" [uid] #(post-translation % uid))
+  (POST "/api/translations/:uid/create" [uid] #(post-translation % (Integer/parseInt uid)))
   (GET "/api/translations/:uid" [uid] #(flat-user-translations % uid))
   (GET "/vocabulary" [] (-> action-vocabulary auth-middleware))
   (GET "/signin" [] action-signin)


stop using HystrixCollapser/reset-collapser

See https://github.com/Netflix/Hystrix/pull/106 and https://github.com/Netflix/Hystrix/issues/102

--- hystrix-contrib/hystrix-clj/src/main/clojure/com/netflix/hystrix/core.clj
+++ hystrix-contrib/hystrix-clj/src/main/clojure/com/netflix/hystrix/core.clj
@@ -131,8 +131,6 @@
               HystrixCollapser$Scope
               HystrixCollapser$Setter
               HystrixCollapser$CollapsedRequest]))
-
-(declare reset-collapser)

 (defmacro ^:private key-fn
   "Make a function that creates keys of the given class given one of:
@@ -307,8 +305,7 @@

 (defn collapser
   "Helper function that takes a definition map for a HystrixCollapser and returns a normalized
-  version ready for use with execute and queue. It also ensures that global/cached collapser
-  state is reset.
+  version ready for use with execute and queue.

   See ns documentation for valid keys.

@@ -319,7 +316,6 @@
   (let [result (-> options-map
                  (assoc :type :collapser)
                  normalize)]
-    (reset-collapser (:collapser-key result))
     result))

 (defmacro defcollapser
@@ -519,10 +515,6 @@
 ;################################################################################
 ; :collapser impl

-(defn- reset-collapser
-  [key]
-  (HystrixCollapser/resetCollapser (collapser-key key)))
-
 (defmethod normalize :collapser
   [definition]
   (-> definition


#1734 new vis type - scatter w var radii

--- backend/src/akvo/lumen/lib/aggregation/scatter.clj
+++ backend/src/akvo/lumen/lib/aggregation/scatter.clj
@@ -66,19 +66,19 @@
     (lib/ok
      {"series" (cond-> [{"key" column-x-title
                           "label" column-x-title
-                          "data" (mapv (fn [[x-value y-value label]]
+                          "data" (mapv (fn [[x-value y-value size-value label]]
                                           {"value" x-value})
                                         sql-response)
                           "metadata" {"type" column-x-type}}
                         {"key" column-y-title
                           "label" column-y-title
-                          "data" (mapv (fn [[x-value y-value label]]
+                          "data" (mapv (fn [[x-value y-value size-value label]]
                                         {"value" y-value})
                                       sql-response)
                           "metadata"  {"type" column-y-type}}]
                         (some? column-size-title) (conj {"key" column-size-title
                           "label" column-size-title
-                          "data" (mapv (fn [[x-value size-value label]]
+                          "data" (mapv (fn [[x-value y-value size-value label]]
                                           {"value" size-value})
                                         sql-response)
                           "metadata"  {"type" column-size-type}}))


Implement new cells rule

Implement new cells rule


Add gen-class

Add gen-class

--- src/time_tracker/core.clj
+++ src/time_tracker/core.clj
@@ -1,4 +1,5 @@
 (ns time-tracker.core
+  (:gen-class)
   (:require [time-tracker.logging :as log]
             [time-tracker.web.service :as web-service]
             [time-tracker.util :refer [from-config]])


improve description of test

improve description of test

--- test/puppetlabs/trapperkeeper/logging_test.clj
+++ test/puppetlabs/trapperkeeper/logging_test.clj
@@ -18,6 +18,8 @@
     (configure-logging! {:global {:logging-config "./test-resources/log4j.properties"}})
     (is (= (Level/DEBUG) (.getLevel (Logger/getRootLogger)))))

-  (testing "Calling `configure-logging!` with another log4j.properties file"
+  (testing
+      "Calling `configure-logging!` with another log4j.properties file
+      in case the default logging level is DEBUG"
     (configure-logging! {:global {:logging-config "./test-resources/another-log4j.properties"}})
     (is (= (Level/WARN) (.getLevel (Logger/getRootLogger))))))


Fixed namespace

Fixed namespace

--- src/webapp/neo_stuff.cljs
+++ src/webapp/neo_stuff.cljs
@@ -1,4 +1,4 @@
-(ns webapp
+(ns webapp.neo-stuff
  (:refer-clojure :exclude [val empty remove find next parents])
     (:require
         [cljs.reader                     :as reader]
@@ -15,7 +15,7 @@
         [webapp.framework.client.coreclient  :only [ns-coils sql log neo4j neo4j-1 sql-1 log]]
      )
 )
-(ns-coils 'webapp)
+(ns-coils 'webapp.neo-stuff)

 ;(go (<! (add-to-simple-point-layer {:name "ny ny" :x 0.12 :y 0.1} "ore2")))


Yeargh Tip: test your builds before pushing

--- desktop/src-common/escape_game/core.clj
+++ desktop/src-common/escape_game/core.clj
@@ -190,7 +190,7 @@

             :room06
             [(defentity "" "images/room06.png" 0 0 700 480)
-             (arrow :left :room05)]
+             (arrow :left :room05)
              ]})

 ;; main screen - where the game is played


implement clojure.lang.IFn for RangeMap

implement clojure.lang.IFn for RangeMap

--- sample/src/sample/rangemap.clj
+++ sample/src/sample/rangemap.clj
@@ -37,6 +37,12 @@
         not-found)))

+  clojure.lang.IFn
+
+  (invoke [this arg1]
+    (.valAt this arg1))
+
+
   clojure.lang.Seqable

   (seq [this]


Improve test-all alias.

Improve test-all alias.

--- profiles.clj
+++ profiles.clj
@@ -1,5 +1,5 @@
 {:dev
- {:aliases {"test-all" ["with-profile" "dev,1.8:dev,1.6:dev,1.5:dev" "test"]}
+ {:aliases {"test-all" ["with-profile" "dev:dev,1.7:dev,1.6:dev,1.5" "test"]}
   :codeina {:sources ["src"]
             :reader :clojure
             :target "doc/dist/latest/api"


Use clj-http instead of the buggier http.async.client [IMMUTANT-506]

--- web/test/immutant/web_test.clj
+++ web/test/immutant/web_test.clj
@@ -240,4 +240,4 @@

 (deftest encoding
   (run (fn [r] (charset ((handler "ɮѪϴ") r) "UTF-16")))
-  (is (= "ɮѪϴ" (get-body url))))
+  (is (= "ɮѪϴ" (:body (http/get url {:as :auto})))))


Fixes #231 - stop persisting loaded file content to REPL command history prefs

--- ccw.core/src/ccw/repl/view_helpers.clj
+++ ccw.core/src/ccw/repl/view_helpers.clj
@@ -134,7 +134,6 @@
                         cursor-at-end)))))))

     (comp (apply partial eval-expression args)
-      retain-expr-fn
       (fn [expr add-to-log?]
         (reset! retained-input nil)
         (reset! current-step -1)
@@ -144,5 +143,6 @@
                             (if (= expr (last %))
                               %
                               (conj % expr))
-                            (-> % count (- history/max-history) (max 0)))))
+                            (-> % count (- history/max-history) (max 0))))
+          (retain-expr-fn expr))
         expr))))


add slf4j-nop to suppres boot-less logging warnings

--- resources/leiningen/new/oriens/build.boot
+++ resources/leiningen/new/oriens/build.boot
@@ -14,6 +14,7 @@
                  [adzerk/boot-reload          "0.4.12"         :scope "test"]
                  [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]
                  [deraen/boot-less            "0.5.0"          :scope "test"]
+                 [org.slf4j/slf4j-nop         "1.7.21"         :scope "test"]
                  [org.clojure/tools.nrepl     "0.2.12"         :scope "test"]
                  [pandeiro/boot-http          "0.7.3"          :scope "test"]
                  [weasel                      "0.7.0"          :scope "test"]])


create constants to refer to strings

create constants to refer to strings

--- src/cljs/org/broadinstitute/firecloud_ui/page/methods_configs_acl.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/methods_configs_acl.cljs
@@ -21,22 +21,26 @@
 (def ^:private access-levels
   ["READER" "OWNER" "NO ACCESS"])

+(def ^:private reader-level (nth access-levels 0))
+(def ^:private  owner-level (nth access-levels 1))
+(def ^:private  no-access-level (nth access-levels 2))
+
 (defn- index-to-access-level [idx]
   (str (nth access-levels idx)))

 (defn- access-level-to-index [access-level]
   (case access-level
-    "READER" 0
-    "OWNER" 1
-    "NO ACCESS" 2))
+    reader-level 0
+    owner-level 1
+    no-access-level 2))

 (def ^:private column-width "calc(50% - 4px)")

 (defn- correspondsToReader [access-level]
   (if
     (or
-      (= access-level "READER")
-      (= access-level "OWNER"))
+      (= access-level reader-level)
+      (= access-level owner-level))
     true
     false))

@@ -66,7 +70,7 @@
         numJustPublic (count justPublic)]
       (if (<= numJustPublic 0)
       ;if public isn't in the acl-return NO ACCESS
-      "NO ACCESS"
+      no-access-level
       (let [lastPublic (get justPublic (- numJustPublic 1))
             lastPublicAccessLevel (get lastPublic :role)]
         ;if public is in the acl return the value of the last one
@@ -78,7 +82,6 @@
   {:render
    (fn [{:keys [props refs state this]}]
      [dialog/Dialog
-
       {:width "75%"
        :blocking? true
        :dismiss-self (:dismiss-self props)
@@ -131,7 +134,7 @@
                                      :onClick #(swap! state assoc :acl-vec
                                                 (conj
                                                   (react/call :capture-ui-state this)
-                                                  {:user "" :role "READER"}))}]
+                                                  {:user "" :role reader-level}))}]
                       [:input {:type "checkbox"
                                :ref "publicbox"
                                :onChange (fn []
@@ -180,7 +183,7 @@
      (swap! state assoc :saving? true)
      (swap! state assoc :acl-vec
        (flatten [{:user "public" :role
-                 (if (:public-status @state) "READER" "NO ACCESS")}
+                 (if (:public-status @state) reader-level no-access-level)}
        (react/call :capture-ui-state this)]))
      (endpoints/call-ajax-orch
        {:endpoint (endpoints/persist-agora-method-acl (:selected-entity props))


fix bug in gaq

fix bug in gaq

--- frontend/analytics/google.cljs
+++ frontend/analytics/google.cljs
@@ -6,7 +6,7 @@
      ((aget gaq "push") (clj->js args))))

 (defn track-event [& args]
-  (utils/swallow-errors (push "_trackEvent" args)))
+  (utils/swallow-errors (push (cons "_trackEvent" args))))

 (defn track-pageview [& args]
-  (utils/swallow-errors (push "_trackPageview" args)))
+  (utils/swallow-errors (push (cons "_trackPageview" args))))


proxy request to backend trip planner

proxy request to backend trip planner

--- src/otp_api_proxy/core.clj
+++ src/otp_api_proxy/core.clj
@@ -156,6 +156,32 @@

 (defn simple-otp-request-cached []
   test-data/otp-response-1)
+
+
+;; TODO: very important, sanitize the arguments passed.
+(defn otp-request-live [params]
+  (let [pass-arg (fn [arg] (if (get params arg)
+                             (str arg "=" (get params arg))
+                             ""))
+
+        otp-url
+        (str "http://anaheim-otp.ed-groth.com/otp/routers/default/plan"
+             "?"
+             (reduce str [(pass-arg "fromPlace")
+                          "&" (pass-arg "toPlace")
+                          "&" (pass-arg "time")
+                          "&" (pass-arg "date")
+                          "&mode=TRANSIT,WALK"
+                          "&maxWalkDistance=750"
+                          "&walkReluctance=40"
+                          "&walkSpeed=0.3"
+                          "&arriveBy=false"
+                          "&showIntermediateStops=false"
+                          ]))]
+    ; {:body {:plan otp-url}} ))
+    (http-client/get otp-url {:as :json})))
+
+

 (defn simple-otp-request-live []
   (let [test-otp-url
@@ -244,6 +270,26 @@
                    itinernary->add-route-span
                    )))

+(defresource ws-otp-with-args [get-params]
+  :available-media-types ["application/json" "text/plain"]
+  :handle-ok (pretty-json
+               (-> (otp-request-live get-params)
+               ;; (-> (simple-otp-request-live)
+                   otp-response->itinerary
+                   itinernary->add-text2go
+                   itinernary->add-route-url
+                   itinernary->add-route-span
+                   )))
+
+(defresource ws-otp-cooked []
+  :available-media-types ["application/json" "text/plain"]
+  :handle-ok (pretty-json
+               (-> (simple-otp-request-cached)
+                   otp-response->itinerary
+                   itinernary->add-text2go
+                   itinernary->add-route-url
+                   itinernary->add-route-span
+                   )))
 (defresource ws-otp-pass-through [otp-instance route-params params request]
   :last-modified  #inst "2015-04-09"
   :available-media-types ["application/json" "text/plain"]
@@ -267,8 +313,8 @@
   ;; (ANY "/otp-params/:otp-instance" {params :params}
   (context "/trip-planner/:otp-instance" [otp-instance]
     ;; (ANY "/pass-through" {route-params :route-params params :params}
-     (ANY "/plan" []
-       (ws-otp-example))
+     (ANY "/plan" request
+       (ws-otp-with-args (:params request)))
      (ANY "/plan-cooked" []
        (ws-otp-cooked))
      (ANY "/pass-through" request


last 3 top lookbacks

last 3 top lookbacks

--- src/paulkrake/crossval.clj
+++ src/paulkrake/crossval.clj
@@ -82,6 +82,6 @@
         (apply merge-with + x)
         (sort-by second x)
         #_(reverse x)
-        (first x)))
+        (take 3 x)))


Improve comments on handlers

Improve comments on handlers

--- src/re_frame/handlers.cljs
+++ src/re_frame/handlers.cljs
@@ -29,7 +29,7 @@
 ;; -- The Event Conveyor Belt  --------------------------------------------------------------------
 ;;
 ;; Moves events from "dispatch" to the router loop.
-;; This alows for aysnc handling of events.
+;; Allows for the aysnc handling of events.
 ;;
 (def ^:private event-chan (chan))    ;; TODO: how big should we make the buffer?

@@ -37,7 +37,14 @@
 ;; -- lookup and call -----------------------------------------------------------------------------

 (defn- handle
-  "Look up the handler for the given event, then call it, passing in 2 parameters."
+  "Given an event vector, look up the right handler, then call it.
+  By default, handlers are not assumed to be pure. They are called with
+  two paramters:
+  - the `app-db` atom and
+  - the event vector
+  The handler is assumed to side-effect on the atom, the return value is ignored.
+   To write handlers that are pure functions, use the \"pure\" middleware at handler
+   registration time."
   [event-v]
   (let [event-id    (first-in-vector event-v)
         handler-fn  (get @id->fn event-id)]
@@ -48,7 +55,7 @@

 ;; -- router loop ---------------------------------------------------------------------------------
 ;;
-;; In a loop, read events from the dispatch channel, and route them
+;; In a perpretual loop, read events from the dispatch channel, and route them
 ;; to the right handler.
 ;;
 ;; Because handlers occupy the CPU, before each event is handled, hand
@@ -57,7 +64,7 @@
 ;; In odd cases, we need to pause for an entire annimationFrame, to ensure that
 ;; the DOM is fully flushed, before then calling a handler known to hog the CPU
 ;; for an extended period.  In such a case, the event should be laballed with metadata
-;; Example usage:
+;; Example usage (notice the ":flush-dom" metadata):
 ;;   (dispatch ^:flush-dom  [:event-id other params])
 ;;
 ;; router loop
@@ -79,10 +86,11 @@
   [event-v]
   (if (nil? event-v)
     (warn "re-frame: \"dispatch\" is ignoring a nil event.")     ;; nil would close the channel
-    (put! event-chan event-v)))
+    (put! event-chan event-v))
+  nil)   ;; Ensure nil return. See https://github.com/Day8/re-frame/wiki/Returning-False

-;; TODO: remove sync handling.  I don't like it, even for testing.
+;; TODO: remove sync handling.  I don't like it much, even for testing.
 (defn dispatch-sync
   "Invoke the event handler sycronously, avoiding the async-inducing use of core.async/chan"
   [event-v]


CMR-2353 Create test for native format granule counts that tests if counts match up.

--- system-int-test/test/cmr/system_int_test/search/granule_counts_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/granule_counts_search_test.clj
@@ -148,8 +148,10 @@
                                                        coll6 3 orbit-coll 1} refs))))

       (testing "granule counts for native collections"
-          (is (= nil (get (search/find-metadata :collection :native {:include-granule-counts true}) :errors))))
-
+        (let [granules (search/find-metadata :collection :native {:include-granule-counts true})]
+          (is (= nil (get granules :errors)))
+          (is (gran-counts/granule-counts-match? :echo10 {coll1 5 coll2 0 coll3 3 coll4 3
+                                                          coll5 3 coll6 3 orbit-coll 1} granules))))
       ;; CMR-712
       (testing "granule counts with science keywords query"
         (let [refs (search/find-refs :collection {:include-granule-counts true


State.

State.

--- test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_020_atoms.clj
+++ test/com/nomistech/clojure_the_language/c_400_state_and_concurrency/s_020_atoms.clj
@@ -86,12 +86,10 @@
 ;;;;
 ;;;; - Each thread uses `swap!` with a function that runs for a long time.
 ;;;;
-;;;; - Terminology: I'm calling the function passed to `swap!` a "data function".
-;;;;
 ;;;; - Clojure allows each thread that calls `swap!` to be optimistic.
 ;;;;   - So multiple data functions run concurrently (for the same atom).
 ;;;;
-;;;; - When a data function finishes:
+;;;; - When a data function returns the new value:
 ;;;;   - If the current value of the atom is the same as the value when the
 ;;;;     function started
 ;;;;     (this means that this data function did its work based on the


(TK-258) Test default /puppet/v3/environments rule

Without this patch there is no test coverage of the first default rule
in the existing Ruby auth.conf [1]  This patch adds the coverage.  The
test currently specifies that the request should be allowed, which is
technically correct given that [TK-260][2] has not yet been implemented.

The structure is in place, however, for the `allowed?` method to check
the status of the `authentic?` sub-key.

This first rule should deny any unauthenticated request.  It does not,
however, which means the implementation needs to be updated.

[1]: https://github.com/puppetlabs/puppet/blob/826cee5/conf/auth.conf#L63-L65
[2]: https://tickets.puppetlabs.com/browse/TK-260

--- test/puppetlabs/trapperkeeper/services/authorization/authorization_service_test.clj
+++ test/puppetlabs/trapperkeeper/services/authorization/authorization_service_test.clj
@@ -46,6 +46,12 @@
   "Minimal config with a basic rule layered on top."
   (assoc-in minimal-config [:authorization :rules] basic-rules))

+(def default-rules
+  "A representative example list of rules intended to model the defaults"
+  [{:path "/puppet/v3/environments"
+    :type "path"
+    :allow "*"}])
+
 (def catalog-request-nocert
   "A basic request for a catalog without a valid SSL cert"
   {:uri "/puppet/v3/catalog/localhost"
@@ -92,4 +98,18 @@
             (testing "Request is denied due to unauthenticated request"
               (is (= 401 status))
               (is (= body (str "Forbidden request: (127.0.0.1) "
-                               "access to /puppet/v3/catalog/s1 (method :get)"))))))))))
+                               "access to /puppet/v3/catalog/s1 (method :get)"))))))))
+    (testing "With a semi-complex configuration representing our defaults"
+      (with-app-with-config
+        app
+        [echo-reverse-service authorization-service]
+        (assoc-in minimal-config [:authorization :rules] default-rules)
+        (let [svc (get-service app :EchoReverseService)
+              echo-handler (echo-reverse svc "Prefix: ")]
+          (let [req (assoc base-request :uri "/puppet/v3/environments"
+                                        :body "Hello World!")
+                {:keys [body status]} (echo-handler req)]
+            (testing "Request is allowed because name empty-string matches glob"
+              ; FIXME This should be denied, not authentic, no ssl cert
+              (is (= 200 status))
+              (is (= body (str "Prefix: !dlroW olleH"))))))))))


Updated test results to match feature delivery.

--- test/cmr/opendap/tests/system/rest/app/ous.clj
+++ test/cmr/opendap/tests/system/rest/app/ous.clj
@@ -15,7 +15,7 @@

 (use-fixtures :once test-system/with-system)

-(deftest ous-collection-get-with-collection-params
+(deftest ous-collection-get-with-v2-params
   (testing "Minimal GET ..."
     (let [collection-id "C1200187767-EDF_OPS"
           response @(httpc/get
@@ -143,9 +143,30 @@
               :variables []
               :subset nil
               :bounding-box "-9.984375,56.109375,19.828125,67.640625"}
+             (util/parse-response response)))))
+  (testing "GET with variables, graules, and bounding box ..."
+    (let [collection-id "C1200187767-EDF_OPS"
+          response @(httpc/get
+                     (format (str "http://localhost:%s"
+                                  "/opendap/ous/collection/%s"
+                                  "?variables=V1200241812-EDF_OPS&"
+                                  "granules=G1200187775-EDF_OPS&"
+                                  "bounding-box="
+                                  "-9.984375,56.109375,19.828125,67.640625")
+                             (test-system/http-port)
+                             collection-id)
+                     (request/add-token-header {} (util/get-sit-token)))]
+      (is (= 200 (:status response)))
+      (is (= {:collection-id "C1200187767-EDF_OPS"
+              :format "nc"
+              :granules []
+              :exclude-granules false
+              :variables []
+              :subset nil
+              :bounding-box "-9.984375,56.109375,19.828125,67.640625"}
              (util/parse-response response))))))

-(deftest ous-collection-post-with-collection-params
+(deftest ous-collection-post-with-v2-params
   (testing "Minimal POST ..."
     (let [collection-id "C1200187767-EDF_OPS"
           response @(httpc/post
@@ -159,13 +180,8 @@
                       (request/add-token-header
                        {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules []
-              :exclude-granules false
-              :variables []
-              :subset nil
-              :bounding-box nil}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc"]
              (util/parse-response response)))))
   (testing "POST with one variable ..."
     (let [collection-id "C1200187767-EDF_OPS"
@@ -179,13 +195,8 @@
                        {:variables ["V1200241812-EDF_OPS"]})
                        (request/add-token-header {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules []
-              :exclude-granules false
-              :variables ["V1200241812-EDF_OPS"]
-              :subset nil
-              :bounding-box nil}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A_ct,Latitude,Longitude"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc?CH4_VMR_A_ct,Latitude,Longitude"]
              (util/parse-response response)))))
   (testing "POST with variables ..."
     (let [collection-id "C1200187767-EDF_OPS"
@@ -200,13 +211,8 @@
                                     "V1200241813-EDF_OPS"]})
                        (request/add-token-header {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules []
-              :exclude-granules false
-              :variables ["V1200241812-EDF_OPS" "V1200241813-EDF_OPS"]
-              :subset nil
-              :bounding-box nil}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"]
              (util/parse-response response)))))
   (testing "POST with granules ..."
     (let [collection-id "C1200187767-EDF_OPS"
@@ -222,13 +228,8 @@
                       (request/add-token-header
                        {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules ["G1200187775-EDF_OPS" "G1200245955-EDF_OPS"]
-              :exclude-granules false
-              :variables []
-              :subset nil
-              :bounding-box nil}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc"]
              (util/parse-response response)))))
   (testing "POST without granules ..."
     (let [collection-id "C1200187767-EDF_OPS"
@@ -267,13 +268,8 @@
                       (request/add-token-header
                        {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules []
-              :exclude-granules false
-              :variables []
-              :subset ["lat(56.109375,67.640625)" "lon(-9.984375,19.828125)"]
-              :bounding-box nil}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc"]
              (util/parse-response response)))))
   (testing "POST with bounding box ..."
     (let [collection-id "C1200187767-EDF_OPS"
@@ -288,16 +284,11 @@
                       (request/add-token-header
                        {} (util/get-sit-token))))]
       (is (= 200 (:status response)))
-      (is (= {:collection-id "C1200187767-EDF_OPS"
-              :format "nc"
-              :granules []
-              :exclude-granules false
-              :variables []
-              :subset nil
-              :bounding-box "-9.984375,56.109375,19.828125,67.640625"}
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc"]
              (util/parse-response response))))))

-(deftest ous-collection-get-with-prototype-params
+(deftest ous-collection-get-with-v1-params
   (testing "GET with coverage ..."
     (let [collection-id "C1200187767-EDF_OPS"
           response @(httpc/get


Keyword regex context test

Keyword regex context test

--- test/compojure/test/core.clj
+++ test/compojure/test/core.clj
@@ -84,10 +84,14 @@
    (request :get "/bar")))

 (deftest context-test
-  (testing "matching"
+  (testing "keyword matching"
     (let [handler (context "/foo/:id" [id] identity)]
       (is (map? (handler (request :get "/foo/10"))))
       (is (nil? (handler (request :get "/bar/10"))))))
+  (testing "regex matching"
+    (let [handler (context ["/foo/:id" :id #"\d+"] [id] identity)]
+      (is (map? (handler (request :get "/foo/10"))))
+      (is (nil? (handler (request :get "/foo/ab"))))))
   (testing "context key"
     (let [handler (context "/foo/:id" [id] :context)]
       (are [url ctx] (= (handler (request :get url)) ctx)


Fix mixin test

Fix mixin test

Assertions were missing equality check

--- test/om_tools/core_test.cljs
+++ test/om_tools/core_test.cljs
@@ -199,13 +199,13 @@
 (defmixin test-mixin
   (display-name [] :display-name)
   (init-state [] :init-state)
-  (should-update [_ _] :should-update)
+  (should-update [x y] [:should-update x y])
   (will-mount [] :will-mount)
   (did-mount [] :did-mount)
   (will-unmount [] :will-unmount)
-  (will-update [_ _] :will-update)
-  (did-update [_ _] :did-update)
-  (will-receive-props [_] :will-receive-props))
+  (will-update [x y] [:will-update x y])
+  (did-update [x y] [:did-update x y])
+  (will-receive-props [x] [:will-receive-props x]))

 (deftest defmixin-test
   (is (object? test-mixin))
@@ -220,24 +220,24 @@
            "componentWillReceiveProps"}
          (set (js-keys test-mixin))))
   (is (every? fn? (map #(aget test-mixin %) (js-keys test-mixin))))
-  (is :display-name
-      (.getDisplayName test-mixin))
-  (is :init-state
-      (.getInitialState test-mixin))
-  (is :should-update
-      (.shouldComponentUpdate test-mixin nil nil))
-  (is :will-mount
-      (.componentWillMount test-mixin))
-  (is :did-mount
-      (.componentDidMount test-mixin))
-  (is :will-unmount
-      (.componentWillUnmount test-mixin))
-  (is :will-update
-      (.componentWillUpdate test-mixin nil nil))
-  (is :did-update
-      (.componentDidUpdate test-mixin nil nil))
-  (is :will-receive-props
-      (.componentWillReceiveProps test-mixin nil)))
+  (is (= :display-name
+         (.getDisplayName test-mixin)))
+  (is (= :init-state
+         (.getInitialState test-mixin)))
+  (is (= [:should-update :next-props :next-state]
+         (.shouldComponentUpdate test-mixin :next-props :next-state)))
+  (is (= :will-mount
+         (.componentWillMount test-mixin)))
+  (is (= :did-mount
+         (.componentDidMount test-mixin)))
+  (is (= :will-unmount
+         (.componentWillUnmount test-mixin)))
+  (is (= [:will-update :next-props :next-state]
+         (.componentWillUpdate test-mixin :next-props :next-state)))
+  (is (= [:did-update :prev-props :prev-state]
+         (.componentDidUpdate test-mixin :prev-props :prev-state)))
+  (is (= [:will-receive-props :next-props]
+         (.componentWillReceiveProps test-mixin :next-props))))

 (defmixin test-mixin2
   (will-mount [] (this-as this


added more tests to ensure that describe won't shift from under us

--- test/specly/core_test.clj
+++ test/specly/core_test.clj
@@ -143,8 +143,36 @@
            :opt-un
            [:specly.core-test/a :specly.core-test/b])))

-
-
+  (is (= (s/describe (strict-keys :opt-un [::a ::b]
+                                  :opt [::c ::d]))
+         '(strict-keys
+           :opt
+           [:specly.core-test/c :specly.core-test/d]
+           :opt-un
+           [:specly.core-test/a :specly.core-test/b])))
+
+  (is (= (s/describe (s/map-of keyword? even?))
+         '(and (coll-of (tuple keyword? even?) {}) map?)))
+
+  (is (= (s/describe (s/or :yep (s/map-of keyword? even?)))
+         '(or :yep (map-of keyword? even?))))
+
+  (is (= (s/describe (s/and (s/map-of keyword? even?)))
+         '(and (map-of keyword? even?))))
+
+  (is (= (s/describe (s/coll-of keyword? []))
+         '(coll-checker keyword?)))
+
+  (is (= (s/describe (s/and (s/coll-of keyword? [])))
+         '(and (coll-of keyword? []))))
+
+  (is (= (s/describe (s/+ even?))
+         '(+ even?)))
+  (is (= (s/describe (s/* even?))
+         '(* even?)))
+  (is (= (s/describe (s/? even?))
+         '(? even?)))
+
   )

 (deftest pathfinding


CMR-3529 - Added integration test for checking the report cache.

--- system-int-test/test/cmr/system_int_test/search/collection_humanized_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_humanized_search_test.clj
@@ -1,16 +1,21 @@
 (ns cmr.system-int-test.search.collection-humanized-search-test
   "Integration test for CMR collection search by humanized fields"
   (:require
+   [cheshire.core :as json]
+   [clj-http.client :as client]
    [clojure.string :as str]
    [clojure.test :refer :all]
    [cmr.common-app.test.side-api :as side]
+   [cmr.mock-echo.client.echo-util :as e]
    [cmr.search.services.humanizers.humanizer-report-service :as hrs]
    [cmr.system-int-test.data2.core :as d]
    [cmr.system-int-test.data2.umm-spec-collection :as data-umm-c]
+   [cmr.system-int-test.system :as s]
    [cmr.system-int-test.utils.humanizer-util :as hu]
    [cmr.system-int-test.utils.index-util :as index]
    [cmr.system-int-test.utils.ingest-util :as ingest]
    [cmr.system-int-test.utils.search-util :as search]
+   [cmr.system-int-test.utils.url-helper :as url]
    [cmr.umm-spec.test.location-keywords-helper :as lkt]))

 (use-fixtures :each (join-fixtures
@@ -26,6 +31,30 @@
     {:system (get-in user/system [:apps :search])}))
 ;;3. Retrieve the reporting
 ;;  curl http://localhost:3003/humanizers/report
+
+(defn- get-cached-report
+  "Gets the value for a given key from the given cache."
+  []
+  (let [full-url (str (url/search-read-caches-url)
+                      "/"
+                      (name hrs/report-cache-key)
+                      "/"
+                      (name hrs/csv-report-cache-key))
+        admin-read-group-concept-id (e/get-or-create-group (s/context)
+                                                           "admin-read-group")
+        admin-read-token (e/login (s/context)
+                                  "admin"
+                                  [admin-read-group-concept-id])
+        response (client/request {:url full-url
+                                  :method :get
+                                  :query-params {:token admin-read-token}
+                                  :connection-manager (s/conn-mgr)
+                                  :throw-exceptions false})
+        status (:status response)]
+    ;; Make sure the status returned success
+    (when-not (= status 200)
+      (throw (Exception. (str "Unexpected status " status " response:" (:body response)))))
+    (json/decode (:body response) true)))

 (deftest humanizer-report
   (d/ingest-umm-spec-collection "PROV1" (data-umm-c/collection 1
@@ -60,7 +89,9 @@
               "PROV1,C1200000008-PROV1,B,V2,AM-1,Terra"
               "PROV1,C1200000009-PROV1,C,V3,Bioosphere,Biosphere"
               "PROV1,C1200000009-PROV1,C,V3,USGS_SOFIA,USGS SOFIA"]
-             (str/split report #"\n"))))))
+             (str/split report #"\n")))
+      (testing "Ensure that the returned report is the same as the cached one"
+      (is (= report (get-cached-report)))))))

 (deftest humanizer-report-batch
   (side/eval-form `(hrs/set-humanizer-report-collection-batch-size! 10))


I think I finally have these macros working as required - not beautiful, but time is pressing...

--- dada-core/src/main/clojure/org/dada/core/utils.clj
+++ dada-core/src/main/clojure/org/dada/core/utils.clj
@@ -51,17 +51,111 @@

 ;;--------------------------------------------------------------------------------

-(defmacro make-singleton-key-fn [datum-class key]
-  "return a fn that given a datum of class datum-class returns the value of .key applied to that datum."
-  ;; (let [datum 'datum#
-  ;; 	datum-with-meta (with-meta datum {:tag datum-class})]
-  ;;   `(fn [~datum-with-meta] (. ~datum ~key))
-  ;;   )
-  ;;(list 'fn [(with-meta 'datum {:tag datum-class})] (list '. 'datum key)))
-  `(fn [~(with-meta `datum# {:tag datum-class})] (. `datum# ~key))
-  )
-
-(defmacro make-compound-key-fn [datum-class keys]
+;; (defmacro make-singleton-key-fn [datum-class key]
+;;   "return a fn that given a datum of class datum-class returns the value of .key applied to that datum."
+;;   ;; (let [datum 'datum#
+;;   ;; 	datum-with-meta (with-meta datum {:tag datum-class})]
+;;   ;;   `(fn [~datum-with-meta] (. ~datum ~key))
+;;   ;;   )
+;;   ;;(list 'fn [(with-meta 'datum {:tag datum-class})] (list '. 'datum key)))
+
+;;   ;; (let [datum 'datum#]
+;;   ;; `(fn [~(with-meta datum {:tag datum-class})] (. ~datum ~key))
+;;   ;; )
+
+;;   ;;  `(fn [~(with-meta datum# {:tag datum-class})] (. ~datum ~key))
+
+
+;;   ;;)
+
+;;   ;;(let [datum (gensym 'datum)]
+;;   ;;(list 'fn [(with-meta datum {:tag datum-class})] (list '. datum key)))
+
+;;   (let [datum (gensym 'datum)]
+;;     `(fn [~(with-meta datum {:tag datum-class})]
+;;        (. ~datum ~key)))
+
+;;   )
+
+;; (defmacro make-singleton-key-creator [datum-class key]
+;;   (let [datum (gensym 'datum)]
+;;     `(reify Creator (create [this [~(with-meta datum {:tag datum-class}) & _#]] (. ~datum ~key)))))
+
+(defmacro make-singleton-key-getter [datum-class key]
+  (let [datum (gensym 'datum)]
+    `(reify Getter (get [this ~datum] (. ~(with-meta datum {:tag datum-class}) ~key)))))
+
+;; (defmacro make-compound-key-fn [datum-class keys]
+;;   "return a fn that given a datum of class datum-class and a set of
+;; keys, creates a key class that references an instance of datum-class
+;; and implements its hash code and equality in terms of the values
+;; associated with said keys on referenced instance and returns a fn that
+;; will manufacture and instance of this class that refers to an instance
+;; of datum-class. - i,e, creates a minimal footprint compound key."
+;;   (let [key-class (symbol (str datum-class "Key"))
+;; 	datum (with-meta 'datum {:tag datum-class})
+;; 	that-datum (with-meta 'that-datum {:tag datum-class})
+;; 	that 'that
+;; 	that-with-type (with-meta that {:tag key-class})
+;; 	]
+;;     (eval
+;;      `(deftype ~key-class
+;; 	[~datum]
+;; 	Object
+;; 	(^int hashCode [this]
+;; 	      (+ ~@(map (fn [key] `(. ~datum ~key)) keys)))
+;; 	(^boolean equals [this ~that]
+;; 		  (and (not (nil? ~that))
+;; 		       (instance? ~key-class ~that)
+;; 		       ~@(map
+;; 			  (fn [key]
+;; 			      `(= (. ~datum ~key)
+;; 				  (let [~that-datum (.datum ~that-with-type)]
+;; 				    (. ~that-datum ~key))))
+;; 			  keys)))
+;; ;;	(^String toString [this]
+;; ;;		 (str ~keys))
+;; 	))
+;;     `(fn [datum#]
+;;      	 (new ~key-class datum#))
+;;     ))
+
+;; (defmacro make-compound-key-creator [datum-class keys]
+;;   "return a fn that given a datum of class datum-class and a set of
+;; keys, creates a key class that references an instance of datum-class
+;; and implements its hash code and equality in terms of the values
+;; associated with said keys on referenced instance and returns a fn that
+;; will manufacture and instance of this class that refers to an instance
+;; of datum-class. - i,e, creates a minimal footprint compound key."
+;;   (let [key-class (symbol (str datum-class "Key"))
+;; 	datum (with-meta 'datum {:tag datum-class})
+;; 	that-datum (with-meta 'that-datum {:tag datum-class})
+;; 	that 'that
+;; 	that-with-type (with-meta that {:tag key-class})
+;; 	]
+;;     (eval
+;;      `(deftype ~key-class
+;;           [~datum]
+;; 	Object
+;; 	(^int hashCode [this]
+;;           (+ ~@(map (fn [key] `(. ~datum ~key)) keys)))
+;; 	(^boolean equals [this ~that]
+;;           (and (not (nil? ~that))
+;;                (instance? ~key-class ~that)
+;;                ~@(map
+;;                   (fn [key]
+;;                     `(= (. ~datum ~key)
+;;                         (let [~that-datum (.datum ~that-with-type)]
+;;                           (. ~that-datum ~key))))
+;;                   keys)))
+;;         ;;	(^String toString [this]
+;;         ;;		 (str ~keys))
+;; 	))
+;;     (let [datum (gensym 'datum)]
+;;       `(reify Creator (create [this [~(with-meta datum {:tag datum-class}) & _#]] (new ~key-class ~datum))))
+;;     ))
+
+(defmacro make-compound-key-getter [datum-class keys]
   "return a fn that given a datum of class datum-class and a set of
 keys, creates a key class that references an instance of datum-class
 and implements its hash code and equality in terms of the values
@@ -76,31 +170,35 @@
 	]
     (eval
      `(deftype ~key-class
-	[~datum]
+          [~datum]
 	Object
 	(^int hashCode [this]
-	      (+ ~@(map (fn [key] `(. ~datum ~key)) keys)))
+          (+ ~@(map (fn [key] `(. ~datum ~key)) keys)))
 	(^boolean equals [this ~that]
-		  (and (not (nil? ~that))
-		       (instance? ~key-class ~that)
-		       ~@(map
-			  (fn [key]
-			      `(= (. ~datum ~key)
-				  (let [~that-datum (.datum ~that-with-type)]
-				    (. ~that-datum ~key))))
-			  keys)))
-;;	(^String toString [this]
-;;		 (str ~keys))
+          (and (not (nil? ~that))
+               (instance? ~key-class ~that)
+               ~@(map
+                  (fn [key]
+                    `(= (. ~datum ~key)
+                        (let [~that-datum (.datum ~that-with-type)]
+                          (. ~that-datum ~key))))
+                  keys)))
+        ;;	(^String toString [this]
+        ;;		 (str ~keys))
 	))
-    `(fn [datum#]
-     	 (new ~key-class datum#))
+    (let [datum (gensym 'datum)]
+      `(reify Getter (get [this ~datum] (new ~key-class ~(with-meta datum {:tag datum-class})))))
     ))

-(defn xxx [x y] x)
-
-;; (defn make-ref-key-fn [data-class keys]
+;; (defmacro make-ref-key-fn [clazz keys]
 ;;   (if (instance? Collection keys)
-;; ;;    (make-compound-key-fn data-class keys)
-;;     (xxx data-class keys)
-;;     (make-singleton-key-fn data-class keys)
-;;     ))
+;;      `(make-compound-key-fn ~clazz ~keys)
+;;      `(make-singleton-key-fn ~clazz ~keys)
+;;      ))
+
+(defmacro make-key-getter [clazz keys]
+  (if (> (count keys) 1)
+    `(make-compound-key-getter ~clazz ~keys)
+    `(make-singleton-key-getter ~clazz ~(first keys))
+    ))
+


Update test_parser.clj

Update test_parser.clj

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -27,6 +27,7 @@

 #_((value-tag {:tag-value "foo.bar.baz"}) {:foo {:bar {:baz "ok"}}})
 #_((value-tag {:tag-value "foo"}) {:foo "ok"})
+;ok

 (defn read-tag-info [rdr]
   (let [buf (StringBuilder.)
@@ -44,7 +45,10 @@
                 :params (rest content)})))))

 #_(read-tag-info (java.io.StringReader. "% for i in nums %}"))
+;{:params ("i" "in" "nums"), :tag-name "for", :tag-type :expr}
+
 #_(read-tag-info (java.io.StringReader. "{ nums }}"))
+;{:tag-value "nums", :tag-type :value}

 (defn tag-content [close-tag rdr]
   (let [content (transient [])
@@ -69,6 +73,7 @@
 #_(tag-content "endfor" (java.io.StringReader. "foo {{name}} bar {% endfor %}"))

 #_(render (tag-content "endfor" (java.io.StringReader. "foo {{name.first}} bar {% endfor %}")) {:name {:first "Bob"}})
+;"foo Bob bar "

 (def expr-tags
   {:for {:content true


updated render-file to call render

updated render-file to call render

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -20,11 +20,11 @@
   (let [{:keys [template last-modified]} (get @templates filename)
         last-modified-file (.lastModified (java.io.File. filename))]
     (if (and last-modified (= last-modified last-modified-file))
-      template
+      (render template args)
       (let [template (parse filename)]
         (swap! templates assoc filename {:template template
                                          :last-modified last-modified-file})
-        template))))
+        (render template args)))))

 (defn read-char [rdr]
   (let [ch (.read rdr)]


Field variant considers table to pick translation field

--- src/server/pathom/sql.cljs
+++ src/server/pathom/sql.cljs
@@ -78,7 +78,10 @@
   (and (vector? value)
        (= (first value) name)))

-(defn translate-args [{:keys [::schema] :as env} cmds]
+(s/def ::field-variant
+  (s/cat :variant #{::f} :table (s/? keyword?) :field qualified-keyword?))
+
+(defn translate-args [{:keys [::schema]} cmds]
   (let [{:keys [::translate-index]} schema]
     (walk/prewalk
       (fn [x]
@@ -90,13 +93,11 @@
               v)
             x)

-          (variant? x ::f)
-          (let [v (second x)
-                x (if (and (= 2 (cljs.core/count x))
-                           (qualified-keyword? v))
-                    [(first x) (keyword (namespace v)) v]
-                    x)]
-            (str/join "." (translate-args env (rest x))))
+          (s/valid? ::field-variant x)
+          (let [{:keys [table field]} (s/conform ::field-variant x)
+                table (or table (keyword (namespace field)))
+                {::keys [table-name fields]} (get schema table)]
+            (str table-name "." (get fields field)))

           :else
           x))


fixed tests

fixed tests

--- test/sormilla/drone_test.clj
+++ test/sormilla/drone_test.clj
@@ -58,15 +58,15 @@

 (facts pitch
   (pitch    0.0) => (roughly  0.0)
-  (pitch -100.0) => (roughly -1.0)
-  (pitch  100.0) => (roughly  1.0)
-  (pitch  120.0) => (roughly  1.0))
+  (pitch -100.0) => (roughly -0.7)
+  (pitch  100.0) => (roughly  0.7)
+  (pitch  120.0) => (roughly  0.8))

 (facts roll
   (roll   0.0) => (roughly  0.0)
-  (roll  -0.6) => (roughly -1.0)
-  (roll   0.6) => (roughly  1.0)
-  (roll   0.8) => (roughly  1.0))
+  (roll  -0.6) => (roughly -0.8)
+  (roll   0.6) => (roughly  0.8)
+  (roll   0.8) => (roughly  0.8))

 (facts move-command
   (move-command nil) => comm/hover
@@ -74,6 +74,6 @@
   (move-command {:keys {:right true}})            => (comm/move 0.0 0.0 yaw-speed 0.0)
   (move-command {:keys {:right true :up true}})   => (comm/move 0.0 0.0 yaw-speed alt-speed)
   (move-command {:keys {:right true :up true}
-                 :leap {:pitch 100.0 :roll 0.6}}) => (comm/move 1.0 1.0 yaw-speed alt-speed)
+                 :leap {:pitch 100.0 :roll 0.6}}) => (comm/move 0.7 0.8 yaw-speed alt-speed)

   )


Add test for Issue #230.

Add test for Issue #230.

--- test/zprint/zprint_test.cljc
+++ test/zprint/zprint_test.cljc
@@ -6801,6 +6801,14 @@
 "(deftest\n  ^{:database-a-bit-longer :does-not-fit, ::test.hooks/system-init-keys system-keys}\n  websocket-diagnostic-report-measurements-updated-event\n  (let [foo (bar \"1\")] foo))\n"
 {:parse-string? true :style [:community :meta-alt]}))

+;;
+;; Issue #230
+;;
+
+(expect
+"(let)"
+(zprint-file-str "(let)" "stuff" {}))
+


convenience fn for starting austin

convenience fn for starting austin

--- pedestal-app/dev/user.clj
+++ pedestal-app/dev/user.clj
@@ -2,3 +2,13 @@
   []
   (require 'dev)
   (in-ns 'dev))
+
+(require 'cemerick.austin.repls)
+(defn repl
+  "Start Austin cljs-repl and saves repl environment to repl-env.
+  Connect a browser by calling this JS:
+    ;goog.require ('clojure.browser.repl');clojure.browser.repl.connect.call(null, ':repl-url');"
+  []
+  (defonce repl-env (cemerick.austin/repl-env))
+  (println (str "Started austin with repl-url " (:repl-url repl-env)))
+  (cemerick.austin.repls/cljs-repl repl-env))


cleanup subscriber mouse as soon as the drawing starts

--- src-cljs/frontend/components/drawing.cljs
+++ src-cljs/frontend/components/drawing.cljs
@@ -420,6 +420,7 @@
   (let [max-tick (apply max (keys (:ticks tick-state)))]
     (-> tick-state
       (add-tick (inc max-tick) (fn [owner]
+                                 (cleanup owner)
                                  ((om/get-shared owner :cast!) :landing-animation-completed)))
       (annotate-keyframes (inc max-tick)))))


Fix validate

Fix validate

--- src/egg/core.clj
+++ src/egg/core.clj
@@ -1,6 +1,7 @@
 (ns egg.core
   (:require [clojure.tools.cli :refer [parse-opts]]
-            [clojure.string :as string])
+            [clojure.string :as string]
+            [egg.validate :as validate])
   (:gen-class))

 ;; options
@@ -14,12 +15,12 @@

 (def validate-options
   [["-h" "--help"]
-   ["-p" "--path PATH"]])
+   ["-u" "--uri URI"]])

 ;; commands

-(defn validate! [options]
-  (println options))
+(defn validate! [name options]
+  (validate/eggy? (:path options)))

 ;; help


Made basic recommendations function

Made basic recommendations function

--- test/kmg/schema_test.clj
+++ test/kmg/schema_test.clj
@@ -179,42 +179,62 @@
   (is (= (attr-spec :feedback/complete)
          [:db.type/boolean :db.cardinality/one])))

-(defn recommendations [db spec]
-  (d/q '[:find  ?id ?media_id (max 7 ?priority)
-         :in $ ?spec
-         :where
-         [?id :recommendation/specialization ?spec]
-         [?id :recommendation/priority ?priority]
-         [?id :recommendation/media ?bid]
-         [?bid :media/id ?media_id]
-         ]
-       db [:specialization/id spec]))
-
-(defn recommendations-for-user [db user]
-  (d/q '[:find (max ?priority) ?rid ?media_id ?comment
+(defn recommendations-comleted-by-user [db user]
+  (->> (d/q '[:find ?id
          :in $ ?uid
          :where
          [?uid :user/name ?user]
          [?uid :user/goal ?sid]
          [?id :recommendation/specialization ?sid]
          [?id :recommendation/priority ?priority]
-         [?id :recommendation/media ?mid]
+;;       [?id :recommendation/media ?mid]
          [?id :recommendation/id ?rid]
-         [?completed_rec_id :recommendation/id ?rid]
+;;         [?completed_rec_id :recommendation/id ?rid]

          [?fid :feedback/user ?uid]
-         [?fid :feedback/recommendation ?completed_rec_id]
+         [?fid :feedback/recommendation ?id]
          [?fid :feedback.comment/text ?comment]
          [?fid :feedback/complete true]

-         [?mid :media/id ?media_id]
+;;         [?mid :media/id ?media_id]
          ]
-       db [:user/name user]))
-
+       db [:user/name user])
+       (every-first)
+       set))
+
+;;(before #(recommendations-comleted-by-user (db) "user1"))
+;;(before #(recommendations (db) "spec1"))
+(defn recommendations-for-user [db user]
+  (->> (d/q '[:find ?id (max ?priority)
+         :in $ ?uid
+         :where
+         [?uid :user/name ?user]
+         [?uid :user/goal ?sid]
+         [?id :recommendation/specialization ?sid]
+         [?id :recommendation/priority ?priority]
+;;         [?id :recommendation/media ?mid]
+;;         [?id :recommendation/id ?rid]
+;;         [?completed_rec_id :recommendation/id ?rid]
+
+;;         [?mid :media/id ?media_id]
+         ]
+       db [:user/name user])
+  (every-first)
+  set))
 ;;(before #(recommendations-for-user (db) "user1"))
-;;(before #(recommendations (db) "spec1"))
-
-
+
+
+(defn every-first [v]
+  (for [elem v] (first elem)))
+
+;; (every-first [[17592186045432 1000] [17592186045433 900] [17592186045434 800]])
+(use 'clojure.data)
+(defn recommendations [db user]
+  (let [recs (recommendations-for-user db user)
+        completed (recommendations-comleted-by-user db user)]
+    (first (diff recs completed))))
+
+;; (before #(recommendations (db) "user1"))

 (deftest test-kmg-test-data
   (is (= (d/q '[:find ?name


Might as well let gcc use multiple cores

--- tasks.clj
+++ tasks.clj
@@ -42,7 +42,8 @@
                (args prefix)
                (env {"CFLAGS" arch "LDFLAGS" arch}))
           (fix-install-path src "tokyocabinet")
-          (ant ExecTask {:executable "make" :dir src :failonerror true})
+          (ant ExecTask {:executable "make" :dir src :failonerror true}
+               (args "-j10"))
           (ant ExecTask {:executable "make" :dir src :failonerror true}
                (args "install")))
         (let [cflags (format " %s -I%s/include -L%s/lib " arch dest dest)


Gui: structure of main.clj organised

Gui: structure of main.clj organised

--- src/gui/main.clj
+++ src/gui/main.clj
@@ -12,19 +12,7 @@

 ; register own editor parser for highlighting
 (let [tmf (TokenMakerFactory/getDefaultInstance)]
-  (.putMapping tmf "text/mpa" "fully.qualified.MpaTokenMaker"))
-
-(def test-tree
-  (Node. "Project_1" (list
-                       (Node. "Formel_1" "a&b")
-                       (Node. "Formel_2" "a->b"))))
-
-; tree-model
-(def tree-model
-  (simple-tree-model
-    #(.getChildren %)
-    #(.getChildren %)
-    test-tree))
+  (.putMapping tmf "text/mpa" "fully.qualified.MpaTokenMaker"))

 ; result handling
 ; this must be placed here, so it can be accessed from handler.clj
@@ -47,7 +35,18 @@
 (load "handler")
 (load "menus")

-; final window building
+; project file tree
+(def test-tree
+  (Node. "Project_1" (list
+                       (Node. "Formel_1" "a&b")
+                       (Node. "Formel_2" "a->b"))))
+
+(def tree-model
+  (simple-tree-model
+    #(.getChildren %)
+    #(.getChildren %)
+    test-tree))
+
 (def form-tree (scrollable (tree
                              :id :tree
                              :model tree-model
@@ -55,6 +54,7 @@
                            :preferred-size [255 :by 600]
                            :maximum-size [255 :by 32000]))

+; final window building
 (def editor (syntax/text-area :syntax :mpa))
 (def form-editor (scrollable editor
                              :preferred-size [690 :by 400]))


make `content-task` return the fileset

make `content-task` return the fileset

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -287,8 +287,9 @@
             1 (perun/report-info task-name "copied unchanged file %s" (first (keys copy-files)))
             (perun/report-info task-name "copied %s unchanged file(s)" (count copy-files)))
           (boot/empty-dir! tmp)
-          (next-task output-fs)
-          (pod/with-call-in @pod (io.perun.render/reset-refreshed!)))))))
+          (let [result-fs (next-task output-fs)]
+            (pod/with-call-in @pod (io.perun.render/reset-refreshed!))
+            result-fs))))))

 (defn content-paths
   "Returns a map of path -> parser input for basic content tasks"


Fix #63 - Add paginate task

Fix #63 - Add paginate task

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -715,6 +715,44 @@
         grouper #(-> {p {:entries %}})]
     (assortment-impl "collection" :io.perun/collection grouper options)))

+(def ^:private +paginate-defaults+
+  {:out-dir "public"
+   :prefix "page-"
+   :page-size 10
+   :filterer :has-content
+   :sortby (fn [file] (:date-published file))
+   :comparator (fn [i1 i2] (compare i2 i1))})
+
+(deftask paginate
+  "Render multiple collections
+   The symbol supplied as `renderer` should resolve to a function
+   which will be called with a map containing the following keys:
+    - `:meta`, global perun metadata
+    - `:entry`, the metadata for this collection
+    - `:entries`, all entries
+
+   Entries can optionally be filtered by supplying a function
+   to the `filterer` option.
+
+   The `sortby` function can be used for ordering entries before rendering."
+  [o out-dir    OUTDIR     str  "the output directory"
+   f prefix     PREFIX     str  "the prefix for each html file, eg prefix-1.html, prefix-2.html (default: `\"page-\"`)"
+   p page-size  PAGESIZE   int  "the number of entries to include in each page (default: `10`)"
+   r renderer   RENDERER   sym  "page renderer (fully qualified symbol resolving to a function)"
+   _ filterer   FILTER     code "predicate to use for selecting entries (default: `:has-content`)"
+   s sortby     SORTBY     code "sort entries by function"
+   c comparator COMPARATOR code "sort by comparator function"
+   m meta       META       edn  "metadata to set on each collection entry"]
+  (let [options (merge +paginate-defaults+ *opts*)
+        grouper (fn [entries]
+                  (->> entries
+                       (sort-by (:sortby options) (:comparator options))
+                       (partition-all (:page-size options))
+                       (map-indexed #(-> [(str (:prefix options) (inc %1) ".html")
+                                          {:entries %2}]))
+                       (into {})))]
+    (assortment-impl "paginate" :io.perun/paginate grouper options)))
+
 (deftask inject-scripts
   "Inject JavaScript scripts into html files.
    Use either filter to include only files matching or remove to


[#5] Glyphicons for media

[#5] Glyphicons for media

--- src/kmg/core.clj
+++ src/kmg/core.clj
@@ -79,10 +79,23 @@
 (def render-to-response
   (comp html-response render))

+(def type->icon {:media.type/book "book"
+                 :media.type/article "file"
+                 :media.type/video "film"
+                 :media.type/podcast "headphones"
+                 :media.type/course "book"
+                 :media.type/blog "file"})
+
+(defn media-icon-span [media]
+  (str "icon (:media/type media)) "\"> "))
+
+(defn media-title [media]
+  (str (media-icon-span media) (:media/title media) " " ))
+
 (def tmpl "public/html/kmg.html")

 (html/defsnippet recommendation-completed tmpl [:div.recommendation-completed] [{:keys [media]}]
-  [:.recommendation-completed-title] (html/content (:media/title media)))
+  [:.recommendation-completed-title] (html/html-content (media-title media)))

 (html/defsnippet specialization-available tmpl [:div.specialization-available] [specialization]
   [:.specialization-available-title] (html/content (:specialization/title specialization)))


Add delay on health check

Add delay on health check

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -117,7 +117,9 @@
      (when (pos? n)
        (if (= 200 (:status @(http/get (str "http://" host ":" port "/") {:timeout 5000})))
          true
-         (recur (dec n)))))))
+         (do
+           (Thread/sleep 1000)
+           (recur (dec n))))))))

 (defn health-check-instances []
   (doseq [i (vals (:instances @router))]


lots of tweaks to the email message

lots of tweaks to the email message

--- src/pc/email.clj
+++ src/pc/email.clj
@@ -9,18 +9,21 @@
   (hiccup/html
    [:html
     [:body
-     [:p "Hey there,"]
      [:p
-      "Come draw with me on Precursor: "
+      "I'm prototyping something on Precursor, come join me at "
       [:a {:href (str "https://prcrsr.com/document/" doc-id)}
-       (str "https://prcrsr.com/document/" doc-id)]]
+       (str "https://prcrsr.com/document/" doc-id)]
+      "."]
+     [:p "This is what I have so far:"]
      [:p
-      [:a {:href (str "https://prcrsr.com/document/" doc-id)}
-       [:img {:width 256
-              :src (str "https://prcrsr.com/document/" doc-id ".png?printer-friendly=false")}]]]
+      [:a {:href (str "https://prcrsr.com/document/" doc-id)
+           :style "display: inline-block"}
+       [:img {:width 325
+              :style "border: 1px solid #888888;"
+              :alt "Images disabled? Just come and take a look."
+              :src (str "https://prcrsr.com/document/" doc-id ".png")}]]]
      [:p {:style "font-size: 12px"}
-      "If you think this message was an error, let us know: "
-      [:a {:href "mailto:info@prcrsr.com"} "info@prcrsr.com"] "."
+      "Tell us if this message is an error info@prcrsr.com."
       ;; Add some hidden text so that Google doesn't try to trim these.
       [:span {:style "display: none; max-height: 0px; font-size: 0px; overflow: hidden;"}
        " Sent at "
@@ -28,7 +31,7 @@
        "."]]]]))

 (defn send-chat-invite [{:keys [cust to-email doc-id]}]
-  (mailgun/send-message {:from "Precursor <draw@prcrsr.com>"
+  (mailgun/send-message {:from "Precursor <joinme@prcrsr.com>"
                          :to to-email
                          :subject (str/trim (str (:cust/first-name cust)
                                                  (when (and (:cust/first-name cust)


Test for ignore-case in starts- and ends-with

I just passed `false` as ignore-case and it did the wrong thing.  This
wasn't how I intended these to be used but I figure others might make
the same mistake

--- src/str/core.clj
+++ src/str/core.clj
@@ -68,9 +68,11 @@
    (when (.endsWith s suffix)
      s))
   ([^String s ^String suffix ignore-case]
-   (let [end (.substring s (max 0 (- (.length s) (.length suffix))))]
-     (when (.equalsIgnoreCase end suffix)
-       s))))
+   (if-not ignore-case
+     (ends-with? s suffix)
+     (let [end (.substring s (max 0 (- (.length s) (.length suffix))))]
+       (when (.equalsIgnoreCase end suffix)
+         s)))))

 (defn ^String starts-with?
   "Return s if s starts with with prefix.
@@ -80,9 +82,11 @@
    (when (.startsWith s prefix)
      s))
   ([^String s ^String prefix ignore-case]
-   (let [beg (.substring s 0 (.length prefix))]
-     (when (.equalsIgnoreCase beg prefix)
-       s))))
+   (if-not ignore-case
+     (starts-with? s prefix)
+     (let [beg (.substring s 0 (.length prefix))]
+       (when (.equalsIgnoreCase beg prefix)
+         s)))))

 (defn ^String chop
   "Return a new string with the last character removed.


threshold requires a different filtering technique

--- src-cljs/hello.cljs
+++ src-cljs/hello.cljs
@@ -43,8 +43,8 @@
 (defn update [game-world]
   (let [rockets (map update-rocket-step
                   (aget game-world :rockets))
-        spent (filter #(= 0 (get % :remaining-steps)) rockets)
-        remaining (filter #(not= 0 (get % :remaining-steps)) rockets)]
+        spent (filter #(>= (get % :pos-y) (get % :threshold)) rockets)
+        remaining (filter #(< (get % :pos-y) (get % :threshold)) rockets)]
     (aset game-world :rockets remaining)))

 (defn clear-for-frame [graphics-context]


*Do use* the configuration file for origin-re

--- server/src/patavi/server/handlers.clj
+++ server/src/patavi/server/handlers.clj
@@ -34,7 +34,7 @@
     {:error {:uri service-rpc-uri
              :message (str "service " method " not avaiable")}}))

-(def origin-re #"http://.*")
+(def origin-re (:ws-origin-re config))

 (defn handle-service
   "Returns a http-kit websocket handler with wamp subprotocol"