split speed-test-9 into 2 tests: one non-reflexive, one reflexive

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -740,9 +740,22 @@
                  #(time (println
                          (fo (generate {:synsem {:subcat '()
                                                  :sem {:tense :present
+                                                       :reflexive false
                                                        :aspect :perfect}}}
                                          :model (medium)))))))))))

+(deftest speed-test-10
+  (is (= 10
+         (count
+          (take 10
+                (repeatedly
+                 #(time (println
+                         (fo (generate {:synsem {:subcat '()
+                                                 :sem {:tense :present
+                                                       :reflexive true
+                                                       :aspect :perfect}}}
+                                         :model (medium)))))))))))
+


convert all tests for verb conjugation from: {:synsem :subcat :1 :agr} to simply {:synsem :agr}

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -352,36 +352,36 @@
                               {:français {:present :regular}
                                :synsem {:cat :verb
                                         :infl :present
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :1st}}}}}))))
+                                         :agr {:number :plur
+                                               :person :1st}}}))))
 (deftest conjugate-present-er-with-g
   (is (= "mangeons" (conjugate "manger"
                                {:français {:present :regular}
                                 :synsem {:cat :verb
                                          :infl :present
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :1st}}}}}))))
+                                         :agr {:number :plur
+                                               :person :1st}}}))))
 (deftest conjugate-present-re-with-d
   (is (= "apprenons" (conjugate "apprendre"
                                 {:français {:present :regular}
                                  :synsem {:cat :verb
                                           :infl :present
-                                          :subcat {:1 {:agr {:number :plur
-                                                             :person :1st}}}}}))))
+                                          :agr {:number :plur
+                                                :person :1st}}}))))
 (deftest conjugate-conditional
   (is (= "parlerions"
          (conjugate "parler"
                     {:synsem {:cat :verb
                               :infl :conditional
-                              :subcat {:1 {:agr {:number :plur
-                                                 :person :1st}}}}}))))
+                              :agr {:number :plur
+                                    :person :1st}}}))))
 (deftest conjugate-future
   (is (= "parleront"
          (conjugate "parler"
                     {:synsem {:cat :verb
                               :infl :future
-                              :subcat {:1 {:agr {:number :plur
-                                                 :person :3rd}}}}}))))
+                              :agr {:number :plur
+                                    :person :3rd}}}))))
 (deftest conjugate1
   (let [from #"s'([aeéiou].*)er$"
         infinitive "s'amuser"
@@ -392,46 +392,46 @@
   (is (= (conjugate "s'amuser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:number :sing}}}}})
+                              :agr {:number :sing}}})
          "amusé")))

 (deftest conjugate3
   (is (= (conjugate "s'amuser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:number :plur}}}}})
+                              :agr {:number :plur}}})
          "amusés")))

 (deftest conjugate4
   (is (= (conjugate "s'amuser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:gender :masc
-                                                 :number :plur}}}}})
+                              :agr {:gender :masc
+                                    :number :plur}}})
          "amusés")))

 (deftest conjugate5
   (is (= (conjugate "s'amuser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:gender :fem
-                                                 :number :plur}}}}})
+                              :agr {:gender :fem
+                                    :number :plur}}})
          "amusées")))

 (deftest conjugate6
   (is (= (conjugate "se blesser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:gender :masc
-                                                 :number :sing}}}}})
+                              :agr {:gender :masc
+                                    :number :sing}}})
          "blessé")))

 (deftest conjugate7
   (is (= (conjugate "se blesser"
                     {:synsem {:cat :verb
                               :infl :past-p
-                              :subcat {:1 {:agr {:gender :fem
-                                                 :number :plur}}}}})
+                              :agr {:gender :fem
+                                    :number :plur}}})
          "blessées")))

 (deftest conjugate8
@@ -443,16 +443,16 @@
                                     :number :sing}}})
          "blesses")))

-(deftest conjugate-irregular
-  (is (= (conjugate "boire"
+(deftest conjugate-boot-stem-present
+  (is (= "buvons"
+         (conjugate "boire"
                     {:français {:boot-stem2 "buv"
                                 :present {:boot-stem2 true}
                                 :français "boire"}
                      :synsem {:cat :verb
                               :infl :present
                               :agr {:person :1st
-                                    :number :plur}}})
-         "buvons")))
+                                    :number :plur}}}))))

 (deftest have-fun
   (let [have-fun-expression


+{:cat :noun}: needed now by conjugation

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -129,6 +129,7 @@
   (let [result
         {:français
          {:a {:initial true,
+              :cat :noun
               :français "nous"},
           :b {:b {:future-stem "ir",
                   :agr {:number :plur,


better initialization of language model

better initialization of language model

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -22,13 +22,10 @@
    [clojure.set :as set]
    [dag_unify.core :refer [copy fail? get-in strip-refs unify]]))

-(btest/init-db)
-
-;; TODO: move this from babel.test.it to babel.lexicon or similar.
-(defn initialize []
-  (log/info (str "recompiling and writing lexicon to database.."))
-  (write-lexicon "it" (lexicon/compile-lexicon))
-  (log/info (str "done.")))
+(defonce model
+  (do
+    (btest/init-db)
+    @@(get models :it)))

 ;; TODO: consider removing special-purpose grammars like grammar/np-grammar
 ;; and just use model instead.
@@ -36,7 +33,7 @@
 (def np-grammar (delay (grammar/np-grammar)))

 (defn generate-speed-test [spec & [times]]
-  (btest/generate-speed-test spec @@(get models :it) times))
+  (btest/generate-speed-test spec models times))

 (defn run-passato-prossimo-test []
   (generate-speed-test {:synsem {:cat :verb :subcat []
@@ -47,7 +44,7 @@
   (babel.italiano.grammar/model-plus-lexicon
    ;; filtered lexicon:
    (into {}
-         (for [[k lexemes] (:lexicon @@(get models :it))]
+         (for [[k lexemes] (:lexicon models)]
            (let [filtered-lexemes
                  (filter (fn [lexeme]
                            (or (= k "vedere")
@@ -905,8 +902,23 @@
          :head {:comp {:synsem {:pronoun true}}}}]
     (repeatedly #(-> spec generate morph time println))))

+(defn sentences-with-pronoun-objects-hints
+  "supply a spec enhanced with syntactic info to speed-up generation."
+  []
+  (let [spec
+        {:modified false
+         :synsem {:cat :verb
+                  :subcat []
+                  :sem {:pred :top
+                        :tense :present
+                        :aspect :simple
+                        :subj {:pred :top}
+                        :obj {:pred :top}}}
+         :head {:comp {:synsem {:pronoun true}}}}]
+    (repeatedly #(-> spec generate morph time println))))
+
 (defn sentences-with-pronoun-objects-small []
-  (let [lexicon (:lexicon @@(get models :it))
+  (let [lexicon (:lexicon models)
         transitive-verbs
         (filter (fn [k]
                   (let [lexemes (->> (get lexicon k)
@@ -930,12 +942,18 @@
                (for [[k lexemes] lexicon]
                  (let [filtered-lexemes
                        (filter (fn [lexeme]
-                                 (or (and (contains? chosen-subset k)
-                                          (= (get-in lexeme [:synsem :cat])
-                                             :verb)
-                                          (not (empty? (get-in lexeme [:synsem :subcat] [])))
-                                          (map? (get-in lexeme [:synsem :subcat :2]))
-                                          (empty? (get-in lexeme [:synsem :subcat :3] [])))
+                                 (or (and
+
+                                      ;; must have the same surface form as the
+                                      ;; three randomly-chosen words above.
+                                      (contains? chosen-subset k)
+
+                                      ;; must be a transitive verb: exactly 2 arguments (subject and object).
+                                      (= (get-in lexeme [:synsem :cat]) :verb)
+                                      (not (empty? (get-in lexeme [:synsem :subcat] [])))
+                                      (map? (get-in lexeme [:synsem :subcat :2]))
+                                      (empty? (get-in lexeme [:synsem :subcat :3] [])))
+
                                      (and (= (get-in lexeme [:synsem :cat])
                                              :noun)
                                           (= (get-in lexeme [:synsem :pronoun])


added division simplification rules

added division simplification rules

--- src/thesis/simplify.clj
+++ src/thesis/simplify.clj
@@ -10,37 +10,40 @@

 (defn- simplify-expression-once [expression]
   (let [simplification-rules {; Logic rules
-                               [:implies true "x"]      "x"
-                               [:implies "x" true]      true
-                               [:implies false "x"]     true
-                               [:implies "x" false]     [:not "x"]
-                               [:not [:not "x"]]        "x"
-                               [:or "x" false]          "x"
-                               [:or "x" true]           true
-                               [:and "x" false]         false
-                               [:and "x" true]          "x"
-                               [:or "x" "x"]            "x"
-                               [:and "x" "x"]           "x"
-                               [:or "x" [:not "x"]]     true
-                               [:and "x" [:not "x"]]    false
-                               [:and "x" [:or "x" "y"]] "x"
-                               [:or "x" [:and "x" "y"]] "x"
-                               ; Arithmetic rules
-                               [:+ "x" 0]               "x"
-                               [:* "x" 0]               0
-                               [:* "x" 1]               "x"
-                               [:+ [:- "x" "y"] "y"]    "x"
-                               [:- "x" "x"]             0
-                               [:== "x" "x"]            true
-                               [:<= "x" "x"]            true
-                               [:>= "x" "x"]            true
-                               [:!= "x" "x"]            false
-                               [:< "x" "x"]             false
-                               [:> "x" "x"]             false
-                               }]
-        (reduce
-          (fn [expression [p-from p-to]] (expr-transform p-from p-to expression))
-          expression simplification-rules)))
+                              [:implies true "x"]      "x"
+                              [:implies "x" true]      true
+                              [:implies false "x"]     true
+                              [:implies "x" false]     [:not "x"]
+                              [:not [:not "x"]]        "x"
+                              [:or "x" false]          "x"
+                              [:or "x" true]           true
+                              [:and "x" false]         false
+                              [:and "x" true]          "x"
+                              [:or "x" "x"]            "x"
+                              [:and "x" "x"]           "x"
+                              [:or "x" [:not "x"]]     true
+                              [:and "x" [:not "x"]]    false
+                              [:and "x" [:or "x" "y"]] "x"
+                              [:or "x" [:and "x" "y"]] "x"
+                              ; Arithmetic rules
+                              [:+ "x" 0]               "x"
+                              [:* "x" 0]               0
+                              [:* "x" 1]               "x"
+                              [:+ [:- "x" "y"] "y"]    "x"
+                              [:- "x" "x"]             0
+                              [:- "x" 0]               "x"
+                              [(keyword "/") "x" 1]    "x"
+                              [(keyword "/") 0 "x"]    0
+                              [:== "x" "x"]            true
+                              [:<= "x" "x"]            true
+                              [:>= "x" "x"]            true
+                              [:!= "x" "x"]            false
+                              [:< "x" "x"]             false
+                              [:> "x" "x"]             false
+                              }]
+    (reduce
+      (fn [expression [p-from p-to]] (expr-transform p-from p-to expression))
+      expression simplification-rules)))

 (defn- evaluate-constants
   "Find constant sub-expressions in expression and evaluate them"


Rejig order of API functions

Rejig order of API functions

--- src/tick/alpha/api.cljc
+++ src/tick/alpha/api.cljc
@@ -35,6 +35,8 @@
 ;; clojure.spec assertions are used to check correctness, but these
 ;; are disabled by default (except when testing).

+;; Construction
+
 (def new-time core/new-time)
 (def new-date core/new-date)

@@ -49,31 +51,6 @@
 (defn tomorrow [] (core/tomorrow))
 (defn yesterday [] (core/yesterday))

-;; Constants
-
-(def monday (t.i/static-prop  DayOfWeek MONDAY))
-(def tuesday (t.i/static-prop  DayOfWeek TUESDAY))
-(def wednesday (t.i/static-prop  DayOfWeek WEDNESDAY))
-(def thursday (t.i/static-prop  DayOfWeek THURSDAY))
-(def friday (t.i/static-prop  DayOfWeek FRIDAY))
-(def saturday (t.i/static-prop  DayOfWeek SATURDAY))
-(def sunday (t.i/static-prop  DayOfWeek SUNDAY))
-
-(def january (t.i/static-prop  Month JANUARY))
-(def february (t.i/static-prop  Month FEBRUARY))
-(def march (t.i/static-prop  Month MARCH))
-(def april (t.i/static-prop  Month APRIL))
-(def may (t.i/static-prop  Month MAY))
-(def june (t.i/static-prop  Month JUNE))
-(def july (t.i/static-prop  Month JULY))
-(def august (t.i/static-prop  Month AUGUST))
-(def september (t.i/static-prop  Month SEPTEMBER))
-(def october (t.i/static-prop  Month OCTOBER))
-(def november (t.i/static-prop  Month NOVEMBER))
-(def december (t.i/static-prop  Month DECEMBER))
-
-;; Construction and coercion
-
 (defn time
   ([] (core/time (now)))
   ([v] (core/time v)))
@@ -81,6 +58,8 @@
 (defn date
   ([] (today))
   ([v] (core/date v)))
+
+;; Conversion

 (defn nanosecond [t] (core/nanosecond t))
 (defn microsecond [t] (core/microsecond t))
@@ -92,15 +71,19 @@
 (defn day
   ([] (core/day (today)))
   ([v] (core/day v)))
+
 (defn day-of-month
   ([] (core/day-of-month (today)))
   ([v] (core/day-of-month v)))
+
 (defn inst
   ([] (core/inst (now)))
   ([v] (core/inst v)))
+
 (defn instant
   ([] (core/instant (now)))
   ([v] (core/instant v)))
+
 (defn offset-date-time
   ([] (core/offset-date-time (now)))
   ([v] (core/offset-date-time v)))
@@ -133,6 +116,32 @@
 (defn date-time
   ([] (core/date-time (now)))
   ([v] (core/date-time v)))
+
+
+
+;; Constants
+
+(def monday (t.i/static-prop DayOfWeek MONDAY))
+(def tuesday (t.i/static-prop DayOfWeek TUESDAY))
+(def wednesday (t.i/static-prop DayOfWeek WEDNESDAY))
+(def thursday (t.i/static-prop DayOfWeek THURSDAY))
+(def friday (t.i/static-prop DayOfWeek FRIDAY))
+(def saturday (t.i/static-prop DayOfWeek SATURDAY))
+(def sunday (t.i/static-prop DayOfWeek SUNDAY))
+
+(def january (t.i/static-prop Month JANUARY))
+(def february (t.i/static-prop Month FEBRUARY))
+(def march (t.i/static-prop Month MARCH))
+(def april (t.i/static-prop Month APRIL))
+(def may (t.i/static-prop Month MAY))
+(def june (t.i/static-prop Month JUNE))
+(def july (t.i/static-prop Month JULY))
+(def august (t.i/static-prop Month AUGUST))
+(def september (t.i/static-prop Month SEPTEMBER))
+(def october (t.i/static-prop Month OCTOBER))
+(def november (t.i/static-prop Month NOVEMBER))
+(def december (t.i/static-prop Month DECEMBER))
+

 (defn beginning [v] (core/beginning v))
 (defn end [v] (core/end v))


:bug: Fix page version spec.

:bug: Fix page version spec.

--- backend/src/uxbox/api/pages.clj
+++ backend/src/uxbox/api/pages.clj
@@ -18,7 +18,7 @@
 (s/def ::id ::us/uuid)
 (s/def ::name string?)
 (s/def ::project ::us/uuid)
-(s/def ::version (s/and integer? pos?))
+(s/def ::version int?)
 (s/def ::data any?)
 (s/def ::metadata any?)


:tada: Add helper for create custom more easy to read uuids (for testing).

--- backend/src/uxbox/util/uuid.clj
+++ backend/src/uxbox/util/uuid.clj
@@ -37,3 +37,6 @@
   [s]
   (UUID/fromString s))

+(defn custom
+  ([a] (UUID. 0 a))
+  ([b a] (UUID. b a)))


Add :path & :method to Endpoints

Add :path & :method to Endpoints

--- modules/reitit-ring/src/reitit/ring.cljc
+++ modules/reitit-ring/src/reitit/ring.cljc
@@ -6,6 +6,7 @@

 (def http-methods #{:get :head :patch :delete :options :post :put})
 (defrecord Methods [get head post put delete trace options connect patch any])
+(defrecord Endpoint [data handler path method middleware])

 (defn- group-keys [data]
   (reduce-kv
@@ -58,14 +59,19 @@
               acc)) data http-methods)])

 (defn compile-result [[path data] opts]
-  (let [[top childs] (group-keys data)]
+  (let [[top childs] (group-keys data)
+        ->endpoint (fn [p d m s]
+                     (-> (middleware/compile-result [p d] opts s)
+                         (map->Endpoint)
+                         (assoc :path p)
+                         (assoc :method m)))]
     (if-not (seq childs)
-      (map->Methods {:any (middleware/compile-result [path top] opts)})
+      (map->Methods {:any (->endpoint path top :any nil)})
       (reduce-kv
         (fn [acc method data]
           (let [data (meta-merge top data)]
-            (assoc acc method (middleware/compile-result [path data] opts method))))
-        (map->Methods {:any (if (:handler top) (middleware/compile-result [path data] opts))})
+            (assoc acc method (->endpoint path data method method))))
+        (map->Methods {:any (if (:handler top) (->endpoint path data :any nil))})
         childs))))

 (defn router


leaving this commented out for now

leaving this commented out for now

I used it to verify against the output of `javac -g:vars,lines`

--- test/insn/core_test.clj
+++ test/insn/core_test.clj
@@ -278,6 +278,6 @@
                                    [:local-variable "this" :this :BEGIN :END 0]
                                    [:local-variable "i" :int :BEGIN :END 1]]}]}
                 core/visit
-                (core/write (System/getProperty "java.io.tmpdir"))
+                #_(core/write (System/getProperty "java.io.tmpdir"))
                 core/new-instance)]
     (is (= 43 (.inc obj 42)))))


Remove unused function on svg ns.

Remove unused function on svg ns.

--- src/uxbox/util/svg.cljs
+++ src/uxbox/util/svg.cljs
@@ -69,10 +69,3 @@
     (->> (map #(nth result %) [0 3 1 4 2 5])
          (str/join ",")
          (str/format "matrix(%s)"))))
-
-(defn apply-transform
-  [attrs]
-  (let [transform (calculate-transform attrs)]
-    (-> attrs
-        (without-keys [:rotation :width :height :x :y :view-box])
-        (assoc :transform transform))))


restore index from snapshot

restore index from snapshot

--- src/wb_es/web/setup.clj
+++ src/wb_es/web/setup.clj
@@ -72,7 +72,32 @@
          (:id))))

 (defn restore-snapshot
-  [repository-name snapshot-id])
+  [index-id repository-name snapshot-id]
+  (let [max-retry 50
+        interval 10000
+        counter (atom 0)
+        connected (atom false)]
+    (do
+      (try
+        (http/post (format "%s/_snapshot/%s/%s/_restore" es-base-url repository-name snapshot-id))
+        (catch Exception e
+          (throw (Exception. (format "Failed to restore snapshot %s" snapshot-id)))))
+      (println "Restoring index started")
+      (while (not (deref connected))
+        (do
+          (swap! counter inc)
+          (try
+            (do
+              (println (http/get (format "%s/%s/_search" es-base-url index-id)))
+              (swap! connected not)
+              (println "Connected."))
+            (catch Exception e
+              (if (>= (deref counter) max-retry)
+                (throw (Exception. (format "Failed to connect to %s. Start up terminated." es-base-url)))
+                (do
+                  (println (http/get (format "%s/_cat/recovery?format=json" es-base-url repository-name)))
+                  (flush)
+                  (Thread/sleep interval))))))))))

 ;; (let [
 ;;       response
@@ -101,7 +126,7 @@
           (do
             (connect-snapshot-repository repository-name)
             (let [snapshot-id (get-snapshot-id repository-name)]
-              (restore-snapshot repository-name snapshot-id)
+              (restore-snapshot index-id repository-name snapshot-id)
               (println (format "Elasticsearch is restored from snapshot %s" snapshot-id))))))
       )))


Clear out unused stuff

Clear out unused stuff

--- src/bejeweled_bot/pixel_sampler.clj
+++ src/bejeweled_bot/pixel_sampler.clj
@@ -12,7 +12,6 @@
         '[org.opencv.imgproc Imgproc])

 (def image (ImageIO/read (File. "resources/whole.png")))
-(def xy [37 49])
 (defn get-samples
   "Gets pixel color from given coordinates"
   [xy]
@@ -24,13 +23,6 @@
         blue (.getBlue color)]
     {:red red :green green :blue blue}))

-  ;(xy 0)(xy 1))
-
-;(def targetCols 328)
-;(def targetRows 319)
-;(def col 36)
-;(def row 120)
-
 (defn sample-pixels
   ""
   [xl yl xr yr image]
@@ -57,31 +49,3 @@
         row
         ))
     sample-coords))
-
-  ;(Highgui/imwrite "resources/output3.png" image)
-  ;(println sample-coords)
-  ;(println (flatten sample-coords))
-  ;(println 0)
-  ;(def colors
-  ;  (map
-  ;    (fn [row]
-  ;      (map
-  ;        (fn [item]
-  ;          (get-samples item))
-  ;        row))
-  ;    sample-coords))
-
-  ;(map #(map (fn [item] (println item)) %) colors)
-  ;(println (colors 0))
-  ;(println (vector colors)))
-
-
-;(println (sample-pixels col row (+ col targetCols) (+ row targetRows)))
-
-
-;
-;(flatten sample-coords)))
-;        (map
-;          (fn [item]
-;            (get-samples item))
-;          row))


Fix missing state parameter

Fix missing state parameter

--- src/braid/client/state/helpers.cljs
+++ src/braid/client/state/helpers.cljs
@@ -29,7 +29,7 @@
                          (->> (filter (fn [thread]
                                         (or (empty? (thread :tag-ids))
                                             (contains?
-                                              (into #{} (map (partial group-for-tag) (thread :tag-ids)))
+                                              (into #{} (map (partial group-for-tag state) (thread :tag-ids)))
                                               current-group-id))))))]
     open-threads))


move 'I give up' link down a bit

move 'I give up' link down a bit

--- src/clj/learndatalogtoday/views.clj
+++ src/clj/learndatalogtoday/views.clj
@@ -55,7 +55,9 @@
                     :value (with-out-str (fipp/pprint (:value input))))]
     [:div.span8
      [:div.row
-      [:div.span8 [:p [:small [:strong label]]]]]
+      [:div.span8 [:p [:small [:strong label]
+                       (when (= :query (:type input))
+                         [:span.pull-right "[ " [:a {:href "#" :class (str "show-ans-" tab-n)} "I give up!"] " ]"])]]]]
      [:div.row
       [:div.span8 [:textarea {:class (str "input-" tab-n)} input-str]]]]))

@@ -67,10 +69,6 @@
                :id (str "tab" tab-n)}

          (md/md-to-html-string (:question exercise))
-         [:div.row
-          [:div.span8
-           [:small.pull-right "[ " [:a {:href "#" :class (str "show-ans-" tab-n)} "I give up!"] " ]"]]]
-
          [:div.row.inputs
           (build-inputs tab-n (:inputs exercise))]
          [:div.row


Process each event in a separate function

--- src/cljs/asciinema_player/core.cljs
+++ src/cljs/asciinema_player/core.cljs
@@ -29,16 +29,18 @@
 (defn total-time [state]
   (:duration @state))

+(defn process-event [[event-name & args] state]
+  (case event-name
+    :toggle-play (toggle-play state)
+    :seek (seek state (first args))
+    :rewind (seek state (new-position (current-time state) (total-time state) -5))
+    :fast-forward (seek state (new-position (current-time state) (total-time state) 5))))
+
 (defn create-player-with-state [state dom-node]
   (let [events (chan)]
     (go
       (loop []
-        (let [[event & args] (<! events)]
-          (case event
-            :toggle-play (toggle-play state)
-            :seek (seek state (first args))
-            :rewind (seek state (new-position (current-time state) (total-time state) -5))
-            :fast-forward (seek state (new-position (current-time state) (total-time state) 5))))
+        (process-event (<! events) state)
         (recur)))
     (reagent/render-component [view/player state events] dom-node)
     (clj->js {:toggle (fn [] toggle-play state)})))


Pull out a function for getting the next image

--- src/cljs/comic_reader/handlers.cljs
+++ src/cljs/comic_reader/handlers.cljs
@@ -3,6 +3,11 @@
             [comic-reader.history :as h]
             [re-frame.core :as rf]
             [secretary.core :as secretary]))
+
+(defn get-next-image [{:keys site url-list}
+                      :as db]
+  (api/get-img-tag site (first url-list))
+  (assoc db :url-list (rest url-list)))

 (defn init-handlers! []
   (rf/register-handler
@@ -51,8 +56,9 @@
   (rf/register-handler
    :url-list
    (fn [db [_ url-list]]
-     (api/get-img-tag (:site db) (first url-list))
-     (assoc db :url-list (rest url-list))))
+     (-> db
+         (assoc :url-list url-list)
+         get-next-image)))

   (rf/register-handler
    :next-image


Added return_tagspace.

Added return_tagspace.

--- src/clojush/instructions/return.clj
+++ src/clojush/instructions/return.clj
@@ -68,3 +68,10 @@
   (fn [state]
     (assoc state :return (concat (:return state)
                                  (list 'string_pop)))))
+
+; Immediately copies the current tagspace to the environment on the top
+; of the :environment stack.
+(define-registered
+  return_tagspace
+  (fn [state]
+    (assoc-in state [:environment :tag] (:tag state))))


Improves readability

Improves readability

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -7,10 +7,10 @@
 (def app-state (atom {:text "Hello world!"}))

 (defn handle-input [event app owner]
-  (let [input-area (om/get-node owner "input-area")
+  (let [input-area  (om/get-node owner "input-area")
         output-area (om/get-node owner "output-area")
-        text (.-value input-area)
-        markdown (.marked js/window text)]
+        text        (.-value input-area)
+        markdown    (.marked js/window text)]
     (set! (.-innerHTML output-area) markdown)))

 (defn wordsmith-app [app owner]


Adds rename of documents

Adds rename of documents

--- src/wordsmith/core.cljs
+++ src/wordsmith/core.cljs
@@ -28,6 +28,7 @@
      :titles []
      :title ""
      :last-saved nil
+     :last-title ""
      :channel (chan)}))

 ;; Title field
@@ -36,6 +37,13 @@
   (let [new-title (.. event -target -value)]
     (om/update! app :title new-title)))

+(defn handle-title-blur [event app]
+  (let [new-title (.. event -target -value)]
+    (p/set-document new-title (:input @app))
+    (p/remove-document (:last-title @app))
+    (om/update! app :last-title new-title)
+    (om/update! app :titles (p/get-all-titles))))
+
 (defn title-field [app owner]
   (reify
     om/IRender
@@ -43,6 +51,7 @@
       (dom/div #js {:id "title-field"}
         (dom/input #js {:type "text"
                         :onChange #(handle-title-change % app)
+                        :onBlur #(handle-title-blur % app)
                         :value (:title app)})))))

 ;; Left menu
@@ -50,7 +59,8 @@
 (defn update-current [event app]
   (let [title (.. event -target -textContent)]
     (om/update! app :input (p/get-document title))
-    (om/update! app :title title)))
+    (om/update! app :title title)
+    (om/update! app :last-title title)))

 (defn delete-click [title app]
   (p/remove-document title)
@@ -96,6 +106,7 @@

 (defn save-document [app]
   (om/update! app :last-saved (js/Date.))
+  (om/update! app :last-title (:title @app))
   (p/set-document (:title @app) (:input @app))
   (om/update! app :titles (p/get-all-titles)))


Set version to 0.7

Set version to 0.7

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -70,7 +70,7 @@

 (def parse (insta/parser (clojure.java.io/resource "grammar")))

-(def version "0.6")
+(def version "0.7")

 ;; utility defns


removed :email from mock user data in test-user

:email never is returned from the api

--- test-cljs/frontend/models/test_user.cljs
+++ test-cljs/frontend/models/test_user.cljs
@@ -7,7 +7,6 @@
         email "public@profile.com"
         all-emails ["all@emails.com" "last@emails.com"]
         user {:selected_email selected-email
-              :email email
               :all_emails all-emails}]

    (testing "if they have a :selected-email we use that"


[test_voom] Decomplect dag generation and sampling.

--- test/voom/test_voom.clj
+++ test/voom/test_voom.clj
@@ -7,14 +7,15 @@
             [clojure.test.check.generators :as gen]))

 (defn dag-samples-gen
-  [dag percent]
-  (let [dag-size (count dag)
-        sample-count (int (* percent dag-size))]
-    (gen/bind (apply gen/tuple
-                     ;; May collide but this is fine.
-                     (repeat (* 2 sample-count) (gen/choose 0 dag-size)))
-              (fn [samples]
-                (gen/tuple (gen/return dag) (gen/return samples))))))
+  [percent]
+  (fn [dag]
+    (let [dag-size (count dag)
+          sample-count (int (* percent dag-size))]
+      (gen/bind (apply gen/tuple
+                       ;; May collide but this is fine.
+                       (repeat (* 2 sample-count) (gen/choose 0 dag-size)))
+                (fn [samples]
+                  (gen/tuple (gen/return dag) (gen/return samples)))))))

 (defn gen-dag
   ([] (gen-dag [#{}] 10))
@@ -35,7 +36,7 @@
                              (if (< 0 nodes)
                                (gen-dag (conj dag-so-far (set parents))
                                         (dec nodes))
-                               (dag-samples-gen dag-so-far 1/2))))))))
+                               (gen/return dag-so-far))))))))

 (defn anc-model-new [] {})
@@ -65,7 +66,8 @@
 (def dag-similarity-props
   (prop/for-all [[dag samples] (gen/bind (gen/choose 0 100)
                                          (fn [dag-size]
-                                           (gen-dag dag-size)))]
+                                           (gen/bind (gen-dag dag-size)
+                                                     (dag-samples-gen 1/2))))]
                 (let [anc (reduce (fn [a [i ps]]
                                     (apply lag/ancestry-add a i (seq ps)))
                                   (lag/ancestry-new)


Add tests for error catch/rethrow

Add tests for error catch/rethrow

--- test/com/stuartsierra/component_test.clj
+++ test/com/stuartsierra/component_test.clj
@@ -152,23 +152,39 @@
          [:c :b]
          [:d :my-c])))

-(defrecord ErrorStartComponentC [state a b]
-  component/Lifecycle
-  (start [this]
-    (throw (ex-info "Boom!" {:state state})))
+(defrecord ErrorStartComponentC [state error a b]
+  component/Lifecycle
+  (start [this]
+    (throw error))
   (stop [this]
     this))

-(defn error-start-c []
+(defn error-start-c [error]
   (component/using
-    (map->ErrorStartComponentC {:state (rand-int Integer/MAX_VALUE)})
+    (map->ErrorStartComponentC {:error error})
     [:a :b]))

+(defn setup-error
+  ([]
+     (setup-error (ex-info "Boom!" {})))
+  ([error]
+     (try (component/start
+           (assoc (system-1) :c (error-start-c error)))
+          (catch Exception e e))))
+
 (deftest error-thrown-with-partial-system
-  (let [ex (try (component/start (assoc (system-1)
-                                   :c (error-start-c)))
-                (catch Exception e e))]
+  (let [ex (setup-error)]
     (is (started? (-> ex ex-data :system :b :a)))))
+
+(deftest error-thrown-with-component-dependencies
+  (let [ex (setup-error)]
+    (is (started? (-> ex ex-data :component :a)))
+    (is (started? (-> ex ex-data :component :b)))))
+
+(deftest error-thrown-with-cause
+  (let [error (ex-info "Boom!" {})
+        ex (setup-error error)]
+    (is (identical? error (.getCause ^Exception ex)))))

 (defrecord System2b [one]
   component/Lifecycle


Get message-tests passing again

Get message-tests passing again

This looks like a bigger change than it was. It was really just matching
a change in the signature of from-parent/deserialize.

--- test/frereth_cp/message/message_test.clj
+++ test/frereth_cp/message/message_test.clj
@@ -453,22 +453,23 @@
         ;; TODO: This is another piece that's just
         ;; screaming for generative testing
         (log/info "Deserializing message from parent")
-        (let [{:keys [::specs/acked-message
-                      ::specs/ack-length-1
-                      ::specs/ack-length-2
-                      ::specs/ack-length-3
-                      ::specs/ack-length-4
-                      ::specs/ack-length-5
-                      ::specs/ack-length-6
-                      ::specs/ack-gap-1->2
-                      ::specs/ack-gap-2->3
-                      ::specs/ack-gap-3->4
-                      ::specs/ack-gap-4->5
-                      ::specs/ack-gap-5->6
-                      ::specs/buf
-                      ::specs/message-id
-                      ::specs/size-and-flags]
-               :as packet} (time (from-parent/deserialize message-loop-name buf))]
+        (let [{{:keys [::specs/acked-message
+                       ::specs/ack-length-1
+                       ::specs/ack-length-2
+                       ::specs/ack-length-3
+                       ::specs/ack-length-4
+                       ::specs/ack-length-5
+                       ::specs/ack-length-6
+                       ::specs/ack-gap-1->2
+                       ::specs/ack-gap-2->3
+                       ::specs/ack-gap-3->4
+                       ::specs/ack-gap-4->5
+                       ::specs/ack-gap-5->6
+                       ::specs/buf
+                       ::specs/message-id
+                       ::specs/size-and-flags]} ::specs/packet
+               log-state ::log2/state
+               :as packet} (time (from-parent/deserialize log-state buf))]
           (comment (is (not packet)))
           (is (= chzbrgr-lngth size-and-flags))
           (are [expected actual] (= expected actual)


Use an adverbal macro to work on the definition of symbols.

--- src/kolmogorov_music/kolmogorov.clj
+++ src/kolmogorov_music/kolmogorov.clj
@@ -76,6 +76,17 @@
   (live/play row-row)
 )

+(defmacro definitionally [macro sym]
+  (let [value (-> sym repl/source-fn read-string last)]
+    `(~macro ~value)))
+
+(fact "The definitionally macro lets us calculate on the definition of symbols."
+  (definitionally description-length row-row) => 281
+  (definitionally result-length row-row) => 2037
+  (definitionally randomness row-row) => 281/2037
+  (definitionally random? row-row) => false)
+
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; The Library of Babel ;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;


change port

change port

--- src/rrm/core.clj
+++ src/rrm/core.clj
@@ -46,5 +46,5 @@
 (defn -main
   "Record Room Management System "
   [& args]
-  (jetty/run-jetty app {:port 8193
+  (jetty/run-jetty app {:port 80
                         :join? false}))


fix a couple of bugs in audio file fns

fix a couple of bugs in audio file fns

--- src/overtone/helpers/audio_file.clj
+++ src/overtone/helpers/audio_file.clj
@@ -27,7 +27,7 @@
   [data path frame-rate n-channels]
   (when (some #(or (< % -1) (> % 1)) data)
     (throw (Exception. (str "Unable to write audio file with this data as it contains sample points either less than -1 or greater than 1."))))
-  (let [path         (resolve-tilde-path)
+  (let [path         (resolve-tilde-path path)
         frame-rate   (float frame-rate)
         n-channels   (int n-channels)
         sample-bytes (/ Short/SIZE 8)
@@ -74,4 +74,4 @@

 (defmethod write-wav ::sequence
   [data path frame-rate n-channels]
-  (write-audio-file-from-seq (buffer-data data) path frame-rate n-channels))
+  (write-audio-file-from-seq data path frame-rate n-channels))


Update tabledoc.clj

Update tabledoc.clj

--- src/tabledoc.clj
+++ src/tabledoc.clj
@@ -5,8 +5,8 @@
   {:classname "oracle.jdbc.OracleDriver"
    :subprotocol "oracle"
    :subname "thin:@192.168.1.83:1521:testdb"
-   :user "hr"
-   :password "hr"
+   :user "xxx"
+   :password "xxx"
    :naming {:keys str/lower-case :fields str/upper-case}})

 ;; (def db-spec
@@ -22,8 +22,11 @@
 (defentity all_tab_comments)
 (defentity all_col_comments)

-;; (->> (select employees (fields [:FIRST_NAME :fn] [:LAST_NAME :ln]))
-;;      (map #(str (% :fn) " " (% :ln))))
+(defn get-tables [owners]
+  (select all_tables
+          (fields :owner :table_name)
+          (where {:owner [in owners]})
+          (order :table_name)))

 (defn get-tab-stat [owner tab-name]
   (select all_tables
@@ -43,10 +46,8 @@
           (where {:owner owner :table_name tab-name})
           (order :column_id)))

-(defn get-idx-desc [owner idx-name]
+(defn get-idx-desc [owner tab-name]
   (->> (select all_ind_columns
-               (fields :table_name :index_name :column_position :column_name)
-               (where {:index_owner owner :index_name idx-name})
-               (order :column_position))
-       (map #(:column_name %))
-       (str/join "+")))
+               (fields :index_name :column_position :column_name)
+               (where {:table_owner owner :table_name tab-name}))
+       (group-by #(% :index_name))))


Remove test email

Remove test email

--- src/servisne_info/notifications.clj
+++ src/servisne_info/notifications.clj
@@ -23,9 +23,3 @@
               "Servisne informacije"
               (email/render "new_links.txt"
                             {:links (map :url news)})))
-
-(defn send-test-email []
-  (send-email "nebojsa.stricevic@gmail.com"
-              "Test poruka"
-              (email/render "new_links.txt"
-                            {:links ["http://servisne.info/" "http://servisne.info/about"]})))


[scamp] correct sub-handling bug

[scamp] correct sub-handling bug

Fixing new-subscription-handling to work according to the paper. New subscribing
nodes get their contact as a :downstream node already, so if the contact has no
:downstream nodes, the correct action is to do nothing.

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -164,17 +164,14 @@
 (s/defn handle-new-subscription :- [MessageEnvelopeSchema]
   "Forward the 'subscription to every :downstream node, duplicating
   the forwarded 'subscription to :connection-redundancy :downstream
-  nodes. If :downstream is empty, forward the subscription to 'node."
+  nodes. If :downstream is empty, do nothing."
   [config :- WorldConfigSchema
    {:keys [downstream] :as node} :- NetworkedNodeSchema
    subscription :- SubscriptionSchema]
   (if (empty? downstream)
-    ;; There is no 'downstream; forward subscription to :self.
-    [[:message-envelope
-      (node->node-contact-address (:self node))
-      :forwarded-subscription
-      subscription
-      (get-envelope-id)]]
+    ;; There is no 'downstream. Do nothing, because the 'subscription
+    ;; node will already have 'node in its :downstream.
+    []

     ;; Forward subscription to :downstream.
     (let [downstream (seq downstream)


[#3091] Remove logs

[#3091] Remove logs

--- backend/src/akvo/lumen/lib/data_group.clj
+++ backend/src/akvo/lumen/lib/data_group.clj
@@ -54,8 +54,7 @@
 (defn drop-view! [conn dataset-version-2-id]
   (let [view-name (view-table-name dataset-version-2-id)]
     (db.data-group/exists-view? conn view-name)
-    (log/error :drop-view view-name)
-   (jdbc/execute! conn [(format "DROP VIEW IF EXISTS %s" view-name)])))
+    (jdbc/execute! conn [(format "DROP VIEW IF EXISTS %s" view-name)])))

 (defn create-view-from-data-groups
   [tenant-conn dataset-id]
@@ -63,7 +62,6 @@
                                    (map #(update % :columns (comp walk/keywordize-keys vec)))))]
     (let [columns (reduce #(into % (:columns %2)) [] data-groups)
           t-name (view-table-name (:dataset-version-id (first data-groups)))]
-      (log/error :create-view-from-data-groups t-name :dataset-id dataset-id :dsv-id (:dataset-version-id (first data-groups)))
       (if-not (db.data-group/exists-view? tenant-conn t-name)
         (->> data-groups
              data-groups-sql-template


Add github/canonical-url

Add github/canonical-url

--- backend/src/circle/backend/github_url.clj
+++ backend/src/circle/backend/github_url.clj
@@ -76,4 +76,8 @@
  ?url ?expected
  "https://github.com/arohner/CircleCI" "https://github.com/arohner/CircleCI"
  "git@github.com:arohner/CircleCI.git" "https://github.com/arohner/CircleCI"
- "https://arohner@github.com/arohner/CircleCI.git" "https://github.com/arohner/CircleCI")+ "https://arohner@github.com/arohner/CircleCI.git" "https://github.com/arohner/CircleCI")
+
+(defn canonical-url
+  [username password]
+  (format "https://github.com/%s/%s" username password))


Adjust test sleeps

Adjust test sleeps

--- test/photon/current/projections.clj
+++ test/photon/current/projections.clj
@@ -147,10 +147,12 @@
                                                 :initial-value "0"}))
                   (Thread/sleep 5000)
                   (post-one-event m s-name)
+                  (Thread/sleep 5000)
                   (let [current-6 (:processed @(:stats stm))]
                     (fact "1011 events processed"
                           (- current-6 current-5) => 1011)
                     (api/delete-projection! stm "chatter-proj")
+                    (Thread/sleep 5000)
                     (post-one-event m s-name)
                     (let [current-7 (:processed @(:stats stm))]
                       (fact "1 events processed"


Print out err from sh!

Print out err from sh!

--- test/powderkeg/integration_test.clj
+++ test/powderkeg/integration_test.clj
@@ -5,9 +5,9 @@
             [clojure.string :as s]))

 (defn sh! [& args]
-  (let [{:keys [exit out] :as ret} (apply sh args)]
+  (let [{:keys [exit out err] :as ret} (apply sh args)]
     (when-not (zero? exit)
-      (throw (Exception. (str "Problem while running '" (s/join " " args) "': " out))))
+      (throw (Exception. (str "Problem while running '" (s/join " " args) "': " out " " err))))
     (.trim out)))

 (defn start-master [pwd]


forgot this on the last commit

forgot this on the last commit

--- cljs-cheatsheet/cljs_cheatsheet/html.cljs
+++ cljs-cheatsheet/cljs_cheatsheet/html.cljs
@@ -37,6 +37,7 @@
       (replace "<" "LT")
       (replace "!" "BANG")
       (replace "?" "QMARK")
+      (replace "/" "SLASH")
       (replace "*" "STAR")
       (replace "+" "PLUS")
       (replace "=" "EQ")))


azulenoids.clj: made walk more robust, used directly within traversal.

--- clojure/org/gavrog/clojure/azulenoids.clj
+++ clojure/org/gavrog/clojure/azulenoids.clj
@@ -39,8 +39,9 @@

 (defn walk [ds D & idxs]
   "Returns the result of applying the D-symbol operators on ds with the
-   given indices in order, starting with the element D."
-  (reduce #(.op ds %2 %1) D idxs))
+   given indices in order, starting with the element D. If the result of
+   any step is undefined, nil is returned."
+  (reduce #(when %1 (.op ds %2 %1)) D idxs))

 (defn chain-end [ds D i j]
   (loop [E (walk ds D i)]
@@ -55,13 +56,12 @@
   (iterate-cycle [#(walk ds %1 i) #(chain-end ds %1 j k)] D))

 (defn traversal [ds indices seeds]
-  (let [op (fn [i D] (when D (.op ds i D)))
-        stacks (map #(vector % ()) (take 2 indices))
+  (let [stacks (map #(vector % ()) (take 2 indices))
         queues (map #(vector % empty-queue) (drop 2 indices))
         as-root #(vector % :root)
         unseen (fn [i seen bag] (pop-while #(seen [% i]) bag))
         pop-seen #(for [[i ys] %1] (vector i (unseen i %2 ys)))
-        push-neighbors #(for [[i ys] %1] (vector i (conj ys (op i %2))))]
+        push-neighbors #(for [[i ys] %1] (vector i (conj ys (walk ds %2 i))))]
     ((fn collect [seeds-left todo seen]
        (let [seeds-left (drop-while (comp seen as-root) seeds-left)
              todo (pop-seen todo seen)
@@ -70,7 +70,7 @@
            (seq todo-for-i)
            (let [D (first todo-for-i)
                  todo (doall (push-neighbors todo D))
-                 seen (conj seen (as-root D) [D i] [(op i D) i])]
+                 seen (conj seen (as-root D) [D i] [(walk ds D i) i])]
              (lazy-seq (conj (collect seeds-left todo seen) [D i])))
            (seq seeds-left)
            (let [D (first seeds-left)


Code formatting fix

Code formatting fix

--- clstreams/src/clstreams/kstreams/impl.clj
+++ clstreams/src/clstreams/kstreams/impl.clj
@@ -26,8 +26,7 @@
   [dispatch-value-fn initial-mm-data class-name {:keys [members]}]
   (->>
    members
-   (remove
-    #(clojure.string/includes? (str (:name %)) "."))
+   (remove #(clojure.string/includes? (str (:name %)) "."))
    (filter (comp :public :flags))
    (reduce
     (fn


add DATABASE_URL environment variable

add DATABASE_URL environment variable

--- src/deploy.clj
+++ src/deploy.clj
@@ -1,10 +1,9 @@
 (ns deploy
   (:require [ragtime.jdbc :as jdbc]
-            [ragtime.repl :as repl]))
+            [ragtime.repl :as repl]
+            [environ.core :refer [env]]))

-(def pg-db {:dbtype "postgresql"
-            :dbname "otaservice"
-            :host "localhost"})
+(def pg-db (env :database-url))

 (defn load-config []
   {:datastore (jdbc/sql-database pg-db)


scale up channel buffer based on amount of time we need to remember history for

--- src/cljx/jamesmacaulay/zelkova/time.cljx
+++ src/cljx/jamesmacaulay/zelkova/time.cljx
@@ -75,7 +75,7 @@
 (defn delay
   [ms sig]
   (z/splice (fn [to from]
-              (let [waiting (async/chan 1000)
+              (let [waiting (async/chan (+ 1000 ms))
                     fire! #(async/take! waiting (partial async/put! to))]
                 (go-loop []
                   (let [v (<! from)]


Add more example from section 3.6

Add more example from section 3.6

--- src/clojure_walkthrough/cjia/ch03_06.clj
+++ src/clojure_walkthrough/cjia/ch03_06.clj
@@ -50,3 +50,64 @@
 ;; First category was: :books
 ;; First amount was: 49.95

+;; 3.6.2: Map bindings
+
+(def salary-details {:first-name "Barry"
+                     :last-name  "Gibb"
+                     :salary     1.0M })
+
+(defn describe-salary-2 [{first :first-name
+                          last :last-name
+                          annual :salary}]
+  (str first " " last " earns " annual))
+
+(describe-salary-2 salary-details) ;; "Barry Gibb earns 1.0"
+
+;; Use of 'or' to handle optional values
+(defn describe-salary-3 [{first  :first-name
+                          last   :last-name
+                          annual :salary
+                          bonus  :bonus-percentage :or {bonus 5}}]
+  (str first " " last " earns " annual " with a " bonus " percent bonus"))
+
+(describe-salary-3 salary-details) ;; "Barry Gibb"Pascal Dylan earns 85000 with a 20 percent bonus" earns 1.0 with a 5 percent bonus"
+
+;; When call with all arguments will work normally
+
+(def a-user {:first-name       "Pascal"
+             :last-name        "Dylan"
+             :salary           85000
+             :bonus-percentage 20})
+
+(describe-salary-3 a-user) ;; "Pascal Dylan earns 85000 with a 20 percent bonus"
+
+(def another-user {:first-name "Basic"
+                   :last-name  "Groovy"
+                   :salary     7000})
+
+;; Note: the default value is used if the bonus is missing
+(describe-salary-3 another-user) ;; "Basic Groovy earns 7000 with a 5 percent bonus"
+
+;; Use of :as to bind the complete hash map option to a name.
+(defn describe-person [{first :first-name
+                        last :last-name
+                        bonus :bonus-percentage
+                        :or {bonus 5}
+                        :as p}]
+  (str "Info about " first " " last " is :" p ", bonus is :" bonus " percent"))
+
+(def third-user {:first-name "Lambda"
+                 :last-name  "Curry"
+                 :salary     95000})
+
+(describe-person third-user) ;; "Info about Lambda Curry is :{:first-name \"Lambda\", :last-name \"Curry\", :salary 95000}, bonus is :5 percent"
+
+;; Use of :keys
+(defn greet-user [{:keys [first-name last-name]}]
+  (str "Welcome, " first-name " " last-name))
+
+(def roger {:first-name "Roger"
+            :last-name  "Rabbit"
+            :salary     6500})
+
+(greet-user roger) ;; "Welcome, Roger Rabbit"


Added general, logging exec for future use.

--- src/cmr/dev/env/manager/process/core.clj
+++ src/cmr/dev/env/manager/process/core.clj
@@ -14,7 +14,7 @@
   (try
     (.read stream bytes)
     (catch Exception ex
-      (log/error "Could not read stream:" (.getMessage ex))
+      (log/warn "Could not read stream:" (.getMessage ex))
       no-bytes)))

 (defn get-pid
@@ -26,16 +26,23 @@
   [process-data]
   (process/get-descendants (get-pid process-data)))

-(defn terminate-external-process!
-  [pid]
-  (let [result (shell/sh "kill" "-9" (str pid))
+(defn exec
+  "Executes the command and args in a sub-process, returning the result. Will
+  log an error in the event the process writes to `stderr`; will log the result
+  to `stdout` if the D.E.M. log-level is set to `:debug` or lower."
+  [& cmd-and-args]
+  (let [result (apply shell/sh cmd-and-args)
         out (:out result)
         err (:err result)]
     (when (seq out)
       (log/debug out))
     (when (seq err)
       (log/error err))
-    (:exit result)))
+    result))
+
+(defn terminate-external-process!
+  [pid]
+  (:exit (exec "kill" "-9" (str pid))))

 (defn terminate-descendants!
   [process-data]


Refactor pod diff showing logic

Refactor pod diff showing logic

--- src/day8/re_frame/trace/view/app_db.cljs
+++ src/day8/re_frame/trace/view/app_db.cljs
@@ -201,41 +201,46 @@

                               #_"---main-section---"]])
                 (when render-diff?
-                  [rc/v-box
-                   :height common/gs-19s
-                   :justify :end
-                   :style {:margin (css-join "0px" pad-padding)}
-                   :children [[rc/hyperlink-href
-                               ;:class "app-db-path--label"
-                               :label "ONLY BEFORE"
-                               :href "https://github.com/Day8/re-frame-trace/wiki/app-db#diff"]]])
-                (when render-diff?
-                  [rc/v-box
-                   :height "60px"
-                   :min-width "100px"
-                   :style {:background-color cljs-dev-tools-background
-                           :padding          common/gs-7s
-                           :margin           (css-join "0px" pad-padding)}
-                   :children [[components/simple-render
-                               diff-before]]])
-                (when render-diff?
-                  [rc/v-box
-                   :height common/gs-19s
-                   :justify :end
-                   :style {:margin (css-join "0px" pad-padding)}
-                   :children [[rc/hyperlink-href
-                               ;:class "app-db-path--label"
-                               :label "ONLY AFTER"
-                               :href "https://github.com/Day8/re-frame-trace/wiki/app-db#diff"]]])
-                (when render-diff?
-                  [rc/v-box
-                   :height "60px"
-                   :min-width "100px"
-                   :style {:background-color cljs-dev-tools-background
-                           :padding          common/gs-7s
-                           :margin           (css-join "0px" pad-padding)}
-                   :children [[components/simple-render
-                               diff-before]]])
+                  (list
+                    ^{:key "only-before"}
+                    [rc/v-box
+                     :height common/gs-19s
+                     :justify :end
+                     :style {:margin (css-join "0px" pad-padding)}
+                     :children [[rc/hyperlink-href
+                                 ;:class "app-db-path--label"
+                                 :label "ONLY BEFORE"
+                                 :href "https://github.com/Day8/re-frame-trace/wiki/app-db#diff"]]]
+
+                    ^{:key "only-before-diff"}
+                    [rc/v-box
+                     :height "60px"
+                     :min-width "100px"
+                     :style {:background-color cljs-dev-tools-background
+                             :padding          common/gs-7s
+                             :margin           (css-join "0px" pad-padding)}
+                     :children [[components/simple-render
+                                 diff-before]]]
+
+                    ^{:key "only-after"}
+                    [rc/v-box
+                     :height common/gs-19s
+                     :justify :end
+                     :style {:margin (css-join "0px" pad-padding)}
+                     :children [[rc/hyperlink-href
+                                 ;:class "app-db-path--label"
+                                 :label "ONLY AFTER"
+                                 :href "https://github.com/Day8/re-frame-trace/wiki/app-db#diff"]]]
+
+                    ^{:key "only-after-diff"}
+                    [rc/v-box
+                     :height "60px"
+                     :min-width "100px"
+                     :style {:background-color cljs-dev-tools-background
+                             :padding          common/gs-7s
+                             :margin           (css-join "0px" pad-padding)}
+                     :children [[components/simple-render
+                                 diff-before]]]))
                 (when open?
                   [rc/gap-f :size pad-padding])]]))


Remove unused import

Remove unused import

--- src/desdemona/jobs/sample_submit_job.clj
+++ src/desdemona/jobs/sample_submit_job.clj
@@ -3,7 +3,6 @@
             [desdemona.tasks.kafka :refer [add-kafka-input]]
             [desdemona.tasks.sql :refer [add-sql-insert-output]]
             [desdemona.lifecycles.sample-lifecycle :refer [build-lifecycles]]
-            [desdemona.lifecycles.metrics :refer [add-metrics]]
             [desdemona.lifecycles.logging :refer [add-logging]]
             [desdemona.workflows.sample-workflow :refer [build-workflow]]
             [aero.core :refer [read-config]]


use the cdn paths and asset paths in the template so we can mix stefon and cdn

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -22,77 +22,77 @@
 (def templates
   {"ruby" {:language "Ruby"
            :headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
-           :logo-path "/img/outer/languages/ruby-logo.svg"
+           :logo-path (utils/cdn-path "/img/outer/languages/ruby-logo.svg")
            :features [{:feature "CircleCI provides support for a wide variety of Ruby versions and gems, including Ruby on Rails. It is trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
                        :title "Built For Ruby"
-                       :icon "/img/outer/languages/gear-icon.svg"}
+                       :icon (utils/cdn-path "/img/outer/languages/gear-icon.svg")}
                       {:feature "Circle manages all your database requirements for you, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB as well as frameworks such as DataMapper, Mongoid, and ActiveRecord. You can also add custom database commands via your circle.yml."
                        :title "Database Management"
-                       :icon "/img/outer/languages/file-icon.svg"}
+                       :icon (utils/cdn-path "/img/outer/languages/file-icon.svg")}
                       {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha. Parallel builds can also be set up automatically for your Ruby projects to keep build times down."
                        :title "Inference That Just Works"
-                       :icon "/img/outer/languages/book-icon.svg"}]
+                       :icon (utils/cdn-path "/img/outer/languages/book-icon.svg")}]
            :docs-link "/docs/language-ruby-on-rails"
            :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
-                           :img "/img/outer/languages/olivier.jpg"
+                           :img (utils/cdn-path "/img/outer/languages/olivier.jpg")
                            :author "Olivier Melcher"
                            :title "Developer @PasswordBox"}
                           {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                           :img "/assets/img/outer/stories/john.jpg"
+                           :img (stefon/asset-path "/img/outer/stories/john.jpg")
                            :author "John Duff"
                            :title "Director of Engineering @Shopify"}
                           {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                           :img "/img/outer/languages/aaron.jpg"
+                           :img (utils/cdn-path "/img/outer/languages/aaron.jpg")
                            :author "Aaron Suggs"
                            :title "Operations Engineer @Kickstarter"}]}
    "python" {:language "Python"
              :headline "CircleCI makes Continous Integration and Deployment for Python projects a breeze."
-             :logo-path "/img/outer/languages/python-logo.svg"
+             :logo-path (utils/cdn-path "/img/outer/languages/python-logo.svg")
              :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
                          :title "Built For Ruby"
-                         :icon "/img/outer/languages/gear-icon.svg"}
+                         :icon (utils/cdn-path "/img/outer/languages/gear-icon.svg")}
                         {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
                          :title "Database Management"
-                         :icon "/img/outer/languages/file-icon.svg"}
+                         :icon (utils/cdn-path "/img/outer/languages/file-icon.svg")}
                         {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
                          :title "Inference That Just Works"
-                         :icon "/img/outer/languages/book-icon.svg"}]
+                         :icon (utils/cdn-path "/img/outer/languages/book-icon.svg")}]
              :docs-link "/docs/language-ruby-on-rails"
              :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
-                             :img "/img/outer/languages/olivier.jpg"
+                             :img (utils/cdn-path "/img/outer/languages/olivier.jpg")
                              :author "Olivier Melcher"
                              :title "Developer @PasswordBox"}
                             {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                             :img "/assets/img/outer/stories/john.jpg"
+                             :img (stefon/asset-path "/img/outer/stories/john.jpg")
                              :author "John Duff"
                              :title "Director of Engineering @Shopify"}
                             {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                             :img "/img/outer/languages/aaron.jpg"
+                             :img (utils/cdn-path "/img/outer/languages/aaron.jpg")
                              :author "Aaron Suggs"
                              :title "Operations Engineer @Kickstarter"}]}
    "node" {:language "Node"
            :headline "CircleCI makes Continous Integration and Deployment for Node.js projects a breeze."
-           :logo-path "/img/outer/languages/node-logo.svg"
+           :logo-path (utils/cdn-path "/img/outer/languages/node-logo.svg")
            :features [{:feature "CircleCI uses RVM to provide support for a wide variety of Ruby versions and gems. It is also trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
                        :title "Built For Ruby"
-                       :icon "/img/outer/languages/gear-icon.svg"}
+                       :icon (utils/cdn-path "/img/outer/languages/gear-icon.svg")}
                       {:feature "Circle manages all your database requirements for your, such as running your rake commands for creating, loading, and migrating your database. We have pre-installed more than a dozen databases and queues, including PostgreSQL, MySQL, and MongoDB. You can also add custom database commands via your circle.yml."
                        :title "Database Management"
-                       :icon "/img/outer/languages/file-icon.svg"}
+                       :icon (utils/cdn-path "/img/outer/languages/file-icon.svg")}
                       {:feature "For the majority of Ruby projects no configuration is required; you just run your builds on CircleCI and it works! CircleCI will automatically infer your test commands if you're using Test::Unit, RSpec, Cucumber, Spinach, Jasmine, or Konacha."
                        :title "Inference That Just Works"
-                       :icon "/img/outer/languages/book-icon.svg"}]
+                       :icon (utils/cdn-path "/img/outer/languages/book-icon.svg")}]
            :docs-link "/docs/language-ruby-on-rails"
            :testimonials [{:text "I was up and running in CircleCI with Node in literally minutes.  It guessed the correct settings and was running my tests before I even understood what was happening.  Later when we needed more fine grained control it was very easy to grow into greater customization with our integrations.  CircleCI has transformed our testing and deployment process, and allowed us to develop and deploy much faster."
-                           :img "/img/outer/languages/ben.jpg"
+                           :img (utils/cdn-path "/img/outer/languages/ben.jpg")
                            :author "Ben Bernard"
                            :title "CTO @FieldBook"}
                           {:text "CircleCI lets us be more agile and ship product faster. We can focus on delivering value to our customers, not maintaining Continuous Integration and Delivery infrastructure."
-                           :img "/assets/img/outer/stories/john.jpg"
+                           :img (stefon/asset-path "/img/outer/stories/john.jpg")
                            :author "John Duff"
                            :title "Director of Engineering @Shopify"}
                           {:text "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently. CircleCI's customer support is outstanding. We get quick, thorough answers to all our questions."
-                           :img "/img/outer/languages/aaron.jpg"
+                           :img (utils/cdn-path "/img/outer/languages/aaron.jpg")
                            :author "Aaron Suggs"
                            :title "Operations Engineer @Kickstarter"}]}})

@@ -107,7 +107,7 @@
         (html
          [:div.languages.page
           [:div.languages-head {:class (:language template)}
-           [:img {:src (utils/cdn-path (:logo-path template))}]
+           [:img {:src (:logo-path template)}]
            [:h1 (:headline template)]
            [:div.languages-screenshots]
            [:div.hero-shadow]]
@@ -120,7 +120,7 @@
                (if (odd? i)
                  [:div.feature
                   [:div.feature-image
-                   [:img {:src (utils/cdn-path (:icon feature))}]]
+                   [:img {:src (:icon feature)}]]
                   [:div.feature-copy
                    [:h4.feature-title (:title feature)]
                    [:p.feature-description (:feature feature)]]]
@@ -129,7 +129,7 @@
                    [:h4.feature-title (:title feature)]
                    [:p.feature-description (:feature feature)]]
                   [:div.feature-image
-                   [:img {:src (utils/cdn-path (:icon feature))}]]]))
+                   [:img {:src (:icon feature)}]]]))
              (:features template))

             [:div.button
@@ -139,7 +139,7 @@
             [:div.center-text
              [:h3 "TESTIMONIALS"]]
             [:div.testimonial-authors
-             (map-indexed (fn [i testimonial] [:img {:src (utils/cdn-path (:img testimonial)) :on-click #(put! controls-ch [:language-testimonial-tab-selected {:index i}])}])
+             (map-indexed (fn [i testimonial] [:img {:src (:img testimonial) :on-click #(put! controls-ch [:language-testimonial-tab-selected {:index i}])}])
                           (:testimonials template))]
             [:div.testimonial-box
              [:div.testimonial


Fixed :allow-snapshots.

Fixed :allow-snapshots.

--- src/leiningen/ancient/maven_metadata.clj
+++ src/leiningen/ancient/maven_metadata.clj
@@ -84,7 +84,7 @@
   [{:keys [allow-snapshots allow-qualified]} version-maps]
   (let [v version-maps
         v (if-not allow-snapshots (filter (complement snapshot?) v) v)
-        v (if-not allow-qualified (filter (comp nil? :qualifier) v) v)]
+        v (if-not allow-qualified (filter #(or (snapshot? %) (nil? (:qualifier %))) v) v)]
     v))

 (defn latest-version
@@ -92,8 +92,9 @@
    string."
   ([mta] (latest-version mta nil))
   ([mta settings]
-   (->> (version-seq mta)
-     (map version-map)
-     (filter-versions settings)
-     (version-sort)
-     (last))))
+   (let [vs (version-seq mta)]
+     (->> vs
+       (map version-map)
+       (filter-versions settings)
+       (version-sort)
+       (last)))))


I can't explain..

I can't explain..

--- ClojureScript/hello.cljs
+++ ClojureScript/hello.cljs
@@ -11,20 +11,27 @@
         [goog.graphics.Stroke :as Stroke]
         [goog.graphics.SolidFill :as SolidFill]
         [goog.graphics.Path :as Path]
+        [goog.date.UtcDateTime :as UtcDateTime]
         ))

 (def my-code-url "https://github.com/pauldoo/scratch/blob/master/ClojureScript/hello.cljs")
 (def width-in-px 800)
 (def height-in-px 300)
-(def tick-step (/ 1 100))
-(def render-step (/ 1 25))
-(def gravity-strength 300)
-(def ground-rebound-strength 200)
-(def ground-grip-strength 50)
-(def drag-factor 5)
+(def ideal-tick-step (/ 1 100))
+(def worst-tick-step (/ 1 50))
+(def ideal-render-step (/ 1 25))
+(def gravity-strength 500)
+(def ground-rebound-strength 500)
+(def ground-drag-factor 30)
+(def air-drag-factor 1)

 (defn print-to-log [v]
     (.log js/console v))
+
+(defn print-passer [v] (do
+    (print-to-log (pr-str v))
+    v))
+

 (def vec- (partial map -))
 (def vec+ (partial map +))
@@ -47,7 +54,7 @@
     :springs (map
         (fn [s] (assoc s
             :rest-length (magnitude (vec- (:pos (nodes (:node-a s))) (:pos (nodes (:node-b s)))))
-            :strength 2000))
+            :strength 500))
         springs)
     :hinges (map
         (fn [h] (assoc h
@@ -56,7 +63,7 @@
                 c (vec- (:pos (nodes (:node-c h))) (:pos (nodes (:node-b h))))]
                 (angle a c))
             :modifier-angle 0.0
-            :strength 1000000))
+            :strength 2000000))
         hinges)
 })

@@ -67,23 +74,25 @@
         :head (make-node 300 150 2)
         :tail (make-node 100 150 2)

-        :h-l-k (make-node 310 75 0.5)
+        :h-l-k (make-node 300 75 0.5)
         :h-l-f (make-node 300 0 0.5)
-        :h-t-k (make-node 310 75 0.5)
+        :h-t-k (make-node 300 75 0.5)
         :h-t-f (make-node 300 0 0.5)

-        :t-l-k (make-node 90 75 0.5)
+        :t-l-k (make-node 100 75 0.5)
         :t-l-f (make-node 100 0 0.5)
-        :t-t-k (make-node 90 75 0.5)
+        :t-t-k (make-node 100 75 0.5)
         :t-t-f (make-node 100 0 0.5)

         :top-of-head (make-node 320 200 1)
+        :end-of-tail (make-node 80 200 1)
     }
     (map (partial apply make-spring) [
         [:head-a :head]
         [:tail-a :tail]
         [:head-a :tail-a]
         [:top-of-head :head]
+        [:end-of-tail :tail]
         [:head :tail]
         [:head :h-l-k]
         [:h-l-k :h-l-f]
@@ -96,18 +105,19 @@
     ])
     (map (partial apply make-hinge) [
         [:tail :head :h-l-k -0.7 0.7]
-        [:head :h-l-k :h-l-f -1 0.0]
+        [:head :h-l-k :h-l-f -1.2 0.2]
         [:tail :head :h-t-k -0.7 0.7]
-        [:head :h-t-k :h-t-f -1 0.0]
+        [:head :h-t-k :h-t-f -1.2 0.2]
         [:head :tail :t-l-k -0.7 0.7]
-        [:tail :t-l-k :t-l-f -1 0.0]
+        [:tail :t-l-k :t-l-f -1.2 0.2]
         [:head :tail :t-t-k -0.7 0.7]
-        [:tail :t-t-k :t-t-f -1 0.0]
+        [:tail :t-t-k :t-t-f -1.2 0.2]
         [:tail :head :top-of-head 0.0 0.0]
         [:head :tail :tail-a 0.0 0.0]
         [:tail :tail-a :head-a 0.0 0.0]
         [:tail-a :head-a :head 0.0 0.0]
         [:head-a :head :tail 0.0 0.0]
+        [:head :tail :end-of-tail 0.0 0.0]
     ])
 ))

@@ -170,32 +180,56 @@

 (defn calculate-ground-forces [nodes]
     (zipmap (keys nodes)
-        (map (fn [{[ x y ] :pos [ xv yv ] :vel }]
+        (map (fn [{[ _ y ] :pos}]
             (if (< y 0)
-                (vec+
-                    (vec* [(- xv) (Math/max 0 (- yv))] ground-grip-strength)
-                    (vec* [0 (- y)] ground-rebound-strength))
-                [0 0])) (vals nodes))))
-
-(defn calculate-drag-forces [nodes]
-    (zipmap (keys nodes)
-        (map (fn [{v :vel m :mass}] (vec* v (- (* m drag-factor))))
+                (vec* [0 (- y)] ground-rebound-strength)
+                [0 0]))
             (vals nodes))))
+
+(defn calculate-ground-impulses [nodes time-step]
+    (let [loss (- 1.0 (Math/exp (- (* time-step ground-drag-factor))))]
+        (zipmap (keys nodes)
+            (map (fn [{[ _ y ] :pos [ xv yv ] :vel mass :mass}]
+                (if (< y 0)
+                    (vec* [(- xv) (Math/max 0 (- yv))] (* loss mass))
+                    [0 0]))
+                (vals nodes)))))
+
+(defn calculate-air-impulses [nodes time-step]
+    (let [loss (- 1.0 (Math/exp (- (* time-step air-drag-factor))))]
+        (zipmap (keys nodes)
+            (map (fn [{[_ y] :pos vel :vel mass :mass}]
+                (if (< y 0)
+                    [0 0]
+                    (vec* vel (* -1 loss mass))))
+                (vals nodes)))))

 (defn calculate-all-node-forces [{:keys [nodes springs hinges]}]
     (merge-with vec+
         (calculate-spring-forces nodes springs)
         (calculate-hinge-forces nodes hinges)
         (calculate-gravity-forces nodes)
-        (calculate-ground-forces nodes)
-        (calculate-drag-forces nodes)))
-
-(defn update-node-velocities [nodes forces time-step]
-    (merge-with (fn [n f]
-        (assoc n
-            :vel (vec+ (:vel n) (vec* f (/ time-step (:mass n))))))
-        nodes
-        forces))
+        (calculate-ground-forces nodes)))
+
+(defn calculate-all-node-impulses [nodes time-step]
+    (merge-with vec+
+        (calculate-ground-impulses nodes time-step)
+        (calculate-air-impulses nodes time-step)))
+
+(defn update-node-velocities [nodes forces impulses time-step]
+    (merge-with
+        (fn [n i] (assoc n
+            :vel (vec+
+                (:vel n)
+                (vec* i (/ 1.0 (:mass n))))))
+        (merge-with
+            (fn [n f] (assoc n
+                :vel (vec+
+                    (:vel n)
+                    (vec* f (/ time-step (:mass n))))))
+            nodes
+            forces)
+        impulses))

 (defn update-node-positions [nodes time-step]
     (zipmap (keys nodes) (map (fn [n]
@@ -216,6 +250,27 @@

 (defn hinge-nodes [h]
     (map h [:node-a :node-b :node-c]))
+
+(defn now-in-milliseconds []
+    (. (goog.date.UtcDateTime.) (getTime)))
+
+(defn delta [f]
+    (let [prev (atom (f))] (fn []
+        (let [next (f) result (- next @prev)] (do
+            (reset! prev next)
+            result)))))
+
+(defn limiter [f]
+    (fn [] (Math/min (* 1000 worst-tick-step) (f))))
+
+(defn smooth [f]
+    (let [prev (atom 0.0)] (fn []
+        (let [next (f) result (+ (* 0.01 next) (* 0.99 @prev))] (do
+            (reset! prev result)
+            result)))))
+
+(def real-tick-step
+    (smooth (limiter (delta now-in-milliseconds))))

 (defn tick-imp [state tick-step input-state]
     (assoc state
@@ -254,11 +309,12 @@
                 (update-node-velocities
                     (:nodes state)
                     (calculate-all-node-forces state)
+                    (calculate-all-node-impulses (:nodes state) tick-step)
                     tick-step)
                 tick-step)))

-(defn tick [game-state-ref input-state] (do
-    (swap! game-state-ref #(tick-imp % tick-step input-state))))
+(defn tick [game-state-ref input-state] (let [real-step (* 0.001 (real-tick-step))] (do
+    (swap! game-state-ref #(tick-imp % real-step input-state)))))

 (defn world-to-screen [[x y]]
     [x (- 275 y)])
@@ -301,8 +357,8 @@
         game-state-ref (atom initial-game-state)
         input-state-ref (atom {:keys (set)})
         canvas (dom/createDom "div" {} "")
-        tick-timer (goog.Timer. (Math/round (* 1000 tick-step)))
-        render-timer (goog.Timer. (Math/round (* 1000 render-step)))
+        tick-timer (goog.Timer. (Math/round (* 1000 ideal-tick-step)))
+        render-timer (goog.Timer. (Math/round (* 1000 ideal-render-step)))
         ]
         (do
             (. tick-timer (start))


remove error debug

remove error debug

--- kafka-clj/src/kafka_clj/consumer/node.clj
+++ kafka-clj/src/kafka_clj/consumer/node.clj
@@ -36,7 +36,6 @@
   {:pre [redis-conn topics group-name]}
   ;timeout-ms wait-ms
   (let [lock-timeout (* 10 60000)]
-    (error "Work-calculate-delegate!!!: lock")
     (try
       (redis/with-lock
         redis-conn


Fix board uuid.

Fix board uuid.

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -107,7 +107,7 @@
         secure-uuid (:secure-uuid entry)
         org-uuid (:org-uuid entry)
         org-slug (:slug org)
-        board-uuid (:board-uuid board)
+        board-uuid (:uuid board)
         board-slug (:slug board)
         draft? (= :draft (keyword (:status entry)))
         full-entry (if draft?


Write typical-stage-separation

Write typical-stage-separation

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -171,6 +171,15 @@
   ([] (second (typical-stage-extent)))
   ([length-unit]
    (second (typical-stage-extent (constantly (typical-stage-top length-unit))))))
+
+(defn typical-stage-separation
+  "Calculate a typical stage separation (from bottom of previous stage to top of next stage)."
+  ([length-unit]
+   (case length-unit
+     :ft (make-measurement (tuc/draw-normal 495.763 106.098) length-unit)
+     :m (length-as (typical-stage-separation :ft) length-unit)))
+  ([] (let [length-unit (rand-length-unit)]
+        (typical-stage-separation length-unit))))

 (defn typical-stage-completion-time
   "Calculates the typical time in seconds for a stage to be completed."


Reduced duplicate code to convert units

Reduced duplicate code to convert units

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -78,30 +78,19 @@
                    [:m3 :bbl]                 #(* % (factors [:m3 :bbl]))}]
     (converter [from to])))

-(defn force-as [[magnitude from] to]
-  (let [factor 4.44822]  ; pound-force -> Newton
+(defn as-f [from-unit to-unit factor]
+  (fn [[magnitude from] to]
     (condp = [from to]
-      [:lbf :N] [(* magnitude factor) to]
-      [:N :lbf] [(/ magnitude factor) to])))
-
-(defn power-as [[magnitude from] to]
-  (let [factor 745.69987158227022]  ; hp -> W
-    (condp = [from to]
-      [:hp :W] [(* magnitude factor) to]
-      [:W :hp] [(/ magnitude factor) to])))
-
-(defn proppant-concentration-as [[magnitude from] to]
-  (let [factor 119.826]  ; lb-per-gal -> kg-per-cu-m
-    (condp = [from to]
-      [:lb-per-gal :kg-per-m3] [(* magnitude factor) to]
-      [:kg-per-m3 :lb-per-gal] [(/ magnitude factor) to])))
-
-(defn slurry-rate-as [[magnitude from] to]
-  (let [factor 6.28981077]  ; bbl -> m^3 (duration same for both)
-    (condp = [from to]
-      [:bpm :m3-per-min] [(* magnitude factor) to]
-      [:m3-per-min :bpm] [(/ magnitude factor) to])))
-
+      [from-unit to-unit] [(* magnitude factor) to]
+      [to-unit from-unit] [(/ magnitude factor) to])))
+
+(def force-as (as-f :lbf :N 4.44822))
+(def power-as (as-f :hp :W 745.69987158227022))
+(def proppant-concentration-as (as-f :lb-per-gal :kg-per-m3 119.826))
+(def slurry-rate-as (as-f :bpm :m3-per-min 6.28981077))
+
+;; Because conversion between temperature units is not simply multiplicative, I define this function with a
+;; unique body.
 (defn temperature-as [[magnitude from] to]
   (let [f->c #(/ (- % 32) 1.8)
         c->f #(+ (* % 1.8) 32)]


Catch request errors from CISI

Catch request errors from CISI

--- streamable.clj
+++ streamable.clj
@@ -31,20 +31,27 @@
 (defn assoc-streaming-options [ep]
   (println "Getting options for" (:media_title ep))
   (flush)
-  (let [resp (http/get
-               "http://www.canistream.it/services/query"
-               {:query-params {:movieId (:cisi_id ep)
-                               :attributes true
-                               :mediaType "streaming"}
-                :accept :json
-                :as :json})]
-    (->> resp
-         :body
-         vals
-         (map :friendlyName)
-         (map #(or (service-aliases %) %))
-         set
-         (assoc ep :streaming_options))))
+  (let [resp
+        (try
+          (http/get
+                 "http://www.canistream.it/services/query"
+                 {:query-params {:movieId (:cisi_id ep)
+                                 :attributes true
+                                 :mediaType "streaming"}
+                  :accept :json
+                  :as :json})
+          (catch Exception e
+            (println "Request failed")))]
+    (if
+     (nil? resp)
+      (assoc ep :streaming_options [])
+      (->> resp
+           :body
+           vals
+           (map :friendlyName)
+           (map #(or (service-aliases %) %))
+           set
+           (assoc ep :streaming_options)))))

 (def throttled-options (throttle-fn assoc-streaming-options 1 :second 4))


Bring tests in line with Ruby tests.

Bring tests in line with Ruby tests.

The Ruby spec for Bob includes a number of tests that clarify certain
points of Bob's behavior.  This commit brings them to the Clojure spec
for Bob.

--- assignments/clojure/bob/bob_test.clj
+++ assignments/clojure/bob/bob_test.clj
@@ -1,14 +1,35 @@
 (ns bob.test (:use clojure.test))
 (load-file "bob.clj")

+(deftest responds-to-something
+  (is (= "Whatever." (bob/response-for "Tom-ay-to, tom-aaaah-to."))))
+
 (deftest responds-to-shouts
-  (is (= "Woah, chill out!" (bob/response-for "SHOUTING"))))
+  (is (= "Woah, chill out!" (bob/response-for "WATCH OUT!"))))

 (deftest responds-to-questions
-  (is (= "Sure." (bob/response-for "A question?"))))
+  (is (= "Sure." (bob/response-for "Does this cryogenic chamber make me look fat?"))))

-(deftest responds-to-statements
-  (is (= "Whatever." (bob/response-for "A statement."))))
+(deftest responds-to-forceful-talking
+  (is (= "Whatever." (bob/response-for "Let's go make out behind the gym!"))))
+
+(deftest responds-to-acronyms
+  (is (= "Whatever." (bob/response-for "It's OK if you don't want to go to the DMV."))))
+
+(deftest responds-to-forceful-questions
+  (is (= "Woah, chill out!" (bob/response-for "WHAT THE HELL WERE YOU THINKING?"))))
+
+(deftest responds-to-shouting-with-special-characters
+  (is (= "Woah, chill out!" (bob/response-for "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"))))
+
+(deftest responds-to-shouting-numbers
+  (is (= "Woah, chill out!" (bob/response-for "1, 2, 3 GO!"))))
+
+(deftest responds-to-shouting-with-no-exclamation-mark
+  (is (= "Woah, chill out!" (bob/response-for "I HATE YOU"))))
+
+(deftest responds-to-statement-containing-question-mark
+  (is (= "Whatever." (bob/response-for "Ending with ? means a question."))))

 (deftest responds-to-silence
   (is (= "Fine, be that way." (bob/response-for ""))))


CW + JC | Added kerodon test for 500 error page

--- test/stonecutter/integration/kerodon.clj
+++ test/stonecutter/integration/kerodon.clj
@@ -1,13 +1,20 @@
 (ns stonecutter.integration.kerodon
   (:require [midje.sweet :refer :all]
             [kerodon.core :as k]
-            [stonecutter.handler :refer [app]]
+            [stonecutter.handler :as h]
             [stonecutter.storage :as s]
+            [stonecutter.logging :as l]
+            [stonecutter.view.register :refer [registration-form]]
             [net.cgrand.enlive-html :as html]))
+
+(l/init-logger!)
+
+(defn page-title [state]
+  (-> state :enlive (html/select [:title]) first html/text))

 (defn page-title-is [state title]
   (fact {:midje/name "Checking page title:"}
-        (-> state :enlive (html/select [:title]) first html/text) => title)
+       (page-title state) => title)
   state)

 (defn page-uri-is [state uri]
@@ -27,14 +34,14 @@
 (s/start-in-memory-datastore!)

 (facts "Home url redirects to registration page"
-       (-> (k/session app)
+       (-> (k/session h/app)
            (k/visit "/")
            (k/follow-redirect)
            (page-title-is "Register")
            (page-uri-is "/register")))

 (facts "User is returned to same page when email is invalid"
-       (-> (k/session app)
+       (-> (k/session h/app)
            (k/visit "/register")
            (k/fill-in "Email address" "invalid-email")
            (k/press "Create account")
@@ -42,7 +49,7 @@
            (selector-has-content [:.clj--registration-email__validation] "Enter a valid email address")))

 (facts "User is taken to success page when user is successfully created"
-       (-> (k/session app)
+       (-> (k/session h/app)
            (k/visit "/register")
            (k/fill-in :.func--email__input "email@server.com")
            (k/fill-in :.func--password__input "valid-password")
@@ -52,7 +59,7 @@
            (selector-has-content [:body] "You saved the user")))

 (future-facts "User can sign in"
-       (-> (k/session app)
+       (-> (k/session h/app)
            (k/visit "/sign-in")
            (k/fill-in :.func--email__input "email@server.com")
            (k/fill-in :.func--password__input "valid-password")
@@ -61,6 +68,13 @@
            (selector-has-content [:body] "You are signed in as email@server.com")))

 (facts "Not found page is shown for unknown url"
-       (-> (k/session app)
+       (-> (k/session h/app)
            (k/visit "/wrong-url")
            (page-title-is "Error-404")))
+
+(fact "Error page is shown if an exception is thrown"
+      (against-background
+         (registration-form anything) =throws=> (Exception.))
+       (-> (k/session (h/wrap-error-handling h/app))
+           (k/visit "/register")
+           (page-title-is "Error-500")))


and clojure catches up to the pack - w00t

--- tls.clj
+++ tls.clj
@@ -30,17 +30,35 @@
     :else (cons (first (first l))
                 (firsts (rest l)))))

-; insertR
 (defn insertR [n o lat]
   (cond
     (null? lat) '()
-    (= (first lat) n) (cons o (cons n (rest lat)))
-    :else (cons (first lat) (insertR n o (rest lat)))))
+    (= (first lat) o) (cons o (cons n (rest lat)))
+    :else (cons (first lat)
+                (insertR n o (rest lat)))))

-(defn abs [x]
+(defn insertL [n o lat]
   (cond
-    (< x 0) (* x -1)
-    :else x))
+    (null? lat) '()
+    (= (first lat) o) (cons n lat)
+    :else (cons (first lat)
+                (insertL n o (rest lat)))))
+
+(defn subst [n o lat]
+  (cond
+    (null? lat) '()
+    (= (first lat) o) (cons n (rest lat))
+    :else (cons (first lat)
+                (subst n o (rest lat)))))
+
+; end of LISPer, bonus practice
+(defn subst2 [n o1 o2 lat]
+  (cond
+    (null? lat) '()
+    (or (= (first lat) o1)
+        (= (first lat) o2)) (cons n (rest lat))
+    :else (cons (first lat)
+                (subst2 n o1 o2 (rest lat)))))

 (defn add1 [x]
   (+ x 1))


use new permissions model when checking access

--- src/pc/auth.clj
+++ src/pc/auth.clj
@@ -72,15 +72,16 @@
                db prcrsr-bot-email)))

 (defn document-permission [db doc cust]
-  (cond (and cust
-             (:document/creator doc)
-             (crypto/eq? (str (:cust/uuid cust))
-                         (str (:document/creator doc))))
-        :admin
+  (when cust
+    (cond (and (:document/creator doc)
+               (crypto/eq? (str (:cust/uuid cust))
+                           (str (:document/creator doc))))
+          :admin

-        (contains? (permission-model/permits db doc cust) :permission.permits/admin)
-        :admin
-        :else nil))
+          (contains? (permission-model/permits db doc cust) :permission.permits/admin)
+          :admin
+
+          :else nil)))

 (defn has-document-permission? [db doc auth]
   (or (= :document.privacy/public (:document/privacy doc))


Fixed missing ring name.

Fixed missing ring name.

--- deploy/src/elephantdb/deploy/crate/edb.clj
+++ deploy/src/elephantdb/deploy/crate/edb.clj
@@ -21,7 +21,9 @@
                           ["releases" "shared" "log"]))

 (defn- template-context [req]
-  {"GLOBALCONF" (format "%s/global-conf.clj" s3-configs-dir (-> req :environment :ring))
+  {"GLOBALCONF" (str s3-configs-dir
+                     (-> req :environment :ring)
+                     "/global-conf.clj")
    "TOKEN" (int (/ (System/currentTimeMillis) 1000))})

 (defn make-release! []
@@ -37,11 +39,11 @@
       (.setAttribute template k v))
     (str template)))

-(defn render-remote-file! [req rel-path]
+(defn render-remote-file! [session rel-path]
   (let [dst-path (str service-dir rel-path)
         src-path (str local-template-dir rel-path)
-        render (render-template! src-path (template-context req))]
-    (-> req
+        render (render-template! src-path (template-context session))]
+    (-> session
         (remote-file dst-path :content render :mode 744))))

 (defn filelimits [session fd-limit user-seq]


Comment devtools out

Comment devtools out

--- dev/cljs/learn_specter/dev.cljs
+++ dev/cljs/learn_specter/dev.cljs
@@ -3,5 +3,8 @@

 ;; note: unsure how to include this in boot build process

-(devtools/enable-feature! :sanity-hints :dirac)
-(devtools/install!)
+(comment
+  (require '[devtools.core :as devtools])
+  (devtools/enable-feature! :sanity-hints :dirac)
+  (devtools/install!)
+  )


Ready to release menu 0.5.2

Ready to release menu 0.5.2

--- modules/menu/project.clj
+++ modules/menu/project.clj
@@ -1,6 +1,6 @@
 ;; Copyright © 2014 JUXT LTD.

-(defproject juxt.modular/menu "0.5.2-SNAPSHOT"
+(defproject juxt.modular/menu "0.5.2"
   :description "A modular extension that provides support for menus, navbars, and other navigation elements that house hyperlinks."
   :url "https://github.com/juxt/modular/tree/master/modules/nav"
   :license {:name "The MIT License"
@@ -8,4 +8,4 @@
   :dependencies [[com.stuartsierra/component "0.2.1"]
                  [prismatic/schema "0.2.1"]
                  ;; menu extends Cylon's login-form
-                 [cylon "0.4.0-SNAPSHOT"]])
+                 [cylon "0.4.0"]])


(PDB-3038) Add timeouts to command_test chan takes

core.async's take from a channel are blocking. This commit adds a new
function that will perform the blocking take, but timeout after a given
number of milliseconds. I set the timeout intentionally high (i.e. five
minutes), so that it will hopefully never get tripped in real
circumstances (even on slow CI test hardware)

--- test/puppetlabs/puppetdb/command_test.clj
+++ test/puppetlabs/puppetdb/command_test.clj
@@ -109,6 +109,19 @@
 (defn store-command' [q old-command]
   (apply tqueue/store-command q (unroll-old-command old-command)))

+(def default-timeout-in-ms
+  (* 1000 60 5))
+
+(defn take-with-timeout!!
+  "Takes from `port` via <!!, but will throw an exception if
+  `timeout-in-ms` expires"
+  [port timeout-in-ms]
+  (async/alt!!
+    (async/timeout timeout-in-ms)
+    (throw (Exception. (format "Take from channel failed after timeout of '%s' ms was exceeded" timeout-in-ms)))
+    port
+    ([v] v)))
+
 (deftest command-processor-integration
   (let [command {:command "replace catalog" :version 5
                  :payload (get-in wire-catalogs [5 :empty])}]
@@ -143,7 +156,7 @@

                   (is (empty? (fs/list-dir (:path dlo))))

-                  (let [delayed-command (async/<!! command-chan)
+                  (let [delayed-command (take-with-timeout!! command-chan default-timeout-in-ms)
                         actual-exception (:exception (first (:attempts delayed-command)))]
                     (are [x y] (= x y)
                       cmdref (dissoc delayed-command :attempts)
@@ -995,7 +1008,7 @@

             (handle-message (store-command' q new-facts-cmd))
             (reset! second-message? true)
-            (let [failed-cmdref (async/<!! command-chan)]
+            (let [failed-cmdref (take-with-timeout!! command-chan default-timeout-in-ms)]
               (is (= 1 (count (:attempts failed-cmdref))))
               (is (re-matches
                    #"(?sm).*ERROR: could not serialize access due to concurrent update.*"
@@ -1216,7 +1229,7 @@
             (reset! second-message? true)
             (is (empty? (fs/list-dir (:path dlo))))

-            (let [failed-cmdref (async/<!! command-chan)]
+            (let [failed-cmdref (take-with-timeout!! command-chan default-timeout-in-ms)]
               (is (= 1 (count (:attempts failed-cmdref))))
               (is (re-matches
                    #"(?sm).*ERROR: could not serialize access due to concurrent update.*"
@@ -1281,7 +1294,7 @@
             (reset! second-message? true)

             (is (empty? (fs/list-dir (:path dlo))))
-            (let [failed-cmdref (async/<!! command-chan)]
+            (let [failed-cmdref (take-with-timeout!! command-chan default-timeout-in-ms)]
               (is (= 1 (count (:attempts failed-cmdref))))
               (is (re-matches
                    #"(?sm).*ERROR: could not serialize access due to concurrent update.*"


Moved around/refactored the code in DIF 10 collection a little bit.

--- umm-lib/src/cmr/umm/dif10/collection.clj
+++ umm-lib/src/cmr/umm/dif10/collection.clj
@@ -54,25 +54,25 @@
     (c/map->UmmCollection
       {:entry-id (:short-name product)
        :entry-title (cx/string-at-path xml-struct [:Entry_Title])
+       :personnel (personnel/xml-elem->personnel xml-struct)
+       :science-keywords (sk/xml-elem->ScienceKeywords xml-struct)
+       :platforms (platform/xml-elem->Platforms xml-struct)
+       :temporal (t/xml-elem->Temporal xml-struct)
+       :collection-progress (progress/parse xml-struct)
+       :spatial-coverage (s/xml-elem->SpatialCoverage xml-struct)
+       :projects (pj/xml-elem->Projects xml-struct)
+       :quality (cx/string-at-path xml-struct [:Quality])
+       :use-constraints (cx/string-at-path xml-struct [:Use_Constraints])
+       :organizations (org/xml-elem->Organizations xml-struct)
+       :publication-references (ref/xml-elem->References xml-struct)
        :summary (cx/string-at-path xml-struct [:Summary :Abstract])
        :purpose (cx/string-at-path xml-struct [:Summary :Purpose])
+       :related-urls (ru/xml-elem->RelatedURLs xml-struct)
+       :collection-associations (ma/xml-elem->MetadataAssociations xml-struct)
+       :product-specific-attributes (psa/xml-elem->ProductSpecificAttributes xml-struct)
        :product product
-       :quality (cx/string-at-path xml-struct [:Quality])
        :data-provider-timestamps (xml-elem->DataProviderTimestamps xml-struct)
-       :temporal-keywords (seq (cx/strings-at-path xml-struct [:Data_Resolution :Temporal_Resolution]))
-       :temporal (t/xml-elem->Temporal xml-struct)
-       :science-keywords (sk/xml-elem->ScienceKeywords xml-struct)
-       :platforms (platform/xml-elem->Platforms xml-struct)
-       :product-specific-attributes (psa/xml-elem->ProductSpecificAttributes xml-struct)
-       :collection-associations (ma/xml-elem->MetadataAssociations xml-struct)
-       :projects (pj/xml-elem->Projects xml-struct)
-       :related-urls (ru/xml-elem->RelatedURLs xml-struct)
-       :spatial-coverage (s/xml-elem->SpatialCoverage xml-struct)
-       :organizations (org/xml-elem->Organizations xml-struct)
-       :personnel (personnel/xml-elem->personnel xml-struct)
-       :publication-references (ref/xml-elem->References xml-struct)
-       :collection-progress (progress/parse xml-struct)
-       :use-constraints (cx/string-at-path xml-struct [:Use_Constraints])})))
+       :temporal-keywords (seq (cx/strings-at-path xml-struct [:Data_Resolution :Temporal_Resolution]))})))

 (defn parse-collection
   "Parses DIF 10 XML into a UMM Collection record."


Fixing function for determining if a value is a sub-component, and filtering text nodes out of the children, since we use with-text to validate text now

--- web-client/test/test_burgerboard/huh.cljs
+++ web-client/test/test_burgerboard/huh.cljs
@@ -53,7 +53,7 @@
   )

 (defn sub-component? [component]
-  (= (.. component -props -className))
+  (= "huh-sub-component" (.. component -className))
   )

 (defn test-predicates
@@ -99,7 +99,7 @@
         children (.. actual-component -props -children)]
     (cond
      (= (type children) js/Array)
-     (js->clj children)
+     (filter #(not (string? %)) (js->clj children))
      (= js/undefined children)
      []
      :else