simple code + example usage for demonstration!

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

--- server.clj
+++ server.clj
@@ -0,0 +1,134 @@
+(ns server
+  (:use clojure.contrib.except clojure.contrib.def)
+  (:import
+   (java.net Socket)
+   (java.io PrintWriter InputStreamReader BufferedReader)))
+(require '[clojure.contrib.str-utils2 :as s])
+
+(defn group
+  ([coll] (group coll 2))
+  ([the-coll by]
+     (loop [coll the-coll
+	    result nil]
+       (if (empty? coll)
+	 result
+	 (recur (drop by coll) (concat result (list (take by coll))))))))
+
+(defmacro constants [& args]
+  `(do ~@(map #(list 'def (first %) (second %)) (group args))))
+
+(constants
+  +M1+ 1
+  +M5+ 5
+  +M15+ 15
+  +M30+ 30
+  +H1+ 60
+  +H4+ 240
+  +D1+ 1440
+  +W1+ 10080
+  +MN1+ 43200
+
+  +MODE_SMA+ 0
+  +MODE_EMA+ 1
+  +MODE_SMMA+ 2
+  +MODE_LWMA+ 3
+
+  +CLOSE+ 0
+  +OPEN+ 1
+  +HIGH+ 2
+  +LOW+ 3
+  +MEDIAN+ 4
+  +TYPICAL+ 5
+  +WEIGHTED+ 6
+
+  +MODE_DIGITS+ 12
+  +MODE_SPREAD+ 13
+  +MODE_STOPLEVEL+ 14
+  +MODE_LOTSIZE+ 15
+  +MODE_POINT+ 11
+  +MODE_BID+ 9
+  +MODE_ASK+ 10
+
+  +BUY+ 0
+  +SELL+ 1
+  +BUYLIMIT+ 2
+  +SELLLIMIT+ 3
+  +BUYSTOP+ 4
+  +SELLSTOP+ 5)
+
+(defvar *env* (atom {:timeframe +D1+}))
+(defn env [key] (key @*env*))
+(defn env! [map] (swap! *env* #(merge-with (fn [a b] (or b a)) % %2) map))
+
+(defn connect-socket [server]
+  (let [socket (Socket. (:name server) (:port server))
+	in (BufferedReader. (InputStreamReader. (.getInputStream socket)))
+	out (PrintWriter. (.getOutputStream socket))
+	conn (ref {:in in :out out})]
+    conn))
+(defn write-stream [conn msg]
+  (throw-if-not conn "no connection provided")
+  (doto (:out @conn)
+    (.println (str 2 " " msg "\r"))
+    (.flush))
+  conn)
+(defn receive-stream [conn]
+  (assert conn)
+  (rest (s/split (.readLine (:in @conn)) #" +")))
+
+(defn receive [msg]
+  (write-stream (:socket @*env*) msg)
+  (receive-stream (:socket @*env*)))
+
+;;we now can use the sockets - now we need
+;;mql error handling and parsing numbers if no error!
+(def metatrader {:name "localhost" :port 2007})
+(defn connect []
+  (env! {:socket (connect-socket metatrader)}))
+(defmacro wenv [[ & {symbol :symbol socket :socket timeframe :timeframe}] & body]
+  `(binding [*env*  (atom (merge-with #(or %2 %1) @*env* {:symbol ~symbol :socket ~socket :timeframe ~timeframe}))] ~@body))
+
+(defn iMA [symbol timeframe period mode price index]
+  (receive (format "iMA %s %s %s %s %s %s" symbol timeframe period mode price index)))
+
+(defmacro wait-for-update [& body]
+  `(let [call# (fn [] ~@body)]
+     (loop [result# (call#)
+	    try# 0]
+       (if (and (= (first result#) "error") (= (second result#) "4066"))
+	 (do (Thread/sleep 250) (if (< try# 4) (recur (call#) (inc try#)) (throwf "mql4 error %s" (rest result#))))
+	 (if (= (first result#) "error") (throwf "mql4 error %s" (rest result#)) result#)))))
+(defn jpy? [] (re-find #"JPY" (env :symbol)))
+(defn pt [] (if (jpy?) 0.01 0.0001))
+(defn pips [p] (/ p (pt)))
+(defn points [p] (* p (pt)))
+
+(defn mva [period index & {mode :mode price :price}]
+  (Float/parseFloat
+   (first (wait-for-update (iMA (env :symbol) (env :timeframe) period (or mode +MODE_SMA+) (or price +CLOSE+) index)))))
+
+(defn close
+  ([] (close 0))
+  ([index] (mva 1 index :price +CLOSE+)))
+(defn open
+  ([] (open 0))
+  ([index] (mva 1 index :price +OPEN+)))
+(defn high
+  ([] (high 0))
+  ([index] (mva 1 index :price +HIGH+)))
+(defn low
+  ([] (low 0))
+  ([index] (mva 1 index :price +LOW+)))
+
+;;example
+(defn c?
+  ([direction tp] (c? direction tp 0))
+  ([direction tp index]
+     (let [h (+ (high index) (points 5))
+	   l (- (low index) (points 5))
+	   [price sl] (cond (= direction :up) (list h l)
+			    (= direction :down) (list l h)
+			    true (throwf "give me up or down!"))
+	   risk (Math/abs (- price sl))
+	   reward (Math/abs (- price tp))]
+       (print (format "PRICE %s%nTP %s%nSL %s%nRISK %s%nREWARD %s%nR/R %s" price tp sl (pips risk) (pips reward) (/ reward risk))))))


implemented few methods like  dependent-columns and other

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


main: clarify workflow

main: clarify workflow

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


added example in Clojure programming language

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

--- hello-clojure/hello-world.clj
+++ hello-clojure/hello-world.clj
@@ -0,0 +1 @@
+(println "Hello, World.")


day 11

day 11

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

--- src/adventofcode/day11.clj
+++ src/adventofcode/day11.clj
@@ -0,0 +1,36 @@
+(ns adventofcode.day11)
+
+(defn next-char [c]
+  (if (= c \z)
+    \a
+    (-> c byte inc char)))
+
+(defn next-pass [p]
+  (apply
+   str
+   (cond
+     (empty? p) ""
+     (= (last p) \z) (concat (next-pass (drop-last p)) (list \a))
+     :else (concat (drop-last p) (list (next-char (last p)))))))
+
+(def all-passwords (iterate next-pass "hxbxwxba"))
+
+(defn include-increasing-letters? [s]
+  (->> s
+       (map byte)
+       (partition 3 1)
+       (some (fn [[a b c]] (and (= (- b a) 1)
+                                (= (- c b) 1))))))
+
+(def without-bad-symbols? (partial re-find #"^[^oil]+$"))
+(def with-two-pairs?  (partial re-find #"(.)\1.*((?!\1).)\2"))
+
+(def filtered-passwords
+  (->> all-passwords
+       (filter #(and
+                 (include-increasing-letters? %)
+                 (without-bad-symbols? %)
+                 (with-two-pairs? %)))))
+
+(def part-one (first filtered-passwords))
+(def part-two (take 3 filtered-passwords))


fix(performance): execute all requests before extracting results (#72)

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-Digital/pdg-core.git/'


Balio bikotea

Balio bikotea

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


Add initial abstraction draft for media storage layer.

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

--- src/uxbox/media.clj
+++ src/uxbox/media.clj
@@ -0,0 +1,22 @@
+(ns uxbox.media
+  "A media storage persistence layer.")
+
+(defprotocol IStorage
+  "A basic abstraction for storage access."
+  (-save [_ path content] "Persist the content under specified path.")
+  (-delete [_ path] "Delete the file by its path.")
+  (-exists? [_ path] "Check if file exists by path."))
+
+(defprotocol IPublicStorage
+  (-uri [_ path] "Get a public accessible uri for path."))
+
+(defprotocol IStorageIntrospection
+  (-accessed-time [_ path] "Return the last accessed time of the file.")
+  (-created-time [_ path] "Return the creation time of the file.")
+  (-modified-time [_ path] "Return the last modified time of the file."))
+
+(defprotocol IFSStorage
+  "A local filelsystem storage abstraction."
+  (-path [_ path] "Return the absolute path to the file."))
+
+;; TODO impl


Copy tests from election-mail-http-api & update

...them to work more like the user tests do (and simpler and cleaner IMO).

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


add dox

add dox

--- src/metabase/db.clj
+++ src/metabase/db.clj
@@ -112,7 +112,10 @@

    ENTITY may optionally be a fully-qualified string name of an entity; in this case, the symbol's namespace
    will be required and the symbol itself resolved at runtime. This is sometimes neccesary to avoid circular
-   dependencies in the model files. This is slower, however, due to added runtime overhead."
+   dependencies in the model files. This is slower, however, due to added runtime overhead.
+
+   `(sel :one Table :id 1)                           ; returns fn that will sel Table 1 when called`
+   `(sel :one \"metabase.models.table/Table\" :id 1) ; returns fn that will require/resolve metabase.models.table/Table. then sel Table 1`"
   [one-or-many entity & kwargs]
   `(memoize
     (fn []


updated with git src pull

updated with git src pull

--- src/leiningen/new/cryogen/src/cryogen/github.clj
+++ src/leiningen/new/cryogen/src/cryogen/github.clj
@@ -1,5 +1,6 @@
 (ns cryogen.github
-  (:require [cheshire.core :as json]))
+  (:require [cheshire.core :as json])
+  (:import (org.apache.commons.codec.binary Base64 StringUtils)))

 (defn get-gist [gist-uri]
   (let [gist-id (last (clojure.string/split gist-uri #"/+"))
@@ -17,5 +18,18 @@
          :name (get gist "filename")
          :id gist-id}))))

-(get-gist "https://gist.github.com/viperscape/cec68f0791687f5959f1")
+(defn get-src [git-file]
+  (let [gist-resp (try (slurp git-file)
+                       (catch Exception e {:error (.getMessage e)}))]
+    (when-not (:error gist-resp)
+      (if-let [git-src (json/parse-string gist-resp)]
+        {:content (String. (Base64/decodeBase64 (get git-src "content")) "UTF-8")
+         :name (get git-src "name")
+         :uri (get (get git-src "_links") "html")}))))

+
+(defn get-gits-ex []
+  [(get-gist "https://gist.github.com/viperscape/cec68f0791687f5959f1")
+   (get-src "https://api.github.com/repos/viperscape/rust-irc/contents/src/main.rs")])
+
+;(prn (get-gits-ex))


correct handler name in server.clj

correct handler name in server.clj

Was mismatched with project.clj, now matched.

--- src/leiningen/new/cryogen/src/cryogen/server.clj
+++ src/leiningen/new/cryogen/src/cryogen/server.clj
@@ -22,11 +22,11 @@
       (or (resource-response res-path {:root "public"})
           (handler request)))))

-(defroutes handler
+(defroutes routes
   (GET "/" [] (redirect (let [config (read-config)]
-                          (path (:blog-prefix (read-config)) "/"
+                          (path (:blog-prefix config) "/"
                                 (when-not (:clean-urls? config) "index.html")))))
   (route/resources "/")
   (route/not-found "Page not found"))

-(def app (wrap-subdirectories handler))
+(def handler (wrap-subdirectories routes))


Deprecate :pending_memberships and :membership_role_ids

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


flip flop these to put the more unique value earlier

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


Animate pop-in of item-details sidebar

Animate pop-in of item-details sidebar

It's beautiful!

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


test utility using Liquibase for creating DB table

error: pathspec 'src/test/clj/org/bituf/fountain/test_util.clj' did not match any file(s) known to git

--- src/test/clj/org/bituf/fountain/test_util.clj
+++ src/test/clj/org/bituf/fountain/test_util.clj
@@ -0,0 +1,95 @@
+(ns org.bituf.fountain.test-util
+  (:import
+    (java.sql Connection Statement ResultSet))
+  (:require
+    [org.bituf.clj-miscutil  :as mu]
+    [org.bituf.clj-dbspec    :as sp]
+    [org.bituf.clj-liquibase :as lb]
+    [org.bituf.clj-liquibase.change :as ch])
+  (:use clojure.test))
+
+
+(defmacro is-thrown?
+  "Check if given exception is thrown in a test. `ex` can be an exception class
+  or an exception object."
+  [ex & body]
+  `(is (instance? (if (class? ~ex) ~ex
+                    (class ~ex))
+         (last (mu/maybe ~@body)))))
+
+
+(defmacro with-liquibase
+  [& body]
+  `(let [g# (lb/wrap-lb-init (fn [] ~@body))]
+     (g#)))
+
+
+(defmacro with-stmt
+  [st & body]
+  `((sp/wrap-connection
+      (fn []
+        (with-open [~st (.createStatement ^Connection (:connection sp/*dbspec*))]
+          (do ~@body))))))
+
+
+(defn row-count
+  [table-name]
+  (with-stmt ^Statement st
+    (let [^ResultSet rs (.executeQuery st (str "SELECT COUNT(*) FROM "
+                                            (sp/db-iden table-name)))]
+      (.next rs)
+      (.getInt rs 1))))
+
+
+(defn sample-setup
+  []
+  (let [sql-coll (with-liquibase
+                   (lb/change-sql (ch/create-table-withid :sample
+                                    [[:name [:varchar 30] :null false]
+                                     [:age  :int]])))]
+    (with-stmt ^Statement st
+      (mu/maybe (.execute st "DROP TABLE sample"))
+      (doseq [each sql-coll]
+        (println "\n" each "\n")
+        (.execute st ^String each))
+      (.execute st "INSERT INTO sample (name, age)
+                    VALUES ('Harry', 30)"))))
+
+
+(defn sample-count
+  []
+  (row-count :sample))
+
+
+(defn sample2-setup
+  []
+  (let [sql-coll (with-liquibase
+                   (lb/change-sql (ch/create-table-withid :sample2
+                                    [[:extra-id :int          :null false :autoinc true]
+                                     [:name     [:varchar 30] :null false]
+                                     [:age      :int]])))]
+    (with-stmt ^Statement st
+      (mu/maybe (.execute st "DROP TABLE sample2"))
+      ;; Liquibase creates wrong CREATE TABLE SQL for 1+ auto-inc columns
+      ;(doseq [each sql-coll]
+      ;  (println "\n\n**** Executing Liquibase SQL: " each "\n")
+      ;  (.execute st ^String each))
+      (.execute st "CREATE TABLE sample2
+                     (sample_id INT         NOT NULL PRIMARY KEY AUTO_INCREMENT,
+                      extra_id  INT         NOT NULL AUTO_INCREMENT,
+                      name      VARCHAR(30) NOT NULL,
+                      age       INT)")
+      (.execute st "INSERT INTO sample2 (name, age)
+                    VALUES ('Harry', 30)"))))
+
+
+(defn sample2-count
+  []
+  (row-count :sample2))
+
+
+(defn fail
+  ([msg] (is false msg))
+  ([] (is false)))
+
+


fix typo in wiring

fix typo in wiring

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


Formatting.

Formatting.

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


test_parser.clj

test_parser.clj

quick and dirty parser

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

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -0,0 +1,107 @@
+(ns selmer.test-parser)
+
+(declare parse)
+(declare expr-tag)
+
+(defn render [template params]
+  (->> (for [element template]
+         (if (string? element) element (element params)))
+       (apply str)))
+
+(defn read-char [rdr]
+  (let [ch (.read rdr)]
+    (if-not (neg? ch) (char ch))))
+
+(defn peek-stream [rdr size]
+  (.mark rdr size)
+  (let [result (loop [items []]
+                 (let [ch (read-char rdr)]
+                   (if (and ch (< (count items) size))
+                     (recur (conj items ch))
+                     items)))]
+    (.reset rdr)
+    result))
+
+(defn value-tag [{:keys [tag-value]}]
+  (let [value (map keyword (.split tag-value "\\."))]
+    (fn [params] (get-in params value))))
+
+#_((value-tag {:tag-value "foo.bar.baz"}) {:foo {:bar {:baz "ok"}}})
+#_((value-tag {:tag-value "foo"}) {:foo "ok"})
+
+(defn read-tag-info [rdr]
+  (let [buf (StringBuilder.)
+        tag-type (if (= \{(read-char rdr)) :value :expr)]
+    (loop [ch1 (read-char rdr)
+           ch2 (read-char rdr)]
+      (when-not (and (or  (= \% ch1) (= \} ch1)) (= \} ch2))
+        (.append buf ch1)
+        (recur ch2 (read-char rdr))))
+    (let [content (->>  (.split (.toString buf ) " ") (remove empty?) (map (memfn trim)))]
+      (merge {:tag-type tag-type}
+             (if (= :value tag-type)
+               {:tag-value (first content)}
+               {:tag-name (first content)
+                :params (rest content)})))))
+
+#_(read-tag-info (java.io.StringReader. "% for i in nums %}"))
+#_(read-tag-info (java.io.StringReader. "{ nums }}"))
+
+(defn tag-content [close-tag rdr]
+  (let [content (transient [])
+        buf (StringBuilder.)]
+    (loop [ch (read-char rdr)]
+      (if (= \{ ch)
+        (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]
+          (when (not= close-tag tag-name)
+            (println tag)
+            (conj! content (.toString buf))
+            (.setLength buf 0)
+            (conj! content (if (= :value tag-type)
+                             (value-tag tag)
+                             (expr-tag tag rdr)))
+            (recur (read-char rdr))))
+        (do
+          (.append buf ch)
+          (recur (read-char rdr)))))
+    (conj! content (.toString buf))
+    (persistent! content)))
+
+#_(tag-content "endfor" (java.io.StringReader. "foo {{name}} bar {% endfor %}"))
+
+#_(render (tag-content "endfor" (java.io.StringReader. "foo {{name.first}} bar {% endfor %}")) {:name {:first "Bob"}})
+
+(def expr-tags
+  {:for {:content true
+         :close-tag "endfor"}})
+
+(defn expr-tag [{:keys [tag-name params]} rdr]
+  (let [{:keys [content close-tag]} (get expr-tags tag-name)]
+    (if content
+      (tag-content close-tag rdr))))
+
+(defn handle-tag [rdr]
+  (let [tag (read-tag-info rdr)]
+    ((if (:value tag) value-tag expr-tag) tag)))
+
+(defn parse [file & state]
+  (with-open [rdr (clojure.java.io/reader file)]
+      (let [template (transient [])
+            sb (StringBuilder.)]
+        (loop [state state
+               ch (.read rdr)]
+          (when (pos? ch)
+            (let [ch (char ch)]
+              (if (= \{ ch)
+                (do
+                  (conj! template (.toString sb))
+                  (.setLength sb 0)
+                  (conj! template (handle-tag rdr))
+                  (recur state (.read rdr)))
+                (do
+                  (.append sb ch)
+                  (recur state (.read rdr)))))))
+        (persistent! template))))
+
+
+#_(render (parse "home.html") {:name "Bob"})


dimensions namespace

dimensions namespace

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10876 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

error: pathspec 'acqEngine/src/org/micromanager/dimensions.clj' did not match any file(s) known to git

--- acqEngine/src/org/micromanager/dimensions.clj
+++ acqEngine/src/org/micromanager/dimensions.clj
@@ -0,0 +1,298 @@
+(ns org.micromanager.dimensions)
+
+(defn next-item
+  "Given an item and a vector of items, returns the next
+   item in the vector. If item is not found, the first
+   item in the vector is returned."
+  [item items]
+  (nth items (mod (inc (.indexOf items item))
+                        (count items))))
+
+(defn next-indices
+  "Give a vector of indices, and a list of ranges,
+   produces the next vector of indices, where the first index
+   loops the fastest. For example,
+   (next-indices [3 2 4] [4 3 7]) => [0 0 5]) .
+   Returns nil when indices is the last in the sequence."
+  [indices ranges]
+  (let [n (count indices)
+        ranges (vec ranges)]
+    (loop [dimension 0 new-indices (vec indices)]
+      (when (< dimension n)
+        (let [new-index (inc (new-indices dimension))]
+          (if (< new-index (ranges dimension))
+            (assoc new-indices dimension new-index)
+            (recur (inc dimension)
+                   (assoc new-indices dimension 0))))))))
+
+(defn indices-in-order
+  "Give a set of plane-indices and a dimension order, produces a
+   vector of indices (integers. For example,
+   (indices-in-order {:position 10 :slice 4 :channel 3 :frame 20}
+                     [:channel :slice :frame :position])
+     => [3 4 20 10] ."
+  [plane-indices order]
+  (vec (map #(% plane-indices) order)))
+
+(defn next-plane-indices [current-plane-indices dimension-sizes order]
+  (when-let [next-indices  (next-indices (indices-in-order current-plane-indices order)
+                                         (indices-in-order dimension-sizes order))]
+    (zipmap order next-indices)))
+
+(defn plane-indices [{:keys [position channel slice frame] :as plane}
+                     {:keys [positions channels slices] :as dimension-ranges}]
+  {:frame frame
+   :position (.indexOf positions position)
+   :channel (.indexOf channels channel)
+   :slice (.indexOf slices slice)})
+
+(defn plane-values [{:keys [position channel slice frame] :as plane-indices}
+                    {:keys [positions channels slices] :as dimension-values}]
+  {:frame frame
+   :position (positions position)
+   :channel (channels channel)
+   :slice (slices slice)})
+
+(defn dimension-sizes [{:keys [positions channels slices num-frames]}]
+  {:frame num-frames
+   :position (count positions)
+   :slice (count slices)
+   :channel (count channels)})
+
+(defn next-plane [{:keys [position channel slice frame] :as current-plane}
+                  {:keys [positions channels slices frames] :as dimension-values}
+                  order]
+    (let [dimension-sizes (dimension-sizes dimension-values)
+          current-plane-indices (plane-indices current-plane dimension-values)
+          next-plane-indices (next-plane-indices current-plane-indices dimension-sizes order)]
+      (when next-plane-indices
+        (plane-values next-plane-indices dimension-values))))
+
+(defn middle-item [items]
+  (let [n (count items)]
+    (nth items (long (/ n 2)))))
+
+(defn plane-forbidden? [{:keys [position channel slice frame] :as plane}
+                        {:keys [slices] :as dimension-values}
+                      channel-settings]
+  (let [{:keys [use-channel skip-frames use-z-stack] :as channel-setting}
+        (channel-settings channel)]
+    (and channel-setting
+         (or (not use-channel)
+             (and (pos? skip-frames) (pos? (mod frame (inc skip-frames))))
+             (and (not use-z-stack) (not= slice (middle-item slices)))))))
+
+(defn next-allowed-plane [current-plane dimension-values order channel-settings]
+  (loop [plane current-plane]
+    (when-let [next-plane (next-plane plane dimension-values order)]
+      (if (plane-forbidden? next-plane dimension-values channel-settings)
+        (recur next-plane)
+        next-plane))))
+
+;; testing ;;;;;;;;;
+
+
+(defn run-through-planes-simple [first-plane dimension-values order]
+  (take-while identity (iterate #(next-plane % dimension-values order) first-plane)))
+
+(defn run-through-planes [first-plane dimension-values order channel-settings]
+  (take-while identity (iterate #(next-allowed-plane
+                                   % dimension-values order channel-settings)
+                                first-plane)))
+
+(defn compute-first-plane [{:keys [positions channels slices] :as dimension-ranges}]
+  {:frame 0
+   :position (first positions)
+   :slice (first slices)
+   :channel (first channels)})
+
+(def test-dimension-values
+  {:num-frames 10
+   :positions ["Pos0" "Pos1" "Pos2"]
+   :slices [0.0 1.0 2.0]
+   :channels ["Cy5" "DAPI" "FITC"]
+   })
+
+(def test-plane
+  (compute-first-plane test-dimension-values))
+
+(def test-order
+  [:slice :channel :position :frame])
+
+(def test-channel-settings
+  {"Cy5"
+   {;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+    :exposure 10.0,
+    :properties
+    {["Dichroic" "Label"] "400DCLP",
+     ["Emission" "Label"] "Chroma-HQ700",
+     ["Excitation" "Label"] "Chroma-HQ570"},
+    :skip-frames 0,
+    :use-channel true,
+    :use-z-stack false,
+    :z-offset 0.0}
+   "DAPI"
+   {;:color #<Color java.awt.Color[r=0,g=204,b=51]>,
+    :exposure 10.0,
+    :properties
+    {["Dichroic" "Label"] "400DCLP",
+     ["Emission" "Label"] "Chroma-HQ620",
+     ["Excitation" "Label"] "Chroma-D360"},
+    :skip-frames 1,
+    :use-channel true,
+    :use-z-stack true,
+    :z-offset 0.0}
+   "FITC"
+   {;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+    :exposure 10.0,
+    :properties
+    {["Dichroic" "Label"] "Q505LP",
+     ["Emission" "Label"] "Chroma-HQ535",
+     ["Excitation" "Label"] "Chroma-HQ480"},
+    :skip-frames 0,
+    :use-channel true,
+    :use-z-stack true,
+    :z-offset 0.0}})
+
+(defn test-run []
+  (run-through-planes test-plane test-dimension-values test-order test-channel-settings))
+
+
+(def test-acq-settings
+  {:autofocus-skip 0,
+   :channels
+   [{;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+     :exposure 10.0,
+     :name "Cy5",
+     :properties
+     {["Dichroic" "Label"] "400DCLP",
+      ["Emission" "Label"] "Chroma-HQ700",
+      ["Excitation" "Label"] "Chroma-HQ570"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}
+    {;:color #<Color java.awt.Color[r=0,g=204,b=51]>,
+     :exposure 10.0,
+     :name "DAPI",
+     :properties
+     {["Dichroic" "Label"] "400DCLP",
+      ["Emission" "Label"] "Chroma-HQ620",
+      ["Excitation" "Label"] "Chroma-D360"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}
+    {;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+     :exposure 10.0,
+     :name "FITC",
+     :properties
+     {["Dichroic" "Label"] "Q505LP",
+      ["Emission" "Label"] "Chroma-HQ535",
+      ["Excitation" "Label"] "Chroma-HQ480"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}],
+   :comment "",
+   :custom-intervals-ms [],
+   :default-exposure 10.0,
+   :frames '(0 1 2),
+   :interval-ms 0.0,
+   :keep-shutter-open-channels false,
+   :keep-shutter-open-slices false,
+   :numFrames 3,
+   :positions [0 1],
+   :prefix nil,
+   :relative-slices true,
+   :root nil,
+   :save false,
+   :slices [0.0 1.0 2.0],
+   :slices-first false,
+   :time-first false,
+   :use-autofocus false,
+   :zReference 3.0})
+
+(def test-acq-settings
+  {:autofocus-skip 0,
+   :channels
+   [{;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+     :exposure 10.0,
+     :name "Cy5",
+     :properties
+     {["Dichroic" "Label"] "400DCLP",
+      ["Emission" "Label"] "Chroma-HQ700",
+      ["Excitation" "Label"] "Chroma-HQ570"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}
+    {;:color #<Color java.awt.Color[r=0,g=204,b=51]>,
+     :exposure 10.0,
+     :name "DAPI",
+     :properties
+     {["Dichroic" "Label"] "400DCLP",
+      ["Emission" "Label"] "Chroma-HQ620",
+      ["Excitation" "Label"] "Chroma-D360"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}
+    {;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+     :exposure 10.0,
+     :name "FITC",
+     :properties
+     {["Dichroic" "Label"] "Q505LP",
+      ["Emission" "Label"] "Chroma-HQ535",
+      ["Excitation" "Label"] "Chroma-HQ480"},
+     :skip-frames 0,
+     :use-channel true,
+     :use-z-stack true,
+     :z-offset 0.0}],
+   :comment "",
+   :custom-intervals-ms [],
+   :default-exposure 10.0,
+   :frames '(0 1 2),
+   :interval-ms 0.0,
+   :keep-shutter-open-channels false,
+   :keep-shutter-open-slices false,
+   :numFrames 3,
+   :positions [0 1],
+   :prefix nil,
+   :relative-slices true,
+   :root nil,
+   :save false,
+   :slices [0.0 1.0 2.0],
+   :slices-first false,
+   :time-first false,
+   :use-autofocus false,
+   :zReference 3.0})
+
+(def test-acq-event
+  {:close-shutter true,
+   :next-frame-index 0,
+   :frame-index 0,
+   :position 0,
+   :position-index 0,
+   :slice 0.0,
+   :new-position true,
+   :autofocus false,
+   :channel-index 0,
+   :slice-index 0,
+   :frame 0,
+   :channel
+   {;:color #<Color java.awt.Color[r=255,g=0,b=0]>,
+    :exposure 10.0,
+    :name "Cy5",
+    :properties
+    {["Dichroic" "Label"] "400DCLP",
+     ["Emission" "Label"] "Chroma-HQ700",
+     ["Excitation" "Label"] "Chroma-HQ570"},
+    :skip-frames 0,
+    :use-channel true,
+    :use-z-stack true,
+    :z-offset 0.0},
+   :exposure 10.0,
+   :relative-z true,
+   :task :snap,
+   :wait-time-ms 0})


added IndependentDrawer class - thread with it's own surface that can execute drawing commands

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

--- src/clojure/android/clojure/IndependentDrawer.clj
+++ src/clojure/android/clojure/IndependentDrawer.clj
@@ -0,0 +1,242 @@
+
+;; date:   Saturday, 30 March 2013
+;; author: Sergey Vinokurov
+;; email:  serg.foo@gmail.com
+
+(ns android.clojure.IndependentDrawer
+  "Independent drawer class providing Surface and separate thread that
+can receive drawing commands and \"execute\" them on the Surface.
+
+Drawer maintains separate bitmap where most of drawing commands will be
+executed on this bitmap and only after the bitmap will be drawn on
+the surface. This, contents of the bitmap will be preserved between
+drawing commands invokations.
+
+Other type of drawing commands is commands that will be executed
+on the Surface and whose results will not be preserved."
+  (:gen-class :main no
+              :name android.clojure.IndependentDrawer
+              :extends android.view.SurfaceView
+              :implements [android.view.SurfaceHolder$Callback]
+              :state drawer_state
+              :init drawer-init
+              :post-init drawer-post-init)
+  (:import [android.content Context]
+           [android.graphics Bitmap Canvas Color Paint Rect]
+           [android.view MotionEvent SurfaceHolder SurfaceView View Window]
+           [android.util AttributeSet]
+
+           [android.util.Log]
+
+           [java.util.concurrent
+            ConcurrentLinkedQueue
+            LinkedBlockingQueue
+            ThreadPoolExecutor
+            TimeUnit]))
+
+(defn- log
+  ([msg] (android.util.Log/d "IndependentDrawer" msg))
+  ([msg & args] (log (apply format msg args))))
+
+
+
+(defrecord DrawerState [surface-available?
+                        ^Bitmap drawing-bitmap
+                        ^Canvas drawing-canvas
+                        ^Thread drawing-thread
+                        ^ConcurrentLinkedQueue message-queue])
+
+(defn -drawer-init
+  "Initialize drawer state and pass arguments up to super-constructor."
+  ([^Context context]
+     [[context]
+      (DrawerState. (atom nil)
+                    (atom nil :meta {:tag Bitmap})
+                    (atom nil :meta {:tag Canvas})
+                    (atom nil :meta {:tag Thread})
+                    (ConcurrentLinkedQueue.))])
+  ([^Context context ^AttributeSet attrs]
+     [[context attrs]
+      (DrawerState. (atom nil)
+                    (atom nil :meta {:tag Bitmap})
+                    (atom nil :meta {:tag Canvas})
+                    (atom nil :meta {:tag Thread})
+                    (ConcurrentLinkedQueue.))])
+  ([^Context context ^AttributeSet attrs defStyle]
+     [[context attrs defStyle]
+      (DrawerState. (atom nil)
+                    (atom nil :meta {:tag Bitmap})
+                    (atom nil :meta {:tag Canvas})
+                    (atom nil :meta {:tag Thread})
+                    (ConcurrentLinkedQueue.))]))
+
+(defn -drawer-post-init
+  "Register surface callback for managing surface lifecycle."
+  ([^android.clojure.IndependentDrawer this
+    ^Context context]
+     (.. this (getHolder) (addCallback this)))
+  ([^android.clojure.IndependentDrawer this
+    ^Context context ^AttributeSet attrs]
+     (-drawer-post-init this context))
+  ([^android.clojure.IndependentDrawer this
+    ^Context context ^AttributeSet attrs defStyle]
+     (-drawer-post-init this context)))
+
+
+
+(defn -surfaceChanged [^android.clojure.IndependentDrawer this
+                       ^SurfaceHolder holder
+                       format
+                       width
+                       height]
+  (reset! (.drawing-bitmap ^DrawerState (.drawer_state this))
+          (if-let [orig-bmap ^Bitmap @(.drawing-bitmap ^DrawerState (.drawer_state this))]
+            (Bitmap/createScaledBitmap orig-bmap width height true)
+            (Bitmap/createBitmap width height android.graphics.Bitmap$Config/ARGB_8888)))
+  (reset! (.drawing-canvas ^DrawerState (.drawer_state this))
+          (Canvas. @(.drawing-bitmap ^DrawerState (.drawer_state this)))))
+
+
+(declare make-drawing-thread)
+
+(defn -surfaceCreated [^android.clojure.IndependentDrawer this
+                       ^SurfaceHolder holder]
+  (reset! (.surface-available? ^DrawerState (.drawer_state this)) true)
+  (let [thread ^Thread (make-drawing-thread this)]
+    (reset! (.drawing-thread ^DrawerState (.drawer_state this))
+            thread)
+    (.start thread)))
+
+(defn -surfaceDestroyed [^android.clojure.IndependentDrawer this
+                         ^SurfaceHolder holder]
+  (reset! (.surface-available? ^DrawerState (.drawer_state this)) false)
+  (loop []
+    (when (not (try
+                 (.join ^Thread @(.drawing-thread ^DrawerState (.drawer_state this)))
+                 true
+                 (catch InterruptedException e
+                   false)))
+      (recur))))
+
+
+(defmacro with-canvas
+  "action will be executed with canvas-var bound to drawing canvas whole
+contents is stored in drawing bitmap and will be preserved between
+different actions.
+
+after-action will be executed with canvas-var bounded to the
+resulting canvas with drawing-bitmap drawn on. Content of this canvas will
+not be preserved."
+  ([canvas-var surface-view action after-action]
+     `(with-canvas ~canvas-var ~surface-view ~action ~after-action nil))
+  ([canvas-var surface-view action after-action post-action]
+     `(if-let [surface-canvas# ^Canvas (.. ~surface-view (getHolder) (lockCanvas))]
+        (try
+          (let [~canvas-var ^Canvas @(.drawing-canvas ^DrawerState (.drawer_state ~surface-view))]
+            ~action)
+          (.drawBitmap surface-canvas#
+                       ^Bitmap @(.drawing-bitmap ^DrawerState
+                                                 (.drawer_state ~surface-view))
+                       0.0
+                       0.0
+                       nil)
+          (let [~canvas-var ^Canvas surface-canvas#]
+            ~after-action)
+          (finally
+            ~post-action
+            (.. ~surface-view (getHolder) (unlockCanvasAndPost surface-canvas#))))
+        (log "Unexpected error: lockCanvas returned nil"))))
+
+(defmacro call-on-func-or-func-seq [f func-or-coll]
+  `(when ~func-or-coll
+     (if (seq? ~func-or-coll)
+       (dorun (map ~f ~func-or-coll))
+       (~f ~func-or-coll))))
+
+(defn- ^Thread make-drawing-thread [^android.clojure.IndependentDrawer this]
+  (let [msg-queue ^ConcurrentLinkedQueue (.message-queue ^DrawerState (.drawer_state this))]
+    (Thread.
+     (fn []
+       (log "Drawing thread's born")
+       (loop []
+         (when @(.surface-available? ^DrawerState (.drawer_state this))
+           (if-let [msg (.peek msg-queue)]
+             (case (msg :type)
+               :plain
+               (let [{:keys [actions after-actions]} msg]
+                 (with-canvas canvas this
+                   (call-on-func-or-func-seq #(% canvas) actions)
+                   (call-on-func-or-func-seq #(% canvas) after-actions)
+                   (.poll msg-queue)))
+               :animation
+               ;; if type is :animation then anim-actions and anim-after-actions are
+               ;; sequences of functions of two argumetns:
+               ;; canvas and $$ t \in \left[ 0, 1 \right] $$
+               (let [{:keys [anim-actions anim-after-actions duration pause-time]}
+                     msg
+                     start-time (System/currentTimeMillis)]
+                 (with-canvas canvas this
+                   (call-on-func-or-func-seq #(% canvas 0) anim-actions)
+                   (call-on-func-or-func-seq #(% canvas 0) anim-after-actions))
+                 (Thread/sleep pause-time 0)
+                 (loop []
+                   (let [curr-time (System/currentTimeMillis)
+                         diff (- curr-time start-time)]
+                     (assert (<= 0 diff))
+                     (when (< diff duration)
+                       (with-canvas canvas this
+                         (call-on-func-or-func-seq #(% canvas (/ diff duration))
+                                                   anim-actions)
+                         (call-on-func-or-func-seq #(% canvas (/ diff duration))
+                                                   anim-after-actions))
+                       (Thread/sleep pause-time 0)
+                       (recur))))
+                 (with-canvas canvas this
+                   (call-on-func-or-func-seq #(% canvas 1) anim-actions)
+                   (call-on-func-or-func-seq #(% canvas 1) anim-after-actions))
+                 (Thread/sleep pause-time 0)
+                 ;; completed action or not - remove it anyway
+                 (.poll msg-queue)))
+             (Thread/sleep 100 0))
+           (recur)))
+       (log "Drawing thread dies"))
+     (format "Independent drawer thread, %s" this))))
+
+
+;;;; user-visible API
+
+(defn send-drawing-command
+  "Send drawing command to particular drawer. Drawing command is a map with
+:type key one of :plain or :animation
+
+If type is :plain then :actions and :after-actions keys may be provided.
+
+If type is :animation then :anim-actions, :anim-after-actions, :duration and
+:pause time keys may be provided.
+
+:actions is a single function or a sequence of functions of one canvas
+         argument that will be executed on intermediate bitmap and thus will
+         be preserved across different invokations
+
+:after-actions is a single function a sequence of functions of one canvas
+               argument that will be executed on final Surface so that their
+               results would not be preserved
+
+:anim-actions and :anim-after-actions work just like :actions and :after-actions
+but take two arguments: drawing canvas and time argument from [0, 1] real interval.
+
+:duration animation duration in milliseconds
+
+:pause amount of time to wait after execution of each animation command
+
+"
+  [^android.clojure.IndependentDrawer drawer
+   msg]
+  (if (and (contains? msg :type)
+           (contains? #{:plain :animation} (msg :type)))
+    (.add ^ConcurrentLinkedQueue
+          (.message-queue ^DrawerState
+                          (.drawer_state drawer))
+          msg)
+    (log "Error: attempt to send invalid message: %s" msg)))
+


Removed character test.

Removed character 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/inchingforward/eon.git/'


delete jobs dir in teardown

delete jobs dir in teardown

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


Added support for :other-books

Added support for :other-books

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


covers.clj: new file

covers.clj: new file

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

--- clojure/org/gavrog/clojure/covers.clj
+++ clojure/org/gavrog/clojure/covers.clj
@@ -0,0 +1,15 @@
+(ns org.gavrog.clojure.covers
+  (:use (org.gavrog.clojure
+         delaney
+         fundamental
+         cosets)))
+
+(defn subgroup-cover
+  ([ds fund-group subgroup-gens]
+    (let [{:keys [nr-generators relators edge-to-word]} fund-group
+          table (coset-table nr-generators relators subgroup-gens)]
+      (cover ds (count table) (fn [k i D]
+                                (reduce (fn [k g] ((table k) g))
+                                        k (edge-to-word [D i]))))))
+  ([ds subgroup-gens]
+    (subgroup-cover ds (fundamental-group ds) subgroup-gens)))


more Predict the Number

more Predict the Number

Clojure

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


A place for string utils

A place for string utils

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

--- src/detritus/string.clj
+++ src/detritus/string.clj
@@ -0,0 +1,17 @@
+(ns detritus.string)
+
+
+(defn re-fn
+  "Construct a regular expression from string.  Calling a regular
+  expression with no arguments returns a Pattern.  Calling a regular
+  expression with a string argument returns nil if no matches,
+  otherwise the equivalent of (re-seq re string)."
+  [string]
+  (let [pp (re-pattern string)]
+    (fn re
+      ([] pp)
+      ([s] (let [groups (re-seq pp s)]
+             (if (first groups)
+               groups
+               nil))))))
+


Version 1.15.2-SNAPSHOT

Version 1.15.2-SNAPSHOT

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


use cider snapshot w/ clojure alpha

use cider snapshot w/ clojure alpha

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


Update deps & add description to project.clj


Version 176

Version 176

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/tobias/clojars-web.git/'


Kehaar 0.7.0 with bounded thread pools

Kehaar 0.7.0 with bounded thread pools

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


Add transit dependency

Add transit dependency

--- project.clj
+++ project.clj
@@ -27,7 +27,8 @@
    [ring-basic-authentication "1.0.5"]
    [org.clojure/core.async "0.1.346.0-17112a-alpha"]
    [org.clojure/tools.reader "0.9.1"]
-   [org.clojars.ikoblik/clj-index "0.0.2"]]
+   [org.clojars.ikoblik/clj-index "0.0.2"]
+   [com.cognitect/transit-clj "0.8.285"]]

   :pedantic? :abort


Version 160

Version 160


Turn off logging in test profile

Turn off logging in test profile

…as we do in other projects

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


Update deps & clojure

Update deps & clojure

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


update project version

update project version

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject cryogen/lein-template "0.1.6"
+(defproject cryogen/lein-template "0.1.7"
   :description "A Leiningen template for the Cryogen static site generator"
   :url "https://github.com/lacarmen/cryogen"
   :license {:name "Eclipse Public License"


Upgrade Carmine to 2.14.0

Upgrade Carmine to 2.14.0

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


Remove ovp.schema.version reference from template

Also remove it from headers of publish 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/Yleisradio/yle-api-template.git/'


tighten things up a bit more by using destructuring with default values.

--- src/metabase/driver.clj
+++ src/metabase/driver.clj
@@ -31,20 +31,20 @@
      :synchronously [true|false]      (default true)
      :cache_result [true|false]       (default false)
   "
-  [query caller-options]
-  (let [default-options {:synchronously true
-                         :cache_result false}
-        options (merge default-options caller-options)
+  [query {:keys [executed_by synchronously saved_query]
+          :or {synchronously true}
+          :as caller-options}]
+  (let [options (merge {:cache_result false} caller-options)
         query-execution {:uuid (.toString (java.util.UUID/randomUUID))
-                         ;:executor (:executed_by caller-options)
+                         ;:executor executed_by
                          :json_query query
                          :status :starting
                          :started_at (util/new-sql-date)
                          :start_time_millis (System/currentTimeMillis)}]
     ; add :query_id and :version if we are executing from an existing saved query
-    (when-let [saved_query (:saved_query options)]
-      (util/assoc* query-execution :query_id (:id saved_query) :version (:version saved_query)))
-    (if (:synchronously options)
+    (when saved_query
+      (assoc query-execution :query_id (:id saved_query) :version (:version saved_query)))
+    (if synchronously
       (-dataset-query query options query-execution)
       ;; TODO - this is untested/used.  determine proper way to place execution on background thread
       (future (-dataset-query query options query-execution)))))


Make name nullable

Make name nullable

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


Simplifying expression

Simplifying expression


Fixed where clause issue

Fixed where clause issue

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


adjust option map format in method 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 document/get-info method for HEAD request on document


rev comments notes/reminders related to *core-cache-op*

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


more notes

more notes


Refactor the way we handle the unknown routes.

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


Fix typo in Marginalia documentation

Fix typo in Marginalia 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/magoyette/marcandregoyette.com.git/'


Adding user_sql.clj to version control.

Adding user_sql.clj to version control.

error: pathspec 'src/kilo/data/user_sql.clj' did not match any file(s) known to git

--- src/kilo/data/user_sql.clj
+++ src/kilo/data/user_sql.clj
@@ -0,0 +1,26 @@
+(ns kilo.data.user-sql
+  (:use [korma.core]
+        [kilo.sqldb])
+  )
+
+(defentity user
+  (table :mdl_sis_user)
+  )
+
+(defn get-user-data
+  [id]
+  ;; need to convert string id to long
+  (let [id (Long/parseLong id)]
+    (select user
+          (where {:id id})))
+   )
+
+(defn set-user-data
+  [id fields]
+  (let [id (Long/parseLong id)]
+    (update user
+            (set-fields fields)
+            (where {:id id})))
+  )
+
+


util/jruby.clj: added lib for JRuby access

error: pathspec 'src/org/altlaw/util/jruby.clj' did not match any file(s) known to git

--- src/org/altlaw/util/jruby.clj
+++ src/org/altlaw/util/jruby.clj
@@ -0,0 +1,23 @@
+(ns org.altlaw.util.jruby
+  (:require [clojure.contrib.singleton :as sing]
+            [clojure.contrib.java-utils :as j])
+  (:import (javax.script SimpleBindings ScriptContext
+                         ScriptEngine ScriptEngineManager)))
+
+(def #^{:private true} jruby
+     (sing/per-thread-singleton
+      (fn []
+        (.getEngineByName (ScriptEngineManager.) "jruby"))))
+
+(defn- make-bindings [m]
+  (let [bindings (SimpleBindings.)]
+   (doseq [[k v] m]
+     (.put bindings (j/as-str k) v))
+   bindings))
+
+(defn eval-jruby
+  ([script]
+     (.eval (jruby) script))
+  ([script bindings]
+     (.eval (jruby) script (make-bindings bindings))))
+


test-runner namespace

test-runner namespace

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


fix typos in tests

fix typos in tests

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


make `form-type->map` true to its name

make `form-type->map` true to its name

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


re-implemented branch-right as an either-specific synonym of bind

--- src/cats/monad/either.cljc
+++ src/cats/monad/either.cljc
@@ -234,12 +234,14 @@
   (branch e lf right))

 (defn branch-right
-  "Given an either value and a function, if the either is a
+  "Either-specific synonym for #'cats.core/bind
+
+  Given an either value and a function, if the either is a
   right, apply the function to the value it contains; if the
   either is a left, return it."
   [e rf]
   {:pre [(either? e)]}
-  (branch e left rf))
+  (m/bind e rf))

 (def lefts
   "Given a collection of eithers, return only the values that are left."


"cache" is clearer than "fc"

"cache" is clearer than "fc"


simplify naming

simplify naming

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


begin the process of lispification

begin the process of lispification

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


context-path test...?

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


update upcoming-election deadline context for sms


Removed carriage return before closing paren

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


(PDB-5230) Add collected-queries-still-working regression test

Ensure we don't break important queries we've collected from services that
depend on pdb. For now we just ensure the http status of the response is
200.

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

--- test/puppetlabs/puppetdb/query/regression_test.clj
+++ test/puppetlabs/puppetdb/query/regression_test.clj
@@ -0,0 +1,32 @@
+(ns puppetlabs.puppetdb.query.regression-test
+  (:require
+   [clj-yaml.core :as yaml]
+   [clojure.java.io :as io]
+   [clojure.string :as str]
+   [clojure.test :refer [deftest is testing]]
+   [puppetlabs.puppetdb.cheshire :as json]
+   [puppetlabs.puppetdb.testutils.db :refer [with-test-db]]
+   [puppetlabs.puppetdb.testutils.http
+    :refer [query-response with-http-app]]))
+
+(deftest collected-queries-still-working
+  (with-test-db
+    (with-http-app
+      (doseq [file (->> "locust/load-test"
+                        io/as-file
+                        file-seq
+                        (filter #(str/ends-with? % ".yaml")))
+              request-data (yaml/parse-string (slurp file))
+              :let [{:keys [alias method path query]} request-data
+                    keyword-method (case method
+                                     "GET" :get
+                                     "POST" :post)
+                    relative-path (str/replace-first path #"^/pdb/query" "")]]
+        (testing (str "testing " alias " in " file)
+          (let [{:keys [status body]}
+                (query-response keyword-method relative-path query)]
+            ;; If body of response is not valid JSON, the test should fail
+            (is (-> body slurp json/parse-string))
+            ;; If status of response is not 200, the test should fail
+            (is (= 200 status))))))))
+


Test clblast engine on CPU.

Test clblast engine on CPU.

error: pathspec 'test/uncomplicate/neanderthal/clblast_cpu_test.clj' did not match any file(s) known to git

--- test/uncomplicate/neanderthal/clblast_cpu_test.clj
+++ test/uncomplicate/neanderthal/clblast_cpu_test.clj
@@ -0,0 +1,44 @@
+(ns uncomplicate.neanderthal.clblast-cpu-test
+  (:require [midje.sweet :refer :all]
+            [uncomplicate.commons.core :refer [with-release]]
+            [uncomplicate.clojurecl
+             [core :refer [*command-queue* with-platform platforms devices with-queue with-context context]]
+             [legacy :refer [command-queue-1]]]
+            [uncomplicate.neanderthal
+             [core :refer [tr]]
+             [opencl :refer [with-engine *opencl-factory*]]
+             [block-test :as block-test]
+             [real-test :as real-test]
+             [device-test :as device-test]
+             [math-test :as math-test]]
+            [uncomplicate.neanderthal.internal.device.clblast :refer [clblast-float clblast-double]]))
+
+(defn test-blas-clblast [factory]
+  (real-test/test-imin factory)
+  (real-test/test-imax factory)
+  (real-test/test-ge-trans! factory)
+  (real-test/test-ge-sum factory))
+
+(defn test-lapack-clblast [factory]
+  (real-test/test-tr-trs factory tr)
+  (real-test/test-tr-sv factory tr))
+
+(with-release [dev (first (devices (first (platforms)) :cpu))
+               ctx (context [dev])
+               queue (command-queue-1 ctx dev)]
+
+  (with-engine clblast-float queue
+    (block-test/test-all *opencl-factory*)
+    (real-test/test-blas *opencl-factory*)
+    (test-blas-clblast *opencl-factory*)
+    (test-lapack-clblast *opencl-factory*)
+    (device-test/test-all *opencl-factory*)
+    (math-test/test-all-device *opencl-factory*))
+
+  (with-engine clblast-double queue
+    (block-test/test-all *opencl-factory*)
+    (real-test/test-blas *opencl-factory*)
+    (test-blas-clblast *opencl-factory*)
+    (test-lapack-clblast *opencl-factory*)
+    (device-test/test-all *opencl-factory*)
+    (math-test/test-all-device *opencl-factory*)))


Added data about an accordian layout

Added data about an accordian layout

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

--- src/cljs/omnibar/accordion.cljs
+++ src/cljs/omnibar/accordion.cljs
@@ -0,0 +1,134 @@
+(ns omnibar.accordion)
+
+;;"Typical 120-button Stradella bass system. This is the left-hand manual system found on most unisonoric accordions today" -- wikipedia
+(def stradella-bass
+  [{:name "major-3rd-note" :text "Major 3rd note" :notes [
+            {:id "major-3rd-d-flat"
+             :midi []
+             :text "Db"
+             :class "r0 c0"} ;; knowing the row and column can help css styling, so you can highligh the whole row and columns of a selected note.
+            {:id "major-3rd-a-flat"       :midi [] :text "Ab"  :class "r0 c1"}
+            {:id "major-3rd-e-flat"       :midi [] :text "Eb"  :class "r0 c2"}
+            {:id "major-3rd-b-flat"       :midi [] :text "Bb"  :class "r0 c3"}
+            {:id "major-3rd-f"            :midi [] :text "F"   :class "r0 c4"}
+            {:id "major-3rd-c"            :midi [] :text "C"   :class "r0 c5"}
+            {:id "major-3rd-g"            :midi [] :text "G"   :class "r0 c6"}
+            {:id "major-3rd-d"            :midi [] :text "D"   :class "r0 c7"}
+            {:id "major-3rd-a"            :midi [] :text "A"   :class "r0 c8"}
+            {:id "major-3rd-e"            :midi [] :text "E"   :class "r0 c9"}
+            {:id "major-3rd-b"            :midi [] :text "B"   :class "r0 c10"}
+            {:id "major-3rd-f-sharp"      :midi [] :text "F#"  :class "r0 c11"}
+            {:id "major-3rd-c-sharp"      :midi [] :text "C#"  :class "r0 c12"}
+            {:id "major-3rd-g-sharp"      :midi [] :text "G#"  :class "r0 c13"}
+            {:id "major-3rd-d-sharp"      :midi [] :text "D#"  :class "r0 c14"}
+            {:id "major-3rd-a-sharp"      :midi [] :text "A#"  :class "r0 c15"}
+            {:id "major-3rd-e-sharp"      :midi [] :text "E#"  :class "r0 c16"}
+            {:id "major-3rd-b-sharp"      :midi [] :text "B#"  :class "r0 c17"}
+            {:id "major-3rd-double-sharp" :midi [] :text "F##" :class "r0 c18"}
+            {:id "major-3rd-double-sharp" :midi [] :text "C##" :class "r0 c19"}]}
+   {:name "root-note" :text "Root note" :notes [
+            {:id "root-b-double-flat" :midi [] :text "Bbb" :class "r1 c0"}
+            {:id "root-f-flat" :midi [] :text "Fb" :class "r1 c1"}
+            {:id "root-c-flat" :midi [] :text "Cb" :class "r1 c2"}
+            {:id "root-g-flat" :midi [] :text "Gb" :class "r1 c3"}
+            {:id "root-d-flat" :midi [] :text "Db" :class "r1 c4"}
+            {:id "root-a-flat" :midi [] :text "Ab" :class "r1 c5"}
+            {:id "root-e-flat" :midi [] :text "Eb" :class "r1 c6"}
+            {:id "root-b-flat" :midi [] :text "Bb" :class "r1 c7"}
+            {:id "root-f" :midi [] :text "F" :class "r1 c8"}
+            {:id "root-c" :midi [] :text "C" :class "r1 c9"}
+            {:id "root-g" :midi [] :text "G" :class "r1 c10"}
+            {:id "root-d" :midi [] :text "D" :class "r1 c11"}
+            {:id "root-a" :midi [] :text "A" :class "r1 c12"}
+            {:id "root-e" :midi [] :text "E" :class "r1 c13"}
+            {:id "root-b" :midi [] :text "B" :class "r1 c14"}
+            {:id "root-f-sharp" :midi [] :text "F#" :class "r1 c15"}
+            {:id "root-c-sharp" :midi [] :text "C#" :class "r1 c16"}
+            {:id "root-g-sharp" :midi [] :text "G#" :class "r1 c17"}
+            {:id "root-d-sharp" :midi [] :text "D#" :class "r1 c18"}
+            {:id "root-a-sharp" :midi [] :text "A#" :class "r1 c19"}]}
+   {:name "major-chord" :text "Major cho rd" :notes [
+            {:id "major-chord-" :midi [] :text "Db"  :class "r2 c0"}
+            {:id "major-chord-" :midi [] :text "Ab"  :class "r2 c1"}
+            {:id "major-chord-" :midi [] :text "Eb"  :class "r2 c2"}
+            {:id "major-chord-" :midi [] :text "Bb"  :class "r2 c3"}
+            {:id "major-chord-" :midi [] :text "F"   :class "r2 c4"}
+            {:id "major-chord-" :midi [] :text "C"   :class "r2 c5"}
+            {:id "major-chord-" :midi [] :text "G"   :class "r2 c6"}
+            {:id "major-chord-" :midi [] :text "D"   :class "r2 c7"}
+            {:id "major-chord-" :midi [] :text "A"   :class "r2 c8"}
+            {:id "major-chord-" :midi [] :text "E"   :class "r2 c9"}
+            {:id "major-chord-" :midi [] :text "B"   :class "r2 c10"}
+            {:id "major-chord-" :midi [] :text "F#"  :class "r2 c11"}
+            {:id "major-chord-" :midi [] :text "C#"  :class "r2 c12"}
+            {:id "major-chord-" :midi [] :text "G#"  :class "r2 c13"}
+            {:id "major-chord-" :midi [] :text "D#"  :class "r2 c14"}
+            {:id "major-chord-" :midi [] :text "A#"  :class "r2 c15"}
+            {:id "major-chord-" :midi [] :text "E#"  :class "r2 c16"}
+            {:id "major-chord-" :midi [] :text "B#"  :class "r2 c17"}
+            {:id "major-chord-" :midi [] :text "F##" :class "r2 c18"}
+            {:id "major-chord-" :midi [] :text "C##" :class "r2 c19"}]}
+   {:name "minor-chord" :text "Minor chord" :notes [
+            {:id "minor-chord-" :midi [] :text "Db"  :class ""}
+            {:id "minor-chord-" :midi [] :text "Ab"  :class ""}
+            {:id "minor-chord-" :midi [] :text "Eb"  :class ""}
+            {:id "minor-chord-" :midi [] :text "Bb"  :class ""}
+            {:id "minor-chord-" :midi [] :text "F"   :class ""}
+            {:id "minor-chord-" :midi [] :text "C"   :class ""}
+            {:id "minor-chord-" :midi [] :text "G"   :class ""}
+            {:id "minor-chord-" :midi [] :text "D"   :class ""}
+            {:id "minor-chord-" :midi [] :text "A"   :class ""}
+            {:id "minor-chord-" :midi [] :text "E"   :class ""}
+            {:id "minor-chord-" :midi [] :text "B"   :class ""}
+            {:id "minor-chord-" :midi [] :text "F#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "C#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "G#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "D#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "A#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "E#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "B#"  :class ""}
+            {:id "minor-chord-" :midi [] :text "F##" :class ""}
+            {:id "minor-chord-" :midi [] :text "C##" :class ""}]}
+   {:name "dominant-7th-chord" :text "Dominant 7th chord" :notes [
+            {:id "dominant-7th-" :midi [] :text "Db"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "Ab"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "Eb"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "Bb"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "F"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "C"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "G"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "D"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "A"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "E"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "B"   :class ""}
+            {:id "dominant-7th-" :midi [] :text "F#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "C#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "G#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "D#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "A#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "E#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "B#"  :class ""}
+            {:id "dominant-7th-" :midi [] :text "F##" :class ""}
+            {:id "dominant-7th-" :midi [] :text "C##" :class ""}]}
+   {:name "diminished-7th-chord" :text "Diminished 7th chord" :notes [
+            {:id "diminished-7th-" :midi [] :text "Db"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "Ab"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "Eb"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "Bb"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "F"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "C"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "G"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "D"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "A"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "E"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "B"   :class ""}
+            {:id "diminished-7th-" :midi [] :text "F#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "C#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "G#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "D#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "A#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "E#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "B#"  :class ""}
+            {:id "diminished-7th-" :midi [] :text "F##" :class ""}
+            {:id "diminished-7th-" :midi [] :text "C##" :class ""}]}])
+


remove reflection code; use Java 7 API directly for filetype detection

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


we need the stub service for the create

we need the stub service for the create

fatal: unable to access 'https://github.com/democracyworks/electorate-works.git/': The requested URL returned error: 403


Move clojure-fundamentals stuff to here.

error: pathspec 'test/com/nomistech/clojure_the_language/clojure_fundamentals_test.clj' did not match any file(s) known to git


Typo.

Typo.

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


Clean up debug println

Clean up debug println

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


Foods can be updated

Foods can be updated

Fixed issue with PUT

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


huffman and hu-tucker encoding

huffman and hu-tucker encoding

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

--- src/cavm/huffman.clj
+++ src/cavm/huffman.clj
@@ -0,0 +1,315 @@
+(ns
+  ^{:author "Brian Craft"
+    :doc "huffman coding"}
+  cavm.huffman
+  (:import [java.util.concurrent ArrayBlockingQueue]))
+
+; XXX would aget be faster than nth? Note that string nulls
+; are coming in as a vector of one
+; XXX could be done in parallel & merged, perhaps via transducer
+(defn byte-freqs [coll]
+    (let [freqs (transient {})]
+        (loop [coll coll freqs freqs]
+            (if-let [item (first coll)]
+                (recur
+                    (rest coll)
+                    (let [len (count item)]
+                        (loop [i 0 freqs freqs]
+                            (if (< i len)
+                                (let [c (nth item i)]
+                                    (recur (inc i)
+                                           (assoc! freqs c (inc (get freqs c 0)))))
+                                freqs))))
+                (persistent! freqs)))))
+
+(defn- take-lowest [^ArrayBlockingQueue q0
+                   ^ArrayBlockingQueue q1]
+    (let [v0 (.peek q0) v1 (.peek q1)]
+        (if (or (not v1) (and v0 (>= (:priority v1) (:priority v0))))
+            (.take q0)
+            (.take q1))))
+
+; compute huffman tree from char freqs
+(defn- build-tree [freqs]
+    (let [leaves (->> freqs
+                      (sort-by second)
+                      (map #(zipmap [:symbol :priority] %))
+                      (ArrayBlockingQueue. (count freqs) false))
+          nodes (ArrayBlockingQueue. (count freqs))]
+        (while (> (+ (.size leaves) (.size nodes)) 1)
+            (let [a (take-lowest leaves nodes) b (take-lowest leaves nodes)
+                  new-node {:priority (+ (:priority a) (:priority b)) :left a :right b}]
+                (.add nodes new-node)))
+        (.take nodes)))
+
+;
+; hu-tucker
+;
+
+(defn- compatible-pairs [nodes]
+  (let [len (count nodes)]
+    (for [i (range len)
+          :when (nodes i)
+          j (range (inc i) len)
+          :when (nodes j)
+          :while (or (= j (inc i)) (not (:symbol (nodes (dec j)))))]
+      [i j])))
+
+(defn- best-merge [nodes]
+  (->> nodes
+       compatible-pairs
+       (map (fn [pair] {:priority (+ (:priority (nodes (pair 0))) (:priority (nodes (pair 1)))) :pair pair}))
+       (apply min-key :priority)))
+
+;(let [nodes [{:symbol :a :priority 12} nil {:priority 5} {:priority 11 :symbol :c} {:priority 7} nil]]
+;  (best-merge nodes))
+
+; compute hu-tucker tree from char freqs, O(n^2)
+; There are O(n log n), and O(n) algorithms, but they're quite complex.
+(defn- build-ht-tree [freqs]
+  (let [leaves (->> freqs
+                    (sort-by first)
+                    (mapv #(zipmap [:symbol :priority] %)))
+        len (count leaves)]
+    (loop [i (dec len)
+           nodes leaves]
+      (if (> i 0)
+        (let [to-merge (best-merge nodes)
+              pair (:pair to-merge)
+              next-nodes (assoc nodes
+                                (pair 0) (assoc to-merge :left (nodes (pair 0)) :right (nodes (pair 1)))
+                                (pair 1) nil)]
+          (recur (dec i) next-nodes))
+        (some identity nodes)))))
+
+; would this work for huffman, too? It might simplify things to only have a single
+; internal representation of a code. Or would it mess up the compact encoding of
+; the dictionary? Speaking of which, is there a compact encoding of the hu-tucker
+; dictionary?
+(defn- make-ht-codes [tree]
+  (loop [acc [] q [[0 0 tree]]]
+    (if (seq q)
+      (let [[[len code node] & more] q]
+       (if-let [symbol (:symbol node)]
+         (recur (conj acc {:symbol symbol :length len :code code}) more)
+         (recur acc (conj more
+                          [(inc len) (bit-shift-left code 1) (:left node)]
+                          [(inc len) (bit-or (bit-shift-left code 1) 1) (:right node)]))))
+      acc)))
+
+(defn- ht-dictionary [codes]
+  (->> codes
+   (map #(-> [(:symbol %) %]))
+   (into {})))
+
+(defn write-int [i ^java.io.ByteArrayOutputStream out]
+  (.write out (bit-and 0xff i))
+  (.write out (bit-and 0xff (bit-shift-right i 8)))
+  (.write out (bit-and 0xff (bit-shift-right i 16)))
+  (.write out (bit-and 0xff (bit-shift-right i 24))))
+
+; [[codes0] [codes1] ..
+; Should the dict encoding be to bytes, or ByteArrayOutputStream,
+; or something seqable?
+; Might be able to use smaller ints here, instead of 32 bits.
+
+; not sure grouping by length is worth the extra effort.
+; Why output length for each code when we've grouped by length?
+(comment (defn- ht-coded-dictionary [codes ^java.io.ByteArrayOutputStream out]
+           (let [order (group-by :length codes)
+                 len (:length (apply max-key :length codes))]
+             (write-int len out)
+             (doseq [i (range len)]
+               (let [g (order i)]
+                 (if g
+                   (do
+                     (write-int (count g) out)
+                     (doseq [{:keys [code length symbol]} g]
+                       (write-int code out)
+                       (write-int length out)
+                       (.write out ^byte symbol)))
+                   (write-int 0 out)))))))
+
+; if we word-align the ints, I suspect we'll be in a better place.
+(defn- ht-coded-dictionary [codes ^java.io.ByteArrayOutputStream out]
+  (write-int (count codes) out)
+  (doseq [{:keys [code length]} codes]
+            (write-int code out)
+            (write-int length out))
+  (doseq [{:keys [symbol]} codes]
+            (.write out ^byte symbol))
+  (dotimes [i (rem (- 4 (rem (count codes) 4)) 4)] ; extend to word boundary
+    (.write out 0)))
+
+
+(comment
+  (defn- make-ht-codes
+    ([tree] (make-ht-codes tree []))
+    ([tree codes]
+     (if-let [sym (:symbol tree)]
+       [{:symbol sym :codes (apply str codes)}]
+       (concat
+         (make-ht-codes (:left tree) (conj codes \0))
+         (make-ht-codes (:right tree) (conj codes \1))))))
+
+  (let [freqs {\d 17 \a 12 \z 2 \c 10 \b 5}]
+    (->> freqs
+         build-ht-tree
+         make-ht-codes)))
+
+(comment
+  (let [freqs {\d 17 \a 12 \z 2 \c 10 \b 5}]
+    (->> freqs
+         build-ht-tree
+         make-ht-codes
+         ht-dictionary
+         display-dictionary
+         )))
+
+; group huffman tree leaves by length from root
+(defn- find-depth
+    ([tree] (find-depth [tree] 0 []))
+    ([nodes depth acc]
+     (if (seq nodes)
+         (let [{terminals true inner false} (group-by #(contains? % :symbol) nodes)
+               children (mapcat #(-> [(:left %) (:right %)]) inner)]
+             (recur children
+                    (inc depth)
+                    (if terminals (conj acc {:length depth :symbols terminals}) acc)))
+         acc)))
+
+; Compute canonical codes for tree leaves. This isn't a simple 'map' call
+; because we need the 'code' and 'depth' context for each successive leaf depth.
+(defn- make-codes
+    ([groups] (make-codes groups 0 (:length (first groups)) (transient [])))
+    ([groups code depth0 acc]
+     (if-let [group (first groups)]
+         (let [{depth1 :length nodes :symbols} group
+               nodes (sort-by :symbol nodes)
+               start (bit-shift-left code (- depth1 depth0))]
+             (recur
+                 (rest groups)
+                 (+ start (count nodes))
+                 depth1
+                 (conj! acc
+                        (assoc group
+                               :length depth1
+                               :symbols (map #(assoc %1 :code %2)
+                                             nodes
+                                             (drop start (range))))))) ; XXX this is weird. Why don't we pass 'start' to 'range'?
+         (persistent! acc))))
+
+; build the huffman encoding
+(defn build [items]
+  (->> items byte-freqs build-tree find-depth make-codes))
+
+; Build a hash for encoding the text
+(defn dictionary [groups]
+    (into {}
+          (mapcat (fn [group]
+                      (let [{:keys [length symbols]} group]
+                          (map #(-> [(:symbol %) (assoc % :length length)]) symbols)))
+                  groups)))
+
+(comment
+(defn spy [msg x]
+  (println msg x)
+  x))
+
+; Return the compactly-encoded canonical dictionary
+; len count, lens, bytes
+(defn coded-dictionary [groups ^java.io.ByteArrayOutputStream out]
+  (let [len-counts (into {} (map #(-> [(% :length) (count (% :symbols))]) groups))
+        m (apply max (keys len-counts))]
+    (write-int m out)
+    (doseq [c (map #(get len-counts % 0) (range 1 (inc m)))]
+      (write-int c out))
+    (let [symbols (mapcat #(map :symbol (:symbols %)) groups)]
+      (doseq [^byte b symbols]
+        (.write out b))
+      ; XXX this is probably the wrong place for this, since the input
+      ; buffer is passed in.
+      (dotimes [i (rem (- 4 (rem (count symbols) 4)) 4)] ; extend to word boundary
+        (.write out 0)))))
+
+; This is surprisingly complex. We're packing bits into bytes,
+; which requires tracking the input and output positions independently,
+; emitting bytes when they're full, and zero-padding the last
+; partial byte.
+(set! *unchecked-math* true)
+(def masks (mapv #(- (bit-shift-left 1 %) 1) (range 9)))
+(defn encode-bytes [^java.io.ByteArrayOutputStream output dict text]
+    (let [codes (map #(get dict %) text)]
+        (when (seq codes)
+            (loop [codes codes
+                   code (first codes)
+                   out 0
+                   avail 8
+                   ^long remaining (:length code)]
+
+                (let [bits (if (< avail remaining) avail remaining)
+                      rs (- remaining bits)
+                      out (bit-or (bit-shift-left out bits)
+                                  (bit-and (masks bits) (bit-shift-right (:code code)
+                                                                         rs)))
+                      remaining (- remaining bits)
+                      avail (- avail bits)]
+                    (when (= avail 0)
+                        (.write output out))
+
+                    (if (= remaining 0)
+                        (if-let [codes (seq (rest codes))]
+                            (let [code (first codes)
+                                  remaining (:length code)]
+                                (if (= avail 0)
+                                    (recur codes code 0 8 remaining)
+                                    (recur codes code out avail remaining)))
+                            (.write output (bit-shift-left out avail)))
+                        (if (= avail 0)
+                            (recur codes code 0 8 remaining)
+                            (recur codes code out avail remaining))))))))
+(set! *unchecked-math* false)
+
+(defprotocol Encoder
+  (write-dictionary [this out])
+  (write [this out text]))
+
+(defrecord huffman [groups dictionary]
+  Encoder
+  (write-dictionary [this out] (coded-dictionary groups out))
+  (write [this out text] (encode-bytes out dictionary text)))
+
+(defrecord hu-tucker [codes dictionary]
+  Encoder
+  (write-dictionary [this out] (ht-coded-dictionary codes out))
+  (write [this out text] (encode-bytes out dictionary text)))
+
+(defn make-huffman [items]
+  (let [groups (build items)]
+    (->huffman groups (dictionary groups))))
+
+(defn make-hu-tucker [items]
+  (let [codes (->> items byte-freqs build-ht-tree make-ht-codes)]
+    (->hu-tucker codes (ht-dictionary codes))))
+
+; Really want a decode for the output buff.
+
+(defn- ^String toBinaryStr [n]
+    (.replace (format "%8s" (Integer/toBinaryString n)) " " "0"))
+
+(defn display-dictionary [dict]
+    (clojure.pprint/print-table
+      (map #(-> {:symbol (char (:symbol %))
+                 :code (.substring (toBinaryStr (:code %)) (- 8 (:length %)) 8)})
+           (sort-by :symbol (vals dict)))))
+
+(comment
+  (let [s (map #(.getBytes ^String %) ["foo" "bar" "baz" "one" "two" "three"])]
+        (display-dictionary (dictionary (build s))))
+  (let [s (map #(.getBytes ^String %) ["foo" "bar" "baz" "one" "two" "three" "zzzzzzz"])
+        huffman (build s)
+        dict (dictionary huffman)
+        encoded (encode-bytes dict (apply concat s))
+        ]
+    (display-dictionary dict)
+    [(count encoded) (into [] encoded)]))


Add unit test [#1571]

Add unit test [#1571]

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

--- backend/test/akvo/lumen/component/caddisfly_test.clj
+++ backend/test/akvo/lumen/component/caddisfly_test.clj
@@ -0,0 +1,18 @@
+(ns akvo.lumen.component.caddisfly-test
+  (:require [akvo.lumen.component.caddisfly :as c]
+            [clojure.test :refer :all]
+            [com.stuartsierra.component :as component]))
+
+(deftest component-versions-test
+  (testing "prod component version"
+    (let [caddisfly-prod (-> {:schema-uri "https://akvoflow-public.s3.amazonaws.com/caddisfly-tests.json"}
+                             c/caddisfly
+                             component/start)]
+      (is (= (-> caddisfly-prod :schema first val keys)
+             '(:name :uuid :brand :hasImage :results)))))
+  (testing "dev component version"
+    (let [caddisfly-dev (-> {:local-schema-uri "./caddisfly/tests-schema.json"}
+                            c/dev-caddisfly
+                            component/start)]
+      (is (= (-> caddisfly-dev :schema first val keys)
+             '(:name :uuid :brand :hasImage :results))))))


Refactoring

Refactoring

--- jvm-runner/src/clojure/codewars/runner/java.clj
+++ jvm-runner/src/clojure/codewars/runner/java.clj
@@ -1,7 +1,7 @@
 (ns codewars.runner
   (:require [codewars.runner :refer [run]]
             [clojure.java.io :as io]
-            [codewars.util :as util])
+            [codewars.util :refer [write-code!]])
   (:import [codewars.java TempDir]
            [java.net URLClassLoader]
            [javax.tools ToolProvider]
@@ -32,14 +32,17 @@
     (.addListener runner (CwRunListener.))
     (.run runner (into-array [fixture-class]))))

+(defn- file-names [files]
+  (for [{:keys [:file-name]} files
+        :when (not (nil? file-name))]
+    file-name))
+
 (defmethod solution-only "java"
   [{:keys [:setup :solution]}]
   (let [dir (TempDir/create "java")
-        setup (when (not (empty? setup)) (util/write-code! "java" dir setup))
-        solution (util/write-code! "java" dir solution)
-        files (for [{:keys [:file-name]} [setup solution]
-                    :when (not (nil? file-name))]
-                file-name)]
+        setup (when (not (empty? setup)) (write-code! "java" dir setup))
+        solution (write-code! "java" dir solution)
+        files (file-names [setup solution])]
     (apply compile! files)
     (-> solution
         :class-name
@@ -50,11 +53,9 @@
 (defmethod full-project "java"
   [{:keys [:fixture :setup :solution]}]
   (let [dir (TempDir/create "java")
-        fixture (util/write-code! "java" dir fixture)
-        setup (when (not (empty? setup)) (util/write-code! "java" dir setup))
-        solution (util/write-code! "java" dir solution)
-        files (for [{:keys [:file-name]} [fixture setup solution]
-                    :when (not (nil? file-name))]
-                file-name)]
+        fixture (write-code! "java" dir fixture)
+        setup (when (not (empty? setup)) (write-code! "java" dir setup))
+        solution (write-code! "java" dir solution)
+        files (file-names [fixture setup solution])]
     (apply compile! files)
     (->> fixture :class-name (load-class dir) run-junit-tests)))


Adding template

Adding template

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


insert-map-into-db

insert-map-into-db

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


Renamed project

Renamed project

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


Added a couple of simple conversation update tests

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

--- test/conversation_test.clj
+++ test/conversation_test.clj
@@ -0,0 +1,18 @@
+(ns conversation-test
+  (:require [clojure.test :refer :all]
+            [polismath.conversation :refer :all]
+            [polismath.named-matrix :refer :all]))
+
+
+(def rat-mat
+  (named-matrix [:a :b] [:x :y] [[1 0] [-1 1]]))
+
+
+(deftest init-conversation-test
+  (let [new-votes [{:pid :a, :tid :x, :vote 3}]]
+    (testing "should work on empty matrix"
+      (is (small-conv-update {:conv {:rating-mat (named-matrix)} :opts {} :votes new-votes})))
+    (testing "should work on an existing matrix"
+      (is (small-conv-update {:conv {:rating-mat rat-mat} :opts {} :votes new-votes})))))
+
+


Actually commiting now

Actually commiting now

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

--- src/databinder/subscription.clj
+++ src/databinder/subscription.clj
@@ -0,0 +1,173 @@
+(ns databinder.subscription
+  (:use
+   databinder.rdf)
+  (:require
+   [databinder.model :as m] ))
+
+(def test-schema
+  (m/to-statements (m/to-model "
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix : <http://logangilmour.com/data-binder#> .
+@prefix ex: <http://logangilmour.com/example-view#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+
+
+ex:test
+  :name \"test\";
+  :type :list;
+  :property ex:prop;
+  :keyfn \"(fn [x] (str x x))\";
+  :predicate ex:stupid.
+
+ex:prop
+  :name \"prop1\";
+  :predicate ex:rep;
+  :type :literal.
+
+")))
+
+(def test-statements
+  (m/to-statements (m/to-model "
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix : <http://logangilmour.com/data-binder#> .
+@prefix ex: <http://logangilmour.com/example-view#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+
+ex:one ex:stupid [ex:rep \"dumb\"].
+
+")))
+
+(def base
+  {"namebinding" {:down {"predicatebinding" "predicate"
+                         "typebinding" "type"
+                         "namebinding" "name"
+                         "propertybinding" "properties"
+                         "parentbinding" "parent"
+                         "reversebinding" "reverse"
+                         "keyfnbinding" "keyfn"
+                         }}
+   "typebinding" {:down {"predicatebinding" (bind :literal)
+                         "namebinding" (bind :literal)
+                         "typebinding" (bind :literal)
+                         "reversebinding" (bind :literal)
+                         "propertybinding" (bind :list)
+                         "parentbinding" (bind :list)
+                         "keyfnbinding" (bind :function)}}
+   "predicatebinding" {:down {"reversebinding" (bind :reverse)
+                              "typebinding" (bind :type)
+                              "frombinding" (bind :from)
+                              "tobinding" (bind :to)
+                              "namebinding" (bind :name)
+                              "predicatebinding" (bind :predicate)
+                              "propertybinding" (bind :property)
+                              "parentbinding" (bind :property)
+                              "keyfnbinding" (bind :keyfn)}
+                       :up {(bind :reverse) #{"reversebinding"}
+                            (bind :type) #{"typebinding"}
+                            (bind :from) #{"frombinding"}
+                            (bind :to) #{"tobinding"}
+                            (bind :name) #{"namebinding"}
+                            (bind :predicate) #{"predicatebinding"}
+                            (bind :property) #{"propertybinding"}
+                            (bind :keyfn) #{"keyfnbinding"}
+                            }}
+   "reversebinding" {:down {"parentbinding" "true"}
+                     :up {"true" #{"parentbinding"}}}
+   "propertybinding" {:down {"propertybinding" (sorted-map "reversebinding" "reversebinding"
+                                                           "namebinding" "namebinding"
+                                                           "typebinding" "typebinding"
+                                                           "predicatebinding" "predicatebinding"
+                                                           "propertybinding" "propertybinding"
+                                                           "keyfnbinding" "keyfnbinding"
+                                                           "parentbinding" "parentbinding"
+                                                           )}
+                      :up {"namebinding" #{"propertybinding"}
+                           "typebinding" #{"propertybinding"}
+                           "reversebinding" #{"propertybinding"}
+                           "predicatebinding" #{"propertybinding"}
+                           "keyfnbinding" #{"propertybinding"}
+                           "parentbinding" #{"propertybinding"}
+                           "propertybinding" #{"propertybinding"}
+                           }}})
+
+
+
+
+(def bootstrap
+  ((fn f []
+    {:predicate (bind :property)
+     :$id "propertybinding"
+     :type (bind :list)
+     :name "properties"
+     :properties (lazy-seq (list
+                            {:$id "predicatebinding" :predicate (bind :predicate) :type (bind :literal) :name "predicate" :$parents (lazy-seq (list (f)))}
+                            {:$id "reversebinding" :predicate (bind :reverse) :type (bind :literal) :name "reverse" :$parents (lazy-seq (list (f)))}
+                            {:$id "typebinding" :predicate (bind :type) :type (bind :literal) :name "type" :$parents (lazy-seq (list (f)))}
+                            {:$id "frombinding" :predicate (bind :from) :type (bind :literal) :name "from" :$parents (lazy-seq (list (f)))}
+                            {:$id "tobinding" :predicate (bind :to) :type (bind :literal) :name "to" :$parents (lazy-seq (list (f))) }
+                            {:$id "namebinding" :predicate (bind :name) :type (bind :literal) :name "name" :$parents (lazy-seq (list (f)))}
+                            {:$id "keyfnbinding" :predicate (bind :keyfn) :type (bind :function) :name "keyfn" :$parents (lazy-seq (list (f)))}
+                            (f)))
+     :$parents (lazy-seq (list (f)))})))
+
+(declare construct render)
+;; This will be the normalized edition - we are expecting a proper subject-predicate-object thing
+;; with reversals taken care of. Lazy evaluation should ensure we don't make big things, so
+;; calling render in here will be reasonable.
+
+
+(defn insert [sub statement]
+  (let [bindings (get-in sub ["predicatebinding" :up (:predicate statement)])]
+    (reduce (fn [tree binding]
+              (let [binding (construct sub binding bootstrap {})
+                    subject (if (:reverse binding) (:object statement) (:subject statement))
+                    object (if (:reverse binding) (:subject statement) (:object statement))]
+                (-> tree
+                    (update-in [(:$id binding) :down subject] #(if (= (:type binding) (bind :list))
+                                                                 (assoc (or % (sorted-map)) nil object)
+                                                                 object))
+                    (update-in [(:$id binding) :up object] #(conj (or % #{}) subject))))) sub bindings)))
+
+(defn batch [sub statements]
+  (reduce (fn [tree statement]
+            (insert tree statement))
+          sub
+          statements))
+
+(defn ss [] (batch (batch base test-schema) test-statements))
+
+
+(defn construct [sub node binding url-params]
+
+  (cond
+   (= (:type binding) (bind :literal))
+   node
+   (= (:type binding) (bind :function))
+   (eval (read-string node))
+   :default
+   (assoc
+       (into {} (map (fn [sub-binding]
+                       [(keyword (:name sub-binding)) (render sub node sub-binding url-params)])
+                     (:properties binding)))
+     :$id node
+     :$binding (:$id binding)
+     :$parents (map (fn [parent] (construct sub parent (first (:$parents binding)) url-params)) (get-in sub [(:$id (first (:$parents binding))) :up node]))
+     )))
+
+(defn render [sub node binding url-params]
+  (let
+      [prop (get-in sub [(:$id binding) :down node])]
+    (if prop
+      (if (= (:type binding) (bind :list))
+        (map (fn [sub-node] (construct sub sub-node binding url-params))
+             (let [from (if (:from binding) (get url-params (:from binding)))
+                   to (if (:to binding) (get url-params (:to binding)))]
+               (cond
+                (and from to) (map second (subseq prop >= from <= to))
+                from (map second (subseq prop >= from))
+                to (map second (subseq prop <= to))
+                :default (vals prop))))
+        (construct sub prop binding url-params)))))