port port port

port port port

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


transformarea starii in timp

transformarea starii in timp

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/kokosro/kokos-crawler.git/'


Allow project_count, member_count and team_ids for organization group

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


[TH] construct proper ocd-id for DC and set level to :state

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


Remove do

Remove do

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


Should not use unquote splicing

Should not use unquote splicing


Add problem64.clj

Add problem64.clj

error: pathspec 'euler_clojure/src/euler/problem64.clj' did not match any file(s) known to git

--- euler_clojure/src/euler/problem64.clj
+++ euler_clojure/src/euler/problem64.clj
@@ -0,0 +1,46 @@
+(ns euler.problem64
+  "https://projecteuler.net/problem=64
+
+  The first ten continued fraction representations of (irrational) square roots are:
+
+      sqrt(2)=[1;(2)]          period=1
+      sqrt(3)=[1;(1,2)]        period=2
+      sqrt(5)=[2;(4)]          period=1
+      sqrt(6)=[2;(2,4)]        period=2
+      sqrt(7)=[2;(1,1,1,4)]    period=4
+      sqrt(8)=[2;(1,4)]        period=2
+      sqrt(10)=[3;(6)]         period=1
+      sqrt(11)=[3;(3,6)]       period=2
+      sqrt(12)=[3;(2,6)]       period=2
+      sqrt(13)=[3;(1,1,1,1,6)] period=5
+
+  Exactly four continued fractions, for N <= 13, have an odd period. How many
+  continued fractions for N <= 10000 have an odd period?"
+  (:require [clojure.math.numeric-tower :as math]))
+
+(defn continued-fraction-sqrt [S]
+  ;; https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Continued_fraction_expansion
+  ;; Using variables S, m, d, a as in the URL above.
+  (let [root (math/sqrt S)]
+    (if (= root (math/floor root))
+      [root]
+      (loop [seen []
+             m 0
+             d 1
+             a (math/floor (math/sqrt S))]
+        (let [next-seen (conj seen {:m m, :d d, :a a})
+              next-m (- (* d a) m)
+              next-d (/ (- S (math/expt next-m 2)) d)
+              next-a (math/floor (/ (+ (math/floor (math/sqrt S)) next-m) next-d))]
+          ;; If the pattern repeats, return all the 'a' variables collected in order.
+          ;; Otherwise, continue the recursion.
+          (if (some #(= % {:m next-m, :d next-d, :a next-a}) next-seen)
+            (vec (for [x next-seen] (get x :a)))
+            (recur next-seen
+                   next-m
+                   next-d
+                   next-a)))))))
+
+(defn problem64 []
+  (let [cont-fracs (for [i (range 2 10001)] (continued-fraction-sqrt i))]
+    (count (filter #(odd? (count (rest %))) cont-fracs))))


[GREEN] You can save and retrieve moods

[GREEN] You can save and retrieve moods

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


ttable

ttable

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


CMR-5351: Added listener for Elasticsearch async results.

error: pathspec 'src/cmr/nlp/elastic/client/listener.clj' did not match any file(s) known to git

--- src/cmr/nlp/elastic/client/listener.clj
+++ src/cmr/nlp/elastic/client/listener.clj
@@ -0,0 +1,27 @@
+(ns cmr.nlp.elastic.client.listener
+  (:require
+   [cheshire.core :as json]
+   [taoensso.timbre :as log])
+  (:import
+   (java.lang String)
+   (org.elasticsearch.action.support.master AcknowledgedRequest
+                                            AcknowledgedResponse)
+   (org.elasticsearch.common.xcontent XContentType))
+  ;; XXX Once we need more than one class here, let's move :gen-class out of
+  ;;     the namespace and just use the macro
+  (:gen-class
+    :name cmr.nlp.elastic.client.listenerAckListener
+    :implements [org.elasticsearch.action.support.master.AcknowledgedRequest]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;   Implementation   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn -onResponse
+  [^AcknowledgedResponse response]
+  (log/info response))
+
+(defn -onFailure
+  [^Exception ex]
+  (log/error (.getMessage ex))
+  (log/trace ex))


update test to have referendum type "GP"

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


more notes

more notes

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


rewrite term-local

rewrite term-local


views: unit detail

views: unit detail

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


detail

detail

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


Abstract get-inner-message

Abstract get-inner-message

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


cosmetic changes to p12.clj

cosmetic changes to p12.clj

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


Use a fixed thread-pool by default for ning-client

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


first working take at leap year.

first working take at leap year.

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

--- clojure/leap/leap.clj
+++ clojure/leap/leap.clj
@@ -0,0 +1,9 @@
+(ns leap)
+
+(defn- divisible? [a b]
+  (= 0 (mod a b)))
+
+(defn leap-year? [yr]
+  (and (divisible? yr 4)
+       (or (not (divisible? yr 100))
+           (divisible? yr 400))))


Added ID to result items

Added ID to result items

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/kuona/kuona-collector-lib.git/'


Enable generative test

Enable generative test

And handle the case where an empty set of :alternate-hostnames results
in a noop for that attribute.

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


Adds numbered? and value-infix

Adds numbered? and value-infix

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

--- src/the_little_clojurian/chapter6.clj
+++ src/the_little_clojurian/chapter6.clj
@@ -0,0 +1,35 @@
+(ns the-little-clojurian.chapter6
+  (:require [clojure.test :refer :all]
+            [the-little-clojurian.chapter1 :refer :all]
+            [the-little-clojurian.chapter2 :refer :all]
+            [the-little-clojurian.chapter3 :refer :all]
+            [the-little-clojurian.chapter4 :refer :all]
+            [the-little-clojurian.chapter5 :refer :all]))
+
+(with-test
+  (def numbered?
+    (fn [aexp]
+      (cond (atom? aexp) (number? aexp)
+            :else (and (numbered? (car aexp))
+                       (numbered? (car (cdr (cdr aexp))))))))
+
+  (is (= (numbered? 1) true))
+  (is (= (numbered? 'a) false))
+  (is (= (numbered? '(3 + 1)) true))
+  (is (= (numbered? '(3 + (4 * 7))))))
+
+(with-test
+  (def value-infix
+    (fn [u]
+      (cond (atom? u) u
+            (eq? (car (cdr u)) '+) (+ (value-infix (car u))
+                                          (value-infix (car (cdr (cdr u)))))
+            (eq? (car (cdr u)) '*) (- (value-infix (car u))
+                                           (value-infix (car (cdr (cdr u)))))
+            :else (int (java.lang.Math/pow (value-infix (car u))
+                                           (value-infix (car (cdr (cdr u)))))))))
+
+  (is (= (value-infix 13) 13))
+  (is (= (value-infix '(1 + 3)) 4))
+  (is (= (value-infix '(1 + (3 pow 4))) 82)))
+


adding template tests

adding template tests

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

--- test/celestial/features/templates.clj
+++ test/celestial/features/templates.clj
@@ -0,0 +1,16 @@
+(ns celestial.features.templates
+ (:require
+    [celestial.security :refer (set-user current-user)]
+    [celestial.persistency.systems :as s]
+    [celestial.fixtures.core :refer (is-type? with-defaults with-conf)]
+    [celestial.fixtures.populate :refer (populate-all)]
+    [celestial.fixtures.data :refer (small-redis)])
+ (:use midje.sweet))
+
+(with-conf
+  (with-state-changes [(before :facts (set-user {:username "admin"} (populate-all)))]
+   (fact "basic template persistency" :integration :redis :templates
+     (s/add-template small-redis) => 1
+     (s/get-template 1) => (contains {:type "redis"})
+     )
+   ))


tweak team page texts

tweak team page texts

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/clojurecup/cc2014-frontend.git/'


[WM EN] merge in common notification identifiers

notification-works should always add :notification-type and :medium identifiers to scheduled messages.

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


Remove println

Remove println

--- src/clj_http/core2.clj
+++ src/clj_http/core2.clj
@@ -61,7 +61,6 @@
     (DefaultRedirectStrategy/INSTANCE)))

 (defn http-client [conn-mgr redirect-strategy]
-  (println :RS (get-redirect-strategy redirect-strategy))
   (-> (HttpClients/custom)
       (.setConnectionManager conn-mgr)
       (.setRedirectStrategy (get-redirect-strategy redirect-strategy))


Minor tweaks to manual coaching process.

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


Ensure string representation of series UUID

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


make sender (from:) for system emails configurable in site admin section.

--- src/metabase/email.clj
+++ src/metabase/email.clj
@@ -12,11 +12,9 @@
 ;; ## CONFIG

 (defsetting mandrill-api-key "API key for Mandrill.")
+(defsetting email-from-address "Email address used as the sender of system notifications.")
+(defsetting email-from-name "Name used as the sender of the system notifications. (optional)")

-(def ^:private message-sender
-  "The `from` field for messages sent by the Mandrill API."
-  {:email "mailman@metabase.com"
-   :name "Metabase MetaMailMan"})

 ;; ## PUBLIC INTERFACE

@@ -56,8 +54,8 @@
 (defn- api-post-messages-send
   "Make a `POST messages/send` call to the Mandrill API."
   [& {:as kwargs}]
-  (let [defaults {:from_email (message-sender :email)
-                  :from_name (message-sender :name)}]
+  (let [defaults {:from_email (email-from-address)
+                  :from_name (email-from-name)}]
     (= (:status (api-post "messages/send"
                           :body {:message (merge defaults kwargs)}))
        200)))


start new challange

start new challange

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

--- src/4clojure/sequence_reductions.clj
+++ src/4clojure/sequence_reductions.clj
@@ -0,0 +1,17 @@
+;; Sequence Reductions
+;; http://www.4clojure.com/problem/60
+;; Difficulty:	Medium
+;; Topics:	seqs core-functions
+
+
+;; Write a function which behaves like reduce, but returns each intermediate value of the reduction. Your function must accept either two or three arguments, and the return sequence must be lazy.
+
+(defn __
+  ([a b] true)
+  ([a b c] true))
+
+(= (take 5 (__ + (range))) [0 1 3 6 10])
+
+(= (__ conj [1] [2 3 4]) [[1] [1 2] [1 2 3] [1 2 3 4]])
+
+(= (last (__ * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120)


Clojure solution to 13

Clojure solution to 13

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

--- euler013/euler013.clj
+++ euler013/euler013.clj
@@ -0,0 +1,9 @@
+(use 'clojure.java.io)
+
+(defn euler013 [lines]
+  (-> (reduce + (map biginteger lines))
+      (str)
+      (.substring 0 10)))
+
+(with-open [rdr (reader "numbers.txt")]
+  (println (euler013 (line-seq rdr))))


Add Ring live reload middleware

Add Ring live reload middleware

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


Add on-enter submit in 'create list' textinput

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


Also leave tuple type to log when task is null

--- storm-core/src/clj/backtype/storm/daemon/worker.clj
+++ storm-core/src/clj/backtype/storm/daemon/worker.clj
@@ -135,7 +135,7 @@
                     (let [remote (.get remoteMap node+port)]
                       (if (not-nil? task)
                         (.add remote (TaskMessage. task (.serialize serializer tuple)))
-                        (log-warn "Can't transfer tuple - task value is null. tuple information: " tuple))
+                        (log-warn "Can't transfer tuple - task value is null. tuple type: " (type tuple) " and information: " tuple))
                      ))))
                 (local-transfer local)
                 (disruptor/publish transfer-queue remoteMap)


cleanup

cleanup

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


Updated core.clj

Updated core.clj

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


First version of Jenkins API module

First version of Jenkins API module

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

--- src/emender_jenkins/jenkins_api.clj
+++ src/emender_jenkins/jenkins_api.clj
@@ -0,0 +1,17 @@
+(ns emender-jenkins.jenkins-api)
+
+(require '[clojure.xml       :as xml])
+(require '[clojure.zip       :as zip])
+
+(require '[clojure.data.json :as json])
+(require '[clj-http.client   :as http-client])
+
+(defn read-list-of-all-jobs
+    [jenkins-url job-list-part]
+    (let [all-jobs-url (str jenkins-url job-list-part)]
+        (println "Using the following URL to retrieve all Jenkins jobs: " all-jobs-url)
+        (let [data (json/read-str (slurp all-jobs-url))]
+            (if data
+                (get data "jobs")
+                nil))))
+


More notes

More notes

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


sanitize configuration

sanitize configuration

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


system workflow parser added

system workflow parser added

error: pathspec 'src/clj/hellhound/system/workflow.clj' did not match any file(s) known to git

--- src/clj/hellhound/system/workflow.clj
+++ src/clj/hellhound/system/workflow.clj
@@ -0,0 +1,21 @@
+(ns hellhound.system.workflow
+  "TODO"
+  (:import (clojure.lang IPersistentMap
+                         PersistentVector)))
+
+(defn setup
+  [system]
+  (println "SYSTEM MAP" system))
+
+
+(defn ^PersistentVector walk-graph
+  [^IPersistentMap parsed-map ^PersistentVector pair]
+  (assoc parsed-map
+         (first pair)
+         (conj (get parsed-map (first pair)) (second pair))))
+
+(defn ^IPersistentMap workflow-map
+  "Parse the workflow graph and returns a hashmap which keys
+  are the components name and the values are inputs for that component."
+  [^IPersistentMap system-map]
+  (reduce walk-graph {} (:workflow system-map)))


Testing for simplebd

Testing for simplebd

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

--- test/beat_detector/simplebd_test.clj
+++ test/beat_detector/simplebd_test.clj
@@ -0,0 +1,23 @@
+(ns beat-detector.simplebd-test
+  (:require [clojure.test :refer :all])
+  (:use [beat-detector.simplebd]))
+
+(deftest sound-energy-test
+  (is (= (sound-energy [[3 5] [4 12]]) (+ 25 169))))
+
+(def ^:dynamic *raw* '(([1 2 3 4] [0 0 0 0]) ([5 6 7 8] [0 0 0 0])))
+
+(deftest gen-energy-buffer-test
+  (testing "general"
+    (is (= (gen-energy-buffer *raw* 2 4)
+           [5 25])))
+  (testing "when history is longer than raw"
+    (is (= (gen-energy-buffer *raw* 3 9)
+           [14 77 113])))
+  (testing "when instance is longer than raw"
+    (is (= (gen-energy-buffer *raw* 9 9)
+           [204]))))
+
+(deftest next-energy-buffer-test
+  (testing "general"
+    (is (= (next-energy-buffer [0 1] *raw* 2) [1 5]))))


update services query to query unarchived services

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


Fix small indentation issue

Fix small indentation 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/democracyworks/user-http-api.git/'


Made utility functions private.

Made utility functions private.


tightened up printing errors

tightened up printing errors

--- sidecar/src/figwheel_sidecar/type_check.clj
+++ sidecar/src/figwheel_sidecar/type_check.clj
@@ -340,7 +340,6 @@
      :correct-paths (get-paths-for-type root-type typ)
      :confidence :high}))

-
 (defn misspelled-misplaced-key [root-type parent-type bad-key value]
   (for [[ky _ [other-parent-type _ typ]] (*schema-rules* :-)
         :when (and
@@ -384,11 +383,14 @@
   (mapcat (fn [{:keys [key type-sig value] :as error}]
             (let [typ (first type-sig)
                   err' (unknown-key-error-help root-type typ key value)]
-              (map #(assoc %
+              (if (empty? err')
+                [(assoc error :Error (:Error-type error))]
+                (map #(assoc %
                            :path (:path error)
                            :value (:value error)
                            :type-sig (:type-sig error)
-                           :orig-error error) err')))
+                           :orig-error error) err'))
+              ))
         errors))

 (defn type-check [root-type value]
@@ -406,7 +408,13 @@
     (doall (type-check 'Figwheel {:figheel true
                                   :cljsbuild 5})))

+
+(contains? (set [1 2 3]) 3)
 ;; error messages
+#_(pp)
+(defn parent-is-sequence? [{:keys [type-sig path]}]
+  (and (integer? (first path))
+       ((set (map last (*schema-rules* [:=> (second type-sig)]))) :SEQQ)))

 (defmulti predicate-explain (fn [pred _] pred))

@@ -422,6 +430,12 @@
 (defmethod explain-predicate-failure :SEQQ [pred value] "Sequence")

 (defmulti error-help-message :Error)
+
+(defmethod error-help-message :unknown-key [{:keys [path key]}]
+  [:group "Found unrecognized key "
+   (color (pr-str key) :red)
+   " at path "
+   (color (pr-str (vec (reverse (rest path)))) :bold)])

 (defmethod error-help-message :missing-required-key [{:keys [path key]}]
   [:group "Missing required key "
@@ -432,21 +446,32 @@

 #_(pp)

-(defmethod error-help-message :failed-predicate [{:keys [path not value]}]
-  [:group "The key "
-   (color (pr-str (first path)) :bold)
-   " has the wrong value. It should be a "
-   (color (explain-predicate-failure not value) :green)])
-
-(defmethod error-help-message :combined-failed-predicate [{:keys [path not value]}]
-  [:group "The key "
-   (color (pr-str (first path))
-          :bold)
-   " has the wrong value. It can one of the following: "
-   (cons :span (interpose ", "
-                      (map #(color % :green)
-                           (map #(explain-predicate-failure % value) (butlast not)))))
-   " or " (color (pr-str (last not)) :green)])
+(defmethod error-help-message :failed-predicate [{:keys [path not value type-sig] :as error}]
+  (concat
+   (if (parent-is-sequence? error)
+     [:group "The sequence at key " (color (pr-str (second path)) :bold)
+      " contains bad value " (color (pr-str value) :red) ". "]
+     [:group "The key "
+      (color (pr-str (first path)) :bold)
+      " has the wrong value. "])
+   ["It should be a "
+    (color (explain-predicate-failure not value) :green)]))
+
+(defmethod error-help-message :combined-failed-predicate [{:keys [path not value] :as error}]
+  (concat
+   (if (parent-is-sequence? error)
+     [:group "The sequence at key "  (format-key (second path) :bold)
+     " contains bad value " (color (pr-str value) :red) ". "]
+     [:group "The key "
+      (format-key (first path) :bold)
+      " has the wrong value. "
+      ])
+   [
+    "It can one of the following: "
+    (cons :span (interpose ", "
+                           (map #(color % :green)
+                                (map #(explain-predicate-failure % value) (butlast not)))))
+    " or " (color (pr-str (last not)) :green)]))

 #_(error-help-message {:Error :combined-failed-predicate :path [:boolean] :value 5 :not [true false]})

@@ -459,6 +484,21 @@
    " is spelled wrong. It should be "
    (color (pr-str correction) :green)])

+(defmethod error-help-message :misplaced-key [{:keys [key correct-paths]}]
+  [:group
+   "The key "
+   (color (pr-str key) :bold)
+   " is most likely in the wrong place in your config."])
+
+(defmethod error-help-message :misspelled-misplaced-key
+  [{:keys [key correction correct-paths]}]
+  [:group
+   "The key "
+   (color (pr-str key) :bold)
+   " is spelled wrong and is mostly likely in the wrong position."
+   :line " It should be probably be spelled "
+   (color (pr-str correction) :green)]
+  )
 ;; printing

 (defn print-path [[x & xs] leaf-node edn]
@@ -484,7 +524,7 @@
     :break
     :break
     [:nest 2
-     (print-path (reverse (rest path))
+     (print-path (reverse (if (parent-is-sequence? error) (rest (rest path)) (rest path)))
                  leaf-node
                  orig-config)]
     :break
@@ -495,12 +535,47 @@
   ([error leaf]
    (print-path-error error leaf "")))

+
+(defn print-wrong-path-error
+  ([{:keys [path orig-config correction path correct-paths value] :as error} leaf-node document]
+   [:group
+    "------- Figwheel Configuration Error -------"
+    :break
+    (error-help-message error)
+    :break
+    :break
+    [:nest 2
+     (print-path (reverse (rest path))
+                 leaf-node
+                 orig-config)]
+    :break
+    [:group "It should probably be placed here:"]
+    :break
+    :break
+    [:nest 2
+     (let [k (or correction (first path))]
+       (print-path (first correct-paths)
+                   [:group
+                    (color (pr-str k) :green)
+                    " "
+                    [:nest (+ (count (pr-str k)) 2)
+                     (summerize-value value)]
+                    :line]
+                   orig-config))]
+    :break
+    :break
+    document
+    :line
+    ])
+  ([error leaf]
+   (print-path-error error leaf "")))
+
+#_(pp)
+
 ;; Todos

-;; add documentation
-
-;; cover all current errors with messages
-;; handle printing vector errors
+;; handle printing :correct-path with knowledge of available config
+;;     esp. for bad path errors

 ;; move current enum functions into type system in config_validation
 ;; look at adding smart documentation fns
@@ -568,10 +643,65 @@
        :break]
       "")))

+(defn summerize-coll [open close fn v]
+  (concat [:group open " "]
+          (take 2 (map fn v))
+          [[:nest 2 "... " close]]))
+
+(declare summerize-value)
+
+(def summerize-map (partial summerize-coll "{" "}"
+                            (fn [[k v']] [:nest 2 (summerize-value k) " ..."  #_(summerize-value v') :line])))
+
+(defn summer-seq [v] [:group (summerize-value v) :line])
+(def summerize-vec (partial summerize-coll "[" "]" summer-seq))
+(def summerize-seq (partial summerize-coll "(" ")" summer-seq))
+(def summerize-set (partial summerize-coll "#{" "}" summer-seq))
+
+
+(summerize-map {:asdf 4 :asd 6})
+
+(defn summerize-value [v]
+  (cond
+    (map? v) (summerize-map v)
+    (vector? v) (summerize-vec v)
+    (set? v) (summerize-set v)
+    (seq? v) (summerize-seq v)
+    :else (pr-str v)))
+
 #_ (pp)

+(defn format-key
+  ([k] (pr-str k))
+  ([k colr] (color (format-key k) colr)))
+
+(defn format-value
+  ([value] (summerize-value value))
+  ([value colr] (color (format-value value) colr)))
+
+(defn format-key-value [k v message]
+  [:group
+   k
+   " "
+   [:nest (+ (count (pr-str key)) 2)
+    v]
+   [:line " <- "]
+   (color message :underline :magenta)
+   :line])
+
+
+
 (defmulti print-error :Error)

+(defmethod print-error :unknown-key [{:keys [key value path type-sig] :as error}]
+  (pprint-document (print-path-error error
+                                     (format-key-value
+                                      (format-key key :red)
+                                      (format-value value)
+                                      (str "^ key " (pr-str key) " not recognized")))
+                   {:width 40}))
+
+(pp)
 (defmethod print-error :missing-required-key [{:keys [path value type-sig] :as error}]
   (pprint-document (print-path-error error
                                      [:group
@@ -586,47 +716,70 @@

 #_(pp)

-(defmethod print-error :failed-predicate [{:keys [path value type-sig] :as error}]
-  (pprint-document (print-path-error error
-                                     [:group
-                                      (color (pr-str (first path)) :bold)
-                                      " "
-                                      (color (with-out-str
-                                               (print value))
-                                             :red)
-                                      [:line " <- "]
-                                      (color (str "^ key " (pr-str (first path)) " has wrong value")
-                                             :underline :magenta)
-                                      :line]
-                                     (document-key (first (rest type-sig)) (first path)))
+
+
+(defn failed-predicate [{:keys [path value type-sig orig-config] :as error}]
+  (if (parent-is-sequence? error)
+    (let [orig-config-seq (get-in orig-config (reverse (rest path)))]
+      (pprint-document (print-path-error error
+                                         [:nest 2
+
+                                          (concat
+                                           [:group (format-key (second path))  " [ " ]
+                                           [[:nest (+ 3 (count (str (second path))))
+
+                                             (cons :group
+                                                   (interpose :line (map-indexed
+                                                             #(if (= (first path) %1)
+                                                                (color (pr-str %2) :red)
+                                                                (pr-str %2))
+                                                             orig-config-seq)
+                                                      ))]]
+                                           #_(format-value value :red)
+                                           [" ] "])]
+                                         (document-key (first (rest (rest type-sig))) (second path)))
+                       {:width 40}))
+    (pprint-document (print-path-error error
+                                       (format-key-value
+                                        (format-key (first path) :bold)
+                                        (format-value value :red)
+                                        (str "^ key " (pr-str (first path)) " has wrong value"))
+                                       (document-key (first (rest type-sig)) (first path)))
+                     {:width 40})
+    )
+  )
+
+(defmethod print-error :failed-predicate [error] (failed-predicate error))
+(defmethod print-error :combined-failed-predicate [error] (failed-predicate error))
+
+#_(pp)
+(defmethod print-error :misplaced-key [{:keys [key correct-paths correct-type orig-error orig-config type-sig] :as error}]
+  (pprint-document (print-wrong-path-error
+                    error
+                    (format-key-value
+                     (format-key key :red)
+                     (format-value (:value orig-error))
+                     (str "^ key " (format-key key) " is on the wrong path"))
+                    (document-key (first correct-type) key))
                    {:width 40}))

-(defmethod print-error :combined-failed-predicate [{:keys [path value type-sig] :as error}]
-  (pprint-document (print-path-error error
-                                     [:group
-                                      (color (pr-str (first path)) :bold)
-                                      " "
-                                      (color (with-out-str
-                                               (print value))
-                                             :red)
-                                      [:line " <- "]
-                                      (color (str "^ key " (pr-str (first path)) " has wrong value")
-                                             :underline :magenta)
-                                      :line]
-                                     (document-key (first (rest type-sig)) (first path)))
+(defmethod print-error :misspelled-misplaced-key [{:keys [key correct-paths correction correct-type orig-error orig-config type-sig] :as error}]
+  (pprint-document (print-wrong-path-error
+                    error
+                    (format-key-value
+                     (format-key key :red)
+                     (format-value (:value orig-error))
+                     (str "^ key " (format-key key) " is mispelled and on the wrong path"))
+                    (document-key (first correct-type) correction))
                    {:width 40}))
+

 (defmethod print-error :misspelled-key [{:keys [key correction orig-error orig-config type-sig] :as error}]
   (pprint-document (print-path-error error
-                                     [:group
-                                      (color (pr-str key) :red)
-                                      " "
-                                      (with-out-str
-                                               (print (:value orig-error)))
-                                      [:line " <- "]
-                                      (color (str "^ key " (pr-str key) " is spelled wrong")
-                                             :underline :magenta)
-                                      :line]
+                                     (format-key-value
+                                      (format-key key :red)
+                                      (format-value (:value orig-error))
+                                      (str "^ key " (pr-str key) " is spelled wrong"))
                                      (document-key (first type-sig) correction))
                    {:width 40}))

@@ -637,7 +790,8 @@

 (defn pp []
   (with-schema (index-spec
-                (spec 'RootMap {:figwheel (ref-schema 'FigOpts)})
+                (spec 'RootMap {:figwheel (ref-schema 'FigOpts)
+                                :crappers [(ref-schema 'HeyOpts)]})

                 (or-spec 'Boolean
                          true
@@ -649,25 +803,47 @@
                      {:five "What happens with the number 5"
                       :string "A String that describes a string"
                       :magical "How magical do you want to make this?"
+                      :what    "Something what like is something goodness"
                       :boolean "A boolean that tells us whether bolleans are allowed"})
                 (spec 'FigOpts
                       {:five 5
                        :boolean (ref-schema 'Boolean)
                        :other   (ref-schema 'OtherType)
                        :string   string?
+                       :what    [(ref-schema 'Boolean)] #_[string?]
                        :magical "asdf"})
+                (spec 'HeyOpts
+                      {:whaaa 5
+                       :yeah 6})
                 (doc 'OtherType "Options that describe the behavior of Other types"
                      {:master "How amant things should we master"
                       :faster "The number of faster things"})
                 (requires-keys 'OtherType :faster)
                 )

+
+  #_ (doall  (type-check 'RootMap {:figwheel {:five 6
+                                            :string 'asdf
+                                            :boolean 4
+                                            :other {:master 4}
+                                            :magicl "asdf"}
+                                 :willywonka 4}))

   (print-errors-test {:figwheel {:five 6
                                  :string 'asdf
                                  :boolean 4
+                                 :what ["resources/public/js/out"
+                                        "resources/public/js/out"
+                                        "resources/public/js/out"]
                                  :other {:master 4}
-                                 :magicl "asdf"}})
+                                 :magicl "asdf"}
+                      #_:crappers #_[{:whaaa 5
+                                  :yeah 6}
+                                 {:whaaa 5
+                                  :yeahs 6}]
+                      :magicl "asdf"
+
+                      :willywonka 4})

   #_(doall (document-key 'FigOpts :other))


improved key prefix

improved key prefix

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/wilkerlucio/youtube-looper.git/'


Adds the information model to the repo.

Adds the information model to the repo.

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

--- doc/information_model.clj
+++ doc/information_model.clj
@@ -0,0 +1,351 @@
+{:catalog-entry
+ {:onyx/name
+  {:doc "The name of the task that represents this catalog entry. Must correspond to a keyword in the workflow associated with this catalog."
+   :type :keyword
+   :choices :any
+   :restrictions ["Must be unique across all catalog entries."
+                  "Value cannot be `:none`."
+                  "Value cannot be `:all`."]
+   :optional? false}
+
+  :onyx/type
+  {:doc "The role that this task performs. `:input` reads data. `:function` applies a transformation. `:output` writes data."
+   :type :keyword
+   :choices [:input :function :output]
+   :optional? false}
+
+  :onyx/batch-size
+  {:doc "The number of segments a peer will wait to read before processing them all in a batch for this task. Segments will be processed when either `:onyx/batch-size` segments have been received at this peer, or `:onyx/batch-timeout` milliseconds have passed - whichever comes first. This is a knob that is used to tune throughput and latency, and it goes hand-in-hand with `:onyx/batch-timeout`."
+   :type :integer
+   :restrictions ["Value must be greater than 0."]
+   :optional? false}
+
+  :onyx/batch-timeout
+  {:doc "The number of milliseconds a peer will wait to read more segments before processing them all in a batch for this task. Segments will be processe when either `:onyx/batch-timeout` milliseconds passed, or `:onyx/batch-size` segments have been read - whichever comes first. This is a knob that is used to tune throughput and latency, and it goes hand-in-hand with `:onyx/batch-size`."
+   :type :integer
+   :unit :milliseconds
+   :restrictions ["Value must be greater than 0."]
+   :default 1000
+   :optional? true}
+
+  :onyx/doc
+  {:doc "A docstring for this catalog entry."
+   :type :string
+   :optional? true}
+
+  :onyx/max-peers
+  {:doc "The maximum number of peers that will ever be assigned to this task concurrently."
+   :type :integer
+   :restrictions ["Value must be greater than 0."]
+   :optional? true}
+
+  :onyx/min-peers
+  {:doc "The minimum number of peers that will be concurrently assigned to execute this task before it begins. If the number of peers working on this task falls below its initial count due to failure or planned departure, the choice of `:onyx/flux-policy` defines the strategy for what to do."
+   :type :integer
+   :restrictions ["Value must be greater than 0."
+                  "`:onyx/flux-policy` must also be defined in this catalog entry."]
+   :optional? true}
+
+  :onyx/n-peers
+  {:doc "A convenience parameter which expands to `:onyx/min-peers` and `:onyx/max-peers` set to the same value. This is useful if you want to specify exactly how many peers should concurrently execute this task - no more, and no less."
+   :type :integer
+   :restrictions ["Value must be greater than 0."
+                  "`:onyx/min-peers` cannot also be defined for this catalog entry."
+                  "`:onyx/max-peers` cannot also be defined for this catalog entry."
+                  "`:onyx/flux-policy` must also be defined in this catalog entry."]
+   :optional? true}
+
+  :onyx/language
+  {:doc "Designates the language that the function denoted by `:onyx/fn` is implemented in."
+   :type :keyword
+   :choices [:clojure :java]
+   :default :clojure
+   :optional? true}
+
+  :onyx/restart-pred-fn
+  {:doc "A fully-qualified namespaced keyword pointing to function which takes an exception as a parameter, returning a boolean indicating whether the peer that threw this exception should restart its task."
+   :type :keyword
+   :choices :any
+   :restrictions ["Must resolve to a function on the classpath at runtime."]
+   :optional? true}
+
+  :onyx/medium
+  {:doc "Denotes the kind of input or output communication or storage that is being read from or written to (e.g. `:kafka` or `:web-socket`). This is currently does not affect any functionality, and is reserved for the future."
+   :type :keyword
+   :choices :any
+   :required-when ["`:onyx/type` is set to `:input`"
+                   "`:onyx/type` is set to `:output`"]}
+
+  :onyx/plugin
+  {:doc "When `:onyx/language` is set to `:clojure`, this is a fully qualified, namespaced keyword pointing to a function that takes the Event map and returns a Record implementing the Plugin interfaces. When `:onyx/language` is set to `:java`, this is a keyword pointing to a Java class that is constructed with the Event map. This class must implement the interoperability interfaces."
+   :type :keyword
+   :choices :any
+   :required-when ["`:onyx/type` is set to `:input`"
+                   "`:onyx/type` is set to `:output`"]}
+
+  :onyx/pending-timeout
+  {:doc "The duration of time, in milliseconds, that a segment that enters an input task has to be fully acknowledged and processed. That is, this segment, and any subsequent segments that it creates in downstream tasks, must be fully processed before this timeout occurs. If the segment is not fully processed, it will automatically be retried."
+   :type :integer
+   :default 60000
+   :units :milliseconds
+   :optionally-allowed-when ["`:onyx/type` is set to `:input`"
+                             "Value must be greater than 0."]}
+
+  :onyx/input-retry-timeout
+  {:doc "The duration of time, in milliseconds, that the input task goes dormant between checking which segments should expire from its internal pending pool. When segments expire, they are automatically retried."
+   :type :integer
+   :default 1000
+   :units :milliseconds
+   :optionally-allowed-when ["`:onyx/type` is set to `:input`"
+                             "Value must be greater than 0."]}
+
+  :onyx/max-pending
+  {:doc "The maximum number of segments that a peer executing an input task will allow in its internal pending message pool. If this pool is filled to capacity, it will not accept new segments - exhibiting backpressure to upstream message produces."
+   :type :integer
+   :default 10000
+   :units :segments
+   :optionally-allowed-when ["`:onyx/type` is set to `:input`"
+                             "Value must be greater than 0."]}
+
+  :onyx/fn
+  {:doc "A fully qualified, namespaced keyword that points to a function on the classpath. This function takes at least one argument - an incoming segment, and returns either a segment or a vector of segments. This function may not return `nil`. This function can be parameterized further through a variety of techniques."
+   :type :keyword
+   :required-when ["`:onyx/type` is set to `:function`"]
+   :optionally-allowed-when ["`:onyx/type` is set to `:input`"
+                             "`:onyx/type` is set to `:output`"]}
+
+  :onyx/group-by-key
+  {:doc "The key, or vector of keys, to group incoming segments by. Keys that hash to the same value will always be sent to the same virtual peer."
+   :type [:any [:any]]
+   :optionally-allowed-when ["`:onyx/type` is set to `:function`"]
+   :restrictions ["Cannot be defined when `:onyx/group-by-fn` is defined."]}
+
+  :onyx/group-by-fn
+  {:doc "A fully qualified, namespaced keyword that points to a function on the classpath. This function takes a single argument, a segment, as a parameter. The value that the function returns will be hashed. Values that hash to the same value will always be sent to the same virtual peer."
+   :type :keyword
+   :optionally-allowed-when ["`:onyx/type` is set to `:function`"]
+   :restrictions ["Cannot be defined when `:onyx/group-by-key` is defined."]}
+
+  :onyx/bulk?
+  {:doc "Boolean value indicating whether the function in this catalog entry denoted by `:onyx/fn` should take a single segment, or the entire batch of segments that were read as a parameter. When set to `true`, this function's return value is ignored. The segments are identically propogated to the downstream tasks."
+   :type :boolean
+   :default false
+   :optionally-allowed-when ["`:onyx/type` is set to `:function`"]}
+
+
+  :onyx/flux-policy
+  {:doc "The policy that should be used when a task with grouping enabled loses a peer. Losing a peer means that the consistent hashing used to pin the same hashed values to the same peers will be altered. Using the `:kill` flux policy will kill the job. This is useful for jobs that cannot tolerate an altered hashing strategy. Using `:continue` will allow the job to continue running. With `:kill` and `:continue`, new peers will never be added to this job. The final policy is `:recover`, which is like `:continue`, but will allow peers to be added back to this job to meet the `:onyx/min-peers` number of peers working on this task concurrently."
+   :type :keyword
+   :choices [:kill :continue :recover]
+   :optionally-allowed-when ["`:onyx/type` is set to `:function`"
+                             "`:onyx/group-by-key` or `:onyx/group-by-fn` is set."]}
+
+  :onyx/uniqueness-key
+  {:doc "The key of incoming segments that indicates global uniqueness. This is used by the Windowing feature to detect duplicated processing of segments. An example of this would be an `:id` key for segments representing users, assuming `:id` is globally unique in your system. An example of a bad uniqueness-key would be `:first-name` as two or more users may have their first names in common."
+   :type :any
+   :required-when ["A Window is defined on this task."]}}
+
+ :flow-conditions-entry
+ {:flow/from
+  {:doc "The source task from which segments are being sent."
+   :type :keyword
+   :optional? false
+   :restrictions ["Must name a task in the workflow."]}
+
+  :flow/to
+  {:doc "The destination task where segments will arrive. If set to `:all`, all downstream tasks will receive this segment. If set to `:none`, no downstream tasks will receive this segment. Otherwise it must name a vector of keywords indicating downstream tasks. The order of keywords is irrelevant."
+   :type [:keyword [:keyword]]
+   :choices [[:any] :all :none]
+   :optional? false
+   :restrictions ["When the value is a vector of keyword, every keyword must name a task in the workflow."]}
+
+  :flow/predicate
+  {:doc "When denoted as a keyword, this must be a fully qualified, namespaced keyword pointing to a function on the classpath at runtime. This function takes at least 4 arguments - the Event map, the old segment before `:onyx/fn` was applied, the new segment after `:onyx/fn` was applied, and the sequence of new segments generated by the old semgent. If the old segment generated exactly one segment, and not a sequence of segments, the value of the last parameter will be a collection with only the new segment in it.
+
+When denoted as a vector of keywords, the first value in the vector  may either be the keyword `:and`, `:or`, or `:not`, or be a keyword as described above. In the latter case, any subsequent values must be keywords that resolve to keys in the flow condition entries map. The values of these keys are resolved and passed as additional parameters to the function. In the former case, the result of the function (which may again be wrapped with a vector to nest logical operators or parameters), is applied with the designated logical operator. This yields predicate composition."
+   :type [:keyword [:keyword]]
+   :optional? false}
+
+  :flow/exclude-keys
+  {:doc "If any of the keys are present in the segment, they will be `dissoc`ed from the segment before it is sent downstream. This is useful when values in the segment are present purely for the purpose of making a decision about which downstream tasks it should be sent to."
+   :type [[:keyword]]
+   :optional? true}
+
+  :flow/short-circuit?
+  {:doc "When multiple flow condition entry predicates evaluated to true, the tasks in `:flow/to` are set unioned. If this behavior is undesirable, and you want exactly the tasks in this flow condition's `:flow/to` key to be used, plus any previously matched flow conditions `:flow/to` values. Setting `:flow/short-circuit?` to `true` will force the matcher to stop executing and immediately return with the values that it matched."
+   :type :boolean
+   :optional? true
+   :default false
+   :restrictions ["Any entry that has :flow/short-circuit? set to true must come before any entries for an task that have it set to false or nil."]}
+
+  :flow/thrown-exception?
+  {:doc "If an exception is thrown from an Onyx transformation function, you can capture it from within your flow conditions by setting this value to `true`. If an exception is thrown, only flow conditions with `:flow/thrown-exception?` set to `true` will be evaluated. The value that is normally the segment which is sent to the predicate will be the exception object that was thrown. Note that exceptions don't serialize. This feature is meant to be used in conjunction with Post-transformations and Actions for sending exception values to downstream tasks."
+   :type :boolean
+   :optional? true
+   :default false
+   :restrictions ["Exception flow conditions must have `:flow/short-circuit?` set to `true`"]}
+
+  :flow/post-transform
+  {:doc "A fully qualified, namespaced keyword that points to a function on the classpath at runtime. This function is invoked when an exception is thrown processing a segment in `:onyx/fn` and this flow condition's predicate evaluates to `true`. The function takes 3 parameters - the Event map, the segment that causes the exception to be thrown, and the exception object. The return value of this function is sent to the downstream tasks instead of trying to serialize the exception. The return value must be a segment or sequence of segments, and must serialize."
+   :type :keyword
+   :optional? true
+   :default nil
+   :restrictions ["`:flow/thrown-exception?` must be set to `true`."]}
+
+  :flow/action?
+  {:doc "Names a side effect to perform in response to processing this segment. If set to `:retry`, this segment will be immediately, forcibly retried from the root input task from which it eminated. This segment will not be sent to any downstream tasks."
+   :type :keyword
+   :choices [:retry]
+   :optional? true
+   :default nil
+   :restrictions "Any flow condition clauses with `:flow/action` set to `:retry` must also have `:flow/short-circuit?` set to `true`, and `:flow/to` set to `:none`."}}
+
+ :window-entry
+ {:window/id
+  {:doc "A unique identifier for this window."
+   :type :keyword
+   :optional? false
+   :restrictions ["Must be unique across all Window entries."]}
+
+  :window/task
+  {:doc "The task that this window will be applied to."
+   :type :keyword
+   :optional? false
+   :restrictions ["Must name a task in the workflow."]}
+
+  :window/type
+  {:doc "The type of Window to use. See the User Guide for what each type means."
+   :type :keyword
+   :choices [:fixed :sliding :global :session]
+   :optional? false}
+
+  :window/aggregation
+  {:doc "If this value is a keyword, it is a fully qualified, namespaced keyword pointing to a symbol on the classpath at runtime. This symbol must be a map with keys as further specified by the information model. Onyx comes with a handful of aggregations built in, such as `:onyx.windowing.aggregation/min`. See the User Guide for the full list. Users can also implement their own aggregations.
+
+If this value is a vector, it contain two values: a keyword as described above, and another keyword which represents the key to aggregate over."
+   :type [:keyword [:keyword]]
+   :optional? false}
+
+  :window/window-key
+  {:doc "The key of the incoming segments to window over. This key can represent any totally ordered domain, for example `:event-time`."
+   :type :keyword
+   :optional? false}
+
+  :window/min-key
+  {:doc "A globally minimum value that values of `:window/window-key` will never be less than. This is used for calculating materialized aggregates for windows in a space efficient manner."
+   :type :integer
+   :optional? true
+   :default 0}
+
+  :window/range
+  {:doc "The span of time, or other totally ordered domain, that this window will capture data within."
+   :type [:unit]
+   :optional? false
+   :required-when ["The `:window/type` is `:fixed` or `:sliding`."]}
+
+  :window/slide
+  {:doc "To offset of time, or other totally ordered domain, to wait before starting a new window after the previous window."
+   :type [:unit]
+   :required-when ["The `:window/type` is `:sliding`."]}
+
+  :window/init
+  {:doc "The initial value to be used for the aggregate, if required. Some aggregates require this, such as the Minimum aggregate. Others, such as the Conj aggregate, do not, as empty vector makes a suitable initial value."
+   :type :any
+   :required-when ["The `:window/aggregation` has no predefined initial value."]}
+
+  :window/timeout-gap
+  {:doc "The duration of dormant activity that constitutes a session window being closed."
+   :type :unit
+   :required-when ["The `window/type` is `:session`."]}
+
+  :window/doc
+  {:doc "A docstring for this window."
+   :type :string
+   :optional? true}}
+
+ :trigger-entry
+ {:trigger/window-id
+  {:doc "The name of a `:window/id` window to fire the trigger against."
+   :type :keyword
+   :optional? false
+   :restrictions ["Must name a `:window/id` in the window entries."]}
+
+  :trigger/refinement
+  {:doc "The refinement mode to use when firing the trigger against a window. When set to `:accumulating`, the window contents remain. When set to `:discarding`, the window contents are destroyed, resetting the window to the initial aggregation value. The initial value is set lazily so expired windows do not unnecessarily consume memory."
+   :type :keyword
+   :choices [:accumulating :discarding]
+   :optional? false}
+
+  :trigger/on
+  {:doc "The event to trigger in reaction to, such as a segment with a special feature, or on a timer. See the User Guide for the full list of prepackaged Triggers."
+   :type :keyword
+   :optional? false}
+
+  :trigger/sync
+  {:doc "A fully qualified, namespaced keyword pointing to a function on the classpath at runtime. This function takes the window contents as its argument. Its return value is ignored. This function is invoked when the trigger fires, and is used to do any arbitrary action with the window contents, such as sync them to a database."
+   :type :keyword
+   :optional? false}
+
+  :trigger/fire-all-extents?
+  {:doc "When set to `true`, if any particular extent fires in reaction to this trigger, all extents also fire."
+   :type :boolean
+   :optional? true
+   :default false}
+
+  :trigger/doc
+  {:doc "A docstring for this trigger."
+   :type :string
+   :optional? true}}
+
+ :lifecycle-entry
+ {:lifecycle/name
+  {:doc "A unique name identifying this lifecycle."
+   :type :keyword
+   :optional? false
+   :restrictions ["Must be unique across all lifecycle entries."]}
+
+  :lifecycle/calls
+  {:doc "A fully qualified, namespaced keyword pointing to a symbol on the classpath at runtime. This symbol must be a map with keys further specified by the information model. The keys in this map denote the concrete functions to invoke at execution time."
+   :type :keyword
+   :optional? false}
+
+  :lifecycle/doc
+  {:doc "A docstring for this lifecycle."
+   :type :string
+   :optional? true}}
+
+ :peer-config
+ {:onyx.peer/inbox-capacity
+  {:doc "Maximum number of messages to try to prefetch and store in the inbox, since reading from the log happens asynchronously."
+   :type :integer
+   :unit :messages
+   :default 1000
+   :optional? true}
+
+  :onyx.peer/outbox-capacity
+  {:doc "Maximum number of messages to buffer in the outbox for writing, since writing to the log happens asynchronously."
+   :type :integer
+   :unit :messages
+   :default 1000
+   :optional? true}
+
+  :onyx.peer/retry-start-interval
+  {:doc "Number of ms to wait before trying to reboot a virtual peer after failure."
+   :type :integer
+   :unit :milliseconds
+   :default 2000
+   :optional? true}
+
+  :onyx.peer/join-failure-back-off
+  {:doc "Number of ms to wait before trying to rejoin the cluster after a previous join attempt has aborted."
+   :type :integer
+   :unit :milliseconds
+   :default 250
+   :optional? true}
+
+  :onyx.peer/drained-back-off
+  {:doc "Number of ms to wait before trying to complete the job if all input tasks have been exhausted."
+   :type :integer
+   :unit :milliseconds
+   :default 400
+   :optional? true}}}


git-svn-id: svn+ssh://zen.millennium.berkeley.edu/home/eecs/jawolfe/svn/angel@394 cd74b5cd-e609-0410-a199-9e5d10d28226

error: pathspec 'src/edu/berkeley/angel/search/algorithms/real_time.clj' did not match any file(s) known to git

--- src/edu/berkeley/angel/search/algorithms/real_time.clj
+++ src/edu/berkeley/angel/search/algorithms/real_time.clj
@@ -0,0 +1,124 @@
+; Textbook algorithms for fully observable, deterministic problems
+; with countable state spaces and finite action spaces.
+
+(ns edu.berkeley.angel.search.algorithms.real-time
+  (:refer-clojure)
+  (:use (edu.berkeley.angel [util :as util] envs search))
+  )
+
+
+(def *debug-level* 0)
+
+(defn real-time-search "Generic real-time search.  Action-fn maps node->primitive"
+  [state state->search-node max-steps action-fn]
+  (loop [[state cur-seq] [state [[] 0]], max-steps max-steps]
+;  (when (> *debug-level* 0) (prn (clojure.set/intersection state #{'(on d c) '(on c b) '(on b a)})))
+    (let [node (state->search-node state)]
+      (when (> *debug-level* 0) (prn) (prln (node-str node)))
+      (or (and (extract-optimal-solution node) cur-seq)
+	  (and (> max-steps 0)
+	       (recur
+		(next-initial-state
+		 [state cur-seq]
+		 (action-fn node state))
+		(dec max-steps)))))))
+
+; TODO: Various versions for search strategies, alpha pruning, etc.
+(defn lookahead-search "Standard depth-limited greed loookahead search"
+  [state state->search-node max-steps search-depth]
+  (real-time-search state state->search-node max-steps
+    (fn [node state]
+      (node-first-action
+       (random-maximal-element upper-reward-bound (refinements-depth node search-depth))))))
+
+
+(import '(java.util HashMap))
+
+; TODO: Various versions for search strategies, alpha pruning, etc.
+(defn lrta-star "Korf's classic LRTA* with a fixed depth limit. Only for state-space search."
+  [env upper-reward-fn max-steps search-depth]
+  (let [space (state-space-search-space env upper-reward-fn)
+	#^HashMap m (HashMap.)]
+    (real-time-search
+     (get-initial-state env)
+     (partial make-state-space-node space)
+     max-steps
+     (fn [node state]
+       (let [nodes (map-leaf-refinements-depth
+		     node
+		     #(when-let [r (and (not= node %) (.get m (:state %)))]
+;			(prn ". " (:state %) r (reward-so-far %) (upper-reward-bound (adjust-reward % (+ r (reward-so-far %)))))
+			(adjust-reward % (+ r (reward-so-far %))))
+		     search-depth)
+	     best (random-maximal-element upper-reward-bound nodes)]
+	 (.put m state (upper-reward-bound best))
+;	 (prn (or (:state best) (cons "O" (:state (:node best)))) (upper-reward-bound best))
+	 (node-first-action best))))))
+
+
+
+
+
+
+
+
+(comment
+; uninformed lookahead
+(second (or (let [instance
+	(read-strips-planning-instance
+	 (read-strips-planning-domain "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/domain.pddl")
+	 "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/probBLOCKS-4-0.pddl")
+	space (state-space-search-space instance (constantly 0))]
+    (time
+     (lookahead-search
+      (get-initial-state instance)
+      (partial make-state-space-node space)
+      100 1))) nil))
+
+; greedy lookahead - # of conjuncts
+(let [instance
+	(read-strips-planning-instance
+	 (read-strips-planning-domain "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/domain.pddl")
+	 "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/probBLOCKS-4-0.pddl")
+	    space (state-space-search-space instance #(- (count (clojure.set/difference (set (:goal-atoms instance)) %))))]
+	(frequencies (map #(when % true) (take 1000 (repeatedly (fn []
+     (lookahead-search
+      (get-initial-state instance)
+      (partial make-state-space-node space)
+      100 1)))))))
+
+
+; lrta* - # of conjuncts
+(let [instance
+	(read-strips-planning-instance
+	 (read-strips-planning-domain "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/domain.pddl")
+	 "/Users/jawolfe/Projects/research/IPC/IPC2/2000-Tests/Blocks/Track1/Typed/probBLOCKS-4-0.pddl")]
+  (frequencies (map #(when % true) (take 100 (repeatedly (fn []
+     (lrta-star
+      instance
+      #(- (count (clojure.set/difference (set (:goal-atoms instance)) %)))
+      1000
+      1)))))))
+
+
+
+
+
+
+
+;      (state-space-search-node
+
+;     #(- (count (clojure.set/intersection )
+;     )))
+
+
+
+
+
+
+)
+
+
+
+
+


[EN] Catch all Throwables in handle-errors

Throwable is the superclass of all errors and exceptions. We should have
a catch-all catch clause for unexpected errors.

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


irc-bot test module

irc-bot test module

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

--- test/emender_service/irc_bot_test.clj
+++ test/emender_service/irc_bot_test.clj
@@ -0,0 +1,7 @@
+(ns emender-service.irc-bot-test
+  (:require [clojure.test :refer :all]
+            [emender-service.irc-bot :refer :all]))
+
+(deftest a-test
+  (testing "FIXME, I fail."
+    (is (= 0 1))))


Bumping up to see further spelunk

Bumping up to see further spelunk

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


Move parse function out to where it can be smelled.

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


Fix docstring for request function

Fix docstring for request function

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -854,7 +854,7 @@
   * :accept-encoding
   * :as

-  The following additional behaviors over also automatically enabled:
+  The following additional behaviors are also automatically enabled:
   * Exceptions are thrown for status codes other than 200-207, 300-303, or 307
   * Gzip and deflate responses are accepted and decompressed
   * Input and output bodies are coerced as required and indicated by the :as


add new stop language

add new stop language

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 nested-style reporter.

Add nested-style reporter.

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

--- src/main/clojure/lazytest/report/nested.clj
+++ src/main/clojure/lazytest/report/nested.clj
@@ -0,0 +1,51 @@
+(ns lazytest.report.nested
+  (:use lazytest.report.color
+	lazytest.suite))
+
+(defn identifier [result]
+  (let [m (meta (:source result))]
+    (or (:doc m) (:name m))))
+
+(declare report-result)
+
+(defn indent [n]
+  (dotimes [i n] (print "    ")))
+
+(defn report-suite-result [result depth]
+  (indent depth)
+  (println (identifier result))
+  (doseq [child (:children result)]
+    (report-result child (inc depth))))
+
+(defn report-test-case-result [result depth]
+  (indent depth)
+  (println (colorize (identifier result) (if (:pass? result) :green :red))))
+
+(defn result-seq [result]
+  (tree-seq suite-result? :children result))
+
+(defn report-result [result depth]
+  (if (suite-result? result)
+    (report-suite-result result depth)
+    (report-test-case-result result depth)))
+
+(defn summarize [results]
+  (let [test-case-results (remove suite-result? (mapcat result-seq results))
+	total (count test-case-results)
+	passed (count (filter :pass? test-case-results))
+	failed (- total passed)]
+    {:total total, :pass passed, :fail failed}))
+
+(defn print-summary [summary]
+  (let [count-msg (str "Ran " (:total summary) " tests.")]
+    (println (if (zero? (:total summary))
+	       (colorize count-msg :yellow)
+	       count-msg)))
+  (println (colorize (str (:fail summary) " failures.")
+		     (if (zero? (:fail summary)) :green :red))))
+
+(defn report [results]
+  (doseq [r results] (report-result r 0))
+  (newline)
+  (print-summary (summarize results)))
+


Friend and Yokogiri conflict

Friend and Yokogiri conflict

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


updated to reverie 0.7.0-SNAPSHOT branch

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


version bump

version bump

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


Use pdfboxing fork to get security fix

Use pdfboxing fork to get security fix

…until upstream releases a fixed version. PR submitted here: https://github.com/dotemacs/pdfboxing/pull/49

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


Exclude unnecessary junit dependency of jline.

This has gone on long enough.

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


annotation value function

annotation value 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/tokenmill/clj-gate.git/'


Html-renderer test module

Html-renderer test module

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

--- test/emender_service/html_renderer_test.clj
+++ test/emender_service/html_renderer_test.clj
@@ -0,0 +1,7 @@
+(ns emender-service.html-renderer-test
+  (:require [clojure.test :refer :all]
+            [emender-service.html-renderer :refer :all]))
+
+(deftest a-test
+  (testing "FIXME, I fail."
+    (is (= 0 1))))


prefix-tree impl WIP

prefix-tree impl WIP

* opensensors route match, 2.3µs => 1.3µs
* static routes looked first
* fixes pedestal #532

error: pathspec 'perf-test/clj/reitit/trie.cljc' did not match any file(s) known to git

--- perf-test/clj/reitit/trie.cljc
+++ perf-test/clj/reitit/trie.cljc
@@ -0,0 +1,317 @@
+(ns reitit.trie
+  (:require [clojure.walk :as walk]
+            [clojure.string :as str]
+            [criterium.core :as cc]
+            [reitit.impl :as impl]))
+
+(set! *warn-on-reflection* true)
+
+;;
+;; Prefix-tree-router
+;;
+
+(defn- char-key
+  "Return the single character child key for the string started at
+  index i."
+  [s i]
+  (if (< i (count s))
+    (subs s i (inc i))))
+
+(defprotocol Lookup
+  (lookup [this path params]))
+
+(extend-protocol Lookup
+  nil
+  (lookup [_ _ _]))
+
+(defrecord WildNode [segment children param wild catch]
+  Lookup
+  (lookup [this path params]
+    #_(println "w=>" segment "..." path)
+    (let [i (.indexOf ^String path "/")]
+      (if (pos? i)
+        (let [value (subs path 0 i)]
+          (let [childs [(impl/fast-get children (char-key path (inc i))) wild catch]
+                path' (subs path (inc i))
+                params (assoc params param value)]
+            (some #(lookup % path' params) childs)))
+        (assoc params param path)))))
+
+(defrecord CatchAllNode [segment children param]
+  Lookup
+  (lookup [this path params]
+    (assoc params param path)))
+
+(defrecord StaticNode [^String segment ^Integer size children wild catch]
+  Lookup
+  (lookup [this path params]
+    #_(println "s=>" segment "..." path)
+    (if (.equals segment path)
+      params
+      (let [p (if (>= (count path) size) (subs path 0 size))]
+        (if (.equals segment p)
+          (let [childs [(impl/fast-get children (char-key path size)) wild catch]
+                path (subs path size)]
+            (some #(lookup % path params) childs)))))))
+
+(defn- wild? [s]
+  (contains? #{\: \*} (first s)))
+
+(defn- wild-param?
+  "Return true if a string segment starts with a wildcard string."
+  [segment]
+  (= \: (first segment)))
+
+(defn- catch-all-param?
+  "Return true if a string segment starts with a catch-all string."
+  [segment]
+  (= \* (first segment)))
+
+(defn partition-wilds
+  "Given a path-spec string, return a seq of strings with wildcards
+  and catch-alls separated into their own strings. Eats the forward
+  slash following a wildcard."
+  [path-spec]
+  (let [groups (partition-by wild? (str/split path-spec #"/"))
+        first-groups (butlast groups)
+        last-group (last groups)]
+    (flatten
+      (conj (mapv #(if (wild? (first %))
+                     %
+                     (str (str/join "/" %) "/"))
+                  first-groups)
+            (if (wild? (first last-group))
+              last-group
+              (str/join "/" last-group))))))
+
+(defn contains-wilds?
+  "Return true if the given path-spec contains any wildcard params or
+  catch-alls."
+  [path-spec]
+  (let [parts (partition-wilds path-spec)]
+    (or (> (count parts) 1)
+        (wild? (first parts)))))
+
+(defn- make-node
+  "Given a path-spec segment string and a payload object, return a new
+  tree node."
+  [segment o]
+  (cond
+    (wild-param? segment)
+    (map->WildNode
+      {:segment segment
+       :param (keyword (subs segment 1))})
+
+    (catch-all-param? segment)
+    (map->CatchAllNode
+      {:segment segment
+       :param (keyword (subs segment 1))})
+
+    :else
+    (map->StaticNode
+      {:segment segment})))
+
+(defn- add-child
+  "Given a tree node, a single char string key and a child node,
+  return a new tree where this node has this child."
+  [node key child]
+  (assoc-in node [:children key] child))
+
+(declare insert)
+
+(defn- insert-child
+  "Given a tree node, a single char string key, a path-spec string and
+  a payload object, return a tree where this object has been instered
+  at path-spec under this node."
+  [node key path-spec o]
+  (update-in node [:children key] insert path-spec o))
+
+(defn- new-node
+  "Given a path-spec and a payload object, return a new tree node. If
+  the path-spec contains wildcards or catch-alls, will return parent
+  node of a tree (linked list)."
+  [path-spec o]
+  (if (contains-wilds? path-spec)
+    (let [parts (partition-wilds path-spec)]
+      (reduce (fn [child segment]
+                (when (catch-all-param? segment)
+                  (throw (ex-info "catch-all may only appear at the end of a path spec"
+                                  {:patch-spec path-spec})))
+                (-> (make-node segment nil)
+                    (add-child (subs (:segment child) 0 1) child)))
+              (let [segment (last parts)]
+                (make-node segment o))
+              (reverse (butlast parts))))
+    (make-node path-spec o)))
+
+(defn- calc-lcs
+  "Given two strings, return the end index of the longest common
+  prefix string."
+  [s1 s2]
+  (loop [i 1]
+    (cond (or (< (count s1) i)
+              (< (count s2) i))
+          (dec i)
+
+          (= (subs s1 0 i)
+             (subs s2 0 i))
+          (recur (inc i))
+
+          :else (dec i))))
+
+(defn- split
+  "Given a node, a path-spec, a payload object to insert into the tree
+  and the lcs, split the node and return a new parent node with the
+  old contents of node and the new item as children.
+  lcs is the index of the longest common string in path-spec and the
+  segment of node."
+  [node path-spec o lcs]
+  (let [segment (:segment node)
+        common (subs path-spec 0 lcs)
+        parent (new-node common nil)]
+    (if (= common path-spec)
+      (-> parent
+          (add-child (char-key segment lcs)
+                     (update-in node [:segment] subs lcs)))
+      (-> parent
+          (add-child (char-key segment lcs)
+                     (update-in node [:segment] subs lcs))
+          (insert-child (char-key path-spec lcs) (subs path-spec lcs) o)))))
+
+(defn insert
+  "Given a tree node, a path-spec and a payload object, return a new
+  tree with payload inserted."
+  [node path-spec o]
+  (let [segment (:segment node)]
+    (cond (nil? node)
+          (new-node path-spec o)
+
+          (= segment path-spec)
+          node
+
+          ;; handle case where path-spec is a wildcard param
+          (wild-param? path-spec)
+          (let [lcs (calc-lcs segment path-spec)
+                common (subs path-spec 0 lcs)]
+            (if (= common segment)
+              (let [path-spec (subs path-spec (inc lcs))]
+                (insert-child node (subs path-spec 0 1) path-spec o))
+              (throw (ex-info "route conflict"
+                              {:node node
+                               :path-spec path-spec
+                               :segment segment}))))
+
+          ;; in the case where path-spec is a catch-all, node should always be nil.
+          ;; getting here means we have an invalid route specification
+          (catch-all-param? path-spec)
+          (throw (ex-info "route conflict"
+                          {:node node
+                           :path-spec path-spec
+                           :segment segment}))
+
+          :else
+          (let [lcs (calc-lcs segment path-spec)]
+            (cond (= lcs (count segment))
+                  (insert-child node (char-key path-spec lcs) (subs path-spec lcs) o)
+
+                  :else
+                  (split node path-spec o lcs))))))
+
+(defn optimize [tree]
+  (walk/postwalk
+    (fn [x]
+      (if (or (instance? StaticNode x)
+              (instance? WildNode x))
+        (let [wild-child (get-in x [:children ":"])
+              catch-all-child (get-in x [:children "*"])]
+          (cond-> x
+                  wild-child (-> (assoc :wild wild-child)
+                                 (update :children dissoc ":"))
+                  catch-all-child (-> (assoc :catch catch-all-child)
+                                      (update :children dissoc "*"))
+                  (:segment x) (assoc :size (-> x :segment count))
+                  true (update :children impl/fast-map)))
+        x))
+    tree))
+
+;;
+;; testing
+;;
+
+(def routes
+  [["/v2/whoami" {:name :test/route1}]
+   ["/v2/users/:user-id/datasets" {:name :test/route2}]
+   ["/v2/public/projects/:project-id/datasets" {:name :test/route3}]
+   ["/v1/public/topics/:topic" {:name :test/route4}]
+   ["/v1/users/:user-id/orgs/:org-id" {:name :test/route5}]
+   ["/v1/search/topics/:term" {:name :test/route6}]
+   ["/v1/users/:user-id/invitations" {:name :test/route7}]
+   ["/v1/users/:user-id/topics" {:name :test/route9}]
+   ["/v1/users/:user-id/bookmarks/followers" {:name :test/route10}]
+   ["/v2/datasets/:dataset-id" {:name :test/route11}]
+   ["/v1/orgs/:org-id/usage-stats" {:name :test/route12}]
+   ["/v1/orgs/:org-id/devices/:client-id" {:name :test/route13}]
+   ["/v1/messages/user/:user-id" {:name :test/route14}]
+   ["/v1/users/:user-id/devices" {:name :test/route15}]
+   ["/v1/public/users/:user-id" {:name :test/route16}]
+   ["/v1/orgs/:org-id/errors" {:name :test/route17}]
+   ["/v1/public/orgs/:org-id" {:name :test/route18}]
+   ["/v1/orgs/:org-id/invitations" {:name :test/route19}]
+   ["/v1/users/:user-id/device-errors" {:name :test/route22}]
+   ["/v2/login" {:name :test/route23}]
+   ["/v1/users/:user-id/usage-stats" {:name :test/route24}]
+   ["/v2/users/:user-id/devices" {:name :test/route25}]
+   ["/v1/users/:user-id/claim-device/:client-id" {:name :test/route26}]
+   ["/v2/public/projects/:project-id" {:name :test/route27}]
+   ["/v2/public/datasets/:dataset-id" {:name :test/route28}]
+   ["/v2/users/:user-id/topics/bulk" {:name :test/route29}]
+   ["/v1/messages/device/:client-id" {:name :test/route30}]
+   ["/v1/users/:user-id/owned-orgs" {:name :test/route31}]
+   ["/v1/topics/:topic" {:name :test/route32}]
+   ["/v1/users/:user-id/bookmark/:topic" {:name :test/route33}]
+   ["/v1/orgs/:org-id/members/:user-id" {:name :test/route34}]
+   ["/v1/users/:user-id/devices/:client-id" {:name :test/route35}]
+   ["/v1/users/:user-id" {:name :test/route36}]
+   ["/v1/orgs/:org-id/devices" {:name :test/route37}]
+   ["/v1/orgs/:org-id/members" {:name :test/route38}]
+   ["/v2/orgs/:org-id/topics" {:name :test/route40}]
+   ["/v1/whoami" {:name :test/route41}]
+   ["/v1/orgs/:org-id" {:name :test/route42}]
+   ["/v1/users/:user-id/api-key" {:name :test/route43}]
+   ["/v2/schemas" {:name :test/route44}]
+   ["/v2/users/:user-id/topics" {:name :test/route45}]
+   ["/v1/orgs/:org-id/confirm-membership/:token" {:name :test/route46}]
+   ["/v2/topics/:topic" {:name :test/route47}]
+   ["/v1/messages/topic/:topic" {:name :test/route48}]
+   ["/v1/users/:user-id/devices/:client-id/reset-password" {:name :test/route49}]
+   ["/v2/topics" {:name :test/route50}]
+   ["/v1/login" {:name :test/route51}]
+   ["/v1/users/:user-id/orgs" {:name :test/route52}]
+   ["/v2/public/messages/dataset/:dataset-id" {:name :test/route53}]
+   ["/v1/topics" {:name :test/route54}]
+   ["/v1/orgs" {:name :test/route55}]
+   ["/v1/users/:user-id/bookmarks" {:name :test/route56}]
+   ["/v1/orgs/:org-id/topics" {:name :test/route57}]])
+
+(comment
+  (require '[io.pedestal.http.route.prefix-tree :as p])
+  (def tree-old (reduce (fn [acc [p d]] (p/insert acc p d)) nil routes))
+
+  ;; 2.3ms
+  (cc/quick-bench (dotimes [_ 1000] (p/lookup tree-old "/v1/orgs/1/topics"))))
+
+(comment
+  (def tree-new (optimize (reduce (fn [acc [p d]] (insert acc p d)) nil routes)))
+
+  ;; 3.1ms
+  ;; 2.5ms (string equals)
+  ;; 2.5ms (protocol)
+  ;; 2.3ms (nil childs)
+  ;; 2.0ms (rando impros)
+  ;; 1.9ms (wild & catch shortcuts)
+  ;; 1.5ms (inline child fetching)
+  ;; 1.5ms (WildNode also backtracks)
+  ;; 1.4ms (precalculate segment-size)
+  ;; 1.3ms (fast-map)
+  ;; 1.3ms (dissoc wild & catch-all from children)
+  (cc/quick-bench (dotimes [_ 1000] (lookup tree-new "/v1/orgs/1/topics" {}))))


Add test! task that cleans and runs deps first.

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

--- src/leiningen/test!.clj
+++ src/leiningen/test!.clj
@@ -0,0 +1,10 @@
+(ns leiningen.test!
+  (:refer-clojure :exclude [test])
+  (:use [leiningen.clean :only [clean]]
+        [leiningen.deps :only [deps]]
+        [leiningen.test :only [test]]))
+
+(defn test!
+  "Run a project's tests after cleaning and pulling in fresh dependencies."
+  [project]
+  (doto project clean deps test))


Consistent matching style

Consistent matching style

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


Etiketentzat taula erabili

Etiketentzat taula erabili

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


Remove /services/token*

Remove /services/token*

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


Adds auth logging

Adds auth logging


Remove /users

Remove /users


button hacking

button hacking

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


clean up

clean up

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/max-neverov/ads-client.git/'


move plan name to odin.graphql.resolvers.utils

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


Removing gensym

Removing gensym


Add example from 3.4 - scope

Add example from 3.4 - scope

error: pathspec 'src/clojure_walkthrough/jocj/ch03_04.clj' did not match any file(s) known to git

--- src/clojure_walkthrough/jocj/ch03_04.clj
+++ src/clojure_walkthrough/jocj/ch03_04.clj
@@ -0,0 +1,52 @@
+(ns clojure-walkthrough.jocj.ch03-04
+  (use clojure.pprint)
+  (:gen-class))
+
+(def MAX-CONNECTION 10)
+
+(def RABBITMQ-CONNECTION)
+
+(def ^:dynamic RABBITMQ-CONNECTION)
+
+(binding [RABBITMQ-CONNECTION (new-connection)]
+  (
+   ;; do something here with RABBITMQ-CONNECTION
+   ))
+
+
+;; Special variables
+
+(def ^:dynamic *db-host* "localhost")
+
+(defn expense-report [start-date end-date]
+  (println *db-host*))  ;; cand do real work
+
+;; rebind once we are ready
+(binding [*db-host* "production"]
+  (expense-report "2010-01-01" "2010-01-07")) ;; Will print "production" to the console
+
+;; Dynamic Scope
+
+(def ^:dynamic *eval-me* 10)
+
+(defn print-the-var [label]
+  (println label *eval-me*))
+
+(print-the-var "A:") ;; will print "A: 10" in the REPL
+
+(binding [*eval-me* 20] ;; the first binding
+  (print-the-var "B:")
+  (binding [*eval-me* 30] ;; the 2nd binding
+    (print-the-var "C:"))
+  (print-the-var "D:"))
+
+;; Result:
+;; A: 10
+;; B: 20
+;; C: 30
+;; D: 20
+
+(print-the-var "E:")
+
+;; Result:
+;; E: 10


Add note about time/dates.

Add note about time/dates.

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


Working tree map.

Working tree map.


Adding a sampled flute. Copied this off the internet.

Will try to make PASR envelopes and use this, maybe.

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

--- src/movertone/flute.clj
+++ src/movertone/flute.clj
@@ -0,0 +1,57 @@
+(ns movertone.flute
+  (:use [overtone.core])
+  (:require [clojure.string :as str]))
+
+(defn- registered-samples
+  "Fetch flute samples from the asset store if they have been manually
+  registered"
+  []
+  (registered-assets ::TransverseFluteTenutoVibrato))
+
+(def FREESOUND-VIBRATO-FLUTE-SAMPLES
+  "Freesound ids for all samples in the Vibrato Transverse Flute pack"
+  {154274 :C7  154273 :B6 154272 :A#6 154271 :A6 154270 :G#6 154269 :G6  154268 :F#6
+   154267 :F6  154266 :E6 154265 :D#6 154264 :D6 154263 :C#6 154262 :C6  154261 :B5
+   154260 :A#5 154259 :A5 154258 :G#5 154257 :G5 154256 :F#5 154255 :F5  154254 :E5
+   154253 :D#5 154252 :D5 154251 :C#5 154250 :C5 154249 :B4  154248 :A#4 154247 :A4
+   154246 :G#4 154245 :G4 154244 :F#4 154243 :E4 154242 :F4  154241 :D#4 154240 :D4
+   154239 :C#4 154238 :C4})
+
+(def FLUTE-SAMPLE-IDS (keys FREESOUND-VIBRATO-FLUTE-SAMPLES))
+
+(def flute-samples
+  (doall (map freesound-sample FLUTE-SAMPLE-IDS)))
+
+(defn- buffer->midi-note [buf]
+  (-> buf :freesound-id FREESOUND-VIBRATO-FLUTE-SAMPLES name note))
+
+(defn- note-index
+  "Returns a map of midi-note values [0-127] to buffer ids."
+  [buffers]
+  (reduce (fn [index buf]
+            (let [id (-> buf :id)
+                  note (buffer->midi-note buf)]
+              (assoc index note id)))
+          {}
+          buffers))
+
+;; Silent buffer used to fill in the gaps.
+(defonce ^:private silent-buffer (buffer 0))
+
+(defonce index-buffer
+  (let [tab (note-index flute-samples)
+        buf (buffer 128)]
+    (buffer-fill! buf (:id silent-buffer))
+    (doseq [[idx val] tab]
+      (buffer-set! buf idx val))
+    buf))
+
+(definst flute
+  [note 60 dur 1.0 level 1 rate 1 loop? 0
+   attack 0 decay 1 sustain 1 release 0.1 curve -4 gate 4]
+  (let [buf (index:kr (:id index-buffer) note)
+        env (env-gen (adsr 0 0 1 0 level curve)
+                     ;;(adsr attack decay sustain release level curve)
+                     :gate gate
+                     :action FREE)]
+    (* env (scaled-play-buf 2 buf :level level :loop loop? :action FREE))))


Tests for wiki page on predicates

Tests for wiki page on predicates

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

--- test/structural_typing/docs/f_wiki_predicates.clj
+++ test/structural_typing/docs/f_wiki_predicates.clj
@@ -0,0 +1,32 @@
+(ns structural-typing.docs.f-wiki-predicates
+ (:require [structural-typing.type :refer :all]
+           [structural-typing.global-type :refer :all]
+           [structural-typing.api.custom :as custom]
+           [clojure.string :as str])
+ (:use midje.sweet))
+
+(start-over!)
+
+(type! :Address
+       {:name (show-as "short string" #(<= % 10))})
+
+(fact
+  (with-out-str (checked :Address {:name "llllllllllllllllll"}))
+  => #":name should be `short string`")
+
+(def good-password? (partial re-find #"\d"))
+(type! :Account {:password good-password?})
+(fact
+  (with-out-str (checked :Account {:password "fool"}))
+  => #":password should be `your custom predicate`; it is `\"fool\"`")
+
+(def good-password? (->> (partial re-find #"\d")
+                         (explain-with
+                          (fn [oopsie]
+                            (format "%s should contain a digit"
+                                    (custom/friendly-path oopsie))))))
+
+(type! :Account {:password good-password?})
+(fact
+  (with-out-str (checked :Account {:password "foo"}))
+  => #":password should contain a digit")


add loading prop to service list table

add loading prop to service list table


Updated ncRNA gene type assertion rule to work with ccp ext ontology

error: pathspec 'resources/rules/post_identifier_merge/ice_to_bio/ncrna_gene_type_assertions.clj' did not match any file(s) known to git

--- resources/rules/post_identifier_merge/ice_to_bio/ncrna_gene_type_assertions.clj
+++ resources/rules/post_identifier_merge/ice_to_bio/ncrna_gene_type_assertions.clj
@@ -0,0 +1,21 @@
+;; ---------------------------------------------
+;; --------- ncRNA Gene Type Assertion ---------
+;; ---------------------------------------------
+ `{:name "ncRNA-gene-type-assertion"
+   :description "This rule asserts ncRNA gene type"
+   :head ((?/gene rdfs/subClassOf obo/S0_0000655)) ; SO:ncRNA
+
+   :body ((?/record rdf/type ccp/IAO_EXT_0000681) ; ccp:NCBI_gene_info_record
+         (?/record obo/BFO_0000051 ?/dna_field_value) ; BFO:has_part
+         (?/gene_field_value rdf/type ccp/IAO_EXT_0000876) ; ccp:NCBI_gene_info_record__gene_identifier_field_value
+         (?/gene_field_value rdf/type ?/gene_ice_id)
+         (?/gene_ice_id obo/IAO_0000219 ?/gene) ; IAO:denotes
+
+         ;; retrieve gene type
+         (?/record obo/BFO_0000051 ?/type_field_value) ; BFO:has_part
+         (?/type_field_value rdf/type ccp/IAO_EXT_0000884) ; ccp:NCBI_gene_info_record__type_of_gene_field_value
+         (?/type_field_value rdf/type ?/type_ice_id)
+         (?/type_ice_id obo/IAO_0000219 ?/type) ; IAO:denotes
+
+         (= ?/type "ncRNA"))
+   }


Puzzle #17 from 2015

Puzzle #17 from 2015

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

--- src/adventofcode1/seventeen_2015.clj
+++ src/adventofcode1/seventeen_2015.clj
@@ -0,0 +1,71 @@
+(ns adventofcode1.seventeen-2015
+  "http://adventofcode.com/2015/day/17"
+  (:require
+   [clojure.spec :as s]
+   [clojure.spec.gen :as gen]
+   [clojure.spec.test :as stest]
+   [com.gfredericks.test.chuck.generators :as gen']
+   [clojure.test.check :as tc]
+   [clojure.test.check.generators :as tcgen]
+   [clojure.test.check.properties :as tcprop]
+
+   [clojure.core.match :refer [match]]
+
+   mw.utils
+   spyscope.core
+   adventofcode1.spec-test-instrument-debug))
+
+
+(defn count-solutions
+  [left buckets]
+  (if (zero? left) 1
+      (if (empty? buckets) 0
+          (let [use-me (first buckets)
+                left2  (- left use-me)]
+            (if (>= left2 0)
+              (+ (count-solutions left2 (rest buckets))
+                 (count-solutions left  (rest buckets)))
+              0)))))
+
+
+(defn count-shortest-solutions-2
+  [g depth left buckets]
+  (if (zero? left)
+    (do (if (< depth (:size @g))
+          (swap! g (fn [x]{:size depth :count 0})))
+        (if (= depth (:size @g))
+          (swap! g (fn [x]{:size (:size x) :count (inc (:count x))})))
+        0)
+    (if (empty? buckets) 0
+          (let [use-me (first buckets)
+                left2  (- left use-me)]
+            (if (>= left2 0)
+              (+ (count-shortest-solutions-2 g (inc depth) left2 (rest buckets))
+                 (count-shortest-solutions-2 g depth left  (rest buckets)))
+              0)))))
+
+(defn count-shortest-solutions
+  [left buckets]
+  (let [res (atom {:size 100000 :count 0})]
+    (count-shortest-solutions-2 res 0 left buckets)
+    @res))
+
+(def start-state (sort [50 44 11 49 42 46 18 32 26 40 21 7 18 43 10 47 36 24 22 40]))
+
+(def demo-state (sort [20, 15, 10, 5, 5]))
+
+(defn puzzle-demo-first
+  []
+  (count-solutions 25 demo-state))
+
+(defn puzzle-demo-second
+  []
+  (count-shortest-solutions 25 demo-state))
+
+(defn puzzle-first
+  []
+  (count-solutions 150 start-state))
+
+(defn puzzle-second
+  []
+  (count-shortest-solutions 150 start-state))