Add type annotations

Add type annotations

--- src/str/core.clj
+++ src/str/core.clj
@@ -30,89 +30,68 @@

 (alias-ns clojure.string)

-(defn ends-with?
+(defn ^String ends-with?
   "Return s if s ends with suffix."
-  ([s suffix]
-   {:pre [(string? s)
-          (string? suffix)]
-    :post [(or (string? %) (nil? %))]}
+  ([^String s ^String suffix]
    (when (.endsWith s suffix)
      s))
-  ([s suffix ignore-case]
-   {:pre [(string? s)
-          (string? suffix)]
-    :post [(or (string? %) (nil? %))]}
+  ([^String s ^String suffix ignore-case]
    (let [end (.substring s (max 0 (- (.length s) (.length suffix))))]
      (when (.equalsIgnoreCase end suffix)
        s))))

-(defn starts-with?
+(defn ^String starts-with?
   "Return s if s starts with with prefix.

   If a third argument is provided the string comparison is insensitive to case."
-  ([s prefix]
-   {:pre [(string? s)
-          (string? prefix)]
-    :post [(or (string? %) (nil? %))]}
+  ([^String s ^String prefix]
    (when (.startsWith s prefix)
      s))
-  ([s prefix ignore-case]
-   {:pre [(string? s)
-          (string? prefix)]
-    :post [(or (string? %) (nil? %))]}
+  ([^String s ^String prefix ignore-case]
    (let [beg (.substring s 0 (.length prefix))]
      (when (.equalsIgnoreCase beg prefix)
        s))))

-(defn chop
+(defn ^String chop
   "Return a new string with the last character removed.

   If the string ends with \\r\\n, both characters are removed.

   Applying chop to an empty string is a no-op."
-  [s]
-  {:pre [(string? s)]
-   :post [(string? %)]}
+  [^String s]
   (if (.endsWith s "\r\n")
     (.substring s 0 (- (.length s) 2))
     (.substring s 0 (max 0 (dec (.length s))))))

-(defn chomp
+(defn ^String chomp
   "Return a new string with the given record separator removed from
   the end (if present).

   If seperator is not provided chomp will remove \\n, \\r or \\r\\n from
   the end of s."
-  ([s]
-   {:pre [(string? s)]
-    :post [(string? %)]}
+  ([^String s]
    (cond
      (.endsWith s "\r\n") (.substring s 0 (- (.length s) 2))
      (.endsWith s "\r") (.substring s 0 (dec (.length s)))
      (.endsWith s "\n") (.substring s 0 (dec (.length s)))
      :else s))
-  ([s separator]
-   {:pre [(string? s)
-          (string? separator)]
-    :post [(string? %)]}
+  ([^String s ^String separator]
    (if (.endsWith s separator)
      (.substring s 0 (- (.length s) (.length separator)))
      s)))

-(defn capitalize
+(defn ^String capitalize
   "Return a new string where the first character is in upper case and
   all others in lower case."
-  [s]
-  {:pre [(string? s)]
-   :post [(string? %)]}
+  [^String s]
   (case (.length s)
     0 ""
     1 (upper-case s)
     (str (upper-case (.substring s 0 1)) (lower-case (.substring s 1)))) )

-(defn invert-case
+(defn ^String invert-case
   "Change lower case characters to upper case and vice versa."
-  [s]
+  [^String s]
   (let [invert-case (fn [c]
                       (cond
                         (Character/isLowerCase c) (Character/toUpperCase c)


Note alias in auto-dev failure

Note alias in auto-dev failure

--- lib.rebel.auto-dev/src/edge/rebel/main.clj
+++ lib.rebel.auto-dev/src/edge/rebel/main.clj
@@ -61,7 +61,7 @@
                 (println (io.aviso.ansi/bold-yellow "[Edge] Now enter (go) to start the dev system"))
                 (catch Exception e
                   (.printStackTrace e)
-                  (println "[Edge] Failed to require dev, this usually means there was a syntax error. See exception above.")
+                  (println "[Edge] Failed to require dev, this usually means there was a syntax error or you didn't supply dev aliases (e.g. `-A:dev`). See exception above.")
                   (println "[Edge] Please correct it, and enter (fixed!) to resume development."))))
       :print syntax-highlight-pprint)
     ;; When the REPL stops, stop:


Refactor truncation-natification into component

--- src-cljs/frontend/components/build_steps.cljs
+++ src-cljs/frontend/components/build_steps.cljs
@@ -86,31 +86,25 @@
           [:span {:dangerouslySetInnerHTML
                   #js {"__html" trailing-out}}])))))

-(defn action-output [action owner]
-  (reify
-    om/IRenderState
-    (render-state [_ state]
-      (let [truncated-notification
-            (when (:truncated-client-side? action)
-              [:span.truncated
-               (gstring/format
-                "Your build output is too large to display in the browser. Only the first %s characters are displayed."
-                action-model/max-output-size)
-               [:br]
-               (if (= "running" (:status action))
-                 "You can download the output once this step is finished."
-                 [:a
-                  (html-utils/open-ext
-                   {:href (:user-facing-output-url action)
-                    :download "BuildOutput.txt"
-                    :target "_new"})
-                  "Download the output as a file."])])]
-        (html
-         [:pre.output
-          truncated-notification
-          (om/build-all output (:output action) {:key :react-key})
-          (om/build trailing-output (:converters-state action))
-          truncated-notification])))))
+(defn truncation-notification [action ownder]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       (when (:truncated-client-side? action)
+         [:span.truncated
+          (gstring/format
+           "Your build output is too large to display in the browser. Only the first %s characters are displayed."
+           action-model/max-output-size)
+          [:br]
+          (if (= "running" (:status action))
+            "You can download the output once this step is finished."
+            [:a
+             (html-utils/open-ext
+              {:href (:user-facing-output-url action)
+               :download "BuildOutput.txt"
+               :target "_new"})
+             "Download the output as a file."])])))))

 (defn action [action owner {:keys [uses-parallelism?] :as opts}]
   (reify
@@ -177,7 +171,11 @@
                        [:pre.bash-command
                         {:title "The full bash command used to run this setup"}
                         (:bash_command action)]])
-                    (om/build action-output action)])])]]]]])))))
+                    [:pre.output
+                     (om/build truncation-notification action)
+                     (om/build-all output (:output action) {:key :react-key})
+                     (om/build trailing-output (:converters-state action))
+                     (om/build truncation-notification action)]])])]]]]])))))

 (defn container-view [{:keys [container non-parallel-actions]} owner {:keys [uses-parallelism?] :as opts}]
   (reify


insights: hide side menu

insights: hide side menu

--- src-cljs/frontend/controllers/navigation.cljs
+++ src-cljs/frontend/controllers/navigation.cljs
@@ -231,7 +231,8 @@
 (defmethod navigated-to :build-insights
   [history-imp navigation-point args state]
   (-> state
-      (assoc :navigation-point navigation-point)
+      (assoc :navigation-point navigation-point
+             :navigation-data (assoc args :show-aside-menu? false))
       state-utils/clear-page-state
       (assoc-in state/projects-path [])))


Fix db bug and reduce repetition

Fix db bug and reduce repetition

--- common/clojure/nightweb/db.clj
+++ common/clojure/nightweb/db.clj
@@ -145,7 +145,7 @@
          ptr-time (:time params)
          statement ["SELECT * FROM fav
                      WHERE userhash = ? AND ptrhash = ? AND ptrtime IS ?"
-                    ptr-hash ptr-time]
+                    my-user-hash ptr-hash ptr-time]
          rs (jdbc/query @spec statement)]
      (first (prepare-results rs :fav)))))

@@ -425,8 +425,9 @@

 (defn delete-user
   [user-hash]
-  (jdbc/delete! @spec :user ["userhash = ?" user-hash])
-  (jdbc/delete! @spec :post ["userhash = ?" user-hash])
-  (jdbc/delete! @spec :pic ["userhash = ?" user-hash])
-  (jdbc/delete! @spec :fav ["userhash = ?" user-hash])
-  (jdbc/delete! @spec :tag ["userhash = ?" user-hash]))
+  (let [statement ["userhash = ?" user-hash]]
+    (jdbc/delete! @spec :user statement)
+    (jdbc/delete! @spec :post statement)
+    (jdbc/delete! @spec :pic statement)
+    (jdbc/delete! @spec :fav statement)
+    (jdbc/delete! @spec :tag statement)))


removing empty file

removing empty file


Rework handling of Repl binding

Rework handling of Repl binding

Also add *unchecked-math* for 1.3

--- server/src/main/clojure/vimclojure/repl.clj
+++ server/src/main/clojure/vimclojure/repl.clj
@@ -24,9 +24,12 @@
   (:require
     clojure.test)
   (:use
-     [vimclojure.util :only (stream->seq pretty-print pretty-print-causetrace)])
+    [vimclojure.util :only [safe-var-get stream->seq
+                            pretty-print pretty-print-causetrace]])
   (:import
-     (clojure.lang Var Compiler LineNumberingPushbackReader)))
+    clojure.lang.Var
+    clojure.lang.Compiler
+    clojure.lang.LineNumberingPushbackReader))

 (def
   ^{:dynamic true :doc
@@ -47,37 +50,31 @@
   *print-pretty*
   false)

-(defstruct
-  #^{:doc
-  "The structure for the Repl interface. Holds the state of a Repl between
-  invokations. The members correspond to the Vars as bound be with-binding."}
-  repl
-  :id :ns :warn-on-reflection :print-meta :print-length :print-level
-  :compile-path :command-line-args :expr1 :expr2 :expr3 :exception :test-out
-  :line)
+(defn add-binding
+  [bindings sym]
+  (if-let [v (resolve sym)]
+    (assoc bindings v (safe-var-get v))
+    bindings))
+
+(def bindable-vars
+  `[*warn-on-reflection* *print-meta* *print-length*
+    *print-level* *compile-path* *command-line-args*
+    *unchecked-math* *1 *2 *3 *e
+    ; VimClojure specific.
+    *print-pretty*])

 (defn make-repl
   "Create a new Repl."
   ([id] (make-repl id (the-ns 'user)))
   ([id namespace]
-   (struct-map repl
-               :id                 id
-               :ns                 namespace
-               :warn-on-reflection *warn-on-reflection*
-               :print-meta         *print-meta*
-               :print-length       *print-length*
-               :print-level        *print-level*
-               :compile-path       (System/getProperty
-                                     "clojure.compile.path"
-                                     "classes")
-               :command-line-args  nil
-               :expr1              nil
-               :expr2              nil
-               :expr3              nil
-               :exception          nil
-               :print-pretty       vimclojure.repl/*print-pretty*
-               :test-out           nil
-               :line               0)))
+   {:id        id
+    :ns        namespace
+    :test-out  nil
+    :line      1
+    :bindings  (-> (reduce add-binding {} bindable-vars)
+                 (assoc #'*compile-path* (System/getProperty
+                                           "clojure.compile.path"
+                                           "classes")))}))

 (defn start
   "Start a new Repl and register it in the system."
@@ -126,49 +123,28 @@
                    (the-repl :line)
                    line)]
     (with-bindings
-      {Compiler/LINE          (Integer. (.intValue line)) ; #64: Unbox to ensure int.
-       Compiler/SOURCE        (.getName (java.io.File. file))
-       Compiler/SOURCE_PATH   file
-       #'*in*                 (make-reader *in* line)
-       #'*ns*                 (if nspace nspace (the-repl :ns))
-       #'*warn-on-reflection* (the-repl :warn-on-reflection)
-       #'*print-meta*         (the-repl :print-meta)
-       #'*print-length*       (the-repl :print-length)
-       #'*print-level*        (the-repl :print-level)
-       #'*compile-path*       (the-repl :compile-path)
-       #'*command-line-args*  (the-repl :command-line-args)
-       #'*1                   (the-repl :expr1)
-       #'*2                   (the-repl :expr2)
-       #'*3                   (the-repl :expr3)
-       #'*e                   (the-repl :exception)
-       #'vimclojure.repl/*print-pretty* (the-repl :print-pretty)
-       #'clojure.test/*test-out* (if-let [test-out (the-repl :test-out)]
-                                   test-out
-                                   *out*)}
+      (merge (:bindings the-repl)
+             ; #64: Unbox to ensure int.
+             {Compiler/LINE        (Integer. (.intValue line))
+              Compiler/SOURCE      (.getName (java.io.File. file))
+              Compiler/SOURCE_PATH file
+              #'*in*               (make-reader *in* line)
+              #'*ns*               (if nspace nspace (:ns the-repl))
+              #'clojure.test/*test-out* (if-let [test-out (the-repl :test-out)]
+                                          test-out
+                                          *out*)})
       (try
         (thunk)
         (finally
           (when (not= id -1)
             (swap! *repls* assoc id
-                   (struct-map
-                     repl
-                     :id                 id
-                     :ns                 *ns*
-                     :warn-on-reflection *warn-on-reflection*
-                     :print-meta         *print-meta*
-                     :print-length       *print-length*
-                     :print-level        *print-level*
-                     :compile-path       *compile-path*
-                     :command-line-args  *command-line-args*
-                     :expr1              *1
-                     :expr2              *2
-                     :expr3              *3
-                     :exception          *e
-                     :print-pretty       vimclojure.repl/*print-pretty*
-                     :test-out           (let [test-out clojure.test/*test-out*]
-                                           (when-not (identical? test-out *out*)
-                                             test-out))
-                     :line               (dec (.getLineNumber *in*))))))))))
+                   {:id        id
+                    :ns        *ns*
+                    :test-out  (let [test-out clojure.test/*test-out*]
+                                 (when-not (identical? test-out *out*)
+                                   test-out))
+                    :line      (dec (.getLineNumber *in*))
+                    :bindings  (reduce add-binding {} bindable-vars)})))))))

 (defmacro with-repl
   "Executes body in the context of the Repl with the given id. id may be -1


Switch from xylophone to horn.

Switch from xylophone to horn.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -36,20 +36,19 @@
                           (update-in [:time] + fraction))]
       (concat before [first-note second-note] after))))

-(definst akadinda [freq 440 vol 0.5 pan 0]
+(definst horn [freq 440 vol 0.5 pan 0]
   (-> (sin-osc freq)
-      (+ (* 1/3 (sin-osc (* 2.01 freq))))
-      (+ (* 1/2 (sin-osc (* 3.001 freq))))
-      (+ (* 1/8 (sin-osc (* 5.001 freq))))
+      (+ (* 1/2 (sin-osc 3) (sin-osc (* 3.01 freq))))
+      (+ (* 1/5 (sin-osc 3) (sin-osc (* 2 freq))))
+      (+ (* 1/8 (sin-osc 9) (sin-osc (* 4.99 freq))))
+      (+ (* 1/8 (sin-osc (* 7.01 freq))))
       (clip2 0.8)
-      (lpf (* 5 440))
-      (* (env-gen (adsr 0.01 0.05 0.15 0.2) (line:kr 1 0 0.1) :action FREE))
-      (+ (* (env-gen (perc 0.02 0.03)) (* 1/3 (sin-osc (* 0.5 freq)))))
+      (* (env-gen (adsr 0.1 0.3 0.15 0.2) (line:kr 1 0 0.1) :action FREE))
       (pan2 pan)
       (* vol)))

 (defmethod live/play-note :default [{:keys [pitch pan]}]
-  (when pitch (akadinda :freq pitch :pan pan)))
+  (when pitch (horn :freq pitch :pan pan)))

 (defn rand-variations [variations]
   (concat


exit editing state before we take undo snapshot

--- cljs/src/main/plastic/main/editor/ops/editing.cljs
+++ cljs/src/main/plastic/main/editor/ops/editing.cljs
@@ -70,10 +70,13 @@
           (xform-on-worker editor [:insert-placeholder-as-first-child edit-point] select))
         (call-continuation cb (switch-to-editing editor cursor-id))))))

-(defn reset-editing [editor moved-cursor]
+(defn sanitize-cursor [editor moved-cursor]
   (-> editor
-    (editor/set-editing nil)
     (editor/replace-cursor-if-not-valid moved-cursor)))
+
+(defn reset-editing [editor]
+  (-> editor
+    (editor/set-editing nil)))

 (defn stop-editing [editor & [cb]]
   (or
@@ -88,9 +91,9 @@
                 effective? (editor/get-inline-editor-puppets-effective? editor)
                 puppets (if effective? (editor/get-puppets editor) #{})
                 effect (fn [db]
-                         (editor/update-in-db db editor-id (make-continuation cb reset-editing) moved-cursor))]
-            (xform-on-worker editor [:edit edited-node-id puppets value] effect)))))
-    (call-continuation cb editor)))
+                         (editor/update-in-db db editor-id (make-continuation cb sanitize-cursor) moved-cursor))]
+            (xform-on-worker (reset-editing editor) [:edit edited-node-id puppets value] effect)))))
+    (call-continuation cb (reset-editing editor))))

 (defn apply-operation-but-preserve-editing-mode [editor op]
   (if (editor/editing? editor)
@@ -119,7 +122,7 @@
         editor-with-moved-cursor (move-cursor-for-case-of-selected-node-removal editor)
         moved-cursor (editor/get-cursor editor-with-moved-cursor)
         move-cursor (fn [db]
-                      (editor/update-in-db db editor-id (make-continuation cb reset-editing) moved-cursor))]
+                      (editor/update-in-db db editor-id (make-continuation cb sanitize-cursor) moved-cursor))]
     (xform-on-worker editor [:backspace edit-point] move-cursor)))

 (defn delete-linebreak-or-token-after-cursor [editor]


Update internal.clj

Update internal.clj

Redirect to dashboard

--- auth/src/com/sixsq/slipstream/auth/internal.clj
+++ auth/src/com/sixsq/slipstream/auth/internal.clj
@@ -24,7 +24,7 @@
   (assoc
     (uh/response 200)
     :cookies
-    {"com.sixsq.slipstream.cookie" {:value token, :path "/"}}))
+    {"com.sixsq.slipstream.cookie" {:value token, :path "/dashboard"}}))

 (defn valid?
   [credentials]


edit -> edited

edit -> edited

--- src/clj/com/rpl/specter/zipper.cljx
+++ src/clj/com/rpl/specter/zipper.cljx
@@ -27,7 +27,7 @@
     (zip/root (zip/edit structure next-fn))
     ))

-(defn edit [path update-fn]
+(defn edited [path update-fn]
   (fixed-pathed-path [late path]
     (select* [this structure next-fn]
       (next-fn


Possible fix for logistic-prob issue - use row matrices only

--- src/clj/forma/classify/logistic.clj
+++ src/clj/forma/classify/logistic.clj
@@ -206,9 +206,9 @@

 (defn logistic-prob-wrap
   [beta-vec val neighbor-val]
-  (let [beta-mat (to-double-matrix beta-vec)
-        features-mat (to-double-rowmat (unpack-feature-vec val neighbor-val)) ]
-    [(vec (.toArray (logistic-prob beta-mat features-mat)))]))
+  (let [beta-mat (to-double-rowmat beta-vec)
+        features-mat (to-double-rowmat (unpack-feature-vec val neighbor-val))]
+    (flatten (vec (.toArray (logistic-prob beta-mat features-mat))))))

 (defbufferop mk-timeseries
   [tuples]


Removed extraneous call of vec

Removed extraneous call of vec

--- src/clj/forma/hadoop/jobs/forma.clj
+++ src/clj/forma/hadoop/jobs/forma.clj
@@ -107,9 +107,8 @@
                                           [est-start est-end])
         tele-start-idx (inc start-idx)
         tele-end-idx (inc end-idx)]
-    (vec (map
-          (comp vector vec)
-          (f/tele-ts tele-start-idx tele-end-idx val-ts)))))
+    (map (comp vector vec)
+         (f/tele-ts tele-start-idx tele-end-idx val-ts))))

 (defn dynamic-clean
   "Accepts an est-map, and sources for ndvi and rain timeseries and


Use "thread first" macro where appropriate

--- src/cljs/asciinema_player/view.cljs
+++ src/cljs/asciinema_player/view.cljs
@@ -92,13 +92,13 @@
     [:span.fullscreen-button {:on-click on-click} [expand-icon] [shrink-icon]]))

 (defn element-local-mouse-x [e]
-  (let [rect (.getBoundingClientRect (.-currentTarget e))]
+  (let [rect (-> e .-currentTarget .getBoundingClientRect)]
     (- (.-clientX e) (.-left rect))))

 (defn progress-bar [progress events]
   (let [on-mouse-down (fn [e]
                         (.preventDefault e)
-                        (let [bar-width (.-offsetWidth (.-currentTarget e))
+                        (let [bar-width (-> e .-currentTarget .-offsetWidth)
                               mouse-x (util/adjust-to-range (element-local-mouse-x e) 0 bar-width)
                               position (/ mouse-x bar-width)]
                           (go (>! events [:seek position]))))]


Remove state from next-image loader

Remove state from next-image loader

Take a simpler tack and just try to load when scroll is within a fixed
distance of bottom.  Much better than anything else...

--- src/cljs/comic_reader/handlers.cljs
+++ src/cljs/comic_reader/handlers.cljs
@@ -73,31 +73,21 @@

   (rf/register-handler
    :scroll
-   (let [counter (atom 1)
-         scroll-threshold (atom (/ 1 2))]
-     (fn [db _]
-       (if (and (not (:waiting db))
-                (= (:page db)
-                   :read))
-         (let [scroll-y (.-scrollY js/window)
-               window-height (.-innerHeight js/window)
-               screen-bottom (+ scroll-y window-height)
-               document-height (-> js/document
-                                   .-body
-                                   .-clientHeight)]
-           (.log js/console "Threshold: " @scroll-threshold)
-           (if (> screen-bottom
-                  (* @scroll-threshold document-height))
-             (do
-               (swap! counter inc)
-               (swap! scroll-threshold
-                      +
-                      (/ 1
-                         (.pow js/Math
-                               2 @counter)))
-               (get-next-image db))
-             db))
-         db))))
+   (fn [db _]
+     (if (and (not (:waiting db))
+              (= (:page db)
+                 :read))
+       (let [scroll-y (.-scrollY js/window)
+             window-height (.-innerHeight js/window)
+             screen-bottom (+ scroll-y window-height)
+             document-height (-> js/document
+                                 .-body
+                                 .-clientHeight)]
+         (if (> screen-bottom
+                (- document-height 100))
+           (get-next-image db)
+           db))
+       db)))

   (rf/register-handler
    :next-image


Don't interfere with Ctrl+Shift commands

--- src/clojure/nightcode/shortcuts.clj
+++ src/clojure/nightcode/shortcuts.clj
@@ -95,7 +95,9 @@
                     (= (.getKeyCode e) KeyEvent/VK_META))
             (toggle-hints target @is-down?)))
         ; provide special actions for certain keys
-        (if (and @is-down? (= (.getID e) KeyEvent/KEY_PRESSED))
+        (if (and @is-down?
+                 (not (.isShiftDown e))
+                 (= (.getID e) KeyEvent/KEY_PRESSED))
           (func (.getKeyCode e))
           false))))
   target)


Add using merge-indexes

Add using merge-indexes

--- src/com/wsscode/pathom/connect.cljc
+++ src/com/wsscode/pathom/connect.cljc
@@ -92,17 +92,17 @@
   ([indexes sym sym-data]
    (let [{::keys [input output] :as sym-data} (merge (resolver->in-out sym)
                                                      sym-data)]
-     (-> indexes
-         (assoc-in [::index-resolvers sym] sym-data)
-         (update-in [::index-io input] #(-> % (merge-io (normalize-io output))))
-         (cond-> (= 1 (count input)) (update ::idents (fnil conj #{}) (first input)))
-         (as-> <>
-           (reduce (fn [indexes out-attr]
-                     (cond-> indexes
-                       (not= #{out-attr} input)
-                       (update-in [::index-oir out-attr input] (fnil conj #{}) sym)))
-                   <>
-                   (flat-query output)))))))
+     (merge-indexes indexes
+       (cond-> {::index-resolvers {sym sym-data}
+                ::index-io        {input (normalize-io output)}
+                ::index-oir       (reduce (fn [indexes out-attr]
+                                            (cond-> indexes
+                                              (not= #{out-attr} input)
+                                              (update-in [out-attr input] (fnil conj #{}) sym)))
+                                          {}
+                                          (flat-query output))}
+         (= 1 (count input))
+         (assoc ::idents #{(first input)}))))))

 (s/fdef add
   :args (s/cat :indexes (s/or :index ::indexes :blank #{{}})


remove test code

remove test code

--- sherpa-clojure/src/main/clojure/sherpa/sherpa_client.clj
+++ sherpa-clojure/src/main/clojure/sherpa/sherpa_client.clj
@@ -35,10 +35,4 @@
                                   (.iterator mgr))))
            (close [_] (.close transceiver)))))

-(defn test-calling-client []
-  (let [client (sherpa-client {:host "localhost" :port 1234})
-        results (query client "SELECT ?x ?y WHERE { ... }" nil nil)]
-
-    ;; results are a seq of solutions where each solution is a
-    ;; map from key (variable) to value (an RDF data type).
-    ))
+


4clojure:: practice ongoing...

4clojure:: practice ongoing...

--- src/clojure_learning/4clojure-exercises.clj
+++ src/clojure_learning/4clojure-exercises.clj
@@ -691,3 +691,30 @@
   0 [:a :b :c])

 (repeat 3 0) ; (0 0 0)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Intro to destructuring
+;; Let bindings and function parameter lists support destructuring.
+;; (= [2 4] (let [[a b c d e f g] (range)] __))
+(let [{:keys (a b c d)} (apply hash-map [:a 1 :b 2 :c 3 :d 4])] [b d])
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;; Reimplement [iterate]
+;; Given a side-effect free function f and an initial value x write a function which returns an
+;; infinite lazy sequence of x, (f x), (f (f x)), (f (f (f x))), etc.
+;; (= (take 5 (__ #(* 2 %) 1)) [1 2 4 8 16])
+;; (= (take 100 (__ inc 0)) (take 100 (range)))
+(iterate #(+ 2 %) 0)
+(map #(* % %) (range))
+
+(reduce #(lazy-seq (conj % %2)) [] (range))
+(for [x (range) y (drop 1 (range))] [x y])
+(take 5 (foo #(* 2 %) 1))
+
+(defn iterate-recur
+  [func start]
+    (lazy-cat (list start)
+              (lazy-seq (iterate-recur func (func start)))))
+
+(take 5 (iterate-recur #(* 2 %) 1))


Removed use of "read-string" of an evolved string, since it was causing stack overflow errors

--- src/clojush/problems/software/syllables.clj
+++ src/clojush/problems/software/syllables.clj
@@ -118,14 +118,12 @@
                              ; Error is Levenshtein distance and, if ends in an integer, distance from correct integer
                              (vector
                                (levenshtein-distance correct-output printed-result)
-                               (let [num-result (try (read-string (last (string/split printed-result #"\s+")))
-                                                  (catch Exception e nil))]
-                                 (if (integer? num-result)
-                                   (abs (- (try (read-string (last (string/split correct-output #"\s+")))
-                                             (catch Exception e nil))
-                                           num-result)) ;distance from correct integer
-                                   1000)
-                                 ))))))]
+                               (if-let [num-result (try (Integer/parseInt (last (string/split printed-result #"\s+")))
+                                                      (catch Exception e nil))]
+                                 (abs (- (Integer/parseInt (last (string/split correct-output #"\s+")))
+                                         num-result)) ;distance from correct integer
+                                 1000)
+                               )))))]
           (when @global-print-behavioral-diversity
             (swap! population-behaviors conj @behavior))
           errors)))))


clojure: small improvement in morphism function

--- clojure/org/gavrog/clojure/pgraph_morphisms.clj
+++ clojure/org/gavrog/clojure/pgraph_morphisms.clj
@@ -108,8 +108,7 @@
   (when (.isUnimodularIntegerMatrix M)
     (let [sigs (node-signatures net)
           d (.minus (first (first (sigs w))) (first (first (sigs v))))
-          op (.times (Operator. (extend-matrix M)) (Operator. d))
-          check-sigs (fn [a b] (equal-sigs? (map-sig op (sigs v)) (sigs w)))]
+          op (.times (Operator. (extend-matrix M)) (Operator. d))]
       (loop [src2img {}
              q (conj empty-queue [v w])]
         (let [[a b] (first q)]
@@ -117,6 +116,9 @@
             (empty? q)
             src2img

+            (nil? b)
+            nil
+
             (= b (src2img a))
             (recur src2img (pop q))

@@ -126,7 +128,7 @@
             (instance? IEdge a)
             (recur (assoc src2img a b) (conj (pop q) [(.target a) (.target b)]))

-            (not (check-sigs a b))
+            (not (equal-sigs? (map-sig op (sigs a)) (sigs b)))
             nil

             :else
@@ -136,8 +138,7 @@
                      (into (pop q)
                            (for [d (keys nv)
                                  :let [e1 (.get nv d)
-                                       e2 (.get nw (.times d op))]
-                                 :when e2]
+                                       e2 (.get nw (.times d op))]]
                              [e1 e2]))))))))))

 (defn symmetries [net]


load-index now supports receiving the index atom to update after fetching is complete

--- src/com/wsscode/pathom/connect/graphql.cljc
+++ src/com/wsscode/pathom/connect/graphql.cljc
@@ -341,9 +341,13 @@
         x))
     schema))

-(defn load-index [req]
-  (let-chan [{:keys [data]} (request req (pg/query->graphql schema-query))]
-    (index-schema (assoc req ::schema (normalize-schema data)))))
+(defn load-index
+  ([req]
+   (let-chan [{:keys [data]} (request req (pg/query->graphql schema-query))]
+     (index-schema (assoc req ::schema (normalize-schema data)))))
+  ([req indexes]
+   (let-chan [idx (load-index req)]
+     (swap! indexes pc/merge-indexes idx))))

 (defn graphql-resolve [config env]
   (let [env' (merge env config)


[ISSUE #3224] Click on user picture open profile

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/chat/views/message/message.cljs
+++ src/status_im/chat/views/message/message.cljs
@@ -1,7 +1,6 @@
 (ns status-im.chat.views.message.message
   (:require-macros [status-im.utils.views :refer [defview letsubs]])
   (:require [re-frame.core :as re-frame]
-            [clojure.walk :as walk]
             [reagent.core :as reagent]
             [status-im.ui.components.react :as react]
             [status-im.ui.components.animation :as animation]
@@ -21,8 +20,7 @@
             [status-im.i18n :as i18n]
             [status-im.ui.components.colors :as colors]
             [clojure.string :as string]
-            [status-im.chat.events.console :as console]
-            [taoensso.timbre :as log]))
+            [status-im.chat.events.console :as console]))

 (def window-width (:width (react/get-dimensions "window")))

@@ -69,7 +67,7 @@
   [{:keys [content params] :as message}]
   (letsubs [command [:get-command (:content-command-ref content)]]
     (let [preview (:preview content)
-          {:keys [type color] icon-path :icon} command]
+          {:keys [color] icon-path :icon} command]
       [react/view style/content-command-view
        (when color
          [react/view style/command-container
@@ -192,7 +190,7 @@
   [wrapper message [text-message message]])

 (defmethod message-content constants/content-type-status
-  [_ message]
+  [_ _]
   [message-content-status])

 (defmethod message-content constants/content-type-command
@@ -242,7 +240,7 @@
              (str "+ " (- delivery-statuses-count 3))])]]))))

 (defn message-delivery-status
-  [{:keys [message-id chat-id current-public-key user-statuses content]}]
+  [{:keys [chat-id current-public-key user-statuses content]}]
   (let [outgoing-status (or (get user-statuses current-public-key) :sending)
         delivery-status (get user-statuses chat-id)
         status          (cond (and (= constants/console-chat-id chat-id)
@@ -276,7 +274,9 @@
      (when-not same-author?
        (if outgoing
          [my-photo from]
-         [member-photo from]))]
+         [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-profile from])}
+          [react/view
+           [member-photo from]]]))]
     [react/view (style/group-message-view message)
      content
      (when last-outgoing?
@@ -292,9 +292,9 @@
         (animation/start
          (animation/timing val {:toValue  to-value
                                 :duration 250})
-          (fn [arg]
-            (when (.-finished arg)
-              (callback))))))))
+         (fn [arg]
+           (when (.-finished arg)
+             (callback))))))))

 (defn message-container [message & children]
   (if (:appearing? message)


kill old actions buttons (relocated to main menu)

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -111,67 +111,6 @@
                           :title (when info-button-learned? "What is Precursor?")}
            (common/icon :info)])))))

-(defn main-actions [data owner]
-  (reify
-    om/IInitState
-    (init-state [_] {:listener-key (.getNextUniqueId (.getInstance IdGenerator))})
-    om/IDidMount
-    (did-mount [_]
-      (d/listen! (om/get-shared owner :db)
-                 (om/get-state owner :listener-key)
-                 (fn [tx-report]
-                   ;; TODO: better way to check if state changed
-                   (when-let [chat-datoms (seq (filter #(= :chat/body (:a %)) (:tx-data tx-report)))]
-                     (om/refresh! owner)))))
-    om/IWillUnmount
-    (will-unmount [_]
-      (d/unlisten! (om/get-shared owner :db) (om/get-state owner :listener-key)))
-    om/IRender
-    (render [_]
-      (let [{:keys [cast! db]} (om/get-shared owner)
-            aside-opened? (get-in data state/aside-menu-opened-path)
-            last-read-time (get-in data (state/last-read-chat-time-path (:document/id data)))
-            unread-chat-count (chat-model/compute-unread-chat-count @db last-read-time)
-            unread-chat-count (if last-read-time
-                                unread-chat-count
-                                ;; add one for the dummy message
-                                (inc unread-chat-count))
-            info-button-learned? (get-in data state/info-button-learned-path)
-            menu-button-learned? (get-in data state/menu-button-learned-path)
-            newdoc-button-learned? (get-in data state/newdoc-button-learned-path)
-            your-docs-learned? (get-in data state/your-docs-learned-path)]
-        (html
-         [:div.main-actions
-         ; [:a.action-menu {:on-click #(cast! :main-menu-opened)
-         ;                  :role "button"
-         ;                  :data-right (when-not menu-button-learned? "Open Menu")
-         ;                  :title (when menu-button-learned? "Open Menu")}
-         ;  (common/icon :menu)]
-          ; [:a.action-menu {:on-click #(cast! :aside-menu-toggled)
-          ;                  :class (when-not aside-opened? "closed")
-          ;                  :data-right (when-not menu-button-learned? "Open Menu")
-          ;                  :title (when menu-button-learned? (if aside-opened? "Close Menu" "Open Menu"))}
-          ;  (common/icon :menu)]
-          (when (and (not aside-opened?) (pos? unread-chat-count))
-            [:div.unseen-eids (str unread-chat-count)])
-          (om/build overlay/auth-link data)
-          [:a.action-newdoc {:on-click #(cast! :newdoc-button-clicked)
-                             :href "/"
-                             :target "_self"
-                             :data-right (when-not newdoc-button-learned? "New Document")
-                             :title (when newdoc-button-learned? "New Document")}
-           (common/icon :newdoc)]
-          [:a.action-your-docs {:on-click #(cast! :your-docs-opened)
-                                :data-right (when-not your-docs-learned? "Your Docs")
-                                :title (when your-docs-learned? "Your Docs")}
-           (common/icon :clock)]
-          [:a.action-info {:on-click #(cast! :overlay-info-toggled)
-                           :class (when-not info-button-learned? "hover")
-                           :data-right (when-not info-button-learned? "What is this thing?")
-                           :title (when info-button-learned? "What is this thing?")}
-           (common/icon :info)]])))))
-
-
 (defn app* [app owner]
   (reify
     om/IRender
@@ -187,14 +126,6 @@
                 (om/build chat-menu-button app)
                 (when-not (:cust app)
                   (om/build about-button (select-in app [state/info-button-learned-path])))
-                ; (om/build main-actions (select-in app [state/aside-menu-opened-path
-                ;                                        state/menu-button-learned-path
-                ;                                        state/info-button-learned-path
-                ;                                        state/newdoc-button-learned-path
-                ;                                        state/login-button-learned-path
-                ;                                        [:cust]
-                ;                                        [:document/id]
-                ;                                        (state/last-read-chat-time-path (:document/id app))]))
                 (when (and (:mouse app) (not= :touch (:type (:mouse app))))
                   [:div.mouse-stats
                    (pr-str (select-keys (:mouse app) [:x :y :rx :ry]))])


Update retry-build event
    Retry builds should work for Github and Bitbucket.

    * Add build-retry path
    * Add indent

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -402,19 +402,21 @@
 (defmethod post-control-event! :retry-build-clicked
   [target message {:keys [build-num build-id vcs-url no-cache?] :as args} previous-state current-state]
   (let [api-ch (-> current-state :comms :api)
-        org-name (vcs-url/org-name vcs-url)
-        repo-name (vcs-url/repo-name vcs-url)
-        uuid frontend.async/*uuid*]
-    (go
-     (let [api-result (<! (ajax/managed-ajax :post (gstring/format "/api/v1/project/%s/%s/%s/retry" org-name repo-name build-num)
-                                             :params (when no-cache? {:no-cache true})))]
-       (put! api-ch [:retry-build (:status api-result) api-result])
-       (release-button! uuid (:status api-result))
-       (when (= :success (:status api-result))
-         (analytics/track {:event-type :build-triggered
-                           :current-state current-state
-                           :build (:resp api-result)
-                           :properties {:no-cache? no-cache?}}))))))
+        uuid frontend.async/*uuid*
+        build {:org-name (vcs-url/org-name vcs-url)
+               :repo-name (vcs-url/repo-name vcs-url)
+               :build-num build-num
+               :vcs-type (vcs-url/vcs-type vcs-url)}]
+    (go
+      (let [api-result (<! (ajax/managed-ajax :post (api-path/build-retry build)
+                                              :params (when no-cache? {:no-cache true})))]
+        (put! api-ch [:retry-build (:status api-result) api-result])
+        (release-button! uuid (:status api-result))
+        (when (= :success (:status api-result))
+          (analytics/track {:event-type :build-triggered
+                            :current-state current-state
+                            :build (:resp api-result)
+                            :properties {:no-cache? no-cache?}}))))))

 (defmethod post-control-event! :ssh-build-clicked


dumb mistake

dumb mistake

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -81,8 +81,8 @@
 ;; TODO: this shouldn't assume it's sending a mouse position
 (defn maybe-notify-subscribers! [previous-state current-state x y]
   (when (get-in current-state [:subscribers :mice (:client-id current-state) :show-mouse?])
-    (let [previous-info (extract-sub-info current-state x y)
-          current-info (extract-sub-info previous-state x y)]
+    (let [previous-info (extract-sub-info previous-state x y)
+          current-info (extract-sub-info current-state x y)]
       (when-not (= previous-info current-info)
         (sente/send-msg (:sente current-state)
                         [:frontend/mouse-position current-info])))))


fixing tests to use spec directly

fixing tests to use spec directly

--- test/org/libraryweasel/ligature/core_test.clj
+++ test/org/libraryweasel/ligature/core_test.clj
@@ -8,7 +8,8 @@

 (ns org.libraryweasel.ligature.core-test
   (:require [clojure.test :refer :all]
-            [org.libraryweasel.ligature.core :refer :all]))
+            [org.libraryweasel.ligature.core :refer :all]
+            [clojure.spec.alpha :as s]))

 (deftest identifier?-test
   (testing "Common examples"
@@ -38,21 +39,21 @@

 (deftest statement?-test
   (testing "Common examples"
-    (is (statement? ["hello" "world" "triple"]))
-    (is (statement? ["hello" "world" "triple" "graph"]))
-    (is (not (statement? [])))
-    (is (not (statement? ["g"])))
-    (is (not (statement? ["test" "test"])))
-    (is (not (statement? ["test" "test" "g" "h" "e"])))
-    (is (not (statement? [5 3 66 554])))
-    (is (not (statement? ["test" "test" :a])))
-    (is (statement? ["test" :a "test" "test"])))) ; TODO more test cases
+    (is ((s/valid? ::statement ["hello" "world" "triple"])))
+    (is ((s/valid? ::statement ["hello" "world" "triple" "graph"])))
+    (is (not ((s/valid? ::statement []))))
+    (is (not ((s/valid? ::statement ["g"]))))
+    (is (not ((s/valid? ::statement ["test" "test"]))))
+    (is (not ((s/valid? ::statement ["test" "test" "g" "h" "e"]))))
+    (is (not ((s/valid? ::statement [5 3 66 554]))))
+    (is (not ((s/valid? ::statement ["test" "test" :a]))))
+    (is ((s/valid? ::statement ["test" :a "test" "test"]))))) ; TODO more test cases

 (deftest statements?-test
   (testing "Common examples"
-    (is (statements? [["hello" "world" "triple"]]))
-    (is (statements? #{["hello" "world" "triple"]}))
-    (is (statements? '(["hello" "world" "triple"]))))) ; TODO more test cases
+    (is ((s/valid? ::statements [["hello" "world" "triple"]])))
+    (is ((s/valid? ::statements #{["hello" "world" "triple"]})))
+    (is ((s/valid? ::statements '(["hello" "world" "triple"])))))) ; TODO more test cases

 (deftest lang-tag?-test
   (testing "Common examples"


[inbox] Switch away from deprecated component-will-receive-props

--- src/braid/core/client/ui/views/threads.cljs
+++ src/braid/core/client/ui/views/threads.cljs
@@ -62,11 +62,11 @@
          (update-threads! (props :threads))
          (reset! this-elt (r-dom/dom-node this)))

-       :component-will-receive-props
-       (fn [this [_ next-props]]
+       :component-did-update
+       (fn [this [_ prev-props]]
          (when (not= (set (map :id ((r/props this) :threads)))
-                     (set (map :id (next-props :threads))))
-           (update-threads! (next-props :threads))))
+                     (set (map :id (prev-props :threads))))
+           (update-threads! ((r/props this) :threads))))

        :reagent-render
        (fn [{:keys [new-thread-view]}]


add target

add target

--- examples/blog/src/io/perun/example/index.clj
+++ examples/blog/src/io/perun/example/index.clj
@@ -11,9 +11,10 @@
       [:meta {:http-equiv "X-UA-Compatible" :content "IE=edge,chrome=1"}]
       [:meta {:name "viewport" :content "width=device-width, initial-scale=1.0, user-scalable=no"}]]
     [:body
-      [:a {:href "/about.html"} "About Page"]
-      [:a {:href "/feed.rss"} "RSS"]
-      [:a {:href "/atom.xml"} "Atom Feed"]
+      [:ul
+        [:li [:a {:href "/about.html"} "About Page"]]
+        [:li [:a {:href "/feed.rss"} "RSS"]]
+        [:li [:a {:href "/atom.xml"} "Atom Feed"]]]
       [:ul.items.columns.small-12
           (for [post posts]
             [:li


(PUP-10364) Add pp_owner ppRegCertExt OID

In Puppet-as-a-Service use cases it is common for individual nodes to be
owned by various different tenant, or customer, teams. None of the
registered ppRegCertExt OIDs we currently provide cleanly allow generic
specification of an owner in this context.

Provide a new OID, pp_owner, which generically fits this use case.


bug #3735 - fixed broken send and request commands in chat

Signed-off-by: Goran Jovic <fc686822162e6f379ea05b6f92d78d206147085c@gmail.com>

--- src/status_im/chat/events/send_message.cljs
+++ src/status_im/chat/events/send_message.cljs
@@ -35,7 +35,7 @@
 (handlers/register-handler-fx
   :chat-send-message/send-command
   message-model/send-interceptors
-  (fn [cofx [_ params]]
+  (fn [cofx [params]]
     (message-model/send-command cofx params)))

 (handlers/register-handler-fx


Clean up test-util ns form

Clean up test-util ns form

--- src/test/cljc/mikron/runtime/test_util.cljc
+++ src/test/cljc/mikron/runtime/test_util.cljc
@@ -1,8 +1,7 @@
 (ns mikron.runtime.test-util
-  (:require [mikron.runtime.processor.validate :as runtime.processor.validate]
-            [clojure.walk :as walk])
-  #?(:clj (:import [java.util Arrays])))
-
+  (:require [clojure.walk :as walk]
+            [mikron.runtime.processor.validate :as runtime.processor.validate]))
+
 (defn nan?
   "Returns `true` if value is NaN, `false otherwise`."
   [value]


Fix printing of instances in the load balancer action

--- src/circle/backend/action/load_balancer.clj
+++ src/circle/backend/action/load_balancer.clj
@@ -18,7 +18,7 @@
                       :let [az (ec2/get-availability-zone i)]]
                 (lb/ensure-availability-zone lb-name az))
             result (lb/add-instances lb-name instance-ids)]
-        (build-log "added %s to load balancer %s successful" instance-ids lb-name))
+        (build-log "added %s to load balancer %s successful" (str/join ", " instance-ids) lb-name))
       (catch AmazonClientException e
         (println "add-instances:" e)
         {:success false


Finish implementation of get-image-tag in manga reader

--- src/clj/comic_reader/sites/manga_reader.clj
+++ src/clj/comic_reader/sites/manga_reader.clj
@@ -115,8 +115,10 @@
           scrape/fetch-url
           (extract-pages-list chapter-url))))

-  (get-image-data [this page]
-    []))
+  (get-image-data [this {page-url :url}]
+    (-> page-url
+        scrape/fetch-url
+        extract-image-tag)))

 (def manga-reader
   (MangaReader.))


Commented publish println logging

Commented publish println logging

--- src/clj_chrome_devtools/impl/connection.clj
+++ src/clj_chrome_devtools/impl/connection.clj
@@ -25,7 +25,7 @@
         event {:domain domain
                :event event
                :params (:params msg)}]
-    (println "PUBLISH: " event)
+    ;(println "PUBLISH: " event)
     (async/go
       (async/>! event-chan event))))


resource chips aligned to middle in single column

--- src/cljs/swarmpit/component/stack/info.cljs
+++ src/cljs/swarmpit/component/stack/info.cljs
@@ -153,10 +153,11 @@
 (defn- resource-chip
   [name count]
   (when (< 0 count)
-    (comp/chip {:style  {:marginBottom "10px"}
-                :key    name
-                :avatar (comp/avatar {} count)
-                :label  (inflect/pluralize-noun count name)})))
+    (comp/grid
+      {:item true}
+      (comp/chip {:key    name
+                  :avatar (comp/avatar {} count)
+                  :label  (inflect/pluralize-noun count name)}))))

 (defn- add-external-status
   [render-metadata stack-name]
@@ -186,15 +187,20 @@
           (form-services-graph services)))
       (comp/grid
         {:item true
-         :xs   6}
+         :xs   6
+         :style {:display "flex"}}
         (comp/card-content
-          {}
-          (html
-            [:div {:style {:marginTop "15px"}}
-             (resource-chip "network" (count networks))
-             (resource-chip "volume" (count volumes))
-             (resource-chip "config" (count configs))
-             (resource-chip "secret" (count secrets))]))))
+          {:style {:display "flex"}}
+          (comp/grid
+            {:container  true
+             :spacing    8
+             :direction  "column"
+             :justify    "center"
+             :alignItems "flex-start"}
+            (resource-chip "network" (count networks))
+            (resource-chip "volume" (count volumes))
+            (resource-chip "config" (count configs))
+            (resource-chip "secret" (count secrets))))))
     (comp/divider
       {})
     (comp/card-content


fix options formatting

fix options formatting

--- src/clojure/catacumba/handlers/security.clj
+++ src/clojure/catacumba/handlers/security.clj
@@ -99,7 +99,7 @@
                                :child-src :connect-src :font-src :form-action
                                :img-src :media-src :object-src :reflected-xss])
          value (reduce (fn [acc [key value]]
-                         (conj acc (str (name key) value)))
+                         (conj acc (format "%s %s" (name key) value)))
                        [] (seq options'))]
      (assert (pos? (count value)))
      (fn [context]


On EOF, call the child callback caller directly

That description seems like nonsense. It should make a lot more sense if
you look at the diff.

Didn't just call the callback because its normal caller has a ton of
logging and error handling.

This got my echo test working again.

--- src/clojure/frereth_cp/message/to_child.clj
+++ src/clojure/frereth_cp/message/to_child.clj
@@ -641,19 +641,22 @@
           finished (dfrd/deferred)]
       (-> result
           (dfrd/chain (fn [success]
-                        ;; OK, we are getting here
-                        (println "parent-monitor source exhausted")
-                        (throw (ex-info "This can't work"
-                                        {::why "Got here because trigger is closed"
-                                         ::=> "We can't write to it"
-                                         ::so "How do I want to handle this?"}))
-                        (let [my-logs (log2/warn my-logs)]
-                          (strm/put! trigger
-                                     {::result-writer finished
-                                      ::log2/state my-logs
-                                      ::specs/bs-or-eof ::specs/normal})))
+                        (let [my-logs (log2/warn my-logs
+                                                 ::parent-monitor-loop
+                                                 "parent-monitor source exhausted")]
+                          ;; Writing to the from-parent-trigger stream
+                          ;; here seems like the obvious thing to do.
+                          ;; But closing that was the signal that
+                          ;; led us here.
+                          ;; So just call the callback's caller directly.
+                          (trigger-from-parent! io-handle
+                                                buffer
+                                                cb
+                                                {::result-writer finished
+                                                 ::log2/state my-logs
+                                                 ::specs/bs-or-eof ::specs/normal})))
                       (fn [_]
-                        (println "EOF put!")
+                        (println "EOF signalled!")
                         finished)
                       (fn [logs]
                         (log2/flush-logs! logger logs)


Fix function name typo.

Fix function name typo.

--- src/clj/clj_templates/github_data.clj
+++ src/clj/clj_templates/github_data.clj
@@ -36,7 +36,7 @@
     (timbre/info "Getting GitHub readme for " template ". url: " url)
     (http/get url http-opts)))

-(defn clear-temlate-github-info [template]
+(defn clear-template-github-info [template]
   (cond-> (assoc template
             :github-url nil
             :github-id nil)
@@ -54,7 +54,7 @@
                              :content
                              (decode))))
       (do (timbre/warn "Something went wrong when getting github info for template " template ": " (:body star-res))
-          (clear-temlate-github-info template)))))
+          (clear-template-github-info template)))))

 (defn update-templates-github-info [templates]
   (let [{:keys [github-templates non-github-templates]} (group-by-github templates)


rotate not randomize players each turn

rotate not randomize players each turn

--- src/clj/wombats/game/frame/player.clj
+++ src/clj/wombats/game/frame/player.clj
@@ -85,7 +85,7 @@
 (defn resolve-player-turns
   "Updates the arena by applying each players' movement logic"
   [{:keys [players clean-arena] :as game-state}]
-  (let [execution-order (randomize-players players)
+  (let [execution-order (rotate-players players)
         player-decisions (resolve-player-decisions players clean-arena)
         sorted-player-decisions (sort-decisions player-decisions execution-order)
         updated-game-state (reduce (apply-decisions command-map)


extract recalculate-account-item

extract recalculate-account-item

--- src/clj_money/models/transactions.clj
+++ src/clj_money/models/transactions.clj
@@ -507,6 +507,28 @@
                  :transaction-date [:between date (t/today)]} ; TODO: use last partition value
                 {:sort [:transaction-date :index]}))

+(defn- recalculate-account-item
+  "Accepts a processing context and an item, updates
+  the items :index and :balance attributes, and returns
+  the context with the updated :last-index and :last-balance
+  values"
+  [{:keys [account storage] :as context} item]
+  (let [new-index (+ 1 (:last-index context))
+        polarized-amount (accounts/polarize-amount item account)
+        new-balance (+ (:last-balance context)
+                       polarized-amount)
+        changed (update-item-index-and-balance
+                  storage
+                  (assoc item
+                         :index new-index
+                         :balance new-balance))
+        updated (assoc context
+                       :last-index new-index
+                       :last-balance new-balance)]
+    (if changed ; if the index and balance didn't change, we can short circuit the update
+      updated
+      (reduced (dissoc updated :last-balance)))))
+
 (defn- recalculate-account-items
   "Accepts a tuple containing an account-id and a base item,
   selects all subsequent items and recalculates the items until
@@ -517,23 +539,10 @@
   [storage [account-id {:keys [transaction-date]}]]
   (let [account (accounts/find-by-id storage account-id)
         items (account-items-on-or-after storage account-id transaction-date)
-        result (reduce (fn [context item]
-                         (let [new-index (+ 1 (:last-index context))
-                               polarized-amount (accounts/polarize-amount item account)
-                               new-balance (+ (:last-balance context)
-                                              polarized-amount)
-                               changed (update-item-index-and-balance
-                                         storage
-                                         (assoc item
-                                                :index new-index
-                                                :balance new-balance))
-                               updated (assoc context
-                                              :last-index new-index
-                                              :last-balance new-balance)]
-                           (if changed
-                             updated
-                             (reduced (dissoc updated :last-balance)))))
-                       {:last-index 0
+        result (reduce recalculate-account-item
+                       {:account account
+                        :storage storage
+                        :last-index 0
                         :last-balance 0M}
                        items)]
     (when-let [last-balance (:last-balance result)]


refactor for readability

refactor for readability

--- src/clj_money/models/transactions.clj
+++ src/clj_money/models/transactions.clj
@@ -707,12 +707,11 @@
   removed from the transaction and returns
   base items for the affected accounts"
   [{:keys [storage transaction existing] :as context}]
-  (let [dereferenced-items (remove (fn [{existing-item-id :id}]
-                                     (some #(= existing-item-id
-                                               (:id %))
-                                           (:items transaction)))
-                                   (:items existing))
-        base-items (->> dereferenced-items
+  (let [base-items (->> (:items existing)
+                        (remove (fn [{existing-item-id :id}]
+                                  (some #(= existing-item-id
+                                            (:id %))
+                                        (:items transaction))))
                         (map (fn [item]
                                (delete-transaction-item
                                  storage
@@ -763,20 +762,19 @@
 (defn- find-existing-transaction
   "Given a transaction that has been updated, find the existing
   transaction in storage. If none can be found, throw an exception."
-  [{storage :storage
-    {:keys [id
-            transaction-date
-            original-transaction-date]} :transaction
-    :as context}]
+  [storage {:keys [id transaction-date original-transaction-date]}]
   (let [search-date (or original-transaction-date transaction-date)]
-    (assoc context :existing
-           (or (find-by-id storage id search-date)
-               (throw (ex-info
-                        (format "Unable to find transaction with id %s and date %s"
-                                id
-                                search-date)
-                        {:id id
-                         :search-date search-date}))))))
+    (or (find-by-id storage id search-date)
+        (throw (ex-info
+                 (format "Unable to find transaction with id %s and date %s"
+                         id
+                         search-date)
+                 {:id id
+                  :search-date search-date})))))
+
+(defn- assoc-existing-transaction
+  [{:keys [storage transaction] :as context}]
+  (assoc context :existing (find-existing-transaction storage transaction)))

 (defn- recalculate-indexes-and-balances-for-update
   [{:keys [storage base-items] :as context}]
@@ -799,7 +797,7 @@
         (-> {:transaction validated
              :storage storage
              :base-items []}
-            find-existing-transaction
+            assoc-existing-transaction
             process-dereferenced-items
             process-dereferenced-accounts
             process-updated-items


always send canShare when updating workspace acls (#1492)

--- src/cljs/main/broadfcui/page/workspace/summary/acl_editor.cljs
+++ src/cljs/main/broadfcui/page/workspace/summary/acl_editor.cljs
@@ -187,10 +187,10 @@
                              (map #(dissoc % :read-only?))
                              (map #(update % :email clojure.string/trim))
                              (remove (comp empty? :email)))
-           grant-filtered-acl (if (common/access-greater-than-equal-to? (:user-access-level props) "OWNER")
-                                filtered-acl
-                                (map #(dissoc % :canShare) filtered-acl))
-           new-emails (set/difference (set (map :email grant-filtered-acl))
+           ;; grant-filtered-acl (if (common/access-greater-than-equal-to? (:user-access-level props) "OWNER")
+           ;;                     filtered-acl
+           ;;                     (map #(dissoc % :canShare) filtered-acl))
+           new-emails (set/difference (set (map :email filtered-acl))
                                       (:initial-acl-emails @locals))
            fails (->> (:non-project-owner-acl-vec @state) count range
                       (map (partial str "acl-key"))
@@ -203,7 +203,7 @@
            (endpoints/call-ajax-orch
             {:endpoint (endpoints/update-workspace-acl (:workspace-id props) invite-new?)
              :headers ajax/content-type=json
-             :payload grant-filtered-acl
+             :payload filtered-acl
              :on-done (fn [{:keys [success? get-parsed-response]}]
                         (swap! state dissoc :saving?)
                         (if-let [users-not-found (seq (:usersNotFound (get-parsed-response)))]


Make lein resolve-dependencies quieter.

Make lein resolve-dependencies quieter.

--- src/leiningen/resolve_git_version.clj
+++ src/leiningen/resolve_git_version.clj
@@ -2,7 +2,8 @@
   (:require [cemerick.pomegranate.aether :as aether]
             [clojure.pprint :refer [pprint]]
             [leiningen.git-version :as gv])
-  (:import (org.sonatype.aether.transfer ArtifactNotFoundException)))
+  (:import (org.sonatype.aether.transfer ArtifactNotFoundException)
+           (java.util.logging Logger Handler Level)))

 (set! *warn-on-reflection* true)

@@ -28,9 +29,25 @@
       (throw (ex-info "TODO" {:ctime ctime :sha sha} old-exception)))
     (throw (ex-info (str "Not parseable as git-version: " version) {:artifact art} old-exception))))

+(defn with-log-level [level f]
+  (let [handlers (doall (.getHandlers (Logger/getLogger "")))
+        old-levels (doall (map #(.getLevel ^Handler %) handlers))
+        _ (doseq [h handlers] (.setLevel ^Handler h level))
+        result (f)]
+    (dorun (map #(.setLevel ^Handler %1 %2) handlers old-levels))
+    result))
+
+(def null-writer
+  (proxy [java.io.Writer] []
+    (write ([_]) ([_ _ _]))
+    (flush [])
+    (close [])))
+
 (defn try-once-resolve-git-version [project]
   (try
-    (leiningen.core.classpath/resolve-dependencies :dependencies project)
+    (with-log-level Level/OFF
+      #(binding [*err* null-writer]
+         (leiningen.core.classpath/resolve-dependencies :dependencies project)))
     :ok
     (catch Exception e
       ;; lein resolve-dependencies wraps a
@@ -45,6 +62,10 @@
   "Resolves project dependencies like 'lein deps', but also uses TOOL_REPOS_DIR"
   [project & args]

-  (loop []
-    (when-not (= :ok (try-once-resolve-git-version project))
-      (recur))))
+  (try
+    (loop []
+      (when-not (= :ok (try-once-resolve-git-version project))
+        (recur)))
+    (catch clojure.lang.ExceptionInfo e
+      (println "Failed to resolve dependency:" (.getMessage e))
+      (pprint {:exception-data (ex-data e)}))))


[#408] Insert correct db-uri

[#408] Insert correct db-uri

--- backend/src/org/akvo/lumen/admin/add_tenant.clj
+++ backend/src/org/akvo/lumen/admin/add_tenant.clj
@@ -25,6 +25,6 @@
                 "LC_COLLATE = 'en_US.UTF-8' "
                 "LC_CTYPE = 'en_US.UTF-8';")
            tenant)
-    (exec! db-uri "CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public;")
-    (exec! db-uri "CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;")
-    (jdbc/insert! db-uri :tenants {:db_uri db-uri :label label :title title})))
+    (exec! "CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public;")
+    (exec! "CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;")
+    (jdbc/insert! db-uri :tenants {:db_uri tenant-db-uri :label label :title title})))


fix domain test

fix domain test

--- test/src/dda/pallet/dda_serverspec_crate/domain_test.clj
+++ test/src/dda/pallet/dda_serverspec_crate/domain_test.clj
@@ -30,4 +30,4 @@

 (defdatatest should-create-http-configuration [input expected]
   (is (= expected
-         (sut/infra-configuration domain-config-http-test))))
+         (sut/infra-configuration input))))


Add DefaultUncaughtExceptionHandler, closes #3


insights: remove unused transition

insights: remove unused transition

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -146,10 +146,6 @@
     ;; bars exit
     (-> bars-join
         (.exit)
-        (.transition)
-        (.duration 300)
-        (.ease "exp")
-        (.attr "width" 0)
         (.remove))

     ;; y-axis


Remove sentence snapping because of browser incompatibility

--- src/discuss/components/tooltip.cljs
+++ src/discuss/components/tooltip.cljs
@@ -71,14 +71,14 @@
 ;; Selection corrections

 (defn- snap-selection
-  "Selection optimizations. Snaps to a specific pattern. Currently selects the
-  whole sentence, where the selected parts are part of."
+  "Selection optimizations. Snaps to a specific pattern. Currently there are no
+  optimizations available, because there is not browser-independent standard."
   []
   (let [sel (js/document.getSelection)]
     (when (-> sel str count pos?)
-      (.modify sel "move"   "backward" "sentence")
-      (.modify sel "extend" "forward"  "sentence")
-      (.modify sel "extend" "backward" "character")
+      (comment (.modify sel "move"   "backward" "sentence")
+               (.modify sel "extend" "forward"  "sentence")
+               (.modify sel "extend" "backward" "character"))
       sel)))

 (defn- save-selected-text


Getting rid of carmine related error

Getting rid of carmine related error

--- jvm-runner/project.clj
+++ jvm-runner/project.clj
@@ -8,7 +8,7 @@
                  [com.h2database/h2 "1.3.170"] ; In Memory Database
                  [org.xerial/sqlite-jdbc "3.7.15-M1"] ; SQLite
                  [com.novemberain/monger "2.0.0"] ; Monger
-                 [com.taoensso/carmine "2.7.0"] ; Carmine
+                 [com.taoensso/carmine "2.7.0" :exclusions [org.clojure/clojure]] ; Carmine
                  [org.clojure/core.async "0.1.346.0-17112a-alpha"] ; Go-Routines
                  [org.clojure/test.check "0.5.9"] ; Generative Testing
                  [prismatic/schema "0.2.6"] ; Schema Verification


CMR-1297 Adds Atom concept route tests

CMR-1297 Adds Atom concept route tests

--- system-int-test/test/cmr/system_int_test/search/collection_search_format_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_search_format_test.clj
@@ -203,6 +203,13 @@
                               {:url-extension (name format)}))]
           (are [concept] (= (da/collection->expected-atom concept)
                             (dj/parse-json-collection (:body (get-response concept :json))))
+            c1-echo
+            c3-dif
+            c5-iso)
+          (are [concept] (= [(da/collection->expected-atom concept)]
+                            (:entries
+                             (da/parse-atom-result :collection
+                                                   (:body (get-response concept :atom)))))
             c1-echo
             c3-dif
             c5-iso)))


(SERVER-1153) Added an gzip environment_classes integration test

This commit adds another test for the environment_classes middleware
which more explicitly tries to trigger the web server to gzip a very
large response body and validates that the etag roundtripped during the
next request to the server still returns an HTTP 304 (Not Modified)
response.

--- test/integration/puppetlabs/services/master/environment_classes_int_test.clj
+++ test/integration/puppetlabs/services/master/environment_classes_int_test.clj
@@ -4,6 +4,9 @@
             [puppetlabs.kitchensink.core :as ks]
             [puppetlabs.puppetserver.bootstrap-testutils :as bootstrap]
             [puppetlabs.puppetserver.testutils :as testutils]
+            [puppetlabs.trapperkeeper.testutils.webserver :as jetty9]
+            [puppetlabs.services.master.master-core :as master-core]
+            [puppetlabs.services.protocols.jruby-puppet :as jruby]
             [cheshire.core :as cheshire]
             [me.raynes.fs :as fs]))

@@ -55,6 +58,10 @@
         "environment="
         env)
    testutils/ssl-request-options))
+
+(defn response-etag
+  [request]
+  (get-in request [:headers "etag"]))

 (deftest ^:integration environment-classes-integration-test
   (bootstrap/with-puppetserver-running app
@@ -93,7 +100,6 @@
                                           "default_source" "\"is foo\""}]}]}]
                                     "name" "production"}
          initial-response (get-env-classes "production")
-         response-etag #(get-in % [:headers "etag"])
          initial-etag (response-etag initial-response)]
      (testing "initial fetch of environment_classes info is good"
        (is (= 200 (:status initial-response))
@@ -474,3 +480,43 @@
                   (response->class-info-map
                    test-response-after-all-flush))
                "unexpected body for test response")))))))
+
+(deftest ^:integration
+         not-modified-returned-for-environment-class-info-request-with-gzip-tag
+  (testing (str "SERVER-1153 - when the webserver gzips the response "
+                "containing environment_classes etag, the next request "
+                "roundtripping that etag returns an HTTP 304 (Not Modified)")
+    (let [expected-etag "abcd1234"
+          body-length 200000
+          jruby-service (reify jruby/JRubyPuppetService
+                          (get-environment-class-info-tag [_ _]
+                            expected-etag))
+          app (->
+               (fn [_]
+                 (master-core/response-with-etag
+                  (apply str (repeat body-length "a"))
+                  expected-etag))
+               (master-core/wrap-with-etag-check jruby-service))]
+      (jetty9/with-test-webserver
+       app
+       port
+       (let [request-url (str "http://localhost:" port)
+             initial-response (http-client/get request-url {:as :text})
+             response-tag (response-etag initial-response)
+             response-with-tag (http-client/get
+                                request-url
+                                {:headers {"If-None-Match" response-tag}
+                                 :as :text})]
+         (is (= 200 (:status initial-response))
+             "response for initial request is not 'successful'")
+         (is (= (get-in initial-response [:headers "content-encoding"]) "gzip")
+             "response from initial request was not gzipped")
+         (is (= body-length (count (:body initial-response)))
+             "unexpected response body length for initial response")
+         (is (not (empty? response-tag))
+             "no etag returned for initial response")
+         (is (= 304 (:status response-with-tag))
+             (str "request with prior etag did not return http 304 (not "
+                  "modified) status code"))
+         (is (empty? (:body response-with-tag))
+             "unexpected body for request with prior etag"))))))


Rename `:reitit.core/trie-compiler` -> `:reitit.trie/trie-compiler`

--- modules/reitit-core/src/reitit/core.cljc
+++ modules/reitit-core/src/reitit/core.cljc
@@ -79,11 +79,11 @@

   | key                          | description |
   | -----------------------------|-------------|
-  | `:reitit.core/trie-compiler` | Optional trie-compiler."
+  | `:reitit.trie/trie-compiler` | Optional trie-compiler.
   ([compiled-routes]
    (linear-router compiled-routes {}))
   ([compiled-routes opts]
-   (let [compiler (::trie-compiler opts (trie/compiler))
+   (let [compiler (::trie/trie-compiler opts (trie/compiler))
          names (impl/find-names compiled-routes opts)
          [pl nl] (reduce
                    (fn [[pl nl] [p {:keys [name] :as data} result]]
@@ -174,11 +174,11 @@

   | key                          | description |
   | -----------------------------|-------------|
-  | `:reitit.core/trie-compiler` | Optional trie-compiler."
+  | `:reitit.trie/trie-compiler` | Optional trie-compiler.
   ([compiled-routes]
    (trie-router compiled-routes {}))
   ([compiled-routes opts]
-   (let [compiler (::trie-compiler opts (trie/compiler))
+   (let [compiler (::trie/trie-compiler opts (trie/compiler))
          names (impl/find-names compiled-routes opts)
          [pl nl] (reduce
                    (fn [[pl nl] [p {:keys [name] :as data} result]]


Update docstring

Update docstring

--- modules/reitit-ring/src/reitit/ring.cljc
+++ modules/reitit-ring/src/reitit/ring.cljc
@@ -151,13 +151,14 @@
    (defn create-resource-handler
      "A ring handler for serving classpath resources, configured via options:

-     | key              | description |
-     | -----------------|-------------|
-     | :parameter       | optional name of the wildcard parameter, defaults to unnamed keyword `:`
-     | :root            | optional resource root, defaults to `\"public\"`
-     | :path            | optional path to mount the handler to. Works only if mounted outside of a router.
-     | :loader          | optional class loader to resolve the resources
-     | :index-files     | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`"
+     | key                | description |
+     | -------------------|-------------|
+     | :parameter         | optional name of the wildcard parameter, defaults to unnamed keyword `:`
+     | :root              | optional resource root, defaults to `\"public\"`
+     | :path              | optional path to mount the handler to. Works only if mounted outside of a router.
+     | :loader            | optional class loader to resolve the resources
+     | :index-files       | optional vector of index-files to look in a resource directory, defaults to `[\"index.html\"]`
+     | :not-found-handler | optional handler function to use if the requested resource is missing (404 Not Found)"
      ([]
       (create-resource-handler nil))
      ([{:keys [parameter root path loader allow-symlinks? index-files paths not-found-handler]


Version 0.1.1-SNAPSHOT

Version 0.1.1-SNAPSHOT

--- metlog-agent/project.clj
+++ metlog-agent/project.clj
@@ -1,4 +1,4 @@
-(defproject metlog-agent "0.1.0"
+(defproject metlog-agent "0.1.1-SNAPSHOT"
   :description "Metlog agent - polls data sources for upload to vault."

   :license {:name "Eclipse Public License"


The stop-fn of webserver component has been updated

--- http/src/clj/hellhound/components/webserver.clj
+++ http/src/clj/hellhound/components/webserver.clj
@@ -48,11 +48,10 @@
 (defn stop!
   "Stops the running webserver server."
   [this]
-  (if (:instance this)
-    (do
-      (.close (:instance this))
-      (dissoc this :instance))
-    this))
+  (when-let [server (:instance this)]
+    (.close server))
+  (dissoc this :instance))
+

 (def default-hooks


Add missing table components for reakit

Add missing table components for reakit

--- workspaces/src/com/wsscode/fulcro/ui/reakit.cljs
+++ workspaces/src/com/wsscode/fulcro/ui/reakit.cljs
@@ -65,6 +65,14 @@
 (def step-show (uc/wrap-react-component-localized rk/StepShow))
 (def step-toggle (uc/wrap-react-component-localized rk/StepToggle))
 (def table (uc/wrap-react-component-localized rk/Table))
+(def table-body (uc/wrap-react-component-localized rk/Table.Body))
+(def table-caption (uc/wrap-react-component-localized rk/Table.Caption))
+(def table-cell (uc/wrap-react-component-localized rk/Table.Cell))
+(def table-column (uc/wrap-react-component-localized rk/Table.Column))
+(def table-columngroup (uc/wrap-react-component-localized rk/Table.ColumnGroup))
+(def table-foot (uc/wrap-react-component-localized rk/Table.Foot))
+(def table-head (uc/wrap-react-component-localized rk/Table.Head))
+(def table-row (uc/wrap-react-component-localized rk/Table.Row))
 (def tabs (uc/wrap-react-component-localized rk/Tabs))
 (def tabs-container (uc/wrap-react-component-localized rk/TabsContainer))
 (def tabs-next (uc/wrap-react-component-localized rk/TabsNext))


rhs-delete now remembers joins

rhs-delete now remembers joins

--- dada2-core/src/test/clojure/org/dada2/test_join_model.clj
+++ dada2-core/src/test/clojure/org/dada2/test_join_model.clj
@@ -160,18 +160,17 @@
     ))

 ;;; TODO - ugly, slow, ...
-(defn- rhs-delete [old-indeces i rhs-pk-key rhs-fk-key lhs-fk-keys rhs join-fn join-pk joined-model]
+(defn- rhs-delete [[lhs-indeces old-rhs-indeces old-joins]
+		   i rhs-pk-key rhs-fk-key lhs-fk-keys rhs join-fn join-pk joined-model]
   (let [fk (rhs-fk-key rhs)
-	old-rhs-indeces (second old-indeces)
-	lhs-indeces (first old-indeces)
 	lhses (lhses-get lhs-indeces i fk)
-	old-joins (mapcat (fn [lhs] (derive-joins old-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
-	new-indeces (rhs-dissoc old-indeces i rhs-pk-key fk rhs)
-	new-rhs-indeces (second new-indeces)
-	new-joins (mapcat (fn [lhs] (derive-joins new-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
-	joins (remove (fn [i] (contains? (apply hash-set new-joins) i)) old-joins)
+	old-joins2 (mapcat (fn [lhs] (derive-joins old-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
+	new-rhs-indeces (rhs-dissoc-2 old-rhs-indeces i rhs-pk-key fk rhs)
+	new-joins2 (mapcat (fn [lhs] (derive-joins new-rhs-indeces lhs-fk-keys lhs join-fn)) lhses)
+	joins (remove (fn [i] (contains? (apply hash-set new-joins2) i)) old-joins2)
+	new-joins (reduce (fn [old-joins join] (dissoc old-joins (join-pk join))) old-joins joins)
 	]
-    [new-indeces (fn [_] (on-deletes joined-model joins))]
+    [[lhs-indeces new-rhs-indeces new-joins] (fn [_] (on-deletes joined-model joins))]
     ))

 ;;; TODO
@@ -303,30 +302,30 @@
 	  [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
 	  }
 	  ] (data join)))
-      (is (=
-	   {
+    (is (=
+	 {
+	 [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [0 0 0] "b1-data" "c1-data")
+	 [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
+	 }
+	 (data joined-model)))
+
+    ;; join - new rhs - c2
+    (on-upsert cs c2)
+    (is (= [[{:b {:a1 a1}}{:c {:a1 a1}}]
+	    [{:b {:b1 b1 :b2 b2}} {:c {:c1 c1 :c2 c2}}]
+	    {
+	    [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [0 0 0] "b1-data" "c1-data")
+	    [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
+	    [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [0 0 0] "b1-data" "c2-data")
+	    [:a1 :b2 :c2] (->ABC [:a1 :b2 :c2] [0 0 0] "b2-data" "c2-data")
+	    }] (data join)))
+    (is (= {
 	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [0 0 0] "b1-data" "c1-data")
 	   [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
+	   [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [0 0 0] "b1-data" "c2-data")
+	   [:a1 :b2 :c2] (->ABC [:a1 :b2 :c2] [0 0 0] "b2-data" "c2-data")
 	   }
 	   (data joined-model)))
-
-    ;; join - new rhs - c2
-    (on-upsert cs c2)
-      (is (= [[{:b {:a1 a1}}{:c {:a1 a1}}]
-	      [{:b {:b1 b1 :b2 b2}} {:c {:c1 c1 :c2 c2}}]
-	      {
-	      [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [0 0 0] "b1-data" "c1-data")
-	      [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
-	      [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [0 0 0] "b1-data" "c2-data")
-	      [:a1 :b2 :c2] (->ABC [:a1 :b2 :c2] [0 0 0] "b2-data" "c2-data")
-	      }] (data join)))
-      (is (= {
-	     [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [0 0 0] "b1-data" "c1-data")
-    	     [:a1 :b2 :c1] (->ABC [:a1 :b2 :c1] [0 0 0] "b2-data" "c1-data")
-    	     [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [0 0 0] "b1-data" "c2-data")
-    	     [:a1 :b2 :c2] (->ABC [:a1 :b2 :c2] [0 0 0] "b2-data" "c2-data")
-    	     }
-    	     (data joined-model)))

     ;; join - new lhs - a2
     (on-upsert as a2)
@@ -459,26 +458,32 @@
     	   }
     	   (data joined-model)))

-    ;; ;; join - delete rhs - b2
-    ;; (on-delete bs b2)
-    ;; (is (= [[{:b {:a1 a1v1}} {:c {:a1 a1v1}}]
-    ;; 	    [{:b {:b1 b1v1}} {:c {:c1 c1v1 :c2 c2}}]
-    ;; 	    {}] (data join)))
-    ;; (is (= {
-    ;; 	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
-    ;; 	   [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [1 1 0] "b1v1-data" "c2-data")
-    ;; 	   }
-    ;; 	   (data joined-model)))
-
-    ;; ;; join - delete rhs - c2
-    ;; (on-delete cs c2)
-    ;; (is (= [[{:b {:a1 a1v1}}{:c {:a1 a1v1}}]
-    ;; 	    [{:b {:b1 b1v1}} {:c {:c1 c1v1}}]
-    ;; 	    {}] (data join)))
-    ;; (is (= {
-    ;; 	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
-    ;; 	   }
-    ;; 	   (data joined-model)))
+    ;; join - delete rhs - b2
+    (on-delete bs b2)
+    (is (= [[{:b {:a1 a1v1}} {:c {:a1 a1v1}}]
+    	    [{:b {:b1 b1v1}} {:c {:c1 c1v1 :c2 c2}}]
+    	    {
+	    [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
+	    [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [1 1 0] "b1v1-data" "c2-data")
+	    }
+	    ] (data join)))
+    (is (= {
+    	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
+    	   [:a1 :b1 :c2] (->ABC [:a1 :b1 :c2] [1 1 0] "b1v1-data" "c2-data")
+    	   }
+    	   (data joined-model)))
+
+    ;; join - delete rhs - c2
+    (on-delete cs c2)
+    (is (= [[{:b {:a1 a1v1}}{:c {:a1 a1v1}}]
+    	    [{:b {:b1 b1v1}} {:c {:c1 c1v1}}]
+    	    {
+	    [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
+	    }] (data join)))
+    (is (= {
+    	   [:a1 :b1 :c1] (->ABC [:a1 :b1 :c1] [1 1 1] "b1v1-data" "c1v1-data")
+    	   }
+    	   (data joined-model)))

     ;; TODO:
     ;;  amend in/out


Continue mapping Ableton Push.

Continue mapping Ableton Push.

--- src/afterglow/controllers/ableton_push.clj
+++ src/afterglow/controllers/ableton_push.clj
@@ -62,41 +62,86 @@
   {:off 0 :dim 1 :dim-slow-blink 2 :dim-fast-blink 3
    :bright 4 :bright-slow-blink 5 :bright-fast-blink 6})

+(def color-button-colors
+  "The control values and modes for a labeled button which changes
+  color. These are added to the monocrome states (except for off)
+  to obtain the color and brightness/behavior."
+  {:red 0 :amber 6 :yellow 12 :green 18})
+
 (def control-buttons
   "The labeled buttons which send and respond to Control Change
   events."
-  {:tap-tempo {:control 3 :states monochrome-button-states}
-   :metronome {:control 9 :states monochrome-button-states}
-   :left-arrow {:control 44 :states monochrome-button-states}
-   :right-arrow {:control 45 :states monochrome-button-states}
-   :up-arrow {:control 46 :states monochrome-button-states}
-   :down-arrow {:control 47 :states monochrome-button-states}
-   :select {:control 48 :states monochrome-button-states}
-   :shift {:control 49 :states monochrome-button-states}
-   :note {:control 50 :states monochrome-button-states}
-   :session {:control 51 :states monochrome-button-states}
-   :add-device {:control 52 :states monochrome-button-states}
-   :add-track {:control 53 :states monochrome-button-states}
-   :octave-down {:control 54 :states monochrome-button-states}
-   :octave-up {:control 55 :states monochrome-button-states}
-   :repeat {:control 56 :states monochrome-button-states}
-   :accent {:control 57 :states monochrome-button-states}
-   :scales {:control 58 :states monochrome-button-states}
-   :user-mode {:control 59 :states monochrome-button-states}
-   :mute {:control 60 :states monochrome-button-states}
-   :solo {:control 61 :states monochrome-button-states}
-   :in {:control 62 :states monochrome-button-states}
-   :out {:control 63 :states monochrome-button-states}
+  {:tap-tempo {:control 3 :kind :monochrome}
+   :metronome {:control 9 :kind :monochrome}

-   :play {:control 85 :states monochrome-button-states}
-   :record {:control 86 :states monochrome-button-states}
-   :new {:control 87 :states monochrome-button-states}
-   :duplicate {:control 88 :states monochrome-button-states}
-   :automation {:control 89 :states monochrome-button-states}
-   :fixed-length {:control 90 :states monochrome-button-states}
+   :master {:control 28 :kind :monochrome}
+   :stop   {:control 29 :kind :monochrome}

+   :quarter               {:control 36 :kind :color}
+   :quarter-triplet       {:control 37 :kind :color}
+   :eighth                {:control 38 :kind :color}
+   :eighth-triplet        {:control 39 :kind :color}
+   :sixteenth             {:control 40 :kind :color}
+   :sixteenth-triplet     {:control 41 :kind :color}
+   :thirty-second         {:control 42 :kind :color}
+   :thirty-second-triplet {:control 43 :kind :color}

+   :left-arrow  {:control 44 :kind :monochrome}
+   :right-arrow {:control 45 :kind :monochrome}
+   :up-arrow    {:control 46 :kind :monochrome}
+   :down-arrow  {:control 47 :kind :monochrome}
+
+   :select      {:control 48 :kind :monochrome}
+   :shift       {:control 49 :kind :monochrome}
+   :note        {:control 50 :kind :monochrome}
+   :session     {:control 51 :kind :monochrome}
+   :add-device  {:control 52 :kind :monochrome}
+   :add-track   {:control 53 :kind :monochrome}
+
+   :octave-down {:control 54 :kind :monochrome}
+   :octave-up   {:control 55 :kind :monochrome}
+   :repeat      {:control 56 :kind :monochrome}
+   :accent      {:control 57 :kind :monochrome}
+   :scales      {:control 58 :kind :monochrome}
+   :user-mode   {:control 59 :kind :monochrome}
+   :mute        {:control 60 :kind :monochrome}
+   :solo        {:control 61 :kind :monochrome}
+   :in          {:control 62 :kind :monochrome}
+   :out         {:control 63 :kind :monochrome}
+
+   :play         {:control 85 :kind :monochrome}
+   :record       {:control 86 :kind :monochrome}
+   :new          {:control 87 :kind :monochrome}
+   :duplicate    {:control 88 :kind :monochrome}
+   :automation   {:control 89 :kind :monochrome}
+   :fixed-length {:control 90 :kind :monochrome}
+
+   :device-mode   {:control 110 :kind :monochrome}
+   :browse-mode   {:control 111 :kind :monochrome}
+   :track-mode    {:control 112 :kind :monochrome}
+   :clip-mode     {:control 113 :kind :monochrome}
+   :volume-mode   {:control 114 :kind :monochrome}
+   :pan-send-mode {:control 115 :kind :monochrome}
+
+   :quantize {:control 116 :kind :monochrome}
+   :double   {:control 117 :kind :monochrome}
+   :delete   {:control 118 :kind :monochrome}
+   :undo     {:control 119 :kind :monochrome}
+
    })
+
+(defn set-button-state
+  "Set one of the labeled buttons to a particular state, and, if
+  supported, color."
+  ([button state]
+   (set-button-state button state :amber))
+  ([button state color]
+   (let [base-value ((keyword state) monochrome-button-states)
+         color-shift (or (when (= (:kind button) :color)
+                           ((keyword color) color-button-colors))
+                         0)]
+     (midi/midi-control @user-port-out (:control button)
+                        (+ base-value color-shift)))))

 (defn set-display-line
   "Sets a line of the text display."
@@ -122,20 +167,19 @@
           y (range 8)]
     (set-pad-color x y (com.evocomputing.colors/create-color :pink #_:black)))
   (doseq [[k button] control-buttons]
-    (midi/midi-control @user-port-out (:control button)
-                       (get-in button [:states :bright-fast-blink #_:off]))))
+    (set-button-state button :bright-fast-blink :green)))
+

 (defn connect-to-push
   "Try to establish the connection to the Ableton Push, if that has
   not already been made, initialize the display, and start the UI
   updater thread. Since SysEx messages are required for updating the
   display, assumes that if you are on a Mac, you have installed
-  [osxmidi4j](https://github.com/locurasoft/osxmidi4j) to provide a
-  working implementation. You probably want that anyway so you can
-  live-plug your MIDI interfaces."
+  [mmj](http://www.humatic.de/htools/mmj.htm) to provide a
+  working implementation."
   {:doc/format :markdown}
   [& {:keys [prefix] :or {prefix (when (re-find #"Mac" (System/getProperty "os.name"))
-                                   "CoreMidi - ")}}]
+                                   "Ableton Push - ")}}]
   (swap! user-port-out #(or % (midi/midi-out (str prefix "User Port"))))
   (swap! live-port-out #(or % (midi/midi-out (str prefix "Live Port"))))
   (clear-interface))


Rename function for clarity

Rename function for clarity

--- src/io/aviso/twixt/memory_cache.clj
+++ src/io/aviso/twixt/memory_cache.clj
@@ -21,7 +21,7 @@
           (swap! cache assoc asset-path asset)
           asset)))))

-(defn check-validity
+(defn- modified-at-matches?
   "Returns true if the resource is valid (actual modified-at matches the provided value from the asset map).

   Also returns true if the modified-at is nil (meaning the file is inside a JAR, not on the filesystem)."
@@ -37,12 +37,12 @@
   (cond
     (nil? asset) false
     ;; Non-compiled assets may have no :dependencies key, so use the standard keys
-    (nil? (:dependencies asset)) (check-validity (:resource-path asset) (:modified-at asset))
+    (nil? (:dependencies asset)) (modified-at-matches? (:resource-path asset) (:modified-at asset))
     ;; Compiled assets will have :dependencies that include the original resource.
     ;; Keys are the resource path, values are a map with keys :modified-at and :checksum
     :else (every?
             (fn [[resource-path {:keys [modified-at]}]]
-              (check-validity resource-path modified-at))
+              (modified-at-matches? resource-path modified-at))
             (:dependencies asset))))

 (defn wrap-with-invalidating-cache


fix ai move calculation bug

fix ai move calculation bug

--- src/clj/battlebots/game/step_operators.clj
+++ src/clj/battlebots/game/step_operators.clj
@@ -10,9 +10,9 @@
             [battlebots.arena.utils :as au]))

 (defn- calculate-ai-move
-  [[x y] arena]
+  [[x y] {:keys [dirty-arena] :as game-state}]
   ;; TODO Add bot movement logic
-  arena)
+  game-state)

 (defn- apply-ai-decision
   [{:keys [dirty-arena] :as game-state} ai-uuid]
@@ -20,7 +20,7 @@
         ai-bot (au/get-item bot-coords dirty-arena)
         is-current-ai-bot? (= ai-uuid (:uuid ai-bot))]
     (if is-current-ai-bot?
-      (calculate-ai-move bot-coords dirty-arena)
+      (calculate-ai-move bot-coords game-state)
       game-state)))

 (defn- get-ai-bots


Trying to get the request-id back to browser

So it can figure out which world it's being told about

--- src/clj/com/frereth/web/routes/websock.clj
+++ src/clj/com/frereth/web/routes/websock.clj
@@ -36,6 +36,8 @@

 (declare make-channel-socket reset-web-socket-handler!)
 (s/defrecord WebSockHandler [ch-sock :- (s/maybe channel-socket)
+                             ;; In a lot of ways, this needs to be a map
+                             ;; for handling multiple connections
                              frereth-server
                              ws-controller :- (s/maybe fr-skm/async-channel)
                              ws-stopper :- (s/maybe (s/=> s/Any))]
@@ -126,10 +128,12 @@
 (s/defn initiate-auth!
   [this :- WebSockHandler
    ev-msg]
-  (log/debug "Initial connection to AUTH on server")
+  (comment (log/debug "Initiating AUTH on server based on:\n" (keys ev-msg)
+                      "\nEvent: " (:event ev-msg)
+                      "\nData: " (:?data ev-msg)))
   (async/thread
     (let [cpt (-> this :frereth-server :connection-manager)]
-      (if-let [responder (con-man/initiate-handshake cpt 5 2000)]
+      (if-let [responder (con-man/initiate-handshake cpt (:?data ev-msg) 5 2000)]
         (let [response-chan (:respond responder)
               [v c] (async/alts!! [response-chan (async/timeout 1000)])]
           (if v
@@ -279,7 +283,7 @@
                        (when-not (= event :chsk/ws-ping)
                          ;; Handle it, but don't log about it: this happens far too often
                          ;; to spam the logs with the basic fact
-                         (log/debug "Message to handle:\n" (util/pretty v))))
+                         (log/debug "Message to handle:\n" (util/pretty (select-keys v [:client-id :connected-uids :uid :event])))))
                      (try
                        (handle-ws-event-loop-msg {:ch ch
                                                   :rcvr rcvr


remove nrepl-select checking if a client is connected

equally confusing errors and prevents calling nrepl-select
directly after watch since the client will have had no time
to connect.

--- src/main/shadow/cljs/devtools/api.clj
+++ src/main/shadow/cljs/devtools/api.clj
@@ -259,9 +259,6 @@
       (nil? worker)
       [:no-worker id]

-      (not (repl-client-connected? worker))
-      [:no-client id "Make sure your JS environment has loaded your compiled ClojureScript code."]
-
       :else
       (do (set! *nrepl-cljs* id)


Code cleanup

Code cleanup

cleanup

--- src/webapp/framework/client/coreclient.cljs
+++ src/webapp/framework/client/coreclient.cljs
@@ -1162,33 +1162,33 @@
         )

      (let [
-           ui-state         (get @data-window-atom  :ui-state)
-           view-start       (:start @data-window-atom)
-           view-end         (:end @data-window-atom)
-
-           data-source      (:data-source data-window-key)
-           full-path        (:full-path data-window-key)
-           ui-full-path     (conj full-path  :values)
-
-           value-path   (conj full-path :values)
-           count-path   (conj full-path :count)
-           end-path     (conj full-path :end)
-           start-path   (conj full-path :start)
-           order-path   (conj full-path :order)
-
-           rel-path         (get data-window-key :relative-path)
-           rel-value-path   (conj rel-path :values)
-           rel-count-path   (conj rel-path :count)
-           rel-end-path     (conj rel-path :end)
-           rel-start-path   (conj rel-path :start)
-           rel-order-path   (conj rel-path :order)
-           rel-touch-path   (conj rel-path :touch)
-
-           data-query-atom  (get @client-query-cache query-key)
-           query-start      (:start @data-query-atom)
-           query-end        (:end @data-query-atom)
-           query-count      (if (:count @data-query-atom) (:count @data-query-atom) 0)
-           end-marker       (min view-end query-count)
+           ui-state            (get @data-window-atom  :ui-state)
+           data-window-start   (:start @data-window-atom)
+           data-window-end     (:end @data-window-atom)
+
+           data-source         (:data-source data-window-key)
+           full-path           (:full-path data-window-key)
+           ui-full-path        (conj full-path  :values)
+
+           value-path          (conj full-path :values)
+           count-path          (conj full-path :count)
+           end-path            (conj full-path :end)
+           start-path          (conj full-path :start)
+           order-path          (conj full-path :order)
+
+           rel-path            (get data-window-key :relative-path)
+           rel-value-path      (conj rel-path :values)
+           rel-count-path      (conj rel-path :count)
+           rel-end-path        (conj rel-path :end)
+           rel-start-path      (conj rel-path :start)
+           rel-order-path      (conj rel-path :order)
+           rel-touch-path      (conj rel-path :touch)
+
+           data-query-atom     (get @client-query-cache query-key)
+           query-start         (:start @data-query-atom)
+           query-end           (:end @data-query-atom)
+           query-count         (if (:count @data-query-atom) (:count @data-query-atom) 0)
+           end-marker          (min data-window-end  query-count)

            ui-list-of-records     (into
                                    {}
@@ -1206,21 +1206,16 @@
                                                       ]
                                                  {record-id {:pos    record-position
                                                              :value  (if record  @(get @record :value)        {})}}))
-                                             (range view-start (inc end-marker))))))
-
-
-           ui-order-of-records  ;(into
-                                 ;{}
-                                 ;(map (fn[e] (first e))
-                                      (into {}
-                                          (map
-                                           (fn [record-position]
-
-                                             (let [ record-id      (get  (get @data-query-atom :values) record-position) ]
-                                               {   record-position  record-id } ))
-                                           (range view-start (inc end-marker)))
-                                          )
-                                          ;)))
+                                             (range data-window-start (inc end-marker))))))
+
+
+           ui-order-of-records        (into {}
+                                            (map
+                                             (fn [record-position]
+
+                                               (let [ record-id      (get  (get @data-query-atom :values) record-position) ]
+                                                 {   record-position  record-id } ))
+                                             (range data-window-start (inc end-marker))))

            ]


Fix prepare test.

Fix prepare test.

--- test/onyx/log/prepare_join_cluster_test.clj
+++ test/onyx/log/prepare_join_cluster_test.clj
@@ -66,6 +66,7 @@
   (fact reactions => nil))

 (let [old-replica {:messaging {:onyx.messaging/impl :dummy-messenger}
+                   :job-scheduler :onyx.job-scheduler/greedy
                    :peers [:a]}
       new-replica (f old-replica)
       diff (rep-diff old-replica new-replica)