moved spec demo into ip-tupelo-demo/clojure-spec repo

--- test/clj/tst/tupelo/x/spec.clj
+++ test/clj/tst/tupelo/x/spec.clj
@@ -1,437 +0,0 @@
-;   Copyright (c) Alan Thompson. All rights reserved.
-;   The use and distribution terms for this software are covered by the Eclipse Public License 1.0
-;   (http://opensource.org/licenses/eclipse-1.0.php) which can be found in the file epl-v10.html at
-;   the root of this distribution.  By using this software in any fashion, you are agreeing to be
-;   bound by the terms of this license.  You must not remove this notice, or any other, from this
-;   software.
-(ns tst.tupelo.x.spec
-  (:use tupelo.core tupelo.test )
-  (:require
-    [clojure.set :as set]
-    [clojure.string :as str]
-    [clojure.test.check.generators :as tcgen]
-    [tupelo.spec :as tsp] ))
-
-(when-clojure-1-9-plus
-
-  (require
-    '[clojure.spec.alpha :as s]
-    '[clojure.spec.gen.alpha :as gen]
-    '[clojure.spec.test.alpha :as stest])
-
-
-  (dotest
-    (is= (s/valid? even? 4) true) ; NOTE: normally just use (is   (s/valid? ...))
-    (is= (s/valid? even? 5) false) ; NOTE: normally just use (isnt (s/valid? ...))
-
-    (is= (s/conform even? 4) 4)
-    (is= (s/conform even? 5) :clojure.spec.alpha/invalid)
-
-    ; (s/check-asserts?) => normally false
-    (s/check-asserts true)
-    (is (s/check-asserts?))
-    (is= 4 (s/assert even? 4))
-    (throws? (s/assert even? 5))
-
-    (is (s/valid? nil? nil))
-    (is (s/valid? string? "abc"))
-    (is (s/valid? #(< % 5) 3))
-    (isnt (s/valid? #(< % 5) 9))
-
-    (is (s/valid? inst? (java.util.Date.)))
-
-    (is (s/valid? #{:club :diamond :heart :spade} :club))
-    (isnt (s/valid? #{:club :diamond :heart :spade} 42))
-    (is (s/valid? #{42 43 44} 42))
-
-    (let [ki-spec (s/map-of keyword? int?)]
-      (is (s/valid? ki-spec {:a 1 :b 2}))
-      (isnt (s/valid? ki-spec {:a 1 :b "hello"}))
-
-      (is= (s/conform ki-spec {:a 1 :b 2}) {:a 1 :b 2})
-      (is= (s/conform ki-spec {:a 1 :b "hello"}) :clojure.spec.alpha/invalid))
-
-    (let [int-coll-spec (s/coll-of int?)]
-      (is (s/valid? int-coll-spec [1 2 3 4]))
-      (is (s/valid? int-coll-spec #{1 2 3 4}))
-      (isnt (s/valid? int-coll-spec #{1 :b 3})))
-
-    (let [v4 [1 2 3 4]
-          f3 [1 3 3]
-          f4 [1 2 3 :d]]
-      (is (s/valid? (s/coll-of int?) v4))
-      (isnt (s/valid? (s/coll-of int?) f4))
-      (is (s/valid? (s/coll-of int? :kind vector?) v4))
-      (isnt (s/valid? (s/coll-of int? :kind list?) v4))
-
-      (is (s/valid? (s/coll-of int? :min-count 2) v4))
-      (isnt (s/valid? (s/coll-of int? :min-count 5) v4))
-      (is (s/valid? (s/coll-of int? :min-count 2 :max-count 5) v4))
-      (isnt (s/valid? (s/coll-of int? :min-count 2 :max-count 3) v4))
-
-      (is (s/valid? (s/coll-of int? :distinct true) v4)) ; #todo usage unclear, need example
-      (is (s/valid? (s/coll-of int? :distinct int?) v4)) ; #todo usage unclear, need example
-      (is (s/valid? (s/coll-of int? :distinct false) v4)) ; #todo usage unclear, need example
-
-      (is (s/valid? (s/coll-of int? :distinct false) f3))
-      (isnt (s/valid? (s/coll-of int? :distinct true) f3)))
-
-    ; s/every is the "sampling" version of s/coll-of
-    (let [v4 [1 2 3 4]
-          f3 [1 3 3]
-          f4 [1 2 3 :d]]
-      (is (s/valid? (s/every int?) v4))
-      (isnt (s/valid? (s/every int?) f4))
-      (is (s/valid? (s/every int? :kind vector?) v4))
-      (isnt (s/valid? (s/every int? :kind list?) v4))
-
-      (is (s/valid? (s/every int? :min-count 2) v4))
-      (isnt (s/valid? (s/every int? :min-count 5) v4))
-      (is (s/valid? (s/every int? :min-count 2 :max-count 5) v4))
-      (isnt (s/valid? (s/every int? :min-count 2 :max-count 3) v4))
-
-      (is (s/valid? (s/every int? :distinct true) v4)) ; #todo usage unclear, need example
-      (is (s/valid? (s/every int? :distinct int?) v4)) ; #todo usage unclear, need example
-      (is (s/valid? (s/every int? :distinct false) v4)) ; #todo usage unclear, need example
-
-      (is (s/valid? (s/every int? :distinct false) f3))
-      (isnt (s/valid? (s/every int? :distinct true) f3)))
-    )
-
-  (dotest
-    (s/def ::date inst?)
-    (s/def ::suit #{:club :diamond :heart :spade})
-    (is (s/valid? ::date (java.util.Date.)))
-    (is (s/valid? ::suit :club))
-
-    (s/def ::big-even (s/and int? even? #(< 1000 %)))
-    (is (s/valid? ::big-even 2222))
-    (isnt (s/valid? ::big-even 10))
-    (isnt (s/valid? ::big-even :foo))
-
-    (s/def ::name-or-id (s/or :name string?
-                          :id int?))
-    (is (s/valid? ::name-or-id "abc"))
-    (is (s/valid? ::name-or-id 100))
-    (isnt (s/valid? ::name-or-id :foo))
-
-    (is= (s/conform ::name-or-id "abc") [:name "abc"])
-    (is= (s/conform ::name-or-id 100) [:id 100])
-
-    (isnt (s/valid? string? nil))
-    (is (s/valid? (s/nilable string?) nil))
-
-    ;(is= (s/explain-data ::name-or-id :foo)
-    ;  #:clojure.spec.alpha{:problems
-    ;                              '({:path [:name], ; ### NOTE need to quote list ***
-    ;                                 :pred clojure.core/string?,
-    ;                                 :val  :foo,
-    ;                                 :via  [:tst.tupelo.x.spec/name-or-id],
-    ;                                 :in   []}
-    ;                                 {:path [:id],
-    ;                                  :pred clojure.core/int?,
-    ;                                  :val  :foo,
-    ;                                  :via  [:tst.tupelo.x.spec/name-or-id],
-    ;                                  :in   []}),
-    ;                       :spec  :tst.tupelo.x.spec/name-or-id,
-    ;                       :value :foo})
-  )
-
-  (dotest
-    (def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$")
-    (s/def ::email-type (s/and string? #(re-matches email-regex %)))
-    (s/def ::acctid int?)
-    (s/def ::first-name string?)
-    (s/def ::last-name string?)
-    (s/def ::email ::email-type)
-    (s/def ::person (s/keys :req [::first-name ::last-name ::email]
-                      :opt [::phone])) ; #todo s/keys -> tsp/map-with-keys tsp/entity-map
-
-    (is (s/valid? ::person {::first-name "Elon" ::last-name "Musk" ::email "elon@example.com"}))
-    (isnt (s/valid? ::person {::first-name "Elon"}))
-    (isnt (s/valid? ::person {::first-name "Elon" ::last-name "Musk" ::email "n/a"}))
-
-    ; NOTE:  we cannot avoid mis-spellings of keys like ::phony (instead of ::phone)
-    ; or arbitrary additions like ::snailmail
-    (is (s/valid? ::person {::first-name "Elon" ::last-name "Musk" ::email "elon@example.com"
-                            ::phony      "714-555-1234" ::snailmail "3rd door on left" }))
-
-    ; NOTE: we specify *qualified* keywords here, but they will match *unqualified* keywords later
-    (s/def :unq/person (s/keys :req-un [::first-name ::last-name ::email]
-                         :opt-un [::phone])) ; #todo s/keys -> tsp/map-with-keys tsp/entity-map
-    (is= (s/conform :unq/person {:first-name "Elon" :last-name "Musk" :email "elon@example.com"})
-      {:first-name "Elon", :last-name "Musk", :email "elon@example.com"})
-
-    (defrecord Person [first-name last-name email phone])
-    (is (val=
-          (s/conform :unq/person (->Person "Elon" "Musk" "elon@example.com" nil))
-          {:first-name "Elon", :last-name "Musk", :email "elon@example.com", :phone nil})))
-
-  (dotest
-    (s/def ::port number?)
-    (s/def ::host string?)
-    (s/def ::id keyword?)
-    (s/def ::server (s/keys* :req [::id ::host] :opt [::port]))
-    (is= (s/conform ::server [::id :s1 ::host "example.com" ::port 5555])
-      {::id :s1, ::host "example.com", ::port 5555}))
-
-  (dotest
-    (s/def :animal/kind string?)
-    (s/def :animal/says string?)
-    (s/def :animal/common (s/keys :req [:animal/kind :animal/says])) ; common keys for any animal
-    (s/def :dog/tail? boolean?)
-    (s/def :dog/breed string?)
-    (s/def :animal/dog (s/merge :animal/common
-                         (s/keys :req [:dog/tail? :dog/breed]))) ; merge in additional keys to create dog spec
-    (is (s/valid? :animal/dog {:animal/kind "dog"
-                               :animal/says "woof"
-                               :dog/tail?   true
-                               :dog/breed   "retriever"})))
-
-  (dotest
-    (s/def :event/type keyword?)
-    (s/def :event/timestamp int?)
-    (s/def :search/url string?)
-    (s/def :error/message string?)
-    (s/def :error/code int?)
-
-    (defmulti event-type :event/type)
-    (defmethod event-type :event/search [_]
-      (s/keys :req [:event/type :event/timestamp :search/url]))
-    (defmethod event-type :event/error [_]
-      (s/keys :req [:event/type :event/timestamp :error/message :error/code]))
-
-    (s/def :event/event (s/multi-spec event-type :event/type))
-
-    (is (s/valid? :event/event {:event/type      :event/search
-                                :event/timestamp 1463970123000
-                                :search/url      "https://clojure.org"}))
-    (is (s/valid? :event/event {:event/type      :event/error
-                                :event/timestamp 1463970123000
-                                :error/message   "Invalid host"
-                                :error/code      500}))
-
-    ;(is= (s/explain-data :event/event {:event/type :event/restart})
-    ;  #:clojure.spec.alpha{:problems [{:path   [:event/restart],
-    ;                                   :pred   'tst.tupelo.x.spec/event-type,
-    ;                                   :val    #:event{:type :event/restart},
-    ;                                   :reason "no method",
-    ;                                   :via    [:event/event],
-    ;                                   :in     []}],
-    ;                       :spec     :event/event,
-    ;                       :value    #:event{:type :event/restart}})
-
-    (is= (s/conform (s/coll-of keyword?) [:a :b :c]) [:a :b :c])
-    (is= (s/conform (s/coll-of number?) [1 2 3]) [1 2 3])
-
-    (s/def ::vnum3 (s/coll-of number? :kind vector? :count 3 :distinct true :into #{}))
-    (is= (s/conform ::vnum3 [1 2 3]) #{1 2 3})
-    (is= (s/conform ::vnum3 #{1 2 3}) :clojure.spec.alpha/invalid)
-    (is= (s/conform ::vnum3 [1 1 1]) :clojure.spec.alpha/invalid)
-    (is= (s/conform ::vnum3 [1 2 :a]) :clojure.spec.alpha/invalid)
-
-    (s/def ::point (s/tuple double? double? double?))
-    (is= (s/conform ::point [1.5 2.0 3.1]) [1.5 2.0 3.1])
-
-    (s/def ::scores (s/map-of string? int?)) ; every entry is string -> int
-    (is= (s/conform ::scores {"Sally" 1000 "joe" 500}) {"Sally" 1000 "joe" 500}))
-
-  (dotest
-    (s/def ::ingredient (s/cat :quantity number? :unit keyword?))
-    (is (s/valid? ::ingredient [2 :teaspoon]))
-    (is= (s/conform ::ingredient [2 :teaspoon])
-      {:quantity 2, :unit :teaspoon})
-
-    (s/def ::seq-of-keywords (s/* keyword?))
-    (is= (s/conform ::seq-of-keywords [:a :b :c]) [:a :b :c])
-
-    (s/def ::odds-then-maybe-even (s/cat :odds (s/+ odd?)
-                                    :even (s/? even?)))
-    (is (s/valid? ::odds-then-maybe-even [1 3 5 66]))
-    (is (s/valid? ::odds-then-maybe-even [1 3 5]))
-    (isnt (s/valid? ::odds-then-maybe-even [1 3 66 5]))
-    (isnt (s/valid? ::odds-then-maybe-even [2]))
-
-    ; opts are alternating pairs of keyword & boolean
-    (s/def ::opts (s/* (s/cat :opt keyword? :val boolean?)))
-    (is= (s/conform ::opts [:silent false :verbose true])
-      [{:opt :silent, :val false} {:opt :verbose, :val true}])
-
-    (s/def ::config (s/* (s/cat :prop string?
-                           :val (s/alt :s string? :b boolean?))))
-    (is= (s/conform ::config ["-server" "foo" "-verbose" true "-user" "joe"])
-      [{:prop "-server", :val [:s "foo"]}
-       {:prop "-verbose", :val [:b true]}
-       {:prop "-user", :val [:s "joe"]}])
-
-    (is= (s/describe ::seq-of-keywords)
-      '(* keyword?))
-    (is= (s/describe ::odds-then-maybe-even)
-      '(cat :odds (+ odd?) :even (? even?)))
-    (is= (s/describe ::opts)
-      '(* (cat :opt keyword? :val boolean?)))
-
-    (s/def ::even-strings (s/& (s/* string?) #(even? (count %))))
-    (is (s/valid? ::even-strings ["a" "b"]))
-    (is (s/valid? ::even-strings ["a" "b" "c" "d"]))
-    (isnt (s/valid? ::even-strings ["a"]))
-    (isnt (s/valid? ::even-strings ["a" "b" "c"]))
-
-    (s/def ::nested
-      (s/cat :names-kw #{:names}
-        :names (s/spec (s/* string?))
-        :nums-kw #{:nums}
-        :nums (s/spec (s/* number?))))
-    (is= (s/conform ::nested [:names ["a" "b"] :nums [1 2 3]])
-      {:names-kw :names, :names ["a" "b"], :nums-kw :nums, :nums [1 2 3]})
-
-    (s/def ::unnested
-      (s/cat :names-kw #{:names}
-        :names (s/* string?)
-        :nums-kw #{:nums}
-        :nums (s/* number?)))
-    (is= (s/conform ::unnested [:names "a" "b" :nums 1 2 3])
-      {:names-kw :names, :names ["a" "b"], :nums-kw :nums, :nums [1 2 3]}))
-
-  (dotest
-    (def suit? #{:club :diamond :heart :spade}) ; remember sets are predicates
-    (def rank? (into #{:jack :queen :king :ace} (thru 2 10))) ; remember sets are predicates
-    (def deck (forv [suit suit? rank rank?]
-                [rank suit]))
-    (is (set/subset? #{[2 :club] [5 :diamond] [:queen :heart]}
-          (into #{} deck)))
-
-    (s/def ::card (s/tuple rank? suit?))
-    (s/def ::hand (s/* ::card))
-
-    (s/def ::name string?)
-    (s/def ::score int?)
-    (s/def ::player (s/keys :req [::name ::score ::hand]))
-    ; #todo s/keys -> tsp/map-with-keys  tsp/entity-map (really more like an object declaration)
-
-    (s/def ::players (s/* ::player))
-    (s/def ::deck (s/* ::card))
-    (s/def ::game (s/keys :req [::players ::deck])) ; #todo s/keys -> tsp/map-with-keys tsp/entity-map
-
-    (def kenny {::name  "Kenny Rogers"
-                ::score 100
-                ::hand  []})
-    (is (s/valid? ::player kenny))
-    (is (s/valid? ::player {::name  "Kenny Rogers"
-                            ::score 100
-                            ::hand  [[2 :heart]]}))
-    (isnt (s/valid? ::player {::name  "Kenny Rogers"
-                              ::score 100
-                              ::hand  [[2 :hurts]]}))
-
-    ; Create a generator for ::player, generate a single sample value, and verify it is valid
-    (is (s/valid? ::player (gen/generate (s/gen ::player)))))
-
-
-  (defn ranged-rand
-    "Returns random int in range start <= rand < end"
-    [start end]
-    (+ start (long (rand (- end start)))))
-
-  (s/fdef ranged-rand
-    :args (s/and
-            (s/cat :start int?
-                   :end   int?)
-            #(< (:start %) (:end %) 1e9)) ; need add 1e9 limit to avoid integer overflow
-    :ret int?
-    :fn (s/and #(<= (-> % :args :start) (:ret %))
-               #(< (:ret %) (-> % :args :end))))
-
-  (dotest
-    (when true
-      (stest/instrument `ranged-rand)
-      (throws? Exception (ranged-rand 8 5))
-      ; (spyx (stest/check `ranged-rand))  #todo
-      ; (spyx (s/exercise-fn `ranged-rand))
-      )
-    )
-
-  ;-----------------------------------------------------------------------------
-  ; examples from: Clojure spec Screencast - Customizing Generators: https://youtu.be/WoFkhE92fqc
-
-  (when false
-    (s/def ::foo-id (s/and string? #(str/starts-with? % "FOO-")))
-    (defn foo-id-gen []
-      (->> (s/gen (s/int-in 1 100))
-        (gen/fmap #(str "FOO-" %))))
-
-
-    (dotest
-      (spy :foo-id (mapv first (s/exercise ::foo-id 10
-                                 {::foo-id foo-id-gen})))) ; a generator override
-
-    ; Lookup
-    (s/def ::lookup (s/map-of keyword? string? :min-count 1))
-    (s/def ::lookup-finding-k (s/and (s/cat
-                                       :lookup ::lookup
-                                       :k keyword?)
-                                (fn [{:keys [lookup k]}] (contains? lookup k))))
-    (defn lookup-finding-k-gen []
-      (gen/bind (s/gen ::lookup)
-        #(gen/tuple
-           (gen/return %)
-           (gen/elements (keys %)))))
-
-    (dotest
-      (nl)
-      (spyx (mapv first (s/exercise ::lookup)))
-      (throws? (mapv first (s/exercise ::lookup-finding-k)))
-      (spyx (s/exercise ::lookup-finding-k 10 {::lookup-finding-k lookup-finding-k-gen})))
-
-    (defn my-index-of [source tgt] (str/index-of source tgt))
-    (defn my-index-of-2 [source tgt] (str/index-of source tgt))
-    (defn my-index-of-3 [source tgt] (str/index-of source tgt))
-    (defn my-index-of-4 [source tgt] (str/index-of source tgt))
-
-    (s/fdef my-index-of :args (s/cat
-                                :source string?
-                                :tgt string?))
-    ; constructively generate a string and substring
-    (def string-and-substring-model (s/cat :prefix string? :match string? :suffix string?))
-    (defn gen-string-and-substring [] (gen/fmap
-                                        (fn [[prefix match suffix]] [(str prefix match suffix) match])
-                                        (s/gen string-and-substring-model)))
-    (s/def ::my-index-of-args (s/cat :source string? :tgt string?))
-    (s/fdef my-index-of-2 :args (s/spec ::my-index-of-args
-                                  :gen gen-string-and-substring))
-
-    (defn gen-my-index-of-args []
-      (gen/one-of [(gen-string-and-substring)
-                   (s/gen ::my-index-of-args)]))
-    (s/fdef my-index-of-3 :args (s/spec ::my-index-of-args
-                                  :gen gen-my-index-of-args))
-
-    (defn gen-string-and-substring-let []
-      ; RHS must be tcgen/* generator fns
-      (tcgen/let [prefix tcgen/string-alphanumeric
-                  tgt tcgen/string-alphanumeric
-                  suffix tcgen/string-alphanumeric]
-        (let [search-str (str prefix tgt suffix)
-              result     [search-str tgt]]
-          result)))
-    (defn gen-my-index-of-let []
-      (gen/one-of [(gen-string-and-substring-let)
-                   ;(s/gen ::my-index-of-args)
-                   ]))
-    (s/fdef my-index-of-4 :args (s/spec ::my-index-of-args
-                                  :gen gen-my-index-of-let))
-
-    (dotest
-      (nl) (spyx (s/exercise-fn `my-index-of))
-      (nl) (spyx (s/exercise-fn `my-index-of-2))
-      (nl) (spyx (s/exercise-fn `my-index-of-3))
-      (nl) (spyx (s/exercise-fn `my-index-of-4)))
-
-    (dotest (nl)
-      (spyx (tcgen/sample (tcgen/fmap set (tcgen/vector tcgen/nat))))
-      (spyx (tcgen/sample (tcgen/fmap
-                            (fn [v]
-                              [(rand-nth v) v])
-                            (tcgen/not-empty (tcgen/vector tcgen/nat)))))))
-
-)


no more h2 trace file

no more h2 trace file

--- test/clojento/magento/t_db.clj
+++ test/clojento/magento/t_db.clj
@@ -49,8 +49,8 @@
   (let [unique (gensym)
         path   (str "./data/test-db-" unique)]
     {:path path
-     :rw (str "jdbc:h2:file:" path ";MODE=MySQL")
-     :ro (str "jdbc:h2:file:" path ";MODE=MySQL;ACCESS_MODE_DATA=r")}))
+     :rw (str "jdbc:h2:file:" path ";MODE=MySQL;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=1")
+     :ro (str "jdbc:h2:file:" path ";MODE=MySQL;TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=1;ACCESS_MODE_DATA=r")}))

 (defn test-db-config-ro [test-db-urls]
   {:adapter  "h2"
@@ -64,7 +64,7 @@
 (defn cleanup-db-fixture [path]
   (log/info "deleting database fixture:" path)
   (io/delete-file (str path ".mv.db"))
-  (io/delete-file (str path ".trace.db")))
+  nil)

 (defrecord DatabaseFixture [config created]
   component/Lifecycle


Preparation for sending in device measurements

--- test/kixi/hecuba/amon_test.clj
+++ test/kixi/hecuba/amon_test.clj
@@ -50,13 +50,14 @@
     (is (not (nil? response)))
     (is (= (:status response) 201))
     (is (= (count @db) 1))
-    (let [{handler :handler {uuid :amon/entity-id} :params}
+    (let [{handler :handler {entity-id :amon/entity-id} :params}
           (bidi/match-route routes (get-in response [:headers "Location"]))
-          uuid (UUID/fromString uuid)]
+          entity-id (UUID/fromString entity-id)]
       (is (= handler (:entity handlers)))
-      (is (contains? @db uuid))
-      ;; Return the uuid
-      uuid)))
+      (is (contains? @db entity-id))
+      ;; Return the entity-id, might be useful
+      entity-id
+      )))

 (defn get-entity [db id]
   (let [handlers (-> db make-mock-records amon/make-handlers)
@@ -100,9 +101,10 @@
           {handler :handler {entity-id :amon/entity-id
                              device-id :amon/device-id} :params}
           (bidi/match-route routes location)
-          ]
+          device-id (java.util.UUID/fromString device-id)]
       (is (not (nil? (java.util.UUID/fromString entity-id))))
-      (is (not (nil? (java.util.UUID/fromString device-id))))
+      ;; Return the device-id to the caller, might be useful
+      device-id
       )))

 (defn create-device-with-bad-entity-in-body [db entity-id]
@@ -139,4 +141,12 @@
   ;; Test create device with wrong entity in body
   (let [db (ref {})
         entity-id (create-entity db)]
-    (create-device-with-bad-entity-in-body db entity-id)))
+    (create-device-with-bad-entity-in-body db entity-id))
+
+  ;; Send in some measurements to a new device
+  (let [db (ref {})
+        entity-id (create-entity db)]
+    (create-device db entity-id)
+
+    )
+  )


Add Pixellicious bar definition.

Add Pixellicious bar definition.

--- src/afterglow/fixtures/blizzard.clj
+++ src/afterglow/fixtures/blizzard.clj
@@ -418,6 +418,20 @@
               (chan/functions :control 9 0 nil
                               128 {:type :sound-active :var-label "Sensitivity" :range :variable})]})

+(defn pixellicious
+  "4x40 LED pixel tile in 480 channel mode."
+  []
+  {:name "Blizzard Pixellicious"
+   :channels []
+   :heads (for [i (range 160)]
+            (let [x (+ (* (rem i 40) 0.025) -0.5)
+                  y (+ (* (quot i 40) 0.025) -0.05)
+                  c (+ (* i 3) 1)]
+              {:channels [(chan/color c :red)
+                          (chan/color (inc c) :green)
+                          (chan/color (+ 2 c) :blue)]
+               :x x :y y}))})
+
 (defn pixellicious-2
   "12x12 LED pixel tile in 432 channel mode."
   []


Add log fading

Add log fading

--- src/robinson/ui/components/robinson.clj
+++ src/robinson/ui/components/robinson.clj
@@ -1064,7 +1064,13 @@
   (let [{:keys [game-state]} (zc/props this)
         current-time     (rw/get-time game-state)
         log-idx          (get-in game-state [:world :log-idx] 0)
-        current-logs     (rlog/current-logs game-state)
+        current-logs     (let [logs (rlog/current-logs game-state)]
+                           (if (not-empty logs)
+                             logs
+                             (let [log (into {} (rlog/last-log game-state))]
+                               (log/info "ll" log)
+                               (when (< current-time (+ (get log :time 0) 5))
+                                 [log]))))
         num-logs         (count current-logs)
         msg-above?       (< log-idx (dec num-logs))
         msg-below?       (pos? log-idx)
@@ -1077,8 +1083,11 @@
         message          (if (zero? num-logs)
                            {:message "" :time 0 :color :black}
                            (nth (reverse current-logs) log-idx))
-        darken-factor    (inc  (* (/ -1 5) (- current-time (message :time))))
-        log-color        (rcolor/darken-rgb (rcolor/color->rgb (get message :color)) darken-factor)]
+        darken-factor    (/ 1 (inc (- current-time (get message :time 0))))
+        log-color        (rcolor/darken-rgb (rcolor/color->rgb (get message :color :gray)) darken-factor)]
+    (log/info "darken-factor" darken-factor)
+    (log/info "current-time" current-time)
+    (log/info message)
     (zc/csx
         [:view {:style {:position :absolute
                         :top 0 :left 0
@@ -1101,7 +1110,7 @@
                                [ruicommon/down-arrow-char]]]])
               (zc/csx [:text {} ["   "]]))
             (if (get message :text)
-              (zc/csx [:text {:style {:color (rcolor/color->rgb (get message :color))
+              (zc/csx [:text {:style {:color log-color
                                       :background-color (zcolor/with-alpha (rcolor/color->rgb :black) 242)}}
                              [(str (get message :text))]])
               (zc/csx [:text {} [""]]))]]]])))


Removing this to avoid warning since SO error is gone in latest lein

--- wildfly/project.clj
+++ wildfly/project.clj
@@ -17,6 +17,4 @@

   :dependencies [[org.immutant/core _]
                  [org.clojure/tools.nrepl "_"]
-                 [org.projectodd.wunderboss/wunderboss-wildfly _]]
-
-  :pedantic? false)
+                 [org.projectodd.wunderboss/wunderboss-wildfly _]])


More comprehensive dispatcher spec

More comprehensive dispatcher spec

--- spec/rook/dispatcher_spec.clj
+++ spec/rook/dispatcher_spec.clj
@@ -1,7 +1,29 @@
 (ns rook.dispatcher-spec
   (:use speclj.core)
   (:require [io.aviso.rook.dispatcher :as dispatcher]
-            [ring.mock.request :as mock]))
+            [io.aviso.rook.client :as client]
+            [io.aviso.rook.utils :as utils]
+            [io.aviso.rook.async :as rook-async]
+            [io.aviso.rook :as rook]
+            [ring.mock.request :as mock]
+            [clojure.core.async :as async]))
+
+
+(defn namespace-handler
+  "Produces a handler based on the given namespace."
+  ([ns-sym]
+     (dispatcher/compile-dispatch-table
+       (dispatcher/namespace-dispatch-table ns-sym)))
+  ([context-pathvec ns-sym]
+     (dispatcher/compile-dispatch-table
+       (dispatcher/namespace-dispatch-table context-pathvec ns-sym)))
+  ([context-pathvec ns-sym middleware]
+     (dispatcher/compile-dispatch-table
+       (dispatcher/namespace-dispatch-table context-pathvec ns-sym middleware)))
+  ([options context-pathvec ns-sym middleware]
+     (dispatcher/compile-dispatch-table options
+       (dispatcher/namespace-dispatch-table context-pathvec ns-sym middleware))))
+

 (create-ns 'example.foo)

@@ -60,13 +82,19 @@

     (it "should produce a handler returning valid response maps"

-      (let [handler (dispatcher/compile-dispatch-table simple-dispatch-table)
-            index-response (handler (mock/request :get "/foo"))
-            show-response  (handler (mock/request :get "/foo/1"))]
+      (let [handler (dispatcher/compile-dispatch-table
+                      (mapv (comp #(conj % rook/wrap-with-default-arg-resolvers) pop)
+                        simple-dispatch-table))
+            index-response  (handler (mock/request :get "/foo"))
+            show-response   (handler (mock/request :get "/foo/1"))
+            create-response (handler (merge (mock/request :post "/foo")
+                                       {:params {:x 123}}))]
         (should= {:status 200 :headers {} :body "Hello!"}
           index-response)
         (should= {:status 200 :headers {} :body "Interesting id: 1"}
-          show-response)))
+          show-response)
+        (should= {:status 200 :headers {} :body "Created 123"}
+          create-response)))

     (it "should inject the middleware"

@@ -85,5 +113,50 @@

       (let [dt (set (dispatcher/unnest-dispatch-table
                       (dispatcher/namespace-dispatch-table
-                        [] 'example.foo `*default-middleware*)))]
-        (should= (set simple-dispatch-table) dt)))))
+                        ["foo"] 'example.foo `*default-middleware*)))]
+        (should= (set simple-dispatch-table) dt))))
+
+  (describe "async handlers"
+
+    (it "should return a channel with the correct response"
+
+      (let [handler (namespace-handler
+                      {:apply-middleware-fn dispatcher/apply-middleware-async}
+                      [] 'barney `*default-middleware*)]
+        (should= {:message "ribs!"}
+          (-> (mock/request :get "/") handler async/<!! :body))))
+
+    (it "should expose the request's :params key as an argument"
+      (let [handler (namespace-handler
+                      {:apply-middleware-fn dispatcher/apply-middleware-async}
+                      [] 'echo-params rook/wrap-with-default-arg-resolvers)
+            params {:foo :bar}]
+        (should-be-same params
+          (-> (mock/request :get "/")
+            (assoc :params params)
+            handler
+            async/<!!
+            :body
+            :params-arg)))))
+
+  (describe "loopback-handler"
+
+    (it "should allow resources to collaborate"
+      (let [handler (rook-async/async-handler->ring-handler
+                      (rook-async/wrap-with-loopback
+                        (dispatcher/compile-dispatch-table
+                          {:apply-middleware-fn dispatcher/apply-middleware-async}
+                          (into
+                            (dispatcher/namespace-dispatch-table
+                              ["fred"] 'fred rook/wrap-with-default-arg-resolvers)
+                            (dispatcher/namespace-dispatch-table
+                              ["barney"] 'barney rook/wrap-with-default-arg-resolvers)))))]
+        (should= ":barney says `ribs!'"
+          (-> (mock/request :get "/fred")
+            handler
+            :body
+            :message))))
+
+    (it "should send schema validation failures")
+
+    (it "should return a 500 response if a sync handler throws an exception")))


fix hydration of FK targets which was still using the old ForeignKey model

--- src/metabase/models/field.clj
+++ src/metabase/models/field.clj
@@ -90,8 +90,15 @@
 (defn- pre-cascade-delete [{:keys [id]}]
   (db/cascade-delete Field :parent_id id)
   (db/cascade-delete ForeignKey (k/where (or (= :origin_id id)
-                                          (= :destination_id id))))
+                                             (= :destination_id id))))
   (db/cascade-delete 'FieldValues :field_id id))
+
+(defn ^:hydrate target
+  "Return the FK target `Field` that this `Field` points to."
+  [{:keys [special_type fk_target_field_id]}]
+  (when (and (= :fk special_type)
+             fk_target_field_id)
+    (Field fk_target_field_id)))

 (defn ^:hydrate values
   "Return the `FieldValues` associated with this FIELD."
@@ -116,16 +123,6 @@
   {:arglists '([field])}
   [{:keys [table_id]}]
   (db/sel :one 'Table, :id table_id))
-
-(defn field->fk-field
-  "Attempts to follow a `ForeignKey` from the the given FIELD to a destination `Field`.
-
-   Only evaluates if the given field has :special_type `fk`, otherwise does nothing."
-  {:hydrate :target}
-  [{:keys [id special_type]}]
-  (when (= :fk special_type)
-    (let [dest-id (db/sel :one :field [ForeignKey :destination_id] :origin_id id)]
-      (Field dest-id))))

 (u/strict-extend (class Field)
   i/IEntity (merge i/IEntityDefaults


What is the simplest infix->dsl test?

What is the simplest infix->dsl test?

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -2,6 +2,10 @@
   (:require
    [desdemona.query :as q]
    [clojure.test :refer [deftest is are testing]]))
+
+(deftest infix->dsl-tests
+  (is (= '(= (:ip x) "10.0.0.1")
+         (q/infix->dsl "ip(x) is 10.0.0.1"))))

 (def dsl->logic
   @#'desdemona.query/dsl->logic)


Revert "Adding failing test to test CI."

This reverts commit bf373ae68fce104646934b0e65c5b468775f3ccd.

--- test/cmr/umm/test/echo10/collection.clj
+++ test/cmr/umm/test/echo10/collection.clj
@@ -10,10 +10,6 @@
             ;; my code
             [cmr.umm.echo10.collection :as c]
             [cmr.umm.collection :as umm-c]))
-
-(deftest will-always-fail
-  (println "Failing to test CI")
-  (is (= 5 4)))

 (defspec generate-collection-is-valid-xml-test 100
   (for-all [collection umm-gen/collections]


BlockingObservable Refactor

BlockingObservable Refactor

No longer extends from Observable. If someone chooses to use BlockingObservable the intent is to leave the Observable so it shouldn't show the non-blocking operators.
Remove duplicate static methods, similar to how done on Observable in earlier commit.

--- src/test/clojure/rx/lang/clojure/interop_test.clj
+++ src/test/clojure/rx/lang/clojure/interop_test.clj
@@ -120,14 +120,16 @@
                                     (.onNext o 99)
                                     (.onCompleted o)
                                     (rx.subscriptions.Subscriptions/empty)))
-               (BlockingObservable/single)))))
+               .toBlockingObservable
+               .single))))

   (testing "can pass rx/fn to map and friends"
     (is (= (+ 1 4 9)
            (-> (Observable/from [1 2 3])
                (.map (rx/fn [v] (* v v)))
                (.reduce (rx/fn* +))
-               (BlockingObservable/single)))))
+           .toBlockingObservable
+           .single))))

   (testing "can pass rx/action to subscribe and friends"
     (let [finally-called (atom nil)


(maint) simplify dotestseq macro

(maint) simplify dotestseq macro

--- test/utils/puppetlabs/pcp/testutils.clj
+++ test/utils/puppetlabs/pcp/testutils.clj
@@ -6,10 +6,9 @@
     `(do ~@body)
     (let [case-versions (remove keyword? (take-nth 2 bindings))]
       `(doseq ~bindings
-         (testing (str "Testing case: " (clojure.string/join
-                                         ", "
-                                         (map #(clojure.string/join ": " %)
-                                              (partition
-                                               2
-                                               (interleave '~case-versions (list ~@case-versions))))))
+         (testing (str "with " (clojure.string/join
+                                ", "
+                                (map #(str (pr-str %1) ": " (pr-str %2))
+                                     '~case-versions
+                                     (list ~@case-versions))))
            ~@body)))))


Fixing integration tests after changing webp compression ratio

--- test/vignette/http/integration_test.clj
+++ test/vignette/http/integration_test.clj
@@ -160,7 +160,7 @@
       (:status response) => 200
       (get (:headers response) "Surrogate-Key") => "e77cd6979116303a6d50610962fa9790469574c2"
       (get (:headers response) "Content-Disposition") => "inline; filename=\"baboon.webp\"; filename*=UTF-8''baboon.webp"
-      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 18000 50)
+      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 17790 50)
       (get (:headers response) "Connection") => "close"
       (get (:headers response) "Cache-Control") => "public, max-age=31536000"
       (get (:headers response) "Content-Type") => "image/webp"
@@ -171,7 +171,7 @@
       (:status response) => 200
       (get (:headers response) "Surrogate-Key") => "6f13d7df6b332e4945d90bd6785226b535f8b248"
       (get (:headers response) "Content-Disposition") => "inline; filename=\"beach.webp\"; filename*=UTF-8''beach.webp"
-      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 17950 50)
+      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 16820 50)
       (get (:headers response) "Connection") => "close"
       (get (:headers response) "Cache-Control") => "public, max-age=31536000"
       (get (:headers response) "Content-Type") => "image/webp"


process to map

process to map

--- src/ads_txt_crawler/process.clj
+++ src/ads_txt_crawler/process.clj
@@ -72,3 +72,39 @@
   [domain]
   (read-ads-txt-url (build-url domain)))

+(defn read-ads-txt-url-map [url]
+  ;; read the contents of url
+  ;; - ignore non-text returns
+  ;; - ignore commented lines
+  ;; - parse lines into map of values
+  ;; - ignore
+  (let [rtn {}
+        {:keys [status headers body error] :as resp} (h/get-url url)]
+    ;; (println error)
+    ;; (println status)
+    ;; (println headers)
+    ;; (println body)
+    ;; Error reaching the domain
+    (if error
+      (assoc rtn :error true :error-message (.getMessage error) :status status)
+      (if status
+        ;; Error returned from server
+        (if (is-error status)
+          (assoc rtn :error true :error-message (format "Invalid status %d" status) :status status)
+          ;; Issue without having headers
+          (if (not headers)
+            (assoc rtn :error true :error-message "Blank headers" :status status)
+            ;; Non-text returned
+            (if (not (is-text url headers))
+              (assoc rtn :error true :error-message "Non-text result" :status status)
+              ;; Valid data. Process and return as data
+              (assoc rtn :error false :status status :data (remove nil? (map process-line (clojure.string/split-lines body)))))))
+        ;; No status, No error
+        (assoc rtn :error true :error-message "Unknown issue. No error, No Status")
+        ))))
+
+(defn process-to-map
+  "Return results in a map including a status value"
+  [domain]
+  (read-ads-txt-url-map (build-url domain)))
+


New form: edit-product

New form: edit-product

--- src/hurvinek/html_renderer.clj
+++ src/hurvinek/html_renderer.clj
@@ -180,7 +180,8 @@
                         (for [product product-list]
                             [:tr
                                 [:td [:a {:href (str "product?product-id=" (:id product))} (:name product)]]
-                                [:td [:a {:href (str "product?product-id=" (:id product))} (:description product)]]])
+                                [:td [:a {:href (str "product?product-id=" (:id product))} (:description product)]]
+                                [:td [:a {:href (str "edit-product?product-id=" (:id product))} "Edit"]]])
                     ]
                     [:br]
                     [:h3 "New product"]
@@ -194,6 +195,45 @@
                             [:input {:type "text" :class "form-control" :id "product-description" :name "description" :placeholder "description"}]
                         ]
                         [:button {:type "submit" :class "btn btn-primary"} "Add new product"]
+                    )
+                ]
+                (render-back-link url-prefix)
+                (render-html-footer)
+            ] ; </div class="container">
+        ] ; </body>
+    ))
+
+(defn render-edit-product
+    "Render the page with product."
+    [url-prefix title product-id product-name description & {:keys [message-type message]}]
+    (page/xhtml
+        (render-html-header url-prefix title)
+        [:body
+            [:div {:class "container"}
+                (render-navigation-bar-section url-prefix title)
+                (render-breadcrumb url-prefix "select-product" "Product list")
+                (if message
+                    [:div {:class "container-fluid"}
+                        [:div {:class (str "alert alert-" message-type)}
+                            message
+                        ]
+                    ])
+                [:div {:class "container-fluid"}
+                    [:h3 "Edit product"]
+                    (form/form-to [:get "edit-product"]
+                        [:fieldset {:class "form-group"}
+                            [:label {:for "product-id"} "Product id"]
+                            [:input {:type "text" :class "form-control" :id "product-id" :name "product-id" :placeholder "product id" :value product-id :readonly "readonly"}]
+                        ]
+                        [:fieldset {:class "form-group"}
+                            [:label {:for "product-name"} "Product name"]
+                            [:input {:type "text" :class "form-control" :id "product-name" :name "product-name" :placeholder "product name" :value product-name}]
+                        ]
+                        [:fieldset {:class "form-group"}
+                            [:label {:for "product-description"} "Description for product"]
+                            [:input {:type "text" :class "form-control" :id "product-description" :name "description" :placeholder "description" :value description}]
+                        ]
+                        [:button {:type "submit" :class "btn btn-primary"} "Update"]
                     )
                 ]
                 (render-back-link url-prefix)


make "neonato" conform to our current (verbose) conventions for describing nouns

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1676,11 +1676,16 @@
                       :sem {:pred :be-born}}
              :italiano {:passato "nato"}}

-   "neonato" {:synsem {:cat :noun
-                       :agr {:gender :masc}
-                       :sem {:pred :newborn
-                             :human true
-                             :adult false}}}
+   "neonato"
+   (unify agreement-noun
+          common-noun
+          countable-noun
+          masculine-noun
+          {:synsem {:cat :noun
+                    :agr {:gender :masc}
+                    :sem {:pred :newborn
+                          :human true
+                          :adult false}}})

    ;; non-comparative
    ;; TODO: add comparative


fix typo

fix typo

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1076,9 +1076,9 @@
                                   :2plur "fate"
                                   :3plur "fanno"}}}]
         [(merge shared-part-of-fare
-                {:synsem {:pred :do}})
+                {:synsem {:sem {:pred :do}}})
          (merge shared-part-of-fare
-                {:synsem {:pred :make}})
+                {:synsem {:sem {:pred :make}}})
          (merge shared-part-of-fare
                 (let [subject-semantics (atom {:human true})
                       subject-agr (atom :top)]


Allow navigating strings as a base data structure

--- src/themis/extended_protos.clj
+++ src/themis/extended_protos.clj
@@ -9,5 +9,9 @@

  clojure.lang.IPersistentMap
  (-navigate [t coordinate-vec]
-   (get-in t coordinate-vec)))
+   (get-in t coordinate-vec))
+
+  java.lang.String
+  (-navigate [t coordinate-vec]
+    (get-in t coordinate-vec)))


Make img tag's 100% width always

Make img tag's 100% width always

--- src/clj/comic_reader/server.clj
+++ src/clj/comic_reader/server.clj
@@ -68,8 +68,8 @@
   (c/GET "/" [] (hp/html5
                  [:head
                   (hp/include-css "css/foundation.css")
-                  (hp/include-js "js/vendor/modernizr.js")
-                  ]
+                  [:style "img {width: 100%;}"]
+                  (hp/include-js "js/vendor/modernizr.js")]
                  [:body
                   [:div.row
                    [:div#app.large-12.columns]]


Fix style of repl input

Fix style of repl input

--- src/cljs/cljs_webrepl/core.cljs
+++ src/cljs/cljs_webrepl/core.cljs
@@ -302,11 +302,10 @@

 (defn repl-input [props]
   [:div.input
-   [:div.mdl-grid.mdl-shadow--2dp.white-bg
-    [:div.mdl-cell--12-col
-     [:div.flex-h
-      [input-field props]
-      [run-button props]]]]])
+   [:div.card-data.expression
+    [:div.flex-h
+     [input-field props]
+     [run-button props]]]])

 (defn input-card [{:keys [state] :as props} num]
   [:div.mdl-cell.mdl-cell--12-col


first point extracted

first point extracted

--- test/analyze_runs/gpx_test.clj
+++ test/analyze_runs/gpx_test.clj
@@ -5,32 +5,29 @@
             [analyze-runs.gpx :refer :all]))

 (def points-from-sample-file (get-points "test/sample.gpx"))
+(def first-point (first points-from-sample-file))

 (deftest should-read-3-records-from-sample-file
   (is (= 3 (count points-from-sample-file))))

 (deftest assert-time-first-point
-  (let [first-point (first points-from-sample-file)]
-    (is (= (:time first-point) (tf/parse "2016-02-17T17:35:18Z")))))
+  (is (= (:time first-point) (tf/parse "2016-02-17T17:35:18Z"))))

 (deftest assert-elevation-first-point
-  (let [first-point (first points-from-sample-file)]
-    (is (= (:elevation first-point) 37.083679))))
+  (is (= (:elevation first-point) 37.083679)))

 (deftest assert-lat-first-point
-  (let [first-point (first points-from-sample-file)]
-    (is (= (:lat first-point) 50.671865))))
+  (is (= (:lat first-point) 50.671865)))

 (deftest assert-lon-first-point
-  (let [first-point (first points-from-sample-file)]
-    (is (= (:lon first-point) 7.187874))))
+  (is (= (:lon first-point) 7.187874)))

-(comment deftest assert-heart-rate-first-point
-  (let [first-point (first points-from-sample-file)]
-    (is (= (:heart-rate first-point) 114))))
+(deftest assert-heart-rate-first-point
+  (is (= (:heart-rate first-point) 114)))

 (deftest assert-elapsed-time
   (is (= 3 (calculate-time points-from-sample-file))))

 (deftest assert-distance
   (is (= 0.008250017987846405 (calculate-distance points-from-sample-file))))
+


Add missing hardcoded tweet

Add missing hardcoded tweet

--- tutorial.vent/src/tutorial/vent/lib.clj
+++ tutorial.vent/src/tutorial/vent/lib.clj
@@ -23,7 +23,7 @@
     :username "john_smith"
     :favorite? true}
    {:id 2
-    :text ""
+    :text "A second hardcoded tweet"
     :author {:name "Jane Smith"}
     :username "jane_smith"}])


use css to animate loading spinner, less cpu


added main.clj stylesheet

added main.clj stylesheet

--- src/elliot/stylesheets/main.clj
+++ src/elliot/stylesheets/main.clj
@@ -12,7 +12,8 @@
    [:.search-div {:position "relative"}]
    [:.search-div-contents {:position "absolute"
                            :bottom 0
-                           :width "60%"}]])
+                           :width "60%"}]
+   [:#daemon-img {:height "140px"}]])

 (def search-results


parser: add underscore in possible chars

--- src/io/cyanite/query/parser.clj
+++ src/io/cyanite/query/parser.clj
@@ -202,7 +202,7 @@
    <w>            = weightedavg

-   <uqpath>       = #'(?i)[a-z0-9.*-]+'
+   <uqpath>       = #'(?i)[a-z0-9.*_-]+'
    <qpath>        = <'\"'> uqpath <'\"'>
    path           = uqpath | qpath
    <func>         = a|c|d|e|g|h|i|k|l|m|n|o|p|r|s|t|u|w


CLJS-1349: cljs.build.api tests are broken due to cljs.util/to-target-file behavior

default to "cljs" extension if :source-file not provided

--- src/main/clojure/cljs/util.cljc
+++ src/main/clojure/cljs/util.cljc
@@ -80,7 +80,9 @@
   ([target-dir ns-info]
     (to-target-file target-dir ns-info "js"))
   ([target-dir {:keys [ns source-file] :as ns-info} ext]
-    (let [src-ext (cljs.util/ext source-file)
+    (let [src-ext (if source-file
+                    (cljs.util/ext source-file)
+                    "cljs")
           ns      (if (or (= src-ext "clj")
                           (and (= ns 'cljs.core) (= src-ext "cljc")))
                     (symbol (str ns "$macros"))


[scamp] Remove deprecated pre/post conditions

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -226,9 +226,6 @@
   [logging-config
    {:keys [downstream] :as node} :- NetworkedNodeSchema
    subscriber-contact-address :- NodeContactAddressSchema]
-  ;; TODO: use clojure.spec
-  {:pre [(string? subscriber-contact-address)]
-   :post [(vector? %) (-> % first map?) (-> % second vector?)]}
   (timbre/log* logging-config :trace
                :handle-forwarded-subscription
                :node node


Reflect latest wboss changes

Reflect latest wboss changes

--- modules/web/src/immutant/web.clj
+++ modules/web/src/immutant/web.clj
@@ -26,7 +26,7 @@
   (:import org.projectodd.wunderboss.WunderBoss))

 (defn server
-  "Create a server; defaults for :name, :host, :port"
+  "Create an HTTP server"
   [& {:as opts}]
   (WunderBoss/findOrCreateComponent "web"
     (stringify-keys
@@ -37,20 +37,16 @@
   "Mount a Ring handler at a context path on a server"
   ([server handler] (mount-handler server handler "/"))
   ([server handler context-path]
-     (.registerHttpHandler server context-path
+     (.registerHandler server context-path
        (undertow/create-http-handler handler)
        ;; options
        nil)))

-(defn unmount-handler
-  [server context-path]
-  (.unregisterHttpHandler server context-path))
-
 (defn mount-servlet [])

-(defn unmount-servlet
+(defn unmount
   [server context-path]
-  (.unregisterServlet server context-path))
+  (.unregister server context-path))

 (defn run
   "Creates a server, mounts the handler at root context and runs it"


Work around Leiningen issue 1099

Work around Leiningen issue 1099

--- metrics-clojure-core/project.clj
+++ metrics-clojure-core/project.clj
@@ -14,5 +14,5 @@
                :1.4    {:dependencies [[org.clojure/clojure "1.4.0"]]}
                :1.6    {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}
                :master {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}}
-  :aliases  {"all" ["with-profile" "dev:dev,1.3:dev,1.4:dev,1.6:dev,master"]}
+  :aliases  {"all" ["with-profile" "+dev:+1.3:+1.4:+1.6:+master"]}
   :warn-on-reflection true)


Explicitly load analysis cache

Explicitly load analysis cache

Fixes #491

--- planck-cljs/src/planck/repl.cljs
+++ planck-cljs/src/planck/repl.cljs
@@ -734,6 +734,8 @@
   [name path macros cache-prefix source source-modified raw-load]
   (let [path (cond-> path
                macros (add-suffix "$macros"))
+        aname (cond-> name
+                macros ana/macro-ns-name)
         cache-prefix (if (= :calculate-cache-prefix cache-prefix)
                        (cache-prefix-for-path (second (extract-cache-metadata-mem source)) macros)
                        cache-prefix)
@@ -753,7 +755,9 @@
           {:source     (cond-> js-source (not (bundled? js-modified source-modified)) strip-first-line)
            :source-url (file-url (add-suffix path ".js"))})
         (when cache-json
-          {:cache (transit-json->cljs cache-json)})))))
+          (let [cache (transit-json->cljs cache-json)]
+            (cljs/load-analysis-cache! st aname cache)
+            {:cache cache}))))))

 (declare inject-planck-eval)


Fixed typos and language

Fixed typos and language

--- src/ardoq/swagger/swagger_v2.clj
+++ src/ardoq/swagger/swagger_v2.clj
@@ -134,15 +134,15 @@
     (let [model (common/find-or-create-model client "Swagger 2.0")
           _ (socket-send (str "Created Swagger2 mode\nStarting on workspace"))
           workspace (create-workspace client model wsname spec)
-          _ (socket-send (str "Created workspace " (:name workspace) "\nGonna create " (count (:paths spec)) " defitinitions"))
+          _ (socket-send (str "Created workspace " (:name workspace) "\nAbout to create " (count (:paths spec)) " definitions"))
           defs (create-defs client model spec workspace)
-          _ (socket-send (str "Created " (count defs) " definitions\nGonna create " (count (:parameters spec)) " parameters"))
+          _ (socket-send (str "Created " (count defs) " definitions\nAbout to create " (count (:parameters spec)) " parameters"))
           params (create-params client model spec workspace)
-          _ (socket-send (str "Created " (count params) " parameters\nGonna create " (count (:securityDefinitions spec)) " security definitions"))
+          _ (socket-send (str "Created " (count params) " parameters\nAbout to create " (count (:securityDefinitions spec)) " security definitions"))
           secur (create-security-defs client model spec workspace)
-          _ (socket-send (str "Created " (count secur) " security definitions\nGonna create " (count (:tags spec)) " tags"))
+          _ (socket-send (str "Created " (count secur) " security definitions\nAbout to create " (count (:tags spec)) " tags"))
           tags-cache (atom (create-tags client spec (:_id workspace)))]
-      (socket-send (str "Created " (count @tags-cache) " tags\nGonna create " (count (:path spec)) "resources"))
+      (socket-send (str "Created " (count @tags-cache) " tags\nAbout to create " (count (:path spec)) "resources"))
       (create-resource client model spec defs params secur tags-cache workspace)
       (socket-send (str "Updating tags"))
       (update-tags client @tags-cache)


Fix sell min/max logic bug

Fix sell min/max logic bug

--- src/stocks/core.clj
+++ src/stocks/core.clj
@@ -122,29 +122,31 @@
     0 (stats/mean v)))

 (defn find-closing-price*
-  [profit-fnc open-p prices]
+  [profit-fnc decision open-p prices]
   (loop [prices prices
          best open-p]
     (if (empty? prices)
       nil
       (let [head (first prices)]
         (cond
-          (< (profit-fnc head) (- (* STOP-LOSS head)))
+          (< (profit-fnc head) (- (* STOP-LOSS open-p)))
           ; settle for a stop loss
           head
-          (and (> (profit-fnc head) (* TAKE-PROFIT open-p))
-               (< (+ head (* STOP-LOSS best)) best))
+          (and (> (profit-fnc head) (* TAKE-PROFIT open-p)))
           ; surpass the take-profit mark
           head
           :else
           (recur (next prices)
-                 (max head best)))))))
+                 (if (= "SELL" decision)
+                   (min head best)
+                   (max head best))))))))

 (defn find-closing-price
   [decision open-p prices]
   (find-closing-price* (if (= "SELL" decision)
                          #(- open-p %)
                          #(- % open-p))
+                       decision
                        open-p
                        prices))

@@ -165,8 +167,8 @@
                      res)
               :else
               (let [current-seq (first flat-seq)
-                    updated-timestamps (remove-until #(= % (-> flat-seq second
-                                                               first first))
+                    updated-timestamps (remove-until #(= % (-> current-seq
+                                                               last first))
                                                      timestamps)
                     updated-closing (drop (- (count timestamps)
                                              (count updated-timestamps))


added devdocs.io links for !js !css !html

--- src/xebang/apps.clj
+++ src/xebang/apps.clj
@@ -13,4 +13,8 @@
        :else (.replace "https://duckduckgo.com/?q={{{s}}}" "{{{s}}}" raw-query))))

 (def catalog
-  {'!weather "http://www.weather.com/weather/hourbyhour/graph/{{{s}}}"})+  {'!weather "http://www.weather.com/weather/hourbyhour/graph/{{{s}}}"
+   '!devdocs "http://devdocs.io/#q={{{s}}}"
+   '!js      "http://devdocs.io/#q=js {{{s}}}"
+   '!css     "http://devdocs.io/#q=css {{{s}}}"
+   '!html    "http://devdocs.io/#q=html {{{s}}}"})


Revert "CMR-1799: Removed unsused index set mappings"

This reverts commit d3e44729d68fe1a64c1c5d6c6de11548f6ced784.

--- indexer-app/src/cmr/indexer/data/index_set.clj
+++ indexer-app/src/cmr/indexer/data/index_set.clj
@@ -246,12 +246,19 @@
                                     ;; nested document. However the counts that come back are counts
                                     ;; of the nested documents. We want counts of collections for each
                                     ;; value so we must also capture the values at the parent level.
+                                    :category string-field-mapping
                                     :category.lowercase string-field-mapping
+                                    :topic string-field-mapping
                                     :topic.lowercase string-field-mapping
+                                    :term string-field-mapping
                                     :term.lowercase string-field-mapping
+                                    :variable-level-1 string-field-mapping
                                     :variable-level-1.lowercase string-field-mapping
+                                    :variable-level-2 string-field-mapping
                                     :variable-level-2.lowercase string-field-mapping
+                                    :variable-level-3 string-field-mapping
                                     :variable-level-3.lowercase string-field-mapping
+                                    :detailed-variable string-field-mapping
                                     :detailed-variable.lowercase string-field-mapping

                                     ;; mappings added for atom


Add lazy map implementation

Add lazy map implementation

--- cortex/src/cortex/util.cljc
+++ cortex/src/cortex/util.cljc
@@ -8,7 +8,8 @@
     #?(:cljs [goog.string :refer [format]]))

   #?(:clj (:import [mikera.vectorz Vectorz]))
-  #?(:clj (:import [java.util Random])))
+  #?(:clj (:import [java.io Writer]
+                   [java.util Random])))

 #?(:clj (do (set! *warn-on-reflection* true)
             (set! *unchecked-math* :warn-on-boxed)))
@@ -127,6 +128,128 @@
                (assoc m k (f v)))
              {}
              map))
+
+(defn map-entry
+  [k v]
+  (clojure.lang.MapEntry/create k v))
+
+;;;; Lazy maps
+
+;;; Inspired by https://github.com/Malabarba/lazy-map-clojure
+;;; but makes a few improvements, like having the seq not return
+;;; map entries with Delays still in them, supporting reduce-kv,
+;;; and having a prettier str representation.
+(deftype LazyMap [^clojure.lang.IPersistentMap contents]
+  clojure.lang.Associative
+  (containsKey [this k]
+    (.containsKey contents k))
+  (entryAt [this k]
+    (map-entry k (.valAt this k)))
+
+  clojure.lang.IFn
+  (invoke [this k]
+    (.valAt this k))
+  (invoke [this k not-found]
+    (.valAt this k not-found))
+
+  clojure.lang.IKVReduce
+  (kvreduce [this f init]
+    (reduce-kv (map-vals force contents) f init))
+
+  clojure.lang.ILookup
+  (valAt [this k]
+    (force (.valAt contents k)))
+  (valAt [this k not-found]
+    ;; This will not behave properly if not-found is a Delay,
+    ;; but that's a pretty obscure edge case.
+    (force (.valAt contents k not-found)))
+
+  clojure.lang.IMapIterable
+  (keyIterator [this]
+    (.iterator
+      ^java.lang.Iterable
+      (keys contents)))
+  (valIterator [this]
+    (.iterator
+      ;; Using the higher-arity form of map prevents chunking.
+      ^java.lang.Iterable
+      (map (fn [[k v] _]
+             (force v))
+           contents
+           (repeat nil))))
+
+  clojure.lang.IPersistentCollection
+  (count [this]
+    (.count contents))
+  (empty [this]
+    (.empty contents))
+  (cons [this o]
+    (LazyMap. (.cons contents o)))
+
+  clojure.lang.IPersistentMap
+  (assoc [this key val]
+    (LazyMap. (.assoc contents key val)))
+  (without [this key]
+    (LazyMap. (.without contents key)))
+
+  clojure.lang.Seqable
+  (seq [this]
+    ;; Using the higher-arity form of map prevents chunking.
+    (map (fn [[k v] _]
+           (map-entry k (force v)))
+         contents
+         (repeat nil)))
+
+  java.lang.Iterable
+  (iterator [this]
+    (.iterator
+      ^java.lang.Iterable
+      (.seq this))))
+
+(defrecord PlaceholderText [text])
+
+(defmethod print-dup PlaceholderText
+  [placeholder ^Writer writer]
+  (.write writer ^String (:text placeholder)))
+
+(defmethod print-method PlaceholderText
+  [placeholder ^Writer writer]
+  (.write writer ^String (:text placeholder)))
+
+(defn lazy-map->str
+  ^String [^LazyMap m]
+  (str (map-vals #(if (and (delay? %)
+                           (not (realized? %)))
+                    (->PlaceholderText "<unrealized>")
+                    (force %))
+                 (.contents m))))
+
+(defmethod print-dup LazyMap
+  [m ^Writer writer]
+  (.write writer (lazy-map->str m)))
+
+(defmethod print-method LazyMap
+  [m ^Writer writer]
+  (.write writer (lazy-map->str m)))
+
+(defn ->lazy-map
+  [map]
+  (if (instance? LazyMap map)
+    map
+    (LazyMap. map)))
+
+(defmacro lazy-map
+  [& forms]
+  `(->lazy-map
+     ~(->> forms
+        (partition 2)
+        (map (fn [[k v]] [k `(delay ~v)]))
+        (into {}))))
+
+(defn force-map
+  "Realizes all the values in a lazy map, returning a regular map."
+  [m]
+  (into {} m))

 ;;;; Arrays and matrices


Disambiguate environment var from env

Disambiguate environment var from env

env-vars are gotten with magic parameters, and the env is where resolved
keys live.

--- src/aero/core.cljc
+++ src/aero/core.cljc
@@ -31,19 +31,19 @@
     :else
     (throw (ex-info (#?(:clj format :cljs gstring/format) "No reader for tag %s" tag) {:tag tag :value value}))))

-(defn- env [s]
+(defn- get-env [s]
   #?(:clj (System/getenv (str s)))
   #?(:cljs (gobj/get js/process.env s)))

 (defmethod reader 'env
   [opts tag value]
-  (env value))
+  (get-env value))

 (defmethod reader 'envf
   [opts tag value]
   (let [[fmt & args] value]
     (apply #?(:clj format :cljs gstring/format) fmt
-           (map #(str (env (str %))) args))))
+           (map #(str (get-env (str %))) args))))

 (defmethod reader 'prop
    [opts tag value]
@@ -339,7 +339,7 @@

 (defmethod eval-tagged-literal 'user
   [tl {:keys [user] :as opts} env ks]
-  (expand-case (or user (aero.core/env "USER"))
+  (expand-case (or user (get-env "USER"))
                tl opts env ks))

 (defmethod eval-tagged-literal 'or


GR - #2 Keywordise keys using Cheshire, not walk

--- src/d_cent/api.clj
+++ src/d_cent/api.clj
@@ -1,8 +1,7 @@
 (ns d-cent.api
   (:require [org.httpkit.client :as http]
             [d-cent.utils :as utils]
-            [cheshire.core :as json]
-            [clojure.walk :as walk]))
+            [cheshire.core :as json]))

 (def api-failure nil)

@@ -10,5 +9,5 @@
   (let [{:keys [body status]} @(http/post (str utils/host-url "/api/v1/users")
                                 {:headers {"Content-Type" "application/json"}
                                  :body (json/generate-string user-profile)})]
-    (cond (= status 201)   (walk/keywordize-keys (json/parse-string body))
+    (cond (= status 201)   (json/parse-string body true)
           :else            api-failure)))


Reorganizing the source coude on the dalap.html ns


Intermediate commit for implementing thread stats.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -18,14 +18,37 @@
     dsbdp.local-data-processing-pipeline)
   (:import
     (dsbdp Counter ProcessingLoop)
+    (java.lang.management ManagementFactory ThreadInfo ThreadMXBean)
     (java.util HashMap Map))
   (:gen-class))

+(defn create-thread-info-fn
+  []
+  (let [tmxb (ManagementFactory/getThreadMXBean)
+        delta-cntr (delta-counter)]
+;    (println (.isThreadCpuTimeSupported tmxb))
+;    (println (.isThreadContentionMonitoringSupported tmxb))
+    (.setThreadContentionMonitoringEnabled tmxb true)
+    (fn []
+      (let [t-ids (vec (.getAllThreadIds tmxb))]
+        (doseq [t-id t-ids]
+          (let [t-info (.getThreadInfo tmxb t-id)
+                t-name (.getThreadName t-info)
+                waited (.getWaitedTime t-info)
+                blocked (.getBlockedTime t-info)
+                kw-w (keyword (str "waited" t-id))]
+            (print kw-w)
+            (println (str t-name "," waited "," blocked ","
+                          (delta-cntr kw-w waited) ","
+                          (delta-cntr (keyword t-name) blocked)))))))))
+
+
 (defn -main [& args]
   (println "Starting dsbdp main...")
+  (.setName (Thread/currentThread) "Main")
   (let [in-cntr (Counter.)
         out-cntr (Counter.)
-        no-op true
+        no-op false
         delta-cntr (delta-counter)
         stats-fn (fn []
                    (println
@@ -43,14 +66,14 @@
                      out-fn))
         in-fn (if (not (nil? pipeline))
                 (get-in-fn pipeline))
-        in-loop (if (not (nil? in-fn))
-                  (ProcessingLoop.
+        in-loop (ProcessingLoop.
+                  "InLoop"
+                  (if (not (nil? in-fn))
                     (fn []
                       (in-fn in-data)
-                      (.inc in-cntr)))
-                  (ProcessingLoop.
+                      (.inc in-cntr))
                     (fn []
                       (.inc in-cntr))))]
     (.start in-loop)
-    (run-repeat (executor) stats-fn 1000)))
+    (run-repeat (executor) (fn [] (stats-fn) ((create-thread-info-fn)) (println)) 1000)))


add missing language-keyword

add missing language-keyword

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -762,6 +762,8 @@
                    (map #(keyword (get-in % [:rule])) grammar)
                    grammar)

+     :language-keyword :english
+
      :morph-walk-tree (fn [tree]
                         (do
                           (merge tree


+uses of masculine-noun and feminine-noun

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -9,7 +9,9 @@
                               animal
                               common-noun
                               countable-noun
+                              feminine-noun
                               intransitivize
+                              masculine-noun
                               subject-verb-agreement
                               transitivize]]
    [dag_unify.core :refer [fail? get-in merge strip-refs]]))
@@ -20,6 +22,14 @@

 (def lexicon-source
   {
+
+   "_"
+   (unify agreement-noun
+          common-noun
+          feminine-noun
+          countable-noun
+          {:synsem {:sem {:pred :blank}}})
+
    "Antonia"
    {:synsem {:sem {:pred :antonia
                    :human true}
@@ -502,6 +512,15 @@
       :english {:participle "falling asleep"
                 :present {:3sing "falls asleep"}
                 :past "fell asleep"}})
+
+   "father"
+   (unify agreement-noun
+          common-noun
+          countable-noun
+          masculine-noun
+          {:synsem {:sem {:human true
+                          :pred :father
+                          :child false}}})

    "finish" {:synsem {:cat :verb
                       :sem {:pred :finish}}}
@@ -1070,6 +1089,7 @@
    (unify agreement-noun
           common-noun
           countable-noun
+          feminine-noun
           {:synsem {:sem {:human true
                           :pred :madre
                           :child false}}})
@@ -1631,6 +1651,7 @@
    (unify agreement-noun
           common-noun
           countable-noun
+          feminine-noun
           {:english {:plur "women"}
            :synsem {:sem {:human true
                           :pred :donna


added remain1 and remain2

added remain1 and remain2

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1230,9 +1230,18 @@
                           :physical-object true
                           :human false}}})

- "remain" {:synsem {:cat :verb
-                      :sem {:pred :remain}}}
-
+ "remain" [{:synsem {:cat :verb
+                      :sem {:pred :remain}}} ;; for other than italian
+
+          ;; these two below are for Italian.
+
+           {:english {:note {:it "ri"}}
+            :synsem {:cat :verb
+                      :sem {:pred :remain1}}}
+          {:english {:note {:it "re"}}
+            :synsem {:cat :verb
+                      :sem {:pred :remain2}}}
+]

    "remember"  {:synsem {:cat :verb
                          :sem {:pred :ricordare}}}


add TODO

add TODO

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1613,6 +1613,7 @@
    "warn" {:synsem {:cat :verb
                      :sem {:pred :warn}}}

+   ;; TODO: rename {:pred :wash} to {:pred :wash-oneself} and add non-reflexive "wash" with {:pred :wash}.
    "wash" (let [subject-semantics (atom :top)]
             {:synsem {:cat :verb
                       :sem {:pred :wash


intransitivize some verbs

intransitivize some verbs

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -417,7 +417,8 @@
                       :sem {:pred :coffee}}}

    "come" {:synsem {:cat :verb
-                    :sem {:pred :come}}
+                    :sem {:pred :come}
+                    :subcat {:2 '()}}
            :english {:past "came"}}

    "comment" {:synsem {:cat :verb
@@ -548,7 +549,8 @@
                       :sem {:pred :escape}}}

    "exist" {:synsem {:cat :verb
-                     :sem {:pred :exist}}}
+                     :sem {:pred :exist}
+                     :subcat {:2 '()}}}

    "exit" {:synsem {:cat :verb
                      :sem {:pred :exit}}}
@@ -792,10 +794,11 @@
                 :past "had fun"}})

    "have lunch" {:synsem {:cat :verb
-                            :sem {:pred :have-lunch}}
-                   :english {:present {:3sing "has lunch"}
-                             :past "had lunch"
-                             :participle "having lunch"}}
+                          :sem {:pred :have-lunch}
+                          :subcat {:2 '()}}
+                 :english {:present {:3sing "has lunch"}
+                           :past "had lunch"
+                           :participle "having lunch"}}

    "have to" {:synsem {:cat :verb
                        :sem {:pred :have-to}}


Change unit/unit-per-m and its friends

Change unit/unit-per-m and its friends

--- src/bakyeono/litedocx/unit.clj
+++ src/bakyeono/litedocx/unit.clj
@@ -10,6 +10,12 @@
   (into {}
     (for [[k v] m]
       [k (/ 1 (k m))])))
+
+(defconst flat-unit-per-m
+  {:cm       100
+   :km       1/1000
+   :m        1
+   :mm       1000})

 (defconst unit-per-inch
   {:cm       2.54
@@ -26,21 +32,15 @@
 (defconst inch-per-unit (reverse-conversion-map unit-per-inch))

 (defconst unit-per-m
-  {:cm       100
-   :dxa      (* (:m inch-per-unit) (inch-per-unit :dxa))
-   :emu      (* (:m inch-per-unit) (inch-per-unit :emu))
-   :inch     (:m inch-per-unit)
-   :km       1/1000
-   :m        1
-   :mm       1000
-   :pt       (* (:m inch-per-unit) (inch-per-unit :pt))
-   :px       (* (:m inch-per-unit) (inch-per-unit :px))
-   :twip     (* (:m inch-per-unit) (inch-per-unit :twip))})
+  (into (into {} (for [k (keys unit-per-inch)]
+                   [k (* (inch-per-unit :m)
+                         (k unit-per-inch))]))
+        flat-unit-per-m))

 (defconst m-per-unit (reverse-conversion-map unit-per-m))

 ;;; Conversion rate map selector
-(defconst metric-set #{:cm :km :m :mm})
+(defconst metric-set (set (keys flat-unit-per-m)))
 (defconst inch-set (clojure.set/difference (set (keys unit-per-inch))
                                            metric-set))


mark a thread read by clicking it

mark a thread read by clicking it

--- src/braid/ui/views/thread.cljs
+++ src/braid/ui/views/thread.cljs
@@ -125,6 +125,9 @@
                             (when focused? "focused")
                             (when dragging? "dragging")])

+          :on-click (fn [e]
+                      ; TODO: focus input
+                      (dispatch! :mark-thread-read (thread :id)))
           :on-focus
           (fn [e]
             (set-focused! true))


remove debugging hard-code of contant

remove debugging hard-code of contant

--- src/chat/server/extensions.clj
+++ src/chat/server/extensions.clj
@@ -15,7 +15,7 @@
    :body (pr-str clj-body)
    :status (or status 200)})

-(def redirect-uri (str "https://chat.leanpixel.com" #_(env :site-url) "/extension/oauth"))
+(def redirect-uri (str (env :site-url) "/extension/oauth"))
 (def webhook-uri (str (env :site-url) "/extension/webhook"))

 (defmulti handle-oauth-token (fn [ext state code] (get-in ext [:config :type])))


compiler exception fix

compiler exception fix

--- src/clinvar_submitter/form.clj
+++ src/clinvar_submitter/form.clj
@@ -142,8 +142,10 @@
   (let [can-allele (ld1-> sym-tbl interp-input "is_about_allele")
         b38-ctx-allele (ld1-> sym-tbl can-allele "related contextual allele" (prop= sym-tbl "GRCh38" "reference genome build" "label"))
         pref-ctx-allele (ld1-> sym-tbl can-allele "related contextual allele" (prop= sym-tbl true "preferred"))
+        b37-ctx-allele (ld1-> sym-tbl can-allele "related contextual allele" (prop= sym-tbl "GRCh37" "reference genome build" "label"))
         b38-hgvs (ld1-> sym-tbl b38-ctx-allele "allele name" (prop= sym-tbl "hgvs" "name type") "name")
         pref-hgvs (ld1-> sym-tbl pref-ctx-allele "allele name" (prop= sym-tbl "hgvs" "name type") "name")
+        b37-hgvs (ld1-> sym-tbl b37-ctx-allele "allele name" (prop= sym-tbl "hgvs" "name type") "name")
         [refseq hgvs] (if-not (nil? b38-hgvs)
                         (str/split b38-hgvs #":")
                         (if-not (nil? pref-hgvs)


:monkey_face::wrench::coffee::wrench::monkey_face:

--- src/clj/mokkameister/train.clj
+++ src/clj/mokkameister/train.clj
@@ -15,6 +15,7 @@
                               :sparkles 2
                               :sweat_drops 2
                               :exclamation 1
+                              :runner 1
                               :rainbow 1})

 (def ^:private num-wagons 7)
@@ -67,6 +68,12 @@
    (train-coffee :battery)
    (train-coffee :bomb)
    (train-coffee :verynice)
+   (train-coffee :zap)
+   (train-coffee :cake)
+   (train-coffee :notes)
+   (train-coffee :fuelpump)
+   (train-coffee :alarm_clock)
+   (train-coffee :monkey_face :wrench)
    (train-coffee :heavy_heart_exclamation_mark_ornament)
    (train-coffee :badger :mushroom)
    (train-coffee :coffeepot :heart)


Start adding taxes.

Start adding taxes.

--- src/cljs/beatha/automaton.cljs
+++ src/cljs/beatha/automaton.cljs
@@ -194,8 +194,11 @@
     (nth (keys m) (count (take-while #(<= % r) w)))))

 (def market-model
-  (let [env (atom {:prices
+  (let [env (atom {:tax-rate 0.05
+                   :prices
                    {:corp-1 10 :corp-2 10 :corp-3 10 :corp-4 10}
+                   :capital
+                   {:corp-1 0 :corp-2 0 :corp-3 0 :corp-4 0 :government 0}
                    :depreciation 0.03
                    :utility-params
                    {:a 1 :p -1}
@@ -249,7 +252,8 @@
           (transition
            this grid :without-good
            (fn [this width height cells x y]
-             (let [env @env
+             (let [env-atom env
+                   env @env
                    get-cell (partial get-cell this cells)
                    n-states
                    (ordered-neighbour-states get-cell width height x y)
@@ -261,6 +265,15 @@
                    cell (get-cell [x y])
                    s (:state cell)
                    without-good? (fn [s] (= :without-good s))]
+               (when-not (without-good? s)
+                 (let [price (get-in env [:prices s] 0)
+                       tax (* price (get env :tax-rate 0))
+                       income (- price tax)]
+                   (swap! env-atom
+                          (fn [e]
+                            (-> e
+                                (update-in [:capital s] + income)
+                                (update-in [:capital :government] + tax))))))
                {[x y]
                 {:state
                  (cond


multi-chunk text editing basically works

--- src/cljs/greffe/doc_comps.cljs
+++ src/cljs/greffe/doc_comps.cljs
@@ -131,10 +131,12 @@
                                     (om/transact! elem
                                       (fn [el]
                                         (if-let [new-el
-                                                 (gm/parse-gmark-text
-                                                   new-val
-                                                   mk/inner-tokens
-                                                   (assoc el :content []))]
+                                                 (if (is-multi? el)
+                                                   (gm/parse-gmark-multi-text new-val tei el)
+                                                   (gm/parse-gmark-text
+                                                     new-val
+                                                     mk/inner-tokens
+                                                     (assoc el :content [])))]
                                           new-el
                                           el)))))}))


Style.

Style.

--- src/cljs/town_client/data.cljs
+++ src/cljs/town_client/data.cljs
@@ -34,9 +34,8 @@
                         (if (not-empty path-elements)
                           (clojure.string/join "/" path-elements))
                         (if (not-empty real-params)
-                          "?"))
-        url (str url-string (map->query real-params))]
-    url))
+                          "?"))]
+    (str url-string (map->query real-params))))

 (defn get-data [type params path-elements callback]
   (.send goog.net.XhrIo


add new isSearch var and remove userdata require

--- src/cljs/traveler/ng/core.cljs
+++ src/cljs/traveler/ng/core.cljs
@@ -1,5 +1,4 @@
 (ns traveler.ng.core
-  (:require [traveler.ng.userdata :refer [userdata]])
   (:use-macros [purnam.core :only [!]]
                [gyr.core :only [def.module def.controller def.directive]]))

@@ -18,7 +17,8 @@
   (! $scope.usersPerPage 10)

   ;;don't modify these values
-  (! $scope.showPaging true)
+  (! $scope.showPaging false)
+  (! $scope.isSearch false)
   (! $scope.filteredUsers (array))
   (! $scope.pagedUsers (array))
   (! $scope.currentPage 1)
@@ -47,6 +47,7 @@
                        ($scope.loadUsers)
                        (do
                          (! $scope.usersLoaded "loading")
+                         (! $scope.isSearch true)
                          (! $scope.showPaging false)
                          (-> $http
                              (.get (str "/api/user/search/" $scope.query))
@@ -114,6 +115,7 @@
                             (* $scope.usersPerPage $scope.currentPage)))))

   (! $scope.loadUsers (fn []
+                        (! $scope.isSearch false)
                         (! $scope.usersLoaded "loading")
                         (-> $http
                             (.get (str "/api/users/" $scope.usersPerPage "/" $scope.currentPage))


Fixed null exception by adding key-size to default session key

--- src/compojure/http/session.clj
+++ src/compojure/http/session.clj
@@ -75,7 +75,7 @@
 ;; Cookie sessions

 (def default-session-key
-  (delay (gen-secret-key)))
+  (delay (gen-secret-key {:key-size 128})))

 (defn- get-session-key
   "Get the session key from the repository or use the default key."


Add some comments

Add some comments

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -139,6 +139,7 @@
         ;; and redirect to the index
         (response/redirect-after-post "/")))))

+;; catalog
 (defn catalog [request & error]
   (let [identity (friend/identity request)]
     (layout/common identity
@@ -226,6 +227,7 @@
   (-> (response/redirect-after-post "/")
       (assoc :flash {:message "Production has been deleted"})))

+;; bulk import from vubis
 (defn production-bulk-import-form [request & [errors]]
   (let [identity (friend/identity request)]
     (layout/common identity


Minor spelling fixes

Minor spelling fixes

--- src/leiningen/new/figwheel.clj
+++ src/leiningen/new/figwheel.clj
@@ -19,19 +19,19 @@
 (defn clean-opts
   "Takes the incoming options and compares them to the valid ones.
    It aborts the process and spits an error if an invalid option is present
-   or both --om and --reagent where selected."
+   or both --om and --reagent were selected."
   [valid-options opts]
   (let [valid-opts (map (partial str "--") valid-options)]
     (doseq [opt opts]
       (if-not (some #{opt} valid-opts)
         (apply main/abort "Unrecognized option:" opt ". Should be one of" valid-opts)))
     (if (and (om? opts) (reagent? opts))
-      (main/abort "Both --om and --reagent where selected. Please choose one")
+      (main/abort "Both --om and --reagent were selected. Please choose one")
       valid-opts)))

 (defn figwheel
   "Takes a name and options with the form --option and produces an interactive
-   ClojureScript + Fighweel template.
+   ClojureScript + Figwheel template.
    The valid options are:
      --om      which adds a minimal Om application in core.cljs
      --reagent which adds a minimal Reagent application in core.cljs


remove unused key from destructure in index view

--- src/mars_ogler/views/index.clj
+++ src/mars_ogler/views/index.clj
@@ -49,8 +49,7 @@
       w [:span.x " x "] h " " type " | ID: " [:a {:href (pic->href pic)} id]]]))

 (defn pic->grid-hiccup
-  [{:keys [acquired-stamp cam-name id sol taken-marstime released-stamp
-           thumbnail-url url]
+  [{:keys [acquired-stamp cam-name id sol taken-marstime thumbnail-url url]
     :as pic}
    visit-last]
   (let [new? (> acquired-stamp visit-last)


When deleting an entry check if we are removing the last draft of a draft board, if so remove also the board itself and notify it.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -185,6 +185,17 @@
             entry (:existing-entry ctx)
             _delete-result (entry-res/delete-entry! conn (:uuid entry))]
     (do
+      ;; If deleting a draft on a draft board
+      (when (and (= (keyword (:status entry)) :draft) (:draft board))
+        ;; check how many entries the section still have
+        (let [remaining-entries (entry-res/list-all-entries-by-board conn (:uuid board))]
+          ;; if we are deleting the last draft
+          (when (zero? (count remaining-entries))
+            (timbre/info "Deleting board:" (:uuid board) "because last draft was removed.")
+            ;; Remove also the board
+            (board-res/delete-board! conn (:uuid board) remaining-entries)
+            (timbre/info "Deleted board:" (:uuid board))
+            (notification/send-trigger! (notification/->trigger :delete org {:old board} (:user ctx))))))
       (timbre/info "Deleted entry for:" entry-for)
       (notification/send-trigger! (notification/->trigger :delete org board {:old entry} (:user ctx) nil))
       true)


Added mod-out to consensus comments in update graph

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -299,9 +299,9 @@
                     (-> (conv-repness rating-mat group-clusters base-clusters)
                         (select-rep-comments (:mod-out conv))))

-      :consensus  (plmb/fnk [rating-mat]
-                    (->> (consensus-stats rating-mat)
-                         (select-consensus-comments)))
+      :consensus  (plmb/fnk [conv rating-mat]
+                    (-> (consensus-stats rating-mat)
+                        (select-consensus-comments (:mod-out conv))))

      ; End of large-update
      }))


Simplify prop-name handling a little

Simplify prop-name handling a little

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -13,10 +13,6 @@
              from a tag name."}
   re-tag #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?")

-(def attr-aliases {:class "className"
-                   :for "htmlFor"
-                   :charset "charSet"})
-

 ;;; Common utilities

@@ -37,14 +33,12 @@
    (ifn? v) (fn [& args] (apply v args))
    :else v))

-(defn undash-prop-name [n]
-  (or (attr-aliases n)
-      (util/dash-to-camel n)))
-

 ;;; Props conversion

-(def prop-name-cache #js{})
+(def prop-name-cache #js{:class "className"
+                         :for "htmlFor"
+                         :charset "charSet"})

 (defn obj-get [o k]
   (when (.hasOwnProperty o k)
@@ -56,7 +50,8 @@
     x
     (if-let [s (obj-get prop-name-cache (name x))]
       s
-      (aset prop-name-cache (name x) (undash-prop-name x)))))
+      (aset prop-name-cache (name x)
+            (util/dash-to-camel x)))))

 (defn convert-prop-value [x]
   (cond (string? x) x
@@ -69,7 +64,7 @@
         :else (to-js-val x)))

 (defn set-id-class [props id-class]
-  (when-some [id (.' id-class :idName)]
+  (when-some [id (.' id-class :id)]
     (let [pid (.' props :id)]
       (.! props :id (if (some? pid) pid id))))
   (when-some [class (.' id-class :className)]
@@ -162,7 +157,7 @@
     (assert tag (str "Unknown tag: '" hiccup-tag "'"))
     #js{:name tag
         :hasIdClass (or (some? id) (some? class'))
-        :idName id
+        :id id
         :className class'}))

 (defn fn-to-class [f]


Fix multimethods with newer ClojureScript

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -16,8 +16,13 @@

 ;;; Common utilities

+(defn named? [x]
+  (or (keyword? x)
+      (symbol? x)))
+
 (defn hiccup-tag? [x]
-  (or (implements? INamed x)
+  (or (keyword? x)
+      (symbol? x)
       (string? x)))

 (defn valid-tag? [x]
@@ -36,7 +41,7 @@
     (aget o k)))

 (defn cached-prop-name [k]
-  (if-not (implements? INamed k)
+  (if-not (named? k)
     k
     (if-let [k' (obj-get prop-name-cache (name k))]
       k'
@@ -45,7 +50,7 @@

 (defn convert-prop-value [x]
   (cond (or (string? x) (number? x) (fn? x)) x
-        (implements? INamed x) (name x)
+        (named? x) (name x)
         (map? x) (reduce-kv (fn [o k v]
                               (doto o
                                 (aset (cached-prop-name k)


Remove warnings

Remove warnings

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -1,8 +1,7 @@
 (ns sierpinski-sieve.core
   (:require [reagent.core :as reagent]
             [reagent.dom :as rdom]
-            [sierpinski-sieve.macros :include-macros true :refer [forloop]]
-            [sierpinski-sieve.blit :as blit]))
+            [sierpinski-sieve.macros :include-macros true :refer [forloop]]))

 (enable-console-print!)
 (defn log [& args] (.log js/console args))
@@ -29,18 +28,17 @@
   (dotimes [x (alength row)]
     (let [disp-x (+ (* (- size y) 0.5) x)
           value (aget row x)]
-      (if (odd? value)
+      (when (odd? value)
         (.fillRect ctx disp-x y 1 1)))))

 (defn paint [canvas-id size sieve]
   (when-let [canvas-element (.getElementById js/document canvas-id)]
     (when-let [ctx (.getContext canvas-element "2d")]
-      (do
-        (set! (.-fillStyle ctx) "black")
-        (.fillRect ctx 0 0 size size)
-        (set! (.-fillStyle ctx) "white")
-        (dotimes [y size]
-          (paint-row ctx y (aget sieve y) size))))))
+      (set! (.-fillStyle ctx) "black")
+      (.fillRect ctx 0 0 size size)
+      (set! (.-fillStyle ctx) "white")
+      (dotimes [y size]
+        (paint-row ctx y (aget sieve y) size)))))

 (defn slider [name key value settings]
   [:div


Update `utils/declare-remote` to support symbol metadata

--- src/taoensso/carmine/utils.clj
+++ src/taoensso/carmine/utils.clj
@@ -3,14 +3,17 @@
   (:require [clojure.string :as str]))

 (defmacro declare-remote
-  "Declares the given ns-qualified names. Useful for circular dependencies."
+  "Declares the given ns-qualified names, preserving symbol metadata. Useful for
+  circular dependencies."
   [& names]
-  (let [orig-ns (str *ns*)]
-    `(do ~@(map (fn [n] (let [ns (namespace n)
-                             v  (name n)]
-                         `(do (in-ns '~(symbol ns))
-                              (declare ~(symbol v))))) names)
-         (in-ns '~(symbol orig-ns)))))
+  (let [original-ns (str *ns*)]
+    `(do ~@(map (fn [n]
+                  (let [ns (namespace n)
+                        v  (name n)
+                        m  (meta n)]
+                    `(do (in-ns  '~(symbol ns))
+                         (declare ~(with-meta (symbol v) m))))) names)
+         (in-ns '~(symbol original-ns)))))

 (defmacro time-ns
   "Returns number of nanoseconds it takes to execute body."


cosmetic changes

cosmetic changes

--- src/adventofcode1/twentythree.clj
+++ src/adventofcode1/twentythree.clj
@@ -81,6 +81,7 @@
   (if-let [[_ x y] (re-find (re-matcher #"^jnz (-?\d+) (-?\d+)$" cmd))]
     {:cmd :jnz-value :x (parse-int x) :y (parse-int y)}))

+;; added in 2nd puzzle
 (defn parse-jnz-value-2
   [cmd]
   (if-let [[_ x y] (re-find (re-matcher #"^jnz (-?\d+) ([a-z]+)$" cmd))]
@@ -138,7 +139,7 @@
       [cmds (inc ip) regs]
       (let
           [before (nth cmds idx)
-           after
+           after-instruction
            (match [(:cmd before)(:y before)]
              [:inc nil] :dec
              [_    nil] :inc
@@ -146,7 +147,7 @@
              [:jnz-value _] :cpy-value
              [:cpy-reg _]   :jnz-x-reg
              [:cpy-value _] :jnz-value)
-           cmds2 (assoc cmds idx (sp/setval [:cmd] after before))]
+           cmds2 (assoc cmds idx (sp/setval [:cmd] after-instruction before))]
         [cmds2 (inc ip) regs]))))

 (s/fdef maybe-deref
@@ -201,6 +202,8 @@
            (recur (inc ctr) cmds2 {:ip ip2 :regs regs2}))))))

+(clojure.spec.test/instrument)
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; sample data

@@ -273,5 +276,3 @@
 jnz d -2
 inc c
 jnz c -5")
-
-(clojure.spec.test/instrument)


compare record with array access - surely sme mistake ?

--- dada-core/src/test/clojure/org/dada/core/test_clojure.clj
+++ dada-core/src/test/clojure/org/dada/core/test_clojure.clj
@@ -10,7 +10,7 @@
   `(do
      (print (quote ~body))
      (let [start# (System/currentTimeMillis)]
-       (dotimes [_# ~times] ~body)
+       (do (dotimes [_# ~times] ~body) nil)
        (let [elapsed# (- (System/currentTimeMillis) start#)]
 	 (println ": " elapsed# " millis")
 	 elapsed#))))
@@ -47,3 +47,23 @@
 	^String p ""]
     (faster 100000000 (.v r)(.length p))))

+;; this may be needed for where we need to access a field via a function rather than a java accessor... - not much in it...
+
+(deftest test-get
+  (let [^Value v (Value. 0)] (is (faster 1000000000 ((fn [^Value v] (.v v)) v) (:v v)))))
+
+;; doseq nearly twice as fast
+
+(deftest doseq-vs-dorun-map
+  (is (faster 1 (doseq [n (range 10000000)] (identity n)) (dorun (map identity (range 10000000))))))
+
+;; seems to be true - but so close I can't rely on it not to fail build
+
+;;(deftest assoc-vs-conj
+;;  (is (faster 1 (reduce (fn [r i] (assoc r i i)) {} (range 3000000)) (reduce (fn [r i] (conj r [i i])) {} (range 3000000)))))
+
+;; surely some mistake (on my part) here - I can look up a field in a record 100o x faster than I can in an array - I expected it to be fater, but...
+(deftest record-vs-array-access
+  (let [^Value r (Value. 0)
+	^{:tag (type (into-array Object []))} a (into-array Object [0])]
+    (is (faster 1000000 (.v r) (aget a 0)))))


more ibm wierdness

more ibm wierdness

--- dada-core/src/test/clojure/org/dada/core/test_clojure.clj
+++ dada-core/src/test/clojure/org/dada/core/test_clojure.clj
@@ -71,10 +71,11 @@
 ;; surely some mistake (on my part) here - I can look up a field in a record 100o x faster than I can in an array - I expected it to be faster, but...
 ;; this is down to reflection - investigate how to use an Object array efficiently
 ;; type hint was wrong - but why ?
-(deftest record-vs-array-access
-  (let [^Value r (Value. 0)
- 	^objects a (into-array Object [0])]
-    (is (faster 1000000000 (.v r) (aget a 0)))))
+(if (not (ibm?))
+  (deftest record-vs-array-access
+    (let [^Value r (Value. 0)
+	  ^objects a (into-array Object [0])]
+      (is (faster 1000000000 (.v r) (aget a 0))))))

 ;; but accessing a record field still appears to be 10 times faster than an array - is the int being boxed on the way out ?
 (if (not (ibm?))


Forgot to bump version

Forgot to bump version

--- src/leiningen/grim.clj
+++ src/leiningen/grim.clj
@@ -5,7 +5,7 @@
   ['[org.clojure/tools.namespace "0.2.7"]
    '[org.clojure/java.classpath "0.2.2"]
    '[org.clojure-grimoire/lib-grimoire "0.1.2"]
-   '[org.clojure-grimoire/lein-grim "0.1.1"] ;; FIXME: do this better?
+   '[org.clojure-grimoire/lein-grim "0.2.0"] ;; FIXME: do this better?
    '[me.arrdem/detritus "0.2.0"]])

 (defn grim


enable the _index field for documents

enable the _index field for documents

see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-index-field.html

--- src/brainbot/nozzle/esconnect.clj
+++ src/brainbot/nozzle/esconnect.clj
@@ -34,6 +34,7 @@
   (def mapping-types
     {"doc" {:_all {:enabled false},
             :_source {:enabled true},
+            :_index {:enabled true},
             :properties
             {:parent parent
              :tags {:index "not_analyzed",


added try-catch statement to check for singular matrices

--- src/clj/forma/trends/analysis.clj
+++ src/clj/forma/trends/analysis.clj
@@ -56,7 +56,9 @@
 (defn hansen-stat
   "Returns the Hansen (1992) test statistic, based on (1) the
   first-order conditions, and (2) the cumulative first-order
-  conditions.
+  conditions. The try statement will most likely fail if `foc-mat` is
+  singular, which will occur when the hansen-stat is applied to a
+  constant timeseries.

   Example:
     (hansen-stat ndvi) => 0.9113
@@ -67,12 +69,14 @@
   [ts]
   (let [ts-mat (i/matrix ts)
         foc (first-order-conditions ts-mat)
-        foc-mat (i/mmult foc (i/trans foc))
-        final-mat (i/mult foc-mat (i/nrow ts-mat))]
-    (if-not (singular? final-mat)
+        foc-mat (i/mmult foc (i/trans foc))]
+    (try
       (let [focsum (map i/cumulative-sum foc)
             focsum-mat (i/mmult focsum (i/trans focsum))]
-        (-> (i/solve final-mat) (i/mmult focsum-mat) (i/trace))))))
+        (-> (i/solve (i/mult foc-mat (i/nrow ts-mat)))
+            (i/mmult focsum-mat)
+            (i/trace)))
+      (catch Exception e))))

 ;; Long-term trend characteristic; supporting functions


Fix doc link.

Fix doc link.

--- src/afterglow/effects/params.clj
+++ src/afterglow/effects/params.clj
@@ -320,7 +320,7 @@
   greater than `1`). This specifies what fraction of each interval is
   involved in fading to or from the next value. See the graphs in the
   Step
-  Parameters [documentation](https://github.com/brunchboy/afterglow/blob/master/doc/params.adoc#step-parameters)
+  Parameters [documentation](https://github.com/brunchboy/afterglow/blob/master/doc/parameters.adoc#step-parameters)
   for a visual illustration of how this parameter works.

   A fade fraction of `0` provides the default behavior of an instant


Wrap related keywords

Wrap related keywords

--- src/cljs/cljs_repl_web/views.cljs
+++ src/cljs/cljs_repl_web/views.cljs
@@ -233,6 +233,7 @@
               [h-box
                :size "0 0 auto"
                :gap "4px"
+               :style {:flex-flow "wrap"}
                :children (for [rel related]
                            [hyperlink-href
                             :label (utils/strip-namespace rel)


Pause examples on examples page after rendering first frame

--- src/cljs/main/quil_site/main.cljs
+++ src/cljs/main/quil_site/main.cljs
@@ -39,20 +39,10 @@
   (->> (cstr/replace name " " "-")
        (str "/sketches/show/example_")))

-(defn pause-after-next-frame [sketch]
-  (let [real-sketch (aget (aget sketch "externals") "sketch")
-        set-on-frame-end #(aset real-sketch "onFrameEnd" %)]
-    (set-on-frame-end
-     (fn []
-       (q/with-sketch sketch
-         (q/no-loop))
-       (set-on-frame-end (fn []))))))
-
 (defn should-start-paused? []
   (boolean (query-selector ".container.examples-page")))

 (defn setup-play-pause-functionality [host sketch]
-  ;; (pause-after-next-frame sketch)
   (let [play-button (query-selector host ".play")
         pause-button (query-selector host ".pause")]
     (classes/remove play-button "hidden")
@@ -66,7 +56,8 @@
                      (classes/remove pause-button "invisible")))
     (events/listen pause-button EventType/CLICK
                    (fn []
-                     (pause-after-next-frame sketch)
+                     (q/with-sketch sketch
+                       (q/no-loop))
                      (classes/remove play-button "hidden")
                      (classes/add pause-button "invisible")))))

@@ -89,9 +80,11 @@
                         (str "by " author))
     (let [sketch (run-fn (query-selector host ".canvas-container") 200)]
       (when (should-start-paused?)
+        (q/with-sketch sketch
+          (q/no-loop))
         (setup-play-pause-functionality host sketch))
-        (when white-play-button?
-          (classes/add (query-selector host ".play") "white")))))
+      (when white-play-button?
+        (classes/add (query-selector host ".play") "white")))))

 (defn register-example! [name author run-fn &
                          {:keys [interactive? display-name]


specs

specs

--- src/cljs/triboard/logic/move.cljs
+++ src/cljs/triboard/logic/move.cljs
@@ -79,12 +79,13 @@
 (defn all-available-moves
   "Return all move available on the board, grouped by player and by move"
   [board]
-  (transduce
-    (mapcat #(available-conversions-at board %))
-    #(update-in %1 [(:winner %2) (:point %2)] conj %2)
-    {}
-    (board/empty-cells board)
-    ))
+  (dissoc
+    (transduce
+      (mapcat #(available-conversions-at board %))
+      #(update-in %1 [(:winner %2) (:point %2)] conj %2)
+      {}
+      (board/empty-cells board))
+    nil))                                                   ;; TODO - find why we have nil

 (s/fdef apply-conversion
   :args (s/tuple ::board/board ::conversion)


Add missing argument

Add missing argument

--- src/clojure/nightcode/dialogs.clj
+++ src/clojure/nightcode/dialogs.clj
@@ -28,7 +28,7 @@
 (defn show-save-dialog!
   []
   (if (System/getProperty "SandboxDirectory")
-    (show-native-dialog! FileDialog/SAVE)
+    (show-native-dialog! nil FileDialog/SAVE)
     (chooser/choose-file :type :save)))

 (defn show-open-dialog!


Check for nil before installing completer

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -407,7 +407,6 @@
   []
   (let [text-area (create-text-area)
         extension "clj"
-        completer (create-completer text-area extension)
         consume-commands #{KeyEvent/VK_Z KeyEvent/VK_Y}]
     (doto text-area
       (.setSyntaxEditingStyle (get styles extension))
@@ -419,8 +418,9 @@
           (keyPressed [this e]
             (when (and @shortcuts/is-down?
                        (contains? consume-commands (.getKeyCode e)))
-              (.consume e)))))
-      (install-completer! completer))
+              (.consume e))))))
+    (when-let [completer (create-completer text-area extension)]
+      (install-completer! text-area completer))
     (JConsole. text-area)))

 (defn init-paredit!
@@ -515,7 +515,8 @@
                 :key-released
                 (fn [e] (update-buttons! text-group text-area)))
       ; install completer
-      (install-completer! text-area completer)
+      (when completer
+        (install-completer! text-area completer))
       ; enable/disable buttons while typing
       (.addDocumentListener (.getDocument text-area)
                             (reify DocumentListener


Simplify function

Simplify function

--- src/clojure/nightcode/sandbox.clj
+++ src/clojure/nightcode/sandbox.clj
@@ -26,10 +26,7 @@

 (defn set-home!
   []
-  (some->> (get-dir)
-           (io/file (System/getProperty "user.home"))
-           .getCanonicalPath
-           (System/setProperty "user.home")))
+  (some->> (get-dir) get-path (System/setProperty "user.home")))

 (defn set-temp-dir!
   []