Revert "done-working needs an empty arg"

This reverts commit 8c6fc304775b118e884aec7ee7a509faba8651b6.

--- src/lt/objs/langs/clj.cljs
+++ src/lt/objs/langs/clj.cljs
@@ -237,12 +237,12 @@
                   :triggers #{:editor.eval.cljs.no-op
                               :editor.eval.clj.no-op}
                   :reaction (fn [this]
-                              (notifos/done-working "")))
+                              (notifos/done-working)))

 (object/behavior* ::cljs-result
                   :triggers #{:editor.eval.cljs.result}
                   :reaction (fn [obj res]
-                              (notifos/done-working "")
+                              (notifos/done-working)
                               (let [type (or (-> res :meta :result-type) :inline)
                                     ev (->dottedkw :editor.eval.cljs.result type)]
                                 (object/raise obj ev res))))
@@ -275,7 +275,7 @@
 (object/behavior* ::clj-result
                   :triggers #{:editor.eval.clj.result}
                   :reaction (fn [obj res]
-                              (notifos/done-working "")
+                              (notifos/done-working)
                               (let [type (or (-> res :meta :result-type) :inline)
                                     ev (->dottedkw :editor.eval.clj.result type)]
                                 (object/raise obj ev res))))
@@ -367,7 +367,7 @@
 (object/behavior* ::handle-cancellation
                   :triggers #{:editor.eval.clj.cancel}
                   :reaction (fn [this]
-                              (notifos/done-working "")
+                              (notifos/done-working)
                               (notifos/set-msg! "Canceled clj eval." {:class "error"})))

 (object/behavior* ::print-length
@@ -762,7 +762,7 @@
                                 (object/update! this [:buffer] str out)
                                 (if (> (.indexOf out "nREPL server started") -1)
                                   (do
-                                    (notifos/done-working "")
+                                    (notifos/done-working)
                                     (object/merge! this {:connected true})
                                     (let [client (clients/by-id (:cid @this))]
                                       (object/merge! client {:port (-> (re-seq #"port ([\d]+)" out) first second)})
@@ -789,8 +789,8 @@
                   :reaction (fn [this data]
                               ;(object/update! this [:buffer] str data)
                               (when-not (:connected @this)
-                                (notifos/done-working "")
-                                (notifos/done-working "")
+                                (notifos/done-working)
+                                (notifos/done-working)
                                 (popup/popup! {:header "We couldn't connect."
                                                :body [:span "Looks like there was an issue trying to connect
                                                       to the project. Here's what we got:" [:pre (:buffer @this)]]


Add create migration operation to migrator

--- src/madouc/db/migrator.clj
+++ src/madouc/db/migrator.clj
@@ -28,3 +28,8 @@
 (defn debug-config
   []
   (config->migratus-params env))
+
+(defn create!
+  [migration-name]
+  (migratus/create (config->migratus-params env) migration-name))
+


Cleaned up code / added more documentation

--- src/mail_sieve_e/sieve.clj
+++ src/mail_sieve_e/sieve.clj
@@ -4,13 +4,11 @@
             [clojure.string :refer [join]])
   (:import [java.io FileWriter]))

-
-;; TODO: Fix follower sieve-e
-(def chunk-size (atom 0))
-
-(def comp-num (atom 0))
+;; Main logic for the sieve

 (defn gen-table
+  "Given: [lower upper] - lower bound int and upper bound int
+  produces a transient vector between those ranges skip counting by 2"
   [[lower upper]]
   (transient (vec (range lower upper 2))))

@@ -83,6 +81,9 @@
         (recur (inc stop))))))

 (defn finish
+  "Takes raw-chunk - transient vector of primes to process
+         my-num    - this machines number
+  and writes the contents to a file"
   [raw-chunk my-num]
   (println "Writing primes to file...")
   (when (= 1 my-num)
@@ -108,6 +109,7 @@
     (println "")))

 (defn find-first-prime
+  "Find first non-zero number in a chunk"
   [coll cs]
   (if-not (zero? (get coll 0))
     0
@@ -168,22 +170,3 @@
                   (println "Appointed as new lead.\n")
                   (sieve-e my-num true (chan 100) chunk out-channel))
                 (recur)))))))))
-
-(defn dis-sieve-e
-  [num-machines n]
-  (let [debug (vec (repeat num-machines (chan 100000000)))]
-    (loop [i 1
-           chunks (mapv gen-table (spread-work n num-machines))
-           mach-chans (repeat num-machines (chan (* num-machines n 2)))]
-      (when-not (= i (inc num-machines))
-        (if (= i 1)
-          (do
-            (println "starting lead machine...")
-                                        ;Make a lead machine
-            (sieve-e 1 true (chan 10) (first chunks) mach-chans (first debug))
-            (recur (inc i) (rest chunks) mach-chans))
-          (do
-            (println "starting following machine" i "...")
-            (sieve-e i false (first mach-chans) (first chunks) (rest mach-chans) (get debug (dec i)))
-            (recur (inc i) (rest chunks) (rest mach-chans))))))
-    debug))


add datom-added to pprint view

add datom-added to pprint view

--- src/datascript/db.cljc
+++ src/datascript/db.cljc
@@ -736,7 +736,10 @@
          (pp/write-out (.-v d))
          (.write ^java.io.Writer *out* " ")
          (pp/pprint-newline :linear)
-         (pp/write-out (datom-tx d))))
+         (pp/write-out (datom-tx d))
+         (.write ^java.io.Writer *out* " ")
+         (pp/pprint-newline :linear)
+         (pp/write-out (datom-added d))))

      (defn- pp-db [db ^java.io.Writer w]
        (pp/pprint-logical-block :prefix "#datascript/DB {" :suffix "}"


Refactor.

Refactor.

--- src/datascript/js.cljs
+++ src/datascript/js.cljs
@@ -47,11 +47,10 @@

 (defn ^:export q [query callback & sources]
   (let [query   (cljs.reader/read-string query)
-        results (apply d/q query (fn [results]
-                                    (->> (for [tuple results]
+        results (apply d/q query #(->> (for [tuple %1]
                                           (into-array tuple))
-                                        (into-array)
-                                        (callback))) sources)]))
+                                      (into-array)
+                                      (callback)) sources)]))

 (defn ^:export db_with [db entities]
   (d/db-with db (entities->clj entities)))


Deletes comment

Deletes comment

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -1108,25 +1108,3 @@
   "Given a sequence of results from `clojure.spec.test.alpha/check`, returns a string summarizing the results."
   [check-results]
   (with-out-str (explain-results check-results)))
-
-(comment
-  (defmulti pet :pet/type)
-  (defmethod pet :dog [_]
-    (s/keys))
-  (defmethod pet :cat [_]
-    (s/keys))
-
-  (defmulti animal :animal/type)
-  (defmethod animal :dog [_]
-    (s/keys))
-  (defmethod animal :cat [_]
-    (s/keys))
-
-  (s/def :multispec-in-compound-spec/pet1 (s/and
-                                           map?
-                                           (s/multi-spec pet :pet/type)))
-
-  (s/def :multispec-in-compound-spec/pet2 (s/or
-                                           :map1 (s/multi-spec pet :pet/type)
-                                           :map2 (s/multi-spec animal :animal/type)))
-  (expound :multispec-in-compound-spec/pet2 {:pet/type :fish}))


Removes unused code

Removes unused code

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -65,21 +65,9 @@
        (= partial-path
           (subvec full-path 0 (count partial-path)))))

-(defrecord KeyPathSegment [key]
-  ;; TODO - remove
-  ;; IComparable
-  ;; (-compare [this that]
-  ;;   (compare (:key this) (:key that)))
-
-  )
-
-(defrecord KeyValuePathSegment [idx]
-  ;; TODO - remove
-  ;; IComparable
-  ;; (-compare [this that]
-  ;;   (compare (:idx this) (:idx that)))
-
-  )
+(defrecord KeyPathSegment [key])
+
+(defrecord KeyValuePathSegment [idx])

 (defn kps? [x]
   (instance? KeyPathSegment x))


Renames functions

Renames functions

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -506,24 +506,22 @@
     :else
     :expound.problem/unknown))

-;;; TODO clean up
-(defn ^:private lcs [[x & xs] [y & ys]]
+(defn ^:private lcs* [[x & xs] [y & ys]]
   (cond
     (or (= x nil) (= y nil)) nil
-    (= x y) (vec (cons x (lcs xs ys)))
+    (= x y) (vec (cons x (lcs* xs ys)))
     :else []))

-;; TODO - rename
-(defn ^:private lcs1 [& paths]
+(defn ^:private lcs [& paths]
   (reduce
    (fn [xs ys]
-     (lcs xs ys))
+     (lcs* xs ys))
    paths))

 (defn ^:private alternation [grp1 grp2]
   (let [xs (:path-prefix grp1)
         ys (:path-prefix grp2)
-        prefix (lcs1 xs ys)]
+        prefix (lcs xs ys)]
     (if (and
          (not (empty? prefix))
          (some? prefix)
@@ -538,8 +536,8 @@

 (defn ^:private problem-group [grp1 grp2]
   {:expound.spec.problem/type :expound.problem-group/many-values
-   :path-prefix               (lcs1 (:path-prefix grp1)
-                                    (:path-prefix grp2))
+   :path-prefix               (lcs (:path-prefix grp1)
+                                   (:path-prefix grp2))
    :problems                  (into
                                (if (= :expound.problem-group/many-values (:expound.spec.problem/type grp1))
                                  (:problems grp1)
@@ -574,7 +572,7 @@
                                           :path-prefix               (:expound/path (first grp))
                                           :problems                  grp}
                                          {:expound.spec.problem/type :expound.problem-group/one-value
-                                          :path-prefix               (apply lcs1 (map :expound/path grp))
+                                          :path-prefix               (apply lcs (map :expound/path grp))
                                           :problems                  grp}))))]
     (->> grouped-by-in-path
          (reduce


Fix Error Handling in get-movie-by-id

Fix Error Handling in get-movie-by-id

Changes error handling for ObjectId in movie API
To return 404 when id is malformed. Commit also
refactors assoc-stars-reviews. Closes #5

--- src/movie_app/response.clj
+++ src/movie_app/response.clj
@@ -16,17 +16,17 @@
    :body (cheshire/generate-string
           to-render {:key-fn #(util/memoized->camelCase (name %))})})

-(defn json-404 []
+(defn json-404 [e]
   {:status 404
    :headers {"Content-Type" "text/json; charset=utf-8"
              "Cache-Control" "no-cache, no-store, must-revalidate"
              "Pragma" "no-cache"
              "Expires" "0"}
-   :body (cheshire/generate-string "Page not found")})
+   :body (cheshire/generate-string e)})

 (defn result-nil? [result]
   (if (nil? result)
-    (json-404)
+    (json-404 "404 - Page not found")
     (json-200 result)))

 (defn gen-stars-per-movie [movie-id]
@@ -47,15 +47,12 @@

 (defn assoc-stars-reviews [movie movie-id]
   (let [id (convert-to-object-id movie-id)]
-    (assoc (db/get-by-id "movies" (convert-to-object-id movie-id))
-           :stars (format "%.1f" (gen-stars-per-movie (convert-to-object-id movie-id)))
-           :reviews (get-movie-reviews (convert-to-object-id movie-id)))))
+    (assoc (db/get-by-id "movies" id)
+           :stars (format "%.1f" (gen-stars-per-movie id))
+           :reviews (get-movie-reviews id))))

 (defn get-movie-by-id [id]
-  (try
-    (assoc-stars-reviews (db/get-by-id "movies" (convert-to-object-id id)) id)
-    (catch IllegalArgumentException e
-      (str "Caught exception: " (.getMessage e)))))
+  (assoc-stars-reviews (db/get-by-id "movies" (convert-to-object-id id)) id))

 (defn get-rated-movies []
   (for [movie (db/get-maps "movies")]
@@ -68,5 +65,8 @@
     (result-nil? result)))

 (defn get-movie-entry [id-string]
-  (let [result (get-movie-by-id id-string)]
-    (result-nil? result)))
+  (try
+    (let [result (get-movie-by-id id-string)]
+      (result-nil? result))
+    (catch IllegalArgumentException e
+      (json-404 (.toString e)))))


stores files as binary

stores files as binary

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -8,7 +8,8 @@
 (defonce app-state (atom {:users []
                           :messages []
                           :upload-progress nil
-                          :data-uploaded 0}))
+                          :data-uploaded 0
+                          :current-file-download ""}))

 (enable-console-print!)

@@ -83,9 +84,11 @@

 (.on (new js/ss socket) "file-to-client"
   (fn [stream]
-    (println "WOO")
-    (.on stream "data" #(println "H"))
-    (.on stream "end" #(println "DONE!"))))
+    (.on stream "data"
+      (fn [chunk]
+        (println "H")
+        (swap! app-state assoc :current-file-download (+ chunk (:current-file-download @app-state)))))
+    (.on stream "end" #(println (:current-file-download @app-state)))))

 (.change (js/$ "#file_upload_input")
   (fn [e]


Proof of concept asynchronous app.

Proof of concept asynchronous app.

--- src/helloworld/web.clj
+++ src/helloworld/web.clj
@@ -1,12 +1,43 @@
 (ns helloworld.web
-  (:use [compojure.core :only [defroutes GET]])
-  (:require [aleph http]))
+  (:use [compojure.core :only [defroutes GET PUT]])
+  (:require [aleph http]
+            [lamina core]))
+
+(defn modref [f sym]
+    (dosync (ref-set sym (f (deref sym)))))
+
+(defn appendref [sym value] (modref #(conj % value) sym))
+
+(defn getset [sym value]
+    (dosync (let [old (deref sym)] (do (ref-set sym value) old))))
+
+; FIXME: atomicity of answering these
+
+(def waiting-channels (ref []))
+
+(defn waitfor-handler [channel request] (do
+    (prn (deref waiting-channels))
+    (prn "Waiting for: " channel)
+    (appendref waiting-channels channel)
+    (prn (deref waiting-channels))))
+
+(defn freeall []
+    (doseq [c (getset waiting-channels [])]
+        (prn "Freeing: " c)
+        (lamina.core/enqueue c {:status 200 :body "I am free"})))

 (defroutes app
   (GET "/" []
        {:status 200
         :headers {"Content-Type" "text/plain"}
-        :body "Hello from Heroku"}))
+        :body "Hello from Heroku"})
+   (GET "/waitfor" [] (aleph.http/wrap-aleph-handler waitfor-handler))
+   (GET "/freeall" [] (do
+        (prn (deref waiting-channels))
+        (prn "Freeing channels")
+        (freeall)
+        (prn (deref waiting-channels))
+        "They are free")))

 (defn -main [port]
   (aleph.http/start-http-server


Add log-exceptions wrapper to watch.

Add log-exceptions wrapper to watch.

--- src/incise/watcher.clj
+++ src/incise/watcher.clj
@@ -1,12 +1,20 @@
 (ns incise.watcher
   (:require [watchtower.core :refer [watcher rate file-filter extensions
                                      on-change]]))
+
+(defn log-exceptions [func & args]
+  "Log (i.e. print) exceptions received from the given function."
+  (try
+    (apply func args)
+    (catch Exception e
+      (println (.getMessage e)))))
+

 (defn watch
   [change-fn]
   (watcher ["resources/posts/" "resources/pages/"]
            (rate 300)
-           (on-change change-fn)))
+           (on-change (partial log-exceptions change-fn))))

 (def watching nil)


optimal-lookback

optimal-lookback

--- src/paulkrake/crossval.clj
+++ src/paulkrake/crossval.clj
@@ -75,6 +75,13 @@
       (sort-by first x1))))

+(defn optimal-lookback [s t n metric-fn]
+  (as->  (dc/range-spieltage s t n) x
+        (map (fn [[s t]] (lookback s t metric-fn)) x)
+        (map (fn [lb] (into {} lb)) x)
+        (apply merge-with + x)
+        (sort-by second x)
+        #_(reverse x)
+        (first x)))

-


Rename exit-with-error to abort.

Rename exit-with-error to abort.

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -34,7 +34,7 @@
 ;; So it doesn't need to be fully-qualified in project.clj
 (with-ns 'clojure.core (use ['leiningen.core :only ['defproject]]))

-(defn exit-with-error [msg]
+(defn abort [msg]
   (println msg)
   (System/exit 1))

@@ -45,7 +45,7 @@
       (load-file file)
       project
       (catch java.io.FileNotFoundException _
-        (exit-with-error "No project.clj found in this directory."))))
+        (abort "No project.clj found in this directory."))))
   ([] (read-project "project.clj")))

 (def aliases {"--help" "help" "-h" "help" "-?" "help"
@@ -57,8 +57,8 @@
   (let [task-ns (symbol (str "leiningen." task))
         task (symbol task)
         error-fn (fn [& _]
-                   (exit-with-error
-                     (format "%s is not a task. Use \"help\" to list all tasks."
+                   (abort
+                    (format "%s is not a task. Use \"help\" to list all tasks."
                              task)))]
     (try
      (require task-ns)
@@ -78,7 +78,7 @@
       (try
        (apply (resolve-task task) args)
        (catch IllegalArgumentException _
-         (exit-with-error (format "Wrong number of arguments to task %s."
-                                  task)))))
+         (abort (format "Wrong number of arguments to task %s."
+                        task)))))
     ;; In case tests or some other task started any:
     (shutdown-agents)))


Rebind clojure.test/*test-out* in test runs.

--- src/leiningen/test.clj
+++ src/leiningen/test.clj
@@ -24,15 +24,15 @@
         (doseq [n# '~namespaces]
           (require n#))
         ~(form-for-hook-selectors selectors)
-        (let [summary# (apply ~'clojure.test/run-tests '~namespaces)]
+        (let [summary# (binding [clojure.test/*test-out* *out*]
+                         (apply ~'clojure.test/run-tests '~namespaces))]
           (when-not (= "1.5" (System/getProperty "java.specification.version"))
             (shutdown-agents))
           ;; Stupid ant won't let us return anything, so write results to disk
           (with-open [w# (-> (java.io.File. ~result-file)
                              (java.io.FileOutputStream.)
                              (java.io.OutputStreamWriter.))]
-            (.write w# (pr-str summary#))))
-        (System/exit 0))))
+            (.write w# (pr-str summary#)))))))

 (defn- read-args [args project]
   (let [args (map read-string args)


Include &who condition in conditions converted from Java Throwables.

--- src/active/clojure/condition.cljc
+++ src/active/clojure/condition.cljc
@@ -115,7 +115,7 @@
   {:pre [(condition? cond)]}
   (::components (ex-data cond)))

-(declare make-throwable make-error make-assertion-violation make-message-condition)
+(declare make-throwable make-error make-assertion-violation make-message-condition make-who-condition)

 (defn make-condition
   "Make a condition from components.
@@ -128,6 +128,20 @@
             ::components condition-components}))

 #?(:clj
+(defn stack-trace-who
+  "Get a suitable argument for [[&who]] from an exception object."
+  [st]
+  ;; the top is the let, above that it's stack-trace-who itself
+  (if-let [^StackTraceElement e (nth st 2)]
+    (let [class (.getClassName e)
+          method (.getMethodName e)]
+      ;; adapted from clojure.stacktrace
+      (let [match (re-matches #"^([A-Za-z0-9_.-]+)\$(\w+)$" (str class))]
+        (if (and match (= "invoke" method))
+          (apply format "%s/%s" (rest match))
+          (format "%s.%s" class method)))))))
+
+#?(:clj
 (defn ->condition
   "Coerce something into a condition object.

@@ -138,14 +152,16 @@
    (condition? thing) thing

    (instance? Throwable thing)
-   (make-condition (mapcat condition-components
-                           (filter identity
-                                   [(make-throwable thing)
-                                    (make-message-condition (.getMessage ^Throwable thing))
-                                    (cond
-                                     (instance? Exception thing) (make-error)
-                                     (instance? Error thing) (make-assertion-violation)
-                                     :else nil)])))
+   (let [^Throwable throwable thing]
+     (make-condition (mapcat condition-components
+                             (filter identity
+                                     [(make-throwable throwable)
+                                      (make-message-condition (.getMessage throwable))
+                                      (cond
+                                       (instance? Exception throwable) (make-error)
+                                       (instance? Error throwable) (make-assertion-violation)
+                                       :else nil)
+                                      (make-who-condition (stack-trace-who (.getStackTrace throwable)))]))))

    :else (clojure.core/assert (instance? Throwable thing) "not a throwable"))))

@@ -328,35 +344,19 @@
                                (make-irritants-condition irritants)))))

 #?(:clj
-(defn stack-trace-who
-  "Get a suitable argument for [[&who]] from an exception object."
-  []
-  (let [^Thread thr (Thread/currentThread)
-        st (.getStackTrace thr)]
-    ;; the top is the let, above that it's stack-trace-who itself
-    (if-let [^StackTraceElement e (nth st 2)]
-      (let [class (.getClassName e)
-            method (.getMethodName e)]
-        ;; adapted from clojure.stacktrace
-        (let [match (re-matches #"^([A-Za-z0-9_.-]+)\$(\w+)$" (str class))]
-          (if (and match (= "invoke" method))
-            (apply format "%s/%s" (rest match))
-            (format "%s.%s" class method))))))))
-
-#?(:clj
 (defmacro assert
   "Evaluates expr and throws an exception if it does not evaluate to
   logical true."
   ([x]
      (when *assert*
        `(when-not ~x
-          (assertion-violation (stack-trace-who)
+          (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
                                (str "Assertion failed")
                                '~x))))
   ([x message]
      (when *assert*
        `(when-not ~x
-          (assertion-violation (stack-trace-who)
+          (assertion-violation (stack-trace-who (.getStackTrace (Thread/currentThread)))
                                (str "Assert failed: " ~message)
                                '~x))))))

@@ -365,7 +365,7 @@
 (defmacro condition
   [?base ?message & ?irritants]
   `(combine-conditions ~?base
-                       (make-who-condition (stack-trace-who))
+                       (make-who-condition (stack-trace-who (.getStackTrace (Thread/currentThread))))
                        (make-message-condition ~?message)
                        (make-irritants-condition [~@?irritants]))))


[#11964] "TypeError: Network request failed" when switching to Goerli network

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/utils/config.cljs
+++ src/status_im/utils/config.cljs
@@ -143,7 +143,7 @@
     :config         {:NetworkId      (ethereum/chain-keyword->chain-id :goerli)
                      :DataDir        "/ethereum/goerli_rpc"
                      :UpstreamConfig {:Enabled true
-                                      :URL     "https://goerli.blockscout.com/"}}}])
+                                      :URL     (str "https://goerli.infura.io/v3/" INFURA_TOKEN)}}}])

 (def default-networks
   (concat testnet-networks mainnet-networks sidechain-networks))


avoid stack overflow in (defn exception-generator): use (mapcat) rather than recursively calling (exception-generator)

--- src/babel/espanol/morphology.cljc
+++ src/babel/espanol/morphology.cljc
@@ -599,105 +599,105 @@
        (lookup-fn surface-form)))))

 (defn exception-generator [lexicon]
-  (let [lexeme-kv (first lexicon)
-        lexemes (second lexeme-kv)]
-    (if lexeme-kv
-      (let [result (mapcat (fn [path-and-merge-fn]
-                             (let [path (:path path-and-merge-fn)
-                                   merge-fn (:merge-fn path-and-merge-fn)]
-                               ;; a lexeme-kv is a pair of a key and value. The key is a string (the word's surface form)
-                               ;; and the value is a list of lexemes for that string.
-                               (log/trace (str (first lexeme-kv) ": looking at path: " path))
-                               (mapcat (fn [lexeme]
-                                         ;; this is where a unify/dissoc that supported
-                                         ;; non-maps like :top and :fail, would be useful:
-                                         ;; would not need the (if (not (fail? lexeme)..)) check
-                                         ;; to avoid a difficult-to-understand "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap" error.
-                                         (let [lexeme (cond (= lexeme :fail)
-                                                            :fail
-                                                            (= lexeme :top)
-                                                            :top
-                                                            true
-                                                            (copy lexeme))]
-                                           (if (not (= :none (get-in lexeme path :none)))
-                                             (list {(get-in lexeme path :none)
-                                                    (merge
-                                                     lexeme
-                                                     (unifyc (apply merge-fn (list lexeme))
-                                                             {:espanol {:exception true}}))}))))
-                                       lexemes)))
-                           [
-                            ;; 1. past-tense exceptions
-                            {:path [:espanol :passato]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :past
-                                           :espanol (get-in val [:espanol :passato] :nothing)}})}
-
-                            ;; 2. present-tense exceptions
-                            {:path [:espanol :present :1sing]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :1sing] :nothing)
-                                           :agr {:number :sing
-                                                 :person :1st}}})}
-                            {:path [:espanol :present :2sing]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :2sing] :nothing)
-                                           :agr {:number :sing
-                                                 :person :2nd}}})}
-
-                            {:path [:espanol :present :3sing]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :3sing] :nothing)
-                                           :agr {:number :sing
-                                                 :person :3rd}}})}
-
-                            {:path [:espanol :present :1plur]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :1plur] :nothing)
-                                           :agr {:number :plur
-                                                 :person :1st}}})}
-
-                            {:path [:espanol :present :2plur]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :2plur] :nothing)
-                                           :agr {:number :plur
-                                                 :person :2nd}}})}
-
-                            {:path [:espanol :present :3plur]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:infl :present
-                                           :espanol (get-in val [:espanol :present :3plur] :nothing)
-                                           :agr {:number :plur
-                                                 :person :3rd}}})}
-
-                            ;; adjectives
-                            {:path [:espanol :masc :plur]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:agr {:gender :masc
-                                                 :number :plur}}})}
-
-                            {:path [:espanol :fem :plur]
-                             :merge-fn
-                             (fn [val]
-                               {:espanol {:agr {:gender :fem
-                                                 :number :plur}}})}
-                            ])]
-        (if (not (empty? result))
-          (concat result (exception-generator (rest lexicon)))
-          (exception-generator (rest lexicon)))))))
+  (mapcat
+   (fn [lexeme-kv]
+     (let [lexemes (second lexeme-kv)]
+       (if lexeme-kv
+         (let [result (mapcat (fn [path-and-merge-fn]
+                                (let [path (:path path-and-merge-fn)
+                                      merge-fn (:merge-fn path-and-merge-fn)]
+                                  ;; a lexeme-kv is a pair of a key and value. The key is a string (the word's surface form)
+                                  ;; and the value is a list of lexemes for that string.
+                                  (log/trace (str (first lexeme-kv) ": looking at path: " path))
+                                  (mapcat (fn [lexeme]
+                                            ;; this is where a unify/dissoc that supported
+                                            ;; non-maps like :top and :fail, would be useful:
+                                            ;; would not need the (if (not (fail? lexeme)..)) check
+                                            ;; to avoid a difficult-to-understand "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap" error.
+                                            (let [lexeme (cond (= lexeme :fail)
+                                                               :fail
+                                                               (= lexeme :top)
+                                                               :top
+                                                               true
+                                                               (copy lexeme))]
+                                              (if (not (= :none (get-in lexeme path :none)))
+                                                (list {(get-in lexeme path :none)
+                                                       (merge
+                                                        lexeme
+                                                        (unifyc (apply merge-fn (list lexeme))
+                                                                {:espanol {:exception true}}))}))))
+                                          lexemes)))
+                              [
+                               ;; 1. past-tense exceptions
+                               {:path [:espanol :passato]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :past
+                                             :espanol (get-in val [:espanol :passato] :nothing)}})}
+
+                               ;; 2. present-tense exceptions
+                               {:path [:espanol :present :1sing]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :1sing] :nothing)
+                                             :agr {:number :sing
+                                                   :person :1st}}})}
+                               {:path [:espanol :present :2sing]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :2sing] :nothing)
+                                             :agr {:number :sing
+                                                   :person :2nd}}})}
+
+                               {:path [:espanol :present :3sing]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :3sing] :nothing)
+                                             :agr {:number :sing
+                                                   :person :3rd}}})}
+
+                               {:path [:espanol :present :1plur]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :1plur] :nothing)
+                                             :agr {:number :plur
+                                                   :person :1st}}})}
+
+                               {:path [:espanol :present :2plur]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :2plur] :nothing)
+                                             :agr {:number :plur
+                                                   :person :2nd}}})}
+
+                               {:path [:espanol :present :3plur]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:infl :present
+                                             :espanol (get-in val [:espanol :present :3plur] :nothing)
+                                             :agr {:number :plur
+                                                   :person :3rd}}})}
+
+                               ;; adjectives
+                               {:path [:espanol :masc :plur]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:agr {:gender :masc
+                                                   :number :plur}}})}
+
+                               {:path [:espanol :fem :plur]
+                                :merge-fn
+                                (fn [val]
+                                  {:espanol {:agr {:gender :fem
+                                                   :number :plur}}})}
+                               ])]
+           result))))
+   lexicon))

 (defn phonize [a-map a-string]
   (let [common {:phrasal false}]


Change to use account wide access policy to ES

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -66,19 +66,18 @@
                           nginx])))

 (defn elasticsearch-policy
-  []
-  (json/generate-string {"Version" "2012-10-17",
-                         "Statement" [{"Action" "es:*",
-                                       "Principal" "*",
-                                       "Resource" "$${es-arn}",
-                                       ;; There is currently a bug which means 'Resource' needs adding after the
-                                       ;; cluster is created or it will constantly say it needs to change.
-                                       ;; https://github.com/hashicorp/terraform/issues/5067
-                                       "Effect" "Allow",
-                                       "Condition"
-                                       {
-                                        "IpAddress"
-                                        {"aws:SourceIp" ["$${allowed-ips}"]}}}]}))
+  [iam-root es-arn-*]
+  (json/generate-string
+   {
+    "Statement" [
+                 {
+                  "Action" "es:*"
+                  "Effect" "Allow"
+                  "Principal" {
+                                 "AWS" iam-root
+                                 }
+                   "Resource" es-arn-*}]
+    "Version" "2012-10-17"}))

 (defn elasticsearch-cluster [name {:keys [es-endpoint vpc-name account-number region azs default-ami mesos-ami vpc-cidr-block cert-name key-name] :as spec}]
   ;; http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-ebs
@@ -90,11 +89,12 @@
         vpc-security-group (partial scoped-security-group vpc-unique)
         elb-listener (account-elb-listener account-number)
         es-arn (str "arn:aws:es:" region ":" account-number ":domain/" name)
+        iam-root (str "arn:aws:iam::" account-number ":root")
         es-arn-* (str es-arn "/*")]

     (merge-in
      (template-file (vpc-unique "elasticsearch-policy")
-                    (elasticsearch-policy)
+                    (elasticsearch-policy iam-root es-arn-*)
                     {:es-arn es-arn-*
                      :allowed-ips  (vpc-output-of "aws_eip" "logstash" "public_ip")})


messing with devcards macro

messing with devcards macro

--- src/untangled/client/cards.cljc
+++ src/untangled/client/cards.cljc
@@ -1,15 +1,10 @@
 (ns untangled.client.cards
   #?(:cljs (:require
-             [untangled.client.core :as uc]
-             [untangled.dom :as udom]
              [devcards.core :as dc])))

 (defmacro untangled-app [root-ui & args]
-  (let [varname (gensym)]
-    `(dc/dom-node
-       (fn [state-atom# node#]
-         (defonce ~varname (atom (uc/new-untangled-client :initial-state state-atom# ~@args)))
-         (reset! ~varname (uc/mount @~varname ~root-ui node#))
-         ; ensures shows app state immediately if you're using inspect data and InitialAppState:
-         (js/setTimeout (fn [] (swap! state-atom# assoc :ui/react-key (udom/unique-key))) 200)
-         node#))))
+  `(dc/dom-node
+     (fn [state-atom# node#]
+       (untangled.client.core/mount (untangled.client.core/new-untangled-client :initial-state state-atom# ~@args) ~root-ui node#)
+       ; ensures shows app state immediately if you're using inspect data and InitialAppState:
+       (js/setTimeout (fn [] (swap! state-atom# assoc :ui/react-key (untangled.dom/unique-key))) 200))))


+(defn filter-map-by),(defn only-nonempty-vals)

--- src/babel/lexiconfn.cljc
+++ src/babel/lexiconfn.cljc
@@ -135,6 +135,23 @@
         (for [[k v] m]
           ;; for each <k,v> pair, return a <k,v'>, where v' = f(v).
           [k (f k v)])))
+
+(defn filter-map-by
+  "return a map where only elements for which (f k v)=true."
+  [m f]
+  (into {}
+        (for [[k v] m]
+          (if (= true (f k v))
+            [k v]))))
+
+(defn only-nonempty-vals
+  "return a map where only elements for which (not (empty? (f v))) is true."
+  [m f]
+  (into {}
+        (for [[k v] m]
+          (let [result (f v)]
+            (if (not (empty? result))
+              [k result])))))

 (defn check-lexicon [lexicon]
   (let [check-one (fn [k v]


Show message directly, force flush

Show message directly, force flush

--- src/buildviz/go/sync.clj
+++ src/buildviz/go/sync.clj
@@ -177,6 +177,7 @@
   (println "Go" go-url (distinct (map :group pipeline-stages)) "-> buildviz" buildviz-url)
   (print (format "Finding all pipeline runs for syncing (starting from %s)..."
                  (tf/unparse (:date-time tf/formatters) sync-start-time)))
+  (flush)

   pipeline-stages)


factor out common user-id check in sync methods

--- src/chat/server/sync.clj
+++ src/chat/server/sync.clj
@@ -41,7 +41,8 @@
 (defn event-msg-handler* [{:as ev-msg :keys [id ?data event]}]
   (when-not (= event [:chsk/ws-ping])
     (debugf "User: %s Event: %s" (get-in ev-msg [:ring-req :session :user-id]) event))
-  (event-msg-handler ev-msg))
+  (when-let [user-id (get-in ev-msg [:ring-req :session :user-id])]
+    (event-msg-handler (assoc ev-msg :user-id user-id))))

 (defstate router
   :start (sente/start-chsk-router! ch-chsk event-msg-handler*)
@@ -174,285 +175,259 @@
   )

 (defmethod event-msg-handler :chsk/uidport-open
-  [{:as ev-msg :keys [event id ring-req]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (broadcast-user-change user-id [:user/connected user-id])))
+  [{:as ev-msg :keys [event id ring-req user-id]}]
+  (broadcast-user-change user-id [:user/connected user-id]))

 (defmethod event-msg-handler :chsk/uidport-close
-  [{:as ev-msg :keys [event id ring-req]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (broadcast-user-change user-id [:user/disconnected user-id])))
+  [{:as ev-msg :keys [event id user-id]}]
+  (broadcast-user-change user-id [:user/disconnected user-id]))

 (defmethod event-msg-handler :chat/new-message
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [new-message (-> ?data
-                          (update-in [:content] #(apply str (take 5000 %)))
-                          (assoc :created-at (java.util.Date.)))]
-      (if (new-message-valid? new-message)
-        (when (user-can-message? user-id new-message)
-          (db/create-message! new-message)
-          (when-let [cb ?reply-fn]
-            (cb :braid/ok))
-          (broadcast-thread (new-message :thread-id) [])
-          (notify-users new-message))
-        (do
-          (timbre/warnf "Malformed new message: %s" (pr-str new-message))
-          (when-let [cb ?reply-fn]
-            (cb :braid/error)))))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [new-message (-> ?data
+                        (update-in [:content] #(apply str (take 5000 %)))
+                        (assoc :created-at (java.util.Date.)))]
+    (if (new-message-valid? new-message)
+      (when (user-can-message? user-id new-message)
+        (db/create-message! new-message)
+        (when-let [cb ?reply-fn]
+          (cb :braid/ok))
+        (broadcast-thread (new-message :thread-id) [])
+        (notify-users new-message))
+      (do
+        (timbre/warnf "Malformed new message: %s" (pr-str new-message))
+        (when-let [cb ?reply-fn]
+          (cb :braid/error))))))

 (defmethod event-msg-handler :user/subscribe-to-tag
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (db/user-subscribe-to-tag! user-id ?data)))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (db/user-subscribe-to-tag! user-id ?data))

 (defmethod event-msg-handler :user/unsubscribe-from-tag
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (db/user-unsubscribe-from-tag! user-id ?data)))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (db/user-unsubscribe-from-tag! user-id ?data))

 (defmethod event-msg-handler :user/set-nickname
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if (valid-nickname? (?data :nickname))
-      (try
-        (do (db/set-nickname! user-id (?data :nickname))
-            (broadcast-user-change user-id [:user/name-change
-                                            {:user-id user-id
-                                             :nickname (?data :nickname)}])
-            (when ?reply-fn (?reply-fn {:ok true})))
-        (catch java.util.concurrent.ExecutionException _
-          (when ?reply-fn (?reply-fn {:error "Nickname taken"}))))
-      (when ?reply-fn (?reply-fn {:error "Invalid nickname"})))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if (valid-nickname? (?data :nickname))
+    (try
+      (do (db/set-nickname! user-id (?data :nickname))
+          (broadcast-user-change user-id [:user/name-change
+                                          {:user-id user-id
+                                           :nickname (?data :nickname)}])
+          (when ?reply-fn (?reply-fn {:ok true})))
+      (catch java.util.concurrent.ExecutionException _
+        (when ?reply-fn (?reply-fn {:error "Nickname taken"}))))
+    (when ?reply-fn (?reply-fn {:error "Invalid nickname"}))))

 (defmethod event-msg-handler :user/set-password
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if (string/blank? (?data :password))
-      (when ?reply-fn (?reply-fn {:error "Password cannot be blank"}))
-      (do
-        (db/set-user-password! user-id (?data :password))
-        (when ?reply-fn (?reply-fn {:ok true}))))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if (string/blank? (?data :password))
+    (when ?reply-fn (?reply-fn {:error "Password cannot be blank"}))
+    (do
+      (db/set-user-password! user-id (?data :password))
+      (when ?reply-fn (?reply-fn {:ok true})))))

 (defmethod event-msg-handler :user/set-preferences
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (doseq [[k v] ?data]
-      (db/user-set-preference! user-id k v))
-    (when ?reply-fn (?reply-fn :braid/ok))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (doseq [[k v] ?data]
+    (db/user-set-preference! user-id k v))
+  (when ?reply-fn (?reply-fn :braid/ok)))

 (defmethod event-msg-handler :chat/hide-thread
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (db/user-hide-thread! user-id ?data)))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (db/user-hide-thread! user-id ?data))

 (defmethod event-msg-handler :chat/mark-thread-read
-  [{:as ev-msg :keys [ring-req ?data]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (db/update-thread-last-open ?data user-id)))
+  [{:as ev-msg :keys [ring-req ?data user-id]}]
+  (db/update-thread-last-open ?data user-id))

 (defmethod event-msg-handler :chat/create-tag
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if (db/user-in-group? user-id (?data :group-id))
-      (if (valid-tag-name? (?data :name))
-        (let [new-tag (db/create-tag! (select-keys ?data [:id :name :group-id]))
-              connected? (set (:any @connected-uids))]
-          (doseq [u (db/get-users-in-group (:group-id new-tag))]
-            (db/user-subscribe-to-tag! (u :id) (new-tag :id))
-            (when (and (not= user-id (u :id)) (connected? (u :id)))
-              (chsk-send! (u :id) [:chat/create-tag new-tag])))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if (db/user-in-group? user-id (?data :group-id))
+    (if (valid-tag-name? (?data :name))
+      (let [new-tag (db/create-tag! (select-keys ?data [:id :name :group-id]))
+            connected? (set (:any @connected-uids))]
+        (doseq [u (db/get-users-in-group (:group-id new-tag))]
+          (db/user-subscribe-to-tag! (u :id) (new-tag :id))
+          (when (and (not= user-id (u :id)) (connected? (u :id)))
+            (chsk-send! (u :id) [:chat/create-tag new-tag])))
+        (when ?reply-fn
+          (?reply-fn {:ok true})))
+      (do (timbre/warnf "User %s attempted to create a tag %s with an invalid name"
+                        user-id (?data :name))
           (when ?reply-fn
-            (?reply-fn {:ok true})))
-        (do (timbre/warnf "User %s attempted to create a tag %s with an invalid name"
-                          user-id (?data :name))
-            (when ?reply-fn
-              (?reply-fn {:error "invalid tag name"}))))
-      ; TODO: indicate permissions error to user?
-      (timbre/warnf "User %s attempted to create a tag %s in a disallowed group"
-                    user-id (?data :name) (?data :group-id)))))
+            (?reply-fn {:error "invalid tag name"}))))
+    ; TODO: indicate permissions error to user?
+    (timbre/warnf "User %s attempted to create a tag %s in a disallowed group"
+                  user-id (?data :name) (?data :group-id))))

 (defmethod event-msg-handler :chat/set-tag-description
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [{:keys [tag-id description]} ?data]
-      (when (and tag-id description)
-        (let [group-id (db/tag-group-id tag-id)]
-          (when (db/user-is-group-admin? user-id group-id)
-            (db/tag-set-description! tag-id description)
-            (broadcast-group-change
-              group-id [:group/tag-descrption-change [tag-id description]])))))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [{:keys [tag-id description]} ?data]
+    (when (and tag-id description)
+      (let [group-id (db/tag-group-id tag-id)]
+        (when (db/user-is-group-admin? user-id group-id)
+          (db/tag-set-description! tag-id description)
+          (broadcast-group-change
+            group-id [:group/tag-descrption-change [tag-id description]]))))))

 (defmethod event-msg-handler :chat/create-group
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (cond
-      (string/blank? (?data :name))
-      (do
-        (timbre/warnf "User %s attempted to create group with a bad name '%s'"
-                      user-id (?data :name))
-        (when ?reply-fn
-          (?reply-fn {:error "Bad group name"})))
-
-      (db/group-exists? (?data :name))
-      (do
-        (timbre/warnf "User %s attempted to create group that already exsits %s"
-                      user-id (?data :name))
-        (when ?reply-fn
-          (?reply-fn {:error "Group name already taken"})))
-
-      :else
-      (let [new-group (db/create-group! ?data)]
-        (db/user-make-group-admin! user-id (new-group :id))))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (cond
+    (string/blank? (?data :name))
+    (do
+      (timbre/warnf "User %s attempted to create group with a bad name '%s'"
+                    user-id (?data :name))
+      (when ?reply-fn
+        (?reply-fn {:error "Bad group name"})))
+
+    (db/group-exists? (?data :name))
+    (do
+      (timbre/warnf "User %s attempted to create group that already exsits %s"
+                    user-id (?data :name))
+      (when ?reply-fn
+        (?reply-fn {:error "Group name already taken"})))
+
+    :else
+    (let [new-group (db/create-group! ?data)]
+      (db/user-make-group-admin! user-id (new-group :id)))))

 (defmethod event-msg-handler :chat/search
-  [{:keys [event id ?data ring-req ?reply-fn send-fn] :as ev-msg}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    ; this can take a while, so move it to a future
-    (future
-      (let [user-tags (db/get-user-visible-tag-ids user-id)
-            filter-tags (fn [t] (update-in t [:tag-ids] (partial into #{} (filter user-tags))))
-            thread-ids (search/search-threads-as user-id ?data)
-            threads (map (comp filter-tags db/get-thread) (take 25 thread-ids))]
-        (when ?reply-fn
-          (?reply-fn {:threads threads :thread-ids thread-ids}))))))
-
-(defmethod event-msg-handler :chat/load-threads
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
+  [{:keys [event id ?data ring-req ?reply-fn send-fn user-id] :as ev-msg}]
+  ; this can take a while, so move it to a future
+  (future
     (let [user-tags (db/get-user-visible-tag-ids user-id)
           filter-tags (fn [t] (update-in t [:tag-ids] (partial into #{} (filter user-tags))))
-          thread-ids (filter (partial db/user-can-see-thread? user-id) ?data)
-          threads (map filter-tags (db/get-threads thread-ids))]
+          thread-ids (search/search-threads-as user-id ?data)
+          threads (map (comp filter-tags db/get-thread) (take 25 thread-ids))]
       (when ?reply-fn
-        (?reply-fn {:threads threads})))))
+        (?reply-fn {:threads threads :thread-ids thread-ids})))))
+
+(defmethod event-msg-handler :chat/load-threads
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [user-tags (db/get-user-visible-tag-ids user-id)
+        filter-tags (fn [t] (update-in t [:tag-ids] (partial into #{} (filter user-tags))))
+        thread-ids (filter (partial db/user-can-see-thread? user-id) ?data)
+        threads (map filter-tags (db/get-threads thread-ids))]
+    (when ?reply-fn
+      (?reply-fn {:threads threads}))))

 (defmethod event-msg-handler :chat/threads-for-tag
-  [{:keys [event id ?data ring-req ?reply-fn send-fn] :as ev-msg}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [user-tags (db/get-user-visible-tag-ids user-id)
-          filter-tags (fn [t] (update-in t [:tag-ids]
-                                         (partial into #{} (filter user-tags))))
-          offset (get ?data :offset 0)
-          limit (get ?data :limit 50)
-          threads (-> (db/threads-with-tag user-id (?data :tag-id) offset limit)
-                      (update :threads (comp doall (partial map filter-tags))))]
-      (when ?reply-fn
-        (?reply-fn threads)))))
+  [{:keys [event id ?data ring-req ?reply-fn send-fn user-id] :as ev-msg}]
+  (let [user-tags (db/get-user-visible-tag-ids user-id)
+        filter-tags (fn [t] (update-in t [:tag-ids]
+                                       (partial into #{} (filter user-tags))))
+        offset (get ?data :offset 0)
+        limit (get ?data :limit 50)
+        threads (-> (db/threads-with-tag user-id (?data :tag-id) offset limit)
+                    (update :threads (comp doall (partial map filter-tags))))]
+    (when ?reply-fn
+      (?reply-fn threads))))

 (defmethod event-msg-handler :chat/invite-to-group
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if (db/user-in-group? user-id (?data :group-id))
-      (let [data (assoc ?data :inviter-id user-id)
-            invitation (db/create-invitation! data)]
-        (if-let [invited-user (db/user-with-email (invitation :invitee-email))]
-          (chsk-send! (invited-user :id) [:chat/invitation-received invitation])
-          (invites/send-invite invitation)))
-      ; TODO: indicate permissions error to user?
-      (timbre/warnf
-        "User %s attempted to invite %s to a group %s they don't have access to"
-        user-id (?data :invitee-email) (?data :group-id)))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if (db/user-in-group? user-id (?data :group-id))
+    (let [data (assoc ?data :inviter-id user-id)
+          invitation (db/create-invitation! data)]
+      (if-let [invited-user (db/user-with-email (invitation :invitee-email))]
+        (chsk-send! (invited-user :id) [:chat/invitation-received invitation])
+        (invites/send-invite invitation)))
+    ; TODO: indicate permissions error to user?
+    (timbre/warnf
+      "User %s attempted to invite %s to a group %s they don't have access to"
+      user-id (?data :invitee-email) (?data :group-id))))

 (defmethod event-msg-handler :chat/generate-invite-link
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if (db/user-in-group? user-id (?data :group-id))
-      (let [{:keys [group-id expires]} ?data]
-        (?reply-fn {:link (invites/make-open-invite-link group-id expires)}))
-      (do (timbre/warnf
-            "User %s attempted to invite %s to a group %s they don't have access to"
-            user-id (?data :invitee-email) (?data :group-id))
-          (?reply-fn {:braid/error :not-allowed})))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if (db/user-in-group? user-id (?data :group-id))
+    (let [{:keys [group-id expires]} ?data]
+      (?reply-fn {:link (invites/make-open-invite-link group-id expires)}))
+    (do (timbre/warnf
+          "User %s attempted to invite %s to a group %s they don't have access to"
+          user-id (?data :invitee-email) (?data :group-id))
+        (?reply-fn {:braid/error :not-allowed}))))

 (defmethod event-msg-handler :chat/invitation-accept
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if-let [invite (db/get-invite (?data :id))]
-      (do
-        (db/user-add-to-group! user-id (invite :group-id))
-        (db/user-subscribe-to-group-tags! user-id (invite :group-id))
-        (db/retract-invitation! (invite :id))
-        (chsk-send! user-id [:chat/joined-group
-                             {:group (db/get-group (invite :group-id))
-                              :tags (db/get-group-tags (invite :group-id))}])
-        (chsk-send! user-id [:chat/update-users (db/fetch-users-for-user user-id)])
-        (broadcast-group-change (invite :group-id) [:group/new-user (db/user-by-id user-id)]))
-      (timbre/warnf "User %s attempted to accept nonexistant invitaiton %s"
-                    user-id (?data :id)))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if-let [invite (db/get-invite (?data :id))]
+    (do
+      (db/user-add-to-group! user-id (invite :group-id))
+      (db/user-subscribe-to-group-tags! user-id (invite :group-id))
+      (db/retract-invitation! (invite :id))
+      (chsk-send! user-id [:chat/joined-group
+                           {:group (db/get-group (invite :group-id))
+                            :tags (db/get-group-tags (invite :group-id))}])
+      (chsk-send! user-id [:chat/update-users (db/fetch-users-for-user user-id)])
+      (broadcast-group-change (invite :group-id) [:group/new-user (db/user-by-id user-id)]))
+    (timbre/warnf "User %s attempted to accept nonexistant invitaiton %s"
+                  user-id (?data :id))))

 (defmethod event-msg-handler :chat/invitation-decline
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (if-let [invite (db/get-invite (?data :id))]
-      (db/retract-invitation! (invite :id))
-      (timbre/warnf "User %s attempted to decline nonexistant invitaiton %s"
-                    user-id (?data :id)))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (if-let [invite (db/get-invite (?data :id))]
+    (db/retract-invitation! (invite :id))
+    (timbre/warnf "User %s attempted to decline nonexistant invitaiton %s"
+                  user-id (?data :id))))

 (defmethod event-msg-handler :chat/make-user-admin
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [{new-admin-id :user-id group-id :group-id} ?data]
-      (when (and new-admin-id group-id
-                 (db/user-is-group-admin? user-id group-id))
-        (db/user-make-group-admin! new-admin-id group-id)
-        (broadcast-group-change group-id
-                                [:group/new-admin [group-id new-admin-id]])))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [{new-admin-id :user-id group-id :group-id} ?data]
+    (when (and new-admin-id group-id
+            (db/user-is-group-admin? user-id group-id))
+      (db/user-make-group-admin! new-admin-id group-id)
+      (broadcast-group-change group-id
+                              [:group/new-admin [group-id new-admin-id]]))))

 (defmethod event-msg-handler :chat/remove-from-group
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [{group-id :group-id to-remove-id :user-id} ?data]
-      (when (and group-id to-remove-id
-              (or (= to-remove-id user-id)
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [{group-id :group-id to-remove-id :user-id} ?data]
+    (when (and group-id to-remove-id
+            (or (= to-remove-id user-id)
                 (db/user-is-group-admin? user-id group-id)))
-        (db/user-leave-group! to-remove-id group-id)
-        (broadcast-group-change group-id [:group/user-left
-                                          [group-id to-remove-id]])
-        (chsk-send!
-          to-remove-id
-          [:user/left-group [group-id (:name (db/get-group group-id))]])))))
+      (db/user-leave-group! to-remove-id group-id)
+      (broadcast-group-change group-id [:group/user-left
+                                        [group-id to-remove-id]])
+      (chsk-send!
+        to-remove-id
+        [:user/left-group [group-id (:name (db/get-group group-id))]]))))

 (defmethod event-msg-handler :chat/set-group-intro
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [{:keys [group-id intro]} ?data]
-      (when (and group-id (db/user-is-group-admin? user-id group-id))
-        (db/group-set! group-id :intro intro)
-        (broadcast-group-change group-id [:group/new-intro [group-id intro]])))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [{:keys [group-id intro]} ?data]
+    (when (and group-id (db/user-is-group-admin? user-id group-id))
+      (db/group-set! group-id :intro intro)
+      (broadcast-group-change group-id [:group/new-intro [group-id intro]]))))

 (defmethod event-msg-handler :chat/set-group-avatar
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [{:keys [group-id avatar]} ?data]
-      (when (and group-id (db/user-is-group-admin? user-id group-id))
-        (db/group-set! group-id :avatar avatar)
-        (broadcast-group-change group-id [:group/new-avatar [group-id avatar]])))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [{:keys [group-id avatar]} ?data]
+    (when (and group-id (db/user-is-group-admin? user-id group-id))
+      (db/group-set! group-id :avatar avatar)
+      (broadcast-group-change group-id [:group/new-avatar [group-id avatar]]))))

 (defmethod event-msg-handler :chat/set-group-publicity
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [[group-id publicity] ?data]
-      (when (and group-id (db/user-is-group-admin? user-id group-id))
-        (db/group-set! group-id :public? publicity)
-        (broadcast-group-change group-id [:group/publicity-changed [group-id publicity]])))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [[group-id publicity] ?data]
+    (when (and group-id (db/user-is-group-admin? user-id group-id))
+      (db/group-set! group-id :public? publicity)
+      (broadcast-group-change group-id [:group/publicity-changed [group-id publicity]]))))

 (defmethod event-msg-handler :session/start
-  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
-  (when-let [user-id (get-in ring-req [:session :user-id])]
-    (let [connected (set (:any @connected-uids))]
-      (chsk-send!
-        user-id
-        [:session/init-data
-         {:user-id user-id
-          :version-checksum (digest/from-file "public/js/desktop/out/braid.js")
-          :user-groups (db/get-groups-for-user user-id)
-          :user-threads (db/get-open-threads-for-user user-id)
-          :user-subscribed-tag-ids (db/get-user-subscribed-tag-ids user-id)
-          :user-preferences (db/user-get-preferences user-id)
-          :users (into ()
-                       (map #(assoc % :status
-                                    (if (connected (% :id)) :online :offline)))
-                       (db/fetch-users-for-user user-id))
-          :invitations (db/fetch-invitations-for-user user-id)
-          :tags (db/fetch-tags-for-user user-id)}]))))
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn user-id]}]
+  (let [connected (set (:any @connected-uids))]
+    (chsk-send!
+      user-id
+      [:session/init-data
+       {:user-id user-id
+        :version-checksum (digest/from-file "public/js/desktop/out/braid.js")
+        :user-groups (db/get-groups-for-user user-id)
+        :user-threads (db/get-open-threads-for-user user-id)
+        :user-subscribed-tag-ids (db/get-user-subscribed-tag-ids user-id)
+        :user-preferences (db/user-get-preferences user-id)
+        :users (into ()
+                     (map #(assoc % :status
+                             (if (connected (% :id)) :online :offline)))
+                     (db/fetch-users-for-user user-id))
+        :invitations (db/fetch-invitations-for-user user-id)
+        :tags (db/fetch-tags-for-user user-id)}])))


Changed the header code in CSV to pull from the rows so that column order matches.

--- src/blutwurst/tuple_formatter.clj
+++ src/blutwurst/tuple_formatter.clj
@@ -14,7 +14,7 @@
    {:table (:table table)
     :tuples (vector (with-out-str
                        (csv/write-csv *out*
-                                      (concat (vector (map #(:name %) (:columns (:table table))))
+                                      (concat (vector (map #(-> % first name) (first (:tuples table))))
                                               (extract-data-from-table-tuples table)))
                        ))
    })


fix keyword typo in multiplicative-dropout function in layers.clj

I found a typo in the multiplicative-dropout function where it would create a
map with :ditribution as the keyword rather than the correct :distribution.

--- src/cortex/nn/layers.clj
+++ src/cortex/nn/layers.clj
@@ -289,7 +289,7 @@
      (assert (:variance args))
      [(assoc args
              :type :dropout
-             :ditribution :gaussian)]))
+             :distribution :gaussian)]))
   ([variance & args]
    [(merge-args
      {:type :dropout :distribution :gaussian :variance variance}


and now invariant records are (mostly) in place.

--- src/fogus/me/trammel.clj
+++ src/fogus/me/trammel.clj
@@ -268,17 +268,23 @@
       ((partial contract identity) (apply f m args))
       (apply f m args))))

+(alter-var-root (var assoc) apply-contract)
+(alter-var-root (var dissoc) apply-contract)
+(alter-var-root (var merge) apply-contract)
+(alter-var-root (var merge) apply-contract)
+(alter-var-root (var merge-with) (fn [f] (fn [f & maps] (apply (apply-contract merge-with) f maps))))
+(alter-var-root (var into) apply-contract)
+(alter-var-root (var conj) apply-contract)
+(alter-var-root (var assoc-in) apply-contract)
+(alter-var-root (var update-in) apply-contract)

 (comment
   (defconstrainedrecord Foo [a 1 b 2]
     [(every? number? [a b])]
     Object
     (toString [this] (str "record Foo has " a " and " b)))
-
-
-  (def a (wrap assoc))
-
-  (a (new-Foo) :a 33 :b 45 :c 88)
+
+  (str (new-Foo :a 77))
 )


Fix compile issue

Fix compile issue

--- src/rainboots/core.clj
+++ src/rainboots/core.clj
@@ -94,7 +94,7 @@
           (on-disconnect client))))
     ;; request terminal type
     ;; FIXME we should allow specifying more than :do
-    (doseq [opt accepted-opts]
+    (doseq [opt telnet-opts]
       (telnet! client {:telnet :do
                        :opt opt}))))


- lists: cleanup use of :div :label etc to eat our dogfood

--- src/re_demo/lists.cljs
+++ src/re_demo/lists.cljs
@@ -80,45 +80,50 @@
   [width]
   [v-box
    :width (str width "px")
-   :children [[:div.h4 "Parameters:"]
-              [:div {:style {:font-size "small"}}
-               [:label {:style {:font-variant "small-caps"}} "general"]
-               [:div {:style {:padding-left "10px"}}
-                 [:p "All parameters are passed as named arguments using keyword value pairs in the component vector e.g."]
-                 [:pre {:style {:font-size "smaller"}} [:code "[inline-list :choices [\"pick 1\" \"pick 2\"] :model #{\"pick 2\"} :required false]"]]
-                 [:p "Any parameter can optionally be a reagent atom and will be derefed."]]
-               [:label {:style {:font-variant "small-caps"}} "required"]
-               [:div {:style {:padding-left "10px"}}
-                [:p [:code ":choices"]
-                 (str " - list of selectable items. Elements can be strings or "
-                      " more interesting data items like {:label \"some name\" :sort 5}"
-                      " can be used. Also see :label-fn bellow.")]
-                [:p [:code ":model"]
-                  " - set of currently selected items. Note: items are considered distinct."]
-                 [:p [:code ":on-change"]
-                  " - callback will be passed set of selected items"]]
-               [:label {:style {:font-variant "small-caps"}} "optional"]
-               [:div {:style {:padding-left "10px"}}
-                [:p [:code ":multi-select"]
-                 " - boolean. When true, items use check boxes otherwise radio buttons. (default: true)"]
-                [:p [:code ":as-exclusions"]
-                 " - boolean. When true, selected items are shown with struck-out labels. (default: false)"]
-                [:p [:code ":required"]
-                 (str " - boolean. When true, at least one item must be selected. (default: false) "
-                      "Note: being able to un-select a radio button is not a common use case,"
-                      " so this should probably be set to true when in single select mode.")]
-                [:p [:code ":width"]
-                 " - CSS style value e.g. \"250px\" Fixed, when specified item labels will be clipped. Otherwise based on widest label."]
-                [:p [:code ":height"]
-                 " - CSS style value e.g. \"150px\" Fixed, beyond which items will scroll."]
-                [:p [:code ":max-height"]
-                 " - CSS style value e.g. \"150px\" Variable, beyond which items will scroll. If there are less items then this height, box will shrink."]
-                [:p [:code ":disabled"]
-                 " - boolean. When true, scrolling is allowed but selection is disabled. (default: false)"]
-                [:p [:code ":hide-border"]
-                 " - boolean. (default: false)"]
-                [:p [:code ":label-fn"]
-                 " - IFn to call on each element to get label string, default #(str %)"]]]]])
+   :children [[:h4 "Parameters:"]
+              [v-box
+               :style {:font-size "small"}
+               :children [
+                           [label     :style {:font-variant "small-caps"} :label "general"]
+                           [v-box
+                            :style    {:padding-left "10px"}
+                            :children [[:p "All parameters are passed as named arguments using keyword value pairs in the component vector e.g."]
+                                       [:pre {:style {:font-size "smaller"}} [:code "[inline-list :choices [\"pick 1\" \"pick 2\"] :model #{\"pick 2\"} :required false]"]]
+                                       [:p "Any parameter can optionally be a reagent atom and will be derefed."]]]
+                           [label     :style {:font-variant "small-caps"} :label "required"]
+                           [v-box
+                            :style    {:padding-left "10px"}
+                            :children [[:p [:code ":choices"]
+                                        (str " - list of selectable items. Elements can be strings or "
+                                             " more interesting data items like {:label \"some name\" :sort 5}"
+                                             " can be used. Also see :label-fn bellow.")]
+                                       [:p [:code ":model"]
+                                        " - set of currently selected items. Note: items are considered distinct."]
+                                       [:p [:code ":on-change"]
+                                        " - callback will be passed set of selected items"]]]
+                           [label     :style {:font-variant "small-caps"} :label "optional"]
+                           [v-box
+                            :style    {:padding-left "10px"}
+                            :children [[:p [:code ":multi-select"]
+                                        " - boolean. When true, items use check boxes otherwise radio buttons. (default: true)"]
+                                       [:p [:code ":as-exclusions"]
+                                        " - boolean. When true, selected items are shown with struck-out labels. (default: false)"]
+                                       [:p [:code ":required"]
+                                        (str " - boolean. When true, at least one item must be selected. (default: false) "
+                                             "Note: being able to un-select a radio button is not a common use case,"
+                                             " so this should probably be set to true when in single select mode.")]
+                                       [:p [:code ":width"]
+                                        " - CSS style value e.g. \"250px\" Fixed, when specified item labels will be clipped. Otherwise based on widest label."]
+                                       [:p [:code ":height"]
+                                        " - CSS style value e.g. \"150px\" Fixed, beyond which items will scroll."]
+                                       [:p [:code ":max-height"]
+                                        " - CSS style value e.g. \"150px\" Variable, beyond which items will scroll. If there are less items then this height, box will shrink."]
+                                       [:p [:code ":disabled"]
+                                        " - boolean. When true, scrolling is allowed but selection is disabled. (default: false)"]
+                                       [:p [:code ":hide-border"]
+                                        " - boolean. (default: false)"]
+                                       [:p [:code ":label-fn"]
+                                        " - IFn to call on each element to get label string, default #(str %)"]]]]]]])

 (defn panel


Fix meta descriptions

Fix meta descriptions

--- src/clj/chili_dog_night/views.clj
+++ src/clj/chili_dog_night/views.clj
@@ -76,24 +76,24 @@

 (defn not-found []
   (common "404"
-          [:meta {:description "You look lost."}]
+          [:meta {:name "description" :content "You look lost."}]
           [:section
            [:h2 404]
            [:p "The resource you requested was not found."]]))

 (defn home [data]
   (common "Our cinematic torture chamber."
-          [:meta {:description "This is the story of a friendship forged in food, film, and fear. It is pain, but it is also laughter. This is Chili Dog Night."}]
+          [:meta {:name "description" :content "This is the story of a friendship forged in food, film, and fear. It is pain, but it is also laughter. This is Chili Dog Night."}]
           (gathering-partial data)))

 (defn gathering [data]
   (common (:date data)
-          [:meta {:description (:synopsis data)}]
+          [:meta {:name "description" :content (:synopsis data)}]
           (gathering-partial data)))

 (defn about []
   (common "About"
-          [:meta {:description "Somehow we got the part. Don't ask. This is Chili Dog Night."}]
+          [:meta {:name "description" :content "Somehow we got the part. Don't ask. This is Chili Dog Night."}]
           [:section
            [:h2 "About"]
            [:p "Chili Dog Night is a celebration of the worst kinds of moving images "
@@ -121,7 +121,7 @@

 (defn colophon []
   (common "Colophon"
-          [:meta {:description "We made it good with a beginning, middle, and end. This is Chili Dog Night."}]
+          [:meta {:name "description" :content "We made it good with a beginning, middle, and end. This is Chili Dog Night."}]
           [:section
            [:h2 "Colophon"]
            [:p "This website was made possible by "


Improvement

Improvement

--- src/cljs/battle_console/game.cljs
+++ src/cljs/battle_console/game.cljs
@@ -21,6 +21,7 @@
   (state/set-state :loading-game nil)
   (state/set-state :player-code (get-in data ["viewed-by" "player-code"]))
   (let [final-data (normalize-board data)]
+    (state/set-state :raw-game-data data)
     (state/set-state :original-game-data final-data)
     (state/set-state :game-data final-data)))

@@ -200,18 +201,17 @@
   []
   (state/set-state :processing-action nil))

+(defn- game-played
+  "After the game was deployed"
+  [data]
+  (game-loaded data)
+  (state/set-state :current-actions nil)
+  (state/set-state :processing-action nil))
+
 (defn- game-deployed
   "After the game was deployed"
   [data]
   (game-played data))
-
-(defn- game-played
-  "After the game was deployed"
-  [data]
-  (state/set-state :game-data data)
-  (state/set-state :original-game-data data)
-  (state/set-state :current-actions nil)
-  (state/set-state :processing-action nil))

 (defn- deploy-game
   "Deploys a game"
@@ -232,7 +232,7 @@
   "Plays a game"
   [ev]
   (let [actions (or (state/get-state :current-actions) [])
-        game (state/get-state :original-game-data)
+        game (state/get-state :raw-game-data)
         player-code (get-in game ["viewed-by" "player-code"])
         token (state/get-state :token)
         game-id (state/get-state :game-id)
@@ -249,7 +249,7 @@
   (let [action (reader/read-string (get-action))
         current-actions (or (state/get-state :current-actions) [])
         new-actions (conj current-actions action)
-        game (state/get-state :original-game-data)
+        game (state/get-state :raw-game-data)
         player-code (get-in game ["viewed-by" "player-code"])
         game (-> game
                  (assoc :actions new-actions)
@@ -257,6 +257,7 @@
                  (assoc :action-focus player-code))
         jsgame (js/encodeURIComponent (.stringify js/JSON (clj->js game)))
         url (str "http://rules.api.orionsbelt.eu/game/turn/" player-code "?context=" jsgame)]
+    (println game)
     (state/set-state :processing-action action)
     (GET url {:handler action-added
               :error-handler error-loading-action})))
@@ -282,7 +283,6 @@
   "Checks if the play button should be disabled"
   [state]
   (let [player-code (get-in state [:game-data "viewed-by" "player-code"])]
-    (println (get-in state [:original-game-data "board" "state"]))
     (cond
       (state :processing-action) "disabled"
       (not= player-code (get-in state [:original-game-data "board" "state"])) "disabled"