failed attempt at #150

failed attempt at #150

error: pathspec 'Alfa/src/alfa/under200/two.clj' did not match any file(s) known to git

--- Alfa/src/alfa/under200/two.clj
+++ Alfa/src/alfa/under200/two.clj
@@ -0,0 +1,42 @@
+(ns alfa.under200.two
+  (:require
+    [clojure.set :refer [union difference intersection subset?]]
+    [clojure.core.reducers :as r]
+    [clojure.string :refer [split-lines]]
+    [alfa.common :refer :all]
+    [clojure.string :as cs]))
+
+;; Problem 150
+
+(defonce
+  matrix
+  (let [tar (expt 2 20)
+        modi (expt 2 19)
+        mentah (loop [t 0 k (int 0) res []]
+                 (if (> k 500500)
+                   (rest res)
+                   (recur (mod (+' 797807 (*' 615949 t)) tar)
+                          (+ k 1)
+                          (conj res (- t modi)))))]
+    (loop [awal mentah res [] i (int 1)]
+      (if (empty? awal)
+        res
+        (recur (drop i awal)
+               (conj res (vec (take i awal)))
+               (+ i 1))))))
+
+(defn sub-triangle
+  [a b]
+  (if (== a 999)
+    {:total (get-in matrix [a b])
+     :left  0
+     :right 0}
+    (let [left (sub-triangle (+ a 1) b)
+          right (sub-triangle (+ a 1) (+ b 1))]
+      {:total (- (+ (get-in matrix a b) (:total left)
+                    (:total right))
+                 (:right left)) :left (:total left)
+       :right (:total right)})))
+
+
+


Update readme test

Update readme test

--- src/test/clojure/pigpen/README_test.clj
+++ src/test/clojure/pigpen/README_test.clj
@@ -179,9 +179,7 @@
                       (pig/map (fn [x] (* x x)))
                       (pig/filter odd?)
                       (pig/store-clj "odd-squares.clj"))]
-    (->>
-      (pig/script even-squares odd-squares)
-      (pig/show))))
+    (pig/script even-squares odd-squares)))


for database

for database

error: pathspec 'src/adder/dbManagement.clj' did not match any file(s) known to git

--- src/adder/dbManagement.clj
+++ src/adder/dbManagement.clj
@@ -0,0 +1,85 @@
+(ns adder.dbManagement
+  (:require [clojure.java.jdbc :as sql]))
+
+
+(def db {:classname "com.mysql.jdbc.Driver"
+         :subprotocol "mysql"
+         :subname "//localhost:3306/watchlist"
+         :user "root"
+         :password ""})
+
+;(defn list-movies []
+ ; (sql/with-connection db
+  ;  (sql/with-query-results rows
+   ;   ["select * from flick"]
+      ;(println rows)
+    ;  )))
+
+
+
+
+(defn list-one-film-from-series [id sid]
+  (flatten (sql/with-connection db
+    (sql/with-query-results row
+      ["select * from flick where id = ? and series =?" id]
+      (doall row)))))
+
+
+
+
+
+(defn list-all-movies-from-serie [sid]
+  (flatten (sql/with-connection db
+    (sql/with-query-results row
+      ["select * from flick where series =?" sid]
+      (doall row)))))
+
+(defn list-movies []
+  (flatten (sql/with-connection db
+    (sql/with-query-results rows
+      ["select * from flick"]
+      (doall rows)))))
+
+(defn list-one-film [id]
+  (flatten (sql/with-connection db
+    (sql/with-query-results row
+      ["select * from flick where id = ?" id]
+      (doall row)))))
+
+(defn insert-flick [name Producer duration series]
+  (sql/with-connection db (sql/insert-values :flick [:name :Producer :duration :series] [name Producer  duration series])))
+
+(defn update-flick [id update-map]
+  (sql/with-connection db
+    (sql/update-values :flick ["id=?" id] update-map)))
+
+(defn delete-flick [id]
+  (sql/with-connection db
+    (sql/delete-rows :flick ["id=?" id])))
+
+
+(defn list-one-series [id]
+  (flatten (sql/with-connection db
+    (sql/with-query-results row
+      ["select * from series where Series_ID = ?" id]
+      (doall row)))))
+
+;(defn save-film )
+
+
+(defn list-series []
+  (flatten (sql/with-connection db
+    (sql/with-query-results rows
+      ["select * from series"]
+      (doall rows)))))
+
+(defn insert-serie [series_name series_production]
+  (sql/with-connection db (sql/insert-values :series [:series_name :series_production] [series_name series_production])))
+
+(defn update-serie [id update-map]
+  (sql/with-connection db
+    (sql/update-values :series ["Series_ID=?" id] update-map)))
+
+(defn delete-series [id]
+  (sql/with-connection db
+    (sql/delete-rows :series ["Series_ID=?" id])))


Make ocd-id level regexes more robust

Make ocd-id level regexes more robust

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/voter-registration-works.git/'


Teardrop Rainbow (with @scripttease)

Teardrop Rainbow (with @scripttease)

error: pathspec 'src/art/teardrop_rainbow.clj' did not match any file(s) known to git

--- src/art/teardrop_rainbow.clj
+++ src/art/teardrop_rainbow.clj
@@ -0,0 +1,53 @@
+(ns art.teardrop-rainbow
+  (:require [quil.core :as q]
+            [quil.middleware]))
+
+(def width  810)
+(def height 540)
+; (def width 1080)
+; (def height 720)
+
+(defn random-color []
+  (+ 40 (rand-int 215)))
+
+(defn teardrop [x y size]
+  (let [half (* 0.5 size)]
+    (q/arc x y size size (q/radians 0) (q/radians 180))
+    (q/triangle (- x half) y
+                x (- y size)
+                (+ x half) y)))
+
+(defn render []
+  (let [x (rand-int (q/width))
+        y (rand-int (q/height))
+        r (random-color)
+        g (random-color)
+        b (random-color)]
+    (q/fill r g b)
+    (teardrop x y 50)
+    ))
+
+(defn setup []
+  (q/fill 0 0)
+  (q/no-stroke)
+  (q/background 255)
+  ; (render)
+  )
+
+(defn step [state] state)
+
+(defn draw [state]
+  (render)
+  )
+
+(defn run []
+  (q/defsketch example
+    :title "Art!"
+    :middleware [quil.middleware/fun-mode]
+    :settings #(q/smooth 2)
+    :setup setup
+    :update step
+    :draw draw
+    :size [width height]
+    ))
+(run)


Draft parameter coercion

Draft parameter coercion

error: pathspec 'src/yada/schema.cljc' did not match any file(s) known to git

--- src/yada/schema.cljc
+++ src/yada/schema.cljc
@@ -0,0 +1,69 @@
+(ns yada.schema
+  (:require
+   [plumbing.core]
+   [schema.core :as s #?@(:cljs [:include-macros true])]
+   [schema.coerce :refer [coercer
+                          string->keyword
+                          keyword-enum-matcher
+                          set-matcher
+                          json-coercion-matcher]])
+  (:import [schema.core RequiredKey OptionalKey]
+           [clojure.lang Keyword]))
+
+(def +x-json-coercions+
+  schema.coerce/+json-coercions+)
+
+(defprotocol ParameterKey
+  (to-key [_])
+  (to-fn [_]))
+
+(extend-protocol ParameterKey
+  OptionalKey
+  (to-key [o] (to-key (:k o)))
+  (to-fn [o] (to-fn (:k o)))
+  RequiredKey
+  (to-key [o] (to-key (:k o)))
+  (to-fn [o] (to-fn (:k o)))
+  Keyword
+  (to-key [k] (name k))
+  (to-fn [k] string->keyword)
+  String
+  (to-key [s] s)
+  (to-fn [s] identity))
+
+(defn kw-map-matcher [schema]
+  (if (instance? clojure.lang.APersistentMap schema)
+    (let [fns (into {}
+                    (for [k (keys schema)]
+                      [(to-key k) (to-fn k)]))]
+      (fn [x]
+        (if (map? x)
+          (->> x
+               (map (fn [[k v]] [((get fns k identity) k) v]))
+               (into {}))
+          x)))))
+
+(defn keyword->string [k]
+  (if (keyword? k) (name k) k))
+
+(defn multiple-args-matcher [schema]
+  (when (instance? clojure.lang.APersistentVector schema)
+    (fn [x]
+      (if (not (sequential? x)) [x] x))))
+
+(defn x-json-coercion-matcher
+  "A matcher that coerces keywords and keyword enums from strings, and longs and doubles
+     from numbers on the JVM (without losing precision)"
+  [schema]
+  (or (+x-json-coercions+ schema)
+      (keyword-enum-matcher schema)
+      (set-matcher schema)
+      (multiple-args-matcher schema)
+      (kw-map-matcher schema)))
+
+((coercer {(s/optional-key "first.name") s/Str
+           :surname s/Str
+           :phone [s/Str]
+           } x-json-coercion-matcher)
+ {"phone" ["789"] "first.name" "Frank" "surname" "Briggs"}
+ )


Make component stops idempotent.

Make component stops idempotent.

--- src/incise/server.clj
+++ src/incise/server.clj
@@ -69,18 +69,24 @@
   (start [this]
     (assoc this :server (serve-nrepl port)))
   (stop [this]
-    (nrepl/stop-server server)
-    (.delete (get-nrepl-port-file))
-    (info "Stopped nREPL server on port" port)
-    (assoc this :server nil)))
+    (if server
+      (do
+        (nrepl/stop-server server)
+        (.delete (get-nrepl-port-file))
+        (info "Stopped nREPL server on port" port)
+        (assoc this :server nil))
+      this)))

 (defrecord HttpServer [port stop-server]
   component/Lifecycle
   (start [this] (assoc this :stop-server (serve)))
   (stop [this]
-    (stop-server)
-    (report "Stopped HTTP server on port" port)
-    (assoc this :stop-server nil)))
+    (if stop-server
+      (do
+        (stop-server)
+        (report "Stopped HTTP server on port" port)
+        (assoc this :stop-server nil))
+      this)))

 (defn create-http-server []
   (map->HttpServer {:port (conf/get :port)}))


Making sure that pub-keys are x962-encoded when deriving sins

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/xcthulhu/clj-bitauth.git/'


beginnings of default core

beginnings of default core

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/transwarp.git/'


views: add link to unit detail view

views: add link to unit detail view

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/pyr/bundes.git/'


detail view

detail view

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/kenichirow/recipes.git/'


whoops, UTM query string addition is screwed up...hopefully we don't need anything smarter than this!

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-notification-works.git/'


add compose

add compose

error: pathspec 'src/functions/compose.cljc' did not match any file(s) known to git

--- src/functions/compose.cljc
+++ src/functions/compose.cljc
@@ -0,0 +1,9 @@
+(ns functions.compose)
+
+
+(def process-strings
+  (comp keyword #(.toLowerCase %) name))
+
+(comment
+  (map process-strings '(a B W)))
+


Support gdb write

Support gdb write

error: pathspec 'gdbwrite.boot' did not match any file(s) known to git

--- gdbwrite.boot
+++ gdbwrite.boot
@@ -0,0 +1,2 @@
+target remote localhost:3333
+load


Removed views.clj

Removed views.clj

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aneeshpu/pms.git/'


First draft

First draft

--- lazytest.clj
+++ lazytest.clj
@@ -0,0 +1,145 @@
+;;; TEST2: a new testing framework for Clojure
+
+;; by Stuart Sierra, http://stuartsierra.com/
+;; February 18, 2010
+
+;; Copyright (C) 2010 Stuart Sierra.
+
+;; The use and distribution terms for this software are covered by the
+;; Eclipse Public License 1.0
+;; <http://opensource.org/licenses/eclipse-1.0.php>.  By using this
+;; software in any fashion, you are agreeing to be bound by the terms
+;; of this license.  You must not remove this notice, or any other,
+;; from this software.
+
+
+(ns clojure.test2)
+
+(def *active-contexts* {})
+
+(defprotocol Successful
+  (success? [r] "Returns true if the result r was 100% successful."))
+
+(deftype Assertion [form])
+
+(deftype Test [locals contexts assertions])
+
+(deftype Context [before after])
+
+(deftype Suite [contexts tests])
+
+(deftype AssertionSuccess [assertion]
+  Successful (success? [] true))
+
+(deftype AssertionFailure [assertion]
+  Successful (success? [] false))
+
+(deftype AssertionThrown [assertion throwable]
+  Successful (success? [] false))
+
+(deftype TestResult [test assertion-results]
+  Successful (success? [] (every? success? assertion-results)))
+
+(deftype SuiteResult [suite test-results]
+  Successful (success? [] (every? success? test-results)))
+
+(defn context?
+  "Returns true if x is a Context."
+  [x]
+  (= ::Context (type x)))
+
+(defn test?
+  "Returns true if x is a Test."
+  [x]
+  (= ::Test (type x)))
+
+(defn suite?
+  "Returns true if x is a Suite."
+  [x]
+  (= ::Suite (type x)))
+
+(defn- format-assertion [expr]
+  `(try (if ~expr
+          (AssertionSuccess (quote ~expr))
+          (AssertionFailure (quote ~expr)))
+        (catch Throwable t#
+          (AssertionThrown (quote ~expr) t#))))
+
+(defn- format-test [t]
+  {:pre [(test? t)
+         (vector? (:locals t))
+         (every? symbol? (:locals t))]}
+  `(fn ~(:locals t)
+     (list ~@(map format-assertion (:assertions t)))))
+
+(defn- compile-test* [t]
+  (eval (format-test t)))
+
+(def #^{:doc "Compile a Test to a function of its locals. (memoized)"
+        :arglists '([t])}
+     compile-test (memoize compile-test*))
+
+(defn- open-context
+  "Calls Context c's :before function, returns result."
+  [c]
+  (or (*active-contexts* c)
+      (when-let [f (:before c)]
+        (f))))
+
+(defn- close-context
+  "Calls Context c's :after function on state."
+  [c state]
+  (when-not (contains? *active-contexts* c)
+    (when-let [f (:after c)]
+      (f state))))
+
+(defn call-with-contexts
+  "Applies f to the result of opening all contexts,
+  then closes contexts in reverse order."
+  [contexts f]
+  {:pre [(every? context? contexts)]}
+  (let [states (map open-context contexts)
+        result (binding [*active-contexts*
+                         (merge *active-contexts*
+                                (zipmap contexts states))]
+                 (apply f states))]
+    (dorun (map close-context
+                (reverse contexts) (reverse states)))
+    result))
+
+(defn run-test
+  "Run a Test t, return a TestResult."
+  [t]
+  {:pre [(test? t)]}
+  (TestResult t (call-with-contexts (:contexts t)
+                  (compile-test t))))
+
+(defn run-suite
+  "Run a Suite s, return a SuiteResult."
+  [s]
+  (SuiteResult s (call-with-contexts (:contexts s)
+                   (fn [& _]
+                     (doall (map run-test (:tests s)))))))
+
+
+;;; USAGE:
+
+(def c1 (Context (fn [] 1) nil))
+
+(def c2 (Context (fn [] 2) nil))
+
+(def t1 (Test '[a b] [c1 c2] '[(integer? a) (integer? b)]))
+
+(def t2 (Test '[a b] [c1 c2] '[(> b a) (< a b)]))
+
+(def s1 (Suite [c1] [t1 t2]))
+
+;; user=> (run-suite s1)
+;; ...
+;; user=> (success? *1)
+;; true
+
+
+;;; STILL TO DO:
+
+;; * Come up with convenient macro syntax.


pretty-print output of 'alda parse' task

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jtbeckha/alda.git/'


a few more sync faces

a few more sync faces

--- src/metabase/driver/sync.clj
+++ src/metabase/driver/sync.clj
@@ -102,9 +102,11 @@
                                 "😒"  ; unamused face
                                 "😕"  ; confused face
                                 "😐"  ; neutral face
-                                "😶"  ; face without mouth
+                                "😬"  ; grimacing face
+                                "😌"  ; relieved face
                                 "😏"  ; smirking face
                                 "😋"  ; face savouring delicious food
+                                "😊"  ; smiling face with smiling eyes
                                 "😍"  ; smiling face with heart shaped eyes
                                 "😎"] ; smiling face with sunglasses
         percent-done->emoji    (fn [percent-done]


Dissoc voter-info before updating it

Dissoc voter-info before updating it

...to make sure we don't serve stale / wrong data when it's been removed from the Civic Info API rather than replaced.


Only (in|de)flate and g(un)zip streams when there's something to compress, fixes #9

--- src/clj_http/util.clj
+++ src/clj_http/util.clj
@@ -36,23 +36,27 @@
 (defn gunzip
   "Returns a gunzip'd version of the given byte array."
   [b]
-  (IOUtils/toByteArray (GZIPInputStream. (ByteArrayInputStream. b))))
+  (when b
+    (IOUtils/toByteArray (GZIPInputStream. (ByteArrayInputStream. b)))))

 (defn gzip
   "Returns a gzip'd version of the given byte array."
   [b]
-  (let [baos (ByteArrayOutputStream.)
-        gos  (GZIPOutputStream. baos)]
-    (IOUtils/copy (ByteArrayInputStream. b) gos)
-    (.close gos)
-    (.toByteArray baos)))
+  (when b
+    (let [baos (ByteArrayOutputStream.)
+          gos  (GZIPOutputStream. baos)]
+      (IOUtils/copy (ByteArrayInputStream. b) gos)
+      (.close gos)
+      (.toByteArray baos))))

 (defn inflate
   "Returns a zlib inflate'd version of the given byte array."
   [b]
-  (IOUtils/toByteArray (InflaterInputStream. (ByteArrayInputStream. b))))
+  (when b
+    (IOUtils/toByteArray (InflaterInputStream. (ByteArrayInputStream. b)))))

 (defn deflate
   "Returns a deflate'd version of the given byte array."
   [b]
-  (IOUtils/toByteArray (DeflaterInputStream. (ByteArrayInputStream. b))))
+  (when b
+    (IOUtils/toByteArray (DeflaterInputStream. (ByteArrayInputStream. b)))))


Add filtering by type.

Add filtering by type.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtravers/incidents.git/'


[EN] Correct some grammar.

[EN] Correct some grammar.


add github rss handler

add github rss handler

error: pathspec 'src/panpan/github.clj' did not match any file(s) known to git

--- src/panpan/github.clj
+++ src/panpan/github.clj
@@ -0,0 +1,18 @@
+(ns panpan.github
+  (:require
+    [jubot.adapter   :as ja]
+    [jubot.scheduler :as js]
+    [jubot.util.rss  :as rss]))
+
+(def ^:const SCHEDULE "0 /1 * * * * *")
+(def ^:const NAME "エイナ")
+(def ^:const RSS_URL "https://github.com/liquidz.atom")
+(def ^:const ICON "https://dl.dropboxusercontent.com/u/14918307/slack_icon/eina.png")
+(def ^:private out (do (ja/out (apply str %&) :as NAME :icon-url ICON) nil))
+
+(def github-schedule
+  (scheduler/schedules
+    SCHEDULE
+    #(let [feeds (rss/get-unread-feeds URL)]
+       (when-not (empty? feeds)
+         (out "OK")))))


Basic planck script to drive releases

Basic planck script to drive releases

https://app.asana.com/0/17212341701456/46395347403915

error: pathspec 'gfs.cljs' did not match any file(s) known to git

--- gfs.cljs
+++ gfs.cljs
@@ -0,0 +1,49 @@
+#!/usr/local/bin/planck
+(ns memento.deploy.core
+  (:require [goog.i18n.DateTimeFormat :as dtf]
+            [planck.core :refer [exit]]
+            [planck.shell :refer [sh]]))
+
+(def format-map
+  (let [f goog.i18n.DateTimeFormat.Format]
+    {:FULL_DATE (.-FULL_DATE f)
+    :FULL_DATETIME (.-FULL_DATETIME f)
+    :FULL_TIME (.-FULL_TIME f)
+    :LONG_DATE (.-LONG_DATE f)
+    :LONG_DATETIME (.-LONG_DATETIME f)
+    :LONG_TIME (.-LONG_TIME f)
+    :MEDIUM_DATE (.-MEDIUM_DATE f)
+    :MEDIUM_DATETIME (.-MEDIUM_DATETIME f)
+    :MEDIUM_TIME (.-MEDIUM_TIME f)
+    :SHORT_DATE (.-SHORT_DATE f)
+    :SHORT_DATETIME (.-SHORT_DATETIME f)
+    :SHORT_TIME (.-SHORT_TIME f)}))
+
+(defn format-date-generic
+  "Format a date using either the built-in goog.i18n.DateTimeFormat.Format
+  enum or a formatting string like \"dd MMMM yyyy\""
+  [date-format date]
+  (.format (goog.i18n.DateTimeFormat.
+            (or (format-map date-format) date-format))
+           (js/Date. date)))
+
+
+(defn ensure-succeeded! [x]
+  (print (:out x))
+  (when-not (zero? (:exit x))
+    (println "Non-zero exit code! There may be unstaged changes.")
+    (print (:err x))
+    (exit (:exit x))))
+
+
+(defn do! [& args]
+  (ensure-succeeded! (apply sh args)))
+
+(def timestamp (format-date-generic "yyyyMMddHHmm" (js/Date.)))
+
+; TODO: Once we get planck 1.6, add command line args so that we can do either
+; release or start
+
+(do! "git" "flow" "release" "start" timestamp)
+
+(println "Done")


make google-election-id optional

make google-election-id optional


Generify update-record.

Generify update-record.


doto erabiliz gero hobe

doto erabiliz gero hobe

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lnmnd/magnet.zer.git/'


Feedback: Use error-api-response to handle search exception.

--- src/clojars/web/search.clj
+++ src/clojars/web/search.clj
@@ -3,7 +3,9 @@
                                         collection-fork-notice user-link
                                         format-date page-nav]]
             [clojars.search :as search]
-            [cheshire.core :as json]))
+            [cheshire.core :as json]
+            [clojars.errors :as errors]
+            [clojars.web.error-api :as error-api]))

 (defn- jar->json [jar]
   (let [m {:jar_name (:artifact-id jar)
@@ -25,10 +27,10 @@
                 (json/generate-string {:count (count results)
                                        :results (map jar->json results)})))
       (catch Exception _
-        (assoc response
-          :status 400
-          :body (json/generate-string
-                  {:error (format "Invalid search syntax for query `%s`" query)}))))))
+        (error-api/error-api-response
+         {:status 400
+          :error-message (format "Invalid search syntax for query `%s`" query)}
+         (errors/error-id))))))

 (defn html-search [search account query page]
   (html-doc (str query " - search") {:account account :query query :description (format "Clojars search results for '%s'" query)}


Fatrpm: experimenting with config

Fatrpm: experimenting with config

--- tasks/leiningen/fatrpm.clj
+++ tasks/leiningen/fatrpm.clj
@@ -107,14 +107,18 @@

         ; Binary
         {:directory "/usr/bin"
-         :filemode "0755"
+         :filemode "755"
          :sources [(source (file (:root project) "pkg" "deb" "riemann")
                            "riemann")]}

-        ; Config
+        ; Config dir
         {:directory "/etc/riemann"
-         :filemode "0644"
-         :directory-included? true
+         :filemode "755"
+         :directory-included? true}
+
+        ; Config file
+        {:directory "/etc/riemann"
+         :filemode "644"
          :configuration true
          :sources [(source (file (:root project) "pkg" "riemann.config")
                            "riemann.config")]}]))


Import archived productions into db

Import archived productions into db

error: pathspec 'src/mdr2/abacus/import.clj' did not match any file(s) known to git

--- src/mdr2/abacus/import.clj
+++ src/mdr2/abacus/import.clj
@@ -0,0 +1,42 @@
+(ns mdr2.abacus.import
+  "Funtionality for the initial import of the production data from
+  ABACUS to Madras2"
+  (:require [clojure.java.io :as io]
+            [clojure.data.csv :as csv]
+            [clojure.string :as string]
+            [clojure.java.jdbc :as jdbc]
+            [environ.core :refer [env]]
+            [mdr2.production :as prod]))
+
+(def ^:private db (env :database-url))
+
+(defn fix-production
+  "Fix a `production`, i.e. fix some of the fields as they are coing
+  from ABACUS the values as they are expected by Madras2"
+  [{:keys [id periodical_number] :as production}]
+  (-> production
+   (assoc :id (second (re-find #"dam(\d+)" id)))
+   (assoc :production_type "book")
+   (assoc :periodical_number
+          (when-not (string/blank? periodical_number) periodical_number))
+   (dissoc :Produktestatus)))
+
+(defn productions
+  "Given a file or a filename `f` return a lazy seq of productions"
+  [f]
+  (->> f
+   io/reader
+   csv/read-csv
+   (drop 2) ; ignore headers
+   (map #(zipmap [:product_number :creator :title :production_type
+                  :periodical_number :source_publisher :source_date
+                  :source :Produktestatus :volumes :id :multimedia_type
+                  :narrator :produced_date :total_time :state :date :depth] %))
+   (map prod/parse)
+   (map fix-production)
+   (map #(merge (prod/default-meta-data) %))))
+
+(defn import!
+  "Import all productions from file `f` and insert them in the data base"
+  [f]
+  (apply jdbc/insert! db :production (productions f)))


Forma eman

Forma eman

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lnmnd/magnet.bez.git/'


More clear handling of body in alet macro, suggestion by @yurrriq

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -352,7 +352,7 @@
                                        acc
                                        (reverse syms))]
                         `(fapply (fmap ~cf ~fa) ~@faps)))))
-                body
+                `(do ~@body)
                 (reverse batches))
         join-count (dec (count batches))]
     (reduce (fn [acc _]
@@ -413,14 +413,13 @@
                    (even? (count bindings)))
       (throw (IllegalArgumentException. "bindings has to be a vector with even number of elements.")))
     (let [bindings (partition 2 bindings)
-          body (cons 'do body)
           [bindings body] (dedupe-symbols bindings body)
           batches (bindings->batches bindings)
           env (into {} bindings)]
       (if (and (= (count batches) 1)
                (= (count (map first bindings)) 1))
         `(fmap (fn [~@(map first bindings)]
-                 ~body)
+                 ~@body)
                ~@(map second bindings))
         (alet* batches env body))))


some CSS classing on components

some CSS classing on components

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/talexand/kittens-gallery.git/'


Added Vectors Summed problem

Added Vectors Summed problem

error: pathspec 'src/clojush/problems/software/vectors_summed.clj' did not match any file(s) known to git

--- src/clojush/problems/software/vectors_summed.clj
+++ src/clojush/problems/software/vectors_summed.clj
@@ -0,0 +1,170 @@
+;; vectors_summed.clj
+;; Tom Helmuth, thelmuth@cs.umass.edu
+;;
+;; Problem Source: iJava (http://ijava.cs.umass.edu/)
+;;
+;; Given two vectors of integers in [-1000,1000] of the same length <= 50,
+;; return a vector of integers that sums the other two at each index.
+;;
+;; input stack has 2 input vectors of integers
+
+(ns clojush.problems.software.vectors-summed
+  (:use clojush.pushgp.pushgp
+        [clojush pushstate interpreter random util globals]
+        clojush.instructions.tag
+        [clojure.math numeric-tower combinatorics]
+        ))
+
+; Atom generators
+(def vectors-summed-atom-generators
+  (concat (list
+            []
+            ;;; end constants
+            (fn [] (- (lrand-int 2001) 1000)) ;Integer ERC [-1000,1000]
+            ;;; end ERCs
+            (tag-instruction-erc [:integer :vector_integer :exec] 1000)
+            (tagged-instruction-erc 1000)
+            ;;; end tag ERCs
+            'in1
+            ;;; end input instructions
+            )
+          (registered-for-stacks [:integer :vector_integer :exec])))
+
+
+;; Define test cases
+(defn vectors-summed-input
+  "Makes a pair of Vectors Summed input vectors of length len."
+  [len]
+  (vector (vec (repeatedly len
+                           #(- (lrand-int 2001) 1000)))
+          (vec (repeatedly len
+                           #(- (lrand-int 2001) 1000)))))
+
+;; A list of data domains for the problem. Each domain is a vector containing
+;; a "set" of inputs and two integers representing how many cases from the set
+;; should be used as training and testing cases respectively. Each "set" of
+;; inputs is either a list or a function that, when called, will create a
+;; random element of the set.
+(def vectors-summed-data-domains
+  [[(list [[] []]) 1 0] ;; Empty vectors
+   [(concat (list [[0] [0]]
+                  [[0] [10]]
+                  [[3] [5]]
+                  [[7] [-9]]
+                  [[-432] [-987]])
+            (repeatedly 5 #(vectors-summed-input 1))) 10 0] ;; Length 1 vectors
+   [(list [[0 0] [0 0]]
+          [[0 1] [-4 2]]
+          [[-1 0] [-3 0]]
+          [[-90 -6] [-323 49]]) 4 0] ;; Length 2 vectors
+   [(fn [] (vectors-summed-input 50)) 10 100] ;; Length 50 vectors
+   [(fn [] (vectors-summed-input (inc (lrand-int 50)))) 125 1400] ;; Random length vectors
+   ])
+
+;;Can make Vectors Summed test data like this:
+;(test-and-train-data-from-domains vectors-summed-data-domains)
+
+; Helper function for error function
+(defn vectors-summed-test-cases
+  "Takes a sequence of inputs and gives IO test cases of the form
+   [input output]."
+  [inputs]
+  (map (fn [in]
+         (vector in
+                 (vec (map + (first in) (second in)))))
+       inputs))
+
+; Define error function. For now, each run uses different random inputs
+(defn vectors-summed-error-function
+  "Returns the error function for the vectors-summed problem. Takes as
+   input Vectors Summed data domains."
+  [data-domains]
+  (let [[train-cases test-cases] (map vectors-summed-test-cases
+                                      (test-and-train-data-from-domains data-domains))]
+    (when false ;; Change to false to not print test cases
+      (doseq [[i case] (map vector (range) train-cases)]
+        (println (format "Train Case: %3d | Input/Output: %s" i (str case))))
+      (doseq [[i case] (map vector (range) test-cases)]
+        (println (format "Test Case: %3d | Input/Output: %s" i (str case)))))
+    (fn the-actual-vectors-summed-error-function
+      ([program]
+        (the-actual-vectors-summed-error-function program :train))
+      ([program data-cases] ;; data-cases should be :train or :test
+        (the-actual-vectors-summed-error-function program data-cases false))
+      ([program data-cases print-outputs]
+        (let [behavior (atom '())
+              errors (doall
+                       (for [[[input1 input2] correct-output] (case data-cases
+                                                                           :train train-cases
+                                                                           :test test-cases
+                                                                           [])]
+                         (let [final-state (run-push program
+                                                     (->> (make-push-state)
+                                                       (push-item input2 :input)
+                                                       (push-item input1 :input)))
+                               result (top-item :vector_integer final-state)]
+                           (when print-outputs
+                             (println (format "| Correct output: %s\n| Program output: %s\n" (pr-str correct-output) (pr-str result))))
+                           ; Record the behavior
+                           (when @global-print-behavioral-diversity
+                             (swap! behavior conj result))
+                           ; Error is integer error at each position in the vectors, with additional penalties for incorrect size vector
+                           (if (vector? result)
+                             (+' (apply +' (map (fn [cor res]
+                                                  (abs (- cor res)))
+                                                correct-output
+                                                result))
+                                 (*' 10000 (abs (- (count correct-output) (count result))))) ; penalty of 10000 times difference in sizes of vectors
+                             1000000000) ; penalty for no return value
+                           )))]
+          (when @global-print-behavioral-diversity
+            (swap! population-behaviors conj @behavior))
+          errors)))))
+
+(defn vectors-summed-report
+  "Custom generational report."
+  [best population generation error-function report-simplifications]
+  (let [best-program (not-lazy (:program best))
+        best-test-errors (error-function best-program :test)
+        best-total-test-error (apply +' best-test-errors)]
+    (println ";;******************************")
+    (printf ";; -*- Vectors Summed problem report - generation %s\n" generation)(flush)
+    (println "Test total error for best:" best-total-test-error)
+    (println (format "Test mean error for best: %.5f" (double (/ best-total-test-error (count best-test-errors)))))
+    (when (zero? (:total-error best))
+      (doseq [[i error] (map vector
+                             (range)
+                             best-test-errors)]
+        (println (format "Test Case  %3d | Error: %d" i error))))
+    (println ";;------------------------------")
+    (println "Outputs of best individual on training cases:")
+    (error-function best-program :train true)
+    (println ";;******************************")
+    )) ;; To do validation, could have this function return an altered best individual
+       ;; with total-error > 0 if it had error of zero on train but not on validation
+       ;; set. Would need a third category of data cases, or a defined split of training cases.
+
+
+; Define the argmap
+(def argmap
+  {:error-function (vectors-summed-error-function vectors-summed-data-domains)
+   :atom-generators vectors-summed-atom-generators
+   :max-points 500
+   :max-points-in-initial-program 250
+   :evalpush-limit 1500
+   :population-size 1000
+   :max-generations 300
+   :parent-selection :lexicase
+   :genetic-operator-probabilities {:alternation 0.2
+                                    :uniform-mutation 0.2
+                                    :uniform-close-mutation 0.1
+                                    [:alternation :uniform-mutation] 0.5
+                                    }
+   :alternation-rate 0.01
+   :alignment-deviation 10
+   :uniform-mutation-rate 0.01
+   :problem-specific-report vectors-summed-report
+   :print-behavioral-diversity true
+   :report-simplifications 0
+   :final-report-simplifications 5000
+   })


Fix error case test failing due to a cached good response

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/turbovote-http-api.git/'


Minor refactor

Minor refactor

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/scheduled-message-works.git/'


Added tests and docs highlighting problem with handling final period in input TS

--- test/forma/trends/stretch_test.clj
+++ test/forma/trends/stretch_test.clj
@@ -9,14 +9,15 @@
   (let [ts (schema/timeseries-value 384 [1 2 3])]
     (shift-periods-target-res "32" "16" (:start-idx ts) (:end-idx ts)) => [736 739]))

+
 (fact
   "Expect to see values repeated the correct number of days given a monthly dataset (e.g. 31 for January, 28 for non-leap year February."
   (expand-to-days 384 [1 2 3] 384 1 "32" 0) => [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3])

 (fact
-  "Starting with January 2002 (non-leap year), period 384, a 3-period \"32\"-day timeseries."
+  "Starting with January 2002 (non-leap year), period 384, a 3-period \"32\"-day timeseries. For a 32-day ts [1 2 3] for January-March, we expect to see five periods, through mid-March. The next period, which would run past the end of March, requires having the value for April. Since we only have through March, that second period in March is not generated."
   (let [ts (schema/timeseries-value 384 [1 2 3])
-        output {:start-idx 736 :end-idx 739 :series [1.0 1.0625 2.0 2.3125]}]
+        output {:start-idx 736 :end-idx 740 :series [1.0 1.0625 2.0 2.3125 3.0]}]
     (ts-expander "32" "16" ts) => output))

 (fact
@@ -24,4 +25,34 @@
   (let [periods-32 12 ;; number of periods, 32-day res
         periods-16 23 ;; expected number of periods, 16-day res
         ts (schema/timeseries-value 360 (take periods-32 data/ndvi))]
-    (count (:series (ts-expander "32" "16" ts))) => periods-16))+    (count (:series (ts-expander "32" "16" ts))) => periods-16))
+
+(tabular
+ (fact
+   "A monthly timeseries of identical values Jan-Dec, followed by one additional, different value for the following January, should produce a 16-day timeseries of 23 periods of identical values for the year, plus one period, with a value from the 2nd January.
+
+Note that this one additional period only covers the first half of January. The ts value for the second period in Janaury cannot be expanded until you've got data for February, since the second 16-day period runs through Feb. 1 (Jan. 17 + 16 = Feb. 1)
+
+We'll add a few additional values to make sure extending beyond January works.
+
+0 0 => all ones through end of December
+1 1 => all ones then twos through first period of January
+2 3 => all ones then twos through mid-February
+3 5 => all ones then twos through mid-Marchoutput through mid-March
+12 23 => all ones then twos through end of second December
+
+The problem at present: The output timeseries seems to be too short by 1-2 periods. So even if we have monthly data for December (starting on 12/1/2011), the output will only run through 11/16/2011 because the 16-day periods are bounded by 12/1/2011 rather than 12/31/2011.
+"
+   (let [series (concat (repeat 12 1) (repeat ?extra-32 2))
+         ts (schema/timeseries-value 360 series)
+         expanded-ts (:series (ts-expander "32" "16" ts))
+         expected-ts (map float (concat (repeat 23 1) (repeat ?extra-16 2)))]
+     expanded-ts => expected-ts))
+ ?extra-32 ?extra-16
+ 0          0
+ 1          1 ;; outputs through first half of January
+ 2          3 ;; outputs through mid-January
+ 3          5 ;; outputs through
+ 12         23)
+
+


add CSS Typed OM specs

add CSS Typed OM specs

error: pathspec 'src/cljss/css/typed.clj' did not match any file(s) known to git

--- src/cljss/css/typed.clj
+++ src/cljss/css/typed.clj
@@ -0,0 +1,140 @@
+(ns cljss.css.typed
+  "CSS Typed OM Level 1
+  Spec https://drafts.css-houdini.org/css-typed-om/
+  Article https://developers.google.com/web/updates/2018/03/cssom"
+  (:require [clojure.spec.alpha :as s]))
+
+(s/def ::CSSNumericBaseType
+  #{"length" "angle" "time" "frequency"
+    "resolution" "flex" "percent"})
+
+(s/def ::CSSMathOperator
+  #{"sum" "product" "negate" "invert" "min" "max"})
+
+(s/def ::CSSUnit
+  #{"number" "percent" "%" "em" "ex"
+    "ch" "ic" "rem" "lh" "rlh" "vw" "vh"
+    "vi" "vb" "vmin" "vmax" "cm" "mm" "Q"
+    "in" "pt" "pc" "px" "deg" "grad" "rad"
+    "turn" "s" "ms" "Hz" "kHz" "dpi" "dpcm"
+    "dppx" "fr"})
+
+(s/def ::CSSUnitValue
+  (s/cat
+    :value number?
+    :unit ::CSSUnit))
+
+(s/def ::CSSNumericValue
+  (s/or
+    :unit-value ::CSSUnitValue
+    :math-value ::CSSMathValue))
+
+(s/def ::CSSNumberish
+  (s/or
+    :number-value number?
+    :numeric-value ::CSSNumericValue))
+
+(s/def ::CSSMathSum
+  (s/cat
+    :operator #{:math/+}
+    :operands (s/+ ::CSSNumberish)))
+
+(s/def ::CSSMathProduct
+  (s/cat
+    :operator #{:math/*}
+    :operands (s/+ ::CSSNumberish)))
+
+(s/def ::CSSMathValue
+  (s/alt
+    :math-sum ::CSSMathSum
+    :math-product ::CSSMathProduct))
+
+(s/def ::CSSPositionValue
+  (s/cat
+    :x ::CSSNumericValue
+    :y ::CSSNumericValue))
+
+;; CSS Transform
+(s/def ::CSSTranslate
+  (s/cat
+    :op #{:translate}
+    :x ::CSSNumericValue
+    :y ::CSSNumericValue
+    :z (s/? ::CSSNumericValue)))
+
+(s/def ::CSSRotate
+  (s/alt
+    :short (s/cat
+             :op #{:rotate}
+             :angle ::CSSNumericValue)
+    :full (s/cat
+            :op #{:rotate}
+            :x ::CSSNumberish
+            :y ::CSSNumberish
+            :z ::CSSNumberish
+            :angle ::CSSNumericValue)))
+
+(s/def ::CSSScale
+  (s/cat
+    :op #{:scale}
+    :x ::CSSNumberish
+    :y ::CSSNumberish
+    :z (s/? ::CSSNumberish)))
+
+(s/def ::CSSTransformComponent
+  (s/alt
+    :translate ::CSSTranslate
+    :rotate ::CSSRotate
+    :scale ::CSSScale))
+
+(s/def ::CSSTransformValue
+  (s/coll-of ::CSSTransformComponent :min-count 1))
+
+;; ========================================
+(defn -dispatch-compile-typed-css [v]
+  (first v))
+
+(defmulti compile-typed-css #'-dispatch-compile-typed-css)
+
+(defmethod compile-typed-css :unit-value
+  [[_ {:keys [value unit]}]]
+  `(js/CSSUnitValue. ~value ~unit))
+
+(defmethod compile-typed-css :math-value
+  [[_ math-value]]
+  (compile-typed-css math-value))
+
+(defmethod compile-typed-css :numeric-value
+  [[_ value]]
+  (compile-typed-css value))
+
+(defmethod compile-typed-css :number-value)
+(defmethod compile-typed-css :number-value
+  [[_ value]]
+  value)
+
+(defmethod compile-typed-css :math-sum
+  [[_ {:keys [operands]}]]
+  `(js/CSSMathSum. ~@(map compile-typed-css operands)))
+
+(defmethod compile-typed-css :math-product
+  [[_ {:keys [operands]}]]
+  `(js/CSSMathProduct. ~@(map compile-typed-css operands)))
+
+(defmethod compile-typed-css :translate
+  [[_ {:keys [x y z]}]]
+  `(js/CSSTranslate. ~@(->> (filter identity [x y z])
+                            (map compile-typed-css))))
+
+(defmethod compile-typed-css :rotate
+  [[_ [_ {:keys [angle]}]]]
+  `(js/CSSRotate. ~(compile-typed-css angle)))
+
+(defmethod compile-typed-css :scale
+  [[_ {:keys [x y z]}]]
+  `(js/CSSScale. ~@(->> (filter identity [x y z])
+                        (map compile-typed-css))))
+
+(comment
+  (let [ast (s/conform ::CSSUnitValue [16 "px"])]
+    (compile-typed-css [:unit-value ast])))


Add first test for data.clj

Add first test for data.clj

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/qu-platform/qu-core.git/'


Fix `queue/initialize`

Fix `queue/initialize`

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/partner-works.git/'


port test cases

port test cases

error: pathspec 'test/cljsfmt/core_test.cljs' did not match any file(s) known to git

--- test/cljsfmt/core_test.cljs
+++ test/cljsfmt/core_test.cljs
@@ -0,0 +1,190 @@
+(ns cljfmt.core-test
+  (:require [cljs.test :refer :all]
+            [cljsfmt.core :refer :all]))
+
+(deftest test-indent
+  (testing "list indentation"
+    (is (= (reformat-string "(foo bar\nbaz\nquz)")
+           "(foo bar\n     baz\n     quz)"))
+    (is (= (reformat-string "(foo\nbar\nbaz)")
+           "(foo\n bar\n baz)")))
+
+  (testing "block indentation"
+    (is (= (reformat-string "(if (= x 1)\n:foo\n:bar)")
+           "(if (= x 1)\n  :foo\n  :bar)"))
+    (is (= (reformat-string "(do\n(foo)\n(bar))")
+           "(do\n  (foo)\n  (bar))"))
+    (is (= (reformat-string "(do (foo)\n(bar))")
+           "(do (foo)\n    (bar))"))
+    (is (= (reformat-string "(deftype Foo\n[x]\nBar)")
+           "(deftype Foo\n         [x]\n  Bar)"))
+    (is (= (reformat-string "(cond->> x\na? a\nb? b)")
+           "(cond->> x\n  a? a\n  b? b)")))
+
+  (testing "constant indentation"
+    (is (= (reformat-string "(def foo\n\"Hello World\")")
+           "(def foo\n  \"Hello World\")"))
+    (is (= (reformat-string "(defn foo [x]\n(+ x 1))")
+           "(defn foo [x]\n  (+ x 1))"))
+    (is (= (reformat-string "(defn foo\n[x]\n(+ x 1))")
+           "(defn foo\n  [x]\n  (+ x 1))"))
+    (is (= (reformat-string "(defn foo\n([] 0)\n([x]\n(+ x 1)))")
+           "(defn foo\n  ([] 0)\n  ([x]\n   (+ x 1)))"))
+    (is (= (reformat-string "(fn [x]\n(foo bar\nbaz))")
+           "(fn [x]\n  (foo bar\n       baz))"))
+    (is (= (reformat-string "(fn [x] (foo bar\nbaz))")
+           "(fn [x] (foo bar\n             baz))")))
+
+  (testing "inner indentation"
+    (is (= (reformat-string "(letfn [(foo [x]\n(* x x))]\n(foo 5))")
+           "(letfn [(foo [x]\n          (* x x))]\n  (foo 5))"))
+    (is (= (reformat-string "(reify Closeable\n(close [_]\n(prn :closed)))")
+           "(reify Closeable\n  (close [_]\n    (prn :closed)))"))
+    (is (= (reformat-string "(defrecord Foo [x]\nCloseable\n(close [_]\n(prn x)))")
+           "(defrecord Foo [x]\n  Closeable\n  (close [_]\n    (prn x)))")))
+
+  (testing "data structure indentation"
+    (is (= (reformat-string "[:foo\n:bar\n:baz]")
+           "[:foo\n :bar\n :baz]"))
+    (is (= (reformat-string "{:foo 1\n:bar 2}")
+           "{:foo 1\n :bar 2}"))
+    (is (= (reformat-string "#{:foo\n:bar\n:baz}")
+           "#{:foo\n  :bar\n  :baz}"))
+    (is (= (reformat-string "{:foo [:bar\n:baz]}")
+           "{:foo [:bar\n       :baz]}")))
+
+  (testing "embedded structures"
+    (is (= (reformat-string "(let [foo {:x 1\n:y 2}]\n(:x foo))")
+           "(let [foo {:x 1\n           :y 2}]\n  (:x foo))"))
+    (is (= (reformat-string "(if foo\n(do bar\nbaz)\nquz)")
+           "(if foo\n  (do bar\n      baz)\n  quz)")))
+
+  (testing "namespaces"
+    (is (= (reformat-string "(t/defn foo [x]\n(+ x 1))")
+           "(t/defn foo [x]\n  (+ x 1))"))
+    (is (= (reformat-string "(t/defrecord Foo [x]\nCloseable\n(close [_]\n(prn x)))")
+           "(t/defrecord Foo [x]\n  Closeable\n  (close [_]\n    (prn x)))")))
+
+  (testing "function #() syntax"
+    (is (= (reformat-string "#(while true\n(println :foo))")
+           "#(while true\n   (println :foo))"))
+    (is (= (reformat-string "#(reify Closeable\n(close [_]\n(prn %)))")
+           "#(reify Closeable\n   (close [_]\n     (prn %)))")))
+
+  (testing "multiple arities"
+    (is (= (reformat-string "(fn\n([x]\n(foo)\n(bar)))")
+           "(fn\n  ([x]\n   (foo)\n   (bar)))")))
+
+  (testing "comments"
+    (is (= (reformat-string ";foo\n(def x 1)")
+           ";foo\n(def x 1)"))
+    (is (= (reformat-string "(ns foo.core)\n\n;; foo\n(defn foo [x]\n(inc x))")
+           "(ns foo.core)\n\n;; foo\n(defn foo [x]\n  (inc x))"))
+    (is (= (reformat-string ";; foo\n(ns foo\n(:require bar))")
+           ";; foo\n(ns foo\n  (:require bar))"))
+    (is (= (reformat-string "(defn foo [x]\n  ;; +1\n(inc x))")
+           "(defn foo [x]\n  ;; +1\n  (inc x))"))
+    (is (= (reformat-string "(let [;foo\n x (foo bar\n baz)]\n x)")
+           "(let [;foo\n      x (foo bar\n             baz)]\n  x)"))
+    (is (= (reformat-string "(binding [x 1] ; foo\nx)")
+           "(binding [x 1] ; foo\n  x)")))
+
+  (testing "metadata"
+    (is (= (reformat-string "(defonce ^{:doc \"foo\"}\nfoo\n:foo)")
+           "(defonce ^{:doc \"foo\"}\n  foo\n  :foo)"))
+    (is (= (reformat-string "(def ^:private\nfoo\n:foo)")
+           "(def ^:private\n  foo\n  :foo)"))
+    (is (= (reformat-string "(def ^:private foo\n:foo)")
+           "(def ^:private foo\n  :foo)")))
+
+  (testing "fuzzy matches"
+    (is (= (reformat-string "(with-foo x\ny\nz)")
+           "(with-foo x\n  y\n  z)"))
+    (is (= (reformat-string "(defelem foo [x]\n[:foo x])")
+           "(defelem foo [x]\n  [:foo x])")))
+
+  (testing "comment before ending bracket"
+    (is (= (reformat-string "(foo a ; b\nc ; d\n)")
+           "(foo a ; b\n     c ; d\n     )"))
+    (is (= (reformat-string "(do\na ; b\nc ; d\n)")
+           "(do\n  a ; b\n  c ; d\n  )"))
+    (is (= (reformat-string "(let [x [1 2 ;; test1\n2 3 ;; test2\n]])")
+           "(let [x [1 2 ;; test1\n         2 3 ;; test2\n         ]])")))
+
+  (testing "indented comments with blank lines"
+    (is (= (reformat-string "(;a\n\n ;b\n )")
+           "(;a\n\n ;b\n )")))
+
+  (testing "indentated forms in letfn block"
+    (is (= (reformat-string "(letfn [(f [x]\nx)]\n(let [x (f 1)]\n(str x 2\n3 4)))")
+           (str "(letfn [(f [x]\n          x)]\n"
+                "  (let [x (f 1)]\n    (str x 2\n         3 4)))")))))
+
+(deftest test-surrounding-whitespace
+  (testing "surrounding spaces"
+    (is (= (reformat-string "( foo bar )")
+           "(foo bar)"))
+    (is (= (reformat-string "[ 1 2 3 ]")
+           "[1 2 3]"))
+    (is (= (reformat-string "{  :x 1, :y 2 }")
+           "{:x 1, :y 2}")))
+
+  (testing "surrounding newlines"
+    (is (= (reformat-string "(\n  foo\n)")
+           "(foo)"))
+    (is (= (reformat-string "(  \nfoo\n)")
+           "(foo)"))
+    (is (= (reformat-string "(foo  \n)")
+           "(foo)"))
+    (is (= (reformat-string "(foo\n  )")
+           "(foo)"))
+    (is (= (reformat-string "[\n1 2 3\n]")
+           "[1 2 3]"))
+    (is (= (reformat-string "{\n:foo \"bar\"\n}")
+           "{:foo \"bar\"}"))
+    (is (= (reformat-string "( let [x 3\ny 4]\n(+ (* x x\n)(* y y)\n))")
+           "(let [x 3\n      y 4]\n  (+ (* x x) (* y y)))"))))
+
+(deftest test-missing-whitespace
+  (is (= (reformat-string "(foo(bar baz)qux)")
+         "(foo (bar baz) qux)"))
+  (is (= (reformat-string "(foo)bar(baz)")
+         "(foo) bar (baz)"))
+  (is (= (reformat-string "(foo[bar]#{baz}{quz bang})")
+         "(foo [bar] #{baz} {quz bang})")))
+
+(deftest test-consecutive-blank-lines
+  (is (= (reformat-string "(foo)\n\n(bar)")
+         "(foo)\n\n(bar)"))
+  (is (= (reformat-string "(foo)\n\n\n(bar)")
+         "(foo)\n\n(bar)"))
+  (is (= (reformat-string "(foo)\n \n \n(bar)")
+         "(foo)\n\n(bar)"))
+  (is (= (reformat-string "(foo)\n\n\n\n\n(bar)")
+         "(foo)\n\n(bar)"))
+  (is (= (reformat-string "(foo)\n\n;bar\n\n(baz)")
+         "(foo)\n\n;bar\n\n(baz)"))
+  (is (= (reformat-string "(foo)\n;bar\n;baz\n;qux\n(bang)")
+         "(foo)\n;bar\n;baz\n;qux\n(bang)")))
+
+(deftest test-options
+  (is (= (reformat-string "(foo)\n\n\n(bar)" {:remove-consecutive-blank-lines? false})
+         "(foo)\n\n\n(bar)"))
+  (is (= (reformat-string "(  foo  )" {:remove-surrounding-whitespace? false})
+         "(  foo  )"))
+  (is (= (reformat-string "(foo(bar))" {:insert-missing-whitespace? false})
+         "(foo(bar))"))
+  (is (= (reformat-string "(foo\nbar)" {:indents '{foo [[:block 0]]}})
+         "(foo\n  bar)"))
+  (is (= (reformat-string "(do\nfoo\nbar)" {:indents {}})
+         "(do\n foo\n bar)"))
+  (is (= (reformat-string "(do\nfoo\nbar)" {:indentation? false})
+         "(do\nfoo\nbar)")))
+
+(deftest test-parsing
+  (is (= (reformat-string ";foo") ";foo"))
+  (is (= (reformat-string "::foo") "::foo"))
+  (is (= (reformat-string "::foo/bar") "::foo/bar"))
+  (is (= (reformat-string "foo:bar") "foo:bar"))
+  (is (= (reformat-string "#_(foo\nbar)") "#_(foo\n   bar)"))
+  (is (= (reformat-string "(juxt +' -')") "(juxt +' -')")))


Changes to autoconstruction and autoconstructive demo.

error: pathspec 'src/clojush/problems/demos/autoconstructive_replace_space_with_newline.clj' did not match any file(s) known to git

--- src/clojush/problems/demos/autoconstructive_replace_space_with_newline.clj
+++ src/clojush/problems/demos/autoconstructive_replace_space_with_newline.clj
@@ -0,0 +1,192 @@
+;; autoconstructive_replace_space_with_newline.clj
+;; A version of replace_space_with_newline.clj modified to use only the autoconstriction
+;; genetic operator. Changes from standard version marked #auto.
+
+;;*****************************************************************************
+;; NOTE: This is work in progress, based on ideas that are under development.
+;; For the time being you shouldn't expect it to work well or remain stable.
+;; Documentation is also spotty.
+;;*****************************************************************************
+
+;; Documentation for the original replace_space_with_newline.clj file:
+
+;; replace_space_with_newline.clj
+;; Tom Helmuth, thelmuth@cs.umass.edu
+;;
+;; Problem Source: iJava (http://ijava.cs.umass.edu/)
+;;
+;; Given a string input, print the string, replacing spaces with newlines.
+;; The input string will not have tabs or newlines, but may have multiple spaces
+;; in a row. It will have maximum length of 20 characters. Also, the program
+;; should return the integer count of the non-whitespace characters.
+;;
+;; input stack has the input string
+
+(ns clojush.problems.demos.autoconstructive-replace-space-with-newline
+  (:use clojush.pushgp.pushgp
+        [clojush pushstate interpreter random util globals]
+        clojush.instructions.tag
+        clojure.math.numeric-tower)
+    (:require [clojure.string :as string]))
+
+;; Define test cases
+(defn replace-space-input
+  "Makes a Replace Space With Newline input of length len."
+  [len]
+  (apply str
+         (repeatedly len
+                     (fn []
+                       (if (< (lrand) 0.2)
+                         \space
+                         (lrand-nth (map char (range 32 127))))))))
+
+; Atom generators
+(def replace-space-atom-generators
+  (concat (list
+            \space
+            \newline
+            ;;; end constants
+            (fn [] (lrand-nth (concat [\newline \tab] (map char (range 32 127))))) ;Visible character ERC
+            (fn [] (replace-space-input (lrand-int 21))) ;String ERC
+            ;;; end ERCs
+            (tag-instruction-erc [:exec :integer :boolean :string :char] 1000)
+            (tagged-instruction-erc 1000)
+            ;;; end tag ERCs
+            'in1
+            ;;; end input instructions
+            'autoconstructive_integer_rand ;; #auto
+            )
+          (registered-for-stacks [:integer :boolean :string :char :exec :print :genome]))) ;; #auto
+
+
+;; A list of data domains for the problem. Each domain is a vector containing
+;; a "set" of inputs and two integers representing how many cases from the set
+;; should be used as training and testing cases respectively. Each "set" of
+;; inputs is either a list or a function that, when called, will create a
+;; random element of the set.
+(def replace-space-data-domains
+  [[(list "", "A", "*", " ", "s", "B ", "  ", " D", "ef", "!!", " F ", "T L", "4ps", "q  ", "   ", "  e", "hi ",
+          "  $  ", "      9",
+          (apply str (take 13 (cycle (list \i \space \!))))
+          (apply str (repeat 20 \8))
+          (apply str (repeat 20 \space))
+          (apply str (repeat 20 \s))
+          (apply str (take 20 (cycle (list \1 \space))))
+          (apply str (take 20 (cycle (list \space \v))))
+          (apply str (take 20 (cycle (list \H \a \space))))
+          (apply str (take 20 (cycle (list \x \space \y \!))))
+          (apply str (take 20 (cycle (list \G \5))))
+          (apply str (take 20 (cycle (list \> \_ \= \]))))
+          (apply str (take 20 (cycle (list \^ \_ \^ \space))))) 30 0] ;; "Special" inputs covering some base cases
+   [(fn [] (replace-space-input (+ 2 (lrand-int 19)))) 70 1000]
+   ])
+
+;;Can make Replace Space With Newline test data like this:
+;(test-and-train-data-from-domains replace-space-data-domains)
+
+; Helper function for error function
+(defn replace-space-test-cases
+  "Takes a sequence of inputs and gives IO test cases of the form
+   [input output]."
+  [inputs]
+  (map (fn [in]
+         (vector in
+                 [(string/replace in \space \newline)
+                  (count (filter #(not= \space %) in))]))
+       inputs))
+
+; Define error function. For now, each run uses different random inputs
+(defn replace-space-error-function
+  "Returns the error function for the Replace Space With Newline problem. Takes as
+   input Replace Space With Newline data domains."
+  [data-domains]
+  (let [[train-cases test-cases] (map #(sort-by (comp count first) %)
+                                      (map replace-space-test-cases
+                                           (test-and-train-data-from-domains data-domains)))]
+    (when true ;; Change to false to not print test cases
+      (doseq [[i case] (map vector (range) train-cases)]
+        (println (format "Train Case: %3d | Input/Output: %s" i (str case))))
+      (doseq [[i case] (map vector (range) test-cases)]
+        (println (format "Test Case: %3d | Input/Output: %s" i (str case)))))
+    (fn the-actual-replace-space-error-function
+      ([program]
+        (the-actual-replace-space-error-function program :train))
+      ([program data-cases] ;; data-cases should be :train or :test
+        (the-actual-replace-space-error-function program data-cases false))
+      ([program data-cases print-outputs]
+        (let [behavior (atom '())
+              errors (flatten
+                       (doall
+                         (for [[input [correct-output correct-int]] (case data-cases
+                                                                      :train train-cases
+                                                                      :test test-cases
+                                                                      [])]
+                           (let [final-state (run-push program
+                                                       (->> (make-push-state)
+                                                         (push-item input :input)
+                                                         (push-item "" :output)))
+                                 printed-result (stack-ref :output 0 final-state)
+                                 int-result (stack-ref :integer 0 final-state)]
+                             (when print-outputs
+                               (println (format "\n| Correct output: %s\n| Program output: %s" (pr-str correct-output) (pr-str printed-result)))
+                               (println (format "| Correct integer: %2d | Program integer: %s" correct-int (str int-result))))
+                             ; Record the behavior
+                             (when @global-print-behavioral-diversity
+                               (swap! behavior conj [printed-result int-result]))
+                             ; Error is Levenshtein distance for printed string and
+                             ; integer distance for returned integer
+                             (vector
+                               (levenshtein-distance correct-output printed-result)
+                               (if (number? int-result)
+                                 (abs (- int-result correct-int)) ;distance from correct integer
+                                 1000) ;penalty for no return value
+                               )))))]
+          (when @global-print-behavioral-diversity
+            (swap! population-behaviors conj @behavior))
+          errors)))))
+
+(defn replace-space-report
+  "Custom generational report."
+  [best population generation error-function report-simplifications]
+  (let [best-program (not-lazy (:program best))
+        best-test-errors (error-function best-program :test)
+        best-total-test-error (apply +' best-test-errors)]
+    (println ";;******************************")
+    (printf ";; -*- Replace Space With Newline problem report - generation %s\n" generation)(flush)
+    (println "Test total error for best:" best-total-test-error)
+    (println (format "Test mean error for best: %.5f" (double (/ best-total-test-error (count best-test-errors)))))
+    (when (zero? (:total-error best))
+      (doseq [[i error] (map vector
+                             (range)
+                             best-test-errors)]
+        (println (format "Test Case  %3d | Error: %s" i (str error)))))
+    (println ";;------------------------------")
+    (println "Outputs of best individual on training cases:")
+    (error-function best-program :train true)
+    (println ";;******************************")
+    )) ;; To do validation, could have this function return an altered best individual
+       ;; with total-error > 0 if it had error of zero on train but not on validation
+       ;; set. Would need a third category of data cases, or a defined split of training cases.
+
+
+; Define the argmap
+(def argmap
+  {:error-function (replace-space-error-function replace-space-data-domains)
+   :atom-generators replace-space-atom-generators
+   :max-points 1600
+   :max-genome-size-in-initial-program 400
+   :evalpush-limit 1600
+   :population-size 1000
+   :max-generations 10000 ;; #auto
+   :parent-selection :lexicase
+   :genetic-operator-probabilities {:autoconstruction 1.0} ;; #auto
+   :epigenetic-markers [:close :silent] ;; #auto
+   ;:alternation-rate 0.01 ;; #auto
+   ;:alignment-deviation 10 ;; #auto
+   ;:uniform-mutation-rate 0.01 ;; #auto
+   :problem-specific-report replace-space-report
+   :print-behavioral-diversity true
+   :report-simplifications 0
+   :final-report-simplifications 5000
+   :max-error 5000
+   })


Server module for manipulaing requests and responses via Clojure Ring

error: pathspec 'src/hurvinek/server.clj' did not match any file(s) known to git

--- src/hurvinek/server.clj
+++ src/hurvinek/server.clj
@@ -0,0 +1,79 @@
+;
+;  (C) Copyright 2016  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
+(ns hurvinek.server
+    "Server module with functions to accept requests and send response back to users via HTTP.")
+
+(require '[ring.util.response     :as http-response])
+(require '[clojure.data.json      :as json])
+(require '[clojure.xml            :as xml])
+(require '[clojure.data.csv       :as csv])
+
+(require '[hurvinek.html-renderer :as html-renderer])
+
+(defn println-and-flush
+    "Original (println) has problem with syncing when it's called from more threads.
+     This function is a bit better because it flushes all output immediatelly."
+    [& more]
+    (.write *out* (str (clojure.string/join " " more) "\n"))
+    (flush))
+
+(defn get-title
+    [request]
+    (-> (:configuration request)
+        :display
+        :app-name))
+
+(defn get-url-prefix
+    [request]
+    (-> (:configuration request)
+        :server
+        :url-prefix))
+
+(defn finish-processing
+    [request title]
+    (let [params        (:params request)
+          url-prefix    (get-url-prefix request)]
+          (-> (http-response/response (html-renderer/render-front-page url-prefix title))
+              (http-response/content-type "text/html"))))
+
+(defn process-front-page
+    "Function that prepares data for the front page."
+    [request title]
+    (let [params         (:params request)]
+        (finish-processing request title)))
+
+(defn return-file
+    "Creates HTTP response containing content of specified file.
+     Special value nil / HTTP response 404 is returned in case of any I/O error."
+    [file-name content-type]
+    (let [file (new java.io.File "www" file-name)]
+        (println-and-flush "Returning file " (.getAbsolutePath file))
+        (if (.exists file)
+            (-> (http-response/response file)
+                (http-response/content-type content-type))
+            (println-and-flush "return-file(): can not access file: " (.getName file)))))
+
+(defn handler
+    "Handler that is called by Ring for all requests received from user(s)."
+    [request]
+    (println-and-flush "request URI: " (request :uri))
+    (let [uri          (request :uri)
+          title        (get-title request)]
+        (condp = uri
+            "/favicon.ico"                (return-file "favicon.ico"       "image/x-icon")
+            "/bootstrap.min.css"          (return-file "bootstrap.min.css" "text/css")
+            "/hurvinek.css"               (return-file "hurvinek.css"      "text/css")
+            "/bootstrap.min.js"           (return-file "bootstrap.min.js"  "application/javascript")
+            "/"                           (process-front-page    request title)
+            )))
+


Stopping point, time to work on individual ops

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/thinktopic/netlib-ccm.git/'


Add logging auth exception

Add logging auth exception

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/physion/ovation-webapi.git/'


improved pixel conversion

improved pixel conversion

--- src/gif_to_html/convert.clj
+++ src/gif_to_html/convert.clj
@@ -8,13 +8,12 @@
 (def ascii [\# \@ \O \% \$ \i \o \c \* \; \: \+ \! \^ \' \- \. \space])
 (def max-items (dec (count ascii)))

-(defn colors [^BufferedImage img ^Integer x ^Integer y]
-  (let [c (Color. (.getRGB img x y))]
-    [(.getRed c) (.getGreen c) (.getBlue c)]))
-
 (defn ascii-color [^BufferedImage img ^Integer y ^Integer x]
-  (let [[r g b :as rgb] (colors img x y)
-        max-color (apply max rgb)
+  (let [pixel (.getRGB img x y)
+        r (bit-and (bit-shift-right pixel 16) 0x000000FF)
+        g (bit-and (bit-shift-right pixel 8) 0x000000FF)
+        b (bit-and pixel 0x000000FF)
+        max-color (max r g b)
         idx (if (zero? max-color) max-items (int (* max-items (/ max-color 255))))]
     (nth ascii (max idx 0))))


remove debug statements

remove debug statements


nire-gogokoak API deirik gabe eguneratu

nire-gogokoak API deirik gabe eguneratu


fix exception printing bug

fix exception printing bug

--- sidecar/src/figwheel_sidecar/utils.clj
+++ sidecar/src/figwheel_sidecar/utils.clj
@@ -13,7 +13,8 @@
                            (thunk)
                            (catch Exception e
                              ;; TODO better execption reporting
-                             (println (.message e))))
+                             (println (.getMessage e))
+                             ))
                          v)))

 (defn clean-cljs-build* [{:keys [output-to output-dir]}]


Adds testing for self collision

Adds testing for self collision

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/thorsteinson/cljs-snake.git/'


Add test namespace for layers with generative testing

error: pathspec 'test/cortex/layers_test.clj' did not match any file(s) known to git

--- test/cortex/layers_test.clj
+++ test/cortex/layers_test.clj
@@ -0,0 +1,11 @@
+(ns cortex.layers_test
+  "Tests for behaviour of standard layer implementations"
+  (:use [clojure.test])
+  (:use [cortex.core])
+  (:require [clojure.core.matrix :as m]
+            [cortex.layers :as layers]
+            [cortex.util :as util]
+            [clojure.test.check :as sc]
+            [clojure.test.check.generators :as gen]
+            [clojure.test.check.properties :as prop]
+            [clojure.test.check.clojure-test :refer (defspec)]))


a cljs test

a cljs test

error: pathspec 'test/midje/cljs/t_basic.clj' did not match any file(s) known to git

--- test/midje/cljs/t_basic.clj
+++ test/midje/cljs/t_basic.clj
@@ -0,0 +1,6 @@
+(ns ^{:cljs-ns 'midje.cljs.basic
+      :cljs-file "midje/cljs/basic.cljs"}
+  midje.cljs.t-basic
+  (:use [midje.sweet]))
+
+(fact (doubler 5) => 10)


tests for mean and std-dev

tests for mean and std-dev

--- test/riemann/test/folds.clj
+++ test/riemann/test/folds.clj
@@ -105,3 +105,10 @@
          (is (= (quotient-sloppy [{:metric 0 :a true} {:metric 0}])
                 {:metric 0 :a true})))

+(deftest mean-test
+    (is (= {:metric 4} (mean [{:metric 2} {:metric 4} {:metric 6}])))
+    (is (= {:metric 4} (mean [{:metric 2} {:metric 4} {:metric nil} {:metric 6}]))))
+
+(deftest std-dev-test
+    (is (= 147.0 (Math/floor (:metric (std-dev [{:metric 600} {:metric 470} {:metric 170} {:metric 430} {:metric 300}])))))
+    (is (= 147.0 (Math/floor (:metric (std-dev [{:metric 600} {:metric nil} {:metric 470} {:metric 170} {:metric 430} {:metric 300}]))))))


bring in macros from ld34

bring in macros from ld34

error: pathspec 'src/cljs/infinitelives/pixi/macros.clj' did not match any file(s) known to git

--- src/cljs/infinitelives/pixi/macros.clj
+++ src/cljs/infinitelives/pixi/macros.clj
@@ -0,0 +1,50 @@
+(ns infinitelives.pixi.macros)
+
+(defmacro ^:private assert-args
+  [& pairs]
+  `(do (when-not ~(first pairs)
+         (throw (IllegalArgumentException.
+                 (str (first ~'&form) " requires " ~(second pairs) " in " ~'*ns* ":" (:line (meta ~'&form))))))
+       ~(let [more (nnext pairs)]
+          (when more
+            (list* `assert-args more)))))
+
+(defmacro get-layer [canvas layer]
+  `(-> ~canvas :layer ~layer))
+
+(defmacro with-sprite [canvas layer bindings & body]
+  (assert-args
+   (vector? bindings) "a vector for its binding"
+   (even? (count bindings)) "an even number of forms in binding vector")
+
+  (if (pos? (count bindings))
+    (let [symb (first bindings) val (second bindings)]
+      `(let [~symb ~val]
+         (.addChild (get-layer ~canvas ~layer) ~symb)
+         (with-sprite ~canvas ~layer ~(subvec bindings 2) ~@body)
+         (.removeChild (get-layer ~canvas ~layer) ~symb)))
+    `(do ~@body)))
+
+(defmacro with-sprite-set [canvas layer bindings & body]
+  (assert-args
+   (vector? bindings) "a vector for its binding"
+   (even? (count bindings)) "an even number of forms in binding vector")
+
+  (if (pos? (count bindings))
+    (let [symb (first bindings) val (second bindings)]
+      `(let [~symb ~val]
+         (doseq [sprite# ~symb]
+           (.addChild (get-layer ~canvas ~layer) sprite#))
+         (with-sprite-set ~canvas ~layer ~(subvec bindings 2) ~@body)
+         (doseq [sprite# ~symb]
+           (.removeChild (get-layer ~canvas ~layer) sprite#))))
+    `(do ~@body)))
+
+(defmacro while-let
+    "Repeatedly executes body while test expression is true, evaluating the body with binding-form bound to the value of test."
+    [bindings & body]
+    (let [form (first bindings) test (second bindings)]
+        `(loop [~form ~test]
+             (when ~form
+                 ~@body
+                 (recur ~test)))))


Add sha1 to ach on cljs

Add sha1 to ach on cljs

--- src-cljs/acha.cljs
+++ src-cljs/acha.cljs
@@ -130,8 +130,19 @@
       [:ul
         (map (fn [u] [:li (user u)]) users)]]))

+(defn- sha1-url [url sha1]
+  (let [path (condp re-matches url
+               #"(?i)(?:https?://)?(?:www\.)?github.com/([\-_\w0-9\.\/]+/?)\.git" :>> second
+               #"(?i)git\@github\.com\:([\-_\w0-9\.\/]+)\.git" :>> second
+               nil)]
+    (when path
+      (str "https://github.com/" path "/commit/" sha1))))
+
 (r/defc ach [ach]
-  (let [achent (:ach/achent ach)]
+  (let [achent (:ach/achent ach)
+        repo-url (get-in ach [:ach/repo :repo/url])
+        sha1 (:ach/sha1 ach)]
+    (println (sha1-url repo-url sha1))
     (s/html
       [:.ach
         [:.ach__logo
@@ -141,7 +152,7 @@
             [:.ach__level lvl])
           [:span.id (:ach/id ach)]]
         [:.ach__desc (:achent/desc achent)]
-        [:.ach__repo (get-in ach [:ach/repo :repo/url])]])))
+        [:.ach__repo repo-url]])))

 (r/defc ach-pane [aches]
   (s/html
@@ -286,6 +297,7 @@
                                :ach/repo   (repos (:repoid a))
                                :ach/user   (users (:userid a))
                                :ach/achent achent
+                               :ach/sha1   (:sha1 a)
                                :ach/ts     (.parse js/Date (:timestamp a)) }
                              (:level a)
                                (assoc :ach/level (:level a))))))


Adjust properly the display of the footer at mobile resolutions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/magoyette/marcandregoyette.com.git/'


added tmpfile registry functions

added tmpfile registry functions

error: pathspec 'src/tailrecursion/boot/tmpregistry.clj' did not match any file(s) known to git

--- src/tailrecursion/boot/tmpregistry.clj
+++ src/tailrecursion/boot/tmpregistry.clj
@@ -0,0 +1,74 @@
+(ns tailrecursion.boot.tmpregistry
+  (:require [clojure.java.io :as io]
+            [clojure.string :as str])
+  (:import java.io.File))
+
+;;; file stuff
+
+(def ^:dynamic *basedir* (File. "."))
+
+(defn append-path [f parts]
+  (apply str
+         (.getAbsolutePath (io/file f))
+         (interleave (repeat File/separator) parts)))
+
+(defn delete! [f]
+  (let [delete (io/file f)]
+    (doseq [child (.listFiles delete)] (delete! child))
+    (.delete delete)))
+
+(defn make-parents! [f]
+  (.. (io/file f) getParentFile mkdirs))
+
+;;; registry setup/teardown
+
+(def registries (atom {}))
+
+(defn ^File registry-dir []
+  (let [relative ".boot/tmp"]
+    (io/file (append-path *basedir* (str/split relative #"/")))))
+
+(defn destroy-registry! []
+  (let [dir (registry-dir)]
+    (swap! registries dissoc dir)
+    (delete! dir)))
+
+(defn create-registry! []
+  (destroy-registry!)
+  (let [dir (registry-dir)]
+    (swap! registries assoc-in [dir] {})
+    (doto dir (.mkdirs))))
+
+;;; obtaining, deleting tmp files from a registry
+
+(defn ^File mk [k name]
+  {:pre [(or (symbol? k) (keyword? k) (string? k))]}
+  (let [reg (registry-dir)
+        tmp (append-path reg [(munge k) name])]
+    (io/file (get-in (swap! registries assoc-in [reg k] tmp) [reg k]))))
+
+(defn mktemp [k & [name]]
+  (doto (mk k (or name (str (gensym "file") ".tmp")))
+    make-parents!
+    (.createNewFile)
+    (.setLastModified (System/currentTimeMillis))))
+
+(defn mktempdir [k & [name]]
+  (doto (mk k (or name (str (gensym "dir"))))
+    delete!
+    (.mkdirs)))
+
+(defn unmk [k]
+  (let [reg (registry-dir)]
+    (swap! registries update-in [reg] dissoc k)
+    (delete! (append-path reg [(munge k)]))))
+
+(comment
+  ;; by default, the registry goes in (File. "."). can be set with *basedir*.
+  (create-registry!)    ;=> recursively deletes and creates: #<File /home/alan/./.boot/tmp>
+  (mktemp ::foo)        ;=> #<File /home/alan/./.boot/tmp/_COLON_tmpregistry_SLASH_foo/file745.tmp>
+  (mktemp ::file "a.b") ;=> #<File /home/alan/./.boot/tmp/_COLON_tmpregistry_SLASH_file/a.b>
+  (mktempdir ::out)     ;=> #<File /home/alan/./.boot/tmp/_COLON_tmpregistry_SLASH_out/dir750>
+  (unmk ::out)
+  (destroy-registry!)   ;=> true (~/.boot/tmp was recursively deleted)
+)


Add 1st pass of state-id-instructions

Add 1st pass of state-id-instructions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-notification-works.git/'


more Mth to last element

more Mth to last element

Clojure

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/nikai3d/ce-challenges.git/'


test fix

test fix

--- src/metabase/models/field_values.clj
+++ src/metabase/models/field_values.clj
@@ -30,9 +30,9 @@
 (defn field-should-have-field-values?
   "Should this `Field` be backed by a corresponding `FieldValues` object?"
   {:arglists '([field])}
-  [{:keys [base_type special_type]}]
-  {:pre [base_type
-         special_type]}
+  [{:keys [base_type special_type] :as field}]
+  {:pre [(contains? field :base_type)
+         (contains? field :special_type)]}
   (or (contains? #{:category :city :state :country} (keyword special_type))
       (= (keyword base_type) :BooleanField)))


add new challange: Security Key Spaces

add new challange: Security Key Spaces

error: pathspec 'src/hackerrank/security/security_key_spaces.clj' did not match any file(s) known to git

--- src/hackerrank/security/security_key_spaces.clj
+++ src/hackerrank/security/security_key_spaces.clj
@@ -0,0 +1,26 @@
+;; Security Key Spaces
+;; https://www.hackerrank.com/challenges/security-key-spaces
+
+(ns hackerrank.security.key-spaces
+  (:require [clojure.java.io :as io])
+  (:use [clojure.string :only (split join trim)]))
+
+(defn parseInt [string]
+  (Integer/parseInt string))
+
+;; solution idea:
+
+(defn key-spaces
+  ([]
+    (def before (seq "0123456789"))
+    (def after (seq "1234567890"))
+    (def zipped (into {} (map hash-map before after)))
+    (let [message (trim (read-line))
+          e (parseInt (read-line))]
+      (apply str (map zipped (seq message)))))
+
+  ([input]
+   (with-in-str input
+     (key-spaces))))
+
+(key-spaces "391\n2")


Add a one-click-deploy function.

Add a one-click-deploy function.

error: pathspec 'src/circle/backend/build/deploy.clj' did not match any file(s) known to git

--- src/circle/backend/build/deploy.clj
+++ src/circle/backend/build/deploy.clj
@@ -0,0 +1,12 @@
+(ns circle.backend.build.deploy
+  "Deploying the circle app"
+  (:require [circle.backend.build.run :as run])
+  (:require [circle.backend.build.config :as config]))
+
+(defn one-click-deploy []
+  "Deploy immediately"
+  (let [build (config/build-from-url
+               "https://github.com/arohner/CircleCI"
+               :job-name
+               :deploy)]
+    (run/run-build build)))


Fix for splitting paths on non-Unix file systems

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/hudren/ebook-novel.git/'


Add temp-file and temp-dir contexts

Add temp-file and temp-dir contexts

error: pathspec 'src/main/clojure/lazytest/context/file.clj' did not match any file(s) known to git

--- src/main/clojure/lazytest/context/file.clj
+++ src/main/clojure/lazytest/context/file.clj
@@ -0,0 +1,64 @@
+(ns lazytest.context.file
+  (:use [lazytest.context :only (Context setup teardown)]
+	[lazytest.context.stateful :only (stateful)]
+	[clojure.java.io :only (file)])
+  (:import (java.io File)))
+
+(deftype TempFileContext [name suffix dir ^{:tag File :unsynchronized-mutable true} f]
+  Context
+  (setup [this] (set! f (File/createTempFile name suffix dir)))
+  (teardown [this] (.delete f)))
+
+(defn temp-file
+  "Returns a stateful context that creates a temporary file.  After
+  setup, an empty file named with the given prefix and suffix (both
+  optional) will exist.  The state of the context is the java.io.File.
+  The file will be deleted during teardown.
+
+  If suffix is a file extension, it should include the leading period,
+  e.g., \".txt\"
+
+  If dir is specified (string or File), the temporary file will be
+  created in that directory; otherwise it will be in the
+  system-default temporary directory."
+  ([]
+     (temp-file "temp" nil nil))
+  ([prefix]
+     (temp-file prefix nil nil))
+  ([prefix suffix]
+     (temp-file prefix suffix nil))
+  ([prefix suffix dir]
+     {:pre [(string? prefix)
+	    (or (nil? suffix) (string? suffix))]}
+     (let [dir (if (nil? dir) dir (file dir))]
+       (stateful (TempFileContext. prefix suffix dir nil)))))
+
+(deftype TempDirContext [name dir ^{:tag File :unsynchronized-mutable true} f]
+  Context
+  (setup [this]
+	 (set! f (File/createTempFile name "" dir))
+	 (assert (.delete f))
+	 (assert (.mkdirs f))
+	 f)
+  (teardown [this]
+	    (doseq [x (reverse (file-seq f))]
+	      (.delete x))))
+
+
+(defn temp-dir
+  "Returns a stateful context that creates a temporary directory.
+  After setup, an empty directory named with the given prefix and will
+  exist.  The state of the context is the java.io.File.  The directory
+  and all its contents will be recursively deleted during teardown.
+
+  If dir is specified (string or File), the temporary directory will
+  be created in that directory; otherwise it will be in the
+  system-default temporary directory."
+  ([]
+     (temp-dir "temp" nil))
+  ([prefix]
+     (temp-dir prefix nil))
+  ([prefix dir]
+     {:pre [(string? prefix)]}
+     (let [dir (if (nil? dir) dir (file dir))]
+       (stateful (TempDirContext. prefix dir nil)))))


[WM] wire up voter reg status fns

[WM] wire up voter reg status fns

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/voter-registration-http-api.git/'


Add overtone.synth.timing ns for synths related to timing signals

error: pathspec 'src/overtone/synth/timing.clj' did not match any file(s) known to git

--- src/overtone/synth/timing.clj
+++ src/overtone/synth/timing.clj
@@ -0,0 +1,15 @@
+(ns ^{:doc "A suite of synths useful for populating and manipulating
+            control busses of time signals i.e. generating and counting
+            beats."
+      :author "Sam Aaron"}
+  overtone.synth.timing
+  (:use [overtone.core]))
+
+(defsynth trigger [rate 100 out-bus 0]
+  (out:kr out-bus (impulse:kr rate)))
+
+(defsynth counter [in-bus 0 out-bus 0]
+  (out:kr out-bus (pulse-count:kr (in:kr in-bus))))
+
+(defsynth divider [div 32 in-bus 0 out-bus 0]
+  (out:kr out-bus (pulse-divider (in:kr in-bus) div)))


No idea what I'm doing. It's pretty shitty tooling system

error: pathspec 'Living_Clojure/first.clj' did not match any file(s) known to git

--- Living_Clojure/first.clj
+++ Living_Clojure/first.clj
@@ -0,0 +1,11 @@
+(ns first
+  (:require [clojure.set :as s]))
+
+(defn common-foods [foods1 foods2]
+  (let [food-set1 (set foods1)
+        food-set2 (set foods2)
+        common-foods (s/intersection food-set1 food-set2)]
+    (str "Common foods:" common-foods)))
+
+(common-foods ["pizza" "burgers" "burritos"]
+              ["pizza" "pasta" "nachos"])


fix occasional throttler test failures

fix occasional throttler test failures

--- test/metabase/api/common/throttle_test.clj
+++ test/metabase/api/common/throttle_test.clj
@@ -3,38 +3,38 @@
             [metabase.api.common.throttle :as throttle]
             [metabase.test.util :refer [resolve-private-fns]]))

-(def ^:private test-throttler (throttle/make-throttler :test, :initial-delay-ms 2, :attempts-threshold 3, :delay-exponent 2, :attempt-ttl-ms 10))
+(def ^:private test-throttler (throttle/make-throttler :test, :initial-delay-ms 5, :attempts-threshold 3, :delay-exponent 2, :attempt-ttl-ms 25))

 ;;; # tests for calculate-delay
 (resolve-private-fns metabase.api.common.throttle calculate-delay)

 ;; no delay should be calculated for the 3rd attempt
 (expect nil
-  (do (reset! (:attempts test-throttler) '([:x 100],[:x 99]))
+  (do (reset! (:attempts test-throttler) '([:x 100], [:x 99]))
       (calculate-delay test-throttler :x 101)))

-;; 1 ms delay on 4th attempt 1ms after the last
-(expect 1
+;; 4 ms delay on 4th attempt 1ms after the last
+(expect 4
   (do (reset! (:attempts test-throttler) '([:x 100], [:x 99], [:x 98]))
       (calculate-delay test-throttler :x 101)))

-;; 2 ms after last attempt, they should be allowed to try again
+;; 5 ms after last attempt, they should be allowed to try again
 (expect nil
   (do (reset! (:attempts test-throttler) '([:x 100], [:x 99], [:x 98]))
-      (calculate-delay test-throttler :x 102)))
+      (calculate-delay test-throttler :x 105)))

-;; However if this was instead the 5th attempt delay should grow exponentially (2 * 2^2 = 8), - 2 ms = 6
-(expect 6
+;; However if this was instead the 5th attempt delay should grow exponentially (5 * 2^2 = 20), - 2ms = 18ms
+(expect 18
   (do (reset! (:attempts test-throttler) '([:x 100], [:x 99], [:x 98], [:x 97]))
       (calculate-delay test-throttler :x 102)))

-;; Should be allowed after 6 more secs
+;; Should be allowed after 18 more secs
 (expect nil
   (do (reset! (:attempts test-throttler) '([:x 100], [:x 99], [:x 98], [:x 97]))
-      (calculate-delay test-throttler :x 108)))
+      (calculate-delay test-throttler :x 120)))

-;; Check that delay keeps growing according to delay-exponent (2 * 3^2 = 2 * 9 = 18)
-(expect 18
+;; Check that delay keeps growing according to delay-exponent (5 * 3^2 = 5 * 9 = 45)
+(expect 45
   (do (reset! (:attempts test-throttler) '([:x 108], [:x 100], [:x 99], [:x 98], [:x 97]))
       (calculate-delay test-throttler :x 108)))

@@ -70,32 +70,32 @@
          [:success]]
   [(attempt 4 :a)
    (do
-     (Thread/sleep 2)
+     (Thread/sleep 5)
      (attempt 1 :a))])

 ;; Next attempt should be throttled, however
 (expect [:success "Too many attempts! You must wait 0 seconds before trying again."]
   (do
     (attempt 4 :b)
-    (Thread/sleep 2)
+    (Thread/sleep 5)
     (attempt 2 :b)))

-;; Sleeping 2 ms after that shouldn't work due to exponential growth
+;; Sleeping 5 ms after that shouldn't work due to exponential growth
 (expect ["Too many attempts! You must wait 0 seconds before trying again."]
   (do
     (attempt 4 :c)
-    (Thread/sleep 2)
+    (Thread/sleep 5)
     (attempt 2 :c)
-    (Thread/sleep 2)
+    (Thread/sleep 5)
     (attempt 1 :c)))

-;; Sleeping 8 ms however should work
+;; Sleeping 20 ms however should work
 (expect [:success]
   (do
     (attempt 4 :d)
-    (Thread/sleep 2)
+    (Thread/sleep 5)
     (attempt 2 :d)
-    (Thread/sleep 8)
+    (Thread/sleep 20)
     (attempt 1 :d)))

 ;; Check that the interal list for the throttler doesn't keep growing after throttling starts
@@ -111,6 +111,6 @@
        (count @(:attempts test-throttler)))
    (do (attempt 3)
        (count @(:attempts test-throttler)))
-   (do (Thread/sleep 10)
+   (do (Thread/sleep 25)
        (attempt 1)
        (count @(:attempts test-throttler)))])


Change expected implementation file name for consistency

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mhelmetag/exercism.io.git/'


add default push-statey handler that always returns the index

error: pathspec 'src/main/shadow/http/push_state.clj' did not match any file(s) known to git

--- src/main/shadow/http/push_state.clj
+++ src/main/shadow/http/push_state.clj
@@ -0,0 +1,8 @@
+(ns shadow.http.push-state
+  (:require [clojure.java.io :as io]))
+
+(defn handle [{:keys [http-root devtools] :as req}]
+  (let [index-name
+        (get devtools :push-state/index "index.html")]
+    {:status 200
+     :body (slurp (io/file http-root index-name))}))


Of course - the new source file would be helpful too :-(

error: pathspec 'src/aeolian/abc/notelength.clj' did not match any file(s) known to git

--- src/aeolian/abc/notelength.clj
+++ src/aeolian/abc/notelength.clj
@@ -0,0 +1,6 @@
+(ns aeolian.abc.notelength)
+
+(def ^:const whole "")
+(def ^:const half "2")
+(def ^:const quarter "4")
+(def ^:const eighth "8")


more Multiplication Tables

more Multiplication Tables

Clojure


Adding some datalog util functions

Adding some datalog util functions

error: pathspec 'src/conceptnet_clj/datalog.clj' did not match any file(s) known to git

--- src/conceptnet_clj/datalog.clj
+++ src/conceptnet_clj/datalog.clj
@@ -0,0 +1,12 @@
+(ns conceptnet-clj.datalog)
+
+(defn tuplify
+  "Returns a vector of the vals at keys ks in map."
+  [m ks]
+  (mapv #(get m %) ks))
+
+(defn maps->rel
+  "Convert a collection of maps into a relation, returning
+   the tuplification of each map by ks"
+  [maps ks]
+  (mapv #(tuplify % ks) maps))


button hacking

button hacking

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/couragelabs/coachbot.git/'


start new

start new

fatal: unable to access 'https://github.com/ccqpein/Arithmetic-Exercises.git/': The requested URL returned error: 403


return row_count with GET /api/qs/:uuid response (expected by UI)

--- src/metabase/api/qs.clj
+++ src/metabase/api/qs.clj
@@ -51,12 +51,14 @@
   [{{:keys [cols columns rows data]
      :or {cols []
           columns []}} :result_data :as query-execution}]
-  (->
-    (select-keys query-execution [:id :uuid :status])
-    (assoc :data {:rows (or rows data [])
-                  :cols cols
-                  :columns columns})
-    (cond->
-      (= "failed" (:status query-execution)) (assoc :error (:error query-execution)
-                                                    ;; TODO - sql error formatting FN
-                                                    :sql_error (:error query-execution)))))
+  (let [rows (or rows data [])]
+    (->
+     (select-keys query-execution [:id :uuid :status])
+     (assoc :data {:rows rows
+                   :cols cols
+                   :columns columns}
+            :row_count (count rows))
+     (cond->
+         (= "failed" (:status query-execution)) (assoc :error (:error query-execution)
+                                                       ;; TODO - sql error formatting FN
+                                                       :sql_error (:error query-execution))))))


Uploader

Uploader

error: pathspec 'mtg-pairings-wer/src/mtg_pairings/uploader.clj' did not match any file(s) known to git

--- mtg-pairings-wer/src/mtg_pairings/uploader.clj
+++ mtg-pairings-wer/src/mtg_pairings/uploader.clj
@@ -0,0 +1,49 @@
+(ns mtg-pairings.uploader
+  (:require [org.httpkit.client :as http]
+            [cheshire.core :as json]))
+
+(defmacro response [callback]
+  `(fn [response#]
+     (doto (update-in response# [:body] #(json/parse-string % true))
+       ~callback)))
+
+(defmacro GET [url callback]
+  `(http/get ~url {} (response ~callback)))
+
+(defmacro POST [url options callback]
+  (let [opts (update-in options [:body] json/generate-string)]
+    `(http/post ~url ~opts (response ~callback))))
+
+(defmacro PUT [url options callback]
+  (let [opts (update-in options [:body] json/generate-string)]
+    `(http/put ~url ~opts (response ~callback))))
+
+(defn options [api-key body]
+  {:timeout 1000
+   :query-params {:key api-key}
+   :body body})
+
+(defn upload-tournament! [url api-key tournament callback]
+  (POST (str url "/tournament")
+        (options api-key tournament)
+        callback))
+
+(defn upload-teams! [url tournament-id api-key teams callback]
+  (PUT (str url "/tournament/" tournament-id "/teams")
+       (options api-key teams)
+       callback))
+
+(defn upload-seatings! [url tournament-id api-key seatings callback]
+  (PUT (str url "/tournament/" tournament-id "/seatings")
+       (options api-key seatings)
+       callback))
+
+(defn upload-pairings! [url tournament-id round api-key pairings callback]
+  (PUT (str url "/tournament/" tournament-id "/round-" round "/pairings")
+       (options api-key pairings)
+       callback))
+
+(defn upload-results! [url tournament-id round api-key results callback]
+  (PUT (str url "/tournament/" tournament-id "/round-" round "/results")
+       (options api-key pairings)
+       callback))


Added the input-receiver

Added the input-receiver

- not sure yet, it is kind of strange, but I want to define some interface between the terminal reader and the human player agent

Signed-off-by: Stefan Marr <46f1a0bd5592a2f9244ca321b129902a06b53e03@stefan-marr.de>

error: pathspec 'Clojure/src/snake/input_receiver.clj' did not match any file(s) known to git

--- Clojure/src/snake/input_receiver.clj
+++ Clojure/src/snake/input_receiver.clj
@@ -0,0 +1,9 @@
+(ns snake.input-receiver)
+
+(defn input-direction
+  "The agent or map representing the input receiver
+   needs to hold a function without arguments for
+   all symbols it needs to understand.
+   This function will be selected and called."
+  [current-agent dir-symbol]
+  ((get current-agent dir-symbol)))


Simple phrasing achievement scanners.

Simple phrasing achievement scanners.

error: pathspec 'src-clj/acha/achievement.clj' did not match any file(s) known to git

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -0,0 +1,69 @@
+(ns acha.achievement)
+
+(def example-achievement
+  {:name "Shiny Metal Ass"
+   :username "Bender"
+   :level 3
+   :timestamp 1234567890})
+
+(defn substring-phrasing-scanner [name needle]
+  (fn [commit-info]
+    (let [l-needle (.toLowerCase needle)
+          l-msg (.toLowerCase (:message commit-info))]
+    (when (.contains l-msg l-needle)
+      {:name name
+       :username (:author-name commit-info)
+       :timestamp (:timestamp commit-info)}))))
+
+; TODO commit-info achievements
+(defn catchphrase [timeline] nil)
+(defn bad-motherfucker [timeline] nil)
+(defn hello-linus [timeline] nil)
+(defn man-of-few-words [timeline] nil)
+(defn leo-tolstoy [timeline] nil)
+(defn citation-needed [timeline] nil)
+(defn no-more-letters [timeline] nil)
+(defn cool-kid [timeline] nil)
+(defn beggar [timeline] nil)
+(defn borat [timeline] nil)
+(defn never-probably [timeline] nil)
+
+; TODO diff achievements
+
+; TODO timeline achievements
+(defn catchphrase [timeline]
+  nil)
+
+; All the scanners return either nil or an achievement
+
+(def all-diff-scanners
+  [])
+
+(def all-commit-info-scanners
+  [(substring-phrasing-scanner "Mission impossible" "impossible")
+   (substring-phrasing-scanner "The Colour of Magic" "magic")
+   (substring-phrasing-scanner "Salvation" "sorry")
+   (substring-phrasing-scanner "I can sort it out myself" "google")
+   (substring-phrasing-scanner "Second thoughts" "forgot")
+   (substring-phrasing-scanner "Save the day" "fix")
+   (substring-phrasing-scanner "We're safe now" "secure")
+   (substring-phrasing-scanner "We're safe now" "secure")
+   (substring-phrasing-scanner "1337 H4XX0R" "hack")
+   (substring-phrasing-scanner "Wow" "wow")
+   catchphrase
+   bad-motherfucker
+   hello-linus
+   man-of-few-words
+   leo-tolstoy
+   citation-needed
+   no-more-letters
+   cool-kid
+   beggar
+   borat
+   never-probably
+   ])
+
+(def all-timeline-scanners
+  [catchphrase
+   ])
+


Moar achievements.

Moar achievements.

fatal: unable to access 'https://github.com/pjagielski/acha.git/': The requested URL returned error: 403


conj is OK with a nil list

conj is OK with a nil list

error: pathspec 'src/experiments/conj.clj' did not match any file(s) known to git

--- src/experiments/conj.clj
+++ src/experiments/conj.clj
@@ -0,0 +1,3 @@
+
+(println (conj () :a))
+(println (conj nil :a))


implemented get-json

implemented get-json

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/skprasadu/crud-ui-framework.git/'


save the chars

save the chars

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/starcity-properties/odin.git/'