:fire: Remove some commented code.

:fire: Remove some commented code.

--- backend/test/uxbox/tests/test_projects.clj
+++ backend/test/uxbox/tests/test_projects.clj
@@ -43,7 +43,7 @@
         (let [uri (str th/+base-url+ "/api/projects/" (:id proj))
               params {:body (assoc proj :name "proj2")}
               [status data] (th/http-put user uri params)]
-          (prn "RESPONSE:" status data)
+          ;; (prn "RESPONSE:" status data)
           (t/is (= 200 status))
           (t/is (= (:user data) (:id user)))
           (t/is (= (:name data) "proj2")))))))
@@ -55,6 +55,7 @@
       (th/with-server {:handler @http/app}
         (let [uri (str th/+base-url+ "/api/projects/" (:id proj))
               [status data] (th/http-delete user uri)]
+          ;; (prn "RESPONSE:" status data)
           (t/is (= 204 status))
           (let [sqlv ["SELECT * FROM projects WHERE \"user\"=? AND deleted_at is null"
                       (:id user)]


Fixed dsets.clj

Fixed dsets.clj

--- clojure/org/gavrog/clojure/dsets.clj
+++ clojure/org/gavrog/clojure/dsets.clj
@@ -20,7 +20,10 @@
         (if (nil? oDi)
           false
           (let [Di (or (o2n oDi) (inc n))
-                d (- Di (s ds i D))]
+                d (- Di (s ds i D))
+                free (if (<= Di n)
+                       free
+                       (into free (for [j (indices ds)] [j Di])))]
             (cond (neg? d) true
                   (pos? d) false
                   :else (recur (assoc o2n oDi Di)


[#148] Add set! and fix bug in re-matches

--- priv/clojure/core.clj
+++ priv/clojure/core.clj
@@ -1616,6 +1616,10 @@
   #_(clojerl.MultiFn/get_prefer_table.e multifn))

 ;;;;;;;;; var stuff
+
+(defn set!
+  [x val]
+  (clj_core/set!.e x val))

 (defmacro ^{:private true} assert-args
   [& pairs]
@@ -4739,8 +4743,8 @@
   [re s]
   (if (string? s)
     (let [matches (re-find re s)
-          matches (if (string? matches) matches (first matches))]
-      (when (= matches s)
+          match   (if (string? matches) matches (first matches))]
+      (when (= match s)
         (if (== (count matches) 1)
           (first matches)
           matches)))


Update phantomjs settings

Update phantomjs settings

--- src/export_server/utils/phantom.clj
+++ src/export_server/utils/phantom.clj
@@ -1,7 +1,8 @@
 (ns export-server.utils.phantom
-  (:import (org.openqa.selenium.phantomjs PhantomJSDriver)
+  (:import (org.openqa.selenium.phantomjs PhantomJSDriver PhantomJSDriverService)
            (org.openqa.selenium.remote DesiredCapabilities)
-           (org.openqa.selenium Dimension))
+           (org.openqa.selenium Dimension)
+           (java.util ArrayList))
   (:require [clj-webdriver.core :as core]
             [clj-webdriver.taxi :refer :all :as taxi]
             [clj-webdriver.driver :refer [init-driver]]
@@ -11,7 +12,13 @@
 ; PhantomJS initialization
 ;====================================================================================
 (defn- create-driver []
-  (init-driver {:webdriver (PhantomJSDriver. (DesiredCapabilities.))}))
+  (let [caps (DesiredCapabilities.)
+        cliArgsCap (ArrayList.)]
+    (.add cliArgsCap "--web-security=false")
+    (.add cliArgsCap "--ssl-protocol=any")
+    (.add cliArgsCap "--ignore-ssl-errors=true")
+    (.setCapability caps PhantomJSDriverService/PHANTOMJS_CLI_ARGS cliArgsCap)
+    (init-driver {:webdriver (PhantomJSDriver. caps)})))

 (defonce drivers (atom []))
 (defonce drivers-queue nil)


Fix deploy test.

Fix deploy test.

--- test/test_deploy.clj
+++ test/test_deploy.clj
@@ -9,7 +9,7 @@

 (deftest test-deploy
   (delete-file-recursively "/tmp/lein-repo" :silently)
-  (deploy test-project "file:///tmp/lein-repo")
+  (deploy test-project :snapshots "file:///tmp/lein-repo")
   (let [dir (file "/tmp/lein-repo/nomnomnom/nomnomnom/0.5.0-SNAPSHOT/")
         files (.list dir)
         year (+ 1900 (.getYear (java.util.Date.)))]


Favor qualified imports

Favor qualified imports

--- src/refactor_nrepl/ns/ns_parser.clj
+++ src/refactor_nrepl/ns/ns_parser.clj
@@ -12,8 +12,7 @@
    :refer-macros [referred macros here]
    :require-macros true}"
   (:require [clojure.set :as set]
-            [refactor-nrepl.ns.helpers :refer [get-ns-component prefix-form?]]
-            [refactor-nrepl.ns.helpers :refer [read-ns-form]]
+            [refactor-nrepl.ns.helpers :as helpers]
             [refactor-nrepl.util :as util])
   (:import java.io.File))

@@ -34,7 +33,7 @@
                              (rest libspec))
                            (symbol (str prefix "." libspec))))
         normalize-libspec-vector (fn [libspec]
-                                   (if (prefix-form? libspec)
+                                   (if (helpers/prefix-form? libspec)
                                      (let [prefix (first libspec)]
                                        (map (partial prepend-prefix prefix)
                                             (rest libspec)))
@@ -43,7 +42,7 @@

 (defn- use-to-refer-all [use-spec]
   (if (vector? use-spec)
-    (if (prefix-form? use-spec)
+    (if (helpers/prefix-form? use-spec)
       [(first use-spec) (map #(conj % :refer :all))]
       (conj use-spec :refer :all))
     [use-spec :refer :all]))
@@ -52,7 +51,7 @@
   "Bind the symbol libspecs to the libspecs extracted from the key in
   ns-form and execute body."
   [ns-form key & body]
-  `(let [~'libspecs (rest (get-ns-component ~ns-form ~key))]
+  `(let [~'libspecs (rest (helpers/get-ns-component ~ns-form ~key))]
      ~@body))

 (defn- extract-required-macros [libspec-vector]
@@ -85,7 +84,7 @@
                                          (symbol (str package "." class-name)))
                                        (rest import-spec)))
                                 import-spec))]
-    (some->> (get-ns-component ns-form :import)
+    (some->> (helpers/get-ns-component ns-form :import)
              rest ; drop :import
              (map expand-prefix-specs)
              flatten


cleanup

cleanup

--- solutions/day07/solution.clj
+++ solutions/day07/solution.clj
@@ -22,7 +22,6 @@
         cmd (or (first (filter commands parts)) "SET")
         operands (map make-input (remove commands parts))]
     {:fn (cmd->fn cmd)
-     :operands operands
      :target target
      :inputs (fn [circuit] (map #(% circuit) operands))}))


Update slamhound dep.

Update slamhound dep.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -4,7 +4,7 @@
                        [redl "0.1.0"]
                        [speclj-tmux "1.0.0"]
                        [spyscope "0.1.3"]
-                       [slamhound "1.3.3"]]
+                       [slamhound "1.5.0"]]
         :plugins [[lein-difftest "1.3.7"]
                   [lein-exec "0.3.0"]
                   [org.bodil/lein-noderepl "0.1.10"]


[CS] Less output at end of imports

[CS] Less output at end of imports

Now that we have the results database and Metis starting to work
locally, getting all validation errors printed out (being unbounded in
size and without even being valid edn to copy into a text editor or repl
to investigate) has outlived its usefulness. Curbs the output to the
location of the temp sqlite db, the xml file, and the import id that can
be used to find validation errors in the results db.

Cuts the final ctx from the error, as the stacktrace and initial context
are what you really want.

--- src/vip/data_processor/pipeline.clj
+++ src/vip/data_processor/pipeline.clj
@@ -47,10 +47,9 @@
              :fatal {}
              :pipeline pipeline}
         result (run-pipeline ctx)]
-    (log/info (select-keys result [:errors :warnings :critical :fatal :db :xml-output-file]))
+    (log/info (select-keys result [:import-id :db :xml-output-file]))
     (when-let [ex (:exception result)]
       (log/error (with-out-str (stacktrace/print-stack-trace ex)))
       (throw (ex-info "Exception during processing" {:exception ex
-                                                     :initial-ctx ctx
-                                                     :final-ctx result})))
+                                                     :initial-ctx ctx})))
     result))


Simplify claim tests

Simplify claim tests

Extract unsign-exp-succ to encapsulate testing signature/claims checking

--- test/buddy/sign/jws_tests.clj
+++ test/buddy/sign/jws_tests.clj
@@ -28,57 +28,57 @@
 (def ec-privkey (keys/private-key "test/_files/privkey.ecdsa.pem" "secret"))
 (def ec-pubkey (keys/public-key "test/_files/pubkey.ecdsa.pem"))

+(defn- unsign-exp-succ
+  ([signed claims]
+   (unsign-exp-succ signed claims {}))
+  ([signed claims opt]
+   (is (= (jws/unsign signed secret) (merge claims opt)))))
+
 (defn- unsign-exp-fail
-  ([signed]
-   (unsign-exp-fail signed {}))
-  ([signed opts]
+  ([signed cause]
+   (unsign-exp-fail signed {} cause))
+  ([signed opts cause]
    (try
      (jws/unsign signed secret opts)
      (throw (Exception. "unexpected"))
      (catch clojure.lang.ExceptionInfo e
-       (:cause (ex-data e))))))
+       (is (= (:cause (ex-data e)) cause))))))

 (deftest jws-decode
   (let [candidate {:foo "bar"}
-        signed (jws/encode candidate secret)
-        unsigned (jws/decode signed secret)]
-    (is (= unsigned candidate))))
+        signed (jws/encode candidate secret)]
+    (unsign-exp-succ signed candidate)))

 (deftest jws-time-claims-validation
   (testing ":exp claim validation"
     (let [candidate {:foo "bar"}
           now       (util/timestamp)
           exp       (+ now 2)
-          signed    (jws/encode candidate secret {:exp exp})
-          unsigned  (jws/decode signed secret)]
+          signed    (jws/encode candidate secret {:exp exp})]
       (Thread/sleep 3000)
-      (is (= (unsign-exp-fail signed) :exp))))
+      (unsign-exp-fail signed :exp)))

   (testing ":nbf claim validation"
     (let [candidate {:foo "bar"}
           now       (util/timestamp)
           nbf       (+ now 2)
           signed    (jws/sign candidate secret {:nbf nbf})]
-      (is (= (unsign-exp-fail signed) :nbf))
-
+      (unsign-exp-fail signed :nbf)
       (Thread/sleep 3000)
-      (let [unsigned (jws/unsign signed secret)]
-        (is (= unsigned (assoc candidate :nbf nbf)))))))
+      (unsign-exp-succ signed candidate {:nbf nbf}))))

 (deftest jws-other-claims-validation
   (testing ":iss claim validation"
     (let [candidate {:foo "bar" :iss "foo:bar"}
-          signed    (jws/sign candidate secret)
-          unsigned  (jws/unsign signed secret)]
-      (is (= unsigned candidate))
-      (is (= (unsign-exp-fail signed {:iss "bar:foo"}) :iss))))
+          signed    (jws/sign candidate secret)]
+      (unsign-exp-succ signed candidate)
+      (unsign-exp-fail signed {:iss "bar:foo"} :iss)))

   (testing ":aud claim validation"
     (let [candidate {:foo "bar" :aud "foo:bar"}
-          signed    (jws/sign candidate secret)
-          unsigned  (jws/unsign signed secret)]
-      (is (= unsigned candidate))
-      (is (= (unsign-exp-fail signed {:aud "bar:foo"}) :aud)))))
+          signed    (jws/sign candidate secret)]
+      (unsign-exp-succ signed candidate)
+      (unsign-exp-fail signed {:aud "bar:foo"} :aud))))

 (deftest jws-hs256-sign-unsign
   (let [candidate {:foo "bar"}
@@ -132,19 +132,18 @@
 (deftest jws-wrong-key
   (let [candidate {:foo "bar"}
         result    (jws/sign candidate ec-privkey {:alg :es512})]
-    (is (= (unsign-exp-fail result) :header))))
+    (unsign-exp-fail result :header)))

 (deftest wrong-data
   ;; (str "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9."
   ;;      "eyJmb28iOiJiYXIifQ."
   ;;      "FvlogSd-xDr6o2zKLNfNDbREbCf1TcQri3N7LkvRYDs")

-  (is (= (unsign-exp-fail "xyz") :signature))
+  (unsign-exp-fail "xyz" :signature)
   (let [data (str "."
                   "eyJmb28iOiJiYXIifQ."
                   "FvlogSd-xDr6o2zKLNfNDbREbCf1TcQri3N7LkvRYDs")]
-    (is (= (unsign-exp-fail data) :signature)))
+    (unsign-exp-fail data :signature))
   (let [data (str "eyJmb28iOiJiYXIifQ."
                   "FvlogSd-xDr6o2zKLNfNDbREbCf1TcQri3N7LkvRYDs")]
-    (is (= (unsign-exp-fail data) :signature))))
-
+    (unsign-exp-fail data :signature)))


adding route end to end tests

adding route end to end tests

--- test/clj/ohds/server_test.clj
+++ test/clj/ohds/server_test.clj
@@ -0,0 +1,29 @@
+(ns ohds.server-test
+  (:require
+   [ohds.server :refer :all])
+  (:use expectations))
+
+(defn request [resource app method & params]
+  (app {:request-method method :uri resource :form-params (first params)}))
+
+(expect 401 (:status (request "/api/v1/login" routes :post
+                              {"username" "fieldworker"
+                               "password" "badpassword"})))
+
+(expect 200 (:status (request "/api/v1/login" routes :post
+                              {"username" "fieldworker"
+                               "password" "password"})))
+
+(expect AssertionError (:status (request "/api/v1/login" routes :post
+                              {"username" nil
+                               "password" "badpassword"})))
+
+(expect 200 (:status (request "/api/v1/locationHierarchy" routes :get)))
+
+(expect 200 (:status (request "/api/v1/locations/1" routes :get)))
+
+(expect 200 (:status (request "/api/v1/locations/" routes :get)))
+
+(expect 201 (:status (request "/api/v1/locations" routes :post {})))
+
+(expect 201 (:status (request "/api/v1/individuals" routes :post {})))


fixed existing test

fixed existing test

--- test/tick/alpha/api_test.cljc
+++ test/tick/alpha/api_test.cljc
@@ -169,8 +169,9 @@
           (t/now)
           (t/+ (t/now) (t/new-duration 20 :seconds))
           (t/+ (t/now) (t/new-duration 10 :seconds)))))
-  (is (t/<= (t/now) (t/now) (t/+ (t/now) (t/new-duration 1 :seconds))))
-  (is (t/>= (t/now) (t/now) (t/- (t/now) (t/new-duration 10 :seconds))))
+  (let [at (t/now)]
+    (is (t/<= at at (t/+ at (t/new-duration 1 :seconds))))
+    (is (t/>= at at (t/- at (t/new-duration 10 :seconds)))))

   (testing "durations"
     (is (t/> (t/new-duration 20 :seconds) (t/new-duration 10 :seconds)))


Spanish: Adds 'quarter' cycle (#129)

Spanish: Adds 'quarter' cycle (#129)

* Spanish: Adds 'quarter' cycle

* Adding formats to show quarters

--- resources/languages/es/rules/cycles.clj
+++ resources/languages/es/rules/cycles.clj
@@ -30,6 +30,11 @@
   #"(?i)mes(es)?"
   {:dim :cycle
    :grain :month}
+
+  "trimestre (cycle)"
+  #"(?i)trimestres?"
+  {:dim :cycle
+   :grain :quarter}

   "año (cycle)"
   #"(?i)a(n|ñ)os?"
@@ -87,4 +92,15 @@
   "n <cycle> (proximo|que viene)"
   [(integer 2 9999) (dim :cycle) #"(?i)(pr(ó|o)xim(o|a)s?|que vienen?|siguientes?)"]
   (cycle-n-not-immediate  (:grain %2) (:value %1))
+
+  ; quarters are a little bit different, you can say "3rd quarter" alone
+
+  "<ordinal> quarter"
+  [(dim :ordinal) (dim :cycle #(= :quarter (:grain %)))]
+  (cycle-nth-after :quarter (dec (:value %1)) (cycle-nth :year 0))
+
+  "<ordinal> quarter <year>"
+  [(dim :ordinal) (dim :cycle #(= :quarter (:grain %))) #"(?i)del? ?" (dim :time)]
+  (cycle-nth-after :quarter (dec (:value %1)) %3)
+
 )


Remove deprecated parameter counts from tests

--- cortex/test/cljc/cortex/optimise_test.cljc
+++ cortex/test/cljc/cortex/optimise_test.cljc
@@ -32,26 +32,26 @@

 (deftest test-adadelta
   (let [m (layers/linear [[0.1 0.2] [0.3 0.4]] [0.1 0.1])
-        o (adadelta-optimiser (parameter-count m))]
+        o (adadelta-optimiser)]
     (optimiser-test m o)))

 (deftest test-sgd
   (let [m (layers/linear [[0.1 0.2] [0.3 0.4]] [0.1 0.1])
-        o (sgd-optimiser (parameter-count m))]
+        o (sgd-optimiser)]
     (optimiser-test m o)))

 (deftest test-nn
   (let [m (stack-module
             [(layers/linear [[0.1 0.2] [0.3 0.4]] [0.1 0.1])
              (layers/logistic [2])])
-        o (sgd-optimiser (parameter-count m))]
+        o (sgd-optimiser)]
     (optimiser-test m o)))

 (deftest test-relu-nn
   (let [m (stack-module
             [(layers/linear [[0.1 0.2] [0.3 0.4]] [0.1 0.1])
              (layers/relu [2])])
-        o (sgd-optimiser (parameter-count m))]
+        o (sgd-optimiser)]
     (optimiser-test m o)))

 (deftest test-mse-nulls
@@ -66,7 +66,7 @@
             (stack-module
               [(layers/linear [[0.1 0.2] [0.3 0.4]] [0.1 0.1])
                (layers/logistic [2])]))
-        o (sgd-optimiser (parameter-count m))]
+        o (sgd-optimiser)]
     (optimiser-test m o {:iterations 300 :print-iterations false :tolerance 0.1})))

 (defmacro pr-local


add dynamic subscriptions to subscribe

add dynamic subscriptions to subscribe

--- src/chat/client/reagent_adapter.cljs
+++ src/chat/client/reagent_adapter.cljs
@@ -154,7 +154,14 @@
   :user-preference
   state/get-preference)

-(defn subscribe [v]
-  (let [key-v (first v)
-        handler-fn (get @subscriptions key-v)]
-    (handler-fn store/app-state v)))
+(defn subscribe
+  ([v]
+   (let [key-v (first v)
+         handler-fn (get @subscriptions key-v)]
+     (handler-fn store/app-state v)))
+  ([v dynv] ; Dynamic subscription
+   (let [key-v (first v)
+         handler-fn (get @subscriptions key-v)]
+     (let [dyn-vals (reaction (mapv deref dynv))
+           sub (reaction (handler-fn store/app-state v @dyn-vals))]
+       (reaction @@sub)))))


pending endorsements

pending endorsements

--- src/clj/salava/badge/endorsement.clj
+++ src/clj/salava/badge/endorsement.clj
@@ -1,6 +1,6 @@
 (ns salava.badge.endorsement
   (:require [yesql.core :refer [defqueries]]
-            [salava.core.util :refer [get-db]]
+            [salava.core.util :refer [get-db md->html]]
             [slingshot.slingshot :refer :all]
             [clojure.tools.logging :as log]))

@@ -42,24 +42,22 @@
   (try+
     (if (or (endorsement-owner? ctx endorsement-id user-id) (badge-owner? ctx user-badge-id user-id ))
       (do (delete-user-badge-endorsement! {:id endorsement-id} (get-db ctx))
-      {:status "success"})
+        {:status "success"})
       {:status "error"}
       )
     (catch Object _
       (log/error _)
       {:status "error"})))

-#_(defn edit!
-  "Edit endorsement.
-  Does this reset status and promp user to receive again"
-  [ctx endorsement-id user-id])
+(defn user-badge-endorsements
+  [ctx user-badge-id]
+  (select-user-badge-endorsements {:user_badge_id user-badge-id} (get-db ctx)))

-(defn badge-endorsements [ctx user-badge-id]
-  (get-user-badge-endorsements {:user_badge_id user-badge-id} (get-db ctx)))
+(defn received-pending-endorsements [ctx user-id]
+  (map (fn [e]
+         (-> e (update :content md->html)))(select-received-pending-endorsements {:user_id user-id} (get-db ctx))))

-
-
-(defn recieved-endorsements [ctx user-id])
+(defn all-recieved-endorsements [ctx user-id])
 (defn all-given-endorsements [ctx endorser-id])


Removed logging that would have shown passwords just incase someone does use the heroku hosted demo site dispite the warning

--- src/clj_esendex_demo/routes/home.clj
+++ src/clj_esendex_demo/routes/home.clj
@@ -14,7 +14,6 @@
 (defroutes home-routes
   (GET "/" [] (home-page))
   (POST "/Send" req
-    (log/info (:params req))
     (let [params (:params req)
           dispatch (client/sms-dispatcher (:username params) (:password params))]
       (-> (client/sms-xml (:account params) (:to params) (:body params))


Refactor out functions used in `get-largest-consecutive-time-slot-freed-up-by-lesson`

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -553,6 +553,48 @@
   [day rowNum ttLessonInfo]
   (get-in Timetable [day rowNum ttLessonInfo]))

+(defn- timetable-get-closest-TimetableLessonInfo-before-time
+  "Retrieves the `TimetableLessonInfo` which ends before a given time and is
+   the one on the row closest to that time.
+   If such a `TimetableLessonInfo` object does not exist, returns nil."
+  [day rowNum timeIdx]
+  (let [ttRow (get-in Timetable [day rowNum])]
+    (reduce (fn [ttLessonInfoBefore [ttLessonInfo _]]
+              (let [endTime   (:endTime ttLessonInfo)]
+                (cond (and (nil? ttLessonInfoBefore)
+                           (<= endTime timeIdx))
+                      ttLessonInfo
+
+                      (and (not (nil? ttLessonInfoBefore))
+                           (<= endTime timeIdx)
+                           (> endTime (:endTime ttLessonInfoBefore)))
+                      ttLessonInfo
+
+                      :else ttLessonInfoBefore)))
+            nil
+            ttRow)))
+
+(defn- timetable-get-closest-TimetableLessonInfo-on-or-after-time
+  "Retrieves the `TimetableLessonInfo` which begins on or after a given time and
+   is the one on the row closest to that time.
+   If such a `TimetableLessonInfo` object does not exist, returns nil."
+  [day rowNum timeIdx]
+  (let [ttRow (get-in Timetable [day rowNum])]
+    (reduce (fn [ttLessonInfoAfter [ttLessonInfo _]]
+              (let [startTime (:startTime ttLessonInfo)]
+                (cond (and (nil? ttLessonInfoAfter)
+                           (>= startTime timeIdx))
+                      ttLessonInfo
+
+                      (and (not (nil? ttLessonInfoAfter))
+                           (>= startTime timeIdx)
+                           (< startTime (:endTime ttLessonInfoAfter)))
+                      ttLessonInfo
+
+                      :else ttLessonInfoAfter)))
+            nil
+            ttRow)))
+
 (defn- create-lesson-div
   "Creates a <div> element for a new lesson using jQuery"
   [& {:keys [moduleCode moduleName lessonType lessonGroup venue slotsOcc
@@ -1072,10 +1114,9 @@
    augmented with the `:day` and `:rowNum` keys."
   [removedAugTTLessonInfo]
   (let [day        (:day removedAugTTLessonInfo)
-        row        (:rowNum removedAugTTLessonInfo)
+        rowNum     (:rowNum removedAugTTLessonInfo)
         startTime  (:startTime removedAugTTLessonInfo)
         endTime    (:endTime removedAugTTLessonInfo)
-        ttRow      (get-in Timetable [day row])
         minTimeIdx time-helper/TIME-INDEX-MIN
         maxTimeIdx time-helper/TIME-INDEX-MAX]

@@ -1083,42 +1124,16 @@
     [
       ; Find the lesson right before the removed lesson
       (let [immediateTTLessonInfoBefore
-            (reduce (fn [ttLessonInfoBefore [ttLessonInfo _]]
-                      (let [stime (:startTime ttLessonInfo)
-                            etime (:endTime ttLessonInfo)]
-                        (cond (and (nil? ttLessonInfoBefore)
-                                   (<= etime startTime))
-                              ttLessonInfo
-
-                              (and (not (nil? ttLessonInfoBefore))
-                                   (<= etime startTime)
-                                   (> etime (:endTime ttLessonInfoBefore)))
-                              ttLessonInfo
-
-                              :else ttLessonInfoBefore)))
-                    nil
-                    ttRow)]
+            (timetable-get-closest-TimetableLessonInfo-before-time
+              day rowNum startTime)]
         (if (nil? immediateTTLessonInfoBefore)
             minTimeIdx
             (:endTime immediateTTLessonInfoBefore)))

       ; Find the lesson right after the removed lesson
       (let [immediateTTLessonInfoAfter
-            (reduce (fn [ttLessonInfoAfter [ttLessonInfo _]]
-                      (let [stime (:startTime ttLessonInfo)
-                            etime (:endTime ttLessonInfo)]
-                        (cond (and (nil? ttLessonInfoAfter)
-                                   (>= stime endTime))
-                              ttLessonInfo
-
-                              (and (not (nil? ttLessonInfoAfter))
-                                   (>= stime endTime)
-                                   (< stime (:endTime ttLessonInfoAfter)))
-                              ttLessonInfo
-
-                              :else ttLessonInfoAfter)))
-                    nil
-                    ttRow)]
+            (timetable-get-closest-TimetableLessonInfo-on-or-after-time
+              day rowNum endTime)]
         (if (nil? immediateTTLessonInfoAfter)
             maxTimeIdx
             (dec (:startTime immediateTTLessonInfoAfter))))


`timetable.cljs` - s/lessonLabel/lessonGroup/g

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -537,7 +537,7 @@
   "Adds a single lesson of a module the timetable.
    Returns a `ModulesSelectedLessonInfo` object augmented with the `:divElem`,
    `:moduleCode`, `:lessonType` and `:lessonGroup` keys."
-  [moduleCode moduleName lessonType lessonLabel modulesMapLesson bgColorCssClass
+  [moduleCode moduleName lessonType lessonGroup modulesMapLesson bgColorCssClass
    isActuallySelected?]
   (let [rowNum    (find-free-row-for-lesson modulesMapLesson)
         day       (:day modulesMapLesson)
@@ -551,7 +551,7 @@

         $divElem
         (create-lesson-div :moduleCode moduleCode, :moduleName moduleName,
-                           :lessonType lessonType, :lessonGroup lessonLabel,
+                           :lessonType lessonType, :lessonGroup lessonGroup,
                            :venue venue, :slotsOcc slotsOcc,
                            :bgColorCssClass bgColorCssClass,
                            :isActuallySelected? isActuallySelected?)]
@@ -564,7 +564,7 @@
                            rowNum
                            {:moduleCode moduleCode,
                             :lessonType lessonType,
-                            :lessonGroup lessonLabel,
+                            :lessonGroup lessonGroup,
                             :startTime startTime,
                             :endTime endTime}
                            $divElem)
@@ -579,7 +579,7 @@
         (.remove $siblingTd))

       {:day day, :rowNum rowNum, :startTime startTime, :endTime endTime,
-       :moduleCode moduleCode, :lessonType lessonType, :lessonGroup lessonLabel,
+       :moduleCode moduleCode, :lessonType lessonType, :lessonGroup lessonGroup,
        :divElem $divElem})))

 (def ^{:doc     "Sequence of `TimetableLessonInfo` objects augmented with the
@@ -693,7 +693,7 @@

 (defn- make-added-lessons-draggable
   "Makes the <div> elements of selected lessons draggable."
-  [$divElemSeq moduleCode lessonType lessonLabel bgColorCssClass]
+  [$divElemSeq moduleCode lessonType lessonGroup bgColorCssClass]
   ; And Drag event handler
   (doseq [$divElem $divElemSeq]
     (.css $divElem "cursor" "grab")
@@ -702,10 +702,10 @@
                         "helper" "clone"
                         "revert" "invalid"
                         "start"  (lesson-draggable-start-evt-handler-maker
-                                   moduleCode lessonType lessonLabel
+                                   moduleCode lessonType lessonGroup
                                    bgColorCssClass)
                         "stop"   (lesson-draggable-stop-evt-handler-maker
-                                   moduleCode lessonType lessonLabel
+                                   moduleCode lessonType lessonGroup
                                    bgColorCssClass)))))

 (defn- make-fake-lessons-droppable
@@ -750,16 +750,16 @@

    Returns a sequence of `ModulesSelectedLessonInfo` objects each augmented
    with the `:divElem`, `:moduleCode`, `:lessonType`, `:lessonGroup` keys."
-  [moduleCode lessonType lessonLabel bgColorCssClass isActuallySelected?]
-  (if (module-has-lesson-group? moduleCode lessonType lessonLabel)
+  [moduleCode lessonType lessonGroup bgColorCssClass isActuallySelected?]
+  (if (module-has-lesson-group? moduleCode lessonType lessonGroup)
       (let [moduleName          (get-module-name-from-module-code moduleCode)
             modulesMapLessonSeq (get-ModulesMapLesson-seq moduleCode lessonType
-                                                          lessonLabel)
+                                                          lessonGroup)

             augLessonInfoSeq
             (doall (map (fn [modulesMapLesson]
                           (add-module-lesson! moduleCode moduleName lessonType
-                                              lessonLabel modulesMapLesson
+                                              lessonGroup modulesMapLesson
                                               bgColorCssClass
                                               isActuallySelected?))
                         modulesMapLessonSeq))
@@ -773,7 +773,7 @@
               ; Update ModulesSelected with the lesson group
               (set! ModulesSelected
                     (assoc-in ModulesSelected [moduleCode lessonType]
-                              {:label lessonLabel, :info lessonInfoSeq}))
+                              {:label lessonGroup, :info lessonInfoSeq}))

               ; Add to ModulesSelectedOrder
               (if (not-any? #{moduleCode} ModulesSelectedOrder)
@@ -792,7 +792,7 @@
               (if (module-lesson-type-has-multiple-choices? moduleCode
                                                             lessonType)
                   (make-added-lessons-draggable $divElemSeq moduleCode
-                                                lessonType lessonLabel
+                                                lessonType lessonGroup
                                                 bgColorCssClass)))

             ; lesson was added due to draggable <div>


[REFACTOR] Use `TIMETABLE` vector as a function

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -491,7 +491,7 @@
   "Retrieves the in-memory representation of the given 0-indexed day in the
    Timetable, where 0 = Monday, 1 = Tuesday, until 5 = Saturday"
   [day]
-  (nth TIMETABLE day))
+  (TIMETABLE day))

 ; Retrieves a row for a given day in `TIMETABLE`
 (defmulti timetable-get-day-row (fn [a1 _] (number? a1)) :default true)


Uncomment lazy seq test

Uncomment lazy seq test

--- tests/test_core.cljx
+++ tests/test_core.cljx
@@ -39,12 +39,12 @@
   (testing "It works with vectors"
     (is (= (m/sequence [[1 2] [3 4]])
            [[1 3] [1 4] [2 3] [2 4]])))
-;  (testing "It works with lazy seqs"
-;    (is (= (m/sequence [(lazy-seq [1 2]) (lazy-seq [3 4])])
-;           '([1 3] [1 4] [2 3] [2 4]))))
-;  (testing "It works with sets"
-;    (is (= (m/sequence [#{1 2} #{3 4}])
-;           #{[1 3] [1 4] [2 3] [2 4]})))
+  (testing "It works with lazy seqs"
+    (is (= (m/sequence [(lazy-seq [1 2]) (lazy-seq [3 4])])
+           [[1 3] [1 4] [2 3] [2 4]])))
+  (testing "It works with sets"
+    (is (= (m/sequence [#{1 2} #{3 4}])
+           #{[1 3] [1 4] [2 3] [2 4]})))
   (testing "It works with Maybe values"
     (is (= (m/sequence [(maybe/just 2) (maybe/just 3)])
            (maybe/just [2 3])))


(REPL enhancement: move-entities now callable with delta-time)

--- desktop/src-common/brain_gain_or_drain/screens/game_mechanics.clj
+++ desktop/src-common/brain_gain_or_drain/screens/game_mechanics.clj
@@ -52,5 +52,8 @@
                                (filter player? entities)))))

 (defmethod move-entities :in-space
-  [screen move-direction entities]
-  (mapv #(move-entity (:delta-time screen) move-direction %) entities))
+  [screen-or-delta-time move-direction entities]
+  (let [delta-time (if (map? screen-or-delta-time)
+                     (:delta-time screen-or-delta-time)
+                     screen-or-delta-time)]
+    (mapv #(move-entity delta-time move-direction %) entities)))


Handle auto-binding a Push and Push 2 at same time

Since both have the same port name on the Mac, "User Port", we need our
port filter to discriminate on both the port name and device name.
Luckily, that is easy enough. And it looks just insane having both
running at once. :D

--- src/afterglow/controllers.clj
+++ src/afterglow/controllers.clj
@@ -44,7 +44,10 @@
     (when device
       (timbre/info "Attempting auto-binding to potential controller" device args)
       (try
-        (apply bind-to-show (concat [show (:name device)] (flatten (seq args))))
+        (apply bind-to-show (concat [show (fn [port]
+                                            (and (= (:name port) (:name device))
+                                                 (= (:description port) (:description device))))]
+                                    (flatten (seq args))))
         (catch Exception e
           (timbre/error e "Problem binding to controller"))))


cleanup; Clean up docstrings

cleanup; Clean up docstrings

--- src/main/untangled/ui/elements.cljc
+++ src/main/untangled/ui/elements.cljc
@@ -477,8 +477,8 @@
 (def ui-notification
   "Render a notification. Normal HTML/React attributes can be included, and should be a cljs map (not a js object).

-  type: : :success, :warning, :error, :informative
-  size (optional): :wide
+  `:type` :none (default), :success, :warning, :error, :informative
+  `:size` :normal (default), :wide

   You should include two children of this node:

@@ -493,8 +493,8 @@
 (defn ui-progress
   "Render a progress element. Props is a normal clj(s) map with React/HTML attributes plus:

-  className (optional): additional class stylings to apply to the progress element
-  id: Name of the progress control
+  `:className` - additional class stylings to apply to the progress element
+  `:id` - Name of the progress control
   "
   [{:keys [id style] :or {id ""} :as attrs}]
   (let [user-classes (get attrs :className "")


added count

added count

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -274,6 +274,9 @@
    "correspond" {:synsem {:cat :verb
                           :sem {:pred :correspond}}}

+   "count" {:synsem {:cat :verb
+                      :sem {:pred :count}}}
+
    "create" {:synsem {:cat :verb
                       :sem {:pred :create}}}


restrictions on semantics of 'llamarse'

restrictions on semantics of 'llamarse'

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -449,8 +449,8 @@
                             :reflexive true
                             :sem subject-semantics}}}})
    "llamarse"
-   (let [subject-semantics (ref {:human true})
-         called-semantics (ref {:propernoun true})
+   (let [subject-semantics (ref :top)
+         called-semantics (ref :top)
          subject-gender (ref :top)
          subject-person (ref :top)
          subject-number (ref :top)]


Fix namespace imports.

Fix namespace imports.

--- src/cheshire/generate_seq.clj
+++ src/cheshire/generate_seq.clj
@@ -1,9 +1,9 @@
 (ns cheshire.generate-seq
   "Namespace used to generate JSON from Clojure data structures in a
   sequential way."
-  (:require [cheshire.generate :refer [tag JSONable to-json i?
-                                       number-dispatch write-string
-                                       fail]])
+  (:use [cheshire.generate :only [tag JSONable to-json i?
+                                  number-dispatch write-string
+                                  fail]])
   (:import (com.fasterxml.jackson.core JsonGenerator JsonGenerationException)
            (java.util Date Map List Set SimpleTimeZone UUID)
            (java.sql Timestamp)


Removing dep that I didn't mean to commit

--- src/cia/schemas/indicator.clj
+++ src/cia/schemas/indicator.clj
@@ -2,7 +2,6 @@
   (:require [cia.schemas.common :as c]
             [cia.schemas.relationships :as rel]
             [cia.schemas.vocabularies :as v]
-            [lonocloud.synthread :as ->]
             [schema.core :as s]
             [schema-tools.core :as st]))


fix Project Junebug to stop firing even with the Corp on 0 credits

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -374,9 +374,9 @@

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

    "Psychic Field"


fixed card-str calls to use state

fixed card-str calls to use state

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -87,7 +87,7 @@
                                                :effect (effect (add-prop :corp target :advance-counter 1)
                                                                (add-prop :corp fr :advance-counter -1)
                                                                (system-msg (str "uses Constellation Protocol to move an advancement token from "
-                                                                                (card-str fr) " to " (card-str target))))} card nil)
+                                                                                (card-str state fr) " to " (card-str state target))))} card nil)
                                             card nil))}}}}}

    "Contract Killer"


wrap keywork params

wrap keywork params

--- src/clj/hdfs_cleaner/core.clj
+++ src/clj/hdfs_cleaner/core.clj
@@ -8,7 +8,8 @@
             [manifold.deferred :as d]
             [cheshire.core :as json]
             [ring.util.response :refer [content-type]]
-            [ring.middleware.params :as params]
+            [ring.middleware.keyword-params :refer :all]
+            [ring.middleware.params :refer :all]
             [compojure.core :refer :all]
             [compojure.route :as route]
             [aleph.http :as http]
@@ -32,7 +33,7 @@
   (routes
     (GET ["/scan:path", :path #"\/.+"]
          {{hdfs-path :path} :route-params
-          {:keys [depth] :as query} :query}
+          {:keys [depth] :as query} :query-params}
       (spy [depth query])
       (http-res/response (hdfs/scan [hdfs-path depth])))
     (GET "/ping" {}
@@ -53,17 +54,18 @@
              (update response :headers dissoc "transfer-encoding"))))

 (def app
-  (params/wrap-params
-    (fn [req]
-      (log/debug {:type "request" :content req})
-      (d/chain
-        (-> req
-            (app-routes)
-            (d/catch
-              (fn [e]
-                (log/error e "Error on tracking")
-                (http-res/error 500 (.getMessage e)))))
-        encode-response-to-json))))
+  (-> (fn [req]
+        (log/debug {:type "request" :content req})
+        (d/chain
+          (-> req
+              (app-routes)
+              (d/catch
+                (fn [e]
+                  (log/error e "Error on tracking")
+                  (http-res/error 500 (.getMessage e)))))
+          encode-response-to-json))
+      (wrap-keyword-params)
+      (wrap-params)))

 (def ^:private ^:const aleph-config
   {:port 4050


add test for Alix-T4LB07

add test for Alix-T4LB07

--- src/clj/test/cards-assets.clj
+++ src/clj/test/cards-assets.clj
@@ -38,6 +38,24 @@
       (is (=
             2
             (count (get-in @state [:runner :rig :program]))))
+      )))
+
+(deftest alix-t4lb07
+  (do-game
+    (new-game
+      (default-corp [(qty "Alix T4LB07" 1) (qty "PAD Campaign" 3)])
+      (default-runner))
+    (play-from-hand state :corp "Alix T4LB07" "New remote")
+    (let [alix (first (get-in @state [:corp :servers :remote1 :content]))]
+      (core/rez state :corp alix)
+      (play-from-hand state :corp "PAD Campaign" "New remote")
+      (play-from-hand state :corp "PAD Campaign" "New remote")
+      (take-credits state :corp)
+      (take-credits state :runner)
+      (is (= 2 (get-in (refresh alix) [:counter])))
+      (is (= 4 (get-in @state [:corp :credit])))
+      (card-ability state :corp alix 0)
+      (is (= 8 (get-in @state [:corp :credit])))
       )))

 (deftest franchise-city


Don't allow the player to close the door on herself

--- src/cljc/robinson/update.cljc
+++ src/cljc/robinson/update.cljc
@@ -673,6 +673,8 @@
               (rc/append-log state "Cannot close door. There are items in the way.")
             (rw/npc-at-xy state target-x target-y)
               (rc/append-log state "Cannot close door. There is a creature in the way.")
+            (= (rp/player-xy state) [target-x target-y])
+              (rc/append-log state "Cannot close door. You're in the way.")
             :else
             (-> state
               (rc/append-log "The door closes")


correctly format board links

correctly format board links

--- src/cljs/retroboard/user.cljs
+++ src/cljs/retroboard/user.cljs
@@ -100,9 +100,10 @@
     (let [new-value (.. e -target -value)]
       (om/set-state! owner id new-value))))

-(defn board-link [board-id]
-  (dom/a #js {:href (str "/e/" board-id)}
-         (str "http://remboard.com/e/" board-id)))
+(defn board-link [board]
+  (let [board-name (:name board)]
+    (dom/a #js {:href (str "/e/" board-name)}
+           (str "http://remboard.com/e/" board-name))))

 (defn header-nav [& [options]]
   (dom/nav #js {:className "navigation navigation-header"}


Fix a small z-index bug

Fix a small z-index bug

--- src/cljs/sbsk/views/body.cljs
+++ src/cljs/sbsk/views/body.cljs
@@ -117,6 +117,7 @@
                                                         (reset! search-input s)))}]]]
                               [re-com/box
                                :size "32px"
+                               :style {:z-index 1}
                                :child [re-com/md-icon-button
                                        :md-icon-name "zmdi-search"
                                        :on-click (fn [e]


remove debug alert

remove debug alert

--- src/cljs/yantra/graphics.cljs
+++ src/cljs/yantra/graphics.cljs
@@ -66,7 +66,7 @@
             heightdiff (/ (- newheight height) 2)]
         ;(js/alert (str "heightdiff" heightdiff))
         [  [xmin (- ymin heightdiff)] [xmax  (+ ymax heightdiff)]])
-      (do (js/alert (str "no aspect change" plotaspect " " imageaspect)) bounding-box))))
+      bounding-box)))


making java interop consistent with other code

--- src/clojure/sparkling/sql.clj
+++ src/clojure/sparkling/sql.clj
@@ -148,17 +148,17 @@
       .write
       (.json data-source)))

-(defn save-as-parquet
-  "Write out data frame in parquet format"
+(defn write-parquet
+  "write out data frame in parquet format"
   [data-frame path]
-  (.. data-frame
-      write
-      (parquet path)))
+  (-> data-frame
+      .write
+      (.parquet path)))

 (defn read-parquet
   "read folder that contains parquet data"
-  [sql-context path]
-  (.. sql-context
+  [sql-con path]
+  (-> sql-con
       read
       (load path)))


Adds stack trace printing on exceptions.

--- src/clojush/pushgp/pushgp.clj
+++ src/clojush/pushgp/pushgp.clj
@@ -83,7 +83,7 @@

 (defn make-agents-and-rng [{:keys [initial-population use-single-thread population-size
                                    max-points-in-initial-program atom-generators random-seed]}]
-  (let [agent-error-handler (fn [agnt except] (println except) (System/exit 0))]
+  (let [agent-error-handler (fn [agnt except] (.printStackTrace except) (System/exit 0))]
     {:pop-agents (if initial-population
                    (->> (read-string (slurp (str "data/" initial-population)))
                         (map #(if use-single-thread (atom %) (agent %)))


Add function to remove entries from argmap who's values were or contain functions

This fixes the problem of having function values in EDN output which couldn't be successfully read in later.
:random-seed and :atom-generators are hard-coded in as they are objects that contain a function, so there was no easy way to recognize them.

--- src/clojush/pushgp/report.clj
+++ src/clojush/pushgp/report.clj
@@ -589,6 +589,10 @@
           (>= @point-evaluations-count max-point-evaluations) [:failure best]
           :else [:continue best])))

+(defn remove-function-values [argmap]
+  (into {} (filter (fn [[k v]] (not (fn? v)))
+    (dissoc argmap :random-seed :atom-generators))))
+
 (defn initial-report
   "Prints the initial report of a PushGP run."
   [{:keys [problem-specific-initial-report] :as push-argmap}]
@@ -632,12 +636,7 @@
     ;; The edn log is overwritten if it exists
     (with-open [w (io/writer (:edn-log-filename push-argmap) :append false)]
       (.write w "#clojush/run")
-      (.write w (prn-str (dissoc push-argmap
-                                 ;; These keys have functions
-                                 :atom-generators
-                                 :error-function
-                                 :problem-specific-report
-                                 :random-seed)))))
+      (.write w (prn-str (remove-function-values push-argmap)))))
   (when (:visualize push-argmap) ;; Visualization
     ;; Require conditionally (dynamically), avoiding unintended Quil sketch launch
     (require 'clojush.pushgp.visualize)))


Driver feature is `expressions` instead of `custom-fields`

--- src/metabase/driver/generic_sql.clj
+++ src/metabase/driver/generic_sql.clj
@@ -216,7 +216,6 @@
   [driver]
   (cond-> #{:standard-deviation-aggregations
             :foreign-keys
-            :custom-fields
             :expressions}
     (set-timezone-sql driver) (conj :set-timezone)))


Removes unused lens.

Removes unused lens.

--- src/active/clojure/match.clj
+++ src/active/clojure/match.clj
@@ -359,45 +359,6 @@
                       path-matches-with-binding-clause?
                       optional-path-matches-without-binding-clause?
                       optional-path-matches-with-binding-clause?))
-
-;; helpers
-(defn clause-lens
-  [key-exists-without-binding-lens
-   key-exists-with-binding-lens
-   optional-key-exists-without-binding-lens
-   optional-key-exists-with-binding-lens
-   path-exists-without-binding-lens
-   path-exists-with-binding-lens
-   optional-path-exists-without-binding-lens
-   optional-path-exists-with-binding-lens
-   key-matches-without-binding-lens
-   key-matches-with-binding-lens
-   optional-key-matches-without-binding-lens
-   optional-key-matches-with-binding-lens
-   path-matches-without-binding-lens
-   path-matches-with-binding-lens
-   optional-path-matches-without-binding-lens
-   optional-path-matches-with-binding-lens]
-  (fn [clause]
-    (cond
-      (key-exists-without-binding-clause? clause) key-exists-without-binding-lens
-      (key-exists-with-binding-clause? clause)   key-exists-with-binding-lens
-      (optional-key-exists-without-binding-clause? clause) optional-key-exists-without-binding-lens
-      (optional-key-exists-with-binding-clause? clause)   optional-key-exists-with-binding-lens
-      (path-exists-without-binding-clause? clause)  path-exists-without-binding-lens
-      (path-exists-with-binding-clause? clause)  path-exists-with-binding-lens
-      (optional-path-exists-without-binding-clause? clause)  optional-path-exists-without-binding-lens
-      (optional-path-exists-with-binding-clause? clause)  optional-path-exists-with-binding-lens
-      (key-matches-without-binding-clause? clause)  key-matches-without-binding-lens
-      (key-matches-with-binding-clause? clause)  key-matches-with-binding-lens
-      (optional-key-matches-without-binding-clause? clause)  optional-key-matches-without-binding-lens
-      (optional-key-matches-with-binding-clause? clause)  optional-key-matches-with-binding-lens
-      (path-matches-without-binding-clause? clause) path-matches-without-binding-lens
-      (path-matches-with-binding-clause? clause) path-matches-with-binding-lens
-      (optional-path-matches-without-binding-clause? clause) optional-path-matches-without-binding-lens
-      (optional-path-matches-with-binding-clause? clause) optional-path-matches-with-binding-lens
-      :else
-      (c/assertion-violation `clause-lens "not a valid clause" clause))))

 ;;;; Parse
 ;; Translate pattern expressions for `active.clojure.match` to clauses


Put a bound on query-range-channel.

Put a bound on query-range-channel.

--- metlog-vault/src-client/metlog_client/metlog.cljs
+++ metlog-vault/src-client/metlog_client/metlog.cljs
@@ -56,7 +56,7 @@
      :end-t (time-coerce/to-long end-t)}))

 (defn query-range-channel [ periodic-event-channel ]
-  (let [ channel (chan) ]
+  (let [ channel (chan (dropping-buffer 1)) ]
     (pipeline 1 channel (map range-ending-at) periodic-event-channel)
     channel))


+TODO

+TODO

--- src/babel/english/writer.clj
+++ src/babel/english/writer.clj
@@ -50,8 +50,8 @@

         model (-> ((-> models :en)) deref)
         type-of-model (type model)
-        source-expressions (read-all spec
-                                     source-language-short-name)]
+        ;; TODO: use :no-older-than here.
+        source-expressions (read-all spec source-language-short-name)]
     (doall
      (use-map-fn
       ;; source-expression in the language that we want to translate into English.


Use ‘with-binary-context’ in :next-closure implementation of concepts

--- src/main/clojure/conexp/fca/fast.clj
+++ src/main/clojure/conexp/fca/fast.clj
@@ -306,30 +306,24 @@

 (defmethod concepts :next-closure
   [_ context]
-  (let [object-vector    (vec (objects context)),
-        attribute-vector (vec (improve-basic-order (attributes context)
-                                                   #(context-attribute-closure context %))),
-        object-count     (count object-vector),
-        attribute-count  (count attribute-vector),
-        incidence-matrix (to-binary-matrix object-vector attribute-vector (incidence context)),
-
-        o-prime (partial bitwise-object-derivation incidence-matrix object-count attribute-count),
-        a-prime (partial bitwise-attribute-derivation incidence-matrix object-count attribute-count),
-        start   (o-prime (a-prime (BitSet.))),
-        intents (take-while identity
-                            (iterate #(next-closed-set attribute-count
-                                                       (partial bitwise-context-attribute-closure
-                                                                object-count
-                                                                attribute-count
-                                                                incidence-matrix)
-                                                       %)
-                                     start))]
-    (if *concepts-do-conversion*
-      (map (fn [bitset]
-             [(to-hashset object-vector (a-prime bitset)),
-              (to-hashset attribute-vector bitset)])
-           intents)
-      intents)))
+  (with-binary-context context
+    (let [o-prime (partial bitwise-object-derivation incidence-matrix object-count attribute-count),
+          a-prime (partial bitwise-attribute-derivation incidence-matrix object-count attribute-count),
+          start   (o-prime (a-prime (BitSet.))),
+          intents (take-while identity
+                              (iterate #(next-closed-set attribute-count
+                                                         (partial bitwise-context-attribute-closure
+                                                                  object-count
+                                                                  attribute-count
+                                                                  incidence-matrix)
+                                                         %)
+                                       start))]
+      (if *concepts-do-conversion*
+        (map (fn [bitset]
+               [(to-hashset object-vector (a-prime bitset)),
+                (to-hashset attribute-vector bitset)])
+             intents)
+        intents))))

 ;;; Vychodil (:vychodil)


update change log

update change log

--- doc/.template/posts/99-change-log.html.clj
+++ doc/.template/posts/99-change-log.html.clj
@@ -14,4 +14,6 @@
            (ul [
                 "Update misaki.util.sequence/find-first to handle lazy sequence."
                 "Update misaki.util.file/has-extension? to handle all extension(*)."
-                "Add misaki.util.file/normalize-extension."]))])
+                "Add misaki.util.file/normalize-extension."
+                "Update misaki.compiler.default.html.core/heading to generate self heading link."
+                ]))])


Don't enforce a non-empty entries for a new board.

--- src/oc/storage/resources/common.clj
+++ src/oc/storage/resources/common.clj
@@ -113,7 +113,7 @@
 (def NewBoard
   "A new board for creation, requires at least one entry."
   (merge Board {
-    :entries [(schema/one Entry "new-entry") Entry]}))
+    :entries [Entry]}))

 (def User
   "User info to notify via email/slack"


improved distillery.processing/no-punctuation? by using a regular expression

--- src/distillery/processing.clj
+++ src/distillery/processing.clj
@@ -50,30 +50,9 @@
 (defn no-punctuation?
   "Checks whether the given word ends with a colon."
   [word]
-  (let [^String text (:text word)]
-    (not (or
-          (.endsWith text ".")
-          (.endsWith text ",")
-          (.endsWith text ":")
-          (.endsWith text ";")
-          (= text "@")
-          (= text "(")
-          (= text ")")
-          (= text "[")
-          (= text "]")
-          (= text "{")
-          (= text "}")
-          (= text "<")
-          (= text ">")
-          (= text "=")
-          (= text "§")
-          (= text "$")
-          (= text "&")
-          (= text "%")
-          (= text "?")
-          (= text "!")
-          (= text "/")
-          (= text "\\")))))
+  (let [^String text (:text word)
+        regex (re-pattern "\\W")]
+    (not (re-find regex text))))

 (defn not-short?
   "Checks whether a word is long enough to be relevant."


add user management dispatch

add user management dispatch

--- src/clj/lesezeichen/core.clj
+++ src/clj/lesezeichen/core.clj
@@ -42,6 +42,10 @@
   (case topic
     :get-user-bookmarks {:topic topic
                          :data (get-user-bookmarks (:conn @server-state) data)}
+    :register {:topic topic
+               :data (add-user (:conn @server-state) data)}
+    :sign-in {:topic topic
+              :data ()}
     :add-bookmark {:topic topic
                    :data (add-bookmark (:conn @server-state)
                                        (assoc data :title (fetch-url-title (:url data))))}


remove done task

remove done task

--- src/cljs/tictactoe/core.cljs
+++ src/cljs/tictactoe/core.cljs
@@ -5,7 +5,6 @@
     [tictactoe.store :as store]))

-;; TODO - Add message to indicate winner
 ;; TODO - Add ready unit tests
 ;; TODO - Move constants and board - hidden in logic


update ns

update ns

--- src/clojure_fabric/proto.clj
+++ src/clojure_fabric/proto.clj
@@ -18,9 +18,13 @@
 ;;
 (ns clojure-fabric.proto
   (:import [com.google.protobuf ByteString Timestamp]
-           [org.hyperledger.fabric.protos.common Common$ChannelHeader Common$SignatureHeader]
+           [org.hyperledger.fabric.protos.common Common$ChannelHeader Common$SignatureHeader
+            Common$Header]
            org.hyperledger.fabric.protos.msp.Identities$SerializedIdentity
-           [org.hyperledger.fabric.protos.peer Chaincode$ChaincodeID Chaincode$ChaincodeInput Chaincode$ChaincodeInvocationSpec Chaincode$ChaincodeSpec Chaincode$ChaincodeSpec$Type ProposalPackage$ChaincodeHeaderExtension]))
+           [org.hyperledger.fabric.protos.peer Chaincode$ChaincodeID Chaincode$ChaincodeInput
+            Chaincode$ChaincodeInvocationSpec Chaincode$ChaincodeSpec Chaincode$ChaincodeSpec$Type
+            ProposalPackage$ChaincodeHeaderExtension ProposalPackage$Proposal
+            ProposalPackage$ChaincodeProposalPayload ProposalPackage$SignedProposal]))

 ;;;
 ;;;
@@ -29,7 +33,6 @@

 (defprotocol IProtoToClj
   (proto->clj [this]))
-

 ;;;
 ;;; Records are one to one relationship with proto message definitions


Fix phone number formatting

Fix phone number formatting


Add account settings content to the aside

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -267,6 +267,28 @@
     {:type :subpage :href "#projects" :title "Projects" :subpage :projects}
     {:type :subpage :href "#users" :title "Users" :subpage :users}]))

+(defn account-settings-nav-items []
+  [{:type :subpage :href (routes/v1-account-subpage {:subpage "notifications"}) :title "Notifications" :subpage :notifications}
+   {:type :subpage :href (routes/v1-account-subpage {:subpage "api"}) :title "API Tokens" :subpage :api}
+   {:type :subpage :href (routes/v1-account-subpage {:subpage "heroku"}) :title "Heroku" :subpage :heroku}
+   {:type :subpage :href (routes/v1-account-subpage {:subpage "plans"}) :title "Plan Pricing" :subpage :plans}
+   {:type :subpage :href (routes/v1-account-subpage {:subpage "beta"}) :title "Beta Program" :subpage :beta}
+   ])
+
+(defn account-settings-menu [app owner]
+  (reify
+    om/IRender
+    (render [_]
+      (let [subpage (:project-settings-subpage app :overview)]
+        (html
+          [:div.aside-user {:class (when (= :account (:navigation-point app)) "open")}
+           [:header
+            [:h4 "Account Settings"]
+            [:a.close-menu {:href "./"} ; This may need to change if we drop hashtags from url structure
+             (common/ico :fail-light)]]
+           [:div.aside-user-options
+            (expand-menu-items (account-settings-nav-items) subpage)]])))))
+
 (defn admin-settings-nav-items []
   (filter
     identity
@@ -416,6 +438,7 @@
         (om/build project-settings-menu app)
         (om/build org-settings-menu app)
         (om/build admin-settings-menu app)
+        (om/build account-settings-menu app)
         (om/build branch-activity-list app {:opts {:login (:login opts)
                                                    :scrollbar-width (om/get-state owner :scrollbar-width)}})]))))


add stand-in collaborators back

add stand-in collaborators back

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -28,27 +28,27 @@
           ;; [:button.collaborators
           ;;  (common/icon :users)
           ;;  [:span "Collaborators"]]
-          ;; [:div.aside-collaborators
-          ;;  [:button
-          ;;   [:object
-          ;;    (common/icon :bullet)
-          ;;    [:span "Anonymous"]]]
-          ;;  [:button
-          ;;   [:object
-          ;;    (common/icon :bullet)
-          ;;    [:span "Anonymous"]]]
-          ;;  [:button
-          ;;   [:object
-          ;;    (common/icon :bullet)
-          ;;    [:span "Anonymous"]]]
-          ;;  [:button
-          ;;   [:object
-          ;;    (common/icon :bullet)
-          ;;    [:span "Anonymous"]]]
-          ;;  [:button
-          ;;   [:object
-          ;;    (common/icon :bullet)
-          ;;    [:span "Anonymous"]]]]
+          [:div.aside-collaborators
+           [:button
+            [:object
+             (common/icon :bullet)
+             [:span "Anonymous"]]]
+           [:button
+            [:object
+             (common/icon :bullet)
+             [:span "Anonymous"]]]
+           [:button
+            [:object
+             (common/icon :bullet)
+             [:span "Anonymous"]]]
+           [:button
+            [:object
+             (common/icon :bullet)
+             [:span "Anonymous"]]]
+           [:button
+            [:object
+             (common/icon :bullet)
+             [:span "Anonymous"]]]]
           [:div.aside-settings
            [:button
             (common/icon :settings)


DB interface: add-new-chapter function

DB interface: add-new-chapter function

--- src/hurvinek/db_interface.clj
+++ src/hurvinek/db_interface.clj
@@ -127,3 +127,16 @@
                 (println e)
                 e))))

+(defn add-new-chapter
+    [product-id chapter-name]
+    (if (empty? chapter-name)
+        "Chapter name is empty"
+        (try
+            (jdbc/insert! db-spec/hurvinek-db
+                :chapters {:product product-id
+                           :name    chapter-name})
+            nil ; return value
+            (catch Exception e
+                (println e)
+                e))))
+


Tundra: add simple disk datastore

Tundra: add simple disk datastore

--- src/taoensso/carmine/tundra/disk.clj
+++ src/taoensso/carmine/tundra/disk.clj
@@ -2,11 +2,66 @@
   "Simple disk-based DataStore implementation for Tundra."
   {:author "Peter Taoussanis"}
   (:require [taoensso.timbre :as timbre])
-  (:import  [taoensso.carmine.tundra IDataStore]))
+  (:import  [taoensso.carmine.tundra IDataStore]
+            [java.net URLDecoder URLEncoder]
+            [java.nio.file CopyOption Files LinkOption OpenOption Path Paths
+             StandardCopyOption StandardOpenOption NoSuchFileException]))

-;; TODO
+;;;; Utils

-;; (defrecord DiskDataStore [path]
-;;   IDataStore
-;;   (put-key   [dstore k v])
-;;   (fetch-key [dstore k]))
+(defn- uuid [] (java.util.UUID/randomUUID))
+(defn- >fname-safe [s] (URLEncoder/encode (str s) "ISO-8859-1"))
+(defn- <fname-safe [s] (URLDecoder/decode (str s) "ISO-8859-1"))
+(comment (<fname-safe (>fname-safe "hello f8 8 93#**#\\// !!$")))
+
+(defn- path*  [path] (Paths/get "" (into-array String [path])))
+(defn- mkdirs [path] (.mkdirs (.toFile (path* path))))
+(defn- mv [path-source path-dest]
+  (Files/move (path* path-source) (path* path-dest)
+    (into-array CopyOption [StandardCopyOption/ATOMIC_MOVE
+                            StandardCopyOption/REPLACE_EXISTING])))
+
+(defn- read-ba  [path] (Files/readAllBytes (path* path)))
+(defn- write-ba [path ba]
+  (Files/write (path* path) ba
+    (into-array OpenOption [StandardOpenOption/CREATE
+                            StandardOpenOption/TRUNCATE_EXISTING
+                            StandardOpenOption/WRITE
+                            StandardOpenOption/SYNC])))
+
+;;;;
+
+(defrecord DiskDataStore [path]
+  IDataStore
+  (fetch-key [this k] (read-ba (format "%s/%s" (path* path) (>fname-safe k))))
+  (put-key   [this k v]
+    (let [result
+          (try (let [path-full-temp (format "%s/tmp-%s" (path* path) (uuid))
+                     path-full      (format "%s/%s"     (path* path) (>fname-safe k))]
+                 (write-ba path-full-temp v)
+                 (mv       path-full-temp path-full))
+               (catch Exception e e))]
+
+      (cond
+       (instance? Path result) true
+       (instance? NoSuchFileException result)
+       (do (mkdirs path) (recur k v))
+
+       (instance? Exception result) result
+       :else (Exception. (format "Unexpected result: %s" result))))))
+
+(defn disk-datastore
+  "Alpha - subject to change.
+  Requires JVM 1.7+.
+  Supported Freezer io types: byte[s]."
+  [path] {:pre [(string? path)]} (->DiskDataStore path))
+
+(comment
+  (require '[taoensso.carmine.tundra :as tundra])
+  (def dstore (disk-datastore "./tundra"))
+  (tundra/put-key dstore "foo:bar:baz" (.getBytes "hello world"))
+  (String. (tundra/fetch-key dstore "foo:bar:baz"))
+
+  (time (dotimes [_ 10000]
+    (tundra/put-key   dstore "foo:bar:baz" (.getBytes "hello world"))
+    (tundra/fetch-key dstore "foo:bar:baz"))))


Stop horsing around, part 2.

Stop horsing around, part 2.

--- src/lcmap/clownfish/state.clj
+++ src/lcmap/clownfish/state.clj
@@ -20,14 +20,14 @@
       (:body)))

 (defmethod retrieve :local [url]
-  (-> url io/resource slurp (json/decode true)))
+  (-> url io/resource slurp))

 (defstate tile-specs
   ;:start {:tile_x 10 :tile_y 10 :shift_x 0 :shift_y 0})
   :start (let [url (get-in config [:state :tile-specs-url])]
            (log/debug "Loading tile-specs")
            (try
-             (retrieve url)
+             (-> url retrieve (json/decode true))
              (catch Exception e
                (log/errorf e "Could not load tile-specs from: %s" url)
                (throw e)))))


deprecated flag ':overwrite-backup'.

deprecated flag ':overwrite-backup'.

--- src/leiningen/ancient/cli.clj
+++ src/leiningen/ancient/cli.clj
@@ -96,12 +96,13 @@

 (def ^:private deprecated
   "Flags that are no longer supported."
-  (->> {:aggressive     "all lookups are now aggressive"
-        :upgrade        "use task 'upgrade' instead"
-        :upgrade-global "use task 'upgrade-global' instead"
-        :get            "use task 'get' instead"
-        :dependencies   "since it is the default behaviour"
-        :verbose        "run 'DEBUG=1 lein ancient ...' instead"}
+  (->> {:aggressive       "all lookups are now aggressive"
+        :overwrite-backup "a backup file is no longer needed"
+        :upgrade          "use task 'upgrade' instead"
+        :upgrade-global   "use task 'upgrade-global' instead"
+        :get              "use task 'get' instead"
+        :dependencies     "since it is the default behaviour"
+        :verbose          "run 'DEBUG=1 lein ancient ...' instead"}
        (keys->strings)))

 (defn- unrecognized!


Set default proguard config path

Set default proguard config path

--- src/leiningen/droid/utils.clj
+++ src/leiningen/droid/utils.clj
@@ -111,6 +111,7 @@
         has-template (.exists manifest-template-file)]
     {:out-dex-path target-path
      :proguard-execute false
+     :proguard-conf-path "proguard.conf"
      :proguard-output-jar-path (str (file target-path "mininified-classes.jar"))
      :manifest-path (if has-template
                       (str (file target-path "AndroidManifest.xml"))


at least, a 'good' way to booleanify values

--- src/instapapure/articles.clj
+++ src/instapapure/articles.clj
@@ -43,15 +43,19 @@
 (defn get-article [id]
   (ds/get (article-key id)))

-(defn boolify [map klist]
+(defn modify-values [map fun klist]
+  "Apply a fun to the values in the map for the keys in klist"
   (reduce
     (fn [m k]
       (if (not (nil? (m k)))
-        (-> m (assoc k (Boolean. (m k))))
+        (assoc m k (fun (m k)))
         m))
     map klist))

+(defn booleanify [map klist]
+  (modify-values map #(Boolean. %) klist))
+
 (defn update-article [id params]
   (let [article (get-article id)]
-    (ds/put (boolify (merge article params) [:starred :unread]) (article-key id))))
+    (ds/put (booleanify (merge article params) [:starred :unread]) (article-key id))))


An even better answer

An even better answer

--- exercism/clojure/clock/src/clock.clj
+++ exercism/clojure/clock/src/clock.clj
@@ -1,13 +1,13 @@
 (ns clock)

-(defn clock [a b]
-  (let [q (Math/floorDiv b 60)
-        h (mod (+ a q) 24)
-        m (mod b 60)]
-    {:hours h :minutes m}))
+;; Per http://exercism.io/submissions/468867ee4cbd47ca83a4d850f3082e42,
+;; we represent clocks in terms of minutes

-(defn add-time [c n]
-  (clock (:hours c) (+ (:minutes c) n)))
+(defn- to-minutes [c] (mod c 1440))
+
+(defn clock [h m] (to-minutes (+ (* 60 h) m)))
+
+(defn add-time [c m] (to-minutes (+ c m)))

 (defn clock->string [c]
-  (format "%02d:%02d" (:hours c) (:minutes c)))
+  (format "%02d:%02d" (quot c 60) (mod c 60)))


Remove chat-sources logging from Slack

Remove chat-sources logging from Slack

--- src/yetibot/core/adapters/slack.clj
+++ src/yetibot/core/adapters/slack.clj
@@ -226,7 +226,6 @@
                 chat-sources (set (map (comp chat-source chan-or-group-name) chans-or-grps-for-user))
                 ; create a user model
                 user-model (users/create-user (:name user) active? (assoc user :mention-name (str "<@" (:id user) ">")))]
-            (info "chat-sources" chat-sources)
             (if (empty? chat-sources)
               (users/add-user-without-room (:adapter (base-chat-source)) user-model)
               (dorun


Fix roles on user registration.

Fix roles on user registration.

We were storing the role in the database incorrectly and not correctly
creating the :roles set in the authentications.

--- src/kixi/hecuba/security.clj
+++ src/kixi/hecuba/security.clj
@@ -126,7 +126,7 @@
     (if (and (= password confirm_password)
              (every? identity [name email password confirm_password])
              (not-registered? email store))
-      (do (add-user! store name email password #{::user})
+      (do (add-user! store name email password ::user)
           (assoc-in (redirect-after-post "/app")
                     [:session ::friend/identity]
                     {:current email
@@ -136,6 +136,7 @@
                                         :projects {}
                                         :programmes {}
                                         :role ::user
+                                        :roles #{::user}
                                         :username email
                                         :id email}}}))
       (redirect-after-post "/registration-error"))))


CEO-212 Refresh SSL Keystore every 60 seconds

--- src/clj/collect_earth_online/server.clj
+++ src/clj/collect_earth_online/server.clj
@@ -9,7 +9,8 @@
 (defonce server           (atom nil))
 (defonce clean-up-service (atom nil))

-(def expires-in "1 hour in msecs" (* 1000 60 60))
+(def ^:private expires-in "1 hour in msecs" (* 1000 60 60))
+(def ^:private keystore-scan-interval 60) ; seconds

 (defn- expired? [last-mod-time]
   (> (- (System/currentTimeMillis) last-mod-time) expires-in))
@@ -62,11 +63,12 @@
                         {:port  (:http-port options)
                          :join? false}
                         (when ssl?
-                          {:ssl?          true
-                           :ssl-port      https-port
-                           :keystore      "./.key/keystore.pkcs12"
-                           :keystore-type "pkcs12"
-                           :key-password  "foobar"}))]
+                          {:ssl?                   true
+                           :ssl-port               https-port
+                           :keystore               "./.key/keystore.pkcs12"
+                           :keystore-type          "pkcs12"
+                           :keystore-scan-interval keystore-scan-interval
+                           :key-password           "foobar"}))]
         (if (and (not has-key?) https-port)
           (println "ERROR:\n"
                    "  An SSL key is required if an HTTPS port is specified.\n"


Debug symbols removed from interceptors ns

--- src/clj/hellhound/http/interceptors.clj
+++ src/clj/hellhound/http/interceptors.clj
@@ -40,9 +40,4 @@
   (-> service-map
       (http/default-interceptors)
       (remove-unnecessary-interpretors)
-      (hellhound-interceptors)
-      ((fn [x]
-         (println "<<<<<<<<")
-         (println (keys x))
-         (clojure.pprint/pprint (::http/interceptors x))
-         x))))
+      (hellhound-interceptors)))


Introduce idea of multiple trigger points for each waypoint

--- src/cljs/comic_reader/ui/waypoints.cljs
+++ src/cljs/comic_reader/ui/waypoints.cljs
@@ -39,34 +39,45 @@
        offset-position)))

 (defn- make-reset-trigger-point [waypoints id options]
-  (fn [this]
+  (fn [node]
     (swap! waypoints assoc-in
            [id :trigger-point]
-           (get-node-position-at-offset (reagent/dom-node this) (:offset @options)))))
+           (get-node-position-at-offset node (:offset @options)))))
+
+(defn- make-trigger-points [waypoints opts]
+  (let [id (gensym "waypoint-id")
+        options (atom opts)]
+    [{:id id
+      :options options
+      :reset-trigger-point! (make-reset-trigger-point waypoints id options)}]))

 (defn waypoint
   ([child-el] (waypoint {} child-el))
   ([opts child-el]
-   (let [id (gensym "waypoint-id")
-         options (atom opts)
-         reset-trigger-point! (make-reset-trigger-point waypoints id options)]
+   (let [trigger-points (make-trigger-points waypoints opts)
+         reset-trigger-points! (fn [this]
+                                 (doseq [trigger-point trigger-points]
+                                   ((:reset-trigger-point! trigger-point) (reagent/dom-node this))))]
      (reagent/create-class
       {:display-name "waypoint"

        :component-will-mount
        (fn []
-         (swap! waypoints assoc id {:options options}))
+         (doseq [trigger-point trigger-points]
+           (swap! waypoints assoc (:id trigger-point) (select-keys trigger-point [:options]))))

        :component-will-unmount
        (fn []
-         (swap! waypoints dissoc id))
+         (doseq [trigger-point trigger-points]
+           (swap! waypoints dissoc (:id trigger-point))))

-       :component-did-mount reset-trigger-point!
-       :component-did-update reset-trigger-point!
+       :component-did-mount  reset-trigger-points!
+       :component-did-update reset-trigger-points!

        :reagent-render
        (fn [opts child-el]
-         (reset! options opts)
+         (doseq [trigger-point trigger-points]
+           (reset! (:options trigger-point) opts))
          child-el)}))))

 (defn- page-offset []


Provide fallback reduction as an Object extension instead of IFn.

The implementation for the "class" (the function in question) given
one of fluokitten's protocol is chosen:
1) if it directly implements the protocol => (fn ...) doesn't,
2) if one of its direct super-classes implements the protocol
    => in order fn itself, AFunction and AFn don't,
3) if Clojure can find one implementation by the following algorithm:
    a) get all clojure.core/supers of "class" as a set,
    b) iterate over the set (i.e. the order is unknown) to keep only
       implementors of the protocol),
    c) reduces the sequence of implementors left-to-right (the order
       is stable now but it is still unknown) and it either prefers
       the current / the first result or the second if the latter
       is more specific as tested by Class/isAssignableFrom.
       The IFn or IFn$... interfaces are in no such relation
       so it is always false and the reduction prefers always
       the first implementation found,
4) fallback to Object if nothing was found so far.

The important outcome is that it doesn't always work for primitive
functions. It can pick either the specific IFn$... implementation
(which is often the case) or the generic IFn implementation.
 The IFn doesn't have to fail it can work and even return the correct
 answer but it'll use a suboptimal implementation.

However we can take advantage of #4 above - that is let Object be
the fallback implementation instead of IFn.

Signed-off-by: Kamil Toman <4781defe6238d61a1d3bb5df5fe17b0af0f2218d@leafclick.com>

--- src/clojure/uncomplicate/neanderthal/internal/host/fluokitten.clj
+++ src/clojure/uncomplicate/neanderthal/internal/host/fluokitten.clj
@@ -442,7 +442,7 @@

 ;; ============================ Primitive function extensions ==================

-(extend-type IFn
+(extend-type Object
   ReductionFunction
   (vector-reduce
     ([this init x]


test hook

test hook

--- src/main/cawala/api/read.clj
+++ src/main/cawala/api/read.clj
@@ -6,7 +6,7 @@
                      :person/relation :friend}
                  2  {:db/id 2 :person/name "Sally" :person/age 22
                      :person/relation :friend}
-                 3  {:db/id 3 :person/name "Allie" :person/age 67
+                 3  {:db/id 3 :person/name "Allie" :person/age 66
                      :person/relation :enemy}
                  4  {:db/id 4 :person/name "Zoe" :person/age 32
                      :person/relation :friend}


Table sorting reversable fix #24

Table sorting reversable fix #24

--- frontend/src/cruncher/utils/lib.cljs
+++ frontend/src/cruncher/utils/lib.cljs
@@ -23,6 +23,7 @@
 (declare get-pokemon-by-id)
 (declare evolution-sum)

+(defonce sort-direction-asc (atom true))
 ;;;; React compatibility
 (defonce counter (atom 0))

@@ -66,8 +67,8 @@

 (defmethod mutate 'sort/pokemon
   [{:keys [state]} _ {:keys [key]}]
-  {:action (fn [] (swap! state update-in [:pokemon] (fn []
-                                                      (reverse (sort-by (juxt key :individual_percentage :cp) (:pokemon @state))))))})
+  {:action (fn [] (swap! state update-in [:pokemon] (fn [] (cond-> (sort-by (juxt key :individual_percentage :cp) (:pokemon @state))
+                                                      (swap! sort-direction-asc not) reverse))))})

 (defmethod mutate 'change/view
   [{:keys [state]} _ {:keys [view]}]


Fixed syllable processing and added positional support.

--- src/hxgm30/language/syntagmata/core.clj
+++ src/hxgm30/language/syntagmata/core.clj
@@ -3,54 +3,86 @@
     [clojure.java.io :as io]
     [clojure.set :as set]
     [clojure.string :as string]
-    [hxgm30.language.syntagmata.corpus :as corpus]))
+    [hxgm30.language.syntagmata.corpus :as corpus]
+    [hxgm30.language.syntagmata.lang.core :as lang]
+    [hxgm30.language.syntagmata.util :as util]))
+
+(defn pseudo-syllables
+  ""
+  [language words]
+  (map (comp #(if (= % []) [""] %)
+             #(string/split % #"_")
+             #(string/replace % (re-pattern (str (corpus/re-vowel language) "+")) "_"))
+       words))
+
+(defn pseudo-syllable-counts
+  ""
+  [language words]
+  (map count (pseudo-syllables language words)))

 (defn pseudo-syllable-freqs
-  "Create a lookup of key/value pairs where the key is the number
+  "The intent of this function is to provide information regarding how many
+  pseudo-syllables occur in the words of a corpus, ultimately giving a
+  statistical view of word length.
+
+  Create a lookup of key/value pairs where the key is the number
   pseudo-syllables and the associated value is the number of times the given
   pseudo-syllable occurs."
   [language words]
-  (->> words
-       (map (comp inc
-                  count
-                  #(string/split % #"_")
-                  #(string/replace % (re-pattern (str (corpus/re-vowel language) "+")) "_")))
-       frequencies))
+  (frequencies (pseudo-syllable-counts language words)))

-(defn frequency->percent-range
-  "A reducer that, given a frequency and an accumulator, returns an updated
-  accumulator with the given frequency converted to a percent range. The first
-  argument is expectred to be provided as a partial."
-  [total acc [k v]]
-  (let [last-value (or (last (first (last acc))) 0)
-        v-percent (/ v total)]
-    (conj acc [[last-value (+ v-percent last-value)] k])))
-
-(defn frequencies->percent-ranges
-  "Create a lookup of key/value pairs where the key is the range of percentages
-  where a syllable count occurs, and the value is the syllable count."
-  [freqs]
-  (let [total (reduce + 0.0 (vals freqs))]
-    (->> freqs
-         (reduce (partial frequency->percent-range total) [])
-         (into {}))))
-
-(defn sound-transition-freqs
+(defn sound-transitions
   ""
   [language words]
   (->> words
-       (mapcat #(re-seq (re-pattern (corpus/re-sound-transition language)) %))
-       frequencies))
+       (map (comp #(remove nil? %)
+                  #(mapcat rest %)
+                  #(re-seq (re-pattern (corpus/re-sound-transitions language)) %)))))

-(defn stats
+(defn flat-sound-transitions
+  [language words]
+  (flatten (sound-transitions language words)))
+
+(defn positional-sound-transitions
+  [position transitions]
+  (case position
+    :initial (map first transitions)
+    :final (remove nil? (map (comp last rest) transitions))
+    (mapcat (comp butlast rest) transitions)))
+
+(defn positional-sound-transition-freqs
+  [position transitions]
+  (frequencies (positional-sound-transitions position transitions)))
+
+(defn generate-stats
   ""
   [language]
   (let [words (corpus/load-wordlist language)
         pseudo-syllable-freqs (pseudo-syllable-freqs language words)
-        sound-transition-freqs (sound-transition-freqs language words)]
+        transitions (sound-transitions language words)
+        initial (positional-sound-transition-freqs :initial transitions)
+        medial (positional-sound-transition-freqs :medial transitions)
+        final (positional-sound-transition-freqs :final transitions)]
     {:pseudo-syllables {
       :frequencies pseudo-syllable-freqs
-      :percent-ranges (frequencies->percent-ranges pseudo-syllable-freqs)}
+      :percent-ranges (util/frequencies->percent-ranges pseudo-syllable-freqs)}
      :sound-transitions {
-      :frequencies sound-transition-freqs
-      :percent-ranges (frequencies->percent-ranges sound-transition-freqs)}}))
+       :initial {
+         :frequencies initial
+         :percent-ranges (util/frequencies->percent-ranges initial)}
+       :medial {
+         :frequencies medial
+         :percent-ranges (util/frequencies->percent-ranges medial)}
+       :final {
+         :frequencies final
+         :percent-ranges (util/frequencies->percent-ranges final)}}}))
+
+(defn regen-stats
+  []
+  (run!
+    (for [language lang/supported]
+      (corpus/dump :stats language (generate-stats language)))))
+
+(defn stats
+  [language]
+  (corpus/undump :stats language))


putting back my-addresses-loaded

putting back my-addresses-loaded

--- src/name_bazaar/ui/core.cljs
+++ src/name_bazaar/ui/core.cljs
@@ -46,7 +46,7 @@
                    :effects
                    {:async-flow {:first-dispatch [:district0x/load-smart-contracts {:version constants/contracts-version}]
                                  :rules [{:when :seen?
-                                          :events [:district0x/smart-contracts-loaded]
+                                          :events [:district0x/smart-contracts-loaded :district0x/my-addresses-loaded]
                                           :dispatch-n [[:district0x/watch-my-eth-balances]
                                                        [:try-resolving-address]
                                                        [:active-page-changed]]}]}


[test] plot clusters only in a separate heatmap

--- test/clj_dstream/generative_test.clj
+++ test/clj_dstream/generative_test.clj
@@ -48,7 +48,7 @@
   (->> (for [y (range 10) x (range 50)] (n/noise2 (* x 0.1) (* y 0.25)))
        (viz/matrix-2d 50 10)))

-(defn grids-2d->heatmap-vec [grid-cells props]
+(defn grids-2d->heatmap-vec [grid-cells props & {:keys [clusters-only]}]
   (let [phase-space (::core/phase-space props)
         d1          (first phase-space)
         d2          (second phase-space)
@@ -59,8 +59,20 @@

     (let [vecs
           (for [c (range cols) r (range rows)]
-            (let [num (or (::core/density-at-last-update (get grid-cells [r c]))
-                          0.0)]
+            (let [num (or
+                        (when clusters-only
+                          (do
+                            (println "clusers only")
+                            (let [cluster (::core/cluster (get grid-cells [r c]))]
+                              (println "cluster:" cluster)
+                              (if (and (not (= nil cluster))
+                                       (not (= "NO_CLASS" cluster)))
+                                (do
+                                  (println "cluster: " cluster)
+                                  (::core/density-at-last-update (get grid-cells [r c])))
+                                0.0))))
+                        (::core/density-at-last-update (get grid-cells [r c]))
+                        0.0)]
               num
               ))]
       {:matrix (->>
@@ -103,26 +115,25 @@
        (spit (str prefix "-" (name id) ".svg"))))

 (defn display-state [props grid-cells]
-  #_(let [cluster-positions (remove nil? (map (fn [[pos-idx char-vec]]
+  (if (= 2 (::core/dimensions props))
+    (let [hm1 (grids-2d->heatmap-vec grid-cells props)
+          hm2 (grids-2d->heatmap-vec grid-cells props :clusters-only true)]
+
+      (cartesian-viz "hm" :rainbow2 (:matrix hm1) (:cols hm1) (:rows hm1))
+      (cartesian-viz "hm" :rainbow2 (:matrix hm2) (:cols hm2) (:rows hm2)))
+    (let [cluster-positions (remove nil? (map (fn [[pos-idx char-vec]]
                                                 (let [cluster (::core/cluster char-vec)]
                                                   (if-not (or (= nil cluster)
                                                               (= "NO_CLASS" cluster))
                                                     pos-idx)))
-                                              grid-cells))]
-      (if (= 2 (::core/dimensions props))
-        {"none" cluster-positions}
-        (let [_            (println "cluster positions: " cluster-positions)
-              input-matrix (matrix/array :vectorz cluster-positions)
-              _            (println "input mat;" input-matrix)
-              algo-name    :parallel-bht
-              _            (println "tsne: " algo-name)
-              output-map   {algo-name (tsne/tsne input-matrix 2 :tsne-algorithm algo-name :perplexity 0.01)}]
-          output-map)))
-  (let [hm1 (grids-2d->heatmap-vec grid-cells props)
-        hm2 (grids-2d->heatmap-vec grid-cells props)]
-
-    (cartesian-viz "hm" :rainbow2 (:matrix hm1) (:cols hm1) (:rows hm1))
-    (cartesian-viz "hm" :orange-blue (:matrix hm2) (:cols hm2) (:rows hm2)))
+                                              grid-cells))
+          _                 (println "cluster positions: " cluster-positions)
+          input-matrix      (matrix/array :vectorz cluster-positions)
+          _                 (println "input mat;" input-matrix)
+          algo-name         :parallel-bht
+          _                 (println "tsne: " algo-name)
+          output-map        {algo-name (tsne/tsne input-matrix 2 :tsne-algorithm algo-name :perplexity 0.01)}]
+      output-map))
   )

@@ -130,41 +141,43 @@

 (deftest stuff
-  (let [test-props   {
-                      ::core/c_m         3.0
+  (let [test-props   {::core/c_m         3.0
                       ::core/c_l         0.8
                       ::core/lambda      0.998
                       ::core/beta        0.3
                       ::core/dimensions  2
                       ::core/phase-space [
-                                          {::core/domain-start    -2.5
-                                           ::core/domain-end      2.5
+                                          {::core/domain-start    -1.0
+                                           ::core/domain-end      1.0
                                            ::core/domain-interval 0.1}
-                                          {::core/domain-start    -2.5
-                                           ::core/domain-end      2.5
+                                          {::core/domain-start    -1.0
+                                           ::core/domain-end      1.0
                                            ::core/domain-interval 0.1}]
-                      ::core/gap-time    250}
-        ;centroids    (vec (repeatedly 4 (fn [] (get-random-sample :unifrom test-props))))
-        ;_            (println "centroids: " centroids)
-        samples      (repeatedly 50000 #(hash-map
-                                         ::core/raw-datum
-                                         {::core/position-value
-                                                       (vec
-                                                         (take
-                                                           (::core/dimensions test-props)
-                                                           (repeatedly
-                                                             (fn []
-
-                                                               (if (> 0.5 (rand))
-                                                                 (+ 0.1
-                                                                    (* 0.15
-                                                                       (first
-                                                                         (random/sample-normal 1))))
-                                                                 (+ 0.9
-                                                                    (* 0.25
-                                                                       (first
-                                                                         (random/sample-normal 1)))))))))
-                                          ::core/value 1.0}))
+                      ::core/gap-time    100}
+        samples      (repeatedly 10000 #(hash-map
+                                          ::core/raw-datum
+                                          {::core/position-value
+                                                        (vec
+                                                          (take
+                                                            (::core/dimensions test-props)
+                                                            (repeatedly
+                                                              (fn []
+                                                                (let [r (rand)]
+                                                                  (cond (<= 0.0 r 0.9) (+ 0.1
+                                                                                (* 0.1
+                                                                                (first
+                                                                                (random/sample-normal 1))))
+                                                                        (<= 0.9 r 0.95) (-
+                                                                                (* 0.05
+                                                                                (first
+                                                                                (random/sample-normal 1)))
+                                                                                0.3)
+                                                                        (<= 0.95 r 1.0) (+
+                                                                                (* 0.05
+                                                                                (first
+                                                                                (random/sample-normal 1)))
+                                                                                0.3)))))))
+                                           ::core/value 1.0}))

         test-state   {::core/state {::core/grid-cells           {}
                                     ::core/properties           test-props
@@ -178,6 +191,6 @@
     ;;TODO abandon tsne for a simple dxd grid of 2d scatter plots

     (clojure.pprint/pprint displayable)
-    ;(clojure.pprint/pprint sorted-stats)
+    (clojure.pprint/pprint sorted-stats)
     )
   )


a couple more bad example tests

a couple more bad example tests

--- test/dynamodb_expression/grammar.clj
+++ test/dynamodb_expression/grammar.clj
@@ -51,4 +51,6 @@
     (is (vector? (parse "REMOVE MyNumbers[1], MyNumbers[3]"))))

   (testing "Badly-formed examples don't parse"
-    (is (map? (parse "foo")))))
+    (is (map? (parse "foo")))
+    (is (map? (parse "SET list[0] = :val1, REMOVE #m.nestedField1, #m.nestedField2")))
+    (is (map? (parse "SET list[0] = :val1 REMOVE #m.nestedField1 #m.nestedField2")))))


New test: test-log-request-verbose-mode

New test: test-log-request-verbose-mode

--- test/emender_jenkins/server_test.clj
+++ test/emender_jenkins/server_test.clj
@@ -149,10 +149,16 @@
     "Check the function emender-jenkins.server/log-request."
     (testing "the function emender-jenkins.server/log-request."
         (with-redefs [log/log* (fn [logger level throwable message] message)]
-        (are [x y] (= x y)
-            "Handling request:  nil nil"                 (log-request {})
-            "Handling request:  http://test nil"         (log-request {:uri "http://test"})
-            "Handling request:  nil 10.20.30.40"         (log-request {:remote-addr "10.20.30.40"})
-            "Handling request:  http://test 10.20.30.40" (log-request {:uri "http://test" :remote-addr "10.20.30.40"})
-            ))))
+            (are [x y] (= x y)
+                "Handling request:  nil nil"                 (log-request {})
+                "Handling request:  http://test nil"         (log-request {:uri "http://test"})
+                "Handling request:  nil 10.20.30.40"         (log-request {:remote-addr "10.20.30.40"})
+                "Handling request:  http://test 10.20.30.40" (log-request {:uri "http://test" :remote-addr "10.20.30.40"})))))

+(deftest test-log-request-verbose-mode
+    "Check the function emender-jenkins.server/log-request."
+    (testing "the function emender-jenkins.server/log-request."
+        (with-redefs [log/log* (fn [logger level throwable message] message)]
+            (let [request  {:uri "http://test" :remote-addr "10.20.30.40" :configuration {:config {:verbose true :pretty-print false}}}]
+                (is (.startsWith (log-request request) "Handling request:  {"))))))
+


rum mixins

rum mixins

--- src/om_bootstrap/mixins.cljs
+++ src/om_bootstrap/mixins.cljs
@@ -27,12 +27,14 @@
 (def set-listener-mixin
   "Handles a sequence of listeners for the component, and removes them
    from the document when the component is unmounted."
-  {:will-mount (fn [state] (set! (.-listeners (:rum/react-component state)) #js []))
-   :will-unmount (fn [state] (.. (:rum/react-component state) -listeners (map #(%))))})
+  {:will-mount (fn [state]
+                 (assoc state ::listeners (atom [])))
+   :will-unmount (fn [state]
+                   (update state ::listeners swap! (map #(%))))})

 (defn set-listener [state target event-type callback]
   (let [remove-fn (event-listener target event-type callback)]
-    (.push (.-listeners (:rum/react-component state)) remove-fn)))
+    (update state ::listeners swap! conj remove-fn)))

 ;; ## Timeout Mixin

@@ -59,52 +61,50 @@

 (def ESCAPE_KEY 27)

+(declare set-dropdown-state)
+
 (defn bind-root-close-handlers!
   "For dropdowns, binds a handler for that sets the dropdown-mixin's
   `:open?` state to false if the user clicks outside the owning
   component OR hits the escape key."
-  [owner]
-  (let [set-state (aget owner "setDropdownState")]
-    (set! (.-dropdownListeners owner)
-          (array
-           (event-listener
-            js/document "click"
-            (fn [e]
-              (when-not (in-root? (.-target e) (om/get-node owner))
-                (set-state false))))
-           (event-listener
-            js/document "keyup"
-            (fn [e]
-              (when (= ESCAPE_KEY (.-keyCode e))
-                (set-state false))))))))
+  [state]
+  (assoc state ::dropdown-listeners
+         (array
+          (event-listener
+           js/document "click"
+           (fn [e]
+             (when-not (in-root? (.-target e) (.getDOMNode (:rum/react-component state)))
+               (set-dropdown-state state false))))
+          (event-listener
+           js/document "keyup"
+           (fn [e]
+             (when (= ESCAPE_KEY (.-keyCode e))
+               (set-dropdown-state state false)))))))

 (defn unbind-root-close-handlers!
   "If they're present on the owning object, removes the listeners
   registered by the dropdown mixin."
-  [owner]
-  (when-let [listeners (.-dropdownListeners owner)]
-    (map #(%) listeners)
-    (set! (.-dropdownListeners owner) nil)))
+  [state]
+  (update state ::dropdown-listeners
+          (comp (constantly nil)
+                (partial map #(%)))))

-(defmixin dropdown-mixin
+(def dropdown-mixin
   "Mixin that manages a single piece of state - :open?. If a user
   clicks outside the component's owning dom element OR hits the escape
   key, the state will jump back to false.

   Down the road this may need to register a callback when the state
   changes."
-  (init-state [_] {:open? false})
-  (will-unmount [owner] (unbind-root-close-handlers! owner))
-  ;; This function exists because om-tools mixins can't share state
-  ;; with the component that uses them:
-  ;; https://github.com/Prismatic/om-tools/issues/28
-  (isDropdownOpen [owner] (om/get-state owner :open?))
-  (setDropdownState
-   [owner open?]
-   (if open?
-     (bind-root-close-handlers! owner)
-     (unbind-root-close-handlers! owner))
-   (om/set-state! owner [:open?] open?)))
+  {:init (fn [state props] (assoc state :open? (atom false)))
+   :will-unmount (fn [state] (unbind-root-close-handlers! state))})
+
+(defn set-dropdown-state
+  [state open?]
+  (if open?
+    (bind-root-close-handlers! state)
+    (unbind-root-close-handlers! state))
+  (update state :open? reset! open?))

 (defmixin collapsible-mixin
   "Mixin that enables collapsible Panels. Similar to the Dropdown


Fixes a bug when not specifying a scale.

--- src/overtone/music/pitch.clj
+++ src/overtone/music/pitch.clj
@@ -265,7 +265,7 @@
   i.e. the ionian/major scale has an interval sequence of 2 2 1 2 2 2 1
        therefore the 4th degree is (+ 2 2 1 2) semitones from the start of the
        scale."
-  ([n] (nth-interval :scale n))
+  ([n] (nth-interval :diatonic n))
   ([scale n]
      (reduce + (take n (cycle (scale SCALE))))))