[#246] Assign original value when :as is used

--- priv/clojure/core.clj
+++ priv/clojure/core.clj
@@ -3599,8 +3599,11 @@
         pb (fn pb [bvec b v]
              (let [pvec
                    (fn [bvec b val]
-                     (let [gvec (gensym "vec__")]
-                       (loop [ret (-> bvec (conj gvec) (conj val))
+                     (let [gvec (gensym "vec__")
+                           gvec-orig (gensym "vec__")]
+                       (loop [ret (-> bvec
+                                      (conj gvec) (conj val)
+                                      (conj gvec-orig) (conj gvec))
                               n 0
                               bs b
                               seen-rest? false]
@@ -3611,7 +3614,7 @@
                                                     n
                                                     (nnext bs)
                                                     true)
-                               (= firstb :as) (pb ret (second bs) gvec)
+                               (= firstb :as) (pb ret (second bs) gvec-orig)
                                :else (if seen-rest?
                                        (throw "Unsupported binding form, only :as can follow & parameter")
                                        (recur (if (zero? n)


Fix indentation and style

Fix indentation and style

--- src/reagent/impl/template.cljs
+++ src/reagent/impl/template.cljs
@@ -107,7 +107,8 @@
 ;; <input type="??" >
 ;; The properites 'selectionStart' and 'selectionEnd' only exist on some inputs
 ;; See: https://html.spec.whatwg.org/multipage/forms.html#do-not-apply
-(def these-inputs-have-selection-api #{"text" "textarea" "password" "search" "tel" "url"})
+(def these-inputs-have-selection-api #{"text" "textarea" "password" "search"
+                                       "tel" "url"})

 (defn ^boolean has-selection-api?
   [input-type]
@@ -115,45 +116,45 @@

 (defn input-set-value [this]
   (when-some [value ($ this :cljsInputValue)]
-             ($! this :cljsInputDirty false)
-             (let [node       (find-dom-node this)
-                   node-value ($ node :value)]
-               (when (not= value node-value)
-                 (if-not (and (identical? node (.-activeElement js/document))
-                              (has-selection-api? ($ node :type))
-                              (string? value)
-                              (string? node-value))
-                   ; just set the value, no need to worry about a cursor
-                   ($! node :value value)
-
-                   ;; Setting "value" (below) moves the cursor position to the
-                   ;; end which gives the user a jarring experience.
-                   ;;
-                   ;; But repositioning the cursor within the text, turns out to
-                   ;; be quite a challenge because changes in the text can be
-                   ;; triggered by various events like:
-                   ;; - a validation function rejecting a user inputted char
-                   ;; - the user enters a lower case char, but is transformed to
-                   ;;   upper.
-                   ;; - the user selects multiple chars and deletes text
-                   ;; - the user pastes in multiple chars, and some of them are
-                   ;;   rejected by a validator.
-                   ;; - the user selects multiple chars and then types in a
-                   ;;   single new char to repalce them all.
-                   ;; Coming up with a sane cursor repositioning strategy hasn't
-                   ;; been easy ALTHOUGH in the end, it kinda fell out nicely,
-                   ;; and it appears to sanely handle all the cases we could
-                   ;; think of.
-                   ;; So this is just a warning.  The code below is simple
-                   ;; enough, but if you are tempted to change it, be aware of
-                   ;; all the scenarios you have handle.
-                   (let [existing-offset-from-end (- (count node-value)
-                                                     ($ node :selectionStart))
-                         new-cursor-offset        (- (count value)
-                                                     existing-offset-from-end)]
-                     ($! node :value value)
-                     ($! node :selectionStart new-cursor-offset)
-                     ($! node :selectionEnd   new-cursor-offset)))))))
+    ($! this :cljsInputDirty false)
+    (let [node       (find-dom-node this)
+          node-value ($ node :value)]
+      (when (not= value node-value)
+        (if-not (and (identical? node ($ js/document :activeElement))
+                     (has-selection-api? ($ node :type))
+                     (string? value)
+                     (string? node-value))
+          ;; just set the value, no need to worry about a cursor
+          ($! node :value value)
+
+          ;; Setting "value" (below) moves the cursor position to the
+          ;; end which gives the user a jarring experience.
+          ;;
+          ;; But repositioning the cursor within the text, turns out to
+          ;; be quite a challenge because changes in the text can be
+          ;; triggered by various events like:
+          ;; - a validation function rejecting a user inputted char
+          ;; - the user enters a lower case char, but is transformed to
+          ;;   upper.
+          ;; - the user selects multiple chars and deletes text
+          ;; - the user pastes in multiple chars, and some of them are
+          ;;   rejected by a validator.
+          ;; - the user selects multiple chars and then types in a
+          ;;   single new char to repalce them all.
+          ;; Coming up with a sane cursor repositioning strategy hasn't
+          ;; been easy ALTHOUGH in the end, it kinda fell out nicely,
+          ;; and it appears to sanely handle all the cases we could
+          ;; think of.
+          ;; So this is just a warning. The code below is simple
+          ;; enough, but if you are tempted to change it, be aware of
+          ;; all the scenarios you have handle.
+          (let [existing-offset-from-end (- (count node-value)
+                                            ($ node :selectionStart))
+                new-cursor-offset        (- (count value)
+                                            existing-offset-from-end)]
+            ($! node :value value)
+            ($! node :selectionStart new-cursor-offset)
+            ($! node :selectionEnd   new-cursor-offset)))))))

 (defn input-handle-change [this on-change e]
   (let [res (on-change e)]


cleaned up spaces

cleaned up spaces

--- src/reagent_search/search.cljs
+++ src/reagent_search/search.cljs
@@ -6,7 +6,6 @@
             [reagent-search.utils :as utils]))

 ;;; autocomplete panel
-
 (defn- autocomplete-item
   "renders a single autocomplete item in list"
   [chan-selecteditems item]


Make sure handler-sym namespace is loaded.

--- src/containium/http_kit.clj
+++ src/containium/http_kit.clj
@@ -98,7 +98,8 @@
   [{:keys [name project] :as box}]
   (println "Adding ring handler in module" name "...")
   (let [ring-conf (clean-ring-conf (-> project :containium :ring))
-        handler-fn @(boxure/eval box (:handler-sym ring-conf))]
+        handler-fn @(boxure/eval box `(do (require '~(symbol (namespace (:handler-sym ring-conf))))
+                                          ~(:handler-sym ring-conf)))]
     (swap! apps assoc name (RingApp. box handler-fn ring-conf))
     (make-app)
     (println "Ring handler for module" name "added, in context:"


added enumeration option

added enumeration option

--- src/crawler/test_system.clj
+++ src/crawler/test_system.clj
@@ -62,11 +62,11 @@
      (if verbose
        (pmap
         (fn [{url :url xpath :xpath}]
-          (extractor/process-link url))
+          (extractor/process-link url {}))
         *enumerate-positives*)
        (pmap
         (fn [{url :url xpath :xpath}]
-          (let [ranked-enums (extractor/process-link url)
+          (let [ranked-enums (extractor/process-link url {})
                 xpaths       (map #(-> % :xpath) ranked-enums)]
             (.indexOf xpaths xpath)))
         *enumerate-positives*))))
@@ -89,7 +89,9 @@
                               :cosine-sim          (page/signature-similarity-cosine
                                                     signature expl-sign)
                               :cosine-weighted-sim (page/signature-similarity-weighted-cosine
-                                                    signature expl-sign weights-table)})
+                                                    signature expl-sign weights-table)
+                              :cardinality-sim     (page/signature-similarity-cardinality
+                                                    signature expl-sign)})
                           xpath-explorations))
                        explorations))})
    *enumerate-positives*))
@@ -109,6 +111,21 @@
                                 ["--similarity-test"
                                  "Test similarity routines"
                                  :flag true
+                                 :default false]
+
+                                ["--enumeration-test"
+                                 "Test enumeration routine"
+                                 :flag true
+                                 :default false]
+
+                                ["-v" "--verbose"
+                                 "Verbose version"
+                                 :flag true
                                  :default false])]
+
     (when (:similarity-test optional)
-      (clojure.pprint/pprint (test-similarity)))))
+      (clojure.pprint/pprint (test-similarity)))
+
+    (when (:enumeration-test optional)
+      (clojure.pprint/pprint (test-enumeration
+                              {:verbose (optional :verbose)})))))


Save current statement on click

Save current statement on click

--- src/discuss/references.cljs
+++ src/discuss/references.cljs
@@ -66,7 +66,9 @@
             author (:author data)]
         (dom/div #js {:className "bs-callout bs-callout-info"}
                  (dom/a #js {:href    "javascript:void(0)"
-                             :onClick #(lib/change-view! :reference-agree-disagree)}
+                             :onClick (fn [_]
+                                        (lib/save-selected-statement! data)
+                                        (lib/change-view! :reference-agree-disagree))}
                         (dom/strong nil (:text statement)))
                  (dom/div nil "Issue: " (:title issue))
                  (dom/div nil "Author: " (:nickname author)))))))


render a basic triangle

render a basic triangle

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -18,16 +18,25 @@
     (.rect x y 1 1)
     (.fill)))

-(defn paint [canvas-id size]
+(defn next-row [modulus row]
+  (vec (for [x (range 0 (inc (count row)))]
+         (let [before (nth row (dec x) 0)
+               above (nth row x 0)]
+           (mod (+ before above) modulus)))))
+
+(defn sieve [initial-state modulus]
+  (iterate (partial next-row modulus) (vec initial-state)))
+
+(defn paint [canvas-id size sieve]
   (when-let [canvas-element (. js/document getElementById canvas-id)]
     (when-let [ctx (.getContext canvas-element "2d")]
       (do
         (set! (.-fillStyle ctx) "black")
         (.fillRect ctx 0 0 size size)
         (set! (.-fillStyle ctx) "white")
-        (doseq [x (range 100)
-                y (range 10)]
-          (put-pixel ctx x y))))))
+        (doseq [x (range (count sieve)) y (range (count sieve))]
+          (if (odd? (get-in sieve [x y] 0))
+            (put-pixel ctx x y)))))))

 (reagent/render-component [render-canvas]
                           (. js/document (getElementById "app")))
@@ -36,5 +45,5 @@
   ;; optionally touch your app-state to force rerendering depending on
   ;; your application
   ;; (swap! app-state update-in [:__figwheel_counter] inc)
-  (paint "canvas" 400)
+  (paint "canvas" 400 (vec (take 400 (sieve '(1) 2))))
 )


♻ Reuse gis-user's read model as its write model

Why:
- Needs less code
- Unifies with the territory et al. namespaces
- Avoids the need to look up the gis-user inside the command handlers
  when the gis-user instead of the state is a parameter

--- src/territory_bro/gis_user.clj
+++ src/territory_bro/gis_user.clj
@@ -34,26 +34,9 @@

 ;;;; Write model

-(defn- username-path [event-or-command]
-  [::usernames-by-cong-user (select-keys event-or-command [:congregation/id :user/id])])
-
-(defmulti ^:private write-model (fn [_state event] (:event/type event)))
-
-(defmethod write-model :default
-  [state _event]
-  state)
-
-(defmethod write-model :congregation.event/gis-user-created
-  [state event]
-  (-> state
-      ;; TODO: reuse the read model?
-      (assoc-in (username-path event) (:gis-user/username event))))
-
-(defmethod write-model :congregation.event/gis-user-deleted
-  [state event]
-  (-> state
-      ;; TODO: reuse the read model?
-      (dissoc-in (username-path event))))
+(defn- write-model [command events]
+  (let [state (reduce projection nil events)]
+    (get-in state [::gis-users (:congregation/id command) (:user/id command)])))

 ;;;; Command Handlers
@@ -81,11 +64,11 @@

 (defmulti ^:private command-handler (fn [command _state _injections] (:command/type command)))

-(defmethod command-handler :gis-user.command/create-gis-user [command state {:keys [generate-password db-user-exists? check-permit]}]
+(defmethod command-handler :gis-user.command/create-gis-user [command gis-user {:keys [generate-password db-user-exists? check-permit]}]
   (let [cong-id (:congregation/id command)
         user-id (:user/id command)]
     (check-permit [:create-gis-user cong-id user-id])
-    (when (nil? (get-in state (username-path command)))
+    (when (nil? gis-user)
       [{:event/type :congregation.event/gis-user-created
         :event/version 1
         :congregation/id cong-id
@@ -96,17 +79,16 @@
                                (unique-username db-user-exists?))
         :gis-user/password (generate-password)}])))

-(defmethod command-handler :gis-user.command/delete-gis-user [command state {:keys [check-permit]}]
+(defmethod command-handler :gis-user.command/delete-gis-user [command gis-user {:keys [check-permit]}]
   (let [cong-id (:congregation/id command)
         user-id (:user/id command)]
     (check-permit [:delete-gis-user cong-id user-id])
-    (when-some [username (get-in state (username-path command))]
+    (when (some? gis-user)
       [{:event/type :congregation.event/gis-user-deleted
         :event/version 1
         :congregation/id cong-id
         :user/id user-id
-        :gis-user/username username}])))
+        :gis-user/username (:gis-user/username gis-user)}])))

 (defn handle-command [command events injections]
-  (let [state (reduce write-model nil events)]
-    (command-handler command state injections)))
+  (command-handler command (write-model command events) injections))


WS fix

WS fix

--- api/src/geocommit/hook.clj
+++ api/src/geocommit/hook.clj
@@ -1,22 +1,22 @@
-					; geocommit.com HTTP hook API
-					; (c) 2010 David Soria Parra <dsp+geocommit@experimentalworks.net>
-					;          Nils Adermann <naderman+geocommit@naderman.de>
-					;          Filip Noetzel <filip+geocommit@j03.de>
-					; Licensed under the terms of the MIT License
+; geocommit.com HTTP hook API
+; (c) 2010 David Soria Parra <dsp+geocommit@experimentalworks.net>
+;          Nils Adermann <naderman+geocommit@naderman.de>
+;          Filip Noetzel <filip+geocommit@j03.de>
+; Licensed under the terms of the MIT License
 (ns #^{:doc "HTTP signup API functions",
        :author "David Soria Parra"}
   geocommit.hook
   (:use geocommit.core
-	geocommit.config
-	geocommit.http
-	geocommit.services
-	experimentalworks.couchdb
-	clojure.contrib.logging
-	clojure.contrib.json
-	clojure.contrib.condition)
+        geocommit.config
+        geocommit.http
+        geocommit.services
+        experimentalworks.couchdb
+        clojure.contrib.logging
+        clojure.contrib.json
+        clojure.contrib.condition)
   (:require [clojure.contrib.trace :as t])
   (:import geocommit.services.Github
-	   geocommit.services.Bitbucket))
+           geocommit.services.Bitbucket))

 (def *couchdb* (get-config "db.geocommits"))
 (defrecord Repository [_id identifier name description repository-url vcs scanned type])


object semantics default-setting causes a stack overflow

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -132,6 +132,13 @@
                    :subcat {:1 {:sem subject-semantics}}
                    :sem {:subj subject-semantics}}}))

+      ;; commenting out: getting stack overflow.
+;      (default ;;  a verb's second argument is the semantic object of the verb.
+;       (let [object-semantics (atom :top)]
+;         {:synsem {:cat :verb
+;                   :subcat {:2 {:sem object-semantics}}
+;                   :sem {:obj object-semantics}}}))
+
       (default ;; a verb agrees with its first argument
        (let [subject-agreement (atom :top)]
          {:synsem {:cat :verb


[TH] switch to JS friendly regex pattern

--- src/clj/turbovote/imbarcode.clj
+++ src/clj/turbovote/imbarcode.clj
@@ -50,7 +50,7 @@
    parameters."
   ([imbarcode]
      {:pre [(string? imbarcode)
-            (not (nil? (re-find #"\A\d*\z" imbarcode)))
+            (not (nil? (re-find #"^\d*$" imbarcode)))
             (<= 20 (count imbarcode))
             (>= 31 (count imbarcode))]}
      (let [{:keys [barcode service routing] :as imb-data}


cleanup browser repl

cleanup browser repl

--- src-cljs/frontend/core.cljs
+++ src-cljs/frontend/core.cljs
@@ -2,7 +2,6 @@
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
             [frontend.async :refer [put!]]
             [weasel.repl :as ws-repl]
-            [clojure.browser.repl :as repl]
             [clojure.string :as string]
             [datascript :as d]
             [dommy.core :as dommy]
@@ -288,10 +287,7 @@
             ;; of a server to store it
             (async/timeout 10000) (do (print "TODO: print out history: ")))))))

-(defn setup-browser-repl [repl-url]
-  (when repl-url
-    (mlog "setup-browser-repl calling repl/connect with repl-url: " repl-url)
-    (repl/connect repl-url))
+(defn setup-browser-repl []
   ;; this is harmless if it fails
   (ws-repl/connect "ws://localhost:9001" :verbose true)
   ;; the repl tries to take over *out*, workaround for
@@ -339,10 +335,7 @@
       (put! (get-in @state [:comms :nav]) [:error {:status error-status}])
       (sec/dispatch! (str "/" (.getToken history-imp))))
     (when (and (env/development?) (= js/window.location.protocol "http:"))
-      (try
-        (setup-browser-repl (get-in @state [:render-context :browser_connected_repl_url]))
-        (catch js/error e
-          (merror e))))))
+      (swallow-errors (setup-browser-repl)))))

 #_(defn reinstall-om! []
   (install-om debug-state (find-app-container (find-top-level-node)) (:comms @debug-state)))


make a separate function for calling the draw board js

--- src/greybear/pages/game.clj
+++ src/greybear/pages/game.clj
@@ -25,7 +25,11 @@
          [:div#players "Players: " (game :white) " vs. " (game :black)]
          [:div#caca "Username: " session]
          [:canvas#goBoard]
-         (javascript-tag
-          (format "goboard.draw(\"goBoard\", %s, 1, greybear.draw_callback, 18, 17);"
-                  (stones-to-js (game :stones))))])}
+         (js-draw (game :stones) 1 18 17)])}
       (game-not-found game-id))))
+
+(defn js-draw
+  [stones playing last-x last-y]
+  (javascript-tag
+   (format "goboard.draw(\"goBoard\", %s, %s, greybear.draw_callback, %s, %s)"
+           (stones-to-js stones) playing last-x last-y)))


CMR-766: Added more tests for special case polygons.

--- test/cmr/system_int_test/search/collection_spatial_search_test.clj
+++ test/cmr/system_int_test/search/collection_spatial_search_test.clj
@@ -35,61 +35,105 @@
   [& ords]
   (codec/url-encode (umm-s/set-coordinate-system :geodetic (apply polygon ords))))

+(defn make-coll
+  [coord-sys et & shapes]
+  (println "making " et)
+  (d/ingest "PROV1"
+            (dc/collection
+              {:entry-title et
+               :spatial-coverage (dc/spatial {:gsr coord-sys
+                                              :sr coord-sys
+                                              :geometries shapes})})))
+
+(deftest special-case-spatial-search-test
+  (let [west-hemi-poly1 (make-coll :geodetic "west-hemi-poly1"
+                                   (polygon -179.9999 0.0, -179.9999 -89.9999, 0.0 -89.9999,
+                                            0.0 0.0, 0.0 89.9999, -179.9999 89.9999, -179.9999 0.0))
+        west-hemi-poly2 (make-coll :geodetic "west-hemi-poly2"
+                                   (polygon -179.9999 -89.9999, 0.0 -89.9999, 0.0 89.9999,
+                                            -179.9999 89.9999, -179.9999 -89.9999))
+        west-hemi-poly3 (make-coll :geodetic "west-hemi-poly3"
+                                   (polygon -179.9999 75, -179.9 75, -179.9 0, -179.9999 0,
+                                            -179.9999 -89.9999, 0 -89.9999, 0 89.9999,
+                                            -179.9999 89.9999, -179.9999 75))
+        east-hemi-poly1 (make-coll :geodetic "east-hemi-poly1"
+                                   (polygon 0.0001 -89.9999, 180 -89.9999, 180 89.9999,
+                                            0.0001 89.9999, 0.0001 -89.9999))
+        ;; Combines west-hemi-poly3 and east-hemi-poly1
+        combined (make-coll :geodetic "combined"
+                            (polygon -179.9999 75, -179.9 75, -179.9 0, -179.9999 0,
+                                     -179.9999 -89.9999, 0 -89.9999, 0 89.9999,
+                                     -179.9999 89.9999, -179.9999 75)
+                            (polygon 0.0001 -89.9999, 180 -89.9999, 180 89.9999,
+                                     0.0001 89.9999, 0.0001 -89.9999))
+        all-colls [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 east-hemi-poly1 combined]]
+
+    (index/refresh-elastic-index)
+
+    (are [lon_lat items]
+         (let [found (search/find-refs :collection {:point (codec/url-encode (apply p/point lon_lat))
+                                                    :page-size 50})
+               matches? (d/refs-match? items found)]
+           (when-not matches?
+             (println "Expected:" (->> items (map :entry-title) sort pr-str))
+             (println "Actual:" (->> found :refs (map :name) sort pr-str)))
+           matches?)
+
+         ;; north pole
+         [0 90] all-colls
+
+         ;; south pole
+         [0 -90] all-colls
+
+         ;; antimerdian
+         [180 0] [east-hemi-poly1 combined]
+         [-180 0] [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 combined]
+
+         ;; prime meridian
+         [0 0] all-colls
+         [0 10] all-colls
+         [0 -10] all-colls
+
+         ;; middle of east hemisphere
+         [90 45] [east-hemi-poly1 combined]
+
+         ;; middle of west hemisphere
+         [-90 45] [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 combined])))
+
+
 (deftest spatial-search-test
-  (let [make-coll (fn [coord-sys orbit-params et & shapes]
-                    (d/ingest "PROV1"
-                              (dc/collection
-                                {:entry-title et
-                                 :spatial-coverage (dc/spatial {:gsr coord-sys
-                                                                :orbit orbit-params
-                                                                :sr coord-sys
-                                                                :geometries shapes})})))
-
-        ;; orbit parameters
-        orbit-params {:swath-width 2
-                      :period 96
-                      :inclination-angle 45
-                      :number-of-orbits 1
-                      :start-circular-latitude 0}
-        orbit-coll (d/ingest "PROV1"
-                             (dc/collection
-                               {:entry-title "orbit-params"
-                                :spatial-coverage (dc/spatial {:gsr :geodetic
-                                                               :orbit orbit-params})}))
-
-
-        ;; Lines
-        normal-line (make-coll :geodetic nil "normal-line"
+  (let [;; Lines
+        normal-line (make-coll :geodetic "normal-line"
                                (l/ords->line-string :geodetic 22.681 -8.839, 18.309 -11.426, 22.705 -6.557))
-        normal-line-cart (make-coll :cartesian nil "normal-line-cart"
+        normal-line-cart (make-coll :cartesian "normal-line-cart"
                                     (l/ords->line-string :cartesian 16.439 -13.463,  31.904 -13.607, 31.958 -10.401))

         ;; Bounding rectangles
-        whole-world (make-coll :geodetic nil "whole-world" (m/mbr -180 90 180 -90))
-        touches-np (make-coll :geodetic nil "touches-np" (m/mbr 45 90 55 70))
-        touches-sp (make-coll :geodetic nil "touches-sp" (m/mbr -160 -70 -150 -90))
-        across-am-br (make-coll :geodetic nil "across-am-br" (m/mbr 170 10 -170 -10))
-        normal-brs (make-coll :geodetic nil "normal-brs"
+        whole-world (make-coll :geodetic "whole-world" (m/mbr -180 90 180 -90))
+        touches-np (make-coll :geodetic "touches-np" (m/mbr 45 90 55 70))
+        touches-sp (make-coll :geodetic "touches-sp" (m/mbr -160 -70 -150 -90))
+        across-am-br (make-coll :geodetic "across-am-br" (m/mbr 170 10 -170 -10))
+        normal-brs (make-coll :geodetic "normal-brs"
                               (m/mbr 10 10 20 0)
                               (m/mbr -20 0 -10 -10))

         ;; Polygons
-        wide-north (make-coll :geodetic nil "wide-north" (polygon -70 20, 70 20, 70 30, -70 30, -70 20))
-        wide-south (make-coll :geodetic nil "wide-south" (polygon -70 -30, 70 -30, 70 -20, -70 -20, -70 -30))
-        across-am-poly (make-coll :geodetic nil "across-am-poly" (polygon 170 35, -175 35, -170 45, 175 45, 170 35))
-        on-np (make-coll :geodetic nil "on-np" (polygon 45 85, 135 85, -135 85, -45 85, 45 85))
-        on-sp (make-coll :geodetic nil "on-sp" (polygon -45 -85, -135 -85, 135 -85, 45 -85, -45 -85))
-        normal-poly (make-coll :geodetic nil "normal-poly" (polygon -20 -10, -10 -10, -10 10, -20 10, -20 -10))
+        wide-north (make-coll :geodetic "wide-north" (polygon -70 20, 70 20, 70 30, -70 30, -70 20))
+        wide-south (make-coll :geodetic "wide-south" (polygon -70 -30, 70 -30, 70 -20, -70 -20, -70 -30))
+        across-am-poly (make-coll :geodetic "across-am-poly" (polygon 170 35, -175 35, -170 45, 175 45, 170 35))
+        on-np (make-coll :geodetic "on-np" (polygon 45 85, 135 85, -135 85, -45 85, 45 85))
+        on-sp (make-coll :geodetic "on-sp" (polygon -45 -85, -135 -85, 135 -85, 45 -85, -45 -85))
+        normal-poly (make-coll :geodetic "normal-poly" (polygon -20 -10, -10 -10, -10 10, -20 10, -20 -10))

         ;; CMR-724 special case
-        west-hemi-poly1 (make-coll :geodetic nil "west-hemi-poly1"
+        west-hemi-poly1 (make-coll :geodetic "west-hemi-poly1"
                                    (polygon -179.9999 0.0, -179.9999 -89.9999, 0.0 -89.9999,
                                             0.0 0.0, 0.0 89.9999, -179.9999 89.9999, -179.9999 0.0))
-        west-hemi-poly2 (make-coll :geodetic nil "west-hemi-poly2"
+        west-hemi-poly2 (make-coll :geodetic "west-hemi-poly2"
                                    (polygon -179.9999 -89.9999, 0.0 -89.9999, 0.0 89.9999,
                                             -179.9999 89.9999, -179.9999 -89.9999))

-        east-hemi-poly1 (make-coll :geodetic nil "east-hemi-poly1"
+        east-hemi-poly1 (make-coll :geodetic "east-hemi-poly1"
                                    (polygon 0.0001 -89.9999, 180 -89.9999, 180 89.9999,
                                             0.0001 89.9999, 0.0001 -89.9999))

@@ -97,25 +141,25 @@
         outer (umm-s/ords->ring -5.26,-2.59, 11.56,-2.77, 10.47,8.71, -5.86,8.63, -5.26,-2.59)
         hole1 (umm-s/ords->ring 6.95,2.05, 2.98,2.06, 3.92,-0.08, 6.95,2.05)
         hole2 (umm-s/ords->ring 5.18,6.92, -1.79,7.01, -2.65,5, 4.29,5.05, 5.18,6.92)
-        polygon-with-holes  (make-coll :geodetic nil "polygon-with-holes" (poly/polygon [outer hole1 hole2]))
+        polygon-with-holes  (make-coll :geodetic "polygon-with-holes" (poly/polygon [outer hole1 hole2]))

         ;; Cartesian Polygons
-        wide-north-cart (make-coll :cartesian nil "wide-north-cart" (polygon -70 20, 70 20, 70 30, -70 30, -70 20))
-        wide-south-cart (make-coll :cartesian nil "wide-south-cart" (polygon -70 -30, 70 -30, 70 -20, -70 -20, -70 -30))
-        very-wide-cart (make-coll :cartesian nil "very-wide-cart" (polygon -180 40, -180 35, 180 35, 180 40, -180 40))
-        very-tall-cart (make-coll :cartesian nil "very-tall-cart" (polygon -160 90, -160 -90, -150 -90, -150 90, -160 90))
-        normal-poly-cart (make-coll :cartesian nil "normal-poly-cart" (polygon 1.534 -16.52, 6.735 -14.102, 3.745 -9.735, -1.454 -11.802, 1.534 -16.52))
+        wide-north-cart (make-coll :cartesian "wide-north-cart" (polygon -70 20, 70 20, 70 30, -70 30, -70 20))
+        wide-south-cart (make-coll :cartesian "wide-south-cart" (polygon -70 -30, 70 -30, 70 -20, -70 -20, -70 -30))
+        very-wide-cart (make-coll :cartesian "very-wide-cart" (polygon -180 40, -180 35, 180 35, 180 40, -180 40))
+        very-tall-cart (make-coll :cartesian "very-tall-cart" (polygon -160 90, -160 -90, -150 -90, -150 90, -160 90))
+        normal-poly-cart (make-coll :cartesian "normal-poly-cart" (polygon 1.534 -16.52, 6.735 -14.102, 3.745 -9.735, -1.454 -11.802, 1.534 -16.52))

         outer-cart (umm-s/ords->ring -5.26 -22.59 11.56 -22.77 10.47 -11.29 -5.86 -11.37 -5.26 -22.59)
         hole1-cart (umm-s/ords->ring 6.95 -17.95 2.98 -17.94 3.92 -20.08 6.95 -17.95)
         hole2-cart (umm-s/ords->ring 5.18 -13.08 -1.79 -12.99 -2.65 -15 4.29 -14.95 5.18 -13.08)
-        polygon-with-holes-cart (make-coll :cartesian nil "polygon-with-holes-cart" (poly/polygon [outer-cart hole1-cart hole2-cart]))
+        polygon-with-holes-cart (make-coll :cartesian "polygon-with-holes-cart" (poly/polygon [outer-cart hole1-cart hole2-cart]))

         ;; Points
-        north-pole (make-coll :geodetic nil "north-pole" (p/point 0 90))
-        south-pole (make-coll :geodetic nil "south-pole" (p/point 0 -90))
-        normal-point (make-coll :geodetic nil "normal-point" (p/point 10 22))
-        am-point (make-coll :geodetic nil "am-point" (p/point 180 22))]
+        north-pole (make-coll :geodetic "north-pole" (p/point 0 90))
+        south-pole (make-coll :geodetic "south-pole" (p/point 0 -90))
+        normal-point (make-coll :geodetic "normal-point" (p/point 10 22))
+        am-point (make-coll :geodetic "am-point" (p/point 180 22))]
     (index/refresh-elastic-index)

     (testing "line searches"


Don't skip giant messages if they're multipart

--- src/net/dishevelled/mailindex.clj
+++ src/net/dishevelled/mailindex.clj
@@ -171,7 +171,7 @@

 (defn strip-html [^String s]
-  (let [content (org.apache.tika.sax.WriteOutContentHandler. 1000000)]
+  (let [content (org.apache.tika.sax.WriteOutContentHandler. (* MAX_PART_BYTES 6))]
     (.parse (org.apache.tika.parser.html.HtmlParser.)
             (java.io.ByteArrayInputStream. (.getBytes s))
             content
@@ -188,8 +188,11 @@
   (concat
    (extract-part-metadata part)
    (try
-     (if (> (.getSize part) MAX_PART_BYTES)
-       (do (println "Skipping giant part: " (.getSize part))
+     (if (and (> (.getSize part) MAX_PART_BYTES)
+              (not (re-find #"^multipart/" (.toLowerCase (.getContentType part)))))
+       (do (println (format "Skipping giant part: (type: %s) %s"
+                            (.toLowerCase (.getContentType part))
+                             (.getSize part)))
            [])
        (let [content (.getContent part)]
          (condp re-find (.toLowerCase (.getContentType part))


Change test to check for default

Change test to check for default

--- test/buildviz/handler_test.clj
+++ test/buildviz/handler_test.clj
@@ -260,12 +260,11 @@
                                                   "averageRuntime" 20000}]}]}}
              resp-data)))

-    ;; GET should return CSV when client accepts text/plain
+    ;; GET should return CSV by default
     (reset-app!)
     (a-build "aBuild" 1, {})
     (some-test-results "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a,test\" classname=\"a class\" time=\"10\"></testcase></testsuite></testsuites>")
-    (let [response (app (-> (request :get "/testsuites")
-                            (header :accept "text/plain")))]
+    (let [response (app (request :get "/testsuites"))]
       (is (= (:body response)
              (join ["averageRuntime,job,testsuite,classname,name\n"
                     "10000,aBuild,a suite,a class,\"a,test\"\n"]))))


refine import test

refine import test

--- test/clj_money/import_test.clj
+++ test/clj_money/import_test.clj
@@ -356,26 +356,68 @@
         entity (import-data storage-spec
                             (-> context :imports first)
                             (nil-chan))
-        commodity (commodities/find-by storage-spec {:entity-id (:id entity)
-                                                     :symbol "AAPL"})
-        lots (lots/search storage-spec {:commodity-id (:id commodity)})
         [ira four-o-one-k] (map #(accounts/find-by storage-spec
                                                    {:name %
                                                     :entity-id (:id entity)})
                                 ["IRA" "401k"])
-        expected-lots [{:purchase-date (t/local-date 2015 1 17)
-                        :shares-purchased 200M
-                        :shares-owned 200M
-                        :purchase-price 5M ; originally purchased 100 shares at $10/share
-                        :commodity-id (:id commodity)
-                        :account-id (:id ira)}]
-        actual-lots (map #(dissoc % :updated-at :created-at :id) lots)]
-    (is (:trading (:tags ira))
-        "The IRA account has the correct tags")
-    (is (:trading (:tags four-o-one-k))
-        "The 401k account has the correct tags")
-    (is (= 0M (:balance four-o-one-k)) "All shares have been transfered out of 401k")
-    (is (= 1000M (:balance ira)) "Shares have been transfered into IRA")
-    (pprint-diff expected-lots actual-lots)
-    (is (= expected-lots actual-lots)
-        "The commodity has the correct lots after import")))
+        aapl (commodities/find-by storage-spec {:entity-id (:id entity)
+                                                :symbol "AAPL"})]
+
+    (testing "lots are adjusted"
+      (let [
+            lots (lots/search storage-spec {:commodity-id (:id aapl)})
+            expected-lots [{:purchase-date (t/local-date 2015 1 17)
+                            :shares-purchased 200M
+                            :shares-owned 200M
+                            :purchase-price 5M ; originally purchased 100 shares at $10/share
+                            :commodity-id (:id aapl)
+                            :account-id (:id ira)}]
+            actual-lots (map #(dissoc % :updated-at :created-at :id) lots)]
+        (pprint-diff expected-lots actual-lots)
+        (is (= expected-lots actual-lots)
+            "The commodity has the correct lots after import")))
+
+    (testing "accounts are tagged correctly"
+      (is (:trading (:tags ira))
+          "The IRA account has the correct tags")
+      (is (:trading (:tags four-o-one-k))
+          "The 401k account has the correct tags"))
+
+    (testing "transactions are created correctly"
+      (let [ira-aapl (accounts/find-by storage-spec {:parent-id (:id ira)
+                                                     :commodity-id (:id aapl)})
+            expected-ira-items [{:transaction-date (t/local-date 2015 3 2)
+                                 :description "Transfer 100 shares of AAPL"
+                                 :index 0
+                                 :action :debit
+                                 :account-id (:id ira-aapl)
+                                 :amount 100M
+                                 :balance 100M
+                                 :value 1000M}
+                                {:transaction-date (t/local-date 2015 4 1)
+                                 :description "Split shares of AAP 2 for 1"
+                                 :index 1
+                                 :action :debit
+                                 :account-id (:id ira-aapl)
+                                 :amount 100M
+                                 :balance 200M
+                                 :value 0M}]
+            actual-ira-items (->> {:account-id (:id ira-aapl)}
+                                  (transactions/search-items storage-spec)
+                                  (map #(dissoc % :created-at
+                                                  :updated-at
+                                                  :id
+                                                  :memo
+                                                  :transaction-id
+                                                  :negative
+                                                  :polarized-amount
+                                                  :reconciliation-status
+                                                  :reconciliation-id
+                                                  :reconciled?)))]
+        (pprint-diff expected-ira-items actual-ira-items)
+        (is (= expected-ira-items actual-ira-items)
+            "The IRA account has the correct items")))
+
+    (testing "account balances are calculated correctly"
+      (is (= 0M (:balance four-o-one-k)) "All shares have been transfered out of 401k")
+      (is (= 200M (:balance ira)) "Shares have been transfered into IRA")))) ; TODO Adjust this to account for value, not shares


comments; naming

comments; naming

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/stats/timeseries.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/stats/timeseries.cljs
@@ -3,10 +3,10 @@

 (defn date-round
   "Returns function that rounds the provided seconds since epoch down to the
-   nearest time interval s e.g. (date-round 60) creates a function that takes
-   seconds t and rounds them to the nearest minute."
-  [s]
-  (fn [t] (* s (Math/floor (/ t s)))))
+   nearest time interval; for example (date-round 60) creates a function that
+   takes seconds t and rounds them to the nearest minute."
+  [interval]
+  (fn [t] (* interval (Math/floor (/ t interval)))))

 (def m 60)
 (def qhr (* 15 m))


(SERVER-29) Fix jruby interpreter test.

(SERVER-29) Fix jruby interpreter test.

--- test/unit/puppetlabs/services/jruby/jruby_interpreter_test.clj
+++ test/unit/puppetlabs/services/jruby/jruby_interpreter_test.clj
@@ -48,4 +48,4 @@
           jruby-env (.runScriptlet jruby-interpreter "ENV")]

       ; $HOME and $PATH are left in by `jruby-puppet-env`
-      (is (= #{"HOME" "PATH" "GEM_HOME"} (set (keys jruby-env)))))))
+      (is (= #{"HOME" "JARS_NO_REQUIRE" "PATH" "GEM_HOME"} (set (keys jruby-env)))))))


Fix core spec.

Fix core spec.

--- spec/incise/parsers/core_spec.clj
+++ spec/incise/parsers/core_spec.clj
@@ -1,6 +1,6 @@
 (ns incise.parsers.core-spec
   (:require [speclj.core :refer :all]
-            [incise.core :refer [load-parsers-and-layouts]]
+            [incise.load :refer [load-parsers-and-layouts]]
             [clojure.java.io :refer [file resource]]
             [incise.parsers.core :refer :all]))


Fix one namespace declaration

Fix one namespace declaration

--- src/ktra_indexer/parser.clj
+++ src/ktra_indexer/parser.clj
@@ -3,8 +3,7 @@
   (:refer-clojure :exclude [range iterate format max min])
   (:require [clojure.string :as s]
             [java-time :as t])
-  (:import java.time.format.DateTimeFormatter
-           java.time.DayOfWeek
+  (:import java.time.DayOfWeek
            org.jsoup.Jsoup))

 (defn get-friday-date


Find dev-dependencies even when :library-path is customized.

Thanks r0man.

--- src/leiningen/classpath.clj
+++ src/leiningen/classpath.clj
@@ -8,7 +8,8 @@
   "Returns a seq of Files for all the jars in the project's library directory."
   [project]
   (filter #(.endsWith (.getName %) ".jar")
-          (file-seq (file (:library-path project)))))
+          (concat (.listFiles (file (:library-path project)))
+                  (.listFiles (file (:root project) "lib/dev")))))

 (defn make-path
   "Constructs an ant Path object from Files and strings."


Look up system rubocop path

Look up system rubocop path

--- src/lt/plugins/rubocop.cljs
+++ src/lt/plugins/rubocop.cljs
@@ -5,10 +5,14 @@
             [lt.objs.editor :as editor]
             [lt.objs.editor.pool :as pool]
             [lt.objs.files :as files]
+            [lt.util.load :as load]
             [lt.objs.proc :as proc])
   (:require-macros [lt.macros :refer [defui behavior background]]))

 (def exec (.-exec (js/require "child_process")))
+(def shell (load/node-module "shelljs"))
+
+(def rubocop-path (.which shell "rubocop"))

 (defn violations-for-file [json-str]
   (let [parsed (js->clj (JSON/parse json-str))]
@@ -20,9 +24,9 @@
        violations))

 (def offences
-  (background (fn [this cwd path]
+  (background (fn [this cwd path rubocop-path]
                 (.exec (js/require "child_process")
-                       (str "/Users/seancaffery/.rbenv/shims/rubocop --format json '" path "'")
+                       (str rubocop-path " --format json '" path "'")
                        (clj->js {"cwd" cwd})
                        (fn [err stdout stderr]
                           (raise this :cop-finished stdout)
@@ -39,7 +43,7 @@
           :reaction (fn [this]
                       (let [active-ed (pool/last-active)
                             path (-> @active-ed :info :path)]
-                      (offences this (files/parent path) path))))
+                      (offences this (files/parent path) path rubocop-path))))

 (cmd/command {:command ::run-cop
               :desc "Rubocop: start"


Test assignment of type to slot on obj.

Test assignment of type to slot on obj.

--- test/isla/test/interpreter.clj
+++ test/isla/test/interpreter.clj
@@ -74,6 +74,15 @@
     (is false) ;; shouldn't get called
     (catch Exception e
       (is (= (.getMessage e) "Persons do not have a material.")))))
+
+(deftest test-slot-type-assignment
+  (let [result (interpret (parse "isla is a person\nisla friend is a person")
+                          (library/get-initial-env extra-types))]
+    (is (= (get (:ctx result) "isla")
+           (new isla.test.interpreter.Person 0
+                ""
+                (new isla.test.interpreter.Person 0 "" :undefined))))))
+
 ;; test extract fn

 (deftest test-extract-block-tag


removed rando func

removed rando func

--- src/photosure/client/gallery.cljs
+++ src/photosure/client/gallery.cljs
@@ -49,9 +49,6 @@
 (defn disappear [app ndx]
   (om/update! app [:photos ndx :pos] []))

-(defn get-curr-photo [app ndx]
-  (:photo (get (:photos @app) (get (:curr @app) 0))))
-
 (defn gallery [app owner]
   (reify
     om/IInitState


Add fn for upserting oauth tokens

Add fn for upserting oauth tokens

--- src/myshelf/models/user.clj
+++ src/myshelf/models/user.clj
@@ -89,3 +89,17 @@
       (create-user :db-conn db-conn
                    :handle handle
                    :last-tweet last-tweet))))
+
+(defn update-oauth
+  [handle goodreads-id oauth-token oauth-token-secret]
+  (sql/with-db-transaction [db-conn db-spec]
+    (if-let [current-user (find-by-handle db-conn handle)]
+      (update-user db-conn (merge current-user
+                                  {:goodreads_id goodreads-id
+                                   :oauth_token oauth-token
+                                   :oauth_token_secret oauth-token-secret}))
+      (create-user :db-conn db-conn
+                   :goodreads-id goodreads-id
+                   :handle handle
+                   :oauth-token oauth-token
+                   :oauth-token-secret oauth-token-secret))))


some updates

some updates

--- src/ankusha/pg_cluster.cljs
+++ src/ankusha/pg_cluster.cljs
@@ -1,13 +1,16 @@
 (ns ankusha.pg-cluster
-  (:require-macros [cljs.core.async.macros :as m :refer [go alt!]])
+  (:require-macros [cljs.core.async.macros :as m :refer [go alt! go-loop]])
   (:require [cljs.nodejs :as node]
+            [clojure.string :as str]
             [ankusha.shell :as shell]
             [ankusha.pg :as pg]
             [cljs.core.async :as async :refer [<!]]))

 (def proc (node/require "child_process"))

-(def pg-bin-dir "/usr/lib/postgresql/9.5/bin")
+(defonce settings (atom {:bin "/usr/lib/postgresql/9.5/bin"}))
+
+(defn bin [util] (str (:bin @settings) "/" util))

 (defonce pg-proc (atom nil))
 (defonce pg-on-exit (atom nil))
@@ -38,25 +41,24 @@

 (defn start-postgres [cfg]
   (let [chan (async/chan)
-        bin (str pg-bin-dir "/postgres")
-        p (.spawn proc bin #js["-D" (:data-dir cfg)])]
+        p (.spawn proc (bin "postgres") #js["-D" (:data-dir cfg)])]
     (.pipe (.-stdout p ) (.-stdout js/process))
     (.pipe (.-stderr p) (.-stderr js/process))
-    (.on p "exit" (fn [code]
-                    (println "Postgres exit with " code)
-                    (async/put! chan code)
+    (.on p "exit" (fn [code sig]
+                    (println "Postgres exit with " code " SIG " sig)
+                    (when code (async/put! chan code))
                     (async/close! chan)))

     (reset! pg-proc p)
     (reset! pg-on-exit chan)
     chan))

-(defn stop-postgres []
+(defn stop-postgres [sig]
   (when-let [proc @pg-proc]
-    (.kill proc)))
+    (.kill proc (str/upper-case (name sig)))))

 (defn restart-postgres [cfg]
-  (stop-posgres)
+  (stop-postgres :sigint)
   (start-postgres cfg))

 (defn reconfigure [cfg]
@@ -65,50 +67,86 @@
     (println "RESTART:" (<! (restart-postgres cfg)))))

 (defn pg_ctl [cfg cmd]
-  (let [bin (str pg-bin-dir "/pg_ctl")]
-    (shell/spawn bin {:-D (:data-dir cfg)
-                      :-l (str (:data-dir cfg) "/postgres.log")}
-                 (name cmd))))
+  (shell/spawn (bin "pg_ctl") {:-D (:data-dir cfg)
+                               :-l (str (:data-dir cfg) "/postgres.log")}
+               (name cmd)))
+
+(defn stop-by-pid [pid]
+  )
+
+(defn postmaster-pid [cfg]
+  (go (if-let [res (<! (shell/slurp (str (:data-dir cfg) "/postmaster.pid")))]
+        (first (str/split  res #"\n"))
+        nil)))
+
+(defn sighup-params [cfg]
+  (pg/exec (conn-uri cfg)
+           {:select [:name]
+            :from [:pg_settings]
+            :where [:= :context "sighup"]}))

 (defn conn-uri [cfg]
   (str "postgres:///postgres?host=" (:data-dir cfg) "&port=" (get-in cfg [:config :port])))

-
-
 (defn probe-connection [cfg]
   (pg/exec (conn-uri cfg) {:select [1]}))
-

 (defn create-cluster [cfg]
   (let [cmd []]
     (go
       (<! (shell/spawn "rm" "-rf" (:data-dir cfg)))
       (pg_ctl cfg :stop)
-      (let [ch (pg_ctl cfg :initdb)
-            res (<! ch)]
-        (println "Cluster creation status " res)
-        (println "Write config" (<! (update-config cfg)))
-        (println "Start cluster" (<! (pg_ctl cfg :start)))))))
+      (println "Cluster creation status " (<! (pg_ctl cfg :initdb)))
+      (println "Write config" (<! (update-config cfg)))
+      (println "Start cluster" (<! (start-postgres cfg)))
+      (println "Probe connection" (<! (probe-connection config))))))
+
+

 (comment
-  (goprint (pg_ctl config :stop))
-  (goprint (pg_ctl config :restart))
-
-  (goprint (pg_ctl config :start))
-  (goprint (pg_ctl config :status))
-
   (update-config config)
+  (reconfigure config)

   (create-cluster config)

-  (reconfigure config)
+  (goprint (postmaster-pid config ))

-  (goprint (start-postgres config))
+  (goprint
+   (start-postgres config))

-  (stop-postgres)
+  (stop-postgres :sigint)

-  (.kill @pg-proc 15)
+  (.kill @pg-proc "SIGHUP")
+  (.kill @pg-proc "SIGINT")
+
+  (.kill @pg-proc "SIGKILL")

   (goprint (probe-connection config))
+  (goprint (shell/slurp "/tmp/cluster-1/postmaster.pid"))

+  (goprint (sighup-params config))
   )
+
+;; SIGTERM This is the Smart Shutdown mode. After receiving SIGTERM, the server
+;; disallows new connections, but lets existing sessions end their work normally.
+;; It shuts down only after all of the sessions terminate. If the server is in
+;; online backup mode, it additionally waits until online backup mode is no longer
+;; active. While backup mode is active, new connections will still be allowed, but
+;; only to superusers (this exception allows a superuser to connect to terminate
+;; online backup mode). If the server is in recovery when a smart shutdown is
+;; requested, recovery and streaming replication will be stopped only after all
+;; regular sessions have terminated.
+
+;; SIGINT This is the Fast Shutdown mode. The server disallows new connections and
+;; sends all existing server processes SIGTERM, which will cause them to abort
+;; their current transactions and exit promptly. It then waits for all server
+;; processes to exit and finally shuts down. If the server is in online backup
+;; mode, backup mode will be terminated, rendering the backup useless.
+
+;; SIGQUIT This is the Immediate Shutdown mode. The server will send SIGQUIT to all
+;; child processes and wait for them to terminate. If any do not terminate within 5
+;; seconds, they will be sent SIGKILL. The master server process exits as soon as
+;; all child processes have exited, without doing normal database shutdown
+;; processing. This will lead to recovery (by replaying the WAL log) upon next
+;; start-up. This is recommended only in emergencies.
+


more work on new kernel

more work on new kernel

--- core/src/samsara_core/kernel2.clj
+++ core/src/samsara_core/kernel2.clj
@@ -1,9 +1,15 @@
 (ns samsara-core.kernel2
-  (:require [com.stuartsierra.component :as component]
+  (:refer-clojure :exclude [var-get var-set])
+  (:require [clojure.string :as str]
+            [com.stuartsierra.component :as component]
             [moebius
-             [core :refer [where]]
+             [core :refer [where inject-if]]
              [kv :as kv]]
-            [samsara.utils :refer [from-json to-json]]))
+            [samsara.utils :refer [from-json to-json]]
+            [taoensso.timbre :as log])
+  (:require [samsara.trackit :refer [track-time track-rate new-registry
+                                     count-tracker distribution-tracker
+                                     track-pass-count] :as trk]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -15,6 +21,7 @@
 ;; TODO: tracking needs to be reviewed
 ;; TODO: display of events
 ;; TODO: per message vs per batch error handling
+;; TODO: handling of events which not match any route
 ;;

@@ -143,7 +150,7 @@

 (defn to-json-format-wrapper
   "a wrapper which convert the :message from a clojure data structure
-   into ajson formatted string."
+   into a json formatted string."
   [handler]
   (fn [values]
     (handler (map #(update % :message to-json) values))))
@@ -174,6 +181,15 @@
       (handler (map dispatcher values)))))

+;; TODO: add :string and :bytes
+(defn format-wrapper
+  "a wrapper which parses the :message from the appropriate format"
+  [format handler]
+  (case format
+    :json   (from-json-format-wrapper handler)
+    handler))
+
+

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;                                                                            ;;
@@ -202,30 +218,31 @@
   (var-set [this new-val] (.set this new-val))
   (var-get [this] (.get this)))

-
+(declare build-routes)

 (defrecord SamsaraCore
     [config            ;; normalized configuration currently used
-     dispatchers       ;; route dispatchers
+     routes            ;; route dispatchers
      global-stores     ;; global-stores for dimensions
-     stores]           ;; stream-local data stores (thread-locals)
+     output-collector]
     component/Lifecycle

-  (start [{done :initialized :as this}]
+  (start [{done :route config :config :as this}]
     (if-not done
       (-> this
-          (assoc :global-stores (atom {}))
-          (assoc :initialized   true))
+          (assoc :route (build-routes this))
+          (assoc :global-stores    (atom {}))
+          (assoc :output-collector (atom nil)))
       this))

-  (stop [{done :initialized :as this}]
+  (stop [{done :route :as this}]
     (if done
       (-> this
-          (assoc :global-stores nil)
-          (assoc :stores        nil)
-          (assoc :initialized   false))
+          (assoc :route            nil)
+          (assoc :global-stores    nil)
+          (assoc :output-collector nil))
       this)))

@@ -250,8 +267,9 @@
    []))

+
 (defn local-kv-restore
-  "Takes a bunch of tx-log events and restores them in the stream loca-stores"
+  "Takes a bunch of tx-log events and restores them in the stream local-stores"
   ([{:keys [component stream-id events]}]
    (let [kv-store (:local-store (stream-config component stream-id))]
      (var-set kv-store
@@ -280,26 +298,30 @@
 (defn- stream-defaults
   "Apply defaults for a stream configuration"
   [{:keys [input-topic state-topic state processor processor-type] :as stream}]
-  (as-> stream it
-    ;; add default state-topic
-    (if (and (= :partitioned state) (not state-topic))
-      (-> it
-          (assoc :state-topic (str input-topic "-kv"))
-          (assoc :local-store (thread-local (kv/make-in-memory-kvstore))))
-      it)
+  (as-> stream is
+
+    ;; add default state-topic configuration
+    (inject-if is (and (= :partitioned state) (not state-topic))
+               :state-topic (str input-topic "-kv"))
+
+    (inject-if is (and (= :partitioned state) (not state-topic))
+               :local-store (thread-local (kv/make-in-memory-kvstore)))
+
+
     ;; when state is global use global-kv-restore!
-    (if (and (= :global state) (not processor))
-      (-> it
-          (assoc :processor #'global-kv-restore)
-          (assoc :processor-type :component-stream-processor))
-      it)
+    (inject-if is (and (= :global state) (not processor))
+               :processor #'global-kv-restore)
+
+    (inject-if is (and (= :global state) (not processor))
+               :processor-type :component-stream-processor)
+
+
     ;; when state is global use global-kv-restore!
-    (if (and (= :global state) (not processor-type))
-      (assoc it :processor-type :component-stream-processor)
-      it)
+    (inject-if is (and (= :global state) (not processor-type))
+               :processor-type :component-stream-processor)

     ;; merge defaults
-    (merge DEFAULT-STREAM-CFG it)))
+    (merge DEFAULT-STREAM-CFG is)))

@@ -327,6 +349,186 @@
   "Return the configuration for the given stream"
   [component stream-id]
   (get-in component [:config :streams stream-id]))
+
+
+
+(defn component-stream-processor-wrapper
+  [component stream-id handler]
+  (fn [values]
+    (handler {:component component :stream-id stream-id :events values})))
+
+
+(defn- standard-stream-wrappers
+  [component stream-id handler]
+  (let [{:keys [format input-partitions]} (stream-config component stream-id)]
+    (->> handler
+         (message-only-wrapper)
+         (format-wrapper format)
+         (partition-filter-wrapper input-partitions))))
+
+
+(defn- tx-log->formatter
+  "Return a function which turns the tx-log into a a triplet of
+
+   [topic partition-key json-data]"
+  [kvstore-topic]
+  (fn [txlog]
+    (->> txlog
+         (map (fn [[k ver v]]
+                [kvstore-topic k (to-json [k ver v])])))))
+
+;; TODO: change txlog format look like events
+;; TODO: support dispatch-fn and  format fn
+(defn topic-process-wrapper [component stream-id pipeline]
+  (let [{:keys [local-store state-topic
+                output-topic-partition-fn output-topic ]
+         } (stream-config component stream-id)
+        output-collector (:output-collector component)
+        tx-log->messages (tx-log->formatter state-topic)
+        out-dispatch (fn [event] [output-topic
+                                 (output-topic-partition-fn event)
+                                 (to-json event)])]
+    (fn [events]
+      (let [state    (var-get local-store)
+            [new-state rich-events] (pipeline state events)
+            txlog     (kv/tx-log new-state)
+            txlog-msg (tx-log->messages txlog)
+            output-events (map out-dispatch events)
+            all-output (concat txlog-msg output-events)]
+
+        ;; emitting the output
+        (@output-collector all-output)
+
+        ;; flushing tx-log
+        (let [new-state' (kv/flush-tx-log new-state txlog)]
+          (var-set local-store new-state'))))))
+
+
+(defn load-function-from-name
+  ([fqn-fname]
+   (if (string? fqn-fname)
+     (let [[fns ff] (str/split fqn-fname #"/")]
+       (load-function-from-name fns ff))
+     fqn-fname))
+  ([fn-ns fn-name]
+   ;; requiring the namespace
+   (require (symbol fn-ns))
+   (let [fn-symbol (resolve (symbol fn-ns fn-name))]
+     (when-not fn-symbol
+       (throw (ex-info (str "function '" fn-ns "/" fn-name "' not found.") {})))
+     fn-symbol)))
+
+
+(defn processor-wrapper
+  ([component stream-id]
+   (let [{:keys [processor-type processor]} (stream-config component stream-id)]
+     (processor-wrapper component stream-id processor-type processor)))
+
+  ([component stream-id processor-type processor]
+   (log/debug "Initializing processor [" stream-id "/" processor-type "]:" processor)
+   (let [handler (load-function-from-name processor)]
+     (case processor-type
+       :component-stream-processor
+       (component-stream-processor-wrapper component stream-id handler)
+
+       :samsara-factory
+       (let [handler' (handler (:config component))]
+         (topic-process-wrapper component stream-id handler'))
+
+       :raw
+       handler))))
+
+
+
+(defn build-routes-for-stream [component stream-id]
+  (log/debug "Building routes for:" stream-id)
+  (let [{:keys [input-topic state-topic state]} (stream-config component stream-id)]
+    (cond
+
+      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+      ;; build route for partitioned topic with no state
+      (= state :none)
+      [;; add route to handle topic data
+       [(where :topic = input-topic)
+        (->> (processor-wrapper component stream-id)
+             (standard-stream-wrappers component stream-id))]]
+
+
+      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+      ;; build route for partitioned topic with partitioned state
+      (= state :partitioned)
+      [;; add route to handle kv-store
+       [(where :topic = state-topic)
+        (->> (processor-wrapper component stream-id
+                                :component-stream-processor local-kv-restore)
+             (standard-stream-wrappers component stream-id))]
+       ;; add route to handle topic data
+       [(where :topic = input-topic)
+        (->> (processor-wrapper component stream-id)
+             (standard-stream-wrappers component stream-id))]]
+
+
+      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+      ;; build route for global state
+      (= state :global)
+      [[(where :topic = input-topic)
+        (->> (processor-wrapper component stream-id)
+             (standard-stream-wrappers component stream-id))]]
+
+
+      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+      ;; build route for CUSTOM managed routes
+      (= state :custom)
+      [[(where :topic = input-topic)
+        (->> (processor-wrapper component stream-id)
+             (standard-stream-wrappers component stream-id))]]
+      )))
+
+
+(defn build-routes [component]
+  (mapcat (partial build-routes-for-stream component) (:priority (:config component))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;                                                                            ;;
+;;                          ---==| T O O L S |==----                          ;;
+;;                                                                            ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(def all-events-counter
+  "return a function which is a counter
+   when called without argument the counter is increased
+   when called with :current-value it returns its current
+   value.
+
+      (all-events-counter) ;; increase the counter
+
+      (all-events-counter :current-value)
+      ;; => {:count 11}
+
+  "
+  (let [tmp-registry (new-registry)
+        counter (binding [trk/*registry* tmp-registry]
+                  (count-tracker "events.all.counter"))]
+    (fn
+      ([]
+       (counter))
+      ([x]
+       (case x
+         :current-value
+         (binding [trk/*registry* tmp-registry]
+           (trk/get-metric "events.all.counter"))
+         :unknown)))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;                                                                            ;;
+;;                 ---==| * S C R A T C H   A R E A * |==----                 ;;
+;;                                                                            ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (comment
@@ -351,79 +553,37 @@
                        :partition 0
                        :message (to-json m)})))))

+  (def ingest
+    (doall
+     (->> (repeatedly
+           (fn []
+             {:timestamp (System/currentTimeMillis)
+              :eventName "test"
+              :sourceId (rand-nth ["d1" "d2" "d3"])
+              :action (rand-int 100)}))
+          (take 10)
+          (map (fn [x]
+                 {:topic "ingestion"
+                  :key   (:sourceId x)
+                  :partition 0
+                  :message x}))
+          (map #(update % :message to-json)))))
+
+  (def events (concat txlog ingest))
+
   (def cmp (component/start (make-samsara-core config)))
+  (reset! (:output-collector cmp) (fn [e] (doseq [x e] (prn "OUTPUT:" x)) ))
+
+  (build-routes cmp)
+
+  (build-routes-for-stream cmp :ingestion)

   (-> cmp :global-stores)

   (time ((dispatch-group-by
-          (build-routes-for-stream cmp :vod)) txlog))
+          (build-routes cmp)) events))

   )
-
-
-;; TODO: add :string and :bytes
-(defn format-wrapper
-  [format handler]
-  (case format
-    :json   (from-json-format-wrapper handler)
-    handler))
-
-
-
-(defn component-stream-processor-wrapper
-  [component stream-id handler]
-  (fn [values]
-    (handler {:component component :stream-id stream-id :events values})))
-
-
-
-(defn- standard-stream-wrappers
-  [component stream-id handler]
-  (let [{:keys [format input-partitions]} (stream-config component stream-id)]
-    (->> handler
-         (component-stream-processor-wrapper component stream-id)
-         (message-only-wrapper)
-         (format-wrapper format)
-         (partition-filter-wrapper input-partitions))))
-
-
-
-(defn build-routes-for-stream [component stream-id]
-  (let [{:keys [input-topic state-topic state]} (stream-config component stream-id)]
-    (cond
-
-      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-      ;; build route for partitioned topic with no state
-      (= state :none)
-      [;; add route to handle topic data
-       [(where :topic = input-topic)
-        (standard-stream-wrappers component stream-id println)]]
-
-
-      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-      ;; build route for partitioned topic with partitioned state
-      (= state :partitioned)
-      [;; add route to handle kv-store
-       [(where :topic = state-topic)
-        (standard-stream-wrappers component stream-id local-kv-restore)]
-       ;; add route to handle topic data
-       [(where :topic = input-topic)
-        (standard-stream-wrappers component stream-id println)]]
-
-
-      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-      ;; build route for global state
-      (= state :global)
-      [[(where :topic = input-topic)
-        (standard-stream-wrappers component stream-id global-kv-restore)]])))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;                                                                            ;;
-;;                 ---==| * S C R A T C H   A R E A * |==----                 ;;
-;;                                                                            ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Updated cide nrepl to 0.16.0

Updated cide nrepl to 0.16.0

--- web-app/project.clj
+++ web-app/project.clj
@@ -26,7 +26,7 @@
                                                                    ring/ring-core
                                                                    commons-fileupload
                                                                    clj-time]]
-                             [cider/cider-nrepl "0.15.0-SNAPSHOT" :exclusions [org.clojure/clojure
+                             [cider/cider-nrepl "0.16.0-SNAPSHOT" :exclusions [org.clojure/clojure
                                                                                org.clojure/tools.nrepl]]]}}

   :cljsbuild {:builds


Updated cider-nrepl version to 0.14

Updated cider-nrepl version to 0.14

--- web-app/project.clj
+++ web-app/project.clj
@@ -26,7 +26,7 @@
                                                                    ring/ring-core
                                                                    commons-fileupload
                                                                    clj-time]]
-                             [cider/cider-nrepl "0.13.0-SNAPSHOT" :exclusions [org.clojure/clojure
+                             [cider/cider-nrepl "0.14.0-SNAPSHOT" :exclusions [org.clojure/clojure
                                                                                org.clojure/tools.nrepl]]]}}

   :cljsbuild {:builds


bump some deps

bump some deps

--- build.boot
+++ build.boot
@@ -4,17 +4,17 @@
  :source-paths    #{"src/main"}
  :resource-paths  #{"resources"}
  :dependencies '[[org.clojure/clojurescript   "1.9.93"         :scope "provided"]
-                 [org.omcljs/om               "1.0.0-alpha40"  :scope "provided"]
-                 [com.ladderlife/cellophane   "0.3.4"          :scope "provided"]
-                 [com.cognitect/transit-clj   "0.8.285"        :scope "test"]
+                 [org.omcljs/om               "1.0.0-alpha41"  :scope "provided"]
+                 [com.ladderlife/cellophane   "0.3.5"          :scope "provided"]
+                 [com.cognitect/transit-clj   "0.8.288"        :scope "test"]
                  [devcards                    "0.2.1-7"        :scope "test"]
                  [com.cemerick/piggieback     "0.2.1"          :scope "test"]
                  [pandeiro/boot-http          "0.7.3"          :scope "test"]
                  [adzerk/boot-cljs            "1.7.228-1"      :scope "test"]
-                 [adzerk/boot-cljs-repl       "0.3.2"          :scope "test"]
+                 [adzerk/boot-cljs-repl       "0.3.3"          :scope "test"]
                  [adzerk/boot-test            "1.1.2"          :scope "test"]
                  [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]
-                 [adzerk/boot-reload          "0.4.11"          :scope "test"]
+                 [adzerk/boot-reload          "0.4.12"          :scope "test"]
                  [adzerk/bootlaces            "0.1.13"         :scope "test"]
                  [org.clojure/tools.nrepl     "0.2.12"         :scope "test"]
                  [org.clojure/tools.namespace "0.3.0-alpha3"   :scope "test"]


Cleaned up unnecessary method and enhanced button texts.

--- ccw.support.examples/src/ccw/support/labrepl/wizards/LabreplCreateProjectPage.clj
+++ ccw.support.examples/src/ccw/support/labrepl/wizards/LabreplCreateProjectPage.clj
@@ -17,16 +17,12 @@
   (:gen-class
    :extends org.eclipse.ui.dialogs.WizardNewProjectCreationPage
    :exposes-methods {createControl super-createControl}
-   :init myinit
-   :post-init mypostinit
+   :init init
    :state state))

-(defn- -myinit
+(defn- -init
   [page-name]
   [[page-name] (ref {})])
-
-(defn- -mypostinit
-  [_ page-name])

 (defn -createControl
   [this parent]
@@ -45,7 +41,7 @@
     (let [run-lein-deps-button (Button. composite SWT/CHECK)
           run-repl-button (Button. composite SWT/CHECK)]
       (doto run-lein-deps-button
-        (.setText "Run \"lein deps\" to download dependencies")
+        (.setText "Run \"lein deps\" to download dependencies (Internet connection required)")
         (.setSelection true)
         (.addSelectionListener
           (proxy [SelectionAdapter] []
@@ -53,7 +49,7 @@
               (.setEnabled run-repl-button (.getSelection run-lein-deps-button))))))

       (doto run-repl-button
-        (.setText "Run REPL and open web page")
+        (.setText "Run REPL and open tutorial web page")
         (.setSelection true))

       (dosync (alter (.state this) assoc :run-repl-button run-repl-button :run-lein-deps-button run-lein-deps-button))))


Typo in comments

Typo in comments

--- src/cljs/dato/lib/core.cljs
+++ src/cljs/dato/lib/core.cljs
@@ -68,7 +68,7 @@
                                                                                (if-let [cb-id (:server/rpc-id data)]
                                                                                (let [cb-or-ch (get @pending-rpc cb-id)]
                                                                                (swap! pending-rpc dissoc cb-id)
-                                                                                ;; Should we just pass the whole payload through, or just the data/resultts?
+                                                                                ;; Should we just pass the whole payload through, or just the data/results?
                                                                                (cond
                                                                                (chan? cb-or-ch) (put! cb-or-ch (:data data))
                                                                                (fn? cb-or-ch)   (cb-or-ch (:data data))


whitespace

whitespace

--- src/cljs/dato/lib/core.cljs
+++ src/cljs/dato/lib/core.cljs
@@ -42,6 +42,7 @@
   (dsu/qe-by db :dato.meta/bootrapped? true))

 (defmulti ws-message-handler (fn [dato-ch msg] (:op msg)))
+
 (defmethod ws-message-handler :default
   [dato-ch msg]
   ;; TODO replace the dato-ch handler with this


Computing the edges of a lattice the naïve way again

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

--- src/conexp/layouts/util.clj
+++ src/conexp/layouts/util.clj
@@ -9,7 +9,7 @@
 (ns conexp.layouts.util
   (:use conexp.base
         [conexp.layouts.base :only (make-layout, positions, connections, update-positions)]
-        [conexp.fca.lattices :only (base-set, directly-neighboured?, order)])
+        conexp.fca.lattices)
   (:require [clojure.contrib.graph :as graph]))

 (ns-doc
@@ -90,10 +90,9 @@
   "Returns a sequence of pairs of vertices of lattice which are
   directly neighbored in lattice."
   [lattice]
-  (seq (transitive-reduction (base-set lattice)
-                             (let [<= (order lattice)]
-                               #(and (<= %1 %2)
-                                     (not= %1 %2))))))
+  (set-of [x y] [x (base-set lattice),
+                 y (base-set lattice),
+                 :when (directly-neighboured? lattice x y)]))

 (defn top-down-elements-in-layout
   "Returns the elements in layout ordered top down."


Add support for export pages with images.

--- src/uxbox/main/exports.cljs
+++ src/uxbox/main/exports.cljs
@@ -13,7 +13,10 @@
             [uxbox.main.ui.shapes.group :refer (group-shape)]
             [uxbox.main.ui.shapes.path :refer (path-shape)]
             [uxbox.main.ui.shapes.circle :refer (circle-shape)]
+            [uxbox.main.ui.shapes.image :refer (image-shape)]
             [uxbox.util.mixins :as mx :include-macros true]))
+
+(def ^:dynamic *state* st/state)

 (mx/defc background
   []
@@ -34,17 +37,21 @@
     :icon (icon-shape s)
     :rect (rect-shape s)
     :path (path-shape s)
-    :circle (circle-shape s)))
+    :circle (circle-shape s)
+    :image (let [image-id (:image s)
+                 image (get-in @*state* [:images-by-id image-id])]
+             (image-shape (assoc s :image image)))))

 (mx/defc shape
   [sid]
-  (shape* (get-in @st/state [:shapes-by-id sid])))
+  (shape* (get-in @*state* [:shapes-by-id sid])))

 (mx/defc page-svg
   [{:keys [width height] :as page}]
   [:svg {:width width
          :height height
          :version "1.1"
+         :xmlnsXlink "http://www.w3.org/1999/xlink"
          :xmlns "http://www.w3.org/2000/svg"}
    (background)
    (for [item (reverse (:shapes page))]


Refactoring: no defs inside let bindings

Instead keep everything contained within the let-binding of the start-communicator function.

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/communicator.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/communicator.cljs
@@ -8,12 +8,6 @@
 (def packer
   "Defines our packing (serialization) format for client<->server comms."
   (sente-transit/get-flexi-packer :json))
-
-(let [{:keys [chsk ch-recv send-fn state]} (sente/make-channel-socket! "/chsk" {:packer packer :type :auto})]
-  (def chsk       chsk)
-  (def ch-chsk    ch-recv) ; ChannelSocket's receive channel
-  (def chsk-send! send-fn) ; ChannelSocket's send API fn
-  (def chsk-state state))  ; Watchable, read-only atom

 (defn make-handler
   "Create handler function for messages from WebSocket connection, wire channels and the
@@ -32,23 +26,20 @@
                :default (print "unmatched message" payload)))
            :else (print "Unmatched event: %s" event))))

-(defn start-router
-  "Start router after creating the handler with the provided start-function and channels."
-  [cmd-chan data-chan stats-chan]
-  (let [handler (make-handler cmd-chan data-chan stats-chan)]
-    (defonce chsk-router (sente/start-chsk-router! ch-chsk handler))))
-
 (defn query-loop
   "Take command / query message off of channel, enrich payload with :uid of current
    WebSocket connection and send to server. Channel is injected when loop is started."
-  [channel]
+  [channel send-fn chsk-state]
   (go-loop []
            (let [[cmd-type payload] (<! channel)]
-             (chsk-send! [cmd-type (assoc payload :uid (:uid @chsk-state))])
+             (send-fn [cmd-type (assoc payload :uid (:uid @chsk-state))])
              (recur))))

 (defn start-communicator
   "Start communicator by wiring channels."
   [cmd-chan data-chan stats-chan qry-chan]
-  (start-router cmd-chan data-chan stats-chan)
-  (query-loop qry-chan))
+  (let [ws (sente/make-channel-socket! "/chsk" {:packer packer :type :auto})
+        {:keys [chsk ch-recv send-fn state]} ws
+        handler (make-handler cmd-chan data-chan stats-chan)
+        chsk-router (sente/start-chsk-router! ch-recv handler)]
+    (query-loop qry-chan send-fn state)))


Remove unnecessary require

Remove unnecessary require

--- desktop/src/nightmod/core/desktop_launcher.clj
+++ desktop/src/nightmod/core/desktop_launcher.clj
@@ -2,7 +2,6 @@
   (:require [clojure.java.io :as io]
             [nightmod.core :refer :all]
             [nightcode.editors :as editors]
-            [nightcode.dialogs :as dialogs]
             [nightcode.shortcuts :as shortcuts]
             [nightcode.ui :as ui]
             [nightcode.utils :as utils]


Housekeeping

Housekeeping

--- src/taoensso/carmine/protocol.clj
+++ src/taoensso/carmine/protocol.clj
@@ -105,11 +105,11 @@
   Redis will reply to commands with different kinds of replies. It is possible
   to check the kind of reply from the first byte sent by the server:

-      * With a single line reply the first byte of the reply will be `+`
-      * With an error message the first byte of the reply will be `-`
-      * With an integer number the first byte of the reply will be `:`
-      * With bulk reply the first byte of the reply will be `$`
-      * With multi-bulk reply the first byte of the reply will be `*`"
+      * `+` for single line reply.
+      * `-` for error message.
+      * `:` for integer reply.
+      * `$` for bulk reply.
+      * `*` for multi-bulk reply."
   [^DataInputStream in]
   (let [reply-type (char (.readByte in))]
     (case reply-type


Allow _ in history token.

Allow _ in history token.

--- src-cljs/kixi/hecuba/history.cljs
+++ src-cljs/kixi/hecuba/history.cljs
@@ -11,7 +11,7 @@
 (enable-console-print!)

 (defn match-token [s]
-  (re-matches #"((?:[A-Za-z0-9-;]+)(?:,(?:[A-Za-z0-9;-]+))*)(?:/search/(.*))?" s))
+  (re-matches #"((?:[A-Za-z0-9-_;]+)(?:,(?:[A-Za-z0-9-_;]+))*)(?:/search/(.*))?" s))

 ;; TODO let's not use an atom for this.
 (def ^:private key-order (atom []))