Experimental distributed locks ns

Experimental distributed locks ns

error: pathspec 'src/taoensso/carmine/locks.clj' did not match any file(s) known to git

--- src/taoensso/carmine/locks.clj
+++ src/taoensso/carmine/locks.clj
@@ -0,0 +1,123 @@
+(ns taoensso.carmine.locks
+  "Alpha - subject to change.
+  Distributed lock implementation for Carmine based on work by Ronen Narkis
+  and Josiah Carlson.
+
+  Redis keys:
+    * carmine:lock:<lock-name> -> ttl str, lock owner's UUID
+
+  Ref. http://goo.gl/5UalQ for implementation details."
+  (:require [taoensso.carmine       :as car]
+            [taoensso.carmine.utils :as utils]
+            [taoensso.timbre        :as timbre]))
+
+(utils/defonce* config "Alpha - subject to change."
+  (atom {:conns {:pool (car/make-conn-pool)
+                 :spec (car/make-conn-spec)}
+         ;; :defaults {:lock-timeout-ms 2000
+         ;;            :wait-timeout-ms 500}
+         }))
+
+(defn set-config! [[k & ks] val] (swap! config assoc-in (cons k ks) val))
+
+(defmacro ^:private wcar
+  [& body]
+  `(let [{pool# :pool spec# :spec} (:conns @config)]
+     (car/with-conn pool# spec# ~@body)))
+
+;;(def ^:private lkey (memoize (car/make-keyfn "carmine" "lock")))
+(defn- lkey [lock-name] (str "carmine:lock:" (name lock-name)))
+
+(defn acquire-lock
+  "Attempts to acquire a distributed lock, returning owner's UUID iff successful."
+  [lock-name lock-timeout-ms wait-timeout-ms]
+  (let [max-udt (+ wait-timeout-ms (System/currentTimeMillis))
+        uuid    (str (java.util.UUID/randomUUID))]
+    (wcar ; Hold one connection for all attempts
+     (loop []
+       (when (> max-udt (System/currentTimeMillis))
+         (if (-> (car/lua-script
+                  "if redis.call('setnx', _:lkey, _:uuid) == 1 then
+                    redis.call('pexpire', _:lkey, _:lock-timeout-ms)
+                    return 1
+                  elseif redis.call('ttl', _:lkey) < 0 then
+                    redis.call('pexpire', _:lkey, _:lock-timeout-ms)
+                  end
+                  return 0"
+                  {:lkey            (lkey lock-name)}
+                  {:uuid            uuid
+                   :lock-timeout-ms lock-timeout-ms})
+                 car/parse-bool car/with-replies)
+           (car/return uuid)
+           (do (Thread/sleep 1) (recur))))))))
+
+(comment (acquire-lock "my-lock" 2000 500))
+
+(defn release-lock
+  "Attempts to release a distributed lock, returning true iff successful."
+  [lock-name owner-uuid]
+  (-> (car/lua-script
+       "if redis.call('get', _:lkey) == _:uuid then
+         redis.call('del', _:lkey)
+         return 1
+       else
+         return 0
+       end"
+       {:lkey (lkey lock-name)}
+       {:uuid owner-uuid})
+      car/parse-bool wcar))
+
+(comment
+  (when-let [uuid (acquire-lock "my-lock" 2000 500)]
+    [(Thread/sleep 100)
+     (release-lock "my-lock" uuid)
+     (release-lock "my-lock" uuid)]))
+
+(defn have-lock?
+  [lock-name owner-uuid]
+  (-> (car/lua-script
+       "if redis.call('get', _:lkey) == _:uuid then
+         return 1
+       else
+         return 0
+       end"
+       {:lkey (lkey lock-name)}
+       {:uuid owner-uuid})
+      car/parse-bool wcar))
+
+(comment
+  (when-let [uuid (acquire-lock "my-lock" 2000 500)]
+    [(Thread/sleep 100)
+     (have-lock? "my-lock" uuid)
+     (Thread/sleep 2000)
+     (have-lock? "my-lock" uuid)]))
+
+(defmacro with-lock
+  "Attempts to acquire a distributed lock, executing body and then releasing
+  lock when successful. Returns {:result <body's result>} on successful release,
+  or nil if the lock could not be acquired. If the lock is successfully acquired
+  but expires before being released, throws an exception."
+  [lock-name & [lock-timeout-ms wait-timeout-ms & body]]
+  `(when-let [uuid# (acquire-lock ~lock-name ~lock-timeout-ms ~wait-timeout-ms)]
+     (try
+       {:result (do ~@body)} ; Wrapped to distinguish nil body result
+       (catch Throwable t# (throw t#))
+       (finally
+        (when-not (release-lock ~lock-name uuid#)
+          (throw (RuntimeException. (str "Lock expired before it was released: "
+                                         ~lock-name))))))))
+
+(comment
+  (timbre/set-level! :debug)
+  (with-lock "my-lock" 2000 500 (Thread/sleep 1000) "foo!")  ; {:result "foo!"}
+  (with-lock "my-lock" 2000 500 (Thread/sleep 1000) (/ 1 0)) ; ex
+  (with-lock "my-lock" 2000 500 (Thread/sleep 2500) "foo!")  ; ex
+  (do (future (with-lock "my-lock" 2000 500  (Thread/sleep 1000) (println "foo!")))
+      (future (with-lock "my-lock" 2000 500  (Thread/sleep 1000) (println "bar!")))
+      (future (with-lock "my-lock" 2000 2000 (Thread/sleep 1000) (println "baz!")))))
+
+(defn- release-all-locks! []
+  (when-let [lkeys (seq (wcar (car/keys (lkey "*"))))]
+    (wcar (apply car/del lkeys))))
+
+(comment (release-all-locks!))


clean up unused requires

clean up unused requires

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/modnakasta/weasel.git/'


remove TODO RE change that I actually ended up making

--- src/metabase/email.clj
+++ src/metabase/email.clj
@@ -19,7 +19,6 @@
    Provided so you can swap this out with an \"inbox\" for test purposes."
   postal/send-message)

-;; TODO - wouldn't this be *nicer* if all args were kwargs?
 (defn send-message
   "Send an email to one or more RECIPIENTS.
    RECIPIENTS is a sequence of email addresses; MESSAGE-TYPE must be either `:text` or `:html`.


Update tweetwordcount.clj

Update tweetwordcount.clj

fatal: unable to access 'https://github.com/bruinAlex/indoor-stomach.git/': The requested URL returned error: 403


Made sure smash gets updated when generating mobi

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/'


improve send-schema to require pdf-like files

Need to have a ".pdf" extension

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/mail-works.git/'


WIP commit, starting to add a tree shaking pass

error: pathspec 'src/oxcart/passes/tree_shake.clj' did not match any file(s) known to git

--- src/oxcart/passes/tree_shake.clj
+++ src/oxcart/passes/tree_shake.clj
@@ -0,0 +1,70 @@
+;;   Copyright (c) Reid McKenzie, Rich Hickey & contributors. The use
+;;   and distribution terms for this software are covered by the
+;;   Eclipse Public License 1.0
+;;   (http://opensource.org/licenses/eclipse-1.0.php) which can be
+;;   found in the file epl-v10.html at the root of this distribution.
+;;   By using this software in any fashion, you are agreeing to be
+;;   bound by the terms of this license.  You must not remove this
+;;   notice, or any other, from this software.
+
+(ns oxcart.passes.tree-shake
+  {:doc "Implements a tree shaking pass intended to be run after def analysis."
+   :author "Reid McKenzie"
+   :added "0.0.5"}
+  (:require [oxcart.util :as util]
+            [oxcart.passes.defs :as defs]
+            [clojure.set :as set]
+            [clojure.tools.analyzer.ast :as ast]))
+
+
+(defn reach-set
+  "λ AST → #{Symbol}
+
+  Computes the var reach set of an AST"
+  [source]
+  (->> source
+       ast/nodes
+       (keep :var)
+       (into #{})))
+
+
+(defn -step-reach-set
+  [ast]
+  (util/map-vals
+   (fn [v]
+     (->> v
+          (map (partial get ast))
+          (reduce set/union v)))))
+
+
+(defn global-reach-set
+  "λ {Symbol → AST} → {Symbol → #{Symbol}}
+
+  Computes the reach set for an entire program"
+  [whole-program-ast]
+  (util/fix -step-reach-set
+            (-> whole-program-ast
+                (util/map-vals reach-set))))
+
+
+(defn tree-shake-module
+  [module options]
+  )
+
+(defn tree-shake
+  "λ Whole-AST → options → Whole-AST
+
+  Implements def elimination on the basis of prior reachability
+  analysis. Uses the reachability analysis as proof that a given def
+  is used or not used and drops the ASTs constituting unused defs from
+  the program.
+
+  options:
+
+    :entry is a symbol, presumably a namespace qualified -main var,
+    which is the entry point of the prorgam. It is with respect to this
+    function that all other defs will be considered for elimination."
+  [ast {:keys [entry] :as options}]
+  (-> ast
+      (defs/locate-defs options)
+      (util/map-vals (partial tree-shake-module options))))


Fix it so that item text does not wrap, but...

... stays on one line, regardless of line length and whitespace.

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/Reefersleep/sleepydo.git/'


bump reactor dep

bump reactor dep

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/'


add profiles.clj with support for travis-ci

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

--- profiles.clj
+++ profiles.clj
@@ -0,0 +1 @@
+{:travis-ci  {:env {:database-url "postgres://postgres@localhost/babel"}}}


Added an output filename-checking function.

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/'


Add tests for types

Add tests for types

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

--- test/clj/introspect/type_test.clj
+++ test/clj/introspect/type_test.clj
@@ -0,0 +1,51 @@
+(ns introspect.type-test
+  (:import [introspect.helpers FooChildA FooChildB ParentClass ChildClass])
+  (:require [clojure.test :refer :all]
+            [introspect.type :refer :all]
+            [introspect.helpers.simple-functions :as h1]))
+
+(deftest have-common-ancestor-test
+  (is (have-common-ancestor? (type (FooChildA.))
+                             (type (FooChildB.))))
+  )
+
+(deftest subtype-test
+  (is (subtype? (type (ParentClass.))
+                (type (ChildClass.))))
+  (is (any-subtype? (type (ParentClass.))
+                    (type (ChildClass.))))
+  (is (any-subtype? (type (ChildClass.))
+                    (type (ParentClass.))))
+  )
+
+(deftest call-types-match-test
+  (is (call-types-match? [Integer Integer Integer]
+                         #{[Integer Integer Integer]}))
+
+  (is (not (call-types-match? [Integer Integer]
+                              #{[Integer Integer Integer]})))
+
+  (is (call-types-match? [(type (fn []))]
+                         #{[(type (fn []))]}))
+
+  (is (not (call-types-match? [(type (fn []))]
+                              #{[Integer]})))
+
+  (is (call-types-match? [(type (fn []))]
+                         #{[(type (fn []))]}))
+
+  (is (call-types-match? [(type (fn []))]
+                         #{[(type (fn []))]}))
+
+  (is (call-types-match? [(type (ParentClass.)) (type (ParentClass.))]
+                         #{[(type (ChildClass.)) (type (ChildClass.))]}
+                         ))
+
+  (is (call-types-match? [(type (ChildClass.)) (type (ChildClass.))]
+                         #{[(type (ParentClass.)) (type (ParentClass.))]}
+                         ))
+
+
+  (is (call-types-match? [(type (ParentClass.)) (type (ChildClass.))]
+                         #{[(type (ParentClass.)) (type (ChildClass.))]}
+                         )))


adding acme query examples

adding acme query examples

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

--- test/example/query.clj
+++ test/example/query.clj
@@ -0,0 +1,231 @@
+(ns example.query
+  (:use plasma.core
+        test-utils)
+  (require [plasma.query.core :as q]
+           [logjam.core :as log]))
+
+(def acme-graph (open-graph "db/example.query"))
+
+(defn make-acme-graph
+  []
+  (clear-graph)
+  (let [root (root-node-id)] ; acme is root
+    (let-nodes [
+                alice         {:label :alice :gender :female}
+                bob           {:label :bob   :gender :male}
+                maria         {:label :maria :gender :female}
+                lugano        :lugano-office
+                geneva        :geneva-office
+                zurich        :zurich-office
+                product-alpha {:label :alpha :price 110.00}
+                product-beta  {:label :beta  :price 600.00}
+                comp-1        {:label :component-1 :cost 24.00}
+                comp-2        {:label :component-2 :cost 8.00}
+                comp-3        {:label :component-3 :cost 75.00}
+                comp-4        {:label :component-4 :cost 120.00}
+                ]
+      (edges!
+        [
+         root alice         :person
+         root bob           :person
+         root maria         :person
+         root lugano        :location
+         root geneva        :location
+         root zurich        :location
+         alice geneva       :manages
+         geneva alice       :managed-by
+         bob zurich         :manages
+         zurich bob         :managed-by
+         maria lugano       :manages
+         lugano maria       :managed-by
+         root product-alpha :product
+         root product-beta  :product
+         product-alpha lugano :made-in
+         product-beta  lugano :made-in
+         product-alpha comp-1 :component
+         product-alpha comp-2 :component
+         product-beta  comp-2 :component
+         product-beta  comp-3 :component
+         product-beta  comp-4 :component
+         comp-1 zurich :made-in
+         comp-2 zurich :made-in
+         comp-3 geneva :made-in
+         comp-4 geneva :made-in
+         ]))))
+
+(defn setup-acme
+  []
+  (graph-apply acme-graph make-acme-graph))
+
+(defn acme
+  "Define a helper function to query our acme graph."
+  [q]
+  (graph-apply acme-graph #(query q)))
+
+; basic path selection
+;  - no binding
+;  - with binding
+;  - multiple bindings
+
+(defn products-a
+  "Select all of the products connected to the root node with an edge
+  labeled :product."
+  []
+  (q/path [:product]))
+
+(defn products
+  "Select the products exactly as before, but create a path binding variable
+  that can be referred to later in the query."
+  []
+  (q/path [product [:product]]))
+
+(defn managers
+  "Select the manager of each location, and create a query binding
+  to these manager nodes so they can be referred to within the query."
+  []
+  (q/path [manager [:location :managed-by]]))
+
+(defn components
+  "Select the components that make up ACME products.  This example shows how
+  you can use multi-segment bindings in a path expression."
+  []
+  (q/path [product [:product]
+           component [product :component]]))
+
+; projection
+(defn product-prices
+  "By default queries only return the node IDs of the result set, so
+  if you want to get specific properties of a node you need to project
+  those properties.  Note how the query binding variable \"product\" is
+  quoted, which differentiates it from a normal program variable.  This
+  allows you to mix both run-time program variables and query execution
+  time query bindings."
+  []
+  (-> (products)
+    (q/project ['product :label :price])))
+
+(defn with-product-info
+  "It can be useful to have a projection function like this, which you
+  can use to wrap queries that you want to project some specific properties."
+  [query]
+  (-> query
+    (q/project ['product :label :price])))
+
+;For example:
+;  (acme (with-product-info (products)))
+
+(defn with-component-info
+  "It can be useful to have a projection function like this, which you
+  can use to wrap queries that you want to project some specific properties."
+  [query]
+  (-> query
+    (q/project ['component :label :cost])))
+
+;For example:
+;  (acme (with-component-info (components)))
+
+; Could we do something like this?
+(comment def product-component-prices
+  (-> components
+    (q/expr [total-cost (sum (:price 'component))])
+    (q/project ['product :label] 'total-cost)))
+
+; where filtering
+; - simple property equality
+; - with mathematical expression
+; - matching interesting graph pattern using multiple bindings
+
+(defn managers-by-gender
+  "The where form can be used to filter the results based on property
+  values of bound nodes."
+  [gender]
+  (-> (managers)
+    (q/where (= gender (:gender 'manager)))))
+
+(defn female-managers
+  []
+  (managers-by-gender :female))
+
+(defn male-managers
+  []
+  (managers-by-gender :male))
+
+(defn profitable-components
+  "Where forms can be constructed using both arithmetic and boolean
+  expressions.  Here is a function that returns a query which will
+  return all components that have a marked-up cost greater than
+  a given threshold."
+  [markup threshold]
+  (-> (components)
+    (q/where (> (* markup (:cost 'component)) threshold))))
+
+; For example:
+;  (acme (profitable-components 3 100))
+
+; or with the label and price
+;  (acme (with-component-info (profitable-components 3 100)))
+
+(defn with-components-from
+  "The where expression can pertain to multiple binding points in the query
+  as well.  For example, this function will return all products that
+  have components which were made in the specified location."
+  [loc]
+  (-> (q/path [location [(components) :made-in]])
+    (q/where (= loc (:label 'location)))))
+
+; order-by
+; - asc
+; - desc
+(def components-by-cost
+  "By default the sort order is ascending."
+  (-> components
+    (q/order-by 'component :cost)))
+
+(def products-by-price
+  "But you can specify descending like so."
+  (-> products
+    (q/order-by 'product :price :desc)))
+
+; limit
+; - need offset?
+(def cheapest-component
+  (-> components-by-cost
+    (q/limit 1)))
+
+; choose
+(defn n-random-components
+  [n]
+  (-> components
+    (q/choose n)))
+
+; group-by
+(defn components-by-location
+  [loc]
+  (-> (with-components-from loc)
+    (order-by 'location :label)
+    (with-component-info)))
+
+; count
+(def num-products
+  (-> products
+    (count*)))
+
+(defn num-products-with-components-from
+  [loc]
+  (count* (with-components-from loc)))
+
+; average
+(def average-product-price
+  (-> products
+    (avg 'product :price)))
+
+; min/max
+(def cheapest-component
+  (-> components
+    (min 'component :price)))
+
+(def most-expensive-component
+  (-> components
+    (min 'component :price)))
+
+; distinct?


add implementation for update/replace/delete document in document.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/colophon/clarango.git/'


Add random.cljx

Add random.cljx

error: pathspec 'src/cljx/robinson/random.cljx' did not match any file(s) known to git

--- src/cljx/robinson/random.cljx
+++ src/cljx/robinson/random.cljx
@@ -0,0 +1,112 @@
+;; Utility functions and functions for manipulating state
+(ns robinson.random
+  (:use     clojure.contrib.core)
+  (:require [clojure.data.generators :as dg]
+            [clojure.core.typed :as t]
+            [taoensso.timbre :as timbre]
+            [pallet.thread-expr :as tx]))
+
+(timbre/refer-timbre)
+
+(defrecord RandomState [seed have-next-next-gaussian next-next-gaussian])
+
+(defprotocol Random
+  (next-int! [this]
+             [this n])
+  (next-float! [this])
+  (next-long! [this])
+  (next-boolean! [this])
+  (next-double! [this])
+  (next-gaussian! [this])
+  (get-state [this]))
+
+
+(def ^:private addend 0xB)
+(def ^:private multiplier 0x5DEECE66D)
+(def ^:private mask (dec (bit-shift-left 1 48)))
+
+(defn create-random
+  [seed-or-state]
+  (let [seed                    (cond (number? seed-or-state)
+                                      (atom seed-or-state)
+                                      (instance? RandomState seed-or-state)
+                                      (atom (get seed-or-state :seed))
+                                      :else
+                                      (throw "create-random requires either a number or RandomState"))
+        next-next-gaussian      (cond (number? seed-or-state)
+                                      (ref 0)
+                                      (instance? RandomState seed-or-state)
+                                      (ref (get seed-or-state :next-next-gaussian))
+                                      :else
+                                      (throw "create-random requires either a number or RandomState"))
+        have-next-next-gaussian (cond (number? seed-or-state)
+                                      (ref false)
+                                      (instance? RandomState seed-or-state)
+                                      (ref (get seed-or-state :havenext-next-gaussian))
+                                      :else
+                                      (throw "create-random requires either a number or RandomState"))
+        next! (fn [bits]
+                (int (bit-and 0x7FFFFFFF
+                              (unsigned-bit-shift-right
+                                (swap! seed (fn [s]
+                                              (bit-and
+                                                (unchecked-add
+                                                  (unchecked-multiply (long s)
+                                                                      (long multiplier))
+                                                  addend)
+                                                 mask)))
+                                (- 48 bits)))))]
+    (reify Random
+      (next-int! [this]
+        (next! 32))
+      (next-int! [this n]
+        (if (= n (bit-and n (- n)))
+          (int (bit-shift-right (unchecked-multiply n (long (next! 31)))
+                                31))
+          (loop [bits   (next! 31)
+                 value  (mod bits n)]
+            (if (neg? (- bits (+ value (dec n))))
+              (let [bits  (next! 31)
+                    value (mod bits n)]
+                (recur bits value))
+              value))))
+      (next-long! [this]
+        (+ (long (next! 32)) (next! 32)))
+      (next-boolean! [this]
+        (not= (next! 1) 0))
+      (next-float! [this]
+        (/ (next! 24) (float (bit-shift-left 1 24))))
+      (next-double! [this]
+        (/ (+ (bit-shift-left (long (next! 26)) 27)
+              (next! 27))
+           (double (bit-shift-left 1 53))))
+      (next-gaussian! [this]
+        (dosync
+          (if @have-next-next-gaussian
+            (do
+              (ref-set have-next-next-gaussian false)
+              @next-next-gaussian)
+            (loop [v1 (dec (* 2 (next-double! this)))
+                   v2 (dec (* 2 (next-double! this)))
+                   s  (+ (* v1 v1) (* v2 v2))]
+              (if (or (>= s 1) (zero? s))
+                (let [v1 (dec (* 2 (next-double! this)))
+                      v2 (dec (* 2 (next-double! this)))
+                      s  (+ (* v1 v1) (* v2 v2))]
+                  (recur v1 v2 s))
+                (let [multiplier #+clj (StrictMath/sqrt (* -2 (/ (StrictMath/log s) s)))
+                                 #+cljs (.sqrt js/Math (* -2 (/ (.log js/Math s) s)))]
+                  (ref-set next-next-gaussian (* v2 multiplier))
+                  (ref-set have-next-next-gaussian true)
+                  (* v1 multiplier)))))))
+     (get-state [this]
+       (RandomState. @seed @next-next-gaussian @have-next-next-gaussian)))))
+
+(def ^:dynamic
+  *rnd*
+  (create-random 42))
+
+(defn uniform-int
+ ([hi] {:pre [(pos? hi)]} (next-int! *rnd* 0 hi))
+ ([lo hi] {:pre [(< lo hi)]} (next-int! *rnd* lo hi)))
+


Remove cake link.

Remove cake link.

--- src/clojars/web/dashboard.clj
+++ src/clojars/web/dashboard.clj
@@ -21,13 +21,8 @@
      (link-to
       "http://github.com/technomancy/leiningen/blob/master/README.md"
       "Leiningen")
-     " and "
-     (link-to
-      "http://github.com/ninjudd/cake"
-      "Cake")
-     " but you can use it with other build tools like "
-     (link-to "http://maven.apache.org/" "Maven") " or "
-     (link-to "http://ant.apache.org/ivy/" "Ivy") " as well."
+     ", but you can use it with other build tools like "
+     (link-to "http://maven.apache.org/" "Maven") " as well."
      [:div {:class "maven"}
       [:h3 "maven repository"]
       [:pre


bump benchmark dependency versions

bump benchmark dependency versions

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/altamiracorp/honeycomb.git/'


creating centralized metronome as default metro for gui sequencers

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

--- src/overtone/gui/transport.clj
+++ src/overtone/gui/transport.clj
@@ -0,0 +1,6 @@
+(ns overtone.gui.transport
+  (:use [overtone.music rhythm]
+        [overtone.gui color]
+        seesaw.core))
+
+(def ^:dynamic *master-metronome* (metronome 130))


Don't use <img> for images

Don't use <img> for images

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/nvbn/rerenderer.git/'


(comment something)

(comment something)

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/fhirbase/fhirplace.git/'


Warn, don't fail if the requested path for backup does not exist.

--- src/clojars/admin.clj
+++ src/clojars/admin.clj
@@ -14,9 +14,13 @@
   (let [backup (doto (io/file (:deletion-backup-dir config))
                  (.mkdirs))
         parts' (vec (remove nil? parts))]
-    (FileUtils/moveDirectory
-      (apply io/file (:repo config) (str/replace (first parts') "." "/") (rest parts'))
-      (io/file backup (str/join "-" (conj parts' (current-date-str)))))))
+    (try
+      (FileUtils/moveDirectory
+        (apply io/file (:repo config)
+                   (str/replace (first parts') "." "/") (rest parts'))
+        (io/file backup (str/join "-" (conj parts' (current-date-str)))))
+      (catch Exception e
+        (printf "WARNING: failed to backup %s: %s\n" parts' (.getMessage e))))))

 (defn help []
   (println


log messages

log messages

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/jchli/jepsen-aurora.git/'


faster timeout for add-job

faster timeout for add-job


remove extra debug logging

remove extra debug logging

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/'


Fix @-mention tests

Fix @-mention tests


Changed logic to at least persist message

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/acessocard/microscope.git/'


passing (dummy) test

passing (dummy) test

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/'


MOAR TESTS

MOAR TESTS

--- test/dependable/resolve_test.clj
+++ test/dependable/resolve_test.clj
@@ -14,6 +14,8 @@
         (let [[k v] result]
           v)))))

+
+;; TODO: disjunctive clause tests

 (let  [package-a30
        (->package
@@ -188,17 +190,21 @@
                 :conflicts {"d" [#(< (:version %) 22)]})
                [:successful #{package-d22}]))))))

-
-#_(deftest ^:resolve-basic requires
+(deftest ^:resolve-basic requires
     (let [package-a
-          {:id "a"
-           :version 30
-           :location "a_loc30"
-           :requires [{:id "b"}]}
+          (->package
+            "a"
+            30
+            "a_loc30"
+            [
+             [(present "b")]
+             ])
           package-b
-          {:id "b"
-           :version 20
-           :location "b_loc20"}
+          (->package
+            "b"
+            20
+            "b_loc20"
+            nil)
           repo-info
           {"a" [package-a]
            "b" [package-b]}
@@ -206,42 +212,59 @@
       (testing (str "One package should require another and both "
                     "should be found.")
         (is (= (resolve-dependencies
-                [{:id "a"}]
+                 [
+                  [(present "a")]
+                  ]
                 query)
                [:successful #{package-a package-b}])))
       (testing (str "One package should be found when it requires "
                     "another, but it's already installed.")
         (is (= (resolve-dependencies
-                [{:id "a"}]
+                 [
+                  [(present "a")]
+                  ]
                 query
-                :present-packages {"b" 20})
+                :present-packages {"b" package-b})
                [:successful #{package-a}]))))
     (let [package-a
-          {:id "a"
-           :version 10
-           :location "a_loc30"}
+          (->package
+            "a"
+            10
+            "a_loc10"
+            nil)
           package-b
-          {:id "b"
-           :version 20
-           :location "b_loc20"
-           :requires [{:id "c"}]}
+          (->package
+            "b"
+            20
+            "b_loc20"
+            [
+             [(present "c")]
+             ])
           package-c
-          {:id "c"
-           :version 10
-           :conflicts {"a" nil}}
-
+          (->package
+            "c"
+            10
+            "c_loc10"
+            [
+             [(absent "a")]
+             ])
           repo-info
           {"a" [package-a]
            "b" [package-b]
            "c" [package-c]}
           query (map-query repo-info)]
-      (testing (str "A package having dependencies which conflicts with "
-                    "other packages downloaded should be rejected.")
-        (is (= (resolve-dependencies
-                [{:id "a"}
-                 {:id "b"}]
-                query)
-               [:unsuccessful ["b" "c"]]))))
+      (testing
+        (str "A package having dependencies which conflicts with "
+             "other packages downloaded should be rejected.")
+        (let [aclause [(present "a")]
+              bclause [(present "b")]]
+        (is (= (resolve-dependencies
+                 [
+                  aclause
+                  bclause
+                  ]
+                query)
+               [:unsuccessful aclause])))))
     (let [package-a
           {:id "a"
            :version 10
@@ -262,12 +285,53 @@
           query (map-query repo-info)]
       (testing (str "A package having dependencies rejected a priori "
                     "also gets rejected")
-        (is (= (resolve-dependencies
-                [{:id "a"}
-                 {:id "b"}]
-                query
-                :conflicts {"c" nil})
-               [:unsuccessful ["b" "c"]])))))
+               (let [aclause [(present "a")]]
+                 (is (= (resolve-dependencies
+                          [
+                           aclause
+                           [(present "b")]
+                           ]
+                          query
+                          :conflicts {"c" nil})
+                        [:unsuccessful aclause]))))))
+
+(deftest
+  ^:resolve-basic disjunctive-clauses
+  (testing
+    "Disjunction tautology"
+    (is (= (resolve-dependencies
+             [
+              [(absent "c") (present "b")]
+              ]
+             (map-query {}))
+             [:successful #{}])))
+  (testing
+    "Skip past a conflict"
+    (let [package-a
+          (->package
+            "a"
+            30
+            "a_loc30"
+            [
+             [(present "b")]
+             ])
+          package-b
+          (->package
+            "b"
+            20
+            "b_loc20"
+            nil)
+          repo-info
+          {"a" [package-a]
+           "b" [package-b]}
+          query (map-query repo-info)]
+      (is (= (resolve-dependencies
+               [
+                [(absent "c") (present "b")]
+                ]
+               query
+               :present-packages (->package "c" 10 "c_loc10" nil))
+             [:successful #{package-b}])))))

 #_(deftest ^:resolve-basic no-locking
     (testing (str "Find two packages, even when the preferred version "


Add hm_heuristic

Add hm_heuristic

error: pathspec 'src/angelic/sas/hm_heuristic.clj' did not match any file(s) known to git

--- src/angelic/sas/hm_heuristic.clj
+++ src/angelic/sas/hm_heuristic.clj
@@ -0,0 +1,36 @@
+(ns angelic.sas.hm-heuristic
+  (:require [edu.berkeley.ai.util :as util]
+            [edu.berkeley.ai.util.graphs :as graphs]
+            [angelic.sas :as sas])
+  (:import [java.util IdentityHashMap LinkedList]))
+
+;; Obvious generalization of the hm heuristics to SAS+ problems.
+;; Basic idea is to look for actio
+;; First just implement h_max.
+
+(defn h-max [state actions]
+  (let [a-map    (util/map-vals second
+                  (group-by first (for [a actions, kv (:precond-map a)] [kv a])))
+        a-counts (IdentityHashMap.
+                  (into {} (for [a actions] [a (count (:precond-map a))])))
+        closed   (HashMap.)
+        goal-pair [sas/goal-var-name sas/goal-var-true]]
+    (loop [rew 0 open (LinkedList. (seq init)) next-open (LinkedList.)]
+      (if (empty? open)
+        (if (empty? next-open)
+          Double/NEGATIVE_INFINITY
+          (recur (dec rew) next-open open))
+        (let [f (.remove open)]
+          (if (= f goal-pair)
+            rew
+            (doseq [a (a-map f)]
+              (let [oc (.get a-counts a)
+                    nc (dec oc)]
+                (.put a-counts a nc)
+                (when (= nc 0)
+                  (doseq [ep (:effect-map a)]
+                    (when-not (.contains closed ep)
+                      (.put closed ep rew)
+                      (.offer ^LinkedList (case (:reward a) 0 open -1 next-open) a))))))))))))
+
+


Update lein/profiles.clj

Update lein/profiles.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/jongold/dotfiles.git/'


add a bit

add a bit

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

--- src/codeitlater/store_record.clj
+++ src/codeitlater/store_record.clj
@@ -0,0 +1,11 @@
+(ns codeitlater.store-record
+  )
+
+(defn write-down [path lst]
+  "store list result returned from core/read-file to local path"
+  )
+
+(defn read-from [path]
+  "read lst back from local file")
+
+


Feature/api gateway (#95)

Feature/api gateway (#95)

* minimal API Gateway resource set

* Fix missing and incorrect specs. (#92)

error: pathspec 'src/crucible/aws/api_gateway.clj' did not match any file(s) known to git

--- src/crucible/aws/api_gateway.clj
+++ src/crucible/aws/api_gateway.clj
@@ -0,0 +1,63 @@
+(ns crucible.aws.api-gateway
+  "Resources in AWS::ApiGateway::*"
+  (:require [clojure.spec :as s]
+            [crucible.resources :refer [spec-or-ref defresource] :as res]
+            [crucible.encoding.keys :refer [->key]]))
+
+(defn apigw [resource] (str "AWS::ApiGateway::" (->key resource)))
+
+(s/def ::rest-api (s/keys :opt [::body
+                                ::body-s3-location
+                                ::clone-from
+                                ::description
+                                ::fail-on-warnings
+                                ::name
+                                ::parameters]))
+
+(s/def ::account any?)
+
+(defresource account (apigw :account) ::account)
+
+(s/def ::api-key any?)
+
+(defresource api-key (apigw :api-key) ::api-key)
+
+(s/def ::authorizer any?)
+
+(defresource authorizer (apigw :authorizer) ::authorizer)
+
+(s/def ::base-path-mapping any?)
+
+(defresource base-path-mapping (apigw :base-path-napping) ::base-path-mapping)
+
+(s/def ::client-certificate any?)
+
+(defresource client-certificate (apigw :client-certificate) ::client-certificate)
+
+(s/def ::deployment any?)
+
+(defresource deployment (apigw :deployment) ::deployment)
+
+(s/def ::method any?)
+
+(defresource method (apigw :method) ::method)
+
+(s/def ::model any?)
+
+(defresource model (apigw :model) ::model)
+
+(s/def ::resource any?)
+
+(defresource resource (apigw :resource) ::resource)
+
+(s/def ::rest-api any?)
+
+(defresource rest-api (apigw :rest-api) ::rest-api)
+
+(s/def ::stage any?)
+
+(defresource stage (apigw :stage) ::stage)
+
+(s/def ::usage-plan any?)
+
+(defresource usage-plan (apigw :usage-plan) ::usage-plan)


Sketching out simplification

Sketching out simplification

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/leif47/immutabledb-experimental.git/'


convert comments in main to printlns to make output more readable


Gogokoak lortu

Gogokoak lortu

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/'


increased times in in-parallel test to make them stable. was previously flaky on my older laptop

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/tobiasbayer/lambdacd.git/'


very basic version of frames works

very basic version of frames works

error: pathspec 'clojure_dmap/utilities/frame.clj' did not match any file(s) known to git

--- clojure_dmap/utilities/frame.clj
+++ clojure_dmap/utilities/frame.clj
@@ -0,0 +1,75 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; frame.clj
+;; A frame is a hash of attribute-value pairs that is part
+;; of an inheritance hierarchy.
+;; This module includes an uber-hash holding all the frames.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(load-file "arities.clj")
+(def frame-of {})
+
+
+;; TODO consider implementation of relationships to base and children frames
+;; put those frame names in the same space as the attr/values?
+;; How does Riesbeck do it?
+
+(defstruct frame :name :features :specializations :abstractions)
+
+;; stuff is specializations then abstractions
+(defn new-create-frame	[frame-name slot-list value-list & stuff]
+		(def frame-of
+			(assoc frame-of frame-name
+			  (struct frame
+				; name
+				frame-name
+				; features
+				(loop [new-frame {}  local-slot-list slot-list local-value-list value-list]
+					(let [slot (first local-slot-list) value (first local-value-list)]
+						(cond
+							(= (count local-slot-list) 0) new-frame
+							:t
+								(recur
+									(assoc new-frame slot value)
+									(rest local-slot-list)
+									(rest local-value-list)
+								))  ))
+				; specialization
+				(first stuff)
+				; abstractions
+				(second stuff)))))
+
+(defn get-specializations [frame-name]
+	((frame-of frame-name) :specializations))
+
+(defn base-slot [frame-name slot-name]
+	(println "fname:" frame-name "slot value:" ((frame-of frame-name) slot-name)  "slot name:" slot-name)
+	;;((frame-of frame-name) slot-name)
+)
+
+(defn print-frame [frame-name]
+	(println frame-name (frame-of frame-name))
+	(map get-specializations (get-specializations frame-name)) )
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;(create-frame :persona (list :fname :lname )  )
+;(print-frame :persona)
+;(create-frame :person (list :fname :lname :mi) (list "Bob" "Jones" "X") )
+;(print-frame :persona)
+;(print-frame :person)
+(println "======================================")
+
+
+
+;;(new-create-frame :empty-person (list :fname :lname :mi)  nil nil nil )
+(new-create-frame :empty-person (list :fname :lname :mi)  nil  )
+(print-frame :empty-person)
+(new-create-frame :new-person (list :fname :lname :mi) (list "Bob" "Jones" "X") nil nil)
+(print-frame :new-person)
+(println (base-slot :new-person :lname))
+(new-create-frame :new-director (list :company :title :salary) (list "The" "Director" 1000000) :new-person )
+(print-frame :new-person)
+(print-frame :new-director)
+(println (get-specializations :new-director))
+(println print-frame (get-specializations :new-director))
+(println "------------_________________--")


**Websocket handler needs fixing**

**Websocket handler needs fixing**

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/tahmidsadik112/websocket-server.git/'


fix delete

fix delete


Add gc ns.

Add gc ns.

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

--- src/konserve/gc.cljc
+++ src/konserve/gc.cljc
@@ -0,0 +1,13 @@
+(ns konserve.gc)
+
+(defn sweep!
+  "Walk all storage addresses from seq all-addresses, calling delete-fn on
+  each key that for which accept-fn returns true, AND is not contained
+  in the set addresses."
+  [addresses accept-fn all-addresses delete-fn]
+  (loop [addrs all-addresses]
+    (when-let [address (first addrs)]
+      (when (accept-fn address)
+        (delete-fn address))
+      (recur (rest addrs)))))
+


bob.clj

bob.clj

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

--- clojure/bob/bob.clj
+++ clojure/bob/bob.clj
@@ -0,0 +1,5 @@
+(ns bob)
+
+(defn respond-for
+	([x] (str "Whatever."))
+)


Etl in clojure, v1

Etl in clojure, v1

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

--- clojure/etl/etl.clj
+++ clojure/etl/etl.clj
@@ -0,0 +1,9 @@
+(ns etl
+  (:require [clojure.string :as str]))
+
+(defn- pairs [pair]
+  (let [[value key] pair]
+    (map (fn [k] {(str/lower-case k) value}) key)))
+
+(defn transform [words]
+  (into {} (flatten (map pairs words))))


entzun dokumentatu

entzun dokumentatu


Add cljs serializer test.

Add cljs serializer test.

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

--- test/konserve/serializers_test.cljs
+++ test/konserve/serializers_test.cljs
@@ -0,0 +1,47 @@
+(ns konserve.serializers-test
+  (:require [cljs.core.async :as async :refer [<! >!]]
+            [konserve.core :refer [get-in assoc-in dissoc]]
+            [konserve.serializers :refer [fressian-serializer]]
+            [cljs.test :refer-macros [run-tests deftest is testing async use-fixtures]]
+            [konserve.filestore :refer [new-fs-store delete-store list-keys]]
+            [cljs.nodejs :as node])
+  (:require-macros [cljs.core.async.macros :refer [go]]))
+
+(enable-console-print!)
+
+(def custom-read-handler
+  {"js-date" (fn [reader tag field-count]
+               (js/Date. (fress.api/read-object reader)))})
+
+(def custom-write-handler
+  {js/Date (fn [writer o] (let [date-time (.getTime o)]
+                            (fress.api/write-tag writer "js-date" 1)
+                            (fress.api/write-object writer date-time)))})
+
+(use-fixtures :once
+  {:before
+   (fn []
+     (async done
+            (go (delete-store "/tmp/konserve-fs-serializer-node-test")
+                (def store (<! (new-fs-store "/tmp/konserve-fs-serializers-test" :serializer (fressian-serializer custom-read-handler custom-write-handler))))
+                (done))))})
+
+(deftest serializers-test
+  (testing "Test the custom fressian serializers functionality."
+    (async done
+           (go
+             (is (= (<! (get-in store [:foo]))
+                    nil))
+             (<! (assoc-in store [:foo] (js/Date.)))
+             (is (= (type (<! (get-in store [:foo])))
+                      js/Date))
+             (is (= (<! (list-keys store {}))
+                      #{{:key :foo, :format :edn}}))
+             (<! (dissoc store :foo))
+             (is (= (<! (get-in store [:foo]))
+                      nil))
+             (is (= (<! (list-keys store {}))
+                      #{}))
+             (delete-store (:folder store))))))
+
+(run-tests)


Make Pair satisfy Bifunctor

Make Pair satisfy Bifunctor

--- src/cats/data.cljc
+++ src/cats/data.cljc
@@ -107,6 +107,10 @@
     (-fmap [_ f mv]
       (pair (.-fst mv) (f (.-snd mv))))

+    p/Bifunctor
+    (-bimap [_ f g s]
+      (pair (f (.-fst s)) (g (.-snd s))))
+
     p/Foldable
     (-foldl [_ f z mv]
       (f z (.-snd mv)))


correct and complete document CRUD methods documentation

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/colophon/clarango.git/'


add possessive name formatter helpers

add possessive name formatter helpers

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/'


left-over only when there is at least a single

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/narkisr/cloujsearch.git/'


Optimize sorted-merge-by

Optimize sorted-merge-by


Remove unused parameters for easing function

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/dignati/om-charts.git/'


graph example

graph example

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

--- tutorial/graph.clj
+++ tutorial/graph.clj
@@ -0,0 +1,59 @@
+;   Copyright (c) Cognitect, Inc. All rights reserved.
+;   The use and distribution terms for this software are covered by the
+;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;   which can be found in the file epl-v10.html at the root of this distribution.
+;   By using this software in any fashion, you are agreeing to be bound by
+;   the terms of this license.
+;   You must not remove this notice, or any other, from this software.
+
+(require '[clojure.pprint :as pp]
+         '[datomic.client.api.alpha :as d]
+         '[datomic.samples.repl :as repl])
+
+;; inspired by http://docs.neo4j.org/chunked/stable/cypher-cookbook-hyperedges.html
+
+(def conn (repl/scratch-db-conn "config.edn"))
+
+(repl/transact-all conn (repl/resource "day-of-datomic-cloud/graph.edn"))
+
+(def db (d/db conn))
+
+;; find roles for user and particular groups
+(d/q '[:find (pull ?role [:role/name])
+       :in $ ?e ?group
+       :where
+       [?e :hasRoleInGroups ?roleInGroup]
+       [?roleInGroup :hasGroups ?group]
+       [?roleInGroup :hasRoles ?role]]
+     db [:user/name "User1"] [:group/name "Group2"])
+
+;; find all groups and roles for a user
+(pp/pprint
+ (d/q '[:find (pull ?group [:group/name]) (pull ?role [:role/name])
+        :in $ ?e
+        :where
+        [?e :hasRoleInGroups ?roleInGroup]
+        [?roleInGroup :hasGroups ?group]
+        [?roleInGroup :hasRoles ?role]]
+      db [:user/name "User2"]))
+
+(def rules '[[(user-roles-in-groups ?user ?role ?group)
+              [?user :hasRoleInGroups ?roleInGroup]
+              [?roleInGroup :hasGroups ?group]
+              [?roleInGroup :hasRoles ?role]]])
+
+;; find all groups and roles for a user, using a datalog rulea
+(pp/pprint
+ (d/q '[:find (pull ?group [:group/name]) (pull ?role [:role/name])
+        :in $ % ?user
+        :where (user-roles-in-groups ?user ?role ?group)]
+      db rules [:user/name "User1"]))
+
+;; find common groups based on shared roles, counting shared roles
+(d/q '[:find (pull ?group [:group/name]) (count ?role)
+       :in $ % ?user1 ?user2
+       :where (user-roles-in-groups ?user1 ?role ?group)
+              (user-roles-in-groups ?user2 ?role ?group)]
+     db rules [:user/name "User1"] [:user/name "User2"])
+
+(repl/delete-scratch-dbs "config.edn")


Iruzkina idazteak erreferentziak zuzenean gehitu API deirik egin gabe


Remove unnecessary whitespace

Remove unnecessary whitespace

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/croeder/clojure-koans-work.git/'


work on watch function

work on watch function

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/hialin/hialin.git/'


fix reading config file (coerce env string to keyword)

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/fhirbase/fhirterm.git/'


Add detritus.io

Add detritus.io

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

--- src/detritus/io.clj
+++ src/detritus/io.clj
@@ -0,0 +1,12 @@
+(ns detritus.io
+  "Stuff that should be in clojure.java.io"
+  (:import java.io.InputStream))
+
+(defn ^InputStream resource-stream
+  "Returns a stream for a named resource. Use the context class loader
+   if no loader is specified."
+  ([n]
+   (resource-stream n (.getContextClassLoader (Thread/currentThread))))
+
+  ([n ^ClassLoader loader]
+   (.getResourceAsStream loader n)))


mesos: reflect change in protocol location

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/'


Add sodium-init support

Add sodium-init support

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

--- src/caesium/core.clj
+++ src/caesium/core.clj
@@ -0,0 +1,15 @@
+(ns caesium.core
+  (:import (org.abstractj.kalium NaCl)))
+
+(defn sodium-init
+  "Initializes libsodium.
+
+  This should be called once, when your application starts. It is
+  idempotent: calling it doesn't do anything if it had already been
+  called. It is *not* thread-safe (until it has completed once): if
+  you call it in thread A, you can't concurrently call it in thread B,
+  until it finishes executing in thread A. Usually this is not a
+  problem: just run it synchronously in your application's init
+  routine."
+  []
+  (NaCl/init))


actually use `letfn` for `serve-index` to avoid introducing one-off fn

--- src/metabase/core.clj
+++ src/metabase/core.clj
@@ -24,14 +24,12 @@
   ;; call /api/test to see this
   (GET "/test" [] {:status 200 :body {:message "We can serialize JSON <3"}}))

-(defn serve-index "Serve index.html" [request]
-  (resp/file-response "frontend_client/index.html"))
-
-(defroutes routes
-  (GET "/" [] serve-index)                            ; ^/$    -> index.html
-  (context "/api" [] api-routes)                      ; ^/api/ -> API routes
-  (route/files "/app/" {:root "frontend_client/app"}) ; ^/app/ -> static files under frontend_client/app
-  (route/not-found serve-index))                      ; Anything else (e.g. /user/edit_current) should serve up index.html; Angular app will handle the rest
+(letfn [(serve-index [_] (resp/file-response "frontend_client/index.html"))]
+  (defroutes routes
+    (GET "/" [] serve-index)                            ; ^/$    -> index.html
+    (context "/api" [] api-routes)                      ; ^/api/ -> API routes
+    (route/files "/app/" {:root "frontend_client/app"}) ; ^/app/ -> static files under frontend_client/app
+    (route/not-found serve-index)))                     ; Anything else (e.g. /user/edit_current) should serve up index.html; Angular app will handle the rest

 (def app
   "The primary entry point to the HTTP server"


add outputs specs

add outputs specs

error: pathspec 'src/crucible/spec/outputs.clj' did not match any file(s) known to git

--- src/crucible/spec/outputs.clj
+++ src/crucible/spec/outputs.clj
@@ -0,0 +1,10 @@
+(ns crucible.spec.outputs
+  (:require [clojure.spec :as s]
+            [crucible.spec.values :as v]))
+
+(s/def ::description string?)
+
+(s/def ::value ::v/value)
+
+(s/def ::output (s/keys :req [::value]
+                        :opt [::description]))


Don’t join nil classes into classes string

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/tonsky/sablono.git/'


Fix main.clj system config

Fix main.clj system config

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/'


Add internal validation namespace.

Add internal validation namespace.

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

--- src/merkle_db/validate.clj
+++ src/merkle_db/validate.clj
@@ -0,0 +1,96 @@
+(ns merkle-db.validate
+  "Validation framework for testing database MerkleDAG structures."
+  (:require
+    [clojure.future :refer [qualified-keyword?]]
+    [clojure.set :as set]
+    [clojure.spec :as s]
+    [merkledag.core :as mdag]
+    [merkledag.link :as link]
+    [merkledag.node :as node]))
+
+
+;; Path from the validation root to the node being checked.
+(s/def ::path string?)
+
+;; Type of validation check performed.
+(s/def ::type qualified-keyword?)
+
+;; Validation state.
+(s/def ::state #{:pass :warn :fail :error})
+
+;; Validation message describing the check in a human-readable way.
+(s/def ::message string?)
+
+;; Map representing a specific check on a node in the tree.
+(s/def ::result
+  (s/keys :req [::node/id
+                ::type
+                ::path
+                ::state
+                ::message]))
+
+
+(def ^:dynamic *context*
+  "Dynamically-bound validation context."
+  nil)
+
+
+(defmacro collect-results
+  [& body]
+  `(binding [*context* {::results (atom []), ::path []}]
+     ~@body
+     @(::results *context*)))
+
+
+(defmacro checking-node
+  [node-id & body]
+  `(binding [*context* (assoc *context* ::node/id ~node-id)]
+     ~@body))
+
+
+(defmacro check-link
+  [store link check-fn]
+  `(let [link# ~link
+         check# ~check-fn
+         data# (mdag/get-data ~store link#)]
+     (binding [*context* (-> *context*
+                             (assoc ::node/id (::link/target link#))
+                             (update ::path conj (::link/name link#)))]
+       (check# data#))))
+
+
+(defn report!
+  "Record a validation result. The function accepts a multihash node id, a
+  keyword validation type, a result key (:pass, :warn, :fail, or :error) and a
+  message string."
+  [type-key state message]
+  (when-let [results (::results *context*)]
+    (swap! results
+           conj
+           {::node/id (::node/id *context*)
+            ::path (::path *context*)
+            ::type type-key
+            ::state state
+            ::message message})
+    nil))
+
+
+(defmacro check
+  ([type-key test-form]
+   `(check ~type-key ~test-form (pr-str (list 'not '~test-form))))
+  ([type-key test-form message]
+   `(check ~type-key ~test-form ~message :fail))
+  ([type-key test-form message bad-state]
+   `(let [type-key# ~type-key]
+      (try
+        (let [condition# ~test-form
+              state# (if condition# :pass ~bad-state)]
+          (report! type-key# state# ~message)
+          condition#)
+        (catch Throwable t#
+          (report! type-key# :error
+                   (str "Error checking assertion "
+                        (pr-str '~test-form) ": "
+                        (.getName (class t#)) " "
+                        (.getMessage t#)))
+          nil)))))


feat(query): inform query type when parsing queries

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/B2W-BIT/restQL-server.git/'


Exit if -h flag passed, or required flags no passed

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/altamiracorp/honeycomb.git/'


Add dissoc-blank-config-params-with-defaults rmq config helper fn

Hoping to move this to kehaar soon, but this is a good opportunity to
test it out first.

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/'


Documentation.

Documentation.

--- src/clj/freefrog/governance.clj
+++ src/clj/freefrog/governance.clj
@@ -1,7 +1,17 @@
 ;;; # Governance Encoding #
-;;; This namespace defines how governance can be manipulated, and is intended
+;;; Defines how governance can be manipulated, and is intended
 ;;; to comply to the
 ;;; [Holacracy Constitution v4.0](http://holacracy.org/sites/default/files/resources/holacracy_constitution_v4.0.pdf)
+;;;
+;;; Designed to provide all manipulation functions for Holacracy governance
+;;; structures. It is not recommended that the structures
+;;; generated/manipulated by this namespace be manually edited outside of
+;;; this namespace for any purpose.
+;;;
+;;; This would cause difficulties tracking down the source of a structure
+;;; should one need to do so. It also adds the benefit of having all logic in
+;;; one place so one can more easily reason about it.
+
 (ns freefrog.governance
   (:require [clojure.set :as s]))

@@ -130,6 +140,12 @@
     (if (empty? (get-things result role-name type))
       (update-in result [:roles role-name] dissoc type) result)))

+;; These functions are critical to maintaining namespace encapsulation. Simply
+;; allowing an external actor to call directly into the "add-to" and
+;; "remove-from" functions artificially constrains this namespace from
+;; easily being able to cause these functions to differentiate themselves from
+;; one another should they need to, adding a heavier burden on future
+;; maintainers.
 (defn add-domain
   "Add a domain to a role in the given circle."
   [circle role-name domain]


set default field type to :info

set default field type to :info

--- src/metabase/models/field.clj
+++ src/metabase/models/field.clj
@@ -80,7 +80,7 @@
                   :updated_at (util/new-sql-timestamp)
                   :active true
                   :preview_display true
-                  :field_type :dimension
+                  :field_type :info
                   :position 0}]
     (let [{:keys [field_type base_type special_type] :as field} (merge defaults field)]
       (assoc field


Add bookkeeper server component

Add bookkeeper server component

error: pathspec 'src/onyx/state/bookkeeper.clj' did not match any file(s) known to git

--- src/onyx/state/bookkeeper.clj
+++ src/onyx/state/bookkeeper.clj
@@ -0,0 +1,44 @@
+(ns onyx.state.bookkeeper
+  (:require [taoensso.timbre :refer [info error warn trace fatal] :as timbre]
+            [taoensso.nippy :as nippy]
+            [onyx.log.curator :as zk]
+            [onyx.log.zookeeper :as ozk]
+            [com.stuartsierra.component :as component])
+  (:import [org.apache.bookkeeper.client LedgerHandle BookKeeper BookKeeper$DigestType AsyncCallback$AddCallback]
+           [org.apache.bookkeeper.proto BookieServer]
+           [org.apache.bookkeeper.conf ServerConfiguration]
+           [org.apache.bookkeeper.conf ClientConfiguration]
+           [org.apache.bookkeeper.zookeeper ZooKeeperClient]
+           [onyx.log.zookeeper]
+           [org.apache.curator.framework CuratorFramework CuratorFrameworkFactory]))
+
+(def password (.getBytes "somepass"))
+
+(def bookie-server
+  {:zookeeper/address "127.0.0.1:2181"
+   :zookeeper/timeout 20000
+   :onyx/id (java.util.UUID/randomUUID)
+   :bookie/ledger-directories ["/tmp/bk-data996"]
+   :bookie/journal-directory "/tmp/bk-txn996"
+   :bookie/port 3196})
+
+(defrecord Bookie [conf]
+  component/Lifecycle
+  (component/start [component]
+    (let [ledgers-path (ozk/ledgers-path (:onyx/id conf))
+          ledgers-available-path (ozk/ledgers-available-path (:onyx/id conf))
+          conn (zk/connect (:zookeeper/address conf))
+          _ (zk/create-all conn ledgers-available-path :persistent? true)
+          server-conf (doto (ServerConfiguration.)
+                        (.setZkServers (:zookeeper/address conf))
+                        (.setZkLedgersRootPath ledgers-path)
+                        (.setBookiePort (:bookie/port conf))
+                        (.setJournalDirName (:bookie/journal-directory conf))
+                        (.setLedgerDirNames (into-array String (:bookie/ledger-directories conf)))
+                        (.setAllowLoopback true))
+          server (BookieServer. server-conf)]
+      (.start server)
+      (assoc component :server server)))
+  (component/stop [component]
+    (.stop (:server component))
+    (assoc component :server nil)))


added tutorial 7

added tutorial 7

error: pathspec 'src/maqueta/hello/animation.clj' did not match any file(s) known to git

--- src/maqueta/hello/animation.clj
+++ src/maqueta/hello/animation.clj
@@ -0,0 +1,51 @@
+(ns maqueta.hello.animation
+  (:use (maqueta application assets))
+  (:import com.jme3.math.ColorRGBA
+           com.jme3.math.Vector3f
+           com.jme3.scene.Node
+           (com.jme3.animation AnimControl LoopMode)
+           com.jme3.light.DirectionalLight))
+
+(def light (DirectionalLight.))
+
+(def player (load-model "Models/Oto/Oto.mesh.xml"))
+
+(def control (.getControl player AnimControl))
+
+(def channel (.createChannel control))
+
+(defn walk
+  [name is-pressed tpf]
+  (if (not is-pressed)
+    (doto channel
+      (.setAnim "Walk" 0.5)
+      (.setLoopMode LoopMode/Loop))))
+
+(def on-action {:key-space walk})
+
+(defn cycle-done
+  [app control channel]
+  (doto channel
+    (.setAnim "stand" 0.5)
+    (.setLoopMode LoopMode/DontLoop)
+    (.setSpeed 1)))
+
+(def on-anim-cycle-done {"Walk" cycle-done})
+
+(defn setup-fn
+  [app]
+  (let [root-node (.getRootNode app)
+        viewport (.getViewPort app)]
+    (.setBackgroundColor viewport ColorRGBA/LightGray)
+    (.setDirection light (.normalizeLocal (Vector3f. -0.1 -1 -1)))
+    (.addLight root-node light)
+    (.setLocalScale player (Vector3f. 0.5 0.5 0.5))
+    (.addListener control app)
+    (.setAnim channel "stand")))
+
+(defn -main
+  [& args]
+  (.start (make-app :root-node player
+                    :setup-fn setup-fn
+                    :on-anim-cycle-done on-anim-cycle-done
+                    :on-action on-action)))


ttest

ttest

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/clojure-ml/cml.git/'


first pass, does not handle non a-z chars yet.

error: pathspec 'clojure/atbash-cipher/atbash.clj' did not match any file(s) known to git

--- clojure/atbash-cipher/atbash.clj
+++ clojure/atbash-cipher/atbash.clj
@@ -0,0 +1,15 @@
+(ns atbash
+  (require [clojure.string :as str :only [lower-case]]))
+
+(let [letters (map char (range
+                         (int \a)
+                         (inc (int \z))))
+      total-letters (dec (count letters))
+      ]
+  (defn transpose
+    [c]
+    (nth letters (- total-letters
+                    (.indexOf letters c))))
+  (defn encode
+    [s]
+    (apply str (map transpose (str/lower-case s)))))


more deterministic tests

more deterministic tests

--- test/clj_http/test/conn_mgr.clj
+++ test/clj_http/test/conn_mgr.clj
@@ -56,11 +56,12 @@
              (shutdown []
                (reset! shutdown? true)))]
     (try
-      (core/request {:request-method :get :uri "/get"
+      (core/request {:request-method :get :uri "/timeout"
                      :server-port 18080 :scheme :http
                      :server-name "localhost"
-                     ;; socket timeout forces a timeout
+                     ;; timeouts forces an exception being thrown
                      :socket-timeout 1
+                     :conn-timeout 1
                      :connection-manager cm
                      :as :stream})
       (is false "request should have thrown an exception")


implementing example extension of core.logic

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

--- src/clj/eventsourcing/custom.clj
+++ src/clj/eventsourcing/custom.clj
@@ -0,0 +1,34 @@
+(ns eventsourcing.custom
+  (:require [clojure.core.logic :as l]))
+
+(defrecord Fact [e a v t])
+
+(def db [(->Fact :user :name "foo" 1)
+         (->Fact :user :age 23 2)
+         (->Fact :user :name "bar" 3)
+         (->Fact :user :age 25 4)])
+
+(extend-type Fact
+  clojure.core.logic.protocols/IUnifyTerms
+  (unify-terms [u v s]
+    (println "U:" u ", V:" v ", S:" s)
+    (when (and (instance? clojure.lang.PersistentVector v)
+               (> (count v) 1))
+      (loop [i 0 v v s s]
+        (println "I:" i ", V:" v ", S:" s)
+        (if (empty? v)
+          s
+          (when-let [s (l/unify s (first v) (get u (nth [:e :a :v :t] i)))]
+            (recur (inc i) (next v) s)))))))
+
+(defn fact-rel [q]
+  (fn [a]
+    (l/to-stream
+     (map #(l/unify a % q)
+          (sort-by :t > db)))))
+
+#_(l/run 1 [q]
+    (l/fresh [e a v t]
+      (l/== a :name)
+      (fact-rel [e a v t])
+      (l/== q [e a v t])))


Added namespace to handle working with gadm ids and iso codes

error: pathspec 'src/clj/forma/source/gadmiso.clj' did not match any file(s) known to git

--- src/clj/forma/source/gadmiso.clj
+++ src/clj/forma/source/gadmiso.clj
@@ -0,0 +1,28 @@
+(ns forma.source.gadmiso
+  (:use cascalog.api)
+  (:require [clojure.string :as string]))
+
+(def text-map
+  "Returns a sequence vectorized strings (e.g., [\"AFG,1\"]) from the
+  admin-map located in the resources folder."
+  (first (??- (hfs-textline "resources/admin-map.csv"))))
+
+(defn parse-line
+  "Accepts a vectorized string, as outputted by `text-map`, and
+  returns a single hash-map with the GADM ID (integer) as the key and
+  the ISO3 code (string) as the value."
+  [[x]]
+  (let [[iso gadm-str] (string/split x #",")]
+    {(read-string gadm-str) iso}))
+
+(def gadm-iso
+  "Returns a single hash-map that associates all GADMs and ISO codes."
+  (let [small-maps (map parse-line text-map)]
+    (apply merge small-maps)))
+
+(defn gadm->iso
+  "Accepts an integer GADM ID and returns the associated ISO3 code as
+  a string; wraps gadm-iso map for use in a cascalog query"
+  [gadm]
+  (gadm-iso gadm))
+


Added first definitions for the human player

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

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

--- Clojure/src/snake/player.clj
+++ Clojure/src/snake/player.clj
@@ -0,0 +1,21 @@
+(ns snake.player
+  (:use snake.agents-helpers))
+
+(defn create-human-player
+  "Starts an agent that represents a human player"
+  []
+  (start-agent-and-initialize
+         {:type  :player-human
+          :up    nil    ; TODO: provide the handlers for input
+          :left  nil
+          :down  nil
+          :right nil
+          :self  nil    ; self represents the agent reference to itself, is set by initialization
+          }))
+
+
+(defn create-ai-player
+  "Start an agent that represents a simple AI player"
+  []
+  (start-agent-and-initialize {:type :player-ai
+                               :self nil}))


Fleshed out basic integration test

Fleshed out basic integration test

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/lshift/event-framework.git/'


[#1949] Add lib.auth/ids test

[#1949] Add lib.auth/ids test

error: pathspec 'backend/test/akvo/lumen/lib/auth_test.clj' did not match any file(s) known to git

--- backend/test/akvo/lumen/lib/auth_test.clj
+++ backend/test/akvo/lumen/lib/auth_test.clj
@@ -0,0 +1,121 @@
+(ns akvo.lumen.lib.auth-test
+  (:require [akvo.lumen.lib.auth :as auth]
+            [akvo.lumen.specs.visualisation.maps]
+            [akvo.lumen.specs.visualisation]
+            [clojure.set :as set]
+            [clojure.test :refer :all]))
+
+(declare author)
+
+(deftest ids-test
+  (let [ds-id "5ca70f7a-3c66-45ac-a546-820dd55e3916"
+        v-id "5caaf957-e5eb-47be-a807-65697536fa7e"
+        spec-valid? true]
+    (is (= (auth/ids
+            :akvo.lumen.specs.visualisation/visualisation
+            {:name "jolin asdasd",
+             :visualisationType "pie",
+             :type "visualisation",
+             :created 1554708823102,
+             :modified 1554796491579,
+             :datasetId ds-id,
+             :author author,
+             :spec
+             {:sort nil,
+              :filters [],
+              :version 1,
+              :showLegend nil,
+              :legendTitle "Temperature",
+              :bucketColumn "c4"},
+             :status "OK",
+             :id v-id})
+           {:dataset-ids #{ds-id}, :visualisation-ids #{v-id}, :spec-valid? spec-valid?})))
+  (let [ds-id "1"
+        spec-valid? false]
+    (is (= (auth/ids
+            :akvo.lumen.specs.visualisation.maps/layers
+            [{:aggregationMethod "avg", :popup [], :filters [], :layerType "geo-location", :legend {:title "latitude", :visible true}, :rasterId nil, :pointSize 3, :pointColorMapping [], :longitude nil, :datasetId ds-id, :title "Untitled layer 1", :geom "d1", :pointColorColumn "c2", :latitude nil, :visible true}])
+           {:dataset-ids #{ds-id}, :visualisation-ids #{}, :spec-valid? spec-valid?})))
+  (let [ds-id "5cac541e-ba6c-4c78-969a-c55d624fc5ba"
+        spec-valid? true]
+    (is (= (auth/ids
+            :akvo.lumen.specs.visualisation.maps/layers
+            [{:aggregationMethod "avg",
+              :popup [],
+              :filters [],
+              :layerType "geo-location",
+              :legend {:title "latitude", :visible true},
+              :rasterId nil,
+              :pointSize 3,
+              :pointColorMapping [],
+              :longitude nil,
+              :datasetId ds-id,
+              :title "go1",
+              :geom "d1",
+              :pointColorColumn "c2",
+              :latitude nil,
+              :visible true}
+             {:aggregationMethod "avg",
+              :popup [],
+              :filters [],
+              :layerType "raster",
+              :legend {:title nil, :visible true},
+              :rasterId "5cac54fa-d93a-45d3-be6c-356f85559a9d",
+              :pointSize 3,
+              :pointColorMapping [],
+              :longitude nil,
+              :datasetId nil,
+              :title "Untitled layer 2",
+              :geom nil,
+              :pointColorColumn nil,
+              :latitude nil,
+              :visible true}
+             {:aggregationMethod "avg",
+              :popup [{:column "c2"}],
+              :filters [],
+              :layerType "geo-location",
+              :legend {:title "latitude", :visible true},
+              :rasterId nil,
+              :pointSize 3,
+              :pointColorMapping [],
+              :longitude nil,
+              :datasetId ds-id,
+              :title "Untitled layer 3",
+              :geom "d1",
+              :pointColorColumn "c2",
+              :latitude nil,
+              :visible true}])
+           {:dataset-ids #{ds-id},
+            :visualisation-ids #{},
+            :spec-valid? spec-valid?}))))
+
+
+(def author {:given_name "Jerome$auth$",
+             :email "jerome@t1.lumen.localhost",
+             :aud ["akvo-lumen"],
+             :allowed-origins
+             ["http://t1.lumen.local:8081"
+              "http://t1.lumen.local:3030"
+              "http://t2.lumen.local:3030"
+              "http://t2.lumen.local"
+              "http://t1.lumen.local"],
+             :session_state "1d91e2e6-3266-49a7-9d4e-d9dd90a1b8e4",
+             :sub "343ef061-25ca-4808-841b-7218f8a26b7f",
+             :iss "http://auth.lumen.local:8080/auth/realms/akvo",
+             :name "Jerome$auth$ Eginla",
+             :exp "2019-04-08T07:38:37Z",
+             :azp "akvo-lumen",
+             :realm_access
+             {:roles
+              ["akvo:lumen:t1" "akvo:lumen:t1:admin" "uma_authorization"]},
+             :family_name "Eginla",
+             :auth_time 1554707946,
+             :jti "cee78fd0-177b-4ad3-96e6-2530a8682d0c",
+             :nbf "1970-01-01T00:00:00Z",
+             :resource_access
+             {:account {:roles ["manage-account" "view-profile"]}},
+             :acr "0",
+             :nonce "82752bdc-8e7d-453a-8822-99ce72c23893",
+             :typ "Bearer",
+             :preferred_username "jerome",
+             :iat "2019-04-08T07:33:37Z"})


Parses and stringifies empty lists

Parses and stringifies empty lists

--- parser/parser.clj
+++ parser/parser.clj
@@ -70,20 +70,31 @@
 (data expression (Symbol (list int32))
                  (List (list expression)))

-(def read-symbol (input)
+(def push-expression (parent expression)
+     (match parent
+            (List list) (List (Cons expression list))
+            (Symbol _)  parent))
+
+(def parse-symbol (input list parse')
      (match (read-while not-whitespace? input)
-            (Pair input name) (Pair input (Symbol name))))
+            (Pair input name) (Pair input (push-expression list (Symbol name)))))

-(def parse' (input)
+(def parse-list (input list parse')
+     (match (parse' input (List Empty))
+            (Pair input new-list) (Pair input (push-expression list new-list))))
+
+(def parse' (input list)
      (match input
-            Empty       (Pair input (List Empty))
+            Empty       (Pair input list)
             (Cons x xs) (match (= x 40)
-                               True (Pair input (List Empty))
-                               False (read-symbol input))))
+                               True (parse-list xs list parse')
+                  False (match (= x 41)
+                               True (Pair xs list)
+                  False (parse-symbol input list parse')))))

 (def parse (input)
-     (match (parse' (skip-while whitespace? input))
-            (Pair _ expression) expression))
+     (match (parse' (skip-while whitespace? input) (List Empty))
+            (Pair _ (List (Cons expression __))) expression))

 (def str (character)
      (Cons character Empty))
@@ -95,7 +106,9 @@

 (def join (separator list)
      (foldr (fn (x xs)
-                (concat-strings x (concat-strings separator xs)))
+                (match xs
+                       Empty       (concat-strings x xs)
+                       (Cons _ __) (concat-strings x (concat-strings separator xs))))
             Empty
             list))


use a large button

use a large button

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/'


Minimized test data size a bit to avoid long test times.

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/screen6/cardinality.git/'


update access-control-allow-headers

update access-control-allow-headers


build Sierpinski fractal using Pascal's triangle (initial commit)

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

--- src/sandbox/fractal.clj
+++ src/sandbox/fractal.clj
@@ -0,0 +1,27 @@
+(ns sandbox.fractal
+  (:import (java.awt image.BufferedImage Color)
+           (javax.imageio ImageIO)
+           (java.io File)))
+
+(defn pascal-row-step [yield pascal-row]
+;;=> pascal-row is the one above the row we're computing
+  {:pre [(> (get  pascal-row 0) 0)]}  ;=> We can only start from [1]!
+  (let [cnt-elts (count pascal-row)
+        half-row (subvec pascal-row 0 (inc (double (/ cnt-elts 2))))
+;;=> We compute half the above row
+        padded-half-row (into [0] half-row)
+;;=> and add a 0 to the beginning, as we'll use it in computation
+        half-step (vec (map (comp (partial apply yield) vec)
+                            (partition 2 1 padded-half-row)))
+;;=> we compute the first half, summing the above element
+;;      and the element at the left of the above one.
+        other-half-step (vec (if (even? cnt-elts)
+                               (-> half-step
+                                   butlast
+                                   reverse)
+                               (-> half-step
+                                   reverse)))]
+;;=> the mirror of the half we computed. If count elements is
+;; even, we omit the last element from half-step.
+    (into half-step other-half-step)))
+;;=> we return half to which we append the mirror copy.


Refactoring

Refactoring

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/shen.clj.git/'


Remove the old `find-by-identifiers`

Remove the old `find-by-identifiers`

Stop calling the old `find-by-identifiers` which could take a long time.

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/'


add core ns

add core ns

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

--- src/mesh/core.cljc
+++ src/mesh/core.cljc
@@ -0,0 +1,6 @@
+(ns mesh.core
+  (:require
+   [mesh.core.box :as box]
+   [mesh.core.respond :as respond]
+   [mesh.core.utils :as utils]))
+


Unit tests for ``` POST /api/card GET /api/card/:id DELETE /api/card/:id GET /api/card/:id/favorite POST /api/card/:id/favorite DELETE /api/card/:id/favorite ```

error: pathspec 'test/metabase/api/card_test.clj' did not match any file(s) known to git

--- test/metabase/api/card_test.clj
+++ test/metabase/api/card_test.clj
@@ -0,0 +1,138 @@
+(ns metabase.api.card-test
+  "Tests for /api/card endpoints."
+  (:require [expectations :refer :all]
+            [korma.core :refer :all]
+            [metabase.db :refer :all]
+            [metabase.models.card :refer [Card]]
+            [metabase.test.util :refer [match-$ expect-eval-actual-first deserialize-dates]]
+            [metabase.test-data :refer :all]))
+
+;; # CARD LIFECYCLE
+
+;; Helper fns
+(defn post-card [card-name]
+  (-> ((user->client :rasta) :post 200 "card" {:organization (:id @test-org)
+                                               :name card-name
+                                               :public_perms 0
+                                               :can_read true
+                                               :can_write true
+                                               :display "scalar"
+                                               :dataset_query {:type "query"
+                                                               :query {:source_table (table->id :categories)
+                                                                       :filter [nil nil]
+                                                                       :aggregation ["count"]
+                                                                       :breakout [nil]
+                                                                       :limit nil}
+                                                               :database (:id @test-db)}
+                                               :visualization_settings {:global {:title nil}}})
+      (deserialize-dates :updated_at :created_at)))
+
+(defn random-card-name []
+  (name (gensym)))
+
+;; ## POST /api/card
+;; Test that we can make a card
+(let [card-name (random-card-name)]
+  (expect-eval-actual-first (match-$ (sel :one Card :name card-name)
+                              {:description nil
+                               :organization_id (:id @test-org)
+                               :name card-name
+                               :creator_id (user->id :rasta)
+                               :updated_at $
+                               :dataset_query {:type "query"
+                                               :query {:source_table (table->id :categories)
+                                                       :filter [nil nil]
+                                                       :aggregation ["count"]
+                                                       :breakout [nil]
+                                                       :limit nil}
+                                               :database (:id @test-org)}
+                               :id $
+                               :display "scalar"
+                               :visualization_settings {:global {:title nil}}
+                               :public_perms 0
+                               :created_at $})
+    (post-card card-name)))
+
+
+
+;; ## GET /api/card/:id
+;; Test that we can fetch a card
+(let [card-name (random-card-name)
+      {:keys [id]} (post-card card-name)]
+  (expect-eval-actual-first
+      (match-$ (sel :one Card :id id)
+        {:description nil
+         :can_read true
+         :can_write true
+         :organization_id (:id @test-org)
+         :name card-name
+         :organization {:inherits true
+                        :logo_url nil
+                        :description nil
+                        :name "Test Organization"
+                        :slug "test"
+                        :id (:id @test-org)}
+         :creator_id (user->id :rasta)
+         :updated_at $
+         :dataset_query {:type "query"
+                         :query {:source_table (table->id :categories)
+                                 :filter [nil nil]
+                                 :aggregation ["count"]
+                                 :breakout [nil]
+                                 :limit nil}
+                         :database (:id @test-db)}
+         :id id
+         :display "scalar"
+         :visualization_settings {:global {:title nil}}
+         :public_perms 0
+         :created_at $})
+    (-> ((user->client :rasta) :get 200 (format "card/%d" id))
+        (deserialize-dates :updated_at :created_at))))
+
+;; ## DELETE /api/card/:id
+;; Check that we can delete a card
+(let [{:keys [id]} (post-card (random-card-name))]
+  (expect-eval-actual-first nil
+    (do ((user->client :rasta) :delete 204 (format "card/%d" id))
+        (sel :one Card :id id))))
+
+
+;; # CARD FAVORITE STUFF
+
+;; Helper Functions
+(defn fave? [card]
+  ((user->client :rasta) :get 200 (format "card/%d/favorite" (:id card))))
+
+(defn fave [card]
+  ((user->client :rasta) :post 200 (format "card/%d/favorite" (:id card))))
+
+(defn unfave [card]
+  ((user->client :rasta) :delete 204 (format "card/%d/favorite" (:id card))))
+
+;; ## GET /api/card/:id/favorite
+;; Can we see if a Card is a favorite ?
+(expect-let [card (post-card (random-card-name))]
+  {:favorite false}
+  (fave? card))
+
+;; ## POST /api/card/:id/favorite
+;; Can we favorite a card?
+(expect-let [card (post-card (random-card-name))]
+  [{:favorite false}
+   {:favorite true}]
+  [(fave? card)
+   (do (fave card)
+       (fave? card))])
+
+;; DELETE /api/card/:id/favorite
+;; Can we unfavorite a card?
+(expect-let [card (post-card (random-card-name))
+             get-fave? ((user->client :rasta) :get (format "card/%d/favorite" (:id card)))]
+  [{:favorite false}
+   {:favorite true}
+   {:favorite false}]
+  [(fave? card)
+   (do (fave card)
+       (fave? card))
+   (do (unfave card)
+       (fave? card))])


do not assume anything wrt order of arrival

--- test/riemann/test/transport.clj
+++ test/riemann/test/transport.clj
@@ -77,9 +77,9 @@
        (client/send-event client {:service "service1"})
        (client/send-event client {:service "service2"})
        (let [[r2 r1] (channel->seq (map* convert (take* 2 (:body @response))))]
-         ;; Making assumptions on order of arrival might not be very smart
-         (is (= (get r1 "service") "service1"))
-         (is (= (get r2 "service") "service2")))
+
+         (is (#{"service1" "service2"} (get r1 "service")))
+         (is (#{"service1" "service2"} (get r1 "service"))))
        (finally
          (stop! core))))))


Plugged in in-memory storage

Plugged in in-memory storage

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/ben-biddington/solace.git/'


move stuff to cljs

move stuff to cljs

error: pathspec 'src/cljs/om_lette/templater.cljs' did not match any file(s) known to git

--- src/cljs/om_lette/templater.cljs
+++ src/cljs/om_lette/templater.cljs
@@ -0,0 +1,118 @@
+(ns om-lette.templater
+  (:require [clojure.walk :as walk]
+            [hickory.core :as hick]
+            [clojure.string :as s]))
+
+(defonce template-cache (atom {}))
+
+(defn has-all-keys? [m keys]
+  (apply = (map count [keys (select-keys m keys)])))
+
+(defn make-done-loading?-fn [names callback]
+  (fn []
+    (if (has-all-keys? @template-cache names)
+      (callback))))
+
+(defn make-template-handler [template-name callback]
+  (fn handler [response]
+    (swap! template-cache assoc template-name response)
+    (callback)))
+
+;; regex
+(def nonnum "[a-zA-Z\\*\\+!\\-\\_\\?]")
+(def valid-sym-chars "[\\w\\d\\*\\+!\\-\\_\\?]")
+(def valid-sym (str nonnum "+" valid-sym-chars "*"))
+(def om-repeat-expr (str "^=>\\s+(" valid-sym ")\\s+(" valid-sym ")\\s*$"))
+
+;; *******
+
+(defn like-html-vec?
+  [h]
+  (if (and (vector? h) (-> h first keyword?)(-> h second map?))
+    h
+    nil))
+
+(defn has-om-if?
+  [h]
+  (-> h like-html-vec? second :om-if))
+
+(defn has-om-repeat?
+  [h]
+  (->> h
+       like-html-vec?
+       second
+       :om-repeat
+       (#(or % ""))
+       (re-find (re-pattern om-repeat-expr))
+       rest
+       not-empty
+       ))
+
+(defn strip-attrs [tag & xattrs]
+  (let [[name attrs & rest] tag] (vec (concat [name (apply dissoc attrs xattrs)] rest))))
+
+(defn drop-delim
+  [x]
+  (filterv #(-> %
+               #{"" (str (char 30))}
+               not)
+          x))
+
+(defn split-dbl-brackets
+  [t]
+  (-> t
+      (s/replace "{{" (str (char 28) (char 29)))
+      (s/replace "}}" (str (char 29) (char 30) (char 28)))
+      (s/split (re-pattern (str (char 28))))
+      (#(map (fn [x] (s/split x (re-pattern (str (char 29))))) %))))
+
+(defn tokenize-string
+  [p]
+  (->> p
+       split-dbl-brackets
+       (map (fn [x] (condp #(= % (count %2)) x
+                      0 nil
+                      1 [:om-text (first x)]
+                      2 [:om-text (-> x drop-delim first)]
+                      3 [:om-code (second x)])))
+       (filter #(-> % second not-empty))))
+
+(defn grab-om-attrs
+  [a ks]
+  (println "=== grab-om-attrs =======")
+  (println [a ks])
+  (let [r (let [sel-ks (select-keys a ks)]
+            (if (not-empty sel-ks)
+              (-> a
+                  (#(apply dissoc % ks))
+                  (assoc :om-lette (select-keys a ks)))
+              a))]
+    (println r)
+    (println "=========")
+    r))
+
+(defn html->template
+  [h]
+  (->> h
+       hick/parse-fragment
+       first
+       hick/as-hiccup
+       (walk/postwalk (fn [t] (cond (string? t) (tokenize-string t)
+                                    (like-html-vec? t) (update-in t [1] grab-om-attrs [:om-if :om-repeat])
+                                    :else t)))))
+
+
+(defn load-templates [names get-html-template callback]
+  (mapv #(->> (make-done-loading?-fn names)
+              (fn [callback]
+                (swap! template-cache assoc name
+                       (html->template html))
+                (if (has-all-keys? @template-cache names)
+                  callback))
+              (get-html-template %) names)))
+
+(defn render-template
+  [state tname]
+  )
+
+#_(html->template "

")


added streamable work

added streamable work

error: pathspec 'src/cljs/redditv/streamable.cljs' did not match any file(s) known to git

--- src/cljs/redditv/streamable.cljs
+++ src/cljs/redditv/streamable.cljs
@@ -0,0 +1,24 @@
+(ns redditv.streamable
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  (:require [cljs.core.async :refer [put! chan <! >! timeout close!]]
+            [redditv.player :as player]
+            [redditv.events :as events]))
+
+(def example "https://streamable.com/wgdg")
+
+(def regex-streamable-url #"https?://streamable.com/([a-zA-Z0-9])$")
+
+(defn video-url->video-id [url]
+  (when (re-matches regex-streamable-url url)
+    (->> url (re-matches regex-streamable-url) second)))
+
+(defn is-streamable-url? [url]
+  (-> (re-matches regex-streamable-url url) boolean))
+
+(defrecord StreamablePlayer [context video-url event-channel]
+  player/IPlayer
+  (play [this])
+  (pause [this])
+  (dispose [this]))
+
+(defn create-streamableplayer [dom-id video-url event-channel])


Finish find field

Finish find field

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/bsmr-clojure/Nightcode.git/'


Send custom questions immediately!

Send custom questions immediately!

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/'


Add sc-one.clj from overtone/docs/sc-book

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


Add namespace for performing API calls

Add namespace for performing API calls

error: pathspec 'src/sidequarter_frontend/api.cljs' did not match any file(s) known to git

--- src/sidequarter_frontend/api.cljs
+++ src/sidequarter_frontend/api.cljs
@@ -0,0 +1,10 @@
+(ns ^:figwheel-always sidequarter-frontend.api
+    (:require-macros [sidequarter-frontend.env :refer [cljs-env]]
+                     [cljs.core.async.macros :refer [go]])
+    (:require [cljs-http.client :as http]
+              [cljs.core.async :refer [<! >! put! chan]]))
+
+(def api-url (cljs-env :api-url))
+
+(defn get-sidekiqs []
+  (http/jsonp api-url {:callback-name "callback"}))


Fix for api-changes in clojurescript:80ea15e.

cljs.compiler/with-core-cljs changed its method signature.

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/modnakasta/weasel.git/'


Unwire channel closing on shutdown for now

Not sure yet what the best architecture for this will be.

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/'


Use correct signature for redirect; Fixes #103

--- src/clojars/web.clj
+++ src/clojars/web.clj
@@ -154,7 +154,7 @@
             (if-let [jar (find-jar jarname groupname version)]
               (do (promote/promote (set/rename-keys jar {:jar_name :name
                                                          :group_name :group}))
-                  (redirect (jar-url groupname jarname)))
+                  (redirect (jar-url {:group_name groupname :jar_name jarname})))
               :next))))
   (GET "/:username" {session :session {username :username} :params}
        (if-let [user (find-user username)]


Update flow_common.clj

Update flow_common.clj

--- backend/src/akvo/lumen/lib/import/flow_common.clj
+++ backend/src/akvo/lumen/lib/import/flow_common.clj
@@ -6,7 +6,8 @@
             [clojure.string :as str])
   (:import [java.time Instant]))

-(def ^:private http-client-req-defaults (http.client/req-opts 30000))
+;; only use this value from a different thread/future
+(def ^:private http-client-req-defaults (http.client/req-opts 60000))

 (defn survey-definition
   [api-root headers-fn instance survey-id]