Removed redundant expression

Removed redundant expression

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


add text, number, textarea, dropdowns and single checkboxes

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


testing ns added for game ideas!

testing ns added for game ideas!

error: pathspec 'src/pixel_perversion_engine/test_ideas/ideas.clj' did not match any file(s) known to git

--- src/pixel_perversion_engine/test_ideas/ideas.clj
+++ src/pixel_perversion_engine/test_ideas/ideas.clj
@@ -0,0 +1,16 @@
+;this is ns is for testing purposes!  test new ideas here!
+
+(ns pixel-perversion-engine.ideas
+  (:use [pixel-perversion-engine.process.processor]
+        [pixel-perversion-engine.component]
+        [pixel-perversion-engine.component.timer]))
+
+(defn update-game
+  [scene]
+  (swap! scene
+         (fn [s]
+           (assoc s :entities
+                    (-> s
+                        :entities
+                        (->> (map update-timer)))))))
+


[DG] Removed unused notification-type-id

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


Corrected arg position of map-fork

Corrected arg position of map-fork

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


Helper to parse

Helper to parse

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


added test

added test

error: pathspec 'resources/leiningen/new/closp/test/clj/crudify/validation_test.clj' did not match any file(s) known to git

--- resources/leiningen/new/closp/test/clj/crudify/validation_test.clj
+++ resources/leiningen/new/closp/test/clj/crudify/validation_test.clj
@@ -0,0 +1,42 @@
+(ns {{ns}}.crudify.validation-test
+  (:require [clojure.test :refer :all]
+            [taoensso.tempura :refer [tr]]
+            [clojure.spec.alpha :as s]
+            [{{ns}}.crudify.validation :as val]
+            [{{ns}}.db.entities :as ent]
+            [{{ns}}.components.locale :as l]
+            [{{ns}}.crudify.util :as u]))
+
+(def t (partial tr
+                {:default-locale :en
+                 :dict           l/local-dict}
+                ["en"]))
+
+
+(def email-field {:name "email" :type :string :max-length 30 :spec (s/and ::ent/string? ::ent/max-30 ::ent/not-empty)})
+(def number-field {:name "age" :type :string :max-length 30 :spec (s/and ::ent/number? ::ent/max-100 ::ent/not-null)})
+(def date-field {:name "date" :type :date :max-length 30 :spec (s/and ::ent/date? ::ent/not-null) :conformer ent/sql-date-transformer})
+
+;(deftest notempty
+;  (is (= (t [:crudify/not-empty] [(u/prepare-str-for-ui (:name email-field))])
+;         (val/check-spec email-field "" t))))
+;
+;(deftest notstring
+;  (is (= (t [:crudify/not-string] [(u/prepare-str-for-ui (:name email-field))])
+;         (val/check-spec email-field nil t))))
+;
+;(deftest notnumber
+;  (is (= (t [:crudify/not-number] [(u/prepare-str-for-ui (:name number-field))])
+;         (val/check-spec number-field "sdlfkj" t))))
+;
+;(deftest max-length
+;    (is (= (t [:crudify/max-length] [(u/prepare-str-for-ui (:name email-field))])
+;           (val/check-spec email-field "sldkfasdfawerwerwerjsldkfasdfawerwerwerjsldkfasdfawerwerwerjsldkfasdfawerwerwerjsldkfasdfawerwerwerj" t))))
+
+(deftest date
+  (println (val/check-spec date-field "2017-12-28" t)))
+  ;(is (= "" (val/check-spec date-field "2017-12-28" t))))
+
+;(deftest notdate
+;  (is (= (t [:crudify/not-number] [(u/prepare-str-for-ui (:name number-field))])
+;         (val/check-spec number-field "sdlfkj" t))))


Starting initial work on a standalone application.

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

--- src/overtone/app/main.clj
+++ src/overtone/app/main.clj
@@ -0,0 +1,161 @@
+(ns overtone.app.main
+  (:import
+     (java.awt Toolkit EventQueue Font FontMetrics Dimension BorderLayout)
+     (javax.swing JFrame JPanel JLabel JTree JEditorPane JScrollPane JTextPane
+                  JSplitPane JMenuBar JMenu JMenuItem SwingUtilities)
+     (javax.swing.tree TreeModel DefaultTreeCellRenderer)
+     (javax.swing.table TableModel AbstractTableModel)
+     (org.enclojure.repl IReplWindow IReplWindowFactory IRepl)
+     (com.raelity.jvi ViManager ColonCommands)
+     (com.raelity.jvi.swing DefaultViFactory StatusDisplay TextView))
+  (:require [clojure.inspector :as inspector])
+  (:use clojure.contrib.seq-utils
+     org.enclojure.ide.repl.factory))
+
+
+(def APP-NAME "Overtone")
+(def DEFAULT-FONT "Sans")
+(def DEFAULT-FONT-SIZE 12)
+
+(def TAB-STOP 4)
+
+(defn screen-dim []
+  (.getScreenSize (Toolkit/getDefaultToolkit)))
+
+(defn screen-size []
+  (let [dim (screen-dim)]
+    [(.width dim) (.height dim)]))
+
+;TODO: It undecorates, but it doesn't seem to change the size of the frame...
+(defn fullscreen-frame [f]
+    (.setExtendedState f JFrame/MAXIMIZED_BOTH)
+    (.setUndecorated f true))
+
+(defn app-menu-bar []
+  (let [bar (JMenuBar.)
+        file-menu (JMenu. "File")
+        quit-item (JMenuItem. "Quit")
+        help-menu (JMenu. "Help")
+        about-item (JMenuItem. "About")]
+    (doto file-menu
+      (.add quit-item))
+    (doto help-menu
+      (.add about-item))
+    (doto bar
+      (.add file-menu)
+      (.add help-menu))))
+
+(def synths* (ref {:root
+                   {"Instruments"
+                    {"Bass" :bass-obj
+                     "Pad" :pad-obj
+                     "Sizzler" :sizzler-obj}
+                    "Effects"
+                    {"Echo" :echo-obj
+                     "Compressor" :compressor-obj
+                     "Reverb" :reverb-obj
+                     "Chorus" :chors-obj}}}))
+
+(defn tree-cell-renderer []
+  (proxy [DefaultTreeCellRenderer] []
+    (getTreeCellRendererComponenet [tree value selected? expanded?
+                                    leaf? row has-focus?]
+      ;(let [cell (proxy-super tree value selected? expanded? leaf? row has-focus?)]
+      ;  (.setText cell (str (first value)))
+      ;  cell))))
+      ;(JLabel. (str (first value))))))
+      (JLabel. (str "asdf")))))
+
+
+(defn find-in [col item]
+  (first (filter #(= %1 item) col)))
+
+(defn path-get [node path]
+  (cond
+    (= node (first path)) node
+    (empty? path) nil
+    :default (recur (find-in (second node) (first path)) (next path))))
+
+(defn tree-model [root*]
+  (proxy [TreeModel] []
+    (addTreeModelListener [treeModelListener])
+    (removeTreeModelListener [treeModelListener])
+
+    (getRoot [] ["root" @root*])
+
+    (isLeaf [node]
+      (not (coll? (second node))))
+
+    (getChild [parent index]
+      (nth (seq (second parent)) index))
+
+    (getChildCount [node]
+      (count (second node)))
+
+    (valueForPathChanged [path new-val]
+      (let [path (seq (.getPath path))
+            old-val (path-get @root* path)
+            path-keys (map #(first %1) path)]
+        (if (not (= old-val new-val))
+          (dosync (ref-set (assoc-in @root* path-keys
+                                     (concat
+                                       [new-val])))))))
+
+    (getIndexOfChild [parent child]
+      (first (filter (fn [[idx v]] (= child v))
+                     (indexed (second parent)))))))
+
+(defn synth-tree []
+  (let [tree (JTree. (tree-model synths*))
+        scroller (JScrollPane. tree)]
+    (doto tree
+      (.setCellRenderer (tree-cell-renderer))
+      (.setRootVisible false)
+      (.putClientProperty "JTree.lineStyle", "None"))
+    scroller))
+
+(defn editor []
+  (let [editor-pane (JPanel.)
+        editor (JTextPane.)
+        scroller (JScrollPane. editor)
+        status-pane (JPanel.)
+        status (JLabel. "Overtone Live!")
+        font (Font. DEFAULT-FONT
+                    Font/PLAIN
+                    DEFAULT-FONT-SIZE)
+        _ (.setFont editor font)
+        font (.getFont editor)
+        fm (.getFontMetrics editor font)
+        width (* 81 (.charWidth fm \space))
+        height (* 30 (.getHeight fm))]
+    (doto editor-pane
+      (.setLayout (BorderLayout.))
+      (.add scroller BorderLayout/CENTER)
+      (.add status-pane BorderLayout/SOUTH))))
+
+(defn make-repl []
+  (.getReplPanel (create-in-proc-repl)))
+
+(defn main []
+  (let [app-frame (JFrame. APP-NAME)
+        app-pane (.getContentPane app-frame)
+        synth-tree (synth-tree)
+        editor-pane (editor)
+        split-pane (JSplitPane. JSplitPane/HORIZONTAL_SPLIT
+                                synth-tree editor-pane)]
+
+    (doto app-pane
+      (.setLayout (BorderLayout.))
+      ;(.add  BorderLayout/WEST)
+      (.add split-pane BorderLayout/CENTER)
+      (.add (make-repl) BorderLayout/SOUTH))
+
+    ;(.. scroll-pane (getViewport) (setPreferredSize (Dimension. width height)))
+    (doto app-frame
+      (.setJMenuBar (app-menu-bar))
+      (.pack)
+      (.setSize (screen-dim)) ; Fullscreen by default
+      (.setVisible true))
+
+    (.setDividerLocation split-pane 0.1)))
+


Refactor send-notifications out of handle-send*

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


Fix doc string

Fix doc string

--- src/ruuvi_server/util.clj
+++ src/ruuvi_server/util.clj
@@ -10,8 +10,9 @@
     (:use [clojure.tools.logging :only (debug info warn error)])
     )

-(defn modify-map [data key-modifiers value-modifiers]
+(defn modify-map
   "Goes through all entries in data map and converts values"
+  [data key-modifiers value-modifiers]
   (into {}
         (for [[key value] data]
           (let [new-value


rev comments re: cache thread-safety

rev comments re: cache thread-safety

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


app-state should be define only once

app-state should be define only once

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


Expose session store to allow clearing during tests

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


util/s3.clj: started interface to S3

util/s3.clj: started interface to S3

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

--- src/org/altlaw/util/s3.clj
+++ src/org/altlaw/util/s3.clj
@@ -0,0 +1,43 @@
+(ns org.altlaw.util.s3
+  (:import (org.jets3t.service.impl.rest.httpclient RestS3Service)
+           (org.jets3t.service.model S3Bucket S3Object)
+           (org.jets3t.service.security AWSCredentials)))
+
+(def #^{:private true} get-s3
+     (memoize (fn [] (RestS3Service.
+                      (AWSCredentials. (System/getenv "AWS_ACCESS_KEY_ID")
+                                       (System/getenv "AWS_SECRET_ACCESS_KEY"))))))
+
+(def #^{:private true} get-bucket
+     (memoize (fn [x]
+                (if (instance? S3Bucket x) x
+                    (.getBucket (get-s3) x)))))
+
+(defn- make-bucket-symbol [bucket]
+  (with-meta (symbol (.getName bucket))
+             (into {} (.getMetadataMap bucket))))
+
+(defn- make-object-symbol [object]
+  (with-meta (symbol (.getKey object))
+             (into {} (.getMetadataMap object))))
+
+(defn list-buckets
+  "Returns a list of symbols.  Each symbol has a name matching a
+  bucket name, and metadata matching that bucket's S3 metadata."
+  []
+  (map make-object-symbol
+       (.listAllBuckets (get-s3))))
+
+(defn list-objects
+  ([bucket-name]
+     (.listObjects (get-s3) (get-bucket bucket-name)))
+  ([bucket-name prefix]
+     (.listObjects (get-s3) (get-bucket bucket-name) nil)))
+
+(defn get-object [bucket-name object-key]
+  (.getObject (get-s3) (get-bucket bucket-name) object-key))
+
+(defn get-object-meta [bucket-name object-key]
+  (into {} (.getMetadataMap
+            (.getObjectDetails (get-s3) (get-bucket bucket-name)
+                               object-key))))


Testing Specter fix.

Testing Specter fix.

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


"old core" commented code no longer needed for reference


Add clojure.walk with minimal porting

Add clojure.walk with minimal porting

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

--- src/cljs/clojure/walk.cljs
+++ src/cljs/clojure/walk.cljs
@@ -0,0 +1,94 @@
+;   Copyright (c) Rich Hickey. All rights reserved.
+;   The use and distribution terms for this software are covered by the
+;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;   which can be found in the file epl-v10.html at the root of this distribution.
+;   By using this software in any fashion, you are agreeing to be bound by
+;   the terms of this license.
+;   You must not remove this notice, or any other, from this software.
+
+;;; walk.cljs - generic tree walker with replacement
+
+;; by Stuart Sierra
+;; Jul5 17, 2011
+
+;; CHANGE LOG:
+;;
+;; * July 17, 2011: Port to ClojureScript
+;;
+;; * December 15, 2008: replaced 'walk' with 'prewalk' & 'postwalk'
+;;
+;; * December 9, 2008: first version
+
+
+(ns
+  ^{:author "Stuart Sierra",
+     :doc "This file defines a generic tree walker for Clojure data
+structures.  It takes any data structure (list, vector, map, set,
+seq), calls a function on every element, and uses the return value
+of the function in place of the original.  This makes it fairly
+easy to write recursive search-and-replace functions, as shown in
+the examples.
+
+Note: \"walk\" supports all Clojure data structures EXCEPT maps
+created with sorted-map-by.  There is no (obvious) way to retrieve
+the sorting function."}
+  clojure.walk)
+
+(defn walk
+  "Traverses form, an arbitrary data structure.  inner and outer are
+  functions.  Applies inner to each element of form, building up a
+  data structure of the same type, then applies outer to the result.
+  Recognizes all Clojure data structures. Consumes seqs as with doall."
+
+  {:added "1.1"}
+  [inner outer form]
+  (cond
+   (seq? form) (outer (doall (map inner form)))
+   (coll? form) (outer (into (empty form) (map inner form)))
+   :else (outer form)))
+
+(defn postwalk
+  "Performs a depth-first, post-order traversal of form.  Calls f on
+  each sub-form, uses f's return value in place of the original.
+  Recognizes all Clojure data structures. Consumes seqs as with doall."
+  {:added "1.1"}
+  [f form]
+  (walk (partial postwalk f) f form))
+
+(defn prewalk
+  "Like postwalk, but does pre-order traversal."
+  {:added "1.1"}
+  [f form]
+  (walk (partial prewalk f) identity (f form)))
+
+(defn keywordize-keys
+  "Recursively transforms all map keys from strings to keywords."
+  {:added "1.1"}
+  [m]
+  (let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
+    ;; only apply to maps
+    (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
+
+(defn stringify-keys
+  "Recursively transforms all map keys from keywords to strings."
+  {:added "1.1"}
+  [m]
+  (let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
+    ;; only apply to maps
+    (postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
+
+(defn prewalk-replace
+  "Recursively transforms form by replacing keys in smap with their
+  values.  Like clojure/replace but works on any data structure.  Does
+  replacement at the root of the tree first."
+  {:added "1.1"}
+  [smap form]
+  (prewalk (fn [x] (if (contains? smap x) (smap x) x)) form))
+
+(defn postwalk-replace
+  "Recursively transforms form by replacing keys in smap with their
+  values.  Like clojure/replace but works on any data structure.  Does
+  replacement at the leaves of the tree first."
+  {:added "1.1"}
+  [smap form]
+  (postwalk (fn [x] (if (contains? smap x) (smap x) x)) form))


Start bridge to fcalib

Start bridge to fcalib

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

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

--- src/conexp/util/fcalib.clj
+++ src/conexp/util/fcalib.clj
@@ -0,0 +1,36 @@
+;; Copyright (c) Daniel Borchmann. All rights reserved.
+;; The use and distribution terms for this software are covered by the
+;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;; which can be found in the file LICENSE at the root of this distribution.
+;; By using this software in any fashion, you are agreeing to be bound by
+;; the terms of this license.
+;; You must not remove this notice, or any other, from this software.
+
+(ns conexp.util.fcalib
+  (:use conexp.base)
+  (:import [de.tudresden.inf.tcs.fcaapi FCAImplication]
+           [de.tudresden.inf.tcs.fcalib Implication]
+           ;; for now, we use conexp-ng's implementation, until the corresponding code is
+           ;; available in fcalib
+           [fcatools.conexpng.model FormalContext]))
+
+;;
+
+(defn fcalib-to-context [conexp-clj-context]
+  (not-yet-implemented))
+
+(defn fcalib-from-context [^FormalContext fcalib-context]
+  (not-yet-implemented))
+
+(defn fcalib-to-implication [conexp-clj-implication]
+  (not-yet-implemented))
+
+(defn fcalib-from-implication [^FCAImplication fcalib-implication]
+  (not-yet-implemented))
+
+(defn fcalib-to-implication-set [conexp-clj-set-of-implications]
+  (not-yet-implemented))
+
+;;
+
+nil


Start on radar display of solution scores

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

--- src/dot_utility/radial.clj
+++ src/dot_utility/radial.clj
@@ -0,0 +1,128 @@
+(ns dot-utility.radial
+  (:import [javax.swing JFrame JPanel]
+           [java.awt BorderLayout RenderingHints Color Dimension Graphics2D BasicStroke]
+           [java.awt.geom Path2D$Double Line2D$Double]))
+
+(def default-frame-options
+     {:title "Radar display"
+      :width 400
+      :height 400})
+
+(def pi2 (* 2.0 Math/PI))
+(defn cos [^double a] (Math/cos a))
+(defn sin [^double a] (Math/sin a))
+
+(def color-axis (Color. 186 186 186))
+(def color-score (Color. 156 158 222))
+(def color-outline (Color. 109 110 155))
+(def color-fill (Color. 156 158 222 64))
+
+(defn petals-on-the-rose
+  [ds scale-fn]
+  (let [theta (/ pi2 (count ds))]
+    (loop [m []
+           n 0
+           ang (/ Math/PI 2.0)
+           [[_ value domain] & more] (seq ds)]
+      (if value
+        (recur (conj m
+                      {:angle ang
+                       :radius (scale-fn value domain)})
+               (inc n)
+               (+ ang theta)
+               more)
+        m))))
+
+(defn points [ds]
+  (petals-on-the-rose ds /))
+
+(defn axes [ds]
+  (petals-on-the-rose ds (constantly 1.0)))
+
+(defn polar->cartesian
+  [polars]
+  (reduce
+   (fn [coords {radius :radius angle :angle}]
+     (conj coords {:x (* radius (cos angle))
+                   :y (* radius (sin angle))}))
+   []
+   polars))
+
+(defn line
+  [^double x1 ^double y1 ^double x2 ^double y2]
+  (new Line2D$Double x1 y1 x2 y2))
+
+(defn radii
+  [pts]
+  (map (fn [{x :x y :y}] (line 0 0 x y)) pts))
+
+(defn hull
+  [pts]
+  (let [path (Path2D$Double.)
+        {x-org :x y-org :y} (first pts)
+        rest (reverse pts)]
+    (.moveTo path x-org y-org)
+    (doseq [{x :x y :y} rest]
+      (.lineTo path x y))
+    path))
+
+(defn draw-radar
+  [^Graphics2D g ds w h]
+  (let [scale (/ (min w h) 2.0)
+        pen-width (/ 1.5 scale)
+        mapping (affine-mapping scale (- scale) (/ w 2) (/ h 2))
+        axes (polar->cartesian (axes ds))
+        scores (polar->cartesian (points ds))
+        hull (hull scores)
+        ]
+    #_(.scale g scale (- scale))
+    (.translate g (/ w 2.0) (/ h 2.0))
+    (.scale g scale (- scale))
+    (.setStroke g (BasicStroke. pen-width))
+    (.setColor g color-axis)
+    (doseq [l (radii axes)]
+      (.draw g l))
+    (.setStroke g (BasicStroke. (* 2 pen-width)))
+    (.setColor g color-score)
+    (doseq [l (radii scores)]
+      (.draw g l))
+    (.setColor g color-fill)
+    (.fill g hull)
+    (.setColor g color-outline)
+    (.draw g hull)))
+
+(defn antialias
+  "Return a Graphics object with antialiasing turned on.
+   Does not mutate the original"
+  [g]
+  (if (= RenderingHints/VALUE_ANTIALIAS_ON (.getRenderingHint g RenderingHints/KEY_ANTIALIASING))
+    g
+    (doto (.create g)
+      (.setRenderingHint RenderingHints/KEY_ANTIALIASING RenderingHints/VALUE_ANTIALIAS_ON))))
+
+(defn make-radar-panel
+  [ds width height]
+  (doto
+      (proxy [javax.swing.JComponent] []
+        (paintComponent [g]
+                        (draw-radar (antialias g) ds (.getWidth this) (.getHeight this))))))
+
+(defn show-radar-display
+  "Display a new window with a radar plot of the given data items.
+
+   width and height control the size of the window.
+
+   Each item is a list of (label, score, max-score). E.g., (\"Performance\", 3, 10) means
+   that the Performance measure scored 3 out of a possible 10. (All scores start from 0.)"
+  [ds & options]
+  (let [{:keys [width height title]} (into default-frame-options (apply hash-map options))
+        radar (make-radar-panel ds width height)
+        panel (doto (JPanel.)
+                (.setBorder (javax.swing.BorderFactory/createEmptyBorder 20 20 20 20))
+                (.setLayout (BorderLayout.))
+                (.add radar BorderLayout/CENTER))]
+    (doto (JFrame. title)
+      (.add panel)
+      (.setSize width height)
+      (.show))
+    radar))


explicit str

explicit str

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/AustinC/persistent-internals.git/'


Added old version of close-under-implications

since the new (LinClosure) was too slow. Also made
close-under-implications public.

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -66,36 +66,63 @@
   (forall [intent (context-intents ctx)]
     (respects? intent impl)))

-(set! *warn-on-reflection* true)
-
-(defn- close-under-implications
-  "Computes smallest superset of start being closed under given implications."
-  [implications start]
-  ;; this is LinClosure
-  (let [^HashMap counts (HashMap.),
-        ^HashMap list   (HashMap.),
-        ^HashSet update (HashSet. ^java.util.Collection start),
-        ^HashSet newdep (HashSet. ^java.util.Collection start)]
-    (doseq [impl implications,
-            :let [impl-count (count (premise impl))]]
-      (.put counts impl impl-count)
-      (if (zero? impl-count)
-        (do (.addAll update (conclusion impl))
-            (.addAll newdep (conclusion impl)))
-        (doseq [a (premise impl)]
-          (.put list a (conj (.get list a) impl)))))
-    (while (not (.isEmpty update))
-      (let [a (first update)]
-        (.remove update a)
-        (doseq [impl (.get list a)
-                :let [impl-count (.get counts impl)]]
-          (.put counts impl (dec impl-count))
-          (when (zero? (dec impl-count))
-            (doseq [x (conclusion impl)
-                    :when (not (.contains newdep x))]
-              (.add newdep x)
-              (.add update x))))))
-    (set newdep)))
+(defn- add-immediate-elements
+  "Adds all elements which follow from implications with premises in
+  initial-set."
+  [implications initial-set]
+  (loop [conclusions  [],
+         impls        implications,
+         unused-impls []]
+    (if (empty? impls)
+      [(apply union initial-set conclusions) unused-impls]
+      (let [impl (first impls)]
+        (if (and (subset? (premise impl) initial-set)
+                 (not (subset? (conclusion impl) initial-set)))
+          (recur (conj conclusions (conclusion impl))
+                 (rest impls)
+                 unused-impls)
+          (recur conclusions
+                 (rest impls)
+                 (conj unused-impls impl)))))))
+
+(defn close-under-implications
+  "Computes smallest superset of set being closed under given implications."
+  [implications set]
+  (loop [set   set,
+         impls implications]
+    (let [[new impls] (add-immediate-elements impls set)]
+      (if (= new set)
+        new
+        (recur new impls)))))
+
+;; (defn- close-under-implications
+;;   "Computes smallest superset of start being closed under given implications."
+;;   [implications start]
+;;   ;; this is LinClosure
+;;   (let [^HashMap counts (HashMap.),
+;;         ^HashMap list   (HashMap.),
+;;         ^HashSet update (HashSet. ^java.util.Collection start),
+;;         ^HashSet newdep (HashSet. ^java.util.Collection start)]
+;;     (doseq [impl implications,
+;;             :let [impl-count (count (premise impl))]]
+;;       (.put counts impl impl-count)
+;;       (if (zero? impl-count)
+;;         (do (.addAll update (conclusion impl))
+;;             (.addAll newdep (conclusion impl)))
+;;         (doseq [a (premise impl)]
+;;           (.put list a (conj (.get list a) impl)))))
+;;     (while (not (.isEmpty update))
+;;       (let [a (first update)]
+;;         (.remove update a)
+;;         (doseq [impl (.get list a)
+;;                 :let [impl-count (.get counts impl)]]
+;;           (.put counts impl (dec impl-count))
+;;           (when (zero? (dec impl-count))
+;;             (doseq [x (conclusion impl)
+;;                     :when (not (.contains newdep x))]
+;;               (.add newdep x)
+;;               (.add update x))))))
+;;     (set newdep)))

 (defn clop-by-implications
   "Returns closure operator given by implications."


ok so the regex needed one more tweak :sweat:

--- src/metabase/models/common.clj
+++ src/metabase/models/common.clj
@@ -31,7 +31,7 @@
   [^String n]
   (when (seq n)
     (when-let [n (some-> n
-                         (s/replace #"^(.+)(?:[-_]id)$" "$1")                         ; strip off any trailing _id or -id suffix
+                         (s/replace #"^(.+)(?:[-_](?:id)|(?:ID))$" "$1")              ; strip off any trailing _id/_ID/-id/-ID suffix
                          (s/split #"_|-"))]                                           ; explode string on underscores and hyphens
       (->> (for [[first-letter & rest-letters] (filter (complement s/blank?) n)]      ; for each part of the string,
              (apply str (s/upper-case first-letter) (map s/lower-case rest-letters))) ; upcase the first char and downcase the rest


initial; designing alongside cards

initial; designing alongside cards

--- src/cards.clj
+++ src/cards.clj
@@ -0,0 +1,1011 @@
+; as of 12/30/2013 via Hearthpwn's card db
+(ns soot.db)
+
+(def cards [
+; Misc
+{
+  :id 552
+  :name "Chicken"
+  :cost 0
+  :minion {
+    :attack 1
+    :health 1
+    :type :beast
+  }
+}
+{
+  :id 520
+  :name "Excess Mana"
+  :class :druid
+  :cost 0
+  :spell (draw-cards 1)
+}
+{
+  :id 714
+  :name "I Am Murloc"
+  :spell #((summon-minion (repeat (rand-nth [3 4 5]) 715)) %) ; 715 = 1/1 Murloc
+}
+{
+  :id 715
+  :name "Murloc"
+  :cost 1
+  :minion {
+    :attack 1
+    :health 1
+    :type :beast
+  }
+}
+{
+  :id 717
+  :name "Power of the Horde"
+  :spell #((summon-minion (rand-nth ["Frostwolf Grunt" "Sen'jin Shieldmasta"
+    "Cairne Bloodhoof" "Tauren Warrior" "Thrallmar Farseer"
+    "Silvermoon Guardian"])) %)
+}
+{
+  :id 716
+  :name "Rogues Do It..."
+  :spell (-> % (deal-damage 4) (draw-cards 1))
+}
+; The Coin
+{
+  :id 141
+  :name "The Coin"
+  :cost 0
+  :spell (add-temporary-mana 1)
+}
+; Legendaries
+{
+  :id 335
+  :name "Al'Akir the Windlord"
+  :quality :legendary
+  :class :shaman
+  :cost 8
+  :minion {
+    :attack 3
+    :health 5
+    :properties [:windfury :charge :divine-shield :taunt]
+  }
+}
+{
+  :id 303
+  :name "Alexstrasza"
+  :quality :legendary
+  :cost 9
+  :minion {
+    :attack 8
+    :health 8
+    :type :dragon
+    :battlecry (set-hero-health 15)
+  }
+}
+{
+  :id 220
+  :name "Archmage Antonidas"
+  :quality :legendary
+  :class :mage
+  :cost 7
+  :minion {
+    :attack 5
+    :health 7
+    :when-my-spell-cast (give-card "Fireball")
+  }
+}
+{
+  :id 53
+  :name "Ashbringer"
+  :quality :legendary
+  :class :paladin
+  :cost 5
+  :weapon {
+    :attack 5
+    :durability 5
+  }
+}
+{
+  :id 359
+  :name "Baine Bloodhoof"
+  :quality :legendary
+  :cost 4
+  :minion {
+    :attack 4
+    :health 5
+  }
+}
+{
+  :id 539
+  :name "Baron Geddon"
+  :quality :legendary
+  :cost 7
+  :minion {
+    :attack 7
+    :health 5
+    :end-of-my-turn (damage-all 2)
+  }
+}
+{
+  :id 525
+  :name "Bloodmage Thalnos"
+  :quality :legendary
+  :cost 2
+  :minion {
+    :attack 1
+    :health 1
+    :spell-damage 1
+    :deathrattle (draw-cards 1)
+  }
+}
+{
+  :id 498
+  :name "Cairne Bloodhoof"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 4
+    :health 5
+    :deathrattle (summon-minion "Baine Bloodhoof")
+  }
+}
+{
+  :id 267
+  :name "Captain Greenskin"
+  :quality :legendary
+  :cost 5
+  :minion {
+    :attack 5
+    :health 4
+    :type :pirate
+    :battlecry (buff-weapon 1 1)
+  }
+}
+{
+  :id 605
+  :name "Cenarius"
+  :quality :legendary
+  :class :druid
+  :cost 9
+  :minion {
+    :attack 5
+    :health 8
+    :battlecry (choose (buff-minions 2 2) (summon-minion [181 181])) ; 181 = Taunt Treant
+  }
+}
+{
+  :id 474
+  :name "Deathwing"
+  :quality :legendary
+  :cost 10
+  :minion {
+    :attack 12
+    :health 12
+    :type :dragon
+    :battlecry (comp (destroy-minions) (discard :all))
+  }
+}
+{
+  :id 3
+  :name "Edwin VanCleef"
+  :quality :legendary
+  :class :rogue
+  :cost 3
+  :minion {
+    :attack 2
+    :health 2
+    ; todo: make this less shitty
+    :combo #((apply buff-self (repeat 2 (* 2 (cards-played-this-turn %)))) %)
+  }
+}
+{
+  :id 682
+  :name "Elite Tauren Chieftan"
+  :quality :legendary
+  :cost 5
+  :minion {
+    :attack 5
+    :health 5
+    :battlecry (#(comp (give-card (%)) (give-opponent-card (%)))
+      #(rand-nth ["I Am Murloc" "Power of the Horde" "Rogues Do It..."]))
+  }
+}
+{
+  :id 541
+  :name "Finkle Einhorn"
+  :quality :legendary
+  :cost 2
+  :minion {
+    :attack 3
+    :health 3
+  }
+}
+{
+  :id 251
+  :name "Gelbin Mekkatorque"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 6
+    :health 6
+    :battlecry #((summon-minion (rand-nth
+      ["Emboldener 3000" "Homing Chicken" "Poultryizer" "Repair Bot"])) %)
+  }
+}
+{
+  :id 643
+  :name "Grommash Hellscream"
+  :quality :legendary
+  :class :warrior
+  :cost 8
+  :minion {
+    :attack 4
+    :health 9
+    :properties [:charge]
+    :enrage (buff-self 6 0)
+  }
+}
+{
+  :id 18
+  :name "Gruul"
+  :quality :legendary
+  :cost 8
+  :minion {
+    :attack 7
+    :health 7
+    :end-of-turn (buff-self 1 1)
+  }
+}
+{
+  :id 602
+  :name "Harrison Jones"
+  :quality :legendary
+  :cost 5
+  :minion {
+    :attack 5
+    :health 4
+    :battlecry #(-> %
+      (draw-cards (opponent-weapon-durability %))
+      (destroy-opponent-weapon))
+  }
+}
+{
+  :id 39
+  :name "Hogger"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 4
+    :health 4
+    :end-of-my-turn (summon-minion 565) ; 565 = Taunt Gnoll
+  }
+}
+{
+  :id 203
+  :name "Illidan Stormrage"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 7
+    :health 5
+    :type :demon
+    :when-my-card-played (summon-minion "Flame of Azzinoth")
+  }
+}
+{
+  :id 194
+  :name "King Krush"
+  :quality :legendary
+  :class :hunter
+  :cost 9
+  :minion {
+    :attack 8
+    :health 8
+    :type :beast
+    :properties [:charge]
+  }
+}
+{
+  :id 373
+  :name "King Mukla"
+  :quality :legendary
+  :cost 3
+  :minion {
+    :attack 5
+    :health 5
+    :type :beast
+    :battlecry (give-opponent-card (repeat 2 "Bananas"))
+  }
+}
+{
+  :id 674
+  :name "Leeroy Jenkins"
+  :quality :legendary
+  :cost 4
+  :minion {
+    :attack 6
+    :health 2
+    :properties [:charge]
+    :battlecry (summon-opponent-minion (repeat 2 "Whelp"))
+  }
+}
+{
+  :id 482
+  :name "Lord Jaraxxus"
+  :quality :legendary
+  :class :warlock
+  :cost 9
+  :minion {
+    :attack 3
+    :health 15
+    :type :demon
+    :battlecry #(-> %
+      (set-hero 406) ; Lord Jaraxxus hero
+      ; So that any Secrets/etc. that modify minion HP take effect
+      ; 'my-health' since the state has always one acting character
+      ; unsure if positive health effects take place? doubtful
+      (set-hero-health (my-health %))
+      (equip-weapon "Blood Fury")
+      (destroy-self))
+  }
+}
+{
+  :id 406
+  :name "Lord Jaraxxus"
+  :class :warlock
+  :hero {
+    :health 15
+    :type :demon
+    :power "INFERNO!"
+  }
+}
+{
+  :id 456
+  :name "Lorewalker Cho"
+  :quality :legendary
+  :cost 2
+  :minion {
+    :attack 0
+    :health 4
+    :when-spell-cast #((give-opponent-card (current-spell %)) %)
+  }
+}
+{
+  :id 241
+  :name "Malygos"
+  :quality :legendary
+  :cost 9
+  :minion {
+    :attack 4
+    :health 12
+    :type :dragon
+    :spell-damage 5
+  }
+}
+{
+  :id 339
+  :name "Millhouse Manastorm"
+  :quality :legendary
+  :cost 2
+  :minion {
+    :attack 4
+    :health 4
+    :battlecry (next-turn (spells-cost 0)) ; next turn is always a 'half-turn'.
+  }
+}
+{
+  :id 19
+  :name "Nat Pagle"
+  :quality :legendary
+  :cost 2
+  :minion {
+    :attack 0
+    :health 4
+    :end-of-my-turn #((draw-cards (rand-nth [0 1])) %)
+  }
+}
+{
+  :id 285
+  :name "Nozdormu"
+  :quality :legendary
+  :cost 9
+  :minion {
+    :attack 8
+    :health 8
+    :type :dragon
+    :start-of-turn (set-time-limit 15/90) ; How the fuck am I gonna do this?
+  }
+}
+{
+  :id 217
+  :name "Old Murk-Eye"
+  :quality :legendary
+  :cost 4
+  :minion {
+    :attack #(+ 2 (count-minions % :murloc))
+    :health 4
+    :type :murloc
+    :properties [:charge]
+  }
+}
+{
+  :id 432
+  :name "Onyxia"
+  :quality :legendary
+  :cost 9
+  :minion {
+    :attack 8
+    :health 8
+    :type :dragon
+    :battlecry (summon-minion (repeat 6 527)) ; 527 = 1/1 Whelp
+  }
+}
+{
+  :id 228
+  :name "Prophet Velen"
+  :quality :legendary
+  :class :priest
+  :cost 7
+  :minion {
+    :attack 7
+    :health 7
+    :when-my-spell-cast (modify-damage-and-healing (partial * 2))
+    :when-my-hero-power-used (modify-damage-and-healing (partial * 2))
+  }
+}
+{
+  :id 503
+  :name "Ragnaros the Firelord"
+  :quality :legendary
+  :cost 8
+  :minion {
+    :attack 8
+    :health 8
+    :properties [:cant-attack]
+    :end-of-my-turn (damage-random-enemy 8)
+  }
+}
+{
+  :id 33
+  :name "Sylvanas Windrunner"
+  :quality :legendary
+  :cost 5
+  :minion {
+    :attack 5
+    :health 5
+    :deathrattle (mind-control-random)
+  }
+}
+{
+  :id 179
+  :name "The Beast"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 9
+    :health 7
+    :type :beast
+    :deathrattle (summon-opponent-minion "Finkle Einhorn")
+  }
+}
+{
+  :id 396
+  :name "The Black Knight"
+  :quality :legendary
+  :cost 6
+  :minion {
+    :attack 4
+    :health 5
+    :battlecry (target :taunt (destroy-target))
+  }
+}
+{
+  :id 245
+  :name "Tinkmaster Overspark"
+  :quality :legendary
+  :cost 3
+  :minion {
+    :attack 2
+    :health 2
+    :battlecry (target :minion
+      #((polymorph-target (rand-nth ["Devilsaur" "Squirrel"])) %))
+  }
+}
+{
+  :id 391
+  :name "Tirion Fordring"
+  :quality :legendary
+  :class :paladin
+  :cost 8
+  :minion {
+    :attack 6
+    :health 6
+    :properties [:divine-shield :taunt]
+    :deathrattle (equip-weapon "Ashbringer")
+  }
+}
+{
+  :id 495
+  :name "Ysera"
+  :quality :legendary
+  :cost 9
+  :minion {
+    :attack 4
+    :health 12
+    :end-of-my-turn #((give-card (rand-nth ["Dream"
+      "Emerald Drake" "Laughing Sister" "Nightmare" "Ysera Awakens"])) %)
+  }
+}
+{
+  :id 180
+  :name "Adrenaline Rush"
+  :quality :epic
+  :class :rogue
+  :cost 1
+  :spell (combo (draw-cards 1) (draw-cards 2))
+}
+{
+  :id 34
+  :name "Ancient of Lore"
+  :quality :epic
+  :class :druid
+  :cost 7
+  :minion {
+    :attack 5
+    :health 5
+    :battlecry (choose (draw-cards 2) (heal-hero 5))
+  }
+}
+{
+  :id 242
+  :name "Ancient of War"
+  :quality :epic
+  :class :druid
+  :cost 7
+  :minion {
+    :attack 5
+    :health 5
+    :battlecry (choose
+      #(-> % (give-self-taunt) (buff-self 0 5)) (buff-self 5 0))
+  }
+}
+{
+  :id 142
+  :name "Avenging Wrath"
+  :quality :epic
+  :class :paladin
+  :cost 6
+  :spell (apply comp (repeat 8 (target-random :opponent (deal-damage 1))))
+}
+{
+  :id 670
+  :name "Bane of Doom"
+  :quality :epic
+  :class :warlock
+  :cost 5
+  :spell #(-> %
+    (deal-damage 2)
+    (summon-minion-if #(is-dead % (last-targeted-character %))
+      (rand-nth ["Blood Imp" "Voidwalker" "Flame Imp"
+      "Dread Infernal" "Succubus" "Felguard"])))
+}
+{
+  :id 304
+  :name "Bestial Wrath"
+  :quality :epic
+  :class :hunter
+  :cost 1
+  :spell (target :beast #(-> %
+    (buff-target 2 0)
+    (give-target :immune)))
+}
+{
+  :id 73
+  :name "Big Game Hunter"
+  :quality :epic
+  :cost 3
+  :minion {
+    :attack 4
+    :health 2
+    :battlecry (target [:minion (> (:attack %) 6)]
+      (destroy-target))
+  }
+}
+{
+  :id 75
+  :name "Blood Knight"
+  :quality :epic
+  :cost 3
+  :minion {
+    :attack 3
+    :health 3
+    :battlecry #(-> %
+      (apply buff-self (repeat 2 (* 3 (count-minions % :divine-shield))))
+      (remove-all :divine-shield))
+  }
+}
+{
+  :id 297
+  :name "Brawl"
+  :quality :epic
+  :class :warrior
+  :cost 5
+  :spell #((apply comp (repeat (+ (count-minions %) -1)
+    (target-random :minion (destroy-target)))) %)
+}
+{
+  :id 147
+  :name "Cabal Shadow Priest"
+  :quality :epic
+  :class :priest
+  :cost 6
+  :minion {
+    :attack 4
+    :health 5
+    :battlecry (target [:opponent :minion #(< (:attack %) 3)]
+      (mind-control-target))
+  }
+}
+{
+  :id 559
+  :name "Captain's Parrot"
+  :quality :epic
+  :cost 2
+  :minion {
+    :attack 1
+    :health 1
+    :type :beast
+    :battlecry (draw-random :pirate)
+  }
+}
+{
+  :id 172
+  :name "Doomhammer"
+  :quality :epic
+  :class :shaman
+  :cost 5
+  :overload 2
+  :weapon {
+    :attack 2
+    :durability 8
+    :properties [:windfury]
+  }
+}
+{
+  :id 467
+  :name "Doomsayer"
+  :quality :epic
+  :cost 2
+  :minion {
+    :attack 0
+    :health 7
+    :start-of-my-turn (destroy-minions)
+  }
+}
+{
+  :id 124
+  :name "Earth Elemental"
+  :quality :epic
+  :class :shaman
+  :cost 5
+  :overload 3
+  :minion {
+    :attack 7
+    :health 8
+    :properties [:taunt]
+  }
+}
+{
+  :id 450
+  :name "Faceless Manipulator"
+  :quality :epic
+  :cost 5
+  :minion {
+    :attack 3
+    :health 3
+    ; i.e. replace my minion slot's values with that of the target
+    :battlecry (target :minion (copy-target))
+  }
+}
+{
+  :id 107
+  :name "Far Sight"
+  :quality :epic
+  :class :shaman
+  :cost 3
+  :spell (comp
+    #((modify-card-cost (last-card-drawn %) (partial + -3)) %)
+    (draw-cards 1))
+}
+{
+  :id 237
+  :name "Force of Nature"
+  :quality :epic
+  :class :druid
+  :cost 6
+  :spell (summon-minion (repeat 3 337))
+}
+{
+  :id 278
+  :name "Gladiator's Longbow"
+  :quality :epic
+  :class :hunter
+  :cost 7
+  :weapon {
+    :attack 5
+    :durability 2
+    :immune ; todo, remember to interpret this tag for weapons
+  }
+}
+{
+  :id 96
+  :name "Gorehowl"
+  :quality :epic
+  :class :warrior
+  :cost 7
+  :weapon {
+    :attack 7
+    :durability 1
+    :when-minion-attacked (buff-self -1 1) ; todo, remember to interpret this too
+  }
+}
+{
+  :id 660
+  :name "Hungry Crab"
+  :quality :epic
+  :cost 1
+  :minion {
+    :attack 1
+    :health 2
+    :type :beast
+    :battlecry (target :murloc #(-> % (destroy-target) (buff-self 2 2)))
+  }
+}
+{
+  :id 28
+  :name "Ice Block"
+  :quality :epic
+  :class :mage
+  :cost 3
+  :secret {
+    :when-hero-takes-damage #(if (< (hero-health %) 1)
+      (-> %
+        (heal-hero (damage-taken %))
+        (give-hero :immune)))
+  }
+}
+{
+  :id 562
+  :name "Kidnapper"
+  :quality :epic
+  :class :rogue
+  :cost 6
+  :minion {
+    :attack 5
+    :health 5
+    :combo (target :minion (return-to-hand))
+  }
+}
+{
+  :id 506
+  :name "Lay on Hands"
+  :quality :epic
+  :class :paladin
+  :cost 8
+  :spell #(-> (heal-hero 8) (draw-cards 3))
+}
+{
+  :id 301
+  :name "Mindgames"
+  :quality :epic
+  :class :priest
+  :cost 4
+  :spell #(if (> (count (filter-all % [:opponent :undrawn :minion])) 0)
+    ((summon-minion (rand-nth (filter-all % [:opponent :undrawn :minion]))) %)
+    ((summon-minion 582) %)) ; 582 = Shadow of Nothing
+}
+{
+  :id 94
+  :name "Molten Giant"
+  :quality :epic
+  :cost #(+ 20 (- (hero-health %) (hero-max-health %)))
+  :minion {
+    :attack 8
+    :health 8
+  }
+}
+{
+  :id 264
+  :name "Mountain Giant"
+  :quality :epic
+  :cost #(- 12 (cards-in-hand %))
+  :minion {
+    :attack 8
+    :health 8
+  }
+}
+{
+  :id 222
+  :name "Murloc Warleader"
+  :quality :epic
+  :cost 3
+  :minion {
+    :attack 3
+    :health 3
+    :type :murloc
+    :aura {:filter :murloc :attack #(+ 2 %) :health #(+ 1 %)}
+  }
+}
+{
+  :id 14
+  :name "Patient Assassin"
+  :quality :epic
+  :class :rogue
+  :cost 2
+  :minion {
+    :attack 1
+    :health 1
+    :properties [:stealth :poison]
+  }
+}
+{
+  :id 402
+  :name "Pit Lord"
+  :quality :epic
+  :class :warlock
+  :cost 4
+  :minion {
+    :attack 5
+    :health 6
+    :type :demon
+    :battlecry (damage-hero 5)
+  }
+}
+{
+  :id 364
+  :name "Preparation"
+  :quality :epic
+  :class :rogue
+  :cost 0
+  :spell (once-this-turn (spells-cost #(- % 3)))
+}
+{
+  :id 496
+  :name "Pyroblast"
+  :quality :epic
+  :class :mage
+  :cost 8
+  :spell (target :character (damage-target 10))
+}
+{
+  :id 614
+  :name "Sea Giant"
+  :quality :epic
+  :cost (- 10 (count-minions))
+  :minion {
+    :attack 8
+    :health 8
+  }
+}
+{
+  :id 582
+  :name "Shadow of Nothing"
+  :quality :epic
+  :class :priest
+  :cost 0
+  :minion {
+    :attack 0
+    :health 1
+  }
+}
+{
+  :id 421
+  :name "Shadowform"
+  :quality :epic
+  :class :priest
+  :cost 3
+  :spell #(if (= (:name (hero-power %)) "Mind Spike")
+    ((set-hero-power "Mind Shatter") %)
+    ((set-hero-power "Mind Spike") %))
+}
+{
+  :id 50
+  :name "Shield Slam"
+  :quality :epic
+  :class :warrior
+  :cost 1
+  :spell (target :minion #((damage-target (hero-armor %)) %))
+}
+{
+  :id 210
+  :name "Snake Trap"
+  :quality :epic
+  :class :hunter
+  :cost 2
+  :secret {
+    ; 512 = 1/1 Snake
+    :when-my-minion-attacked (comp (end-secret) (summon-minion (repeat 3 512)))
+  }
+}
+{
+  :id 324
+  :name "Southsea Captain"
+  :quality :epic
+  :cost 3
+  :minion {
+    :attack 3
+    :health 3
+    :type :pirate
+    :aura {:filter [:my :pirate] :attack #(+ 1 %) :health #(+ 1 %)}
+  }
+}
+{
+  :id 309
+  :name "Spellbender"
+  :quality :epic
+  :class :mage
+  :cost 3
+  :secret {
+    :when-enemy-spell-cast #(if
+      (and (:minion (current-target %)) (is-friendly (current-target %)))
+      (-> %
+        (summon-minion 645) ; 645 = 1/3 Spellbender
+        (end-secret)))
+  }
+}
+{
+  :id 645
+  :name "Spellbender"
+  :quality :epic
+  :class :mage
+  :cost 0
+  :minion {
+    :attack 1
+    :health 3
+  }
+}
+{
+  :id 567
+  :name "Sword of Justice"
+  :quality :epic
+  :class :paladin
+  :cost 3
+  :weapon {
+    :attack 1
+    :durability 3
+    :when-my-minion-summoned (comp (buff-self 1 1) (buff-weapon 0 -1))
+  }
+}
+{
+  :id 398
+  :name "Twisting Nether"
+  :quality :epic
+  :class :warlock
+  :spell (destroy-minions)
+}
+{
+  :id 597
+  :name "Abomination"
+  :quality :rare
+  :cost 5
+  :minion {
+    :attack 4
+    :health 4
+    :properties [:taunt]
+    :deathrattle (damage-all 2)
+  }
+}
+{
+  :id 425
+  :name "Alarm-o-Bot"
+  :quality :rare
+  :cost 3
+  :minion {
+    :attack 0
+    :health 3
+    :start-of-my-turn #(if (> (count (filter-all % [:my :drawn :minion])) 0)
+      ((target-random [:drawn :minion]
+        (swap-with-target)) %))
+  }
+}
+; Epics
+; Rares
+; Commons
+])


Fix sched-noty->initial-req fn for tv-signup

This is gross, and should be re-thought at some point in the notification system’s future.


Added an example use of Clojush to the src/examples/ directory.

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

--- src/examples/sin_regression.clj
+++ src/examples/sin_regression.clj
@@ -0,0 +1,45 @@
+;; sin_regression.clj
+;; an example problem for clojush, a Push/PushGP system written in Clojure
+;; Tom Helmuth, thelmuth@cs.umass.edu, 2011
+
+(ns examples.sin-regression
+  (:require [clojush] [clojure.contrib.math])
+  (:use [clojush] [clojure.contrib.math]))
+
+(import java.lang.Math)
+
+;;;;;;;;;;;;
+;; Float symbolic regression of 4*x*sin(4*x) with float instructions and an
+;; input instruction that uses the auxiliary stack.
+
+(define-registered in
+                   (fn [state] (push-item (stack-ref :auxiliary 0 state) :float state)))
+
+(pushgp
+  :error-function (fn [program]
+                    (doall
+                      (for [input (map #(float (- % 10)) (range 21))]
+                        (let [state (run-push program
+                                              (push-item input :auxiliary
+                                                         (push-item input :float
+                                                                    (make-push-state))))
+                              top-float (top-item :float state)]
+                          (if (number? top-float)
+                            (abs (- top-float
+                                    (* 4.0 input (Math/sin (* 4.0 input)))))
+                            1000.0)))))
+  :atom-generators (list (fn [] (float (- (rand-int 21) 10)))
+                         'in
+                         'float_add
+                         'float_sub
+                         'float_mult
+                         'float_div
+                         'float_sin
+                         'float_cos
+                         'float_tan
+                         'float_dup
+                         (tag-instruction-erc [:float :exec] 1000)
+                         (tagged-instruction-erc 1000))
+  :population-size 500
+  :max-generations 100
+  :tournament-size 7)


[EN] Clean up the datomic query for finding identifier matches

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


added p21.clj

added p21.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/'


implement morphs and shapes

implement morphs and shapes

error: pathspec 'src-cljs/cljs_workspace/om_morph.cljs' did not match any file(s) known to git

--- src-cljs/cljs_workspace/om_morph.cljs
+++ src-cljs/cljs_workspace/om_morph.cljs
@@ -0,0 +1,124 @@
+(ns cljs-workspace.morph
+  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require [goog.events :as events]
+            [goog.events.EventType :as EventType]
+            [cljs.core.async :as async :refer [>! <! put! chan]]
+            [om.core :as om :include-macros true]
+            [om.dom :as dom :include-macros true]
+            [goog.style :as gstyle]
+            [goog.dom :as gdom]
+            [cljs-workspace.draggable :as draggable]
+            ; [clojure.browser.repl :as repl]
+            )
+  (:import [goog.events EventType]))
+
+(enable-console-print!)
+
+; morph property to CSS property translators
+
+(defn get-fill [value]
+  {"background" value})
+
+(defn get-position [value]
+   {"position" "absolute"
+    "left" (:x value)
+    "top" (:y value)})
+
+(defn get-extent [value]
+  {"height" (:y value)
+   "width" (:x value)})
+
+(defn get-border-width [value]
+  {"border-width" value
+   "border-style" "solid"})
+
+(defn get-border-color [value]
+  {"border-color" value
+   "border-style" "solid"})
+
+; translation from morph data to CSS style prop
+
+(defn dict->js [dict]
+  (apply js-obj (apply concat (seq dict))))
+
+(defn extract-style [state]
+  (apply merge
+        (map (fn [[prop value]]
+            (case prop
+              :Fill (get-fill value)
+              :Position (get-position value)
+              :Extent (get-extent value)
+              :BorderWidth (get-border-width value)
+              :BorderColor (get-border-color value)
+              ;; more to come...
+              nil
+              )) state)))
+
+; morph component + rendering functions
+
+(defmulti shape (fn [app owner] (get-in app  [:shape :ShapeClass])))
+(defmulti morph (fn [app owner] (get-in app [:morph :MorphClass])))
+
+; utilities
+
+(defn render-submorphs [app]
+  (dom/div #js {:className "originNode"}
+    (apply dom/div nil
+      (om/build-all morph (:submorphs app)))))
+
+; multimethod for morph
+
+(defmethod morph "Text" [app owner]
+  (reify
+    om/IRender
+    (render [this]
+      (let [style (dict->js (extract-style (:morph app)))]
+        (dom/div  #js {:style style
+                     :className "morphNode" } (shape app owner))))))
+
+(defmethod morph :default [app owner]
+  (reify
+    om/IRender
+    (render [this]
+      (let [style (dict->js (extract-style (:morph app)))]
+        (dom/div  #js {:style style
+                     :className "morphNode"
+                     :onMouseDown #(draggable/start-dragging % app owner)
+                     :onMouseUp #(draggable/stop-dragging % app)
+                    }
+                 (shape app owner))))))
+
+;; multi method for shape
+(defn handle-input [e owner app]
+  (let [span (om/get-node owner "myInput")]
+    (prn (.-innerText span))
+    (om/update! app [:morph :TextString] (.-innerText span))))
+
+(defn save-input [e owner app]
+  (prn (.-key e))
+  false)
+
+(defn create-text-node [app owner]
+    (dom/div #js {:className "visible Selection"
+                  :contentEditable true
+                  :onMouseDown #(swap! clicked-morph (@app :id))
+                  :onInput #(handle-input % owner app)
+                  ; :onKeyDown #(when (.-metaKey %) (save-input % owner app))} (dom/span #js {
+                    :ref "myInput"} (get-in app [:morph :TextString])))
+
+(defmethod shape "Ellipse" [app owner]
+  (let [style (extract-style (:shape app))]
+    ;; we apply some customizations to the style, to make the shape elliptical
+    (let [ellipse-style (assoc style
+                          "border-radius" (str (style "width") " /" (style "height")))]
+      (dom/div #js {:style (dict->js ellipse-style)} (render-submorphs app)))))
+
+(defmethod shape "Text" [app owner]
+  (prn "Rendering Text Shape")
+  (let [style (dict->js (extract-style (:shape app)))]
+    (dom/div #js {:style style
+                  :className "Morph Text"} (create-text-node app owner))))
+
+(defmethod shape :default [app owner]
+  (let [style (extract-style (:shape app))]
+    (dom/div #js {:style (dict->js style)} (render-submorphs app))))


[TH] expand on docstring to explain what goes on


Remove unnecessary call to partial in second koan

juxt returns a function that takes a variable number of arguments, so a
partial taking one argument does not need to be created.

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


downsize deps :chart_with_downwards_trend:

@jeluard noted that we have `overtone` as a dependency but we're only using `overtone/at-at`, and also that we have `reply` as a dependency but we're not really using it at all :)

It turns out that we were passively using `reply` in that it pulls in JLine, from which we are using the ConsoleReader in alda.repl. We may as well just pull in `jline`, though, instead of `reply` with all its dependencies.

Check out the difference!

Before:

$ boot show -d
[adzerk/boot-test "1.0.4" :scope "test"]
[adzerk/bootlaces "0.1.12" :scope "test"]
[com.taoensso/timbre "4.1.1"]
├── [com.taoensso/encore "2.4.2"]
│   └── [org.clojure/tools.reader "0.9.2"]
└── [io.aviso/pretty "0.1.18"]
[djy "0.1.4"]
[instaparse "1.4.1"]
[midi.soundfont "0.1.0"]
[org.clojure/clojure "1.7.0"]
[org.clojure/tools.cli "0.3.1"]
[overtone "0.9.1"]
├── [clj-glob "1.0.0"]
├── [clj-native "0.9.3"]
│   └── [net.java.dev.jna/jna "3.4.0"]
├── [org.clojure/data.json "0.2.3"]
├── [overtone/at-at "1.2.0"]
├── [overtone/byte-spec "0.3.1"]
├── [overtone/libs.handlers "0.2.0"]
├── [overtone/midi-clj "0.5.0"]
├── [overtone/osc-clj "0.9.0"]
│   ├── [commons-net "3.0.1"]
│   └── [javax.jmdns/jmdns "3.4.1"]
├── [overtone/scsynth-extras "3.5.7.0"]
└── [overtone/scsynth "3.5.7.0"]
[reply "0.3.7"]
├── [clj-stacktrace "0.2.7"]
├── [clojure-complete "0.2.3"]
├── [com.cemerick/drawbridge "0.0.6" :exclusions [[org.clojure/tools.nrepl]]]
│   ├── [clj-http "0.3.6"]
│   │   ├── [org.apache.httpcomponents/httpclient "4.1.2"]
│   │   │   ├── [commons-logging "1.1.1"]
│   │   │   └── [org.apache.httpcomponents/httpcore "4.1.2"]
│   │   └── [org.apache.httpcomponents/httpmime "4.1.2"]
│   └── [ring/ring-core "1.0.2"]
│       ├── [commons-codec "1.4"]
│       ├── [commons-fileupload "1.2.1"]
│       ├── [commons-io "1.4"]
│       └── [javax.servlet/servlet-api "2.5"]
├── [jline "2.12.1"]
├── [net.cgrand/sjacket "0.1.1" :exclusions [[org.clojure/clojure]]]
│   ├── [net.cgrand/parsley "0.9.2"]
│   └── [net.cgrand/regex "1.1.0"]
├── [org.clojure/tools.nrepl "0.2.8"]
├── [org.thnetos/cd-client "0.3.6"]
│   ├── [cheshire "4.0.3"]
│   │   ├── [com.fasterxml.jackson.core/jackson-core "2.0.6"]
│   │   └── [com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.0.6"]
│   └── [clj-http-lite "0.2.0"]
│       └── [slingshot "0.10.3"]
└── [trptcolin/versioneer "0.1.1"]
[str-to-argv "0.1.0"]

After:

$ boot show -d
[adzerk/boot-test "1.0.4" :scope "test"]
[adzerk/bootlaces "0.1.12" :scope "test"]
[com.taoensso/timbre "4.1.1"]
├── [com.taoensso/encore "2.4.2"]
│   └── [org.clojure/tools.reader "0.9.2"]
└── [io.aviso/pretty "0.1.18"]
[djy "0.1.4"]
[instaparse "1.4.1"]
[jline "2.12.1"]
[midi.soundfont "0.1.0"]
[org.clojure/clojure "1.7.0"]
[org.clojure/tools.cli "0.3.1"]
[overtone/at-at "1.2.0"]
[str-to-argv "0.1.0"]

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


confirm partial inline style

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


Update ky absentee ballot request link

Update ky absentee ballot request link

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


Refactor bundle builder.

Refactor bundle builder.

Use existing bundle elements.

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


CMR-2291: Added test for headers returned with ingest and search.

error: pathspec 'system-int-test/test/cmr/system_int_test/header_test.clj' did not match any file(s) known to git

--- system-int-test/test/cmr/system_int_test/header_test.clj
+++ system-int-test/test/cmr/system_int_test/header_test.clj
@@ -0,0 +1,37 @@
+(ns cmr.system-int-test.header_test
+  "Tests for headers in ingest and search responses"
+  (:require [clojure.test :refer :all]
+            [cmr.search.api.routes :as sr]
+            [cmr.system-int-test.utils.metadata-db-util :as mdb]
+            [cmr.system-int-test.utils.ingest-util :as ingest]
+            [cmr.system-int-test.utils.search-util :as search]
+            [cmr.system-int-test.utils.index-util :as index]
+            [cmr.system-int-test.data2.collection :as dc]
+            [cmr.system-int-test.data2.granule :as dg]
+            [cmr.system-int-test.data2.core :as d]
+            [cmr.mock-echo.client.echo-util :as e]
+            [cmr.system-int-test.system :as s]))
+
+(use-fixtures :each (ingest/reset-fixture {"provguid1" "PROV1"}))
+
+(deftest search-and-ingest-headers
+  (let [{ingest-headers :headers} (ingest/ingest-concept
+                                    (dc/collection-concept {:short-name "Foo"})
+                                    {:raw? true})
+        ingest-request-id (ingest-headers "cmr-request-id")
+        _ (index/wait-until-indexed)
+        {search-headers :headers} (search/find-concepts-in-format
+                                    "application/echo10+xml" :collection {})
+        content-type (search-headers "Content-Type")
+        aca-origin (search-headers "Access-Control-Allow-Origin")
+        cmr-hits (search-headers "CMR-Hits")
+        cmr-took (search-headers "CMR-Took")
+        search-request-id (search-headers "cmr-request-id")
+        req-id-regex #"\w{8}-\w{4}-\w{4}-\w{4}-\w{12}"]
+    (cmr.common.dev.capture-reveal/capture-all)
+    (is (re-matches #"application\/echo10\+xml.*" content-type))
+    (is (= aca-origin "*"))
+    (is (= cmr-hits "1"))
+    (is (re-matches req-id-regex ingest-request-id))
+    (is (re-matches req-id-regex search-request-id))
+    (is (re-matches #"\d+" cmr-took))))


adding some geospatial stuff

adding some geospatial stuff

error: pathspec 'src/main/cawala/server_components/geo_spatial.clj' did not match any file(s) known to git

--- src/main/cawala/server_components/geo_spatial.clj
+++ src/main/cawala/server_components/geo_spatial.clj
@@ -0,0 +1,38 @@
+(ns cawala.server-components.geo-spatial
+  (:require [geo [geohash :as geohash] [jts :as jts] [spatial :as spatial]
+            [io :as gio]]))
+
+(comment
+  (spatial/earth-radius spatial/south-pole)
+  (spatial/earth-radius (spatial/geohash-point 45 0))
+  (def lhr (spatial/spatial4j-point 51.477500 -0.461388))
+  (def lax (spatial/spatial4j-point 33.942495 -118.408067))
+  (/ (spatial/distance lhr lax) 1000)
+  (def london (spatial/spatial4j-point 51.5072 0.1275))
+  (spatial/intersects? lhr (spatial/circle london 50000))
+  (spatial/intersects? lhr (spatial/circle london 10000))
+  (-> london (spatial/circle 50) geohash/shape->precision)
+  (def h (-> london (geohash/geohash 35)))
+  h
+  (geohash/geohash-midline-dimensions h)
+  (geohash/string h)
+  (spatial/intersects? (geohash/geohash "u10j4") london)
+  (spatial/relate (geohash/geohash "u10j4bs") (geohash/geohash "u10j4"))
+  (spatial/relate (geohash/geohash "u10j4") (geohash/geohash "u10j4bs"))
+  (spatial/relate h (geohash/northern-neighbor h))
+  (-> (iterate geohash/northern-neighbor h) (nth 5) (spatial/relate h))
+  (-> lhr (spatial/circle 1000) (geohash/geohashes-intersecting 30)
+      (->> (map geohash/string)))
+  (map geohash/string (geohash/geohashes-near lhr 1000 30))
+  (gio/read-geojson "{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[0.0,0.0]},\"properties\":{\"name\":\"null island\"}}")
+  (->> "{\"type\":\"Polygon\",\"coordinates\":[[[-70.0,30.0],[-70.0,31.0],[-71.0,31.0],[-71.0,30.0],[-70.0,30.0]]]}"
+       gio/read-geojson
+       (map :geometry)
+       )
+  (def gj (slurp "/home/paul/Dropbox/cape-breton.geojson"))
+  (def geoms (gio/read-geojson gj))
+  (count geoms)
+  (first geoms)
+  (-> geoms first :geometry .getLength)
+
+  )


Changed typo

Changed typo

--- sidecar/src/figwheel_sidecar/core.clj
+++ sidecar/src/figwheel_sidecar/core.clj
@@ -306,7 +306,7 @@
     :else
     (let [changed-ns-syms       (set (keep (fn [n] (:name (ana-api/find-ns n))) changed-ns-syms'))
           dependants            (set (mapcat
-                                      transitive-dependents
+                                      *transitive-dep-fn*
                                       changed-ns-syms))
           additional-dependents (difference dependants changed-ns-syms)
           additional-dependents (mark-changed-ns state additional-dependents)


added timer module, works fine

added timer module, works fine

error: pathspec 'src/backtype/storm/timer.clj' did not match any file(s) known to git

--- src/backtype/storm/timer.clj
+++ src/backtype/storm/timer.clj
@@ -0,0 +1,116 @@
+;; Licensed to the Apache Software Foundation (ASF) under one
+;; or more contributor license agreements.  See the NOTICE file
+;; distributed with this work for additional information
+;; regarding copyright ownership.  The ASF licenses this file
+;; to you under the Apache License, Version 2.0 (the
+;; "License"); you may not use this file except in compliance
+;; with the License.  You may obtain a copy of the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+
+(ns backtype.storm.timer
+  (:import [backtype.storm.utils Time])
+  (:import [java.util PriorityQueue Comparator])
+  (:import [java.util.concurrent Semaphore])
+  (:use [backtype.storm util log]))
+
+;; The timer defined in this file is very similar to java.util.Timer, except
+;; it integrates with Storm's time simulation capabilities. This lets us test
+;; code that does asynchronous work on the timer thread
+
+(defnk mk-timer [:kill-fn (fn [& _] ) :timer-name nil]
+  (let [queue (PriorityQueue. 10 (reify Comparator
+                                   (compare
+                                     [this o1 o2]
+                                     (- (first o1) (first o2)))
+                                   (equals
+                                     [this obj]
+                                     true)))
+        active (atom true)
+        lock (Object.)
+        notifier (Semaphore. 0)
+        thread-name (if timer-name timer-name "timer")
+        timer-thread (Thread.
+                       (fn []
+                         (while @active
+                           (try
+                             (let [[time-millis _ _ :as elem] (locking lock (.peek queue))]
+                               (if (and elem (>= (current-time-millis) time-millis))
+                                 ;; It is imperative to not run the function
+                                 ;; inside the timer lock. Otherwise, it is
+                                 ;; possible to deadlock if the fn deals with
+                                 ;; other locks, like the submit lock.
+                                 (let [afn (locking lock (second (.poll queue)))]
+                                   (afn))
+                                 (if time-millis
+                                   ;; If any events are scheduled, sleep until
+                                   ;; event generation. If any recurring events
+                                   ;; are scheduled then we will always go
+                                   ;; through this branch, sleeping only the
+                                   ;; exact necessary amount of time.
+                                   (Time/sleep (- time-millis (current-time-millis)))
+                                   ;; Otherwise poll to see if any new event
+                                   ;; was scheduled. This is, in essence, the
+                                   ;; response time for detecting any new event
+                                   ;; schedulings when there are no scheduled
+                                   ;; events.
+                                   (Time/sleep 1000))))
+                             (catch Throwable t
+                               ;; Because the interrupted exception can be
+                               ;; wrapped in a RuntimeException.
+                               (when-not (exception-cause? InterruptedException t)
+                                 (kill-fn t)
+                                 (reset! active false)
+                                 (throw t)))))
+                         (.release notifier)) thread-name)]
+    (.setDaemon timer-thread true)
+    (.setPriority timer-thread Thread/MAX_PRIORITY)
+    (.start timer-thread)
+    {:timer-thread timer-thread
+     :queue queue
+     :active active
+     :lock lock
+     :cancel-notifier notifier}))
+
+(defn- check-active!
+  [timer]
+  (when-not @(:active timer)
+    (throw (IllegalStateException. "Timer is not active"))))
+
+(defnk schedule
+  [timer delay-secs afn :check-active true]
+  (when check-active (check-active! timer))
+  (let [id (uuid)
+        ^PriorityQueue queue (:queue timer)]
+    (locking (:lock timer)
+      (.add queue [(+ (current-time-millis) (secs-to-millis-long delay-secs)) afn id]))))
+
+
+(defn schedule-recurring
+  "Schedules a recurring function to be executed."
+  [timer delay-secs recur-secs afn]
+  (schedule timer
+            delay-secs
+            (fn this []
+              (afn)
+              ; This avoids a race condition with cancel-timer.
+              (schedule timer recur-secs this :check-active false))))
+
+
+(defn cancel-timer
+  [timer]
+  (check-active! timer)
+  (locking (:lock timer)
+    (reset! (:active timer) false)
+    (.interrupt (:timer-thread timer)))
+  (.acquire (:cancel-notifier timer)))
+
+(defn timer-waiting?
+  [timer]
+  (Time/isThreadWaiting (:timer-thread timer)))


removing redundant code

removing redundant code

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