Whoops. That needs removing as well!

Whoops. That needs removing as well!

--- src/exploud/web.clj
+++ src/exploud/web.clj
@@ -21,7 +21,6 @@
              [pokemon :as pokemon]
              [redis :as redis]
              [stats :as stats]
-             [transform :as tn]
              [util :as util]
              [validators :as v]]
             [metrics.ring


Give back objects rather than arrays

Give back objects rather than arrays

--- src/exploud/web.clj
+++ src/exploud/web.clj
@@ -97,11 +97,11 @@

    (GET "/instances/:app-name"
         [app-name]
-        (response (info/instances-for-application default-region app-name)))
+        (response {:instances (info/instances-for-application default-region app-name)}))

    (GET "/images/:app-name"
         [app-name]
-        (response (info/active-amis-for-app default-region app-name)))
+        (response {:images (info/active-amis-for-app default-region app-name)}))

    (GET "/deployments"
         [application start-from start-to size from]


inching towards reuse of BaseModelView pieces

--- dada-core/src/main/clojure/org/dada/core/SimpleModelView.clj
+++ dada-core/src/main/clojure/org/dada/core/SimpleModelView.clj
@@ -2,9 +2,9 @@
     (:use
      [org.dada.core counted-set]
      )
-    ;; (:require
-    ;;  [org.dada.core BaseModelView]
-    ;;  )
+    (:require
+     [org.dada.core BaseModelView]
+     )
     (:import
      [java.util Collection]
      [org.dada.core Metadata Update]


deflakes test-router-state-maintainer-removes-killed-instances (#425)

--- waiter/test/waiter/state_test.clj
+++ waiter/test/waiter/state_test.clj
@@ -1046,7 +1046,7 @@
         make-instance (fn [index]
                         {:id (str service-id "." index)
                          :service-id service-id
-                         :started-at (t/minus (t/now) (t/minutes index))})
+                         :started-at (t/minus (t/now) (t/seconds (+ (-> index t/minutes t/in-seconds) 10)))})
         deployment-error-config {:min-failed-instances 2
                                  :min-hosts 2}
         instance-0 (make-instance 0)


Fix inner function names

Fix inner function names

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -261,8 +261,9 @@
 (defn value
   [key value]
   [:values
-   (fn order-by-query [query-builder]
-     (.value query-builder key value))])
+   (fn value-query [query-builder]
+     (.value query-builder (name key) value))])
+

 (defn values
   ([m]
@@ -279,7 +280,7 @@
   (defn using
     [m]
     [:using
-     (fn order-by-query [query-builder]
+     (fn using-query [query-builder]
        (doseq [[key value] m]
          (.using query-builder ((get with-values key) value)))
        query-builder)]))


show more physics debug info

show more physics debug info

--- desktop/src-common/con_world/debug.clj
+++ desktop/src-common/con_world/debug.clj
@@ -6,7 +6,7 @@
   (-> main-screen :entities deref pprint))

 (defn draw-physics-bodies [screen]
-  (let [debug-renderer (Box2DDebugRenderer.)
+  (let [debug-renderer (Box2DDebugRenderer. true true true true true true)
         projection (-> main-screen :screen deref :camera .combined)
         world (:world screen)]
     (.render debug-renderer world projection)))


Fix title extraction from SoundCloud

Fix title extraction from SoundCloud

--- src/ktra_indexer/parser.clj
+++ src/ktra_indexer/parser.clj
@@ -32,7 +32,7 @@
                                                  "article > p > meta")))
                                       "content")))]
     {:title (s/trim (s/replace (first (s/split (.title document) #" by"))
-                               "KTRA" ""))
+                               "Stream" ""))
      :tracklist (if (s/index-of (s/lower-case tracklist) "tracklist")
                   (s/triml (subs tracklist (+ (s/index-of tracklist "Tracklist")
                                               (count "Tracklist"))))


Added pvalidation test to pauls-tests.

Added pvalidation test to pauls-tests.

--- test/themis/core_test.clj
+++ test/themis/core_test.clj
@@ -24,7 +24,11 @@
         paul-rules [[[:name :first] [[presence {:response {:text "First name is not there"}}]
                                      (fn [t-map data-point opt-map](Thread/sleep 500)(and (= data-point "Paul")
                                                                                {:a 1 :b 2}))]]
-                    [[:pets 0] [(from-predicate preds/longer-than? 20 "Too short; Needs to be longer than 20")]]]]
+                    [[:pets 0] [(from-predicate preds/longer-than? 20 "Too short; Needs to be longer than 20")]]]
+        paul-validation {[:name :first]  '(nil  {:a 1, :b 2}), [:pets 0] "Too short; Needs to be longer than 20"}]
     (testing "Does validation work on paul-rules?"
       (is (= (core/validation paul paul-rules)
-             {[:name :first]  '(nil  {:a 1, :b 2}), [:pets 0] "Too short; Needs to be longer than 20"})))))
+             paul-validation)))
+    (testing "Does pvalidation work on paul-rules?"
+      (is (= (core/pvalidation paul paul-rules)
+             paul-validation)))))


Tidy up

Tidy up

--- src-cljs/kixi/hecuba/main_om.cljs
+++ src-cljs/kixi/hecuba/main_om.cljs
@@ -6,15 +6,18 @@
    [cljs.core.async :refer [<! chan put! sliding-buffer]]
    [ajax.core :refer (GET POST)]))

+;; Deprecated, just left in to show how to pass through a core.async
+;; channel and when to put stuff on it - from Om counters example
 (defn menuitem [data owner ch]
   (om/component
       (dom/li nil
-           (dom/a #js {:onClick (fn [e]
-                                  ;;(.log js/console "Name is :- " (:name (om/read data om/value)))
-                                  ;;(.log js/console "Path is :- " (.-path data))
-                                  (put! ch (:name (om/read data om/value))))}
+           (dom/a
+                #js {:onClick
+                     (fn [_] (put! ch (:name (om/read data om/value))))}
                 (:label data)))))

+;; Deprecated, just let in to show how and when to run a go block in a
+;; component, and how to pass in the channel into sub-components
 (defn menu [app owner]
   (let [in (chan (sliding-buffer 1))]
     (reify
@@ -65,9 +68,7 @@
                {:name "documentation" :label "Documentation"}
                {:name "api_users" :label "API users"}]})

-(def projects (atom {:projects [{:name "Ealing Heating" :leaders "Donnie"}
-                                {:name "Bow Housing" :leaders "Paul"}
-                                {:name "Archway Insulation" :leaders "Dave"}]}))
+(def projects (atom {:projects []}))

 ;; Attach projects to a table component at hecuba-projects
 (om/root projects table (.getElementById js/document "hecuba-projects"))


Added some code comments about changes I'd like to make and updated the way the date-time generator is used.

--- src/cmr/umm/test/generators/collection/temporal.clj
+++ src/cmr/umm/test/generators/collection/temporal.clj
@@ -2,49 +2,55 @@
   "Provides clojure.test.check generators for use in testing other projects."
   (:require [clojure.test.check.generators :as gen]
             [clj-time.core :as t]
-            [cmr.common.test.test-check-ext :as ext-gen :refer [optional]]
+            [cmr.common.test.test-check-ext :as ext-gen]
             [cmr.umm.collection :as c]
             [cmr.umm.temporal-coverage :as tc]))

 ;; temporal attributes
 (def time-types
-  (optional (ext-gen/string-alpha-numeric 1 80)))
+  ;; FIXME - I'd prefer optional to be used where a field is used. A field is optional. The value
+  ;; should always be generated.
+  (ext-gen/optional (ext-gen/string-alpha-numeric 1 80)))

 (def date-types
-  (optional (ext-gen/string-alpha-numeric 1 80)))
+  (ext-gen/optional (ext-gen/string-alpha-numeric 1 80)))

 (def temporal-range-types
-  (optional (ext-gen/string-alpha-numeric 1 80)))
+  (ext-gen/optional (ext-gen/string-alpha-numeric 1 80)))

 (def precision-of-seconds
-  (optional gen/s-pos-int))
+  (ext-gen/optional gen/s-pos-int))

 (def ends-at-present-flag
-  (optional gen/boolean))
+  (ext-gen/optional gen/boolean))

 (def range-date-times
-  (let [begin (first (gen/sample (ext-gen/date-time) 1))
+  ;; FIXME - We should not be using sampling inside of a generator.
+  ;; the bind function is the way to accomplish this.
+  (let [begin (first (gen/sample ext-gen/date-time 1))
         end (t/plus begin (t/days 1))]
-    (ext-gen/model-gen c/->RangeDateTime (gen/return begin) (optional (gen/return end)))))
+    (ext-gen/model-gen c/->RangeDateTime (gen/return begin) (ext-gen/optional (gen/return end)))))

 ;; periodic-date-time attributes
 (def names
   (ext-gen/string-alpha-numeric 1 30))

 (def duration-units
-  (gen/one-of [(gen/return "DAY") (gen/return "MONTH") (gen/return "YEAR")]))
+  (gen/elements ["DAY" "MONTH" "YEAR"]))
+
+;; FIXME both duration values and period-cycle-duration values aren't ideal here
+;; They only choose a valid that makes sense as a month. Their value should change based on
+;; the duration unit being used.

 (def duration-values
   (gen/choose 1 12))
-
-(def period-cycle-duration-units
-  (gen/one-of [(gen/return "DAY") (gen/return "MONTH") (gen/return "YEAR")]))

 (def period-cycle-duration-values
   (gen/choose 1 12))

 (def periodic-date-times
-  (let [begin (first (gen/sample (ext-gen/date-time) 1))
+  ;; FIXME - We should not be using sampling inside of a generator.
+  (let [begin (first (gen/sample ext-gen/date-time 1))
         end (t/plus begin (t/days 1))]
     (ext-gen/model-gen
       c/map->PeriodicDateTime
@@ -53,7 +59,7 @@
                     :end-date (gen/return end)
                     :duration-unit duration-units
                     :duration-value duration-values
-                    :period-cycle-duration-unit period-cycle-duration-units
+                    :period-cycle-duration-unit duration-units
                     :period-cycle-duration-value period-cycle-duration-values))))

 (def temporal-coverages-ranges
@@ -74,7 +80,7 @@
                   :temporal-range-type temporal-range-types
                   :precision-of-seconds precision-of-seconds
                   :ends-at-present-flag ends-at-present-flag
-                  :single-date-times (gen/vector (ext-gen/date-time) 1 3))))
+                  :single-date-times (gen/vector ext-gen/date-time 1 3))))

 (def temporal-coverages-periodics
   (ext-gen/model-gen


Remove redundant conf/load in wrap-serve.

Config is already loaded in wrap-args and loading again here means command line
options do not override config found in incise.edn.

--- src/incise/core.clj
+++ src/incise/core.clj
@@ -62,7 +62,6 @@
 (defn wrap-serve
   [main-func]
   (-> main-func
-      (wrap-pre conf/load)
       (wrap-pre conf/avow!)
       (wrap-log-exceptions :bubble false)))


core: symbol?, keyword?

core: symbol?, keyword?


CMR-2362: Removed unneeded code

CMR-2362: Removed unneeded code

--- metadata-db-app/src/migrations/028_create_global_transaction_sequence.clj
+++ metadata-db-app/src/migrations/028_create_global_transaction_sequence.clj
@@ -8,18 +8,17 @@
   []
   (println "migrations.028-create-global-transaction-sequence up...")
   (when-not (h/sequence-exists? "global_transaction_id_seq")
-    (let [table-name (h/get-all-concept-tablenames)
-          max-rev-id (reduce (fn [acc t]
-                              (let [resp (h/query (format "select max(revision_id) as max_rev_id from %s" t))
-                                    value (-> resp first :max_rev_id)]
-                                (if value
-                                  (max acc (long value))
-                                  acc)))
-                      0
-                      (h/get-all-concept-tablenames))]
-     (h/sql
-       (format "CREATE SEQUENCE METADATA_DB.global_transaction_id_seq START WITH %s INCREMENT BY 1 CACHE 400"
-               (+ 100000 max-rev-id))))))
+    (let [max-rev-id (reduce (fn [max-rev table]
+                               (let [resp (h/query (format "select max(revision_id) as max_rev_id from %s" table))
+                                     value (-> resp first :max_rev_id)]
+                                 (if value
+                                   (max max-rev (long value))
+                                   max-rev)))
+                             0
+                             (h/get-all-concept-tablenames))]
+      (h/sql
+        (format "CREATE SEQUENCE METADATA_DB.global_transaction_id_seq START WITH %s INCREMENT BY 1 CACHE 400"
+                (+ 100000 max-rev-id))))))

 (defn down
   "Migrates the database down from version 28."


make it easy to replace use of a persistant map with a java.util.HashMap - faster, smaller footprint, but requires explicit synchronisation.

--- dada-core/src/main/clojure/org/dada/core/JoinModel.clj
+++ dada-core/src/main/clojure/org/dada/core/JoinModel.clj
@@ -5,7 +5,7 @@
    [org.dada.core counted-set utils]
    )
   (:import
-   [java.util Collection LinkedHashMap Map]
+   [java.util Collection HashMap Map]
    [org.dada.core Attribute Data Getter Metadata Metadata$VersionComparator Model RemoteModel Tuple Update View]
    )
   (:gen-class
@@ -17,6 +17,45 @@
    :post-init post-init)
   )

+(do
+
+  ;; let's use persistant maps - slower, bigger footprint, lock-free
+
+  (def map-new hash-map)
+
+  (defmacro map-put [map key val]
+    `(assoc ~map ~key ~val))
+
+  (defmacro map-get [map key]
+    `(~map ~key))
+
+  (defmacro map-count [map]
+    `(count ~map))
+
+  (defmacro map-locking [lockee & body]
+    `(do ~@body))
+  )
+
+;; (do
+
+;;   ;; let's use hashmaps - faster, smaller footprint with locking
+
+;;   (defn map-new [] (HashMap.))
+
+;;   (defmacro map-put [map key val]
+;;     `(do (.put ~(with-meta map {:tag 'HashMap}) ~key ~val) ~map))
+
+;;   (defmacro map-get [map key]
+;;     `(.get ~(with-meta map {:tag 'HashMap}) ~key))
+
+;;   (defmacro map-count [map]
+;;     `(.size ~(with-meta map {:tag 'HashMap})))
+
+;;   (defmacro map-locking [lockee & body]
+;;     `(locking ~lockee ~@body))
+
+;;   )
+
 ;; these types should really be created on-the-fly to match lhs/rhs relationships
 (defrecord LHSEntry [extant version lhs rhs-refs datum]) ;; rhs-refs - resolution of lhs fks to rhs references
 (defrecord RHSEntry [rhs lhs-pks]) ;; lhs-pks - {lhs-pk : [lhs-fk-i, ...], ...}
@@ -35,7 +74,7 @@
 ;;     ))

 (defn invert-map [m]
-  (reduce (fn [r [k v]] (assoc r v (conj (r v) k))) {} m))
+  (reduce (fn [r [k v]] (map-put r v (conj (map-get r v) k))) (map-new) m))

 (defn make-notification [old-datum new-datum old-insertions old-alterations old-deletions delete]
   (trace ["make-notification" old-datum new-datum old-insertions old-alterations old-deletions delete])
@@ -57,8 +96,8 @@
    ;; instance state [atom(mutable) immutable]
    (let [lhs-metadata (.getMetadata lhs-model)
 	 views nil
-	 lhs-mutable {}
-	 rhs-mutables (apply vector (repeatedly (count (invert-map rhses)) hash-map))]
+	 lhs-mutable (map-new)
+	 rhs-mutables (apply vector (repeatedly (count (invert-map rhses)) map-new))]
      [(atom [views lhs-mutable rhs-mutables]) model-name model-metadata])])

 ;;--------------------------------------------------------------------------------
@@ -80,18 +119,18 @@
 	    (let [old-rhs-index (old-rhs-indeces-2 i)
 		  ;; remove lhs from old-rhs-pks (if necessary) - TODO - tidy up
 		  dummy (trace ["old-rhs-pk" old-rhs-pk old-rhs-index])
-		  tmp-rhs-index (if-let [^RHSEntry old-old-rhs-entry (old-rhs-index old-rhs-pk)]
+		  tmp-rhs-index (if-let [^RHSEntry old-old-rhs-entry (map-get old-rhs-index old-rhs-pk)]
 				  (let [old-lhs-pks (.lhs-pks old-old-rhs-entry)
 					new-lhs-pks (assoc old-lhs-pks j (disj (old-lhs-pks j) lhs-pk))
 					new-old-rhs-entry (RHSEntry. (.rhs old-old-rhs-entry) new-lhs-pks)
 					dummy (trace ["new-old-rhs-entry" new-old-rhs-entry])
-					tmp-rhs-index (assoc old-rhs-index old-rhs-pk new-old-rhs-entry)]
+					tmp-rhs-index (map-put old-rhs-index old-rhs-pk new-old-rhs-entry)]
 				    tmp-rhs-index)
 				  old-rhs-index)
 		  ;; add lhs to new-rhs-pks
 		  [rhs new-rhs-index] (if delete ;we have already deleted rhs backptrs - do no more
 					[nil tmp-rhs-index]
-					(let [^RHSEntry old-new-rhs-entry (tmp-rhs-index new-rhs-pk)
+					(let [^RHSEntry old-new-rhs-entry (map-get tmp-rhs-index new-rhs-pk)
 					    [rhs old-lhs-pks] (if old-new-rhs-entry
 								[(.rhs old-new-rhs-entry) (.lhs-pks old-new-rhs-entry)]
 								[nil
@@ -100,7 +139,7 @@
 					    new-lhs-pks (assoc old-lhs-pks j (conj (old-lhs-pks j) lhs-pk))
 					    new-new-rhs-entry (RHSEntry. rhs new-lhs-pks)
 					    dummy (trace ["new-new-rhs-entry" new-new-rhs-entry])
-					    new-rhs-index (assoc tmp-rhs-index new-rhs-pk new-new-rhs-entry)]
+					    new-rhs-index (map-put tmp-rhs-index new-rhs-pk new-new-rhs-entry)]
 					[rhs new-rhs-index]))
 		  ;; update rhs-indeces
 		  new-rhs-indeces (assoc old-rhs-indeces-2 i new-rhs-index)
@@ -121,7 +160,7 @@
      (let [new-lhs (.getNewValue update)
 	   latest-lhs (or new-lhs (.getOldValue update))
 	   lhs-pk (.get lhs-pk-getter latest-lhs)
-	   ^LHSEntry crt-lhs-entry (old-lhs-index lhs-pk)
+	   ^LHSEntry crt-lhs-entry (map-get old-lhs-index lhs-pk)
 	   [crt-lhs-entry-version crt-lhs-entry-extant crt-lhs-entry-rhs-refs crt-lhs]
 	   (if crt-lhs-entry
 	     [(.version crt-lhs-entry)(.extant crt-lhs-entry)(.rhs-refs crt-lhs-entry)(.lhs crt-lhs-entry)]
@@ -137,7 +176,7 @@
 	       new-datum (if delete crt-entry-datum (join-fn lhs-pk new-lhs-version new-lhs new-rhs-refs))
 	       dummy (trace [new-datum crt-lhs-entry])
 	       new-lhs-entry (LHSEntry. (not delete) new-lhs-version (if delete (or new-lhs crt-lhs) new-lhs) new-rhs-refs new-datum)
-	       new-lhs-index (assoc old-lhs-index lhs-pk new-lhs-entry)
+	       new-lhs-index (map-put old-lhs-index lhs-pk new-lhs-entry)
 	       [new-insertions new-alterations new-deletions] (make-notification (if crt-lhs-entry-extant crt-entry-datum nil) new-datum old-insertions old-alterations old-deletions delete)]
 	   (trace ["update-lhs - insertion/alteration - accepted" crt-lhs new-lhs])
 	   [new-lhs-index new-rhs-indeces new-insertions new-alterations new-deletions]
@@ -176,7 +215,7 @@
    (fn [[old-lhs-index old-insertions old-alterations old-deletions] [j lhs-pks]]
      (reduce
       (fn [[old-lhs-index old-insertions old-alterations old-deletions] lhs-pk]
-	(let [^LHSEntry old-lhs-entry (old-lhs-index lhs-pk)
+	(let [^LHSEntry old-lhs-entry (map-get old-lhs-index lhs-pk)
 	      old-lhs-rhs-refs (.rhs-refs old-lhs-entry)
 	      new-lhs-rhs-refs (assoc old-lhs-rhs-refs i (assoc (old-lhs-rhs-refs i) j new-rhs))
 	      new-lhs-version (inc (.version old-lhs-entry))
@@ -184,7 +223,7 @@
 	      old-datum (if old-lhs-entry (.datum old-lhs-entry))
 	      new-datum (join-fn lhs-pk new-lhs-version lhs new-lhs-rhs-refs)
 	      [new-insertions new-alterations new-deletions] (make-notification old-datum new-datum old-insertions old-alterations old-deletions false) ;TODO
-	      new-lhs-index (assoc old-lhs-index lhs-pk (LHSEntry. (.extant old-lhs-entry) new-lhs-version lhs new-lhs-rhs-refs new-datum))]
+	      new-lhs-index (map-put old-lhs-index lhs-pk (LHSEntry. (.extant old-lhs-entry) new-lhs-version lhs new-lhs-rhs-refs new-datum))]
 	  [new-lhs-index new-insertions new-alterations new-deletions]))
       [old-lhs-index old-insertions old-alterations old-deletions]
       lhs-pks))
@@ -204,11 +243,11 @@
 	   (fn [[old-lhs-index old-rhs-index old-insertions old-alterations old-deletions] ^Update update]
 	     (let [new-rhs (.getNewValue update)
 		   rhs-pk (.get rhs-pk-getter new-rhs)]
-	       (if-let [^RHSEntry old-rhs-entry (old-rhs-index rhs-pk)]
+	       (if-let [^RHSEntry old-rhs-entry (map-get old-rhs-index rhs-pk)]
 		 (let [old-rhs (.rhs old-rhs-entry)]
 		   (if (or (nil? old-rhs) (< (.compareTo rhs-version-comparator old-rhs new-rhs) 0))
 		     (let [new-rhs-entry (RHSEntry. new-rhs (if old-rhs-entry (.lhs-pks old-rhs-entry) initial-lhs-pks))
-			   new-rhs-index (assoc old-rhs-index rhs-pk new-rhs-entry)
+			   new-rhs-index (map-put old-rhs-index rhs-pk new-rhs-entry)
 			   [new-lhs-index new-insertions new-alterations-new-deletions]
 			   (update-rhs-lhs-index old-lhs-index (.lhs-pks old-rhs-entry) i new-rhs join-fn old-insertions old-alterations old-deletions)]
 		       (trace ["update-rhs - alteration - accepted" old-rhs new-rhs])
@@ -217,7 +256,7 @@
 		       (trace ["update-rhs - alteration - rejected" old-rhs new-rhs])
 		       [old-lhs-index old-rhs-index old-insertions old-alterations old-deletions])))
 		 (let [new-rhs-entry (RHSEntry. new-rhs initial-lhs-pks)
-		       new-rhs-index (assoc old-rhs-index rhs-pk new-rhs-entry)]
+		       new-rhs-index (map-put old-rhs-index rhs-pk new-rhs-entry)]
 		   (trace ["update-rhs - insertion" new-rhs])
 		   [old-lhs-index new-rhs-index old-insertions old-alterations old-deletions]))))
 	   [old-lhs-index old-rhs-index nil nil nil]
@@ -245,7 +284,7 @@
   (nth (.state this) 2))

 (defn -find [^org.dada.core.JoinModel this key]
-  (if-let [^LHSEntry entry ((second @(first (.state this))) key)]
+  (if-let [^LHSEntry entry (map-get (second @(first (.state this))) key)]
     (if (.extant entry)
       (.datum entry))))

@@ -253,29 +292,35 @@
 ;; TODO - how can we better share this code with SimpleModelView ?

 (defn ^Data -attach [^org.dada.core.JoinModel this ^View view]
-  (let [[mutable] (.state this)]
-    (let [[views lhs] (swap! mutable (fn [m view] (assoc m 0 (counted-set-inc (m 0) view))) view)]
-      (debug ["ATTACH VIEW: " view views])
-      (extract-data lhs))))
+  (map-locking
+   this
+   (let [[mutable] (.state this)]
+     (let [[views lhs] (swap! mutable (fn [m view] (assoc m 0 (counted-set-inc (m 0) view))) view)]
+       (debug ["ATTACH VIEW: " view views])
+       (extract-data lhs)))))

 (defn ^Data -detach [^org.dada.core.JoinModel this ^View view]
-  (let [[mutable] (.state this)]
-    (let [[views lhs] (swap! mutable (fn [m view] (assoc m 0 (counted-set-dec (m 0) view))) view)]
-      (debug ["DETACH VIEW: " view views])
-      (extract-data lhs))))
+  (map-locking
+   this
+   (let [[mutable] (.state this)]
+     (let [[views lhs] (swap! mutable (fn [m view] (assoc m 0 (counted-set-dec (m 0) view))) view)]
+       (debug ["DETACH VIEW: " view views])
+       (extract-data lhs)))))

 (defn notifyUpdate [^org.dada.core.JoinModel this insertions alterations deletions]
-  (let [[mutable] (.state this)
-	[views] @mutable]
-    (trace ["NOTIFY ->" @mutable])
-    (if (and (empty? insertions) (empty? alterations) (empty? deletions))
-      (warn "empty event raised" (.getStackTrace (Exception.)))
-      (dorun (map (fn [^View view]	;dirty - side-effects
-		      (try (.update view insertions alterations deletions)
-			   (catch Throwable t
-				  (error "View notification failure" t)
-				  (.printStackTrace t))))
-		  (counted-set-vals views))))))
+  (map-locking
+   this
+   (let [[mutable] (.state this)
+	 [views] @mutable]
+     (trace ["NOTIFY ->" @mutable])
+     (if (and (empty? insertions) (empty? alterations) (empty? deletions))
+       (warn "empty event raised" (.getStackTrace (Exception.)))
+       (dorun (map (fn [^View view]	;dirty - side-effects
+		       (try (.update view insertions alterations deletions)
+			    (catch Throwable t
+				   (error "View notification failure" t)
+				   (.printStackTrace t))))
+		   (counted-set-vals views)))))))

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

@@ -285,65 +330,69 @@
 ;;------------------------------------------------------------------------------

 (defn ^{:private true} -writeReplace [^org.dada.core.JoinModel this]
-  (let [[_mutable name metadata] (.state this)]
-      (RemoteModel. name metadata)))
+  (map-locking
+   this
+   (let [[_mutable name metadata] (.state this)]
+     (RemoteModel. name metadata))))

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

 (defn -post-init [^org.dada.core.JoinModel self ^String model-name _ ^Model lhs-model rhses join-fn]
-  (let [[mutable immutable] (.state self)
-	rhs-model-to-lhs-fks (invert-map rhses)
-	lhs-metadata (.getMetadata lhs-model)
-	get-lhs-getter (fn [key] (.getGetter (.getAttribute lhs-metadata key)))
-	i-to-rhs-model-and-lhs-getters (into
-					(sorted-map)
-					(map
-					 (fn [i [^Model model keys]]
-                                           [i [model (map get-lhs-getter keys)]])
-					 (range)
-					 rhs-model-to-lhs-fks))
-	i-to-lhs-getters (into (sorted-map) (map (fn [[i [model getters]]] [i getters]) i-to-rhs-model-and-lhs-getters))]
+  (map-locking
+   self
+   (let [[mutable immutable] (.state self)
+	 rhs-model-to-lhs-fks (invert-map rhses)
+	 lhs-metadata (.getMetadata lhs-model)
+	 get-lhs-getter (fn [key] (.getGetter (.getAttribute lhs-metadata key)))
+	 i-to-rhs-model-and-lhs-getters (into
+					 (sorted-map)
+					 (map
+					  (fn [i [^Model model keys]]
+					      [i [model (map get-lhs-getter keys)]])
+					  (range)
+					  rhs-model-to-lhs-fks))
+	 i-to-lhs-getters (into (sorted-map) (map (fn [[i [model getters]]] [i getters]) i-to-rhs-model-and-lhs-getters))]

-    (dorun
-     (map
-      (fn [[i [^Model rhs-model lhs-getters]]]
-        (trace ["post-init: watching rhs:" i rhs-model])
-        (let [^Metadata rhs-metadata (.getMetadata rhs-model)
-              rhs-pk-getter (.getPrimaryGetter rhs-metadata)
-              rhs-version-comparator (.getVersionComparator rhs-metadata)
-              ^Data data
-              (.attach
-               rhs-model
-               (proxy [View] []
-                 (update [insertions alterations deletions]
-                   (let [[_ _ _ insertions alterations deletions]
-                         (swap! mutable update-rhs insertions alterations deletions i rhs-pk-getter rhs-version-comparator lhs-getters join-fn)]
-                     (if (or insertions alterations deletions)
-                       (notifyUpdate self insertions alterations deletions))))
-                 (toString [] (print-object this (str "Proxy:" model-name)))))]
-          (swap! mutable update-rhs
-                 (map (fn [extant] (Update. nil extant))(.getExtant data))
-                 nil nil i rhs-pk-getter rhs-version-comparator lhs-getters join-fn)))
-      i-to-rhs-model-and-lhs-getters))
-
-    (trace ["post-init: watching lhs:" lhs-model])
-    (let [initial-rhs-refs (apply vector (map (fn [[k vs]] (apply vector (map (fn [v] nil) vs))) rhs-model-to-lhs-fks))
-	  ^Metadata lhs-metadata (.getMetadata lhs-model)
-	  lhs-pk-getter (.getPrimaryGetter lhs-metadata)
-	  lhs-version-comparator (.getVersionComparator lhs-metadata)
-	  ^Data data
-	  (.attach
-	   lhs-model
-	   (proxy [View] []
-             (update [insertions alterations deletions]
-               (let [[_ _ _ insertions alterations deletions]
-                     (swap! mutable update-lhs insertions alterations deletions lhs-pk-getter lhs-version-comparator i-to-lhs-getters join-fn initial-rhs-refs)]
-                 (if (or insertions alterations deletions)
-                   (notifyUpdate self insertions alterations deletions))))))]
-      (swap! mutable update-lhs
-	     (map (fn [extant] (Update. nil extant))(.getExtant data))
-	     nil nil lhs-pk-getter lhs-version-comparator i-to-lhs-getters join-fn initial-rhs-refs) ;; TODO - deletions/extinct
-      )))
+     (dorun
+      (map
+       (fn [[i [^Model rhs-model lhs-getters]]]
+	   (trace ["post-init: watching rhs:" i rhs-model])
+	   (let [^Metadata rhs-metadata (.getMetadata rhs-model)
+		 rhs-pk-getter (.getPrimaryGetter rhs-metadata)
+		 rhs-version-comparator (.getVersionComparator rhs-metadata)
+		 ^Data data
+		 (.attach
+		  rhs-model
+		  (proxy [View] []
+			 (update [insertions alterations deletions]
+				 (let [[_ _ _ insertions alterations deletions]
+				       (swap! mutable update-rhs insertions alterations deletions i rhs-pk-getter rhs-version-comparator lhs-getters join-fn)]
+				   (if (or insertions alterations deletions)
+				     (notifyUpdate self insertions alterations deletions))))
+			 (toString [] (print-object this (str "Proxy:" model-name)))))]
+	     (swap! mutable update-rhs
+		    (map (fn [extant] (Update. nil extant))(.getExtant data))
+		    nil nil i rhs-pk-getter rhs-version-comparator lhs-getters join-fn)))
+       i-to-rhs-model-and-lhs-getters))
+
+     (trace ["post-init: watching lhs:" lhs-model])
+     (let [initial-rhs-refs (apply vector (map (fn [[k vs]] (apply vector (map (fn [v] nil) vs))) rhs-model-to-lhs-fks))
+	   ^Metadata lhs-metadata (.getMetadata lhs-model)
+	   lhs-pk-getter (.getPrimaryGetter lhs-metadata)
+	   lhs-version-comparator (.getVersionComparator lhs-metadata)
+	   ^Data data
+	   (.attach
+	    lhs-model
+	    (proxy [View] []
+		   (update [insertions alterations deletions]
+			   (let [[_ _ _ insertions alterations deletions]
+				 (swap! mutable update-lhs insertions alterations deletions lhs-pk-getter lhs-version-comparator i-to-lhs-getters join-fn initial-rhs-refs)]
+			     (if (or insertions alterations deletions)
+			       (notifyUpdate self insertions alterations deletions))))))]
+       (swap! mutable update-lhs
+	      (map (fn [extant] (Update. nil extant))(.getExtant data))
+	      nil nil lhs-pk-getter lhs-version-comparator i-to-lhs-getters join-fn initial-rhs-refs) ;; TODO - deletions/extinct
+       ))))

 (defn ^String -toString [^org.dada.core.JoinModel this]
   (let [[_ name] (.state this)]


load_all.clj: added jobs.web.crawl

load_all.clj: added jobs.web.crawl

--- src/org/altlaw/load_all.clj
+++ src/org/altlaw/load_all.clj
@@ -1,6 +1,7 @@
 (ns org.altlaw.load-all
   (:require
    ;; org.altlaw.jobs.pre.altcrawl
+   org.altlaw.jobs.web.crawl
    org.altlaw.jobs.pre.ohm1
    org.altlaw.jobs.pre.profed
    org.altlaw.jobs.analyze.graph


Use the dot form to create Java class instances.


[#11163] No margin between "Block this user" button and main tabs panel on user profile view on iOS

--- src/status_im/ui/screens/profile/contact/styles.cljs
+++ src/status_im/ui/screens/profile/contact/styles.cljs
@@ -2,12 +2,13 @@
   (:require [status-im.ui.components.colors :as colors]))

 (def block-action-label
-  {:color colors/red
-   :padding-top      26
-   :margin-left      16})
+  {:color         colors/red
+   :margin-top    26
+   :margin-bottom 50
+   :margin-left   16})

 (def contact-profile-details-container
-  {:padding-top      26})
+  {:padding-top 26})

 (def contact-profile-detail-share-icon
   {:color colors/gray-transparent-40})


Fix reset password form

Fix reset password form

Without explicitly specifying the format as json,
the default will use transit. The backend, however,
is expecting json.

--- src-cljs/rmfu_ui/core.cljs
+++ src-cljs/rmfu_ui/core.cljs
@@ -30,6 +30,7 @@
 (defn request-password-reset [profile]
   (POST "/send-reset-password-email"
         {:params        {:email (:email profile)}
+         :format        :json
          :error-handler #(js/alert %)
          :handler       (fn [res]
                           (do


refining

refining

--- exercism/clojure/beer-song/src/beer_song.clj
+++ exercism/clojure/beer-song/src/beer_song.clj
@@ -1,34 +1,32 @@
 (ns beer-song
   (:require [clojure.string :refer [join capitalize]]))

-(defn- a [n]
-  (cond
-    (zero? n) "no more"
-    (= -1 n) "99"
-    :else (str n)))
+(defn- amount [n]
+  (condp = n
+    0 "no more"
+    -1 "99"
+    (str n)))

-(defn- b [n]
-  (if (= n 1)
-    "bottle"
-    "bottles"))
+(defn- pluralize [n]
+  (if (not= n 1) "s" ""))

-(defn- c [n]
+(defn- continue [n]
   (if (zero? n)
     "Go to the store and buy some more"
-    (str "Take " (if (= n 1) "it" "one") " down and pass it around")))
+    (str "Take" (if (= n 1) " it " " one ") "down and pass it around")))

 (defn verse [n]
   (format
     (str
-      "%s %s of beer on the wall, %s %s of beer.\n"
-      "%s, %s %s of beer on the wall.\n")
-    (capitalize (a n))
-    (b n)
-    (a n)
-    (b n)
-    (c n)
-    (a (dec n))
-    (b (dec n))))
+      "%s bottle%s of beer on the wall, %s bottle%s of beer.\n"
+      "%s, %s bottle%s of beer on the wall.\n")
+    (capitalize (amount n))
+    (pluralize n)
+    (amount n)
+    (pluralize n)
+    (continue n)
+    (amount (dec n))
+    (pluralize (dec n))))

 (defn sing


Une proposition de solution pour "Beer Song" de Exercism dans la track Clojure.

--- exercism/clojure/beer-song/src/beer_song.clj
+++ exercism/clojure/beer-song/src/beer_song.clj
@@ -1,11 +1,26 @@
-(ns beer-song)
+(ns beer-song
+  (:require [clojure.string :as str]))
+
+(defn bottle-or-bottles [num]
+  (if (> num 1)
+    (str num " bottles")
+    (str num " bottle")))

 (defn verse
   "Returns the nth verse of the song."
-  [num])
+  [num]
+  (cond
+    (and (<= num 99) (>= num 2)) (str (bottle-or-bottles num) " of beer on the wall, " (bottle-or-bottles num) " of beer.\nTake one down and pass it around, " (bottle-or-bottles (dec num)) " of beer on the wall.\n")
+    (= num 1) (str (bottle-or-bottles num) " of beer on the wall, " (bottle-or-bottles num) " of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n")
+    (= num 0) "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"))

 (defn sing
   "Given a start and an optional end, returns all verses in this interval. If
   end is not given, the whole song from start is sung."
-  ([start])
-  ([start end]))
+  ([start] (sing start 0))
+  ([start end]
+   (->>
+    (range end (inc start))
+    (reverse)
+    (map #(verse %1))
+    (str/join "\n"))))


Use fileset-diff to only write client code when cljs.edn changes

--- src/adzerk/boot_reload.clj
+++ src/adzerk/boot_reload.clj
@@ -68,12 +68,12 @@
         pr-str
         ((partial spit out-file))))))

-(defn relevant-cljs-edn [fileset ids]
+(defn relevant-cljs-edn [prev fileset ids]
   (let [relevant  (map #(str % ".cljs.edn") ids)
         f         (if ids
                     #(b/by-name relevant %)
                     #(b/by-ext [".cljs.edn"] %))]
-    (-> fileset b/input-files f)))
+    (-> (b/fileset-diff prev fileset) b/input-files f)))

 (deftask reload
   "Live reload of page resources in browser via websocket.
@@ -100,6 +100,7 @@
   (let [pod  (make-pod)
         src  (tmp-dir!)
         tmp  (tmp-dir!)
+        prev-pre (atom nil)
         prev (atom nil)
         out  (doto (io/file src "adzerk" "boot_reload.cljs") io/make-parents)
         url  (start-server @pod {:ip ip :port port :ws-host ws-host :secure? secure
@@ -108,11 +109,12 @@
     (write-cljs! out url on-jsload)
     (fn [next-task]
       (fn [fileset]
-        (doseq [f (relevant-cljs-edn fileset ids)]
+        (doseq [f (relevant-cljs-edn @prev-pre fileset ids)]
           (let [path     (tmp-path f)
                 in-file  (tmp-file f)
                 out-file (io/file tmp path)]
             (add-init! in-file out-file)))
+        (reset! prev-pre fileset)
         (let [fileset (-> fileset (add-resource tmp) commit!)
               fileset (try
                         (next-task fileset)
@@ -121,6 +123,6 @@
                                                                 (ex-data e))})
                           (throw e)))]
           (send-changed! @pod asset-path (changed @prev fileset))
-          (doseq [f (relevant-cljs-edn fileset ids)]
+          (doseq [f (relevant-cljs-edn nil fileset ids)]
             (send-visual! @pod (:adzerk.boot-cljs/messages f)))
           (reset! prev fileset))))))


Fix documentation format.

Fix documentation format.

--- src/afterglow/channels.clj
+++ src/afterglow/channels.clj
@@ -310,6 +310,7 @@
   the offset of the channel containing the most-significant byte in
   `offset`, and specify the offset of the channel containing the
   least-significant byte with `:fine-offset`."
+  {:doc/format :markdown}
   [offset & {:keys [inverted-from fine-offset]}]
   (merge (fine-channel :dimmer offset :fine-offset fine-offset :range-label "Intensity")
          (when inverted-from


Update sample show for Neural Kinetics stage.


Add saturation parameter to rainbow cues.

Gives a nice opportunity to demo the NextFrame afterglow-max object.

--- src/afterglow/examples.clj
+++ src/afterglow/examples.clj
@@ -340,18 +340,24 @@

     (ct/set-cue! (:cue-grid *show*) 0 1
                  (cues/cue :color (fn [_] (global-color-effect
-                                           (params/build-color-param :s 100 :l 50 :h hue-bar)))
-                           :short-name "Rainbow Bar Fade"))
+                                           (params/build-color-param :s :rainbow-saturation :l 50 :h hue-bar)))
+                           :short-name "Rainbow Bar Fade"
+                           :variables [{:key :rainbow-saturation :name "Saturatn" :min 0 :max 100 :start 100
+                                         :type :integer}]))
     (ct/set-cue! (:cue-grid *show*) 1 1
                  (cues/cue :color (fn [_] (global-color-effect
-                                           (params/build-color-param :s 100 :l 50 :h hue-gradient)
+                                           (params/build-color-param :s :rainbow-saturation :l 50 :h hue-gradient)
                                            :include-color-wheels? true))
-                           :short-name "Rainbow Grid"))
+                           :short-name "Rainbow Grid"
+                           :variables [{:key :rainbow-saturation :name "Saturatn" :min 0 :max 100 :start 100
+                                         :type :integer}]))
     (ct/set-cue! (:cue-grid *show*) 2 1
                  (cues/cue :color (fn [_] (global-color-effect
-                                           (params/build-color-param :s 100 :l 50 :h hue-gradient
+                                           (params/build-color-param :s :rainbow-saturation :l 50 :h hue-gradient
                                                                      :adjust-hue hue-bar)))
-                           :short-name "Rainbow Grid+Bar"))
+                           :short-name "Rainbow Grid+Bar"
+                           :variables [{:key :rainbow-saturation :name "Saturatn" :min 0 :max 100 :start 100
+                                         :type :integer}]))

     (ct/set-cue! (:cue-grid *show*) 4 1
                  (cues/cue :color (fn [_] (global-color-effect


useful protocol

useful protocol

--- src/text_stream/handler.clj
+++ src/text_stream/handler.clj
@@ -8,10 +8,10 @@
             [manifold.bus :as bus]
             [clojure.core.async :as async]))

-(def invalid-websocket-response
+(def invalid-response
   {:status 400
    :headers {"Content-Type" "text/plain"}
-   :body "
400
 Expected websocket request."})
+   :body "
400
 This isn't what I wanted!"})

 ;;; The following is *very bad* *placeholder* code, to be replaced with an
 ;;; actual database ASAP.
@@ -40,22 +40,26 @@
                         (fn [_] nil))]
               (if-not conn
                 ;; You didn't connect over ws://
-                invalid-websocket-response
+                invalid-response

-                (let [s (find-stream stream-id)]
-                  ;; Send existing nonsense
-                  (s/put! conn
-                          (str "insert:"
-                               (:text s)))
+                (d/let-flow [ready (s/take! conn)]
+                            (if (= ready "go")
+                              ;; First message must be "go"
+                              (let [s (find-stream stream-id)]
+                                ;; Send existing nonsense
+                                (s/put! conn
+                                        (str "insert:"
+                                             (:text s)))

-                  (s/put! conn
-                          (str "cursor:"
-                               (:pos s)))
+                                (s/put! conn
+                                        (str "cursor:"
+                                             (:pos s)))

-                  ;; Feed messages to clients
-                  (s/connect
-                   (bus/subscribe streamrooms stream-id)
-                   conn)))))
+                                ;; Feed messages to clients
+                                (s/connect
+                                 (bus/subscribe streamrooms stream-id)
+                                 conn))
+                              invalid-response)))))

 (defn new-stream-handler [request]
   (d/let-flow [conn (d/catch
@@ -63,7 +67,7 @@
                         (fn [_] nil))]
               (if-not conn
                 ;; You didn't connect over ws://
-                invalid-websocket-response
+                invalid-response

                 ;; First message should be of the form "inited:<INITIAL TEXT>"
                 (d/let-flow
@@ -90,8 +94,8 @@
                   (let [sid (Integer/parseInt stream-id)]
                     (if (find-stream sid)
                       (read-stream-handler sid request)
-                      invalid-websocket-response))
-                  (catch NumberFormatException _ invalid-websocket-response)))
+                      invalid-response))
+                  (catch NumberFormatException _ invalid-response)))
            (GET "/new" req (new-stream-handler req)))
   (GET "/" [] "Home sweet home")
   (route/not-found "Not Found"))


쿼리 수정.

쿼리 수정.

--- src/tweetbook/models/db.clj
+++ src/tweetbook/models/db.clj
@@ -17,5 +17,6 @@
         rnd (rand-int cnt)
         {:keys [msg src]} (first (mq/with-collection db "quotes"
                                    (mq/skip rnd)
+                                   (mq/limit 1)
                                    (mq/snapshot)))]
     (str msg "\n" src)))


adding gensym to the symbol specification generates for deftest.

this means that we wont get any more silly compile warnings
if the name of your test turns into a symbol that has already
been declared elsewhere.
eg:
```
(def diff ...)
(specification "diff" ...)
```
wont break anymore!

--- src/untangled_spec/core.clj
+++ src/untangled_spec/core.clj
@@ -31,7 +31,7 @@
   (let [var-name-from-string (fn [s] (symbol (s/lower-case (s/replace s #"[()~'\"`!@#$;%^&. ]" "-"))))
         name (var-name-from-string description)
         prefix (if-cljs &env "cljs.test" "clojure.test")]
-    `(~(symbol prefix "deftest") ~name
+    `(~(symbol prefix "deftest") ~(symbol (str name (gensym)))
                (~(symbol prefix "do-report")
                          {:type :begin-specification :string ~description})
                ~@body


updated palana foods to the new NRDB name

--- src/clj/game/cards-identities.clj
+++ src/clj/game/cards-identities.clj
@@ -337,7 +337,7 @@
                               :effect (effect (mill :corp))
                               :req (req (has-subtype? target "Virus"))}}}

-   "Pālanā Foods"
+   "Pālanā Foods: Sustainable Growth"
    {:events {:runner-draw {:msg "gain 1 [Credits]"
                            :once :per-turn
                            :effect (effect (gain [:credit 1]))}}}


Update mappings to 5.x keyword/text

Update mappings to 5.x keyword/text

--- src/clj/runbld/schema/mapping.clj
+++ src/clj/runbld/schema/mapping.clj
@@ -71,11 +71,10 @@
      (def ~(symbol (str name "Mapping")) (mapping-walk ~form))))

 (def not-analyzed
-  {:type :string
-   :index :not_analyzed})
+  {:type :keyword})

 (def analyzed
-  {:type :string})
+  {:type :text})

 (def long
   {:type :long})
@@ -92,9 +91,9 @@
 (def multi-string
   (merge
    not-analyzed
-   {:fields {:analyzed
-             {:type :string
-              :index :analyzed}}}))
+   {:fields
+    {:analyzed
+     {:type :text}}}))

 (def classpath-analyzer
   {:classpath
@@ -102,5 +101,5 @@
     :pattern ":|;"}})

 (def classpath
-  {:type :string
+  {:type :text
    :analyzer "classpath"})


Delete bad Hayley test, Neal said so

Delete bad Hayley test, Neal said so

--- src/clj/test/cards-identities.clj
+++ src/clj/test/cards-identities.clj
@@ -192,55 +192,6 @@
     (let [eli (get-ice state :archives 0)]
       (core/rez state :corp eli)
       (is (= 5 (:current-strength (refresh eli))) "Eli 1.0 at 5 strength"))))
-
-(deftest hayley-kaplan
-  "Hayley Kaplan - Complicated install triggers at end of opponent's turn"
-  (do-game
-    (new-game
-      (default-corp)
-      (make-deck "Hayley Kaplan: Universal Scholar" [(qty "Street Peddler" 1) (qty "Daily Casts" 1) (qty "Gang Sign" 3)
-                                                     (qty "Clone Chip" 1) (qty "Multithreader" 2) (qty "Study Guide" 1)]))
-    (take-credits state :corp)
-    (starting-hand state :runner ["Street Peddler" "Daily Casts" "Clone Chip" "Multithreader" "Multithreader"
-                                  "Study Guide"])
-    (trash-from-hand state :runner "Multithreader")
-    (play-from-hand state :runner "Street Peddler")
-    (prompt-choice :runner "No")
-    (play-from-hand state :runner "Clone Chip")
-    (play-from-hand state :runner "Study Guide")
-    (take-credits state :runner)
-    (core/gain state :runner :credit 7)
-    (core/end-turn state :corp nil)
-    (is (not (:end-turn @state)) "Corp turn has not ended")
-    (card-ability state :runner (-> (get-runner) :rig :hardware first) 0)
-    (prompt-select :runner (first (:discard (get-runner))))
-    (prompt-choice :runner "Yes")
-    (prompt-select :runner (find-card "Multithreader" (:hand (get-runner))))
-    (let [sg (-> (get-runner) :rig :program first)
-          mt1 (-> (get-runner) :rig :program second)
-          mt2 (-> (get-runner) :rig :program next second)
-          sp (-> (get-runner) :rig :resource first)]
-      (is (and sp sg mt1 mt2) "Street Peddler, Study Guide and 2x Multithreaders installed")
-      (card-ability state :runner mt1 0)
-      (card-ability state :runner mt1 0)
-      (card-ability state :runner mt2 0)
-      (card-ability state :runner mt2 0)
-      (card-ability state :runner sg 1)
-      (card-ability state :runner sg 1)
-      (is (= 2 (:current-strength (refresh sg))) "Study Guide at strength 2")
-      (is (= 0 (:rec-counter (refresh mt1))) "Multithreader credits spent")
-      (prompt-choice :runner "Done")
-      (prompt-choice :corp "Done")
-      (is (:end-turn @state) "Corp turn ended")
-      (card-ability state :runner sp 0)
-      (prompt-card :runner (first (:hosted sp)))
-      (prompt-choice :runner "Yes")
-      (prompt-select :runner (find-card "Daily Casts" (:hand (get-runner))))
-      (is (find-card "Daily Casts" (:resource (:rig (get-runner)))) "Daily Casts installed by Haley")
-      (is (= 0 (:credit (get-runner))) "Runner has 0 credits before start of turn")
-      (core/start-turn state :runner nil)
-      (is (= 2 (:credit (get-runner))) "Runner has 2 credits after start of turn")
-      (is (= 2 (:rec-counter (refresh mt1))) "Multithreaders regained credits"))))

 (deftest iain-stirling-credits
   "Iain Stirling - Gain 2 credits when behind"


Seperated loader working

Seperated loader working

Need to try with resource manager and then tidy up

--- src/cljs/cloj/resources/html.cljs
+++ src/cljs/cloj/resources/html.cljs
@@ -73,12 +73,17 @@
   (reify ILoader
     (load-blob! [_ file-name]
       (let [ret-chan (chan)
+            pipe-chan (chan)
             xhr (js/XMLHttpRequest.)]
         (go
-          (put! ret-chan (-> (fn [cb] (get-blob! xhr file-name cb))
-                             (cb->chan )
-                             (<!)))
-          ret-chan)))))
+          (get-blob! xhr file-name (fn [v]
+                                     (put! pipe-chan v)))
+          (let [ret-v (<! pipe-chan)]
+            (put! ret-chan ret-v))
+          )
+          ret-chan
+        ))))
+

 ;; =============================================================================
 ;; todo


fix issue with card-view click handling

fix issue with card-view click handling

--- src/cljs/netrunner/gameboard.cljs
+++ src/cljs/netrunner/gameboard.cljs
@@ -43,18 +43,22 @@
       (.focus input))))

 (defn handle-card-click [{:keys [type zone abilities] :as card} owner]
-  (if (= zone ["hand"])
-    (case type
-      ("Upgrade" "ICE") (-> (om/get-node owner "servers") js/$ .toggle)
-      ("Agenda" "Asset") (if (empty? (get-in @game-state [:corp :servers :remote]))
-                           (send-command "play" {:card card :server "New remote"})
-                           (-> (om/get-node owner "servers") js/$ .toggle))
-      (send-command "play" {:card card}))
-    (if (or (= (:side card) "Runner") (:rezzed card))
-      (if (> (count abilities) 1)
-        (-> (om/get-node owner "abilities") js/$ .toggle)
-        (send-command "ability" {:card card :ability 0}))
-      (send-command "rez" {:card card}))))
+  (cond
+   (= zone ["hand"]) (case type
+                       ("Upgrade" "ICE") (-> (om/get-node owner "servers") js/$ .toggle)
+                       ("Agenda" "Asset") (if (empty? (get-in @game-state [:corp :servers :remote]))
+                                            (send-command "play" {:card card :server "New remote"})
+                                            (-> (om/get-node owner "servers") js/$ .toggle))
+                       (send-command "play" {:card card}))
+   (or (= (first zone) "rig")
+       (and (= (first zone) "server")
+            (:rezzed card))) ((if (> (count abilities) 1)
+                                (-> (om/get-node owner "abilities") js/$ .toggle)
+                                (send-command "ability" {:card card :ability 0})))
+   (and (= (first zone) "server")
+        (not (:rezzed card))) (send-command "rez" {:card card})))
+
+

 (defn in-play? [card]
   (let [dest (when (= (:side card) "Runner")


Une solution au problème Space Age de Exercism dans la track Clojure

--- exercism/clojure/space-age/src/space_age.clj
+++ exercism/clojure/space-age/src/space_age.clj
@@ -1,27 +1,41 @@
 (ns space-age)

 (def earth-orbital-period-in-seconds 31557600.0)
+
+(def mercury-orbital-period-in-seconds (* earth-orbital-period-in-seconds 0.2408467))
+
+(def venus-orbital-period-in-seconds (* earth-orbital-period-in-seconds 0.61519726))
+
+(def mars-orbital-period-in-seconds (* earth-orbital-period-in-seconds 1.8808158))
+
+(def jupiter-orbital-period-in-seconds (* earth-orbital-period-in-seconds 11.862615))
+
+(def saturn-orbital-period-in-seconds (* earth-orbital-period-in-seconds 29.447498))
+
+(def neptune-orbital-period-in-seconds (* earth-orbital-period-in-seconds 164.79132))
+
+(def uranus-orbital-period-in-seconds (* earth-orbital-period-in-seconds 84.016846))

 (defn on-earth [seconds]
   (/ (double seconds) earth-orbital-period-in-seconds))

 (defn on-mercury [seconds]
-  (* (on-earth seconds) 0.2408467))
+  (/ (double seconds) mercury-orbital-period-in-seconds))

 (defn on-venus [seconds]
-  seconds)
+  (/ (double seconds) venus-orbital-period-in-seconds))

 (defn on-mars [seconds]
-  seconds)
+  (/ (double seconds) mars-orbital-period-in-seconds))

 (defn on-jupiter [seconds]
-  seconds)
+  (/ (double seconds) jupiter-orbital-period-in-seconds))

 (defn on-saturn [seconds]
-  seconds)
+  (/ (double seconds) saturn-orbital-period-in-seconds))

 (defn on-neptune [seconds]
-  seconds)
+  (/ (double seconds) neptune-orbital-period-in-seconds))

 (defn on-uranus [seconds]
-  seconds)
+  (/ (double seconds) uranus-orbital-period-in-seconds))


Refactor testutils.logging/logs-matching to match on message and level.

Previously, logs-matching only filtered based on the log message and
given regex. The logged? assertion then checked to ensure there was
exactly 1 matching log line before even considering the specified
log level. This led to the assertion failing in situations where
more than one log message matched even if one of the matches was at a
different level than the one specified in the assertion.

--- test/puppetlabs/trapperkeeper/testutils/logging.clj
+++ test/puppetlabs/trapperkeeper/testutils/logging.clj
@@ -13,6 +13,8 @@
   *test-logs*
   nil)

+(def legal-levels #{nil :trace :debug :info :warn :error :fatal})
+
 (defn- log-entry->map
   [log-entry]
   {:namespace (get log-entry 0)
@@ -21,19 +23,26 @@
    :message   (get log-entry 3)})

 (defn logs-matching
-  "Given a regular expression pattern and a sequence of log messages (in the format
-  used by `clojure.tools.logging`, return only the logs whose message matches the
-  specified regular expression pattern.  (Intended to be used alongside
-  `with-log-output` for tests that are validating log output.)  The result is
-  a sequence of maps, each of which contains the following keys:
-  `:namespace`, `:level`, `:exception`, and `:message`."
-  [pattern logs]
-  {:pre  [(instance? java.util.regex.Pattern pattern)
-          (coll? logs)]}
-  ;; the logs are formatted as sequences, where the string at index 3 contains
-  ;; the actual log message.
-  (let [matches (filter #(re-find pattern (get % 3)) logs)]
-    (map log-entry->map matches)))
+  "Given a regular expression pattern, a sequence of log messages (in the format
+  used by `clojure.tools.logging`, and (optionally) a log level (as a keyword
+  that corresponds to those in `clojure.tools.logging`) return only the logs
+  whose message matches the specified regular expression pattern that were
+  logged at the given level (or at any level if not specified). (Intended to
+  be used alongside `with-log-output` for tests that are validating log
+  output.) The result is a sequence of maps, each of which contains the
+  following keys: `:namespace`, `:level`, `:exception`, and `:message`."
+  ([pattern logs] (logs-matching pattern logs nil))
+  ([pattern logs level]
+   {:pre  [(instance? java.util.regex.Pattern pattern)
+           (coll? logs)
+           (contains? legal-levels level)]}
+   ;; the logs are formatted as sequences, where the keyword at index 1
+   ;; contains the level and the string at index 3 contains the actual
+   ;; log message.
+   (let [matches-level? (fn [log-entry] (or (nil? level) (= level (get log-entry 1))))
+         matches-msg? (fn [log-entry] (re-find pattern (get log-entry 3)))
+         matches (filter #(and (matches-level? %) (matches-msg? %)) logs)]
+     (map log-entry->map matches))))

 (defn log-to-console
   "Utility function called by atom-logger and atom-appender to log entries to the
@@ -164,7 +173,6 @@
         (is (logged? #\"^hi$\" :info)))"
   (let [pattern       (nth form 1)
         level         (nth form 2 nil)
-        legal-levels  #{nil :trace :debug :info :warn :error :fatal}
         debug-msg     "; `with-test-logging-debug` may be useful for debugging tests."]
     (when-not (instance? Pattern pattern)
       (throw (IllegalArgumentException.
@@ -174,25 +182,16 @@
                (str "Optional second argument to `logged?` must be one of "
                     legal-levels "; illegal value: '" level "'"))))
     `(let [logs#    @puppetlabs.trapperkeeper.testutils.logging/*test-logs*
-           matches# (logs-matching ~pattern logs#)]
-       (cond
-         (not (= 1 (count matches#)))
+           matches# (logs-matching ~pattern logs# ~level)]
+       (if-not (= 1 (count matches#))
          (clojure.test/do-report
            {:type      :fail
             :message   ~msg
             :expected  (str "Exactly one log message matching the pattern '"
-                            ~pattern "'")
+                            ~pattern "'"
+                            (when ~level (format " at '%s' level" (name ~level))))
             :actual    (str (count matches#) " matches" ~debug-msg)})

-         (and ~level (not (= ~level (-> matches# first :level))))
-         (clojure.test/do-report
-           {:type      :fail
-            :message   ~msg
-            :expected  (str "Expected level " ~level " for log message matching pattern '"
-                            ~pattern "'")
-            :actual    (str "Actual level: " (-> matches# first :level) ~debug-msg)})
-
-         :else
          (clojure.test/do-report
            {:type      :pass
             :message   ~msg


Docstring for text-field

Docstring for text-field

--- src-cljs/frontend/components/pieces/form.cljs
+++ src-cljs/frontend/components/pieces/form.cljs
@@ -3,7 +3,18 @@
             [om.core :as om :include-macros true])
   (:require-macros [frontend.utils :refer [component html]]))

-(defn text-field [{:keys [label value validation-error disabled? on-change]} owner]
+(defn text-field
+  "A text field, with a label.
+
+  :label            - The label for the field.
+  :value            - The value of the field.
+  :on-change        - An on-change handler for the field. Receives the change
+                      event.
+  :validation-error - (optional) A validation error to display. If given, the
+                      field will appear as invalid.
+  :disabled?        - (optional) If true, the field is disabled.
+                      (default: false)"
+  [{:keys [label value on-change validation-error disabled?]} owner]
   (reify
     om/IInitState
     (init-state [_]


Fix missing name change

Fix missing name change

--- src-cljs/frontend/controllers/navigation.cljs
+++ src-cljs/frontend/controllers/navigation.cljs
@@ -14,7 +14,7 @@
             [frontend.utils.docs :as doc-utils]
             [frontend.utils.state :as state-utils]
             [frontend.utils.vcs-url :as vcs-url]
-            [frontend.utils :as utils :refer [mlog merror set-page-title! scroll-to-fragment! scroll!]]
+            [frontend.utils :as utils :refer [mlog merror set-page-title! scroll-to-id! scroll!]]
             [goog.dom]
             [goog.string :as gstring])
   (:require-macros [frontend.utils :refer [inspect]]


Don't select an organization by default on the add project page.

--- src-cljs/frontend/controllers/navigation.cljs
+++ src-cljs/frontend/controllers/navigation.cljs
@@ -209,9 +209,7 @@
     (when-not (seq (get-in current-state state/projects-path))
       (api/get-projects api-ch))
     (go (let [api-result (<! (ajax/managed-ajax :get "/api/v1/user/organizations"))]
-          (put! api-ch [:organizations (:status api-result) api-result])
-          (when-let [first-org (first (:resp api-result))]
-            (put! (get-in current-state [:comms :controls]) [:selected-add-projects-org {:login (:login first-org) :type :org}]))))
+          (put! api-ch [:organizations (:status api-result) api-result])))
     (ajax/ajax :get "/api/v1/user/collaborator-accounts" :collaborators api-ch))
   (set-page-title! "Add projects")
   (analytics/track-signup))


experiment with different timeouts

experiment with different timeouts

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -3,6 +3,7 @@
    [babel.directory :refer [models]] ;; this is needed even though there are no references to directory in here.
    [babel.generate :as g :refer [frontier generate get-lexemes]]
    [babel.english :as english :refer [model morph morph-ps]]
+   [clojure.core.async :refer [>! alts!! timeout chan go]]
    #?(:cljs [babel.logjs :as log])
    #?(:clj [clojure.tools.logging :as log])
    #?(:clj [clojure.repl :refer [doc]])
@@ -17,12 +18,18 @@
                    :subcat []
                    :sem {:aspect :simple
                          :tense :present}}}]]
-    (repeatedly #(println
-                  (let [spec (first (shuffle specs))]
-                    (morph (generate
-                            spec
-                            model)
-                           :show-notes false))))))
+    (repeatedly
+     #(println
+       (let [spec (first (shuffle specs))]
+         (morph (binding [babel.generate/println? false
+                          babel.generate/truncate? true]
+                  (generate spec model))
+                :show-notes false))))))
+
+(def ^:dynamic wait-ms-for-generation 10000)
+
+(declare wait)
+
 (defn basecamp []
   ;; TODO: improve performance by using {:mod {:first {:obj :modified}}.
   (let [specs
@@ -43,7 +50,11 @@
                                                      :rest []}}}}}}}]]
     (repeatedly #(println
                   (let [spec (first (shuffle specs))]
-                    (morph (time (generate spec model))))))))
+                    (let [result (morph (time (binding [babel.generate/truncate? true]
+                                                (wait wait-ms-for-generation (fn [] (generate spec model))))))]
+                      (or (and (not (empty? result)) result)
+                          "TIMEOUT.")))))))
+
 (defn nextcamp []
   (let [parse (-> "the small dogs you see" parse first)]
     (pprint (u/get-in parse [:synsem :sem]))))
@@ -84,3 +95,9 @@
          (->> (map #(u/assoc-in rule [:head] %)
                    (-> model :lexicon (get lexeme)))
               (remove #(= :fail %))))))
+
+;; Thanks for (defn wait) to Christian Meichsner on https://stackoverflow.com/a/30903731
+(defn wait [ms f & args]
+  (let [c (chan)]
+    (go (>! c (apply f args)))
+    (first (alts!! [c (timeout ms)]))))


Prefer to return cached block from cache-store get.

--- src/blocks/store/cache.clj
+++ src/blocks/store/cache.clj
@@ -133,8 +133,8 @@
     (ensure-initialized! this)
     (or (block/-get cache id)
         (when-let [block (block/-get primary id)]
-          (maybe-cache! this block)
-          block)))
+          (or (maybe-cache! this block)
+              block))))

   (put!


Handle a single recommendation

Handle a single recommendation

In the toc and elsewhere

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -87,15 +87,15 @@
      (when (and (map? items) (< depth to-depth))
        (keep #(toc-entry (% items) (conj path %) to-depth) (order (keys items))))]))

-(defn toc [items path to-depth & {:keys [heading? editorial? recommendation-at-end?]}]
+(defn toc [items path to-depth & {:keys [heading? editorial? recommendation-at-end? single-recommendation?]}]
   (when (map? items)
     [:fo:block {:line-height "150%"
                 :role "TOC"}
      (when heading? (heading :h1 :inhalt []))
      (let [entries (order (keys items))
            entries (cond
-                     recommendation-at-end? (concat [:editorial] entries [:recommendations])
-                     editorial? (concat [:editorial :recommendations] entries)
+                     recommendation-at-end? (concat [:editorial] entries [(if single-recommendation? :recommendation :recommendations)])
+                     editorial? (concat [:editorial (if single-recommendation? :recommendation :recommendations)] entries)
                      :else entries)]
        (keep #(toc-entry (get items %) (conj path %) to-depth) entries))]))

@@ -421,9 +421,11 @@

       (let [subitems (get items fmt)]
         [:fo:flow {:flow-name "xsl-region-body"}
-         (toc subitems [fmt] 3 :heading? true :editorial? true)
+         (toc subitems [fmt] 3 :heading? true :editorial? true :single-recommendation? true)
          (heading :h1 :editorial [fmt :editorial])
-         (heading :h1 :recommendation [fmt :recommendations])
+         (md-to-fop (slurp "/home/eglic/src/catalog/samples/editorial.md"))
+         (heading :h1 :recommendation [fmt :recommendation])
+         (md-to-fop (slurp "/home/eglic/src/catalog/samples/recommendations.md"))
          (mapcat #(genre-sexp subitems fmt % 1) (order (keys subitems)))])]]))

 (defmethod document-sexp :hörbuch


nice-angles get nicer and similarly nice-houses; in both cases checking if data is wanted

--- src/clj/ephemeris/core.clj
+++ src/clj/ephemeris/core.clj
@@ -56,9 +56,16 @@
                :Co-Asc2
                :PolarAsc]
               sub)]
-    (if (= wanted true)
-      all
-      (select-keys all wanted))))
+    (if (angles? wanted)
+      (if (= wanted true)
+        {:angles all}
+        {:angles (select-keys all wanted)})
+      {})))
+
+(defn- nice-houses [data wanted]
+  (if (houses? wanted)
+    {:houses (zipmap (range 1 13) (rest data))}
+    {}))

 (defn calc [stuff]
   (let [sw (SwissEph.)
@@ -97,9 +104,5 @@
                               cusps
                               ascmc)]
           (merge
-            (if (angles? (:angles want))
-              {:angles (nice-angles ascmc (:angles want))}
-              {})
-            (if (houses? (:houses want))
-              {:houses (zipmap (range 1 13) (rest cusps))}
-              {})))))))
+            (nice-angles ascmc (:angles want))
+            (nice-houses cusps (:houses want))))))))


Refactors net damage.

Refactors net damage.

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -202,7 +202,7 @@
                                    :effect (effect (add-prop target :advance-counter 1 {:placed true}) (end-run))}}}]}

    "Chum"
-   {:abilities [{:msg "do 3 net damage" :effect (effect (damage :net 3 {:card card}))}]}
+   {:abilities [(do-net-damage 3)]}

    "Cortex Lock"
    {:abilities [{:label "Do 1 net damage for each unused memory units the Runner has"
@@ -452,7 +452,7 @@
                  :effect (effect (handle-access targets) (trash card))}]}

    "Komainu"
-   {:abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}]}
+   {:abilities [(do-net-damage 1)]}

    "Lab Dog"
    {:abilities [(assoc trash-hardware :label "Force the Runner to trash an installed piece of hardware"
@@ -491,7 +491,7 @@
       :events {:advance ab :advancement-placed ab}})

    "Mamba"
-   {:abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}
+   {:abilities [(do-net-damage 1)
                 {:msg "do 1 net damage using 1 power counter"
                  :counter-cost 1 :effect (effect (damage :net 1 {:card card}))}
                 {:msg "start a Psi game"
@@ -551,7 +551,7 @@
    {:abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))} trash-program]}

    "Neural Katana"
-   {:abilities [{:msg "do 3 net damage" :effect (effect (damage :net 3 {:card card}))}]}
+   {:abilities [(do-net-damage 3)]}

    "News Hound"
    {:abilities [(tag-trace 3)
@@ -605,7 +605,7 @@
    {:abilities [{:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))} end-the-run]}

    "Pup"
-   {:abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}]}
+   {:abilities [(do-net-damage 1)]}

    "Quandary"
    {:abilities [end-the-run]}
@@ -722,8 +722,7 @@
     :abilities [trash-program]}

    "Swordsman"
-   {:abilities [{:msg "do 1 net damage"
-                 :effect (effect (damage :net 1 {:card card}))}
+   {:abilities [(do-net-damage 1)
                 {:prompt "Choose an AI program to trash"
                  :msg (msg "trashes " (:title target))
                  :label "Trash an AI program"
@@ -758,7 +757,8 @@
                                         (system-msg state side "loses [Click]")))}}]}

    "Tsurugi"
-   {:abilities [end-the-run {:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}]}
+   {:abilities [end-the-run
+                (do-net-damage 1)]}

    "Turing"
    {:abilities [end-the-run]
@@ -812,7 +812,8 @@
    {:abilities [end-the-run]}

    "Wall of Thorns"
-   {:abilities [end-the-run {:msg "do 2 net damage" :effect (effect (damage :net 2 {:card card}))}]}
+   {:abilities [end-the-run
+                (do-net-damage 2)]}

    "Wendigo"
    (let [ab {:req (req (= (:cid card) (:cid target)))
@@ -838,7 +839,7 @@

    "Woodcutter"
    {:advanceable :while-rezzed
-    :abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}]}
+    :abilities [(do-net-damage 1)]}

    "Wormhole"
    {:advanceable :always
@@ -857,7 +858,7 @@
               {:runner-install wr :trash wr :card-moved wr})}

    "Yagura"
-   {:abilities [{:msg "do 1 net damage" :effect (effect (damage :net 1 {:card card}))}
+   {:abilities [(do-net-damage 1)
                 {:msg "look at the top card of R&D"
                  :optional {:prompt (msg "Add " (:title (first (:deck corp))) " to bottom of R&D?")
                             :msg "add the top card of R&D to the bottom"


Adding back link to manage page

Adding back link to manage page

--- src/cljs/bmihw/submit.cljs
+++ src/cljs/bmihw/submit.cljs
@@ -43,4 +43,7 @@
             [:br]
             [:button {:id "submit" :class "control"
                       :on-click #(submit-to-fb! @state)}
-             "Submit"]]]]))+             "Submit"]]
+				   [:br]
+				   [:br]
+				   [:div [:a {:href "#/manage"} "Manage Submissions"]]]]))


Minor cosmetic fixes on core.cljs.

Minor cosmetic fixes on core.cljs.

--- src/cljs/pfrt_js/core.cljs
+++ src/cljs/pfrt_js/core.cljs
@@ -24,11 +24,11 @@
         download-speed  (:speed-in data)
         upload-speed    (:speed-out data)]
     (crate/html [:tr {:id (host->id host)}
-           [:td (:name data)]
-           [:td (js/filesize downloaded)]
-           [:td (js/filesize uploaded)]
-           [:td (str (js/filesize download-speed) "/s")]
-           [:td (str (js/filesize upload-speed) "/s")]])))
+                 [:td (:name data)]
+                 [:td (js/filesize downloaded)]
+                 [:td (js/filesize uploaded)]
+                 [:td (str (js/filesize download-speed) "/s")]
+                 [:td (str (js/filesize upload-speed) "/s")]])))

 (defn- render
   "Render all matrix."
@@ -38,7 +38,7 @@
                         (let [data (into {} (second it))]
                           (get data "in")))
         stats         (reverse
-                        (sort-by sortfn (into [] stats)))]
+                       (sort-by sortfn (into [] stats)))]
     (doseq [[host data] stats]
       (append temporal-node (render-host-element host data)))
     temporal-node))


Fix a namespace leftover.

Fix a namespace leftover.

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -9,7 +9,6 @@
             [cljs.repl :as cljs-repl]
             [cljs.pprint :refer [pprint]]
             [replumb.load :as load]
-            [replumb.doc-maps :as docs]
             [replumb.common :as common]))

 ;;;;;;;;;;;;;


true fixed

true fixed

--- src/clojure/nossal/web.clj
+++ src/clojure/nossal/web.clj
@@ -33,16 +33,16 @@
            [48 96 144 192])
       [:link {:rel "canonical" :href (core/cannonical-url req)}]
       [:link {:rel "manifest" :href (s/join ["/" (options :manifest) ".json"])}]
-      [:script {:async true :scr "//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"}]
+      [:script {:async "true" :scr "//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"}]
       [:script "(adsbygoogle = window.adsbygoogle || []).push({google_ad_client: \"ca-pub-9207695243671092\",enable_page_level_ads: true});"]
-      [:script {:async true :src "https://cdn.ampproject.org/v0.js"}]
+      [:script {:async "true" :src "https://cdn.ampproject.org/v0.js"}]
       (if-not (contains? #{"localhost" "127.0.0.1"} (:server-name req))
-        [:script {:async true :custom-element "amp-analytics" :src "https://cdn.ampproject.org/v0/amp-analytics-0.1.js"}])
+        [:script {:async "true" :custom-element "amp-analytics" :src "https://cdn.ampproject.org/v0/amp-analytics-0.1.js"}])
       [:title title]
-      [:style {:amp-custom true} (slurp (io/resource "public/css/screen.css")) css]
-      [:style {:amp-boilerplate true} (slurp (io/resource "amp-css.css"))]
+      [:style {:amp-custom "true"} (slurp (io/resource "public/css/screen.css")) css]
+      [:style {:amp-boilerplate "true"} (slurp (io/resource "amp-css.css"))]
       [:noscript
-       [:style {:amp-boilerplate true} "body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none} "]]]
+       [:style {:amp-boilerplate "true"} "body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none} "]]]
      [:body
       [:script {:type "application/ld+json"} dat/data-website]
       [:amp-analytics {:type "googleanalytics"}


tmpfile

tmpfile

--- src/co/nclk/linen/node.clj
+++ src/co/nclk/linen/node.clj
@@ -65,8 +65,9 @@
 (defn tempfile-name
   [& [local]]
   (str (when-not (false? local)
-         (System/getProperty "java.io.tmpdir"))
-       "/.linen-temp-script-"
+         (str (System/getProperty "java.io.tmpdir")
+              "/"))
+       ".linen-temp-script-"
        (java.util.UUID/randomUUID)))

 (defn invocation-string
@@ -83,9 +84,7 @@
 (defn- invoke-local
   [checkpoint & [argv]]
   (binding [*log* (not (false? (:log checkpoint)))]
-    (let [tmpfile-name (str (System/getProperty "java.io.tmpdir")
-                            "/"
-                            (tempfile-name))
+    (let [tmpfile-name (tempfile-name)
           proxy? (not (nil? argv))
           argv (or argv
                    (remove clojure.string/blank?


Permit :urls or :url in candidate entries.

Entries containing a `:urls []` value will be decomposed into multiple
individual entries.

--- src/wrongtangular/data.cljs
+++ src/wrongtangular/data.cljs
@@ -98,6 +98,26 @@
           (store-in-records! complete)
           (assoc app :direction :backward, :queue queue, :complete complete))))))

+;; Given a seq data structure loaded from candidates.json, generates a list of
+;; images to be judged. Each element of the seq must be a hash with :id and
+;; :name keys; it must also have either a :url key, whose value is a string, or
+;; a :urls key, whose value is a seq of strings.
+;;
+;; In either case, this function returns one {:id :name :url} hash per url.
+;; URLs are assumed unique; ids and names are not.
+(defn- data->queue [data]
+  (let [f (fn [coll entry]
+            (cond
+              ;; place single-url entries directly in the output
+              (contains? entry :url) (conj coll entry)
+              ;; convert multiple urls to single url entries
+              (contains? entry :urls)
+              (vec (concat coll (map #(-> entry (dissoc entry :urls) (assoc :url %))
+                                     (:urls entry))))
+              ;; return collection unchanged
+              :default coll))]
+    (into '() (reduce f [] data))))
+
 (defn- load-initial-data! []
   (go (let [data (sort-by :id (<! (util/get-json candidates-url)))]
         (if-let [[queue complete] (restore-from-records data)]
@@ -111,6 +131,4 @@
           ; load data from JSON, then set it in the app
           (om/transact! (app-cursor)
             (fn [app]
-              (assoc app
-                     :ready? true
-                     :queue (into '() data))))))))
+              (assoc app :ready? true, :queue (data->queue data))))))))


Fix add-path-segments in url builder

Fix add-path-segments in url builder

--- src/common/grafter/url.clj
+++ src/common/grafter/url.clj
@@ -92,7 +92,7 @@
     (.getFragment url))

   (add-path-segments [url segments]
-    (let [new-path (join-paths url segments)]
+    (let [new-path (build-path segments)]
       (URI. (protocol url) (.getUserInfo url) (host url) (or (port url) -1) new-path (.getQuery url) (.getFragment url))))

   (set-path-segments [url segments]
@@ -121,7 +121,7 @@
     url))

 (defn- append-to [url key values]
-  (update-in url [key] #(into % values)))
+  (update-in url [:path-segments] concat [[key values]]))

 (defn- to-uri*
   "Converts a map of URI components into a java.net.URI. The supported components are:
@@ -162,7 +162,7 @@
     (:url-fragment this))

   (add-path-segments [url segments]
-    (append-to url :path-segments segments))
+    (update-in url [:path-segments] concat segments))

   (set-path-segments [url segments]
     (assoc :path-segments segments))


#3 use goog.json.serializer

#3 use goog.json.serializer

--- src_cljs/rrms/corecljs.cljs
+++ src_cljs/rrms/corecljs.cljs
@@ -8,8 +8,8 @@
             [goog.structs :as structs]
             [cljs-time.format :as f]
             [cljs-time.core :as tt])
-  (:import goog.History)
-  )
+  (:import goog.History
+           goog.json.Serializer))

 (def documents (r/atom nil))

@@ -71,7 +71,7 @@
 (defn save [event]
   (let [onres (fn[data] (set! (.-location js/window) "http://localhost:8193"))]
     (http-post "http://localhost:8193/documents/add"
-               onres  (JSON/stringify (clj->js (get-documents-formdata))))))
+               onres  (.serialize (Serializer.) (clj->js (get-documents-formdata))))))

 (defn document-template []
   [:div {:id "add" :class "form-group"}
@@ -103,7 +103,7 @@
   (let [onres (fn[data]
                 (.assign js/location "/"))]
     (http-post "http://localhost:8193/documents/update"
-               onres (JSON/stringify (clj->js (get-update-documents-formdata))))))
+               onres (.serialize (Serializer.) (clj->js (get-update-documents-formdata))))))

 (defn document-update-template [id dmt]


Extract fn for introducting parts over time.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -77,12 +77,16 @@
         g (comp (split 0 1/10) f)]
     (part model a b c d e f g)))

+(defn introduce-after [t parts]
+  (->> parts
+       (map after (range 0 (* (count parts) t) t))))
+
 (def aga-terumo ; p299
   (let [drums [first-drum second-drum third-drum]]
     (->> drums
          ;(map (comp list first))
          (map rand-variations)
-         (map after (range 0 (* 4 3) 4))
+         (introduce-after 4)
          (reduce with))))

 (comment
@@ -189,7 +193,7 @@
         (big (big (big tete))) (big (big (big ta))) (big (big (big ha)))]
        ;(map (comp list first))
        (map rand-variations)
-       (map after (range 0 (* 4 18) 4))
+       (introduce-after 4)
        (reduce with)
        (map pan)))


Only display statistics when they exist

Only display statistics when they exist

--- src/cljs/elevent_client/pages/statistics.cljs
+++ src/cljs/elevent_client/pages/statistics.cljs
@@ -109,14 +109,23 @@
               :yAxis {:title {:text "Number checked in"}}
               :series [{:name "Checked in"}]}
              check-in-data])
-          (when (and (seq activities) (seq schedules))
+          ; Check if there is any data to display
+          (when (reduce #(or %1 %2)
+                        (map
+                          (fn [[activity-name attendance-count]]
+                            (> attendance-count 0))
+                          schedules))
             [chart/component
              {:chart {:type "bar"}
               :title {:text "Activity attendance"}
-              ;:xAxis {:categories (map first schedules)}
               :yAxis {:title {:text "Number of attendees"}
+                      :min 0
+                      :minRange 1
                       :allowDecimals false}
               :series [{:name "Attendee count"}]}
-             schedules])]]))))
+             schedules])
+          (when (and (> @event-id 0)
+                     (not (seq all-attendees)))
+            [:p "There is no data for this event."])]]))))

 (routes/register-page routes/statistics-chan #'page true)


mostly working score - refactoring ahead

--- src/cljs/foosball/locations/report_match.cljs
+++ src/cljs/foosball/locations/report_match.cljs
@@ -62,10 +62,8 @@
           valid-range             (set (cond
                                         (= other 11)  losing-to-eleven-scores
                                         (= other 10)  losing-to-ten-scores
-                                        :else         winning-scores))
-          result (contains? valid-range this)
-          _ (debug "valid?" this other valid-range :contains result)]
-      result)))
+                                        :else         winning-scores))]
+      (valid-range this))))

 (def nil=zero-valid-score? (fnil valid-score? 0 0))

@@ -74,20 +72,15 @@
         team-score       (get-in report-match [team-path :score])
         other-score      (get-in report-match [other-team-path :score])
         invalid-score-fn (complement nil=zero-valid-score?)
-        validation       {:invalid-score (invalid-score-fn team-score other-score)}
-        _                (debug team-path {:this  team-score
-                                           :other other-score
-                                           :valid validation})]
+        invalid?         (invalid-score-fn team-score other-score)]
     [:div.form-group
      [:label.control-label.col-lg-4 "Score"]
      [:div.controls.col-lg-8
-      (om/build e/editable team {:fn (fn [t] (merge t validation))
-                                 :opts {:edit-key :score
+      (om/build e/editable team {:opts {:edit-key :score
                                         :value-fn c/->int
                                         :placeholder "0"
-                                        :input-props {:type "number"}}})
-      #_ [:input.form-control {:type "number" :placeholder "0"
-                               :min "0" :max "11" :value score}]]]))
+                                        :input-props {:type "number"}
+                                        :input-classes (when invalid? ["error"])}})]]))

 (defn render-team-player [report-match players team-path num]
   (let [player-selector (keyword (str "player" num))


Make mandatory authfn param on httpbasic backend.

--- src/clojure/buddy/auth/backends/httpbasic.clj
+++ src/clojure/buddy/auth/backends/httpbasic.clj
@@ -36,6 +36,8 @@
   "Given some options, create a new instance
   of HttpBasicBackend and return it."
   [& [{:keys [realm authfn unauthorized-handler] :or {realm "Buddy Auth"}}]]
+  (when (nil? authfn)
+    (throw (IllegalArgumentException. "authfn parameter is mandatory.")))
   (reify
     proto/IAuthentication
     (parse [_ request]


Add clj and java options and add deprecation message for x-map counterparts.

--- src/dsbdp/data_processing_dsl.clj
+++ src/dsbdp/data_processing_dsl.clj
@@ -241,8 +241,14 @@
         output-sym (if (.endsWith output-type *incremental-indicator-suffix*)
                      'output)
         output-format-fn (condp (fn [^String v ^String s] (.startsWith s v)) output-type
-                           "java-map" java-out-format-fn
-                           "clj-map" clj-out-format-fn
+                           "java" java-out-format-fn
+                           "java-map" (do
+                                        (println "The format string 'java-map' is deprecated. Please use 'java' instead.")
+                                        java-out-format-fn)
+                           "clj" clj-out-format-fn
+                           "clj-map" (do
+                                       (println "The format string 'clj-map' is deprecated. Please use 'clj' instead.")
+                                       clj-out-format-fn)
                            "csv-str" csv-str-out-format-fn
                            "json-str" json-str-out-format-fn
                            (do


Changed implementation of forall semantics

for description logics.

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

--- src/conexp/contrib/dl/framework/semantics.clj
+++ src/conexp/contrib/dl/framework/semantics.clj
@@ -124,8 +124,10 @@
 (define-constructor forall
   (let [r-I (interpret model (first (arguments dl-exp))),
         C-I (interpret model (second (arguments dl-exp)))]
-    (set-of x [x (model-base-set model)
-               :when (forall [y C-I] (contains? r-I [x y]))])))
+    ;; interpreting Delta\(exists r. not C)
+    (difference (model-base-set model)
+                (set-of x [[x y] r-I
+                           :when (not (contains? C-I y))]))))

 (define-constructor inverse
   (let [r-I (interpret model (first (arguments dl-exp)))]


updated Billing Info to show whenever we have a stripe customer id

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -260,7 +260,7 @@
       [{:type :subpage :title "Update plan" :href "#containers" :subpage :containers}]
       (when (pm/transferrable-or-piggiebackable-plan? plan)
         [{:type :subpage :title "Organizations" :href "#organizations" :subpage :organizations}])
-      (when (or (pm/paid? plan) (pm/osx? plan))
+      (when (pm/stripe-customer? plan)
         [{:type :subpage :title "Billing info" :href "#billing" :subpage :billing}])))
    [{:type :heading :title "Organization"}
     {:type :subpage :href "#projects" :title "Projects" :subpage :projects}


Make the sound bearable.

Make the sound bearable.

--- src/leipzig_live/instruments.cljs
+++ src/leipzig_live/instruments.cljs
@@ -3,10 +3,23 @@
 (def context (js/window.AudioContext.))
 (defn beep! [freq start dur]
   (let [start (+ start (.-currentTime context))
-        stop (+ start dur)]
-    (doto (.createOscillator context)
-      (.connect (.-destination context))
-      (-> .-frequency .-value (set! freq))
-      (-> .-type (set! "square"))
-      (.start start)
-      (.stop stop))))
+        stop (+ start dur)
+        halfway (-> stop (- start) (/ 2))
+        harmonic (fn [freq n]
+                   (let [gainNode (doto (.createGain context)
+                                    (.connect (.-destination context)))
+                         gain (doto (.-gain gainNode)
+                                (.setValueAtTime 1 start)
+                                (.linearRampToValueAtTime (/ 1 n) (+ start 0.05))
+                                (.linearRampToValueAtTime 0 (+ start 0.4)))]
+                     (doto (.createOscillator context)
+                       (.connect gainNode)
+                       (-> .-frequency .-value (set! (* n freq)))
+                       (-> .-type  (set! "sine"))
+                       (.start start)
+                       (.stop stop)
+                       )))]
+    (harmonic freq 1)
+    (harmonic freq 2)
+    (harmonic freq 3)
+    (harmonic freq 5)))


Actually have the main fn do something.

Actually have the main fn do something.

--- src/cljs/go.clj
+++ src/cljs/go.clj
@@ -173,4 +173,5 @@
            (compile-file target-dir resource)))))))

 (defn -main [& args]
-  (println "ClojureScript to Go [clojure]"))
+  (println "ClojureScript to Go [clojure]")
+  (compile-clojurescript))


:shell breaks clojure invocation

:shell breaks clojure invocation

clojure -Sdeps "{:aliases ...}" with :shell seems to become
unquotes/multiple args which then fail reading by the tools.deps cli

don't know why lein under windows cmd requires a shell? It just doesn't
do anything without.

closes #213

--- src/main/shadow/cljs/npm/cli.cljs
+++ src/main/shadow/cljs/npm/cli.cljs
@@ -45,11 +45,20 @@
   (-> (fs/lstatSync path)
       (.isDirectory)))

+(defn is-windows? []
+  (str/includes? js/process.platform "win32"))
+
 (defn run [project-root cmd args proc-opts]
   (let [spawn-opts
         (-> {:cwd project-root
-             :shell true
              :stdio "inherit"}
+            (cond->
+              ;; can't figure out why lein won't work without this in windows cmd
+              ;; probably similar issue with tools.deps but that doesn't exist for windows yet
+              ;; need to verify first
+              (and (= "lein" cmd) (is-windows?))
+              (assoc :shell true
+                     :windowsVerbatimArguments true))
             (merge proc-opts)
             (clj->js))]


Change the dtbook templates

Change the dtbook templates

according to the new requirements by the board

--- src/mdr2/dtbook.clj
+++ src/mdr2/dtbook.clj
@@ -16,20 +16,22 @@
   {:de
    {:about "Zu diesem DAISY-Buch"
     :bib "Bibliographische Angaben"
-    :description "Produktbeschreibung des Hörbuchverlages"
     :blurb "Klappentexte"
+    :about_the_book "Über den Inhalt"
+    :about_the_author "Über den Verfasser/die Verfasserin"
     :contributors "Mitwirkende"
-    :enclosures "Hörbuchbeilagen"
+    :enclosures "Produktbeschreibung und Hörbuchbeilagen"
     :end "Ende des Buches"
     :title_creator_fmt "%s von %s"
     :unknown_title "Unbekannter Titel"}
    :en
    {:about "About this DAISY book"
     :bib "Bibliographic information"
-    :description "Product description by talking book publisher"
     :blurb "Blurbs"
+    :about_the_book "About the book"
+    :about_the_author "About the author"
     :contributors "Contributors"
-    :enclosures "Talking book enclosures"
+    :enclosures "Product description and Talking book enclosures"
     :end "End of book"
     :title_creator_fmt "%s by %s"
     :unknown_title "Unknown title"}})
@@ -92,11 +94,13 @@
        [:h1 (t :bib)]
        [:p]]
       [:level1
-       [:h1 (t :description)]
-       [:p]]
-      [:level1
        [:h1 (t :blurb)]
-       [:p]]]
+       [:level2
+        [:h2 (t :about_the_book)]
+        [:p]]
+       [:level2
+        [:h2 (t :about_the_author)]
+        [:p]]]]
      [:bodymatter
       [:level1 [:h1 "[Audioimport]"] [:p]]]
      [:rearmatter


Apparently stereo doesn't use twice as much space

at least that is not how the legacy system works and that seems to do
the right thing

--- src/mdr2/encode.clj
+++ src/mdr2/encode.clj
@@ -100,8 +100,7 @@
   [production]
   (let [dtb (path/recorded-path production)
         duration (quot (dtb/audio-length dtb) 1000) ; convert from millisecs to secs
-        sampling-ratio (if (dtb/mono? dtb) 1 2)
-        max-bitrate (/ (* (/ max-size duration sampling-ratio) 8) 1000)]
+        max-bitrate (/ (* (/ max-size duration) 8) 1000)]
     (->> bitrates
          (filter #(<= % max-bitrate))
          (apply max 0))))


fix upd-non-nil-keys

fix upd-non-nil-keys

--- src/metabase/db.clj
+++ src/metabase/db.clj
@@ -148,9 +148,9 @@
         (> 0))))

 (defn upd-non-nil-keys
-  "Calls `upd`, but filters out KWARGS with null values."
+  "Calls `upd`, but filters out KWARGS with `nil` values."
   [entity entity-id & {:as kwargs}]
-  (->> (m/filter-vals identity kwargs)
+  (->> (m/filter-vals (complement nil?) kwargs)
        (m/mapply upd entity entity-id)))


Generalize API doc to reflect MIDI note support.

--- src/afterglow/show.clj
+++ src/afterglow/show.clj
@@ -646,20 +646,21 @@
   cue grid.

   Afterglow will attempt to provide feedback about the progress of the
-  cue by sending control-change values to the same controller when the
-  cue starts and ends. The note velocities or control values used can
-  be changed by passing in different values with `:feedback-on` and
-  `:feedback-off`, and this behavior can be suppressed entirely by
-  passing `false` with `:feedback-on`.
-
-  Afterglow assumes the control is momentary, meaning it sends a
-  control value of 0 as soon as it is released, and a second press
-  will be used to end the cue unless the cue uses the `:held` modifier
-  to indicate it should be ended when the button is released. If your
-  controller does not have momentary buttons and already requires a
-  second press to turn off the control value, pass `false` with
-  `:momentary` and Afterglow will always end cues when it receives a
-  control value of 0, even if cues are not marked as `:held`."
+  cue by sending note on/off or control-change values to the same
+  controller when the cue starts and ends. The note velocities or
+  control values used can be changed by passing in different values
+  with `:feedback-on` and `:feedback-off`, and this behavior can be
+  suppressed entirely by passing `false` with `:feedback-on`.
+
+  Afterglow assumes the control is momentary, meaning it sends a note
+  off (or control value of 0) as soon as it is released, and a second
+  press will be used to end the cue unless the cue uses the `:held`
+  modifier to indicate it should be ended when the button is released.
+  If your controller does not have momentary buttons and already
+  requires a second press to turn off the note or control value, pass
+  `false` with `:momentary` and Afterglow will always end cues when it
+  receives a control value of 0, even if cues are not marked as
+  `:held`."
   {:doc/format :markdown}
   [midi-device-name channel kind note x y & {:keys [feedback-on feedback-off momentary]
                                                        :or {feedback-on 127 feedback-off 0 momentary true}}]


wrap-resource

wrap-resource

--- mtg-pairings-server/src/mtg_pairings_server/server.clj
+++ mtg-pairings-server/src/mtg_pairings_server/server.clj
@@ -5,6 +5,7 @@
             [compojure.route :as r]
             [ring.middleware.json :refer [wrap-json-body wrap-json-response]]
             [ring.middleware.session :refer [wrap-session]]
+            [ring.middleware.resource :refer [wrap-resource]]
             [ring.util.response :refer [response]]
             [clojure.java.io :as io]
             [clojure.tools.reader.edn :as edn]
@@ -54,6 +55,7 @@
         db (create-db db-properties)
         stop-fn (hs/run-server
                   (-> (routes db)
+                    (wrap-resource "public")
                     wrap-session
                     wrap-json-response
                     (wrap-json-body {:keywords? true}))


Float type comes floating back

Float type comes floating back

--- src/grafter/rdf/sesame.clj
+++ src/grafter/rdf/sesame.clj
@@ -137,6 +137,10 @@

   (sesame-rdf-type->type [this]
     (literal-datatype->type this))
+
+  java.lang.Float
+  (->sesame-rdf-type [this]
+    (NumericLiteralImpl. this))

   java.lang.Double
   (->sesame-rdf-type [this]


RR: show loading if data exists

RR: show loading if data exists

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -321,7 +321,9 @@
     om/IRenderState
     (render-state [_ _]
       (let [no-data? (empty? (get-in app-state [:data]))
-            with-info #(merge % {:dataset-info (:dataset-info app-state)})]
+            {:keys [num_of_submissions] :as dataset-info}
+            (:dataset-info app-state)
+            with-info #(merge % {:dataset-info dataset-info})]
         (html
          [:div.table-view
           (om/build submission-view
@@ -330,8 +332,10 @@
                                   {:view :table})})
           (om/build table-header app-state)
           [:div {:id table-id :class "slickgrid"}
-           (when no-data?
-             [:span {:class "empty-state"} "No data"])]])))
+           (if (and no-data? (zero? num_of_submissions))
+             [:span {:class "empty-state"} "No data"]
+             [:span
+              [:i.fa.fa-spinner.fa-pulse] "Loading..."])]])))
     om/IDidMount
     (did-mount [_]
       (let [data (get-in app-state [:data])]


[defstate]: refactoring "magic" into a clean fn

--- src/mount/core.cljc
+++ src/mount/core.cljc
@@ -131,13 +131,24 @@
         (up name state (atom #{})))
       @inst)))

+
+;;TODO: make private after figuring out the inconsistency betwen cljs compile stages
+;;      (i.e. _sometimes_ this, if private, is not seen by expanded "defmacro" on cljs side)
+(defn mount-it [s-var s-name s-meta]
+  (let [with-inst (assoc s-meta :inst (atom (NotStartedState. s-name))
+                                :var s-var)
+        existing? (cleanup-if-dirty s-name "(namespace was recompiled)")]
+    (update-meta! [s-name] with-inst)
+    (when existing?
+      (log (str ">> starting.. " s-name " (namespace was recompiled)"))
+      (up s-name with-inst (atom #{})))))
+
 #?(:clj
     (defmacro defstate [state & body]
       (let [[state params] (macro/name-with-attributes state body)
             {:keys [start stop suspend resume] :as lifecycle} (apply hash-map params)
             state-name (with-ns *ns* state)
-            order (make-state-seq state-name)
-            sym (str state)]
+            order (make-state-seq state-name)]
         (validate lifecycle)
         (let [s-meta (cond-> {:order order
                               :start `(fn [] ~start)
@@ -147,14 +158,8 @@
                        resume (assoc :resume `(fn [] ~resume)))]
           `(do
              (~'defonce ~state (DerefableState. ~state-name))
-             (let [meta# (~'assoc ~s-meta :inst (~'atom (NotStartedState. ~state-name))
-                                        :var (~'var ~state))
-                   restart?# ((~'var mount.core/cleanup-if-dirty) ~state-name "(namespace was recompiled)")]
-               ((~'var mount.core/update-meta!) [~state-name] meta#)
-               (~'when restart?#
-                 (log (~'str ">> starting.. " ~state-name " (namespace was recompiled)"))
-                 ((~'var mount.core/up) ~state-name meta# (~'atom #{})))
-               (~'var ~state)))))))
+             (mount-it (~'var ~state) ~state-name ~s-meta)
+             (~'var ~state))))))

 #?(:clj
     (defmacro defstate! [state & {:keys [start! stop!]}]


breaking: fn declarations need an arguments vector

--- src/app/cljs/one/sample/controller.cljs
+++ src/app/cljs/one/sample/controller.cljs
@@ -59,7 +59,7 @@
 (dispatch/react-to #{:init :workspace}
                    (fn [t d] (action (assoc d :type t))))

-(defn token-changed-to-id?
+(defn token-changed-to-id? [s]
   (.test (js/RegExp. "^[a-z0-9]{32}$") (name s)))

 (dispatch/react-to token-changed-to-id?


datamunging part3 (clojure)

datamunging part3 (clojure)

--- src/main/clojure/datamunging/datamunging1.clj
+++ src/main/clojure/datamunging/datamunging1.clj
@@ -22,19 +22,24 @@
     (:id row-with-min-values-diff)
 ))

+(defn find-team-with-min-goall-diff [file-name]
+  (defn remove-non-data [lines] (filter #(not (.contains % "----")) (drop 5 (drop-last 1 lines))))
+  (defn take-columns-with-data [lines] (map #(vector (nth % 1) (nth % 6) (nth % 8)) lines))
+  (find-entity-with-min-diff file-name remove-non-data take-columns-with-data)
+)
+
+(defn find-day-with-min-temperature-spread [file-name]
+  (defn remove-non-data [lines] (drop 8 (drop-last 2 lines)))
+  (defn take-columns-with-data [lines] (map #(vector (nth % 0) (nth % 1) (nth % 2)) lines))
+  (find-entity-with-min-diff file-name remove-non-data take-columns-with-data)
+)
+
 (deftest should-find-team-with-min-goall-diff
   (def football-file "/Users/dima/IdeaProjects/katas/src/main/scala/ru/katas/n4/football.dat")
-  (defn remove-non-data [lines] (filter #(not (.contains % "----")) (drop 5 (drop-last 1 lines))))
-  (defn take-columns-with-data [lines] (map #(vector (nth % 1) (nth % 6) (nth % 8)) lines))
-
-  (is (= "Aston_Villa" (find-entity-with-min-diff football-file remove-non-data take-columns-with-data)))
-)
+  (is (= "Aston_Villa" (find-team-with-min-goall-diff football-file))))

 (deftest should-find-day-with-min-temperature-spread
   (def weather-file "/Users/dima/IdeaProjects/katas/src/main/scala/ru/katas/n4/weather.dat")
-  (defn remove-non-data [lines] (drop 8 (drop-last 2 lines)))
-  (defn take-columns-with-data [lines] (map #(vector (nth % 0) (nth % 1) (nth % 2)) lines))
+  (is (= "14" (find-day-with-min-temperature-spread weather-file))))

-  (is (= "14" (find-entity-with-min-diff weather-file remove-non-data take-columns-with-data)))
-)
 (run-tests)


fix :init-fn! spelling so app init gets called

--- src/galleon.clj
+++ src/galleon.clj
@@ -35,12 +35,12 @@
                 :config config-map}]
     (when db-create-rval
       (doseq [app applications]
-        (when (fn? (:init-fn app))
-          ((:init-fn app) system))))
+        (when (fn? (:init-fn! app))
+          ((:init-fn! app) system))))
     system))

 (defn start-system!
-  []
+  [_] ;; TODO: handle incoming system here?
   (let [apps galleon.applications/system-applications
         system (init-system!
                 (load-system-config "to/some/path") ;; TODO: Make this configurable.