Add example tests to demonstrate testing of a main method.

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

--- test/cli4clj/test/example.clj
+++ test/cli4clj/test/example.clj
@@ -0,0 +1,44 @@
+;;;
+;;;   Copyright 2015 Ruediger Gad
+;;;
+;;;   This software is released under the terms of the Eclipse Public License
+;;;   (EPL) 1.0. You can find a copy of the EPL at:
+;;;   http://opensource.org/licenses/eclipse-1.0.php
+;;;
+
+(ns
+  ^{:author "Ruediger Gad",
+    :doc "Example tests for demonstrating the testing of a main method."}
+  cli4clj.test.example
+  (:use clojure.test
+        cli4clj.cli
+        cli4clj.example
+        clj-assorted-utils.util))
+
+(deftest simple-main-method-example-test
+  (let [test-cmd-input ["t"]
+        out-string (test-cli-stdout #(-main "") test-cmd-input)]
+    (is (= "This is a test." out-string))))
+
+(deftest advanced-main-method-example-test
+  (let [test-cmd-input ["add 1 2"
+                        "divide 4 2"
+                        "d 3 2"]
+        out-string (test-cli-stdout #(-main "") test-cmd-input)]
+    (is (= (expected-string ["3" "2" "3/2"]) out-string))))
+
+(deftest simple-main-method-error--example-test
+  (let [test-cmd-input ["divide 4 0"]
+        out-string (test-cli-stderr #(-main "") test-cmd-input)]
+    (is (= "Divide by zero" out-string))))
+
+(deftest advanced-main-method-error-example-test
+  (let [test-cmd-input ["xyz"
+                        "d 4 0"
+                        "a 1 2 3"]
+        out-string (test-cli-stderr #(-main "") test-cmd-input)]
+    (is (= (expected-string ["Invalid command: \"[xyz]\". Please type \"help\" to get an overview of commands."
+                             "Divide by zero"
+                             "Wrong number of args (3) passed to: example/-main/fn--117"])
+           out-string))))
+


Create core.clj

Create core.clj

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

--- src/iyye/bios/core.clj
+++ src/iyye/bios/core.clj
@@ -0,0 +1,116 @@
+; Iyye - AI agent
+; Copyright (C) 2016-2017  Sasha Yumzya
+
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU Affero General Public License as
+; published by the Free Software Foundation, either version 3 of the
+; License, or (at your option) any later version.
+
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU Affero General Public License for more details.
+
+; You should have received a copy of the GNU Affero General Public License
+; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+(ns iyye.bios.core
+  (:require [iyye.bios.iolist :as iolist]
+            [iyye.bios.resource :as resource]
+            [iyye.bios.persistence :as persistence]
+            [clojure.tools.logging :as log]
+            [clojure.tools.cli :refer [parse-opts]]
+            [clojure.string :as str]))
+
+(def DAY_CHECK_TIME_MILLIS 1000)
+
+; wake sleep state machine
+(defn main-loop []
+  (while true
+    (let [current-day (resource/create-day)]
+      (resource/start-day current-day)
+
+      (while (not (resource/is-day-over? current-day))
+        (Thread/sleep DAY_CHECK_TIME_MILLIS))
+
+      (resource/stop-day current-day)
+
+      (let [current-night (resource/create-night current-day)]
+        (resource/start-night current-night)
+        (while (not (resource/is-night-over? current-night))
+          (Thread/sleep DAY_CHECK_TIME_MILLIS))
+
+        (resource/stop-night current-night)))))
+
+(defn- load-state [name]
+  (log/info "first day load")
+  (println "first day load !!")
+  (persistence/load-current-iyye name)
+  (resource/load-day!)
+  (iolist/load-io-state))
+
+(defn- init-state [name]
+  (log/info "first day")
+  (println "first day !!")
+  (persistence/set-current-iyye name))
+
+(defn usage [options-summary]
+  (->> ["Usage: iyye action/option"
+        ""
+        "Options:"
+        options-summary
+        ""
+        "Actions:"
+        "  list    list IYYE"
+        "  load     load IYYE"
+        "  create   create IYYE"
+        ""]
+       (str/join \newline)))
+
+(def cli-options
+  ;; An option with a required argument
+  [["-n" "--name IYYE" "IYYE name"
+    :default "new"]
+   ;   :validate [#(iyye-exists? %) "Does not exist"]]
+   ["-h" "--help"]])
+
+(defn error-msg [errors]
+  (str "The following errors occurred while parsing your command:\n\n"
+       (str/join \newline errors)))
+
+(defn validate-args
+  "Validate command line arguments. Either return a map indicating the program
+  should exit (with a error message, and optional ok status), or a map
+  indicating the action the program should take and the options provided."
+  [args]
+  (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)]
+    ;       (println "opt:" options "args:" arguments "err:" errors "summary:" summary)
+    (cond
+      (:help options) ; help => exit OK with usage summary
+      {:exit-message (usage summary) :ok? true}
+
+      errors ; errors => exit with description of errors
+      {:exit-message (error-msg errors)}
+
+      (and (= 1 (count arguments))
+           (#{"create" "list" "load"} (first arguments)))
+      {:action (first arguments) :options options}
+      :else ; failed custom validation => exit with usage summary
+      {:exit-message (usage summary)})))
+
+(defn exit [status msg]
+  (println msg)
+  (System/exit status))
+
+(defn -main [& args]
+  (let [{:keys [action options exit-message ok?]} (validate-args args)]
+    (if exit-message
+      (exit (if ok? 0 1) exit-message)
+      (case action
+        "list"   (doall (println (persistence/list-iyye) ) (exit 0 ""))
+        "create" (if (persistence/iyye-exists? (:name options)) (exit -1 "Already exists") (init-state (:name options)))
+        "load"  (if (persistence/iyye-exists? (:name options)) (load-state (:name options)) (exit -1 "Does not exist")))))
+
+  (doall  (iolist/init-io))
+  ; Start in a thread so that I can use REPL too
+  (-> (Thread. main-loop) .start))


Reformat: align entire core file

Reformat: align entire core file

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


Add login component.

Add login component.

error: pathspec 'src/uxbox/ui/auth.cljs' did not match any file(s) known to git

--- src/uxbox/ui/auth.cljs
+++ src/uxbox/ui/auth.cljs
@@ -0,0 +1,52 @@
+(ns uxbox.ui.auth
+  (:require [sablono.core :as html :refer-macros [html]]
+            [cats.labs.lens :as l]
+            [rum.core :as rum]
+            [uxbox.router :as r]
+            [uxbox.state :as s]
+            [uxbox.rstore :as rs]
+            [uxbox.data.auth :as da]
+            [uxbox.ui.icons :as i]
+            [uxbox.ui.navigation :as nav]
+            [uxbox.ui.mixins :as mx]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Login
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn- login-render
+  [own local]
+  (letfn [(on-submit []
+            (rs/emit! (da/login {:username "cirilla"
+                                 :password "secret"})))]
+    (html
+     [:div.login
+      [:div.login-body
+       [:a i/logo]
+       [:div.login-content
+        [:input.input-text
+         {:name "email"
+          :placeholder "Email or Username"
+          :type "text"}]
+        [:input.input-text
+         {:name "password"
+          :placeholder "Password"
+          :type "password"}]
+        #_[:div.input-checkbox.check-primary
+         [:input#checkbox1 {:value "1"
+                            :type "checkbox"}]
+         [:label {:for "checkbox1"} "Keep Me Signed in"]]
+        [:input.btn-primary
+         {:name "login"
+          :value "Continue"
+          :type "submit"
+          :on-click on-submit}]
+        [:div.login-links
+         [:a {:on-click #(r/go :auth/recover-password)} "Forgot your password?"]
+         [:a {:on-click #(r/go :auth/register)} "Don't have an account?"]]]]])))
+
+(def ^:const login
+  (mx/component
+   {:render #(login-render % (:rum/local %))
+    :name "login"
+    :mixins [(mx/local)]}))


Add initial version of sahtn

Add initial version of sahtn

error: pathspec 'ros/angelic_planning/src/ros/sahtn.clj' did not match any file(s) known to git

--- ros/angelic_planning/src/ros/sahtn.clj
+++ ros/angelic_planning/src/ros/sahtn.clj
@@ -0,0 +1,172 @@
+;///////////////////////////////////////////////////////////////////////////////
+;// Robot state for high-level planning.
+;//
+;// Copyright (C) 2009, Jason Wolfe
+;//
+;// Redistribution and use in source and binary forms, with or without
+;// modification, are permitted provided that the following conditions are met:
+;//   * Redistributions of source code must retain the above copyright notice,
+;//     this list of conditions and the following disclaimer.
+;//   * Redistributions in binary form must reproduce the above copyright
+;//     notice, this list of conditions and the following disclaimer in the
+;//     documentation and/or other materials provided with the distribution.
+;//   * Neither the name of Stanford University nor the names of its
+;//     contributors may be used to endorse or promote products derived from
+;//     this software without specific prior written permission.
+;//
+;// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+;// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+;// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+;// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+;// POSSIBILITY OF SUCH DAMAGE.
+;//////////////////////////////////////////////////////////////////////////////
+
+
+
+(ns ros.sahtn
+  (:import [java.util HashMap])
+  (:use ros.ros [ros.robot-actions :as ra])
+  )
+
+(set! *warn-on-reflection* true)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn- map-keys [f m] (into {} (for [[k v] m] [(f k) v])))
+(defn- map-vals [f m] (into {} (for [[k v] m] [k (f v)])))
+
+(defn- merge-valuations [& vs]
+  "Like merge-with max, but preserves metadata of the best key."
+  (reduce
+   (fn [v1 v2]
+     (reduce
+      (fn [v1 [k v]]
+	(if (<= v (get v1 k Double/NEGATIVE_INFINITY))
+	    v1
+	  (assoc (dissoc v1 k) k v)))
+      v1 v2))
+   (or (first vs) {}) (rest vs)))
+
+(defn- immediate-refinements [h a s]
+  (if (robot-hla-discrete-refinements? a)
+      (ra/robot-hla-refinements (:nh h) a s)
+    (let [num-refs (safe-get* (:sample-depths h) (:class a))]
+      (filter identity
+	(take num-refs
+	  (repeatedly #(ra/sample-robot-hla-refinement (:nh h) a s)))))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;; Computing result  valuations ;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(declare sahtn-result)
+
+(defn sahtn-compute-result-seq [h as v]
+  "Compute result for sequence as for valuation v."
+  (if (empty? as) v
+    (recur h (rest as)
+      (apply merge-with max
+        (for [[s r] v]
+	  (map-vals #(+ % r)
+  	    (sahtn-result h (first as) s)))))))
+
+(defn sahtn-compute-result [h a s]
+  "Actually refine a from state s.  Metadata on states gives best refinement to reach it."
+  (let [{:keys [nh sample-depths]} h]
+    (if (ra/robot-action-primitive? a)
+        (into {} (robot-primitive-result nh a s))
+      (apply merge-valuations
+	(for [ref (immediate-refinements h a s)]
+	  (map-keys #(with-meta % {:ref ref})
+	    (sahtn-compute-result-seq h ref {s 0})))))))
+
+(defn sahtn-result [h a s]
+  "Memoized result valuation for doing a from s."
+  (let [#^HashMap cache (:cache h)
+	context         (ra/robot-action-precondition-context a s)
+	cache-key       [a context]
+	cache-val       (.get cache cache-key)]
+    (cond (nil? cache-val)           ;; Not computed, actually do work + cache result
+	    (do (.put cache cache-key :in-progress)
+		(let [result        (sahtn-compute-result h a s)
+		      effect-schema (ra/robot-action-effect-context-schema a)]
+		  (.put cache cache-key
+		    (map-keys #(with-meta (cherry-pick effect-schema %) (meta %)) result))
+		  result))
+	  (= cache-val :in-progress) ;; On the stack; this is a loop.
+	    {}
+	  :else                      ;; already computed; reuse
+	    (map-keys #(merge-deep s %) cache-val))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Extracting Solutions  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO: add assertions
+
+(declare sahtn-solution)
+
+(defn sahtn-solution-seq [h as v final-s final-r]
+  "Returns [solution init-s init-rew].  Should always succeed."
+  (if (empty? as) [[] final-s final-r]
+    (let [a      (first as)
+	  next-v (apply merge-valuations
+		   (for [[s r]   v]
+		     (into {}
+		       (for [[ns sr] (sahtn-result h a s)]
+			 [(with-meta ns {:pre s}) (+ r sr)]))))
+	  [rest-sol step-final-s step-final-r]
+	         (sahtn-solution-seq h (rest as) next-v final-s final-r)
+	  [my-fs my-fr] (find next-v step-final-s)
+	  my-is         (:pre (meta my-fs))]
+      (assert (and (= my-fs step-final-s) (= my-fr step-final-r)))
+      [(concat (sahtn-solution h a my-is my-fs my-fr))
+       my-is
+       (safe-get* v my-is)])))
+
+(defn sahtn-solution [h a s final-s final-r]
+  "Returns a solution (possibly [])."
+  (let [#^HashMap cache   (:cache h)
+	context           (ra/robot-action-precondition-context a s)
+	cache-key         [a context]
+	cache-val         (.get cache cache-key)
+	final-s-context   (cherry-pick (ra/robot-action-effect-context-schema a) final-s)
+	[final-s-context final-s-rew] (get cache-val final-s-context Double/NEGATIVE_INFINITY)]
+    (assert (and cache-val (not (= cache-val :in-progress)))) ; Should have been computed
+    (assert (= final-s-rew final-r))                         ; Can't beat optimal.
+    (if (ra/robot-action-primitive? a)
+        [a]
+      (first (sahtn-solution-seq h (:ref (meta final-s-context)) {s 0} final-s final-r)))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Driver  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(derive ::SAHTN-TLA ::ra/RobotHLA)
+(defmethod ra/robot-hla-discrete-refinements? ::SAHTN-TLA [a] true)
+(defmethod ra/robot-action-precondition-context-schema ::SAHTN-TLA [a] true)
+
+
+(defn sahtn
+  [nh initial-plans env sample-depths]
+  (let [h {:nh nh :sample-depths sample-depths :cache (HashMap.)}
+	tla-type (gensym)]
+    (derive tla-type ::SAHTN-TLA)
+    (defmethod ra/robot-hla-refinements tla-type [nh a env] initial-plans)
+    (let [tla               {:class tla-type}
+	  final-val         (sahtn-result h tla env)
+	  [final-s final-r] (last (sort-by val final-val))]
+      [(sahtn-solution h tla env final-s final-r) final-r])))
+
+
+
+
+
+(set! *warn-on-reflection* false)
+


test fix

test fix

--- test/metabase/api/session_test.clj
+++ test/metabase/api/session_test.clj
@@ -46,15 +46,18 @@

 ;; ## POST /api/session/forgot_password
 ;; Test that we can initiate password reset
-(expect true
-  (do
+(expect
+    true
+  (let [reset-fields-set? (fn []
+                            (let [{:keys [reset_token reset_triggered]} (sel :one :fields [User :reset_token :reset_triggered] :id (user->id :rasta))]
+                              (boolean (and reset_token reset_triggered))))]
     ;; make sure user is starting with no values
     (upd User (user->id :rasta) :reset_token nil :reset_triggered nil)
+    (assert (not (reset-fields-set?)))
     ;; issue reset request (token & timestamp should be saved)
     ((user->client :rasta) :post 200 "session/forgot_password" {:email (:email (user->credentials :rasta))})
     ;; TODO - how can we test email sent here?
-    (let [{:keys [reset_token reset_triggered]} (sel :one :fields [User :reset_token :reset_triggered] :id (user->id :rasta))]
-      (and reset_token reset_triggered))))
+    (reset-fields-set?)))

 ;; Test that email is required
 (expect "'email' is a required param."


Adding more functions into manual coaching for data gathering

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


Aha, I missed an important one!

Aha, I missed an important one!

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


Some, in case blank

Some, in case blank


minor change

minor change

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


remove private key path

remove private key path


removed useless getTotalLenght hack

removed useless getTotalLenght hack

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


Don't try and set SANITIZE in makefile.boot

There is no sanitize in the build config.  A too-tolerant SET was
covering up the failed attempt to set the variable.

--- make/makefile.boot
+++ make/makefile.boot
@@ -115,8 +115,8 @@

 makefile: $(REBOL_TOOL) .FORCE
 	$(REBOL) $T/make-make.r OS_ID="$(OS_ID)" DEBUG="$(DEBUG)" \
-		GIT_COMMIT="{$(GIT_COMMIT)}" SANITIZE="$(SANITIZE)" \
-		STANDARD="$(STANDARD)" RIGOROUS="$(RIGOROUS)" WITH_FFI="$(WITH_FFI)" \
+		GIT_COMMIT="{$(GIT_COMMIT)}" STANDARD="$(STANDARD)" \
+		RIGOROUS="$(RIGOROUS)" WITH_FFI="$(WITH_FFI)" \
 		WITH_TCC="$(WITH_TCC)" STATIC="$(STATIC)" \
 		OPTIMIZE="$(OPTIMIZE)" TARGET=makefile CONFIG="$(CONFIG)"
 		#SYMBOLS="$(SYMBOLS)"


all ...-uri methods in http-utility use the same underlying method for requests now

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


:repositories seems unneeded... may need to revisit later

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


Updated deps

Updated deps

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


bump version to 2.8.17

bump version to 2.8.17

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


Update lein-ancient to 0.6.7.

Update lein-ancient to 0.6.7.

It didn't tell me it needed an upgrade...

--- project.clj
+++ project.clj
@@ -58,7 +58,7 @@
              :1.7 {:dependencies [[org.clojure/clojure "1.7.0-alpha4"]]}
              :cli {:main freefrog.cli}}

-  :plugins [[lein-ancient "0.5.5"]
+  :plugins [[lein-ancient "0.6.7"]
             [lein-kibit "0.0.8"]
             [lein-marginalia "0.8.0"]
             [speclj "3.1.0"]]


Change version number to 0.10.0

Change version number to 0.10.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/magoyette/marcandregoyette.com.git/'


added debugs to project.clj

added debugs to project.clj

--- project.clj
+++ project.clj
@@ -20,84 +20,86 @@

             :aliases {"all" ["with-profile" "default"]
                       }
-            :profiles {:default      [:base :system :user :provided :spark-1.6.0 :dev]
-                       :dev          {:dependencies   [[criterium "0.4.3"]]
-                                      :plugins        [[lein-dotenv "RELEASE"]
-                                                       [jonase/eastwood "0.1.4"]
-                                                       [lein-kibit "0.1.2"]
-                                                       [lein-marginalia "0.8.0" :exclusions [org.clojure/clojure com.google.guava/guava]]
-                                                       [lein-ancient "0.5.4" :exclusions [org.clojure/clojure org.clojure/tools.reader commons-codec]]
-                                                       [lein-release "1.0.5" :exclusions [org.clojure/clojure]]
-                                                       [gargamel "0.5.0"]
-                                                       [lein-pprint "1.1.1"]]
-                                      :resource-paths ["data"]
-                                      ;; so gen-class stuff works in the repl
-                                      :aot            [sparkling.api
-                                                       sparkling.function
-                                                       sparkling.scalaInterop
-                                                       ]}
-                       :jenkins      {:plugins [[lein-test-out "0.3.1"]]
-                                      }
+  :profiles {:default      [:base :system :user :provided :spark-1.6.0 :dev :debug]
+             :dev          {:dependencies   [[criterium "0.4.3"]]
+                            :plugins        [[lein-dotenv "RELEASE"]
+                                             [jonase/eastwood "0.1.4"]
+                                             [lein-kibit "0.1.2"]
+                                             [lein-marginalia "0.8.0" :exclusions [org.clojure/clojure com.google.guava/guava]]
+                                             [lein-ancient "0.5.4" :exclusions [org.clojure/clojure org.clojure/tools.reader commons-codec]]
+                                             [lein-release "1.0.5" :exclusions [org.clojure/clojure]]
+                                             [gargamel "0.5.0"]
+                                             [lein-pprint "1.1.1"]]
+                            :resource-paths ["data"]
+                            ;; so gen-class stuff works in the repl
+                            :aot            [sparkling.api
+                                             sparkling.function
+                                             sparkling.scalaInterop
+                                             ]}
+             :jenkins      {:plugins [[lein-test-out "0.3.1"]]
+                            }

-                       :spark-1.1.0  ^{:pom-scope :provided} {:dependencies
-                                      [[org.apache.spark/spark-core_2.10 "1.1.0"]
-                                       ]}
-                       :spark-1.4.0  ^{:pom-scope :provided} {:dependencies
-                                      [[org.apache.spark/spark-core_2.10 "1.4.0"]
-                                       ]}
+             :spark-1.1.0  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.1.0"]
+                                                     ]}
+             :spark-1.4.0  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.4.0"]
+                                                     ]}

-                       :spark-1.5.0  ^{:pom-scope :provided} {:dependencies
-                                                              [[org.apache.spark/spark-core_2.10 "1.5.0"]
-                                                               ]}
+             :spark-1.5.0  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.5.0"]
+                                                     ]}

-                       :spark-1.6.0  ^{:pom-scope :provided} {:dependencies
-                                                              [[org.apache.spark/spark-core_2.10 "1.6.0"]
-                                                               ;[com.github.fommil.netlib/all "1.1.2" :extension "pom"]
-                                                               ;[com.googlecode.matrix-toolkits-java/mtj "1.0.2"]
-                                                               [org.apache.spark/spark-mllib_2.10 "1.6.0" ]
-                                                               ] }
+             :spark-1.6.0  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.6.0"]
+                                                     [com.github.fommil.netlib/all "1.1.2" :extension "pom"]
+                                                     [com.googlecode.matrix-toolkits-java/mtj "1.0.2"]
+                                                     [org.apache.spark/spark-mllib_2.10 "1.6.0" ]
+                                                     ] }

-                       :hadoop-2.6.0 ^{:pom-scope :provided} {:dependencies
-                                                              [[org.apache.hadoop/hadoop-client "2.6.0"
-                                                                :exclusions [commons-codec org.apache.curator/curator-recipes org.slf4j/slf4j-api com.google.guava/guava io.netty/netty org.apache.curator/curator-framework org.apache.zookeeper/zookeeper]]
-                                                               [org.apache.hadoop/hadoop-hdfs "2.6.0" :exclusions [com.google.guava/guava io.netty/netty]]]}
+             :hadoop-2.6.0 ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.hadoop/hadoop-client "2.6.0"
+                                                      :exclusions [commons-codec org.apache.curator/curator-recipes org.slf4j/slf4j-api com.google.guava/guava io.netty/netty org.apache.curator/curator-framework org.apache.zookeeper/zookeeper]]
+                                                     [org.apache.hadoop/hadoop-hdfs "2.6.0" :exclusions [com.google.guava/guava io.netty/netty]]]}

-                       :spark-1.2.1  ^{:pom-scope :provided} {:dependencies
-                                                              [[org.apache.spark/spark-core_2.10 "1.2.1" :scope "provided"
-                                                                :exclusions [commons-net commons-codec commons-io]
-                                                                ]
-                                                               [commons-net "3.1"]
-                                                               [commons-codec "1.4"]
-                                                               [commons-io "2.4"]]}
-                       :spark-1.3.1  ^{:pom-scope :provided} {:dependencies
-                                                              [[org.apache.spark/spark-core_2.10 "1.3.1"]]}
+             :spark-1.2.1  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.2.1" :scope "provided"
+                                                      :exclusions [commons-net commons-codec commons-io]
+                                                      ]
+                                                     [commons-net "3.1"]
+                                                     [commons-codec "1.4"]
+                                                     [commons-io "2.4"]]}
+             :spark-1.3.1  ^{:pom-scope :provided} {:dependencies
+                                                    [[org.apache.spark/spark-core_2.10 "1.3.1"]]}

-
-                       :test         {:resource-paths ["dev-resources" "data"]
-                                      :aot            [sparkling.core
-                                                       sparkling.api
-                                                       sparkling.function
-                                                       sparkling.scalaInterop
-                                                       sparkling.destructuring
-                                                       sparkling.debug
-                                                       sparkling.rdd.hadoopAvro
-                                                       sparkling.rdd.jdbc
-                                                       sparkling.testutils.records.domain
-                                                       sparkling.testutils.records.registrator
-                                                       sparkling.api-test
-                                                       sparkling.core-test
-                                                       sparkling.function-test
-                                                       sparkling.conf-test
-                                                       sparkling.rdd.hadoopAvro-test
-                                                       sparkling.rdd.jdbc-test
-                                                       sparkling.accumulator-test
-                                                       sparkling.test-registrator
-                                                       sparkling.serialization-test
-                                                       sparkling.ml.classification
-                                                       sparkling.ml.core
-                                                       sparkling.ml.transform
-                                                       sparkling.ml.validation]}
-                       }
+             :debug {:debug true
+                     :injections [(prn (into {} (System/getProperties)))]}
+             :test         {:resource-paths ["dev-resources" "data"]
+                            :jvm-opts ^:replace ["-server" "-Xmx2g"]
+                            :aot            [sparkling.core
+                                             sparkling.api
+                                             sparkling.function
+                                             sparkling.scalaInterop
+                                             sparkling.destructuring
+                                             sparkling.debug
+                                             sparkling.rdd.hadoopAvro
+                                             sparkling.rdd.jdbc
+                                             sparkling.testutils.records.domain
+                                             sparkling.testutils.records.registrator
+                                             sparkling.api-test
+                                             sparkling.core-test
+                                             sparkling.function-test
+                                             sparkling.conf-test
+                                             sparkling.rdd.hadoopAvro-test
+                                             sparkling.rdd.jdbc-test
+                                             sparkling.accumulator-test
+                                             sparkling.test-registrator
+                                             sparkling.serialization-test
+                                             sparkling.ml.classification
+                                             sparkling.ml.core
+                                             sparkling.ml.transform
+                                             sparkling.ml.validation]}
+             }
             :source-paths ["src/clojure"]
             :java-source-paths ["src/java"]
             :codox {:defaults                  {:doc/format :markdown}


update to include current today

update to include current today

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


Added include-js and include-react.

Added include-js and include-react.

--- src/sablono/core.cljx
+++ src/sablono/core.cljx
@@ -4,7 +4,8 @@
             [clojure.walk :refer [postwalk-replace]]
             [sablono.util :refer [as-str to-uri]]
             [sablono.interpreter :as interpreter]
-            #+clj [sablono.compiler :as compiler]))
+            #+clj [sablono.compiler :as compiler]
+            #+cljs [goog.dom :as dom]))

 (defmacro html
   "Render Clojure data structures via Facebook's React."
@@ -72,6 +73,19 @@
   [& styles]
   (for [style styles]
     [:link {:type "text/css", :href (as-str style), :rel "stylesheet"}]))
+
+#+cljs
+(defn include-js
+  "Include the JavaScript library at `src`."
+  [src]
+  (dom/appendChild
+   (.-body (dom/getDocument))
+   (dom/createDom "script" #js {:src src})))
+
+#+cljs
+(defn include-react
+  "Include Facebook's React JavaScript library."
+  [] (include-js "http://fb.me/react-0.8.0.js"))

 (defelem link-to
   "Wraps some content in a HTML hyperlink with the supplied URL."


added back hdf_test; mistake to take it out.

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

--- test/forma/source/hdf_test.clj
+++ test/forma/source/hdf_test.clj
@@ -0,0 +1,103 @@
+(ns forma.source.hdf-test
+  (:use [forma.source.hdf] :reload)
+  (:use cascalog.api
+        forma.testing
+        [midje sweet cascalog])
+  (:require [forma.hadoop.io :as io]
+            [cascalog.ops :as c]))
+
+(def hdf-path
+  (dev-path "/testdata/MOD13A3/MOD13A3.A2000032.h03v11.005.2006271174459.hdf"))
+
+(fact "metadata test."
+  (let [meta (with-gdal-open [dataset hdf-path]
+               (metadata dataset))]
+    meta => map?
+    meta => (contains {"ASSOCIATEDPLATFORMSHORTNAME" "Terra"})))
+
+
+(fact "modis-subsets test. All keys in `modis-subsets` should be found
+inside the HDF file located at `hdf-path`."
+  (map subdataset-key
+       (subdataset-names hdf-path)) => (just (keys modis-subsets) :in-any-order))
+
+(facts "filter checker."
+  (let [test-keys (fn [keys]
+                    (filter (dataset-filter keys)
+                            (subdataset-names hdf-path)))]
+    "If the user supplies a sequence of appropriate keys, the function
+will return a sequence of subdataset names corresponding to the
+supplied keys (in order)."
+    (test-keys #{:ndvi :evi}) => #(= (count %) 2)
+    (test-keys [:ndvi :evi])  => #(= (count %) 2)
+
+    "If a key is missing, the generated function throws an assertion
+error."
+    (test-keys #{:missingkey}) => (throws AssertionError)))
+
+(tabular
+ (let [src (io/hfs-wholefile hdf-path)
+       [datasets n] ((juxt identity count) ?dataset-seq)]
+   (fact?<- "Test that our cascalog queries are returning
+             the proper subdatasets."
+            ?result [?count]
+            (src ?filename ?hdf)
+            (unpack-modis [datasets] ?hdf :> ?dataset ?freetile)
+            (c/count ?count)))
+ ?dataset-seq      ?result
+ [:ndvi :evi]      [[2]]
+ [:evi :reli :mir] [[3]])
+
+(tabular
+ (fact "Test ensuring that raster-chunks can be serialized, and that
+ they produce the proper number of chunks for the supplied
+ chunk-size. (By pushing raster-chunks down into a subquery, we force
+ serialization of tuples before they're utilized inside of the final
+ `fact?<-` query.)"
+   (let [src       (io/hfs-wholefile hdf-path)
+         chunk-size ?c-size
+         subquery  (<- [?dataset ?chunkid ?chunk]
+                       (src ?filename ?hdf)
+                       (unpack-modis [[:ndvi]] ?hdf :> ?dataset ?freetile)
+                       (raster-chunks [chunk-size] ?freetile :> ?chunkid ?chunk))]
+     (fact?<- [[?num-chunks]]
+              [?count]
+              (subquery ?dataset ?chunkid ?chunk)
+              (c/count ?count))))
+ ?c-size ?num-chunks
+ 24000   60
+ 48000   30
+ 96000   15)
+
+(tabular
+ (fact "Check on the proper unpacking of the HDF file metadata map."
+   (let [src (io/hfs-wholefile hdf-path)
+         [ks xs] ((juxt keys vals) ?meta-map)]
+     (fact?<- [xs]
+              [?productname ?tileid ?date]
+              (src ?filename ?hdf)
+              (unpack-modis [[:ndvi]] ?hdf :> ?dataset ?freetile)
+              (meta-values [ks] ?freetile :> ?productname ?tileid ?date))))
+ ?meta-map
+ {"RANGEBEGINNINGDATE" "2000-02-01"
+  "SHORTNAME"          "MOD13A3"
+  "TileID"             "51003011"})
+
+(fact "split-id tests."
+  (split-id "51003011") => [3 11]
+  (split-id "52010010") => [10 10]
+  (split-id "54029009") => [29 9])
+
+(fact "modis-chunks test. `modis-chunks` is bound to a subquery, which
+is used as a source for the final count aggregator. We check that the
+chunk-size makes sense for the supplied dataset.
+
+Note that this only works when the file at hdf-path has a spatial
+resolution of 1000m; otherwise, the relationship between chunk-size
+and total chunks becomes off."
+  (let [subquery (->> (io/hfs-wholefile hdf-path)
+                      (modis-chunks [:ndvi] 24000))]
+    (fact?<- [[60]]
+             [?count]
+             (subquery ?datachunk)
+             (c/count ?count))))


Beginnings of the gems map file.

Beginnings of the gems map file.

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

--- src/circle/backend/build/inference/gems_map.clj
+++ src/circle/backend/build/inference/gems_map.clj
@@ -0,0 +1,7 @@
+(ns circle.backend.build.inference.gems-map)
+
+(def gem-package-map
+  ;; this is a map of rubygems to the ubuntu packages necessary for this gem to install. Incomplete.
+  {"memcached" #{"libmemcached-dev" "libsasl2-dev"}
+   "cdamian-geoip_city" #{"libgeoip-dev"}}
+  )


changing repl-api commands so that they return nil

for some reason the SystemMap is getting printed out intermitently,
since these functions are not intended to be composed there is no
reason to return the SystemMap

--- sidecar/src/figwheel_sidecar/repl_api.clj
+++ sidecar/src/figwheel_sidecar/repl_api.clj
@@ -15,10 +15,13 @@
   ([{:keys [figwheel-options all-builds build-ids] :as autobuild-options}]
    (when *repl-api-system*
      (alter-var-root #'*repl-api-system* component/stop))
-   (alter-var-root #'*repl-api-system* (fn [_] (fs/start-figwheel! autobuild-options))))
+   (alter-var-root #'*repl-api-system* (fn [_] (fs/start-figwheel! autobuild-options)))
+   nil)
   ([]
    (if *repl-api-system*
-     (alter-var-root #'*repl-api-system* component/start)
+     (do
+       (alter-var-root #'*repl-api-system* component/start)
+       nil)
      ;; if no system exists try to read in a configuration
      (start-figwheel! (config/fetch-config)))))

@@ -26,7 +29,8 @@
   "If a figwheel process is running, this will stop all the Figwheel autobuilders and stop the figwheel Websocket/HTTP server."
   []
   (when *repl-api-system*
-    (alter-var-root #'*repl-api-system* component/stop)))
+    (alter-var-root #'*repl-api-system* component/stop)
+    nil))

 (defn figwheel-running? []
   (or (get-in *repl-api-system* [:figwheel-system :system-running] false)
@@ -38,11 +42,13 @@
   ([func ids]
    (when (figwheel-running?)
      (let [system (get-in *repl-api-system* [:figwheel-system :system])]
-       (reset! system (func @system ids)))))
+       (reset! system (func @system ids))
+       nil)))
   ([func]
    (when (figwheel-running?)
      (let [system (get-in *repl-api-system* [:figwheel-system :system])]
-       (reset! system (func @system))))))
+       (reset! system (func @system))
+       nil))))

 (defn build-once
   "Compiles the builds with the provided build ids
@@ -88,9 +94,11 @@
   "Prints out the build configs currently focused or optionally the
   configs of the ids provided."
   [& ids]
-  (fs/print-config
-   @(get-in *repl-api-system* [:figwheel-system :system])
-   ids))
+  (do
+    (fs/print-config
+     @(get-in *repl-api-system* [:figwheel-system :system])
+     ids)
+    nil))

 (defn cljs-repl
   "Starts a Figwheel ClojureScript REPL for the provided build id (or


Add Jaunt repl example

Add Jaunt repl example

For those into that thing.

error: pathspec 'examples/jaunt-repl.clj' did not match any file(s) known to git

--- examples/jaunt-repl.clj
+++ examples/jaunt-repl.clj
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+#_[
+   eval "exec $(inlein --sh-cmd "$0" "$@")"
+#_ 0]
+
+;; Instead of using Clojure, we can use the Jaunt-lang fork and make a repl out
+;; of it. Remember that most dependencies depend on Clojure, and so you'll
+;; probably have to explicitly exclude org.clojure/clojure for dependencies you
+;; add in.
+
+'{:dependencies [[org.jaunt-lang/jaunt "1.9.0-RC4"]
+                 [reply "0.3.7" :exclusions [net.cgrand/parsley
+                                             org.clojure/clojure]]
+                 [net.cgrand/parsley "0.9.3" :exclusions [org.clojure/clojure]]]
+  :jvm-opts ["-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" "-Dfile.encoding=UTF-8"]}
+
+(reply.ReplyMain/main (into-array String ["--standalone"]))
+
+


[WM] update deps to latest versions

[WM] update deps to latest versions

...except datomic-toolbox b/c that's a bit harder.


add project.clj

add project.clj

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

--- project.clj
+++ project.clj
@@ -0,0 +1,16 @@
+(defproject core.matrix.dojo "0.0.1-SNAPSHOT"
+  :description "FIXME: write this!"
+  :url "http://example.com/FIXME"
+
+  :dependencies [[org.clojure/clojure "1.5.1"]
+
+                 [org.clojure/java.jdbc "0.3.3"]
+                 [net.mikera/clojure-utils "0.6.0"]
+                 [net.mikera/core.matrix "0.20.0"]
+              ]
+
+  :source-paths ["src/main/clojure"]
+  :test-paths ["src/test/clojure"]
+
+  :resource-paths ["src/main/resources"]
+)


Version 92

Version 92

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


Update dependencies to address CVEs

Update dependencies to address CVEs


bump blueprints

bump blueprints

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


[WM] update deps

[WM] update deps

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


Upgrade kehaar to 0.10.3

Upgrade kehaar to 0.10.3

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


Upgrade bifrost to 0.3.0

Upgrade bifrost to 0.3.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/democracyworks/turbovote-http-api.git/'


upgrade to lein 2

upgrade to lein 2

--- project.clj
+++ project.clj
@@ -1,8 +1,7 @@
 (defproject storm-starter "0.0.1-SNAPSHOT"
-  :source-path "src/clj"
-  :java-source-path "src/jvm"
-  :javac-options {:debug "true" :fork "true"}
-  :resources-path "multilang"
+  :source-paths ["src/clj"]
+  :java-source-paths ["src/jvm"]
+  :resource-paths ["multilang"]
   :aot :all
   :repositories {
 ;;                 "twitter4j" "http://twitter4j.org/maven2"
@@ -14,7 +13,8 @@
                    [commons-collections/commons-collections "3.2.1"]
                  ]

-  :dev-dependencies [[storm "0.8.2"]
-                     [org.clojure/clojure "1.4.0"]
-                     ])
-
+  :profiles {:dev
+              {:dependencies [[storm "0.8.2"]
+                              [org.clojure/clojure "1.4.0"]]}}
+  :min-lein-version "2.0.0"
+  )


Version 1.15.1

Version 1.15.1


Version 147-SNAPSHOT

Version 147-SNAPSHOT


Update carmine deps

Update carmine deps

Signed-off-by: Roman Selmeci <bb938fc7591901d0e874df22e3ae174886bcb931@infones.com>

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/infones/http-kit.git/'


Cleanup license, etc.

Cleanup license, etc.

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


Update Prismatic Schema to latest version (1.0.3)

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


Version 49

Version 49

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojars-web "49-SNAPSHOT"
+(defproject clojars-web "49"
   :min-lein-version "2.0.0"
   :dependencies [[org.clojure/clojure "1.8.0"]
                  [org.clojure/tools.cli "0.2.1"]


Add render2

Add render2

error: pathspec 'src/zaffre/components/render2.cljc' did not match any file(s) known to git

--- src/zaffre/components/render2.cljc
+++ src/zaffre/components/render2.cljc
@@ -0,0 +1,668 @@
+(ns zaffre.components.render2
+  (:require clojure.data
+            [clojure.string]
+            [clojure.test :refer [is]]
+            [taoensso.timbre :as log]
+            [zaffre.components :as zc]
+            [gossamer.core-graal :as g]
+            [gossamer.element :as ge]
+            [gossamer.host-config :as ghc]
+            [zaffre.components.layout :as zl]
+            [zaffre.text :as ztext]
+            [zaffre.terminal :as zt]
+            [zaffre.util :as zu]))
+
+(def default-style
+  {:color (unchecked-int 0xffffffff) #_[255 255 255 255]
+   :background-color (unchecked-int 0x000000ff) #_[0 0 0 255]
+   :border-style :single
+   :border 0
+   :border-left 0
+   :border-right 0
+   :border-top 0
+   :border-bottom 0
+   :mix-blend-mode :normal
+})
+
+;; Primitive elements
+(def primitive-elements #{:terminal :group :layer :view :text :img})
+(defn primitive? [component]
+  (or (string? component)
+      (contains? primitive-elements (first component))))
+
+(def text-forbidden-styles
+  #{:border
+    :border-left
+    :border-right
+    :border-top
+    :border-bottom
+    :border-horizontal
+    :border-vertical
+    :padding
+    :padding-left
+    :padding-right
+    :padding-top
+    :padding-bottom
+    :padding-horizontal
+    :padding-vertical})
+
+; https://stackoverflow.com/questions/5612302/which-css-properties-are-inherited
+(def inheritable-styles #{
+  :azimuth
+  :background-color
+  :border-collapse
+  :border-spacing
+  :caption-side
+  :color
+  :cursor
+  :direction
+  :elevation
+  :empty-cells
+  :font-family
+  :font-size
+  :font-style
+  :font-variant
+  :font-weight
+  :font
+  :letter-spacing
+  :line-height
+  :list-style-image
+  :list-style-position
+  :list-style-type
+  :list-style
+  :orphans
+  :pitch-range
+  :pitch
+  :quotes
+  :richness
+  :speak-header
+  :speak-numeral
+  :speak-punctuation
+  :speak
+  :speech-rate
+  :stress
+  :text-align
+  :text-indent
+  :text-transform
+  :visibility
+  :voice-family
+  :volume
+  :white-space
+  :widows
+  :word-spacing})
+
+(defn cascade-style
+  ([element] (cascade-style {} element))
+  ([parent-style [type props children]]
+    (if (or (= type :text) (= type :img))
+      [type
+       (update-in props [:style] #(merge (select-keys parent-style inheritable-styles) %))
+       children]
+      (let [new-style (merge (select-keys parent-style inheritable-styles) (get props :style {}))]
+        [type
+         (assoc props :style new-style)
+         (map (partial cascade-style new-style) children)]))))
+
+; bounds are [x1 y1 x2 y2]
+(defn layout->bounds [{:keys [x y width height]}]
+  [x y (+ x width) (+ y height)])
+
+(defmacro between [lower-bound value upper-bound]
+  `(and (< ~lower-bound ~value) (< ~value ~upper-bound)))
+
+(defn render-string-into-container [target x y color background-color s blend-mode]
+  {:pre [(number? x)
+         (number? y)
+         (or (integer? color) (vector? color))
+         (or (integer? background-color) (vector? background-color))
+         (string? s)]}
+  ;(log/info "render-string-into-container" x y color background-color s)
+  (when (between -1 y (zt/num-rows target))
+    (let [max-x (int (zt/num-cols target))
+          row (int y)]
+      (loop [index 0 s s]
+        (let [col (int (+ x index))
+              c   (first s)]
+          (when (and c
+                     (between -1 col max-x))
+            (zt/set! target c blend-mode (int 0) color background-color col row)
+            (recur (inc index) (rest s))))))))
+
+(defn render-text-into-container [target text-element]
+  {:pre [(= (first text-element) :text)
+         (map? (second text-element))
+         (not (empty? (last text-element)))]}
+  (log/debug "render-text-into-container" text-element)
+  (let [[type {:keys [style zaffre/layout] :or {style {}} :as props} children] text-element
+        {:keys [x y width height]} layout
+        {:keys [text-align mix-blend-mode] :or {text-align :left mix-blend-mode :normal}} style
+        lines (ztext/word-wrap-text-tree width height (if (every? string? children)
+                                                          [:text props (map (fn [child] [:text {} [child]]) children)]
+                                                          text-element))]
+    (log/trace "render-text-into-container lines" (vec lines))
+    (zu/loop-with-index dy [line lines]
+      (let [default-color (get default-style :color)
+            default-background-color (get default-style :background-color)]
+        (when (and (< dy height) (not (empty? line)))
+          (log/trace "rendering line" (vec line))
+          ;; remove inc? for spaces
+          (let [but-last (butlast line)
+                last-span (let [[s style _] (last line)
+                                s (clojure.string/trim s)]
+                           [s style (count s)])
+                line (concat but-last (list last-span))
+                _ (log/trace "rendering line2" (vec line))
+                span-lengths (map (fn [[s _ length]] length) line)
+                line-length (reduce + 0 span-lengths)
+                align-offset (case text-align
+                               :left 0
+                               :center (/ (- width line-length) 2)
+                               :right (- width line-length))
+                offsets (map (partial + align-offset) (cons 0 (reductions + span-lengths)))]
+            (log/trace "line-length" line-length)
+            (log/trace "lengths" (vec span-lengths))
+            (log/trace "offsets" (vec offsets))
+            (doseq [[dx [s {:keys [color background-color]} _]] (map vector offsets line)]
+              (render-string-into-container
+                target
+                (+ x dx) (+ y dy)
+                (or color default-color)
+                (or background-color default-background-color)
+                (clojure.string/trim s)
+                mix-blend-mode))))))))
+
+(defn render-img-into-container [target img-element]
+  {:pre [(= (first img-element) :img)
+         (map? (second img-element))
+         #_(not (empty? (last img-element)))]}
+  #_(log/debug "render-img-into-container" img-element)
+  (let [[type {:keys [style zaffre/layout] :or {style {}} :as props} children] img-element
+        {:keys [mix-blend-mode] :or {mix-blend-mode (get default-style :mix-blend-mode)}} style
+        {:keys [x y width height overflow-bounds]} layout
+        overflow-bounds (or overflow-bounds (layout->bounds layout))
+        [overflow-min-x overflow-min-y overflow-max-x overflow-max-y] overflow-bounds
+        overflow-max-x (int overflow-max-x)
+        ;; bounds for overflow/target container (whichever is smaller)
+        min-x (dec (max 0 overflow-min-x))
+        min-y (dec (max 0 overflow-min-y))
+        num-cols-target (zt/num-cols target)
+        num-rows (int (zt/num-rows target))
+        max-y (min overflow-max-y num-rows)
+        lines (last img-element)]
+    #_(log/debug "render-img-into-container layout " layout)
+    #_(log/trace "render-img-into-container lines" (vec lines))
+    (zu/loop-with-index dy [line lines]
+      (let [y (int y)
+            dy (int dy)
+            row (+ y dy)]
+        (when (and (< dy height) (not (empty? line)) (< min-y row max-y))
+          #_(log/trace "rendering line" (vec line))
+          (zu/loop-with-index dx [{:keys [c fg bg] :as pixel} line]
+            (assert (char? c))
+            (assert (or (integer? fg) (vector? fg)))
+            (assert (or (integer? bg) (vector? bg)))
+            (let [max-x (min overflow-max-x num-cols-target)
+                  x (int x)
+                  dx (int dx)
+                  col (int (+ x dx))]
+              (when (< min-x col max-x)
+                #_(log/trace "rendering pixel x:" col " y:" row " " pixel " max-x:" max-x " max-y:" (zt/num-rows target))
+                (zt/set! target (get pixel :c) mix-blend-mode (get pixel :palette-offset 0) (get pixel :fg) (get pixel :bg) col row)))))))))
+
+(defn element-seq [element]
+  "Returns :view and top-level :text elements."
+  (tree-seq (fn [[type _ _]] (and (not= type :text) (not= type :img)))
+            (fn [[_ _ children]] children)
+            element))
+
+(defmulti render-component-into-container (fn [_ element] (first element)))
+
+;; render text
+(defmethod render-component-into-container :text
+  [target text-element]
+  (render-text-into-container target text-element))
+
+;; render imgs
+(defmethod render-component-into-container :img
+  [target img-element]
+  (render-img-into-container target img-element))
+
+;; Border
+(def single-border
+  {:horizontal   \u2500
+   :vertical     \u2502
+   :top-left     \u250C
+   :top-right    \u2510
+   :bottom-left  \u2514
+   :bottom-right \u2518})
+
+(def double-border
+  {:horizontal   \u2550
+   :vertical     \u2551
+   :top-left     \u2554
+   :top-right    \u2557
+   :bottom-left  \u255A
+   :bottom-right \u255D})
+
+;; render views
+(defmethod render-component-into-container :view
+  [target [type {:keys [style zaffre/layout]}]]
+    (let [{:keys [x y width height]} layout
+          {:keys [color background-color
+                  border border-style
+                  border-top border-bottom
+                  border-left border-right
+                  mix-blend-mode]} (merge default-style style)]
+      ;; render background when set
+      (when background-color
+        (doseq [dy (range height)
+                :let [color (or color (get default-style :color))]]
+          (render-string-into-container target x (+ y dy) color background-color (clojure.string/join (repeat width " ")) mix-blend-mode)))
+      ; render border when set
+      (when border-style
+        (let [border-map (case border-style
+                           :single single-border
+                           :double double-border)]
+          ; render top
+          (when (or (< 0 border) (< 0 border-top))
+            (render-string-into-container target x y color background-color
+              (str (when (or (< 0 border) (< 0 border-left))
+                     (get border-map :top-left))
+                   (clojure.string/join (repeat (- width (+ (or border border-left) (or border border-right)))
+                                                (get border-map :horizontal)))
+                   (when (or (< 0 border) (< 0 border-right))
+                     (get border-map :top-right)))
+               mix-blend-mode))
+          ; render middle
+          (doseq [dy (range (- height 2))]
+            (when (or (< 0 border) (< 0 border-left))
+              (render-string-into-container target x (+ y dy 1) color background-color (str (get border-map :vertical)) mix-blend-mode))
+            (when (or (< 0 border) (< 0 border-right))
+              (render-string-into-container target (+ x width -1) (+ y dy 1) color background-color (str (get border-map :vertical)) mix-blend-mode)))
+          ; render bottom
+          (when (or (< 0 border) (< 0 border-bottom))
+            (render-string-into-container target x (+ y height -1) color background-color
+              (str (when (or (< 0 border) (< 0 border-left))
+                     (get border-map :bottom-left))
+                   (clojure.string/join (repeat (- width (+ (or border border-left) (or border border-right)))
+                                                (get border-map :horizontal)))
+                   (when (or (< 0 border) (< 0 border-right))
+                     (get border-map :bottom-right)))
+              mix-blend-mode)))))
+    nil)
+
+;; Do nothing for :layer
+(defmethod render-component-into-container :layer
+  [_ component]
+  nil)
+
+;; die if not :layer nor :view nor :text
+(defmethod render-component-into-container :default
+  [_ component]
+  (assert false (format "Found unknown component %s" component)))
+
+(defn intersect-bounds [[ax1 ay1 ax2 ay2 :as a-bounds] [bx1 by1 bx2 by2 :as b-bounds]]
+  (and
+    (< ax1 bx2)
+    (> ax2 bx1)
+    (> ay1 by2)
+    (< ay2 by1)))
+
+(defn inherit-overflow-bounds
+  ([element]
+    (inherit-overflow-bounds nil element))
+  ([parent-bounds element]
+    (let [[type props children] element]
+      (cond
+        (or (= type :text) (= type :img))
+          [type
+           (if parent-bounds
+             (assoc-in props [:zaffre/layout :overflow-bounds] parent-bounds)
+             props)
+           children]
+        (= (get-in props [:style :overflow]) :hidden)
+          [type
+           props
+           (map (partial inherit-overflow-bounds (layout->bounds (get props :zaffre/layout))) children)]
+        :else
+          [type
+           props
+           (map (partial inherit-overflow-bounds parent-bounds) children)]))))
+
+(defn render-layer-into-container
+  [target layer]
+  (log/trace "render-layer-into-container" layer)
+  (let [layer-en-place (zl/layout-element layer)
+        elements (-> (inherit-overflow-bounds layer-en-place)
+                   element-seq
+                   vec)]
+    #_(log/trace "render-layer-into-container elements" elements)
+    #_(log/trace "render-layer-into-container layer-en-place" (zc/tree->str layer-en-place))
+    (doseq [element elements]
+      #_(log/debug "render-layer-into-container element" element)
+      (render-component-into-container target element))
+    elements))
+
+(defn log-layer [layer-id layer-container]
+  (println "▓" layer-id "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓")
+  (doseq [row (range (zt/num-rows layer-container))]
+    (doseq [col (range (zt/num-cols layer-container))
+            :let [c (zt/get-char layer-container col row)]]
+      (if (< 0 (int c) 255)
+        (print c)
+        (print \space)))
+    (println "▓"))
+  (println "▓" layer-id "▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓"))
+
+(defn layer-info [group-info]
+  "Given a terminal's group info, create a map layer-id->{:columns rows}."
+  (into {}
+    (mapcat identity
+      (map (fn [{:keys [layers columns rows]}]
+             (map (fn [layer-id]
+                    [layer-id {:columns columns :rows rows}])
+                  layers))
+           (vals group-info)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Render to virtual dom ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defn type-match? [existing element]
+   (= (get element :type)
+      (get existing :type)))
+
+(defn props-without-children-match? [existing element]
+   (= (get (zc/element-without-children element) :props)
+      (get (zc/element-without-children existing) :props)))
+
+(defn state-changed? [element]
+  (when (and element (get element :id))
+    (zc/element-state-changed? zc/*updater* element)))
+
+(defn- check-elem [existing element result]
+ true
+ #_(if(zc/element? result)
+    true
+    (do
+      (log/error "render did not returnn element")
+      (log/error "existing")
+      (log/error (zc/tree->str existing))
+      (log/error "element")
+      (log/error (zc/tree->str element))
+      (log/error "result")
+      (log/error (zc/tree->str result))
+      false)))
+
+(defn first-element-id [& elements]
+  (some :id elements))
+
+;; render a single element if needed
+(defn render [existing parent element]
+  #_{:pre [(is (or (nil? existing) (zc/element? existing)) (zc/tree->str element))
+         (is (zc/element? element) (zc/tree->str element))]
+   :post [(is (or (nil? %) (string? %) (and (zc/element? %) (check-elem existing element %))) (zc/element-display-name %))]}
+  (log/trace "existing" [(zc/element-display-name existing) (zc/element-id-str existing)]
+            "element"  [(zc/element-display-name element) (zc/element-id-str element)])
+
+  #_(log/info "existing" (zc/tree->str existing))
+  #_(log/info "element" (zc/tree->str element))
+  (if (type-match? existing element)
+    (log/trace "type-match? true")
+    (log/trace "type-mismatch" (get existing :type) (get element :type)))
+  (if (and (zc/element? existing)
+           (props-without-children-match? existing element))
+   (log/trace "props-without-children-match? true")
+   (log/trace "props-without-children-mismatch" (vec (take 2
+                                                  (clojure.data/diff
+                                                    (get (zc/element-without-children existing) :props)
+                                                    (get (zc/element-without-children element) :props))))))
+  (if (and (zc/element? existing)
+           (state-changed? existing))
+    (log/trace "state-changed" (zc/get-state zc/*updater* existing))
+    (log/trace "state-changed? false"))
+  ;; if element = existing, no-op return element
+  (cond
+    ;; identical to existing element. skip lifecycle, just render
+    (and (type-match? existing element)
+         (props-without-children-match? existing element)
+         (not (state-changed? existing)))
+      (binding [zc/*current-owner* existing]
+        #_(log/info "identical rendering element" (zc/element-display-name existing))
+        #_(log/info "existing" (zc/element-id-str existing) "element" (zc/element-id-str element))
+        #_(log/info "element children:\n" (first (zc/element-children element)))
+        (let [instance (zc/construct-instance (assoc element :id (get existing :id)))
+              next-element (zc/render instance)]
+          next-element))
+    ;; same type, new props?
+    (and (type-match? existing element)
+         (or
+           (not (props-without-children-match? existing element))
+           (state-changed? existing)))
+      ;; updating
+      (binding [zc/*current-owner* existing]
+        #_(log/info "same type, different-props or state" (zc/element-display-name existing))
+        #_(log/info "existing" (zc/element-id-str existing) "element" (zc/element-id-str element))
+        (let [; copy prev state into instance because we're checking to see how the component
+              ; handles the change from prev-state to next state
+              instance (zc/construct-instance existing)
+              prev-instance (assoc instance :state (zc/get-prev-state zc/*updater* existing))
+              prev-props (get existing :props)
+              next-props (get element :props)
+              prev-state (zc/get-prev-state zc/*updater* existing)
+              next-state (zc/get-state zc/*updater* existing)
+              ;; only call when props have changed
+              _ (when-not (props-without-children-match? existing element)
+                  (zc/component-will-receive-props prev-instance next-props))]
+         (if (zc/should-component-update? prev-instance next-props next-state)
+           (let [_ (zc/component-will-update prev-instance next-props next-state)
+                 instance (zc/construct-instance (assoc element :id (get existing :id)))
+                 next-element (zc/render instance)
+                 _ (zc/component-did-update instance prev-props prev-state)]
+             (log/debug "should-component-update? = true" (get existing :id) (zc/element-display-name existing))
+             (log/trace "next-element" (type next-element))
+             (log/trace (zc/element-display-name next-element))
+             #_(log/trace (zc/tree->str next-element))
+             next-element)
+           (do
+             (assert false)
+             (log/info "should-component-update? = false" (get existing :id) (zc/element-display-name existing))
+             (first (zc/element-children existing))))))
+    ;; initial render
+    :default
+    (binding [zc/*current-owner* element]
+      #_(log/info "initial-render" (type element))
+      #_(log/info "initial-render" (type existing))
+      #_(log/info "initial-render" "existing" (zc/element-display-name existing) "element" (zc/element-display-name element))
+      (let [instance (zc/construct-instance element)
+            _ (log/trace "constructed component")
+            ;; derive state from props
+            derived-state (let [next-props (get element :props)
+                                prev-state (zc/get-state zc/*updater* element)]
+                            (zc/get-derived-state-from-props instance next-props prev-state))
+            _ (when derived-state
+                (zc/immediate-set-state! zc/*updater* element derived-state))
+            _ (zc/component-will-mount instance)
+            _ (log/trace "rendering component" (str instance))
+            next-element (zc/render instance)
+            _ (zc/component-did-mount instance)]
+        ;; unmount existing if it exists
+        (when (and existing (zc/component? (get existing :type)))
+            (log/trace "unmounting" (get existing :id) (zc/element-display-name existing))
+            (zc/component-will-unmount (zc/construct-instance existing))
+            (zc/enqueue-remove-state! zc/*updater* existing))
+        next-element))))
+
+(defn- without-type [v]
+  (if (map? v)
+    (dissoc v :type)
+    v))
+
+(defn render-recursively
+  ([element]
+    (render-recursively nil element))
+  ([existing element]
+    (render-recursively existing nil element))
+  ([existing parent element]
+   {:post [(is (or (nil? %) (string? %) (and (zc/element? %) (check-elem existing element %))) (zc/element-display-name %))]}
+    #_(when (= existing element)
+      (log/warn "WARNING Existing = Element WARNING"))
+    (log/trace "render-recursively existing" (zc/element-display-name existing) (count (zc/element-children existing)) #_(without-type existing))
+    (log/trace "render-recursively element" (zc/element-display-name element) (count (zc/element-children element)) #_(without-type element))
+    #_(log/trace "existing:\n" (zc/tree->str existing))
+    #_(log/trace "element:\n" (zc/tree->str element))
+    (cond
+      (nil? element)
+        element
+      (string? element)
+        (do (log/trace "rendering string" element)
+        element)
+      ;; built-in?
+      (keyword? (get element :type))
+        (if (= (get element :type) :img)
+          ;; imgs have pre-rendered pixel children
+          (assoc element :id (get existing :id))
+          ;; render other built-ins by rendering their chldren
+          (let [rendered-children (zc/map-children (fn [child existing-child]
+                                                     (render-recursively existing-child element child))
+                                                   element
+                                                   existing)]
+            (-> element
+              (zc/assoc-children (remove nil? rendered-children))
+              (assoc
+                :id
+                (if (type-match? existing element)
+                  (first-element-id existing element)
+                  (get element :id))))))
+      :default
+        (let [;; Render one level
+              rendered-element (render (when (zc/element? existing) existing)
+                                       parent
+                                       element)
+              rendered-child (render-recursively (first (zc/element-children existing))
+                                                    element
+                                                    rendered-element)]
+          (log/trace "rendered element" (zc/element-display-name rendered-element))
+          (log/trace "element-id" (zc/element-id-str rendered-child))
+          (assert (is (zc/element? rendered-element)))
+          (assert (zc/element? rendered-child)
+            (str (zc/element-display-name element) " -> "
+                 (zc/element-display-name rendered-element) " -> "
+                 (zc/element-display-name rendered-child) "\n"
+                 rendered-child))
+          ; take the rendered element and assign it as the child to `element`.
+          ; render recursively, the rendered-element
+          (-> element
+            (zc/assoc-children [rendered-child])
+            ;; assign existing id so that state lookup works
+            ;; FIXME find out why this kills Popup
+            (assoc
+              :id
+              (if (type-match? existing element)
+                (first-element-id existing element)
+                (get element :id))))))))
+
+(defn extract-native-elements [element]
+  (cond
+    (nil? element)
+      []
+    (= :text (get element :type))
+      [[:text
+       (dissoc (get element :props {}) :children)
+       (let [children (zc/element-children element)]
+         (if (every? string? children)
+           children
+           (mapcat extract-native-elements children)))]]
+    (= :img (get element :type))
+      [[:img
+       (dissoc (get element :props {}) :children)
+       (zc/element-children element)]]
+    (keyword? (get element :type))
+      [[(get element :type)
+       (dissoc (get element :props {}) :children)
+       (vec (mapcat extract-native-elements (zc/element-children element)))]]
+    :default
+      (vec (mapcat extract-native-elements (zc/element-children element)))))
+
+(def terminal-layer-buffers (atom {}))
+
+;; Renders component into container. Does not call refresh! on container
+(defn render-into-container
+  "Renders element into target. If existing is supplied, appropriate component
+   lifecycle handlers will be invoked. Response is rendered elements with a
+   meta property :layout-elements containing component id and layout records."
+  ([target element]
+    (render-into-container target nil element))
+  ([target existing root-element]
+    (let [group-info (zt/groups target)
+          layer-info (layer-info group-info)
+          ;; render to native elements
+          #_#_root-element (render-recursively existing element)
+          [type props groups :as root-dom] (-> root-element
+                                              extract-native-elements
+                                              first
+                                              cascade-style)
+          elements (atom (list))]
+      #_(log/info "render-into-container existing" (zc/tree->str existing))
+      #_(log/info "render-into-container rendered-element" (zc/tree->str root-element))
+      ;(log/trace "render-into-container" (clojure.pprint/pprint root-dom))
+      (assert (= type :terminal)
+              (format "Root component not :terminal found %s instead" type))
+      ;; for each group in terminal
+      (doseq [[type {:keys [id pos]} layers] groups
+              :let [{:keys [columns rows]} (get group-info id)]]
+        (assert (= type :group)
+                (format "Expected :group found %s instead" type))
+        (log/trace "rendering group" id)
+        ;; update group pos
+        (when pos
+          (zt/alter-group-pos! target id pos))
+        ;; for each layer in group
+        (doseq [[type {:keys [id style]} :as layer] layers]
+          (assert (= type :layer)
+                  (format "Expected :layer found %s instead. %s" type (str layer)))
+          ;; create a container to hold cells
+          ;; TODO reuse buffers
+          (let [layer-container (zt/array-buffers columns rows)
+                                #_(or (get @terminal-layer-buffers id)
+                                    (let [buffers (zt/array-buffers columns rows)]
+                                      (swap! terminal-layer-buffers assoc id buffers)
+                                      buffers))
+                ;; merge layer width height into layer's style
+                {:keys [columns rows]} (get layer-info id)]
+            (log/trace "render-into-container - layer" id)
+            ;; reusing layer-container so zero out before rendering
+            ;(zt/zero! layer-container)
+            ;; render layer into layer-container
+            (swap! elements concat
+              (render-layer-into-container
+                 layer-container
+                 (-> layer
+                   ;; assign width and height to layer style
+                   (assoc-in [1 :style :width] columns)
+                   (assoc-in [1 :style :height] rows))))
+            #_(log-layer id layer-container)
+            ;; send layer changes to terminal
+            (zt/put-layer! target id layer-container))))
+      (with-meta root-element {:layout-elements @elements}))))
+
+
+(defn commit-mount
+  [terminal frames root-container-instance]
+  (log/info "reset-after-commit")
+  (log/info "rendering" root-container-instance)
+  ;(render-into-container terminal root-container-instance)
+  ;(zt/refresh! terminal)
+  (swap! frames inc)
+  (log/info "After frames inc"))
+
+(defn context
+  [terminal & [frames]]
+  (let [context (g/context {"commitMount" (partial commit-mount terminal frames)})]
+    context))
+
+(defn render
+  [context-ref element]
+  (binding [g/*context* context]
+    ; render into an empty vector
+    (g/render context-ref element [])))
+


Render proper p2 board

Render proper p2 board

--- src/cljs/battle_console/game.cljs
+++ src/cljs/battle_console/game.cljs
@@ -6,13 +6,25 @@
             [cljs.reader :as reader]
             [secretary.core :as secretary :refer-macros [defroute]]))

+(defn- normalize-board
+  "Uses p2-focused-board if present"
+  [data]
+  (println "--normalize-board")
+  (println data)
+  (if (data :p2-focused-board)
+    (-> data
+        (assoc :board (data :p2-focused-board))
+        (dissoc :p2-focused-board))
+    data))
+
 (defn- game-loaded
   "After game was loaded"
   [data]
   (state/set-state :loading-game nil)
   (state/set-state :player-code (get-in data ["viewed-by" "player-code"]))
-  (state/set-state :original-game-data data)
-  (state/set-state :game-data data))
+  (let [final-data (normalize-board data)]
+    (state/set-state :original-game-data final-data)
+    (state/set-state :game-data final-data)))

 (defn- error-loading
   "Error loading game"
@@ -50,9 +62,10 @@
 (defn- get-stash
   "Gets the current stash"
   [game]
-  (or
-    (get-in game ["battle" "stash" "p1"])
-    (get-in game ["battle" "stash" "p2"])))
+  (println game)
+  (if (empty? (get-in game ["battle" "stash" "p1"]))
+    (get-in game ["battle" "stash" "p2"])
+    (get-in game ["battle" "stash" "p1"])))

 (defn- game-stash
   "Shows the current stash if available"
@@ -143,7 +156,7 @@
         current-action (state/get-state :processing-action)
         new-actions (conj actions current-action)
         current-game (state/get-state :game-data)
-        updated-game (assoc current-game "battle" (get data "board"))]
+        updated-game (assoc current-game "battle" (or (get data "p2-focused-board") (get data "board")))]
     (println updated-game)
     (state/set-state :game-data updated-game)
     (state/set-state :current-actions new-actions)
@@ -161,10 +174,13 @@
   (let [action (reader/read-string (get-action))
         current-actions (or (state/get-state :current-actions) [])
         new-actions (conj current-actions action)
+        player-code "p2"
         game (-> (state/get-state :original-game-data)
-                 (assoc :actions new-actions))
+                 (assoc :actions new-actions)
+                 (assoc :p2-focused-board (= player-code "p2"))
+                 (assoc :action-focus player-code))
         jsgame (js/encodeURIComponent (.stringify js/JSON (clj->js game)))
-        url (str "http://rules.api.orionsbelt.eu/game/turn/p1?context=" jsgame)]
+        url (str "http://rules.api.orionsbelt.eu/game/turn/" player-code "?context=" jsgame)]
     (state/set-state :processing-action action)
     (println (.stringify js/JSON (clj->js new-actions)))
     (GET url {:handler action-added


additional state updates to ensure things are kept in sync

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


Fix liking bug.

Fix liking bug.

--- src/cljs/movement/pages/feed.cljs
+++ src/cljs/movement/pages/feed.cljs
@@ -48,14 +48,12 @@
            ^{:key (rand-int 10000000)}
            [movement-component m]))])))

-(defn like [e {:keys [likes user-id url]}]
-  (.preventDefault e)
-  (when-not ((set likes) user-id)
-    (POST "like" {:params        {:session-url url :user-id user-id}
-                  :handler       (fn [r]
-                                   (let [pos (first (positions #{url} (map :url (session/get :feed))))]
-                                     (session/update-in! [:feed pos :session :likes] conj user-id)))
-                  :error-handler (fn [r] nil)})))
+(defn like [{:keys [user-id url]}]
+  (POST "like" {:params        {:session-url url :user-id user-id}
+                :handler       (fn [r]
+                                 (let [pos (first (positions #{url} (map :url (session/get :feed))))]
+                                   (session/update-in! [:feed pos :session :likes] conj user-id)))
+                :error-handler (fn [r] nil)}))

 (defn add-comment [e adding-comment? params]
   (.preventDefault e)
@@ -188,9 +186,10 @@
                likes (:likes session)]
            [:div.pure-u-1
             (when-not (= user-id viewing-user-id)
-              [:i.fa.fa-thumbs-up.fa-2x {:style      {:cursor (when-not ((set likes) user-id) 'pointer) :color (if ((set likes) user-id) "#009900" 'lightgray)}
-                                         :onClick    #(like % {:likes likes :user-id user-id :url url})
-                                         :onTouchEnd #(like % {:likes likes :user-id user-id :url url})}])
+              [:i.fa.fa-thumbs-up.fa-2x {:style      {:cursor (when-not ((set likes) viewing-user-id) 'pointer)
+                                                      :color (if ((set likes) viewing-user-id) "#009900" 'lightgray)}
+                                         :onClick    (fn [e] (.preventDefault e) (like {:user-id viewing-user-id :url url}))
+                                         :onTouchEnd (fn [e] (.preventDefault e) (like {:user-id viewing-user-id :url url}))}])

             [:i.fa.fa-comment.fa-2x {:onClick (fn [e] (.preventDefault e) (reset! adding-comment? (not @adding-comment?)))
                                      :onTouchEnd (fn [e] (.preventDefault e) (reset! adding-comment? (not @adding-comment?)))


mesos: force docker network type to bridge

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


mesos: simplify resource definitions

mesos: simplify resource definitions


added playground file

added playground file

error: pathspec 'pigpen-core/src/main/clojure/pigpen/pg.clj' did not match any file(s) known to git

--- pigpen-core/src/main/clojure/pigpen/pg.clj
+++ pigpen-core/src/main/clojure/pigpen/pg.clj
@@ -0,0 +1 @@
+(ns pigpen.pg)


catching initial build errors

catching initial build errors

--- sidecar/src/figwheel_sidecar/components/cljs_autobuild.clj
+++ sidecar/src/figwheel_sidecar/components/cljs_autobuild.clj
@@ -79,6 +79,17 @@
      libs
      (not-empty (mapv :file foreign-libs)))))

+;; this is just used for the initial build
+(defn catch-print-hook
+  "Build middleware hook that catches and prints errors."
+  [build-fn]
+  (fn [build-state]
+    (try
+      (build-fn build-state)
+      (catch Throwable e
+        (prn (ex-data (.getCause e)))
+        (notifications/report-exception e (ex-data (.getCause e)))))))
+
 (defrecord CLJSAutobuild [build-config figwheel-server]
   component/Lifecycle
   (start [this]
@@ -108,10 +119,11 @@
           ;; tiny experience tweak
           ;; first build shouldn't send notifications
           ((if (= cljs-build-fn figwheel-build)
-            (-> cljs-build
-                injection/hook
-                figwheel-start-and-end-messages)
-            cljs-build-fn) this)
+             (-> cljs-build
+                 catch-print-hook
+                 injection/hook
+                 figwheel-start-and-end-messages)
+             cljs-build-fn) this)
           (assoc this
                  ;; for simple introspection
                  :cljs-autobuild true


Fix DummyAuthorizer method args

Fix DummyAuthorizer method args


Add ss-atomic-orbitals-v2

Add ss-atomic-orbitals-v2

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

--- test/com/nomistech/clojure_the_language/c_900_appy_stuff/s_100_science/ss_atomic_orbitals_v2.clj
+++ test/com/nomistech/clojure_the_language/c_900_appy_stuff/s_100_science/ss_atomic_orbitals_v2.clj
@@ -0,0 +1,76 @@
+(ns com.nomistech.clojure-the-language.c-900-appy-stuff.s-100-science.ss-atomic-orbitals-v2
+  (:require [midje.sweet :refer :all]))
+
+(def +extra-orbitals-in-shell+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the number of extra orbitals of each type when compared to the previous shell."
+  [{}
+   {:s 1}
+   {:p 3}
+   {}
+   {:d 5}
+   {}
+   {:f 7}
+   {}])
+
+(def +orbitals-in-shell+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the number of orbitals of each type."
+  (reductions (fn [orbitals-in-previous-shell
+                   extra-orbitals-in-this-shell]
+                (merge-with + ; in case physics changes (just `merge` would do)
+                            orbitals-in-previous-shell
+                            extra-orbitals-in-this-shell))
+              +extra-orbitals-in-shell+))
+
+(def +max-orbitals-in-shell+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the maximum number of orbitals in that shell."
+  (for [m +orbitals-in-shell+]
+    (apply + (for [[_ v] m] v))))
+
+(def +max-orbitals-across-all-shells+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the maximum number of orbitals in total, across this shell and all
+  lower-energy shells."
+  (->> +max-orbitals-in-shell+
+       (reductions +)))
+
+(def +max-electrons-in-shell+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the maximum number of electrons in that shell."
+  (map (partial * 2)
+       +max-orbitals-in-shell+))
+
+(def +max-electrons-across-all-shells+
+  "For each shell, starting with a notional shell 0 which has no orbitals...
+  the maximum number of electrons in total, across this shell and all
+  lower-energy shells.
+  These numbers are the atomic numbers of the noble gases, with a 0 at the
+  start."
+  (map (partial * 2)
+       +max-orbitals-across-all-shells+))
+
+;;;; ___________________________________________________________________________
+
+(fact +orbitals-in-shell+
+  => [{}
+      {:s 1}
+      {:s 1 :p 3}
+      {:s 1 :p 3}
+      {:s 1 :p 3 :d 5}
+      {:s 1 :p 3 :d 5}
+      {:s 1 :p 3 :d 5 :f 7}
+      {:s 1 :p 3 :d 5 :f 7}])
+
+(fact +max-orbitals-in-shell+
+  => [0 1 4 4 9 9 16 16])
+
+(fact +max-orbitals-across-all-shells+
+  => [0 1 5 9 18 27 43 59])
+
+(fact +max-electrons-in-shell+
+  => [0 2 8 8 18 18 32 32])
+
+(fact +max-electrons-across-all-shells+
+  => [0 2 10 18 36 54 86 118])


trying a different parameter

trying a different parameter

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


comprehensive usage example finished except for one bug

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


Urtea zenbaki bat

Urtea zenbaki bat

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


add util/discard-nils

add util/discard-nils

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


Hahaha, Google throttles you. Thread/sleep keeps it from locking us out.

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


Removes couch/search

Removes couch/search

No longer needed — we go straight to ES

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


Allow any property value

Allow any property value


[#148365963] Allow `last_active` on team membership


Return useful error message for when password error token expires

--- src/metabase/api/session.clj
+++ src/metabase/api/session.clj
@@ -87,17 +87,18 @@
   [:as {{:keys [token password] :as body} :body}]
   {token    Required
    password [Required ComplexPassword]}
-  (api-let [400 "Invalid reset token"] [[_ user-id]                           (re-matches #"(^\d+)_.+$" token)
+  (api-let [400 "Invalid reset token"] [[_ user-id] (re-matches #"(^\d+)_.+$" token)
                                         user-id                               (Integer/parseInt user-id)
                                         {:keys [reset_token reset_triggered]} (sel :one :fields [User :reset_triggered :reset_token] :id user-id)]
     ;; Make sure the plaintext token matches up with the hashed one for this user
-    (check (try (creds/bcrypt-verify token reset_token)
-                (catch Throwable _))
-      [400 "Invalid reset token"]
+    (checkp (try (creds/bcrypt-verify token reset_token)
+                 (catch Throwable _))
+      'password "Invalid reset token")

-      ;; check that the reset was triggered within the last 1 HOUR, after that the token is considered expired
-      (> (* 60 60 1000) (- (System/currentTimeMillis) (or reset_triggered 0)))
-      [400 "Reset token has expired"])
+    ;; check that the reset was triggered within the last 1 HOUR, after that the token is considered expired
+    (checkp (> (* 60 60 1000) (- (System/currentTimeMillis) (or reset_triggered 0)))
+      'password "Reset token has expired")
+
     (set-user-password user-id password)
     ;; after a successful password update go ahead and offer the client a new session that they can use
     (let [session-id (create-session user-id)]


stack implementation

stack implementation

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

--- src/sandbox/stack.clj
+++ src/sandbox/stack.clj
@@ -0,0 +1,119 @@
+(ns sandbox.stack
+  (:require [instaparse.core :as insta])
+  (:require [clojure.zip :as z])
+  (:require [clojure.pprint :refer :all])
+  (:require [clojure.walk :as walk]))
+
+(def p pprint)
+
+(def language
+         "S =  ((FN-CALL|FN-DECL) <FN-SEP>)*
+          FN-CALL = <optional-whitespace> ID <optional-whitespace>
+                    <left-paren> PARAMS-LIST <right-paren>
+          PARAMS-LIST = <optional-whitespace> (ID|FN-CALL)
+                                   (<optional-whitespace> <PARAMS-SEP>
+                                    <optional-whitespace> (ID|FN-CALL))*
+          FN-DECL = <optional-whitespace> 'decl-fn'
+                            <whitespace> ID <optional-whitespace>
+                             <left-paren> ARGS-LIST <right-paren>
+                            <optional-whitespace>
+                            <left-curly>  FN-DECL-BODY <right-curly>
+          ARGS-LIST = <optional-whitespace> ID
+                               (<optional-whitespace> <PARAMS-SEP>
+                                <optional-whitespace> ID)*
+          FN-DECL-BODY = (FN-CALL <FN-SEP>)*
+          left-paren = '('
+          right-paren = ')'
+          left-curly = '{'
+          right-curly = '}'
+          ID = #'[a-zA-Z0-9]+'
+          whitespace = #'\\s+'
+          optional-whitespace = #'\\s*'
+          FN-SEP = <optional-whitespace> ';' <optional-whitespace>
+          PARAMS-SEP = <optional-whitespace> ',' <optional-whitespace>")
+
+(defn gen-program
+  [parser program]
+  (into [] (insta/transform
+            {:S (fn [ & args] args)
+             :FN-CALL (fn [fn-id params] [:FN-CALL
+                                          (fn-id 1)
+                                          params])
+             :PARAMS-LIST (fn[& params] (into [] params) )
+             :FN-DECL (fn [_ decl-fn-id  args body] [:FN-DECL
+                                                     (decl-fn-id 1)
+                                                     args body])
+             :ARGS-LIST (fn [& args] (into [] args))
+             :FN-DECL-BODY (fn [& body] (into [] body))}
+            (parser program))))
+
+(defn get-fn-decls
+  [program]
+  (->> program
+       (filter #(= :FN-DECL (get % 0)))
+       (into [])))
+
+(defn get-instructions
+  [program]
+  (->> program
+       (filter #(not= :FN-DECL (get % 0)))
+       (into [])))
+
+(defn get-fn-id-decl
+  [fn-decls fn-id]
+  (->> fn-decls
+       (filter #(= (get % 1)
+                   fn-id))
+       (first)))
+
+
+(defn call-fn
+  [fn-decl fn-call]
+  (let [decl-args-list (fn-decl 2)
+        decl-body (fn-decl 3)
+        fn-call-params (fn-call 2)]
+    (if (not (= (count decl-args-list) (count fn-call-params)))
+      [:arity-error-in-calling (fn-decl 1 )]
+      (let [replacement-map (zipmap decl-args-list fn-call-params)]
+        (walk/postwalk-replace replacement-map decl-body)))))
+
+(defn expand-to-primitive-calls [program]
+  (let  [fn-decls (get-fn-decls program)
+         instructions (get-instructions program)
+         zpr (z/vector-zip instructions)]
+    (loop [result instructions
+           loc (-> zpr z/down)]
+      (if (-> loc z/end?)
+        result
+        (let [current-node (-> loc z/node)]
+          (if (= (get current-node 0 :FN-CALL))
+            (if-let [the-decl (get-fn-id-decl fn-decls (get current-node 1))]
+              (recur (walk/postwalk-replace {(-> loc z/node)
+                                             (call-fn the-decl
+                                                      current-node)}
+                                            result )
+                     (->  loc z/next))
+              (recur result (-> loc z/next)))
+            (recur result (-> loc z/next))))))))
+
+(defn a-call-stack [a-call]
+  (let [zpr (z/vector-zip a-call)]
+           (loop [result []
+                  loc (-> zpr z/down)]
+             (if (-> loc z/end?)
+               result
+               (let [current-node (-> loc z/node)]
+                 (recur (if (and
+                             (not (vector? current-node))
+                             (not= :FN-CALL current-node)
+                             (not= :ID current-node))
+                          (conj result {(-> loc z/left z/node) current-node})
+       result)
+                        (-> loc z/next)))))))
+
+(defn program-call-stack
+  [prog]
+  (into []
+        (map a-call-stack
+             (expand-to-primitive-calls prog))))
+


add limit of 100 to payments query to fetch all

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


removes duplicate code

removes duplicate code

a bunch of code related to service editing was being redefined by duplicate code
that somehow crept in. strange


feat(run-query): accept any method on handlers [#136] (#137)

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


pepa.log/CTLLogger: Log unqualified component name

--- src/pepa/log.clj
+++ src/pepa/log.clj
@@ -75,13 +75,16 @@

 ;;; Extend Logger

+(defn ^:private component-name [c]
+  (.getSimpleName (class c)))
+
 (extend-type CTLLogger
   ILogger
   (-log
     ([logger component level throwable message]
-     (clojure.tools.logging/log (.getName (type component)) level throwable message))
+     (clojure.tools.logging/log (component-name component) level throwable message))
     ([logger component level message]
-     (clojure.tools.logging/log (.getName (type component)) level nil message))))
+     (clojure.tools.logging/log (component-name component) level nil message))))

 (extend-type DummyLogger
   ILogger


Add tools.cli as a dependency

Add tools.cli as a dependency

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


:arrow_up: Upgrade dependencies

:arrow_up: Upgrade dependencies

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/maoo/bot-unfurl.git/'