Made make-implication to subtract premise from conclusion

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

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -25,8 +25,12 @@
        (= (premise this) (premise other))
        (= (conclusion this) (conclusion other))))

-(defn make-implication [premise conclusion]
-  (conexp.fca.Implication. (set premise) (set conclusion)))
+(defn make-implication
+  "Creates an implication (premise => conclusion \\setminus premise)."
+  [premise conclusion]
+  (let [premise (set premise)
+	conclusion (set conclusion)]
+    (conexp.fca.Implication. premise (difference conclusion premise))))

 (defn respects? [set impl]
   (or (not (subset? (premise impl) set))


Added tab-newline-string copy and paste support to table control

--- src/conexp/gui/editors/util.clj
+++ src/conexp/gui/editors/util.clj
@@ -18,7 +18,8 @@
     [javax.swing.event TreeSelectionListener]
     [javax.swing.table DefaultTableModel])
   (:use clojure.contrib.swing-utils
-    conexp.gui.util))
+    conexp.gui.util
+    [clojure.contrib.string :only (join split-lines split)]))

 ;;;
 ;;; General purpose & macros
@@ -483,8 +484,44 @@
          defaults [ [:set-resize-mode :off]
                     [:set-cell-selection-mode :cells]
                     [:register-keyboard-action
-                      (fn [x] (message-box "Control-C"))
+                      (fn-swing-threads* [obj]
+                        (let [control (get-control obj)
+                              sel-columns ((*comp (rho .getSelectedColumns) extract-array)
+                                           control)
+                              sel-rows ((*comp (rho .getSelectedRows) extract-array)
+                                           control)
+                              sel-pairs (map (fn [y] (map (fn [x] (list y x)) sel-columns))
+                                             sel-rows)
+                              sel-values (map (fn [l] (map (fn [p] (str (.getValueAt control
+                                                                                (first p)
+                                                                                (second p)))) l))
+                                              sel-pairs)
+                              sel-lines (map (rho join "\t") sel-values)
+                              selection (join "\n" sel-lines)]
+                          (set-clipboard-contents selection)))
                       "Copy" keystroke-copy :focus]
+                    [:register-keyboard-action
+                      (fn-swing-threads* [obj]
+                        (let [control (get-control obj)
+                              sel-columns ((*comp (rho .getSelectedColumns) extract-array)
+                                           control)
+                              sel-rows ((*comp (rho .getSelectedRows) extract-array)
+                                           control)]
+                          (if (or (empty? sel-columns) (empty? sel-rows)) nil
+                              (let [data (str (get-clipboard-contents))
+                                    startx (first sel-columns)
+                                    starty (first sel-rows)
+                                    cells (vec (map (*comp (rho split #"\t") (rho vec))
+                                               (split-lines data)))
+                                    lns (range (count cells))]
+                                (one-by-one lns (fn [r]
+                                                  (one-by-one (range (count (cells r)))
+                                                              (fn [c]
+                                                                (.setValueAt control
+                                                                             ((cells r) c)
+                                                                             (+ starty r)
+                                                                             (+ startx c))))))))))
+                      "Paste" keystroke-paste :focus]
                     ]]
     (do
       (deliver self widget)


Add regression tests for ninjudd's recent fixes

--- test/useful/seq_test.clj
+++ test/useful/seq_test.clj
@@ -62,13 +62,22 @@
   (is (= (range 10)
          (lazy-loop [i 0]
            (when-not (= i 10)
-             (cons i (lazy-recur (inc i))))))))
+             (cons i (lazy-recur (inc i)))))))
+  (testing "0-arg lazy-loop"
+    (is (= [1 1 1] (take 3
+                         (lazy-loop []
+                           (cons 1 (lazy-recur))))))))

 (deftest test-alternates
   (is (= '[[a b] [1 2]]
          (alternates '[a 1 b 2])))
   (is (= '[[0 3 6] [1 4 7] [2 5 8]]
-         (alternates 3 (range 9)))))
+         (alternates 3 (range 9))))
+  (testing "Doesn't blow up for empty seqs"
+    (let [a (alternates [])]
+      (testing "Lazy if nothing forced."
+        (is a))
+      (is (not (seq a))))))

 (deftest test-slice
   (let [size 900, slices 7, coll (range size),


fix regression with renaming

fix regression with renaming

--- src/io/perun/sitemap.clj
+++ src/io/perun/sitemap.clj
@@ -22,7 +22,7 @@
     files))

 (defn generate-sitemap [tgt-path files options]
-  (let [sitemap-filepath (str (:target options) "/" (:filename options))
+  (let [sitemap-filepath (str (:out-dir options) "/" (:filename options))
         sitemap-xml      (create-sitemap files)
         sitemap-string   (sitemap-gen/generate-sitemap sitemap-xml)]
     (perun/create-file tgt-path sitemap-filepath sitemap-string)


[boot] fix a classpath conflict

[boot] fix a classpath conflict

--- .boot/profile.boot
+++ .boot/profile.boot
@@ -7,10 +7,12 @@
        'cider.nrepl/cider-middleware
        'refactor-nrepl.middleware/wrap-refactor)

+(set-env! :dependencies '[[sparkfund/boot-lein "0.4.0"]
+                          [vvvvalvalval/scope-capture "0.3.2"
+                           :exclusions [org.clojure/clojure]]])
+
 ;; for boot in IntelliJ
-(set-env! :dependencies '[[sparkfund/boot-lein "0.4.0"]])
 ;; boot-lein: `boot write-project-clj` task directly accessible
 (require '[sparkfund.boot-lein :refer [write-project-clj]])

-(set-env! :dependencies #(conj % '[vvvvalvalval/scope-capture "0.3.2"]))
 (require 'sc.api)


show a list of pending invitations on the new game page

--- src/greybear/pages/new_game.clj
+++ src/greybear/pages/new_game.clj
@@ -22,8 +22,24 @@
         [greybear.model.game-invitations]
         [greybear.utils :only [parse-int]]
         [greybear.pages.helpers :only [get-user-id]]
-        [greybear.pages.layout :only [base-layout]]
-        [greybear.pages.games :only [games-partial]]))
+        [greybear.pages.layout :only [base-layout]]))
+
+
+(defn players-list
+  "Outputs a list of players with some information about each"
+  [players]
+  [:div.row
+   [:table.table.table-striped
+    [:thead
+     [:tr
+      [:th "#"]
+      [:th "Username"]]
+     ]
+    [:tbody
+     (for [[idx player] (map-indexed vector players)]
+       [:tr
+        [:td (+ idx 1)]
+        [:td (:name player)]])]]])

 (defn new-game [request]
   (friend/authenticated
@@ -40,7 +56,11 @@
                   ]
                  [:div.col-md-3]]
                 [:div.row
-                 (games-partial)])))
+                 [:div.col-md-1]
+                 [:div.col-md-10
+                  [:p "Pending invitations: "]
+                  (players-list (invited-by (get-user-id request)))]
+                 [:div.col-md-1]])))

 (defn new-game-post [params]
   (friend/authenticated


added response codes, modified a token generator

--- src/ttt/handler.clj
+++ src/ttt/handler.clj
@@ -10,23 +10,25 @@

 (cheshire.generate/add-encoder org.bson.types.ObjectId cheshire.generate/encode-str)

-(def empty-field 0)
-
 (defn generate
   "generates a unique token for the game"
   []
-  (str (System/currentTimeMillis)))
+  (let [acc [(str (System/currentTimeMillis))]]
+    (loop [x 10 acc acc]
+      (if (= x 0)
+        (clojure.string/join "" acc)
+        (recur (- x 2) (cons (str (rand-int 10000)) acc))))))

 (defn fail
   "returns a serialized json with error description"
   [error]
   (case error
-    :wrong-turn (generate-string {:error "wrong turn"})
-    :occupied-cell (generate-string {:error "the cell is already occupied"})
-    :invalid-state (generate-string {:error "invalid state"})
-    :not-found (generate-string {:error "resource not found"})
-    :not-implemented (generate-string {:error "not implemented"})
-    :bad-request (generate-string {:error "bad request"})
+    :wrong-turn {:status 400 :body (generate-string {:error "wrong turn"})}
+    :occupied-cell {:status 400 :body (generate-string {:error "the cell is already occupied"})}
+    :invalid-state {:status 400 :body (generate-string {:error "invalid state"})}
+    :not-found {:status 404 :body (generate-string {:error "resource not found"})}
+    :not-implemented {:status 501 :body (generate-string {:error "not implemented"})}
+    :bad-request  {:status 400 :body (generate-string {:error "bad request"})}
     (generate-string {:error "unknown error"})))

 (let [conn (mg/connect)
@@ -42,10 +44,17 @@
   (defn new-game
     "Creates a new game"
     [body]
-    (let [{type "type" password "password"} body]
+    (let [empty-field 0
+          {type "type" password "password"} body]
       (case type
-        0 (generate-string
-            (mc/insert-and-return db coll {:token (generate) :type type :field1 empty-field :field2 empty-field :state :first-player-turn}))
+        0 {:status 201
+           :body (generate-string
+                   (mc/insert-and-return db coll {
+                                                   :token (generate)
+                                                   :type type
+                                                   :field1 empty-field
+                                                   :field2 empty-field
+                                                   :state :first-player-turn}))}
         1 (fail :not-implemented)
         (fail :bad-request))))

@@ -56,7 +65,7 @@
         (mc/find-one db coll {:token id} [:token :state :field1 :field2]) false))

   (defn win? [field]
-    "determins if the field has a winning situation"
+    "determines if the field has a winning situation"
     (cond
       (= (bit-and field 7) 7) true
       (= (bit-and field 56) 56) true


avoids NPE due to missing status in work-stealing response (#635)

--- waiter/src/waiter/work_stealing.clj
+++ waiter/src/waiter/work_stealing.clj
@@ -243,13 +243,9 @@
             [{:keys [request-id target-router-id] :as reservation-parameters} cleanup-chan]
             (async/go
               (let [response-result-promise (promise)
-                    response->body (fn [{:keys [body error]}]
-                                     (if error
-                                       (throw error)
-                                       body))
                     default-response-result "work-stealing-error"]
                 (try
-                  (let [{:keys [headers status] :as inter-router-response}
+                  (let [{:keys [body error headers status] :as inter-router-response}
                         (-> (make-inter-router-requests-fn "work-stealing"
                                                            :acceptable-router? #(= target-router-id %)
                                                            :body (-> reservation-parameters
@@ -260,9 +256,10 @@
                                                            :method :post)
                             (get target-router-id)
                             async/<!)
-                        response-result (if (and inter-router-response (<= 200 status 299))
-                                          (-> inter-router-response
-                                              response->body
+                        _ (when error
+                            (throw error))
+                        response-result (if (and inter-router-response status (<= 200 status 299))
+                                          (-> body
                                               async/<! ;; rely on http client library to close the body
                                               str
                                               json/read-str


include path in NaN line exception map

include path in NaN line exception map

--- src/io/cyanite/input/carbon.clj
+++ src/io/cyanite/input/carbon.clj
@@ -19,7 +19,9 @@
       (throw (ex-info "invalid carbon line: missing fields" {:line line}))

       (re-find #"(?i)nan" metric)
-      (throw (ex-info (str "invalid carbon line: NaN metric for path:" path) {:line line})))
+      (throw (ex-info (str "invalid carbon line: NaN metric for path:" path)
+                      {:line line
+                       :path path})))
     (let [metric (try (Double. metric)
                       (catch NumberFormatException e
                         (throw (ex-info "invalid metric" {:metric metric}))))


better code gen for implements?, avoid generating closures

--- src/main/clojure/cljs/core.cljc
+++ src/main/clojure/cljs/core.cljc
@@ -1845,13 +1845,19 @@
              [part bit] (fast-path-protocols p)
              msym       (symbol
                           (core/str "-cljs$lang$protocol_mask$partition" part "$"))]
-    `(let [~xsym ~x]
-       (if ~xsym
-         (let [bit# ~(if bit `(unsafe-bit-and (. ~xsym ~msym) ~bit))]
-           (if (or bit#
-                 ~(bool-expr `(. ~xsym ~(symbol (core/str "-" prefix)))))
+    (if-not (core/symbol? x)
+      `(let [~xsym ~x]
+         (if ~xsym
+           (if (or ~(if bit `(unsafe-bit-and (. ~xsym ~msym) ~bit) false)
+                   ~(bool-expr `(. ~xsym ~(symbol (core/str "-" prefix)))))
              true
-             false))
+             false)
+           false))
+      `(if-not (nil? ~x)
+         (if (or ~(if bit `(unsafe-bit-and (. ~x ~msym) ~bit) false)
+                 ~(bool-expr `(. ~x ~(symbol (core/str "-" prefix)))))
+           true
+           false)
          false))))

 (core/defmacro satisfies?


Clean up: arg names, ns layout

Clean up: arg names, ns layout

--- src/me/shenfeng/http/server.clj
+++ src/me/shenfeng/http/server.clj
@@ -4,11 +4,7 @@
            javax.xml.bind.DatatypeConverter
            java.security.MessageDigest))

-(defn accept [key]
-  (let [md (MessageDigest/getInstance "SHA1")
-        websocket-13-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"]
-    (DatatypeConverter/printBase64Binary
-     (.digest md (.getBytes ^String (str key websocket-13-guid))))))
+;;;; Ring server

 (defn run-server
   [handler {:keys [port thread ip max-body max-line worker-name-prefix]
@@ -21,39 +17,48 @@
   (let [h (RingHandler. thread handler worker-name-prefix)
         s (HttpServer. ip port h max-body max-line)]
     (.start s)
-    ;; return a function to stop this server
-    (fn [] (.close h) (.stop s))))
+    (fn stop-server [] (.close h) (.stop s))))

-(defmacro defasync [name [req] cb & body]
-  `(defn ~name [~req]
+;;;; Asynchronous extension
+
+(defmacro defasync [name [request] callback-name & body]
+  `(defn ~name [~request]
      {:status 200
       :headers {}
       :body (let [data# (atom {})
-                  ~cb (fn [resp#]
-                        (reset! data# (assoc @data# :r resp#))
-                        (when-let [l# ^Runnable (:l @data#)]
-                          (.run l#)))]
+                  ~callback-name
+                  (fn [response#]
+                    (reset! data# (assoc @data# :response response#))
+                    (when-let [listener# ^Runnable (:listener @data#)]
+                      (.run listener#)))]
               (do ~@body)
               (reify IListenableFuture
                 (addListener [this# listener#]
-                  (if-let [d# (:r @data#)]
+                  (if-let [d# (:response @data#)]
                     (.run ^Runnable listener#)
-                    (reset! data# (assoc @data# :l listener#))))
-                (get [this#]
-                  (:r @data#))))}))
+                    (reset! data# (assoc @data# :listener listener#))))
+                (get [this#] (:response @data#))))}))

-(defn on-mesg   [^WsCon con fn]  (.addRecieveListener con fn))
-(defn on-close  [^WsCon con fn]  (.addOnCloseListener con fn))
-(defn send-mesg [^WsCon con msg] (.send con msg))
+;;;; WebSockets
+
+(defn accept [key]
+  (let [md (MessageDigest/getInstance "SHA1")
+        websocket-13-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"]
+    (DatatypeConverter/printBase64Binary
+     (.digest md (.getBytes (str key websocket-13-guid))))))
+
+(defn on-mesg   [^WsCon conn fn]  (.addRecieveListener conn fn))
+(defn on-close  [^WsCon conn fn]  (.addOnCloseListener conn fn))
+(defn send-mesg [^WsCon conn msg] (.send conn msg))
 (defn close-conn
-  ([con]        (.serverClose ^WsCon con))
-  ([con status] (.serverClose ^WsCon con status)))
+  ([^WsCon conn]        (.serverClose conn))
+  ([^WsCon conn status] (.serverClose conn status)))

-(defmacro defwshandler [name [req] con & body]
-  `(defn ~name [~req]
-     (let [~con (:websocket ~req)
-           key# (get-in ~req [:headers "sec-websocket-key"])]
-       (if (and ~con key#)
+(defmacro defwshandler [name [request] conn-name & body]
+  `(defn ~name [~request]
+     (let [~conn-name (:websocket ~request)
+           key# (get-in ~request [:headers "sec-websocket-key"])]
+       (if (and ~conn-name key#)
          (do ~@body
              {:status 101
               :headers {"Upgrade" "websocket"
@@ -63,4 +68,4 @@
                         }})
          {:status 400
           :headers {}
-          :body "websocket expected"}))))+          :body "Websocket expected"}))))


[#3576] Fix tests

[#3576] Fix tests

--- api/test/clojure/org/akvo/flow_api/datastore/survey_test.clj
+++ api/test/clojure/org/akvo/flow_api/datastore/survey_test.clj
@@ -39,7 +39,7 @@
         survey #{:id :name :forms :registration-form-id}
         form #{:id :name :question-groups}
         question-group #{:id :name :repeatable :questions}
-        question #{:id :name :type :order}))))
+        question #{:id :name :type :order :personal-data}))))

 (deftest list-authorized-forms
   (ds/with-remote-api (:remote-api fixtures/*system*) "akvoflowsandbox"


Upgrade noderepl.

Upgrade noderepl.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -9,7 +9,7 @@
         :plugins [[lein-difftest "1.3.7"]
                   [lein-exec "0.3.0"]
                   [com.aphyr/prism "0.1.1"]
-                  [org.bodil/lein-noderepl "0.1.10"]
+                  [org.bodil/lein-noderepl "0.1.11"]
                   [quickie "0.2.1"]
                   [lein-kibit "0.0.8"]
                   [lein-clojars "0.9.1"]


[#3086] Clean groupName and groupId on merge-dataset

--- backend/src/akvo/lumen/lib/transformation/merge_datasets.clj
+++ backend/src/akvo/lumen/lib/transformation/merge_datasets.clj
@@ -249,7 +249,8 @@
   (let [source (get-in op-spec ["args" "source"])
         target (get-in op-spec ["args" "target"])
         source-dataset (get-source-dataset conn source)
-        source-merge-columns (get-source-merge-columns source (:columns source-dataset))
+        source-merge-columns (->> (get-source-merge-columns source (:columns source-dataset))
+                                  (map #(dissoc % "groupId" "groupName")))
         column-names-translation (merge-column-names-map columns
                                                          source-merge-columns)
         target-merge-columns (get-target-merge-columns source-merge-columns


Put mobile group open button on the far left

--- src/braid/client/mobile/views.cljs
+++ src/braid/client/mobile/views.cljs
@@ -69,10 +69,10 @@
     (fn [_]
       [:div.group-header {:style {:background-color (->color @group-id)}}
        [:div.bar
+        [:span.buttons
+         [:a.open-sidebar {:on-click (fn [] (a/put! toggle-draw-ch true))}]]
         [:span.badge-wrapper [sidebar/badge-view @group-id]]
         [group-name-view]
-        [:span.buttons
-         [:a.open-sidebar {:on-click (fn [] (a/put! toggle-draw-ch true))}]]
         [:span.spacer]
         [group-header-buttons-view [{:title "Inbox"
                                      :route-fn routes/inbox-page-path


don't close over owner and thread

don't close over owner and thread

--- src/chat/client/views/threads.cljs
+++ src/chat/client/views/threads.cljs
@@ -59,17 +59,17 @@

 (defn thread-view [thread owner {:keys [searched?] :as opts}]
   (let [scroll-to-bottom
-        (fn []
+        (fn [owner thread]
           (when-not (thread :new?) ; need this here b/c get-node breaks if no refs???
             (when-let [messages (om/get-node owner "messages")]
               (set! (.-scrollTop messages) (.-scrollHeight messages)))))]
     (reify
       om/IDidMount
       (did-mount [_]
-        (scroll-to-bottom))
+        (scroll-to-bottom owner thread))
       om/IDidUpdate
       (did-update [_ _ _]
-        (scroll-to-bottom))
+        (scroll-to-bottom owner thread))
       om/IRender
       (render [_]
         (dom/div #js {:className "thread"}


fix setting data for ephemeral nodes if there's a timeout after checking for existence. switch task heartbeats to non-ephemeral zk nodes

--- src/clj/backtype/storm/cluster.clj
+++ src/clj/backtype/storm/cluster.clj
@@ -1,6 +1,6 @@
 (ns backtype.storm.cluster
   (:import [org.apache.zookeeper.data Stat])
-  (:import [org.apache.zookeeper KeeperException])
+  (:import [org.apache.zookeeper KeeperException KeeperException$NoNodeException])
   (:import [backtype.storm.utils Utils])
   (:use [backtype.storm util log config])
   (:use [clojure.contrib.core :only [dissoc-in]])
@@ -50,7 +50,12 @@
      (set-ephemeral-node [this path data]
                          (zk/mkdirs zk (parent-path path))
                          (if (zk/exists zk path false)
-                           (zk/set-data zk path data) ; should verify that it's ephemeral
+                           (try-cause
+                             (zk/set-data zk path data) ; should verify that it's ephemeral
+                             (catch KeeperException$NoNodeException e
+                               (log-warn-error e "Ephemeral node disappeared between checking for existing and setting data")
+                               (zk/create-node zk path data :ephemeral)
+                               ))
                            (zk/create-node zk path data :ephemeral)
                            ))

@@ -269,7 +274,7 @@
         )

       (task-heartbeat! [this storm-id task-id info]
-        (set-ephemeral-node cluster-state (taskbeat-path storm-id task-id) (Utils/serialize info))
+        (set-data cluster-state (taskbeat-path storm-id task-id) (Utils/serialize info))
         )

       (remove-task-heartbeat! [this storm-id task-id]


Double metaphone lookup steps

Double metaphone lookup steps

--- src/clj_fuzzy/double_metaphone.clj
+++ src/clj_fuzzy/double_metaphone.clj
@@ -18,6 +18,7 @@
 (defn- vowel? [string] (re-test? #"^A|E|I|O|U|Y$" string))

 (def ^:private not-re-test? (complement re-test?))
+

 ;; Steps
 (defn- lookup-vowel [string pos] (if (= 0 pos) [:A :A 1] [nil nil 1]))
@@ -203,4 +204,143 @@
     (lookup-L-1 string pos length lastp)
     [:L :L 1]))

-(comment "")
+(defn- lookup-M [string pos lastp]
+  (if (or (and (= "UMB" (slice string (- pos 1) 3))
+               (or (= (dec lastp) pos)
+                   (= "ER" (slice string (+ pos 2) 2))))
+          (= "M" (slice string (+ pos 1) 1)))
+    [:M :M 2]
+    [:M :M 1]))
+
+(defn- lookup-N [string pos]
+  [:N :N (if (= "N" (slice string (+ pos 1) 1)) 2 1)])
+
+(defn- lookup-NY [string pos]
+  [:N :N 1])
+
+(defn- lookup-P [string pos]
+  (if (= "H" (slice string (+ pos 1) 1))
+    [:F :F 2]
+    [:P :P (if (re-test? #"^P|B$" (slice string (+ pos 1) 1)) 2 1)]))
+
+(defn- lookup-Q [string pos]
+  [:K :K (if (= "Q" (slice string (+ pos 1) 1)) 2 1)])
+
+(defn- lookup-R [string pos lastp]
+  (let [current (if (= "R" (slice string (+ pos 1) 1)) 2 1)]
+    (if (and (= lastp pos)
+             (slavo-germanic? string)
+             (= "IE" (slice string (- pos 2) 2))
+             (not-re-test? #"^M(E|A)$" (slice string (- pos 4) 2)))
+      [nil :R current]
+      [:R :R current])))
+
+(defn- lookup-S-1 [] [nil nil 1])
+
+(defn- lookup-S-2 [] [:X :S 1])
+
+(defn- lookup-S-3 [string pos]
+  (if (re-test? #"^H(EIM|OEK|OLM|OLZ)$" (slice string (+ pos 1) 4))
+    [:S :S 2]
+    [:X :X 2]))
+
+(defn- lookup-S-4 [string]
+  [:S (if (slavo-germanic? string) :S :X) 3])
+
+(defn- lookup-S-5 [string pos]
+  [:S :X (if (= "Z" (slice string (+ pos 1) 1)) 2 1)])
+
+(defn- lookup-S-6 [string pos]
+  (cond (= "H" (slice (+ pos 2) 1)) (if (re-test? #"^OO|ER|EN|UY|ED|EM$" (slice string (+ pos 3) 2))
+                                      [(if (re-test? #"^E(R|N)$" (slice string (+ pos 3) 2)) :X :SK) :SK 3]
+                                      [:X (if (and (= pos 0)
+                                                   (vowel? (slice string 3 1))
+                                                   (not= "W" (slice string (+ pos 3) 1))) :S :X) 3])
+        (re-test? #"^I|E|Y$" (slice string (+ pos 2) 1)) [:S :S 3]
+        :else [:SK :SK 3]))
+
+(defn- lookup-S [string pos lastp]
+  (cond (re-test? #"" (slice string (- pos 1) 3)) (lookup-S-1)
+        (and (= pos 0)
+             (= "SUGAR" (slice (string pos 5)))) (lookup-S-2)
+        (= "SH" (slice string pos 2)) (lookup-S-3 string pos)
+        (or (re-test? #"^SI(O|A)$" (slice string pos 3))
+            (= "SIAN" (slice string pos 4))) (lookup-S-4 string)
+        (or (and (= pos 0)
+                 (re-test? #"^M|N|L|W$" (slice string (+ pos 1) 1)))
+            (= "Z" (slice (+ pos 1)) 1)) (lookup-S-5 string pos)
+        (= "SC" (slice string pos 2)) (lookup-S-6 string pos)
+        :else [(if (and (= lastp pos) (re-test? #"^(A|O)I$" (slice string (- pos 2) 2))) nil :S)
+               :S
+               (if (re-test? #"^(A|O)I$" (slice string (+ pos 1) 1)) 2 1)]))
+
+(defn- lookup-T-1 [] [:X :X 3])
+
+(defn- lookup-T-2 [string pos]
+  (if (or (re-test? #"^(O|A)M$" (slice string (+ pos 2) 2))
+          (re-test? #"^V(A|O)N " (slice string 0 4))
+          (= "SCH" (slice string 0 3)))
+    [:T :T 2]
+    [0 :T 2]))
+
+(defn- lookup-T [string pos]
+  (cond (= "TION" (slice string pos 4)) (lookup-T-1)
+        (re-test? #"^T(IA|CH)$" (slice string pos 3)) (lookup-T-1)
+        (or (= "TH" (slice string pos 2))
+            (= "TTH" (slice string pos 3))) (lookup-T-2 string pos)
+        :else [:T :T (if (re-test? #"^T|D$" (slice string (+ pos 1) 1)) 2 1)]))
+
+(defn- lookup-V [string pos]
+  [:F :F (if (= "V" (slice string (+ pos 1) 1)) 2 1)])
+
+(defn- let-lookup-W [string pos]
+  (if (or (and (= pos 0)
+               (vowel? (slice string (+ pos 1) 1)))
+          (= "WH" (slice string pos 2)))
+    ["A" (if (vowel? (slice string (+ pos 1) 1)) "F" "A")]
+    [nil nil]))
+
+(defn- lookup-W-1 [] [:R :R 2])
+
+(defn- lookup-W-2 [pri sec]
+  [(keyword pri) (keyword (str sec "F")) 1])
+
+(defn- lookup-W-3 [pri sec]
+  [(keyword (str pri "TS")) (keyword (str sec "FX")) 4])
+
+(defn- lookup-W [string pos lastp]
+  (if (= "WR" (slice string pos 2))
+    (lookup-W-1)
+    (let [[pri sec] (let-lookup-W string pos)]
+      (cond (or (and (= lastp pos) (vowel? (slice string (- pos 1) 1)))
+                (= "SCH" (slice string 0 3))
+                (re-test? #"^EWSKI|EWSKY|OWSKI|OWSKY$" (slice string (- pos 1) 5))) (lookup-W-2 pri sec)
+            (re-test? #"^WI(C|T)Z$" (slice string pos 4)) (lookup-W-3 pri sec)
+            :else [(keyword pri) (keyword sec) 1]))))
+
+(defn- lookup-X [string pos lastp]
+  (let [current (if (re-test? #"^C|X$" (slice string (+ pos 1))) 2 1)]
+    (if (not (and (= lastp pos)
+                  (or (re-test? #"^(I|E)AU$" (slice string (- pos 3) 3))
+                      (re-test? #"^(A|O)U$" (slice string (- pos 2) 2)))))
+      [:KS :KS current]
+      [nil nil current])))
+
+(defn- lookup-Z-1 [] [:J :J 2])
+
+(defn- lookup-Z-2 [current] [:S :TS current])
+
+(defn- lookup-Z-3 [current] [:S :S current])
+
+(defn- lookup-Z [string pos]
+  (if (="H" (slice string (+ pos 1) 1))
+    (lookup-Z-1)
+    (let [current (if (= "Z" (slice string (+ pos 1) 1)) 2 1)]
+      (if (or (re-test? #"^Z(O|I|A)$" (slice string (+ pos 1) 2))
+              (and (slavo-germanic? string)
+                   (> pos 0)
+                   (not= "T" (slice string (- pos 1) 1))))
+        (lookup-Z-2 current)
+        (lookup-Z-3 current)))))
+
+;; FINAL nil nil 1


add basic NONE removal tests

add basic NONE removal tests

--- test/com/rpl/specter/core_test.cljc
+++ test/com/rpl/specter/core_test.cljc
@@ -1317,3 +1317,13 @@

 (deftest traversed-test
   (is (= 10 (select-any (s/traversed s/ALL +) [1 2 3 4]))))
+
+(defn- predand= [pred ret v]
+  (and (pred ret)
+       (= ret v)))
+
+(deftest remove-with-NONE-test
+  (is (predand= vector? [1 2 3] (setval [s/ALL nil?] s/NONE [1 2 nil 3 nil])))
+  (is (predand= list? '(1 2 3) (setval [s/ALL nil?] s/NONE '(1 2 nil 3 nil))))
+
+  )


test improvements

test improvements

--- test/com/rpl/specter/core_test.cljx
+++ test/com/rpl/specter/core_test.cljx
@@ -248,7 +248,7 @@
      afn (gen/elements [inc dec #(* % 2)])
      bfn (gen/elements [inc dec #(* % 2)])
      cfn (gen/elements [inc dec #(* % 2)])]
-    (and (= (first (s/select (s/parser afn bfn) i))
+    (and (= (s/select-one! (s/parser afn bfn) i)
             (afn i))
          (= (s/transform (s/parser afn bfn) cfn i)
             (-> i afn cfn bfn))
@@ -767,7 +767,7 @@
     clojure.lang.PersistentQueue/EMPTY
     coll))

-(defspec transform-idempotency
+(defspec transform-idempotency 50
          (for-all+
            [v1 (gen/vector gen/int)
             l1 (gen/list gen/int)


Better task states summary.

Better task states summary.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -854,7 +854,7 @@
              :added "0.8.0"}}}

    :task-states
-   {:summary "Task States describes the different states that the task state machine can be in. The task state machine can only exist in one state at at time. The general operation of the peer is that it will move to `:recover` mode on any change in the job allocation, before continuously cycling through the processing modes (`:start-iteration`, `:barriers`, `:process-batch`, and `:heartbeat`). Some states are blocking, in that some condition must be met before advancing to the next state. Note that not all states are applicable to all tasks. For example, non-windowed tasks will strip any states related to state management and windowing."
+   {:summary "Task States describes the different phases and states that the task state machine can be in. The peer moves to `:recover` mode on any change in the job allocation, before continuously cycling through the processing modes :start-iteration, :barriers, :process-batch, and :heartbeat). Some states are blocking, in that some condition must be met before advancing to the next state. Note that not all states are applicable to all tasks. For example, non-windowed tasks will strip any states related to state management and windowing."
     :model {:recover [{:lifecycle :lifecycle/poll-recover
                        :type #{:input :function :output}
                        :doc "Poll the messenger for the first recovery barrier sent by the coordinator. Once it has received the first barrier, it advances to the next state."


Pipeline fixes.

Pipeline fixes.

--- src/onyx/peer/task_pipeline.clj
+++ src/onyx/peer/task_pipeline.clj
@@ -62,16 +62,14 @@
 (defn munge-status-check [{:keys [sync status-node] :as event}]
   (assoc event :commit? (extensions/place-exists? sync status-node)))

+(defn munge-ack [{:keys [queue batch] :as event}]
+  (doseq [message batch]
+    (extensions/ack-message queue message))
+  event)
+
 (defn munge-commit-tx [{:keys [queue session] :as event}]
   (extensions/commit-tx queue session)
   (assoc event :committed true))
-
-(defn munge-ack [{:keys [queue batch tail-batch?] :as event}]
-  (let [f (if tail-batch? butlast identity)
-        messages (f batch)]
-    (doseq [message messages]
-      (extensions/ack-message queue message))
-    event))

 (defn munge-close-resources [{:keys [queue session producers consumers] :as event}]
   (doseq [producer producers] (extensions/close-resource queue producer))
@@ -163,9 +161,10 @@
 (defn reset-payload-node [reset-ch internal-complete-ch]
   (loop []
     (when-let [event (<!! reset-ch)]
-      (when (:tail-batch? event)
+      (if (:tail-batch? event)
         (let [event (munge-new-payload event)]
-          (>!! internal-complete-ch event)))
+          (>!! internal-complete-ch event))
+        (>!! internal-complete-ch event))
       (recur))))

 (defn complete-task-loop [complete-ch]


fix producer

fix producer

--- kafka-clj/src/kafka_clj/produce.clj
+++ kafka-clj/src/kafka_clj/produce.clj
@@ -238,8 +238,7 @@
                                   (tcp/close! client)
                                   (throw so))))))

-(defn metadata-request
-  -producer
+(defn metadata-request-producer
   "Returns a producer with a metadata-response-decoder set"
   [host port conf]
   (if (not host)


Fix cljsRatom

Fix cljsRatom

--- src/reagent/impl/component.cljs
+++ src/reagent/impl/component.cljs
@@ -137,9 +137,10 @@
 (def static-fns
   {:render
    (fn render []
+     ;; TODO: Use static property for cljsRatom
      (this-as c (if util/*non-reactive*
                   (do-render c)
-                  (let [rat (.-cljsRatom c)]
+                  (let [rat (gobj/get c "cljsRatom")]
                     (batch/mark-rendered c)
                     (if (nil? rat)
                       (ratom/run-in-reaction #(do-render c) c "cljsRatom"
@@ -195,8 +196,7 @@
     :componentWillUnmount
     (fn componentWillUnmount []
       (this-as c
-               (some-> (.-cljsRatom c)
-                       ratom/dispose!)
+               (some-> (gobj/get c "cljsRatom") ratom/dispose!)
                (batch/mark-rendered c)
                (when-not (nil? f)
                  (.call f c c))))


fix find attrnodes

fix find attrnodes

--- src/synthesis_crawlers/core.clj
+++ src/synthesis_crawlers/core.clj
@@ -159,20 +159,23 @@
             (recur (into (rest nodes) (.children node)) done)
             (recur (into (rest nodes) (.children node)) (conj done node))))))))

-(s/fdef find-attr-nodes
-        :args (s/cat :nodes #(or (instance? Elements %) element?) :knowledge ::knowledge)
-        :ret #(instance? Elements %))
-(defn find-attr-nodes
-  "returns the elements which contain text similar to the specified knowledge"
-  [nodes knowledge]
-  (filter #(not-empty (matched-knowledge (.text %) knowledge)) nodes))
-
 (s/fdef reach?
         :args (s/cat :a element? :b element?))
 (defn reach?
   "returns true iff b is reachable from a"
   [a b]
   (->> (filter #(= % b) (.getAllElements a)) empty? not))
+
+(s/fdef find-attr-nodes
+        :args (s/cat :nodes #(or (instance? Elements %) element?) :knowledge ::knowledge))
+(defn find-attr-nodes
+  "returns the elements which contain text similar to the specified knowledge"
+  [nodes knowledge]
+  (reduce
+    (fn [nodes node]
+      (conj (filter #(not (reach? % node)) nodes) node))
+    []
+    (filter #(not-empty (matched-knowledge (.text %) knowledge)) nodes)))

 #_(s/fdef find-nodes
   :args (s/cat :pages ::pages :attr-knowledge ::attr-knowledge))


Add working log test

Add working log test

--- test/onyx/plugin/input_log_test.clj
+++ test/onyx/plugin/input_log_test.clj
@@ -5,6 +5,9 @@
             [onyx.api]
             [midje.sweet :refer :all]
             [datomic.api :as d]))
+
+
+;; NEED TO ADD A TEST SELECTOR SO THIS TEST ONLY RUNS ON CIRCLE CI

 (def id (java.util.UUID/randomUUID))

@@ -29,6 +32,7 @@
 (def peer-group (onyx.api/start-peer-group peer-config))

 (def db-uri (str "datomic:free://"
+                 ;"127.0.0.1"
                  (apply str (butlast (slurp "eth0.ip")))
                  ":4334/"
                  (java.util.UUID/randomUUID)))
@@ -72,37 +76,19 @@

 (def out-chan (chan 1000))

-(def query '[:find ?a :where
-             [?e :user/name ?a]
-             [(count ?a) ?x]
-             [(<= ?x 5)]])
-
-(defn my-test-query [{:keys [datoms] :as segment}]
-  {:names (d/q query datoms)})
-
 (def workflow
-  [[:read-datoms :query]
-   [:query :persist]])
+  [[:read-log :persist]])

 (def catalog
-  [{:onyx/name :read-datoms
-    :onyx/plugin :onyx.plugin.datomic/read-datoms
+  [{:onyx/name :read-log
+    :onyx/plugin :onyx.plugin.datomic/read-log
     :onyx/type :input
     :onyx/medium :datomic
     :datomic/uri db-uri
-    :datomic/t t
-    :datomic/datoms-index :eavt
-    :datomic/datoms-per-segment 20
     :onyx/max-peers 1
+    :datomic/log-end-tx 1006
     :onyx/batch-size batch-size
-    :onyx/doc "Reads a sequence of datoms from the d/datoms API"}
-
-   {:onyx/name :query
-    :onyx/fn ::my-test-query
-    :onyx/type :function
-    :onyx/consumption :concurrent
-    :onyx/batch-size batch-size
-    :onyx/doc "Queries for names of 5 characters or fewer"}
+    :onyx/doc "Reads a sequence of datoms from the d/tx-range API"}

    {:onyx/name :persist
     :onyx/plugin :onyx.plugin.core-async/output
@@ -118,10 +104,9 @@
 (def persist-calls
   {:lifecycle/before-task-start inject-persist-ch})

-
 (def lifecycles
-  [{:lifecycle/task :read-datoms
-    :lifecycle/calls :onyx.plugin.datomic/read-datoms-calls}
+  [{:lifecycle/task :read-log
+    :lifecycle/calls :onyx.plugin.datomic/read-log-calls}
    {:lifecycle/task :persist
     :lifecycle/calls ::persist-calls}
    {:lifecycle/task :persist
@@ -134,10 +119,44 @@
  {:catalog catalog :workflow workflow :lifecycles lifecycles
   :task-scheduler :onyx.task-scheduler/balanced})

+(Thread/sleep 15)
+
+(def people2
+  [{:db/id (d/tempid :com.mdrogalis/people)
+    :user/name "Mike2"}
+   {:db/id (d/tempid :com.mdrogalis/people)
+    :user/name "Dorrene2"}
+   {:db/id (d/tempid :com.mdrogalis/people)
+    :user/name "Benti2"}
+   {:db/id (d/tempid :com.mdrogalis/people)
+    :user/name "Derek2"}
+   {:db/id (d/tempid :com.mdrogalis/people)
+    :user/name "Kristen2"}])
+
+@(d/transact conn people2)
+
 (def results (take-segments! out-chan))

-(fact (set (mapcat #(apply concat %) (map :names results)))
-      => #{"Mike" "Benti" "Derek"})
+;; dissoc ids from here
+(fact results =>
+      [{:data '([13194139534312 50 #inst "2015-08-19T13:27:59.237-00:00" 13194139534312 true]
+                [63 10 :com.mdrogalis/people 13194139534312 true]
+                [0 11 63 13194139534312 true]
+                [64 10 :user/name 13194139534312 true]
+                [64 40 23 13194139534312 true]
+                [64 41 35 13194139534312 true]
+                [0 13 64 13194139534312 true]),
+        ;:id #uuid "55d48473-e6a9-4c58-a093-706b95cac383",
+        :t 1000}
+       {:data '([13194139534313 50 #inst "2015-08-19T13:27:59.256-00:00" 13194139534313 true]
+                [277076930200554 64 "Mike" 13194139534313 true]
+                [277076930200555 64 "Dorrene" 13194139534313 true]
+                [277076930200556 64 "Benti" 13194139534313 true]
+                [277076930200557 64 "Derek" 13194139534313 true]
+                [277076930200558 64 "Kristen" 13194139534313 true]),
+        ;:id #uuid "55d48473-8c98-4955-a865-174cf89c6606",
+        :t 1001}
+       :done])

 (doseq [v-peer v-peers]
   (onyx.api/shutdown-peer v-peer))


Add :headline property to the section test data.

--- test/open_company/lib/resources.clj
+++ test/open_company/lib/resources.clj
@@ -67,14 +67,17 @@

 (def text-section-1 {
   :title "Text Section 1"
+  :headline "Headline Section 1"
   :body "
This is a test.
"})

 (def text-section-2 {
   :title "Text Section 2"
+  :headline "Headline Section 2"
   :body "
This is also a test.
"})

 (def finances-section-1 {
   :title "Finances Section 1"
+  :headline "Headline Finances Section 1"
   :data [
     {
       :period "2015-06"
@@ -85,6 +88,7 @@

 (def finances-section-2 {
   :title "Finances Section 2"
+  :headline "Headline Finances Section 2"
   :data [
     {
       :period "2015-06"
@@ -101,6 +105,7 @@

 (def finances-notes-section-1 {
   :title "Finances with Notes Section 1"
+  :headline "Headline Finances with Notes Section 1"
   :data [
     {
       :period "2015-06"
@@ -113,6 +118,7 @@

 (def finances-notes-section-2 {
   :title "Finances with Notes Section 2"
+  :headline "Headline Finances with Notes Section 2"
   :data [
     {
       :period "2015-06"


Removes useless newline

Removes useless newline

--- src/lt/objs/console.cljs
+++ src/lt/objs/console.cljs
@@ -150,7 +150,6 @@
 (behavior ::menu+
           :triggers #{:menu+}
           :reaction (fn [this items event]
-
                       (conj items
                             {:label "Clear"
                              :order 1


Helper functions for connecting lines

Helper functions for connecting lines

--- src/gigrig/components/diagram.cljs
+++ src/gigrig/components/diagram.cljs
@@ -26,17 +26,30 @@
   (boxed-text-data (merge props {:text "Generator" :background "Orange" :size 13})))

 (defn distributor [props]
-  (boxed-text-data (merge props {:text "Distributor" :background "Green" :size 9})))
+  (boxed-text-data (merge props {:text "Distributor" :background "Green" :size 7})))
+
+(defn center [box]
+  {:x (+ (:x box) (/ (:width box) 2))
+   :y (+ (:y box) (/ (:height box) 2))})
+
+(defn line [p1 p2]
+  {:x1 (:x p1) :y1 (:y p1)
+   :x2 (:x p2) :y2 (:y p2)})
+
+(defn- connect [box1 box2]
+  (line (center box1) (center box2)))

 (defn component [props]
-  [:div
-   [:h1 "DIAGRAM"]
-   [:svg {:view-box "0 0 200 100"
-          :width "800"
-          :height "400"
-          :style {:border "1px solid black"}}
-    [boxed-text (generator {:x 0 :y 0})]
-    [:g {:stroke "black"
-         :stroke-width 1}
-     [:line {:x1 23 :y1 18 :x2 23 :y2 38}]]
-    [boxed-text (distributor {:x 10 :y 38})]]])
+  (let [generator-dims (generator {:x 0 :y 0})
+        distributor-dims (distributor {:x 20 :y 30})]
+    [:div
+     [:h1 "DIAGRAM"]
+     [:svg {:view-box "0 0 200 100"
+            :width "800"
+            :height "400"
+            :style {:border "1px solid black"}}
+      [:g {:stroke "black"
+           :stroke-width 1}
+       [:line (connect generator-dims distributor-dims)]]
+      [boxed-text generator-dims]
+      [boxed-text distributor-dims]]]))


Relations type-declaredsuper, type-declaredsuper+, type-super+.

--- EkekoAspectJ/src/damp/ekeko/aspectj/weaverworld.clj
+++ EkekoAspectJ/src/damp/ekeko/aspectj/weaverworld.clj
@@ -585,22 +585,23 @@

 (defn
+  type-declaredsuper
+  "Relation between an aspect and its super class (including java.lang.Object for aspects
+   that do not declare a super aspect)."
+  [?type ?super]
+  (all
+    (type ?type)
+    (equals ?super (.getSuperclass ?type))))
+
+(defn
   aspect-declaredsuper
   "Relation between an aspect and its super class (including java.lang.Object for aspects
    that do not declare a super aspect)."
   [?aspect ?super]
   (all
     (aspect ?aspect)
-    (equals ?super (.getSuperclass ?aspect))))
-
-(defn
-  type-declaredsuper
-  "Relation between an aspect and its super class (including java.lang.Object for aspects
-   that do not declare a super aspect)."
-  [?type ?super]
-  (all
-    (type ?type)
-    (equals ?super (.getSuperclass ?type))))
+    (type-declaredsuper ?aspect ?super)))
+

 (defn
   aspect-declaredsuperaspect
@@ -618,19 +619,28 @@
   [?aspect ?super]
   (all
     (aspect-declaredsuper ?aspect ?super)
-    (succeeds (.isClass  ?super))))
+    (class ?super)))
+
+
+(defn
+  type-declaredsuper+
+  "Relation between a type and one of the ancestors in its declared super hierarchy."
+  [?type ?ancestor]
+  (conde
+    [(type-declaredsuper ?type ?ancestor) ]
+    [(fresh [?inbetween]
+              (type-declaredsuper ?type ?inbetween)
+              (type-declaredsuper+ ?inbetween ?ancestor))]))

 (defn
   aspect-declaredsuper+
   "Relation between an aspect and one of the ancestors in its declared super hierarchy."
   [?aspect ?ancestor]
-  (conde
-    [(aspect-declaredsuper ?aspect ?ancestor) ]
-    [(fresh [?inbetween]
-              (aspect-declaredsuper ?aspect ?inbetween)
-              (aspect-declaredsuper+ ?inbetween ?ancestor))]))
-
+  (all
+    (aspect ?aspect)
+    (type-declaredsuper+ ?aspect ?ancestor)))
+
 (defn
   aspect-declaredsuperaspect+
   "Relation between an aspect and one of the ancestor aspects in its declared super hierarchy."
@@ -645,11 +655,25 @@
   [?aspect ?ancestor]
   (all
     (aspect-declaredsuper+ ?aspect ?ancestor)
-    (succeeds (.isClass  ?ancestor))))
+    (class  ?ancestor)))

 ;todo: wantgenerics is true, check whether this is compatible with the types returned by the other predicates
 ;(i.e., test with a parameterized aspec)
+
+
+(defn
+  type-super+
+  "Relation between a type and one of its direct or indirect
+   super types (classes, aspects as well as interfaces),
+   including those that stem from an intertype declaration."
+  [?type ?super]
+  (all
+    (!= ?super ?type)
+    (type ?type)
+    (contains (iterator-seq (.getHierarchy ?type true true)) ?super)))
+
+
 (defn
   aspect-super+
   "Relation between an aspect and one of its direct or indirect
@@ -657,9 +681,9 @@
    including those that stem from an intertype declaration."
   [?aspect ?type]
   (all
-    (!= ?type ?aspect)
     (aspect ?aspect)
-    (contains (iterator-seq (.getHierarchy ?aspect true true)) ?type)))
+    (type-super+ ?aspect ?type)))
+

 (defn
   aspect-superaspect+
@@ -678,7 +702,7 @@
   [?aspect ?type]
   (all
     (aspect-super+ ?aspect ?type)
-    (succeeds (.isInterface ?type))))
+    (interface ?type)))

 (defn
   aspect-superclass+
@@ -687,7 +711,7 @@
   [?aspect ?type]
   (all
     (aspect-super+ ?aspect ?type)
-    (succeeds (.isClass ?type))))
+    (class ?type)))

 ;; Advice
@@ -1254,8 +1278,6 @@
   (fresh [?types]
          (declare|parents-parents|types ?declare ?types)
          (contains ?types ?type)))
-
-

 (defn
   declare|parents-target-parent


Fix published stories month list.

Fix published stories month list.

--- src/oc/storage/resources/story.clj
+++ src/oc/storage/resources/story.clj
@@ -165,7 +165,7 @@
   "
   [conn org-uuid :- lib-schema/UniqueID]
   {:pre [(db-common/conn? conn)]}
-  (db-common/months-with-resource conn table-name :org-uuid org-uuid :created-at))
+  (db-common/months-with-resource conn table-name :status-org-uuid [[:published org-uuid]] :created-at))

 ;; ----- Armageddon -----


Add conditional evaluation to oxcart/eval

Conflicts:
	src/oxcart.clj

--- src/oxcart.clj
+++ src/oxcart.clj
@@ -114,7 +114,8 @@
                                                 (.name *ns*))))))))

              ;; Run the code for side-effects
-             (em.jvm/eval mform))))))
+             (when eval?
+               (em.jvm/eval mform)))))))

 (defn load


Prevent dev-extras being unloaded by TNS

This means that a failed `(reset)` from cold if your code is invalid,
doesn't lose the `:require` to dev-extras.  This means that `(reset)`
will continue to work.

--- lib/edge.app.dev/src/dev_extras.clj
+++ lib/edge.app.dev/src/dev_extras.clj
@@ -1,5 +1,5 @@
 ;; Copyright © 2016-2019, JUXT LTD.
-(ns dev-extras
+(ns ^{:clojure.tools.namespace.repl/load false} dev-extras
   (:require
    [clojure.test :refer [run-tests]]
    [edge.system :as system]


don't update @conversations after exception

--- src/polismath/poller.clj
+++ src/polismath/poller.clj
@@ -65,6 +65,9 @@
                (encode-seq (into-array v) jsonGenerator)))

+(defn new-conv []
+  {:rating-mat (named-matrix)})
+

 (defn -main []
   (println "launching poller " (System/currentTimeMillis))
@@ -83,25 +86,29 @@
           (let [lastVoteTimestamp (:created (last votes))]
             (swap! conversations
               (fn [convs]
-                (assoc convs zid
-                    (try
-                      (do
-                        (println "zid: " zid)
-                        (let [foo (conv-update (or (convs zid) {:rating-mat (named-matrix)}) votes)]
-                          (pprint foo)
-                          foo))
-                      (catch Exception e
-                        (do
-                          (println "exception when processing zid: " zid)
-                          (.printStackTrace e)
-                          (convs zid) ; put things back
-                          ))))))
+                (try
+                  (assoc convs zid
+                         (do
+                           (println "zid: " zid)
+                           (let [foo (conv-update (or (convs zid) (new-conv)) votes)]
+                             (pprint foo)
+                             foo)))
+                  (catch Exception e
+                    (do
+                      (println "exception when processing zid: " zid)
+                      (.printStackTrace e)
+                      @conversations ; put things back
+                      )))))
+

             (println "zid: " zid)
             (println "time: " (System/currentTimeMillis))
             (println "\n\n")

-
+            (let [conv (@conversations zid)]
+              (if-not (nil? conv)
+                (do
+
             ; Upload pid mapping NOTE: uploading before primary
             ; results since client triggers resuest for pid mapping in
             ; response to a new primary math result, so there is race.
@@ -141,7 +148,8 @@
                 lastVoteTimestamp
                 (assoc obj
                  "lastVoteTimestamp" lastVoteTimestamp
-                 "zid" zid))))
+                 "zid" zid))))
+                  )))


CMR-5663: Only construct citation when needed.

When OtherCitationDetails is the only key provided in the collection citation, assume that is the full citation.

--- search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
@@ -328,15 +328,19 @@

 (defn citation
   "Create the citation field for the opendata response. extra-fields contain
-   information outside of CollectionCitations to create the full citation field."
+  information outside of CollectionCitations to create the full citation field.
+  When OtherCitationDetails is the ONLY provided field then do not construct
+  the citation and assume that contains the full citation."
   ([collection-citation]
    (citation collection-citation {}))
   ([collection-citation extra-fields]
-   (when-let [citation-details (->> (merge collection-citation extra-fields)
-                                    evaluate-citation
-                                    (remove nil?)
-                                    not-empty)]
-     (str (string/join ". " citation-details) "."))))
+   (if (= [:other-citation-details] (keys collection-citation))
+     (:other-citation-details collection-citation)
+     (when-let [citation-details (->> (merge collection-citation extra-fields)
+                                      evaluate-citation
+                                      (remove nil?)
+                                      not-empty)]
+       (str (string/join ". " citation-details) ".")))))

 (defn- score-browse-image-related-url
   "Score the related-url based off number of browse-image fields."


Add more test cases for insufficient/extra input

--- test/pinpointer/trace_test.cljc
+++ test/pinpointer/trace_test.cljc
@@ -13,4 +13,16 @@
         :steps [:b 1]}
        {:spec `(s/coll-of (s/spec integer?)) :val ["3"] :steps [0]}
        {:spec `(s/spec integer?) :val "3" :steps []}
-       {:spec `integer? :val "3" :steps []}]]]))
+       {:spec `integer? :val "3" :steps []}]]]
+
+    (s/cat :first integer? :second integer?)
+    [1]
+    [[[{:spec `(s/cat :first integer? :second integer?) :val [1] :steps []}
+       {:spec `integer? :val [1] :steps [] :reason "Insufficient input"}]]]
+
+    (s/cat :first integer? :second integer?)
+    [1 2 3]
+    [[[{:spec `(s/cat :first integer? :second integer?)
+        :val [1 2 3]
+        :steps [2]
+        :reason "Extra input"}]]]))


✅ End-to-end test for GIS sync via DB notifications

Why:
- It was previously tested only manually
- The other tests still need to trigger GIS sync explicitly, because
  otherwise they would need polling the same way as this test
- The helper functions in gis-db require the "public" schema on the
  schema path to be able to call the ST_* functions

--- test/territory_bro/api_test.clj
+++ test/territory_bro/api_test.clj
@@ -211,7 +211,7 @@
      :port (:port datasource)
      :user (:user datasource)
      :password (:password datasource)
-     :currentSchema (:schema datasource)}))
+     :currentSchema (str (:schema datasource) ",public")}))

 ;;;; Tests
@@ -687,6 +687,22 @@
       (let [state-before (projections/cached-state)]
         (sync-gis-changes!) ;; should not process the already processed changes
         (is (identical? state-before (projections/cached-state)))))
+
+    (testing "syncing changes is triggered automatically"
+      (let [new-id (jdbc/with-db-transaction [conn db-spec]
+                     (gis-db/create-congregation-boundary! conn testdata/wkt-multi-polygon))
+            deadline (-> (Instant/now) (.plus (Duration/ofSeconds 5)))]
+        (loop []
+          (cond
+            (= new-id (get-in (projections/cached-state) [::congregation-boundary/congregation-boundaries cong-id new-id :congregation-boundary/id]))
+            (is true "was synced")
+
+            (-> (Instant/now) (.isAfter deadline))
+            (is false "deadline reached, was not synced")
+
+            :else
+            (do (Thread/sleep 10)
+                (recur))))))

     (testing "on stream ID conflict a new replacement ID will be generated"
       (let [conflicting-stream-id (create-congregation-without-user! "foo")]


Update graphite-server docstring for parser-fn

--- src/riemann/transport/graphite.clj
+++ src/riemann/transport/graphite.clj
@@ -102,7 +102,7 @@
   :host       \"127.0.0.1\"
   :port       2003
   :protocol   :tcp or :udp (default :tcp)
-  :parser-fn  an optional function given to decode-graphite-line"
+  :parser-fn  an optional function to further transform events after decoding."
   ([] (graphite-server {}))
   ([opts]
      (let [core (get opts :core (atom nil))


Add auto :last-prim-kvs looping for `query`+`scan`, fix prev implementation

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -173,11 +173,11 @@

 (defmacro ^:private am-query|scan-result [result & [meta]]
   `(let [result# ~result]
-     (with-meta (mapv db-item->clj-item (.getItems result#))
-       (merge {:count (.getCount result#)
-               :consumed-capacity (cc-units (.getConsumedCapacity result#))
-               :last-prim-kvs (as-map (.getLastEvaluatedKey result#))}
-              ~meta))))
+     (merge {:items (mapv db-item->clj-item (.getItems result#))
+             :count (.getCount result#)
+             :consumed-capacity (cc-units (.getConsumedCapacity result#))
+             :last-prim-kvs (as-map (.getLastEvaluatedKey result#))}
+            ~meta)))

 (extend-protocol AsMap
   nil                 (as-map [_] nil)
@@ -270,7 +270,7 @@
   [creds table-name status & [{:keys [poll-ms timeout-ms timeout-val]
                                :or   {poll-ms 5000}}]]
   (assert (#{:creating :updating :deleting :active} (utils/un-enum status))
-          (throw (Exception. (str "Invalid table status: " status))))
+          (str "Invalid table status: " status))
   (let [polling-future
         (future
           (loop []
@@ -353,13 +353,13 @@

 (defn create-table
   "Creates a table with options:
-    :name         - (required) table name.
-    :throughput   - (required) {:read <units> :write <units>}.
-    :hash-keydef  - (required) {:name _ :type <#{:s :n :ss :ns :b :bs}>}.
-    :range-keydef - (optional) {:name _ :type <#{:s :n :ss :ns :b :bs}>}.
-    :indexes      - (optional) [{:name _ :range-keydef _
-                                 :projection #{:all :keys-only [<attr> ...]}}].
-    :block?       - (optional) blocks for table to actually be active."
+    :name         - Table name.
+    :throughput   - {:read <units> :write <units>}.
+    :hash-keydef  - {:name _ :type <#{:s :n :ss :ns :b :bs}>}.
+    :range-keydef - {:name _ :type <#{:s :n :ss :ns :b :bs}>}.
+    :indexes      - [{:name _ :range-keydef _
+                      :projection #{:all :keys-only [<attr> ...]}}].
+    :block?       - Block for table to actually be active?"
   [creds {table-name :name
           :keys [throughput hash-keydef range-keydef indexes block?]
           :or   {throughput {:read 1 :write 1}}}]
@@ -408,8 +408,8 @@
 (defn get-item
   "Retrieves an item from a table by its primary key with options:
     prim-kvs     - {<hash-key> <val>} or {<hash-key> <val> <range-key> <val>}.
-    :attrs       - attrs to return, [<attr> ...].
-    :consistent? - use strongly (rather than eventually) consistent reads?"
+    :attrs       - Attrs to return, [<attr> ...].
+    :consistent? - Use strongly (rather than eventually) consistent reads?"
   [creds table prim-kvs & [{:keys [attrs consistent? return-cc?]}]]
   (as-map
    (.getItem (db-client creds)
@@ -433,7 +433,7 @@
 (defn put-item
   "Adds an item (Clojure map) to a table with options:
     :return   - e/o #{:none :all-old :updated-old :all-new :updated-new}.
-    :expected - a map of item attribute/condition pairs, all of which must be
+    :expected - A map of item attribute/condition pairs, all of which must be
                 met for the operation to succeed. e.g.:
                   {<attr> <expected-value> ...}
                   {<attr> false ...} ; Attribute must not exist"
@@ -523,23 +523,21 @@
                                                       :my-range ["0" "1"]}]
                                           :attrs []}}))

-(defn- merge-unprocessed
-  [more-f last-result]
-  (loop [{:keys [items unprocessed consumed-capacity]} last-result]
-    (if-not (seq unprocessed)
-      (if items (with-meta items {:consumed-capacity consumed-capacity})
-                last-result)
-
-      (let [{items* :items unprocessed* :unprocessed
-             consumed-capacity* :consumed-capacity}
-            (more-f unprocessed)]
-
-        (recur (merge {:unprocessed       unprocessed*
-                       :consumed-capacity (when consumed-capacity
-                                            (+ consumed-capacity
-                                               consumed-capacity*))}
-                      (when (or items items*)
-                        {:items (into (or items []) items*)})))))))
+(defn- merge-more
+  "Enables auto paging for batch batch-get/write and query/scan requests.
+  Particularly useful for throughput limitations."
+  [more-f max-idx last-result]
+  (loop [{:keys [unprocessed last-prim-kvs] :as last-result} last-result idx 1]
+    (let [more (or unprocessed last-prim-kvs)]
+      (if (or (empty? more) (>= idx max-idx))
+        (if-let [items (:items last-result)]
+          (with-meta items (dissoc last-result :items))
+          last-result)
+        (let [merge-results (fn [l r] (cond (number? l) (+    l r)
+                                           (vector? l) (into l r)
+                                           :else               r))]
+          (recur (merge-with merge-results last-result (more-f more))
+                 (inc idx)))))))

 (defn batch-get-item
   "Retrieves a batch of items in a single request.
@@ -552,20 +550,22 @@
                :consistent? true}
      :friends {:prim-kvs [{:catagory \"favorites\" :id [1 2 3]}
                           {:catagory \"recent\"    :id [7 8 9]}]}})"
-  [creds requests & [{:keys [return-cc?] :as opts}]]
-  (let [raw-req (if (:raw? opts) requests (batch-request-items requests))]
-    (merge-unprocessed #(batch-get-item creds % (assoc opts :raw? true))
-     (as-map
-      (.batchGetItem (db-client creds)
-        (doto-maybe (BatchGetItemRequest.) g ; {table-str KeysAndAttributes}
-          :always    (.setRequestItems raw-req)
-          return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))))
+  [creds requests & [{:keys [return-cc? max-reqs] :as opts
+                      :or   {max-reqs 5}}]]
+  (letfn [(run1 [raw-req]
+            (as-map
+             (.batchGetItem (db-client creds)
+               (doto-maybe (BatchGetItemRequest.) g ; {table-str KeysAndAttributes}
+                 :always    (.setRequestItems raw-req)
+                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))]
+    (merge-more run1 max-reqs (run1 (batch-request-items requests)))))

 (comment
   (def bigval (.getBytes (apply str (range 14000))))
   (defn- ids [from to] (for [n (range from to)] {:id n :name bigval}))
-  (batch-write-item creds {:faraday.tests.main {:put (ids 0 5)}})
-  (batch-get-item   creds {:faraday.tests.main {:prim-kvs {:id (range 3)}}}))
+  (batch-write-item creds {:faraday.tests.main {:put (ids 0 10)}})
+  (batch-get-item   creds {:faraday.tests.main {:prim-kvs {:id (range 20)}}})
+  (scan creds :faraday.tests.main))

 (defn- write-request [action item]
   (case action
@@ -581,24 +581,24 @@
      {:users {:put    [{:user-id 1 :username \"sally\"}
                        {:user-id 2 :username \"jane\"}]
               :delete [{:user-id [3 4 5]}]}})"
-  [creds requests & [{:keys [return-cc?] :as opts}]]
-  (let [raw-req
-        (if (:raw? opts) requests
-            (utils/name-map
-             ;; {<table> <table-reqs> ...} -> {<table> [WriteRequest ...] ...}
-             (fn [table-request]
-               (reduce into []
-                 (for [action (keys table-request)
-                       :let [items (attr-multi-vs (table-request action))]]
-                   (mapv (partial write-request action) items))))
-             requests))]
-
-    (merge-unprocessed #(batch-write-item creds % (assoc opts :raw? true))
-     (as-map
-      (.batchWriteItem (db-client creds)
-        (doto-maybe (BatchWriteItemRequest.) g
-          :always    (.setRequestItems raw-req)
-          return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))))
+  [creds requests & [{:keys [return-cc? max-reqs] :as opts
+                      :or   {max-reqs 5}}]]
+  (letfn [(run1 [raw-req]
+            (as-map
+             (.batchWriteItem (db-client creds)
+               (doto-maybe (BatchWriteItemRequest.) g
+                 :always    (.setRequestItems raw-req)
+                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))))))]
+    (merge-more run1 max-reqs
+      (run1
+       (utils/name-map
+        ;; {<table> <table-reqs> ...} -> {<table> [WriteRequest ...] ...}
+        (fn [table-request]
+          (reduce into []
+            (for [action (keys table-request)
+                  :let [items (attr-multi-vs (table-request action))]]
+              (mapv (partial write-request action) items))))
+        requests)))))

 ;;;; API - queries & scans

@@ -621,43 +621,51 @@
 (defn query
   "Retries items from a table (indexed) with options:
     prim-key-conds - {<key-attr> [<comparison-operator> <values>] ...}.
-    :last-prim-kvs - primary key-val from which to eval, useful for paging.
+    :last-prim-kvs - Primary key-val from which to eval, useful for paging.
+    :max-reqs      - Max number of requests to automatically stitch together.
     :return        - e/o #{:all-attributes :all-projected-attributes :count
                            [<attr> ...]}.
-    :index         - name of a secondary index to query.
-    :order         - index scaning order e/o #{:asc :desc}.
-    :limit         - max num >=1 of items to eval (≠ num of matching items).
-    :consistent?   - use strongly (rather than eventually) consistent reads?
+    :index         - Name of a secondary index to query.
+    :order         - Index scaning order e/o #{:asc :desc}.
+    :limit         - Max num >=1 of items to eval (≠ num of matching items).
+    :consistent?   - Use strongly (rather than eventually) consistent reads?

   comparison-operators e/o #{:eq :le :lt :ge :gt :begins-with :between}.

   For unindexed item retrievel see `scan`."
   [creds table prim-key-conds
-   & [{:keys [last-prim-kvs return index order limit consistent? return-cc?]
-       :or   {order :asc}}]]
-  (as-map
-   (.query (db-client creds)
-     (doto-maybe (QueryRequest.) g
-       :always (.setTableName        (name table))
-       :always (.setKeyConditions    (query|scan-conditions prim-key-conds))
-       :always (.setScanIndexForward (case order :asc true :desc false))
-       last-prim-kvs   (.setExclusiveStartKey (clj-item->db-item g))
-       limit           (.setLimit    (long g))
-       index           (.setIndexName      g)
-       consistent?     (.setConsistentRead g)
-       (coll?* return) (.setAttributesToGet (mapv name return))
-       return-cc? (.setReturnConsumedCapacity (utils/enum :total))
-       (and return (not (coll?* return))) (.setSelect (utils/enum return))))))
+   & [{:keys [last-prim-kvs max-reqs return index order limit consistent?
+              return-cc?] :as opts
+       :or   {max-reqs 5
+              order    :asc}}]]
+  (letfn [(run1 [last-prim-kvs]
+            (as-map
+             (.query (db-client creds)
+               (doto-maybe (QueryRequest.) g
+                 :always (.setTableName        (name table))
+                 :always (.setKeyConditions    (query|scan-conditions prim-key-conds))
+                 :always (.setScanIndexForward (case order :asc true :desc false))
+                 last-prim-kvs   (.setExclusiveStartKey
+                                  (clj-item->db-item last-prim-kvs))
+                 limit           (.setLimit    (long g))
+                 index           (.setIndexName      g)
+                 consistent?     (.setConsistentRead g)
+                 (coll?* return) (.setAttributesToGet (mapv name return))
+                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))
+                 (and return (not (coll?* return)))
+                 (.setSelect (utils/enum return))))))]
+    (merge-more run1 max-reqs (run1 last-prim-kvs))))

 (defn scan
   "Retrieves items from a table (unindexed) with options:
     :attr-conds     - {<attr> [<comparison-operator> <values>] ...}.
-    :limit          - max num >=1 of items to eval (≠ num of matching items).
-    :last-prim-kvs  - primary key-val from which to eval, useful for paging.
+    :limit          - Max num >=1 of items to eval (≠ num of matching items).
+    :last-prim-kvs  - Primary key-val from which to eval, useful for paging.
+    :max-reqs       - Max number of requests to automatically stitch together.
     :return         - e/o #{:all-attributes :all-projected-attributes :count
                             [<attr> ...]}.
-    :total-segments - total number of parallel scan segments.
-    :segment        - calling worker's segment number (>=0, <=total-segments).
+    :total-segments - Total number of parallel scan segments.
+    :segment        - Calling worker's segment number (>=0, <=total-segments).

   comparison-operators e/o #{:eq :le :lt :ge :gt :begins-with :between :ne
                              :not-null :null :contains :not-contains :in}.
@@ -665,20 +673,25 @@
   For automatic parallelization & segment control see `scan-parallel`.
   For indexed item retrievel see `query`."
   [creds table
-   & [{:keys [attr-conds last-prim-kvs return limit total-segments segment
-              return-cc?]}]]
-  (as-map
-   (.scan (db-client creds)
-     (doto-maybe (ScanRequest.) g
-       :always (.setTableName (name table))
-       attr-conds      (.setScanFilter        (query|scan-conditions g))
-       last-prim-kvs   (.setExclusiveStartKey (clj-item->db-item g))
-       limit           (.setLimit             (long g))
-       total-segments  (.setTotalSegments     (long g))
-       segment         (.setSegment           (long g))
-       (coll?* return) (.setAttributesToGet (mapv name return))
-       return-cc? (.setReturnConsumedCapacity (utils/enum :total))
-       (and return (not (coll?* return))) (.setSelect (utils/enum return))))))
+   & [{:keys [attr-conds last-prim-kvs max-reqs return limit total-segments
+              segment return-cc?] :as opts
+       :or   {max-reqs 5}}]]
+  (letfn [(run1 [last-prim-kvs]
+            (as-map
+             (.scan (db-client creds)
+               (doto-maybe (ScanRequest.) g
+                 :always (.setTableName (name table))
+                 attr-conds      (.setScanFilter        (query|scan-conditions g))
+                 last-prim-kvs   (.setExclusiveStartKey
+                                  (clj-item->db-item last-prim-kvs))
+                 limit           (.setLimit             (long g))
+                 total-segments  (.setTotalSegments     (long g))
+                 segment         (.setSegment           (long g))
+                 (coll?* return) (.setAttributesToGet (mapv name return))
+                 return-cc? (.setReturnConsumedCapacity (utils/enum :total))
+                 (and return (not (coll?* return)))
+                 (.setSelect (utils/enum return))))))]
+    (merge-more run1 max-reqs (run1 last-prim-kvs))))

 (defn scan-parallel
   "Like `scan` but starts a number of worker threads and automatically handles


Template version 0.23.0-SNAPSHOT

Template version 0.23.0-SNAPSHOT

--- template/project.clj
+++ template/project.clj
@@ -1,4 +1,4 @@
-(defproject swagger1st/lein-template "0.22.0"
+(defproject swagger1st/lein-template "0.23.0-SNAPSHOT"
   :description "Leiningen template for creating a swagger1st app."
   :url "https://github.com/zalando/swagger1st"


Zoom control widget on the workspace header

--- src/uxbox/ui/workspace/header.cljs
+++ src/uxbox/ui/workspace/header.cljs
@@ -41,9 +41,13 @@
       [:li.coordinates {:alt "y"}
        (str "Y: " (:y coords "-"))]
       [:li.zoom-input
-       [:span.add-zoom "+"]
-       [:span "100%"]
-       [:span.remove-zoom "-"]]])))
+       [:span.add-zoom
+        {:on-click #(rs/emit! (dw/increase-zoom))}
+        "+"]
+       [:span (str (mth/round (* 100 zoom)) "%")]
+       [:span.remove-zoom
+        {:on-click #(rs/emit! (dw/decrease-zoom))}
+        "-"]]])))

 (def coordinates
   (mx/component


Add cross experiment comparison validation

--- src/aerobio/validate/compsheet.clj
+++ src/aerobio/validate/compsheet.clj
@@ -70,8 +70,13 @@

 (p/defphraser sample-name?
   [_ problem]
-  (format "`%s` is not a sample listed in Exp-SampleSheet"
-          (-> problem :val :nm)))
+  (let [xcomp? (-> problem :val :xcomp)]
+    (if xcomp?
+      (format "`%s` is not a sample listed in %s's Exp-SampleSheet"
+              (-> problem :val :nm)
+              (-> problem :val :EID))
+      (format "`%s` is not a sample listed in Exp-SampleSheet"
+              (-> problem :val :nm)))))

 (p/defphraser efstg?
   [_ problem]
@@ -132,7 +137,7 @@
        (cljstr/join "\n")))

-;;; Main - validate general comparison sheet)
+;;; Main - validate general comparison sheet

 (defn validate-wgcomparison-sheet
   [EID rows]
@@ -160,16 +165,35 @@
                (mapv #(assoc %1 :efs %2) recs efs))]
     (validate-comp-sheet recs)))

+(defn validate-xcomparison-sheet
+  [EID rows]
+  (let [recs (mapv (fn[[c1 c2]]
+                     (let [[eid1 strain cond1] (str/split #"-" c1)
+                           [eid2 strain cond2] (str/split #"-" c2)
+                           strain-cond1 (cljstr/join "-" [strain cond1])
+                           strain-cond2 (cljstr/join "-" [strain cond2])]
+                       (ac/set-exp eid1)
+                       (ac/set-exp eid2)
+                       (set-exp-sheet-data eid1)
+                       (set-exp-sheet-data eid2)
+                       {:sampx {:EID eid1 :nm strain-cond1 :xcomp true}
+                        :sampy {:EID eid2 :nm strain-cond2 :xcomp true}
+                        :EID EID}))
+                   rows)]
+    (validate-comp-sheet recs)))
+
 (defn validate-comparison-sheet
   ([EID compname]
    (let [veol (validate-eols-ok EID compname)]
      (if (not-empty veol)
        veol
        (let [compsheet (make-sheet-fspec EID compname)
-             rows (->> compsheet slurp csv/read-csv rest)
+             [hd & rows] (->> compsheet slurp csv/read-csv)
+             xcomp? (some #(= % "xcompare") hd)
              exp (ac/get-exp-info EID :exp)
              vstg (cond
                     (= exp :wgseq) (validate-wgcomparison-sheet EID rows)
+                    xcomp? (validate-xcomparison-sheet EID rows)
                     :else (validate-rtcomparison-sheet EID rows))]
          (with-out-str
            (when (not (empty? vstg))


Remove 'aliased' leftover from spec

Remove 'aliased' leftover from spec

--- src/cljc/mikron/compiler/spec.cljc
+++ src/cljc/mikron/compiler/spec.cljc
@@ -63,9 +63,6 @@
 (defmethod schema-spec :record [_]
   (schema-spec* [::type] :schemas (s/map-of keyword? ::schema)))

-(defmethod schema-spec :aliased [_]
-  (schema-spec* []))
-
 (defmethod schema-spec :custom [_]
   some?)


Minor: add space after render speed

Minor: add space after render speed

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -39,7 +39,7 @@
          :as stats}
         (get @app-state :stats)]
     (aset (.getElementById js/document "renderSpeed") "innerHTML"
-          (str "Render Speed: " (format-comma render-speed) "px/s"))
+          (str "Render Speed: " (format-comma render-speed) " px/s"))

     (aset (.getElementById js/document "scale") "innerHTML"
           (str "Scale: " (format-comma scale) ))


Minor cosmetic changes on pages data events.

--- frontend/src/uxbox/main/data/pages.cljs
+++ frontend/src/uxbox/main/data/pages.cljs
@@ -134,21 +134,28 @@
       (reduce assoc-page $ pages)
       (reduce assoc-packed-page $ pages))))

+(defn pages-fetched
+  [pages]
+  {:pre [(coll? pages)]}
+  (PagesFetched. pages))
+
 (defn pages-fetched?
   [v]
   (instance? PagesFetched v))

 ;; --- Fetch Pages (by project id)

-(deftype FetchPages [projectid]
+(deftype FetchPages [id]
   ptk/WatchEvent
   (watch [_ state s]
-    (->> (rp/req :fetch/pages-by-project {:project projectid})
-         (rx/map (comp ->PagesFetched :payload)))))
+    (->> (rp/req :fetch/pages-by-project {:project id})
+         (rx/map :payload)
+         (rx/map pages-fetched))))

 (defn fetch-pages
-  [projectid]
-  (FetchPages. projectid))
+  [id]
+  {:pre [(uuid? id)]}
+  (FetchPages. id))

 ;; --- Page Created


some docstring

some docstring

--- src/inf4375_simple_server/core.clj
+++ src/inf4375_simple_server/core.clj
@@ -1,18 +1,20 @@
 (ns inf4375-simple-server.core
   (:gen-class)
-  (:import (java.io InputStreamReader PrintWriter BufferedReader ByteArrayOutputStream )
+  (:import (java.io InputStreamReader PrintWriter BufferedReader)
            (java.net ServerSocket))
   (:require [clojure.string :as str]
             [clojure.pprint :as pp]
             [me.raynes.fs   :as fs]))

 (defn consume-buffer [input]
+  "Consume a input buffer and gives it content as a list of string"
   (loop  [lines '()]
     (if (.ready input)
       (recur(concat lines (list (.readLine input))))
       (remove (fn [l] (empty? l))lines))))

 (defn parse-request [lines]
+  "Structure a http requests"
   (let [[request-line & headers] lines
         [method uri version] (str/split request-line #" ")]
     {:request-line
@@ -24,15 +26,19 @@
                              (assoc memo (keyword k) (str/trim v))))
                       (sorted-map) headers)}))

-(defn compose [lines]
+(defn compose-list [lines]
+  "compose a list of lines with the proper line feeds and returns"
   (reduce
     (fn [res, el] (str/join (list res el "\r\n")))
     lines))

-(defmulti generate-response (fn [code _] code))
+(defmulti generate-response
+          "generate a response base on the response code given"
+          (fn [code _] code))
+
 (defmethod generate-response :404 [_ _]
   (let [page-content "
404 Not Found
"]
-    (compose
+    (compose-list
       (list
         "HTTP/1.1 404 Not Found"
         "Content-Type: text/html; charset=utf-8"
@@ -41,7 +47,7 @@
         page-content))))

 (defmethod generate-response :200 [_ res-as-string]
-  (compose (list
+  (compose-list (list
              "HTTP/1.1 200 OK"
              "content-type: text/html; charset=utf-8"
              (format "content-length: %s" (count res-as-string))
@@ -49,6 +55,7 @@
              res-as-string)))

 (defn run-server [port]
+  "main server loop; will 404 if request is empty or not found"
   (println (format "server accepting request on %s" port))
   (loop [server (new ServerSocket port)]
     (let [socket (.accept server)]


(SERVER-876) Update filebucket tests to include a body

The file_bucket_file tests previously did not include a body, but a
recent change added the wrap-params-with-jruby to the request handler,
which calls a slurp on the body in some cases. This commit adds a body
for both file_bucket_file tests to ensure that there is a body to
slurp/read. This is consistent with the Puppet API docs
https://github.com/puppetlabs/puppet/blob/master/api/docs/http_file_bucket_file.md.

--- test/unit/puppetlabs/services/master/master_core_test.clj
+++ test/unit/puppetlabs/services/master/master_core_test.clj
@@ -54,17 +54,19 @@
                 "is not overwritten, and simply passed through unmodified.")
     (let [handler     (fn ([req] {:request req}))
           app         (build-ring-handler handler "1.2.3")
-          resp        (app {:request-method :put
-                            :content-type   "application/octet-stream"
-                            :uri            "/v3/file_bucket_file/bar"})]
+          resp        (app (-> {:request-method :put
+                                :content-type "application/octet-stream"
+                                :uri "/v3/file_bucket_file/bar"}
+                               (mock/body "foo")))]
       (is (= "application/octet-stream"
              (get-in resp [:request :content-type])))

       (testing "Even if the client sends something insane, "
                "just pass it through and let the puppet code handle it."
-        (let [resp (app {:request-method :put
-                         :content-type   "something-crazy/for-content-type"
-                         :uri            "/v3/file_bucket_file/bar"})]
+        (let [resp (app (-> {:request-method :put
+                          :content-type "something-crazy/for-content-type"
+                          :uri "/v3/file_bucket_file/bar"}
+                            (mock/body "foo")))]
           (is (= "something-crazy/for-content-type"
                  (get-in resp [:request :content-type]))))))))


Working on porting third test.

Working on porting third test.

--- test/blutwurst/jsonschema_test.clj
+++ test/blutwurst/jsonschema_test.clj
@@ -31,7 +31,7 @@
   (testing "Handles complex arrays."
     (let [spec {:connection-string (io/resource "arrays2.json")}
           result (parse-json-schema-from-spec spec)]
-      (is (=  {:entities ({:dependencies []
+      (is (=  {:entities '({:dependencies []
                            :name "Arrays"
                            :properties [{:constraints {:nullable true}
                                          :name "id"


Added a simple integration test for the protocol version and reason phrase parsing from response

--- test/clj_http/test/client_test.clj
+++ test/clj_http/test/client_test.clj
@@ -836,3 +836,13 @@
     (is (= 200 (:status resp)))
     (is (= "close" (get-in resp [:headers "connection"])))
     (is (= "propfindbody" (:body resp)))))
+
+(deftest ^:integration status-line-parsing
+  (run-server)
+  (let [resp (request {:uri "/get" :method :get})
+        protocol-version (:protocol-version resp)]
+    (is (= 200 (:status resp)))
+    (is (= "HTTP" (:name protocol-version)))
+    (is (= 1 (:major protocol-version)))
+    (is (= 1 (:minor protocol-version)))
+    (is (= "OK" (:reason-phrase resp)))))


add the undo PBT

add the undo PBT

--- test/cljs/tictactoe/game_test.cljs
+++ test/cljs/tictactoe/game_test.cljs
@@ -133,6 +133,18 @@
 (defspec try-move-from-valid-game 100
   (prop/for-all [game game-gen] (valid-move-properties game)))

+(defn valid-undo-properties
+  [old-game]
+  (prop/for-all [[x y] coord-gen]
+    (let [new-game (logic/on-move old-game x y)]
+      (or
+        (= old-game new-game)
+        (= old-game (logic/on-undo new-game))
+        ))))
+
+(defspec try-undo-from-valid-game 100
+  (prop/for-all [game game-gen] (valid-undo-properties game)))
+

 ;; ----------------------------------------------------------------------------
 ;; Running the tests


test food resource

test food resource

--- test/sushi_machine/server_test.clj
+++ test/sushi_machine/server_test.clj
@@ -1,11 +1,24 @@
 (ns sushi-machine.server-test
   (:require [sushi-machine.server :refer :all]
             [clojure.test :refer :all]
+            [clojure.edn :as edn]
             [ring.mock.request :as mock]))

 (defmacro req [& args]
-  `(test-handler (mock/request ~@args)))
+  `(-> (mock/request ~@args)
+       (mock/header "accept" "application/edn")
+       (mock/content-type "application/edn")
+       (test-handler)))

-(deftest brille-test
-  (is (= (:body (req :get "/"))
-         "This is an example")))
+(deftest food-rest-resource
+
+  (testing "food resource returns list of food items with name and price"
+    (let [res (req :get "/food/isushi")
+          body (edn/read-string (:body res))]
+      (is (> (count body) 10))
+      (is (contains? (first body) :name))
+      (is (contains? (first body) :price))))
+
+  (testing "food resource returns 404 on not found item"
+    (let [res (req :get "/food/doesntexist")]
+      (is (= (:status res) 404)))))


simplifications: zipmap, or

simplifications: zipmap, or

--- nucleotide-count/example.clj
+++ nucleotide-count/example.clj
@@ -1,10 +1,10 @@
 (ns nucleotide-count
   (:refer-clojure :exclude [count]))

-(def ^{:private :const} dna-nucleotide? #{\A \C \G \T})
+(def ^{:private :const} dna-nucleotides #{\A \C \G \T})

 (def ^{:private :const} base-count
-  (apply hash-map (interleave dna-nucleotide? (repeat 0))))
+  (zipmap dna-nucleotides (repeat 0)))

 (defn nucleotide-counts
   "generate a map of counts per nucleotide in strand"
@@ -14,7 +14,5 @@
 (defn count
   "count occurrences of nucleotide in strand"
   [nucleotide strand]
-  (if
-    (dna-nucleotide? nucleotide)
-    ((nucleotide-counts strand) nucleotide)
-    (throw (Exception. (str "invalid nucleotide '" nucleotide "'")))))
+  (or ((nucleotide-counts strand) nucleotide)
+      (throw (Exception. (str "invalid nucleotide '" nucleotide "'")))))


updated-rhs: use `seq` case instead of `reader-list-form?` &  `string?`

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -10,7 +10,7 @@
         [midje.internal-ideas.expect :only [expect? up-to-full-expect-form]]
         [midje.util.form-utils :only [first-named? translate-zipper map-difference
                                       hash-map-duplicates-ok pred-cond to-thunks
-                                      reader-list-form? quoted-list-form?]]
+                                      quoted-list-form?]]
         [midje.ideas.metaconstants :only [metaconstant-for-form
                                           with-fresh-generated-metaconstant-names]]
         [midje.checkers.extended-equality :only [extended-= extended-list-= extended-fn?]]
@@ -62,10 +62,7 @@
      quoted-list-form?
      `(repeatedly (on-demand (to-thunks ~(second rhs))))

-     reader-list-form?
-     rhs
-
-     string?
+     seq
      rhs

      :else


fix bad merge (#603)

fix bad merge (#603)

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/summary/tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/summary/tab.cljs
@@ -208,8 +208,8 @@
              (when (pos? count-all)
                [:ul {:style {:marginTop "0"}}
                 (for [[status subs] (sort submissions-count)]
-                 [:li {} (str subs " " status)])])]))]]
-       ]]
+                 [:li {} (str subs " " status)])])])))]
+
     (when editing? common/PHI-warning)

      (style/create-section-header "Description")


test for score on synonym is lower than ID

--- test/wb_es/core_test.clj
+++ test/wb_es/core_test.clj
@@ -168,13 +168,27 @@
 (deftest phenotype-type-test
   (testing "phenotype with locomotion variant as example"
     (let [db (d/db datomic-conn)]
-      (index-datomic-entity (d/entity db [:phenotype/id "WBPhenotype:0000643"]))
-      (testing "search for phenotype by alias"
-        (is (->> (get-in (search "unc") [:hits :hits])
-                 (some (fn [hit]
-                         (= "WBPhenotype:0000643"
-                            (get-in hit [:_source :wbid]))))
-                 ))))))
+      (do
+        (index-datomic-entity (d/entity db [:phenotype/id "WBPhenotype:0000643"])
+                              (d/entity db [:gene-class/id "unc"]))
+        (testing "search for phenotype by alias"
+          (is (->> (get-in (search "unc") [:hits :hits])
+                   (some (fn [hit]
+                           (= "WBPhenotype:0000643"
+                              (get-in hit [:_source :wbid]))))
+                   )))
+        (testing "search by alias scores lower than by ID"
+          (let [hits (get-in (search "unc") [:hits :hits])
+                [phenotype-unc-hit] (filter (fn [hit]
+                                              (= "WBPhenotype:0000643"
+                                                 (get-in hit [:_source :wbid])))
+                                            hits)
+                [gene-class-unc-hit] (filter (fn [hit]
+                                               (= "unc"
+                                                (get-in hit [:_source :wbid])))
+                                             hits)]
+            (is (> (:_score gene-class-unc-hit)
+                   (:_score phenotype-unc-hit)))))))))

 (deftest transgene-type-test
   (testing "transgene using syis1 as example"


Working on 0127... Pfffff...

Working on 0127... Pfffff...

--- src/project_euler/problem_0127.clj
+++ src/project_euler/problem_0127.clj
@@ -1,4 +1,7 @@
-(ns project-euler.problem_0127)
+(ns project-euler.problem_0127
+  (:require [clojure.math.combinatorics :as combo])
+  (:require [clojure.set :as set])
+  )

 ;; The radical of n, rad(n), is the product of distinct prime factors of n.
 ;; For example, 504 = 2^3 × 3^2 × 7, so rad(504) = 2 × 3 × 7 = 42.
@@ -20,10 +23,58 @@

 ;; Find ∑c for c < 120000.

+;; From problem 0010 :
+;; -------------------
+(defn prime?
+  [n]
+  {:pre [(integer? n) (> n 0)]}
+  (or (== 2 n)
+      (let [mmax (+ (Math/sqrt n) 1)]
+        (not (some #(== 0 (rem n %)) (concat [2] (range 3 mmax 2))))
+        )))
+
+(defn lz-primes
+  []
+  (concat [2]
+          (filter prime? (iterate #(+ 2 %) 3))))
+
+;;---------------------------------------------------------------------------
+
+(def primes (->> (lz-primes)
+                 (take-while #(< % 120000))
+                 (vec)
+                 ))
+
+(defn abc-hit? [[a b c]]
+  (and (== 1 (gcd a b))
+       (== 1 (gcd a c))
+       (== 1 (gcd b c))
+       (< a b)
+       (== (+ a b) c)
+       (< (rad (* a b c)) c)
+       ))
+
 (defn gcd [x y]
   (if (zero? y)
     x
     (recur y (rem x y))))
+
+(defn decompose [x]
+  (loop [x x
+         ps primes
+         q 0
+         r 1
+         upfs []
+         mpfs []]
+    (let [p (first ps)]
+      (cond (> (* p p) x)   (if (== x q)
+                              [r upfs (conj mpfs x)]
+                              [(* r x) (conj upfs x) mpfs])
+            (< 0 (rem x p)) (recur x          (rest ps) p r        upfs          mpfs)
+            (== p q)        (recur (quot x p) ps        p r        upfs          (conj mpfs p))
+            :else           (recur (quot x p) ps        p (* r p) (conj upfs p)  mpfs)
+            ))))
+

 (defn rad [x]
   (loop [x x p 2 q 0 r 1]
@@ -32,6 +83,8 @@
           (== p q)        (recur (quot x p) p                       p r)
           :else           (recur (quot x p) p                       p (* r p))
         )))
+
+

 (defn naive-solution-for [c-max]
   (->> (range 3 c-max)
@@ -49,3 +102,112 @@
        (reduce +)
        ;;(count)
        ))
+
+;; (defn solution-for [c-max]
+;;   (->> (range 3 c-max)
+;;        (map (fn [c] [c (decompose c)]))
+;;        (filter (fn [[c [r upfs mpfs]]] (seq mpfs)))
+;;        ;;(filter (fn [[c [r upfs mpfs]]] (>= (/ c r) 6)))
+;;        ;;(count)
+;;        (mapcat (fn [[c [r upfs mpfs]]]
+;;                  (->> (if (odd? c) (iterate inc 1) (iterate #(+ % 2) 1))
+;;                       (map (fn [a] [a (- c a) c]))
+;;                       (take-while (fn [[a b c]] (< a b)))
+;;                       (remove (fn [[a b c]]
+;;                                 (some #(or (zero? (rem a %))
+;;                                            (zero? (rem b %))) upfs)
+;;                                 ))
+;;                       )
+;;                  ))
+;;        (filter (fn [[a b c]] (< (rad (* a b c)) c)))
+;;        (map (fn [[a b c]] c))
+;;        (reduce +)
+;;        ))
+
+;; (defn solutions-for-a [rad-ab c-pfs]
+;;   (let [ab-pfs (->> primes
+;;                     (take-while #(< % rad-ab))
+;;                     (filter #(== -1 (.indexOf c-pfs %)))
+;;                     )]
+;;     (products-under rad-ab ab-pfs)))
+
+(defn products-under [p-max xs]
+  (let [[x & xs'] xs]
+    (if x
+      (->> (iterate (fn [[p p-max']] [(* p x) (/ p-max' x)]) [1 p-max])
+                (take-while (fn [[p p-max']] (< p p-max)))
+                (mapcat (fn [[p p-max']]
+                          (map #(* p %) (products-under p-max' xs'))))
+                )
+      [1]
+      )))
+
+(defn solutions-for-ab [c r c-pfs]
+  (let [ab-pfs (->> primes
+                    (take-while #(< % (/ c r)))
+                    (filter #(== -1 (.indexOf c-pfs %)))
+                    )]
+    (println ab-pfs)
+    (->> (products-under (/ c r) ab-pfs)
+         (mapcat (fn [pb]
+                   (->> ab-pfs
+                        (filter #(and (not (zero? (rem pb %)))
+                                      (< % (/ c r (rad pb)))
+                                      ))
+                        (products-under pb)
+                        (map (fn [pa] [pa pb]))
+                        (filter (fn [[a b]] (== c (+ a b))))
+                        (map (fn [[a b]] [a b c]))
+                        )
+                   ))
+         )))
+
+
+;; (defn prime-factors-pairs [p-max xs]
+;;   (->> (combo/subsets xs)
+;;        (filter seq)
+;;        (filter #(<= (apply * %) p-max))
+;;        (mapcat (fn [a-ss]
+;;                  (->> (set/difference (set xs) (set a-ss))
+;;                       (vec)
+;;                       (combo/subsets)
+;;                       (filter seq)
+;;                       (filter #(<= (apply * %) p-max))
+;;                       (map (fn [b-ss] [a-ss b-ss]))
+;;                       )))
+;;        ))
+
+;; (defn solutions-for-ab [p-max c-pfs]
+;;   (let [ab-pfs (->> primes
+;;                     (take-while #(< % p-max))
+;;                     (filter #(== -1 (.indexOf c-pfs %)))
+;;                     )]
+;;     (->> (prime-factors-pairs p-max ab-pfs)
+;;          (mapcat (fn [[a-ss b-ss]]
+;;                    (->> (products-under p-max b-ss)
+;;                         (mapcat (fn [pb]
+;;                                   (->> (products-under pb a-ss)
+;;                                        (map (fn [pa] [pa pb])))))
+;;                         )))
+;;          )))
+
+
+
+(defn solution-for [c-max]
+  (->> (range 3 c-max)
+       (map (fn [c] [c (decompose c)]))
+       (filter (fn [[c [r upfs mpfs]]] (seq mpfs)))
+       (mapcat (fn [[c [r upfs mpfs]]]
+                 (->> (solutions-for-ab c r upfs)
+                      )))
+       ;;(drop 20)
+       (remove abc-hit?)
+       (take 10)
+       ;;(count)
+
+       ;;(filter (fn [[a b c]] (< (rad (* a b c)) c)))
+       ;;(map (fn [[a b c]] c))
+       ;;(reduce +)
+       ))
+
+


(PDB-4934) Add defaults for connection users.

--- src/puppetlabs/puppetdb/config.clj
+++ src/puppetlabs/puppetdb/config.clj
@@ -402,6 +402,16 @@
       (update :migrator-username #(or % (:user config)))
       (update :migrator-password #(or % (:password config)))))

+(defn ensure-connection-users-info [config]
+  ;; This expects to run after ensure-migrator-info and prefer-db-user-on-username-mismatch,
+  ;; so the :user and :migrator-user should already be set
+  (assert (:user config))
+  (assert (:migrator-username config))
+  (-> config
+      (update :connection-username #(or % (:user config)))
+      (update :connection-migrator-username #(or % (:migrator-username config))))
+  )
+
 (defn fix-up-db-settings
   [section-key settings]
   ;; FIXME: double-check this reordering wrt each function,
@@ -416,7 +426,8 @@
       gc-interval->ms
       default-events-ttl
       (prefer-db-user-on-username-mismatch (name section-key))
-      ensure-migrator-info))
+      ensure-migrator-info
+      ensure-connection-users-info))

 (defn configure-read-db
   "Ensures that the config contains a suitable [read-database].  If the


(PDB-3060) Change default `concurrent-writes` val

Change the default value for the concurrent writes configuration setting
from 100 to the minimum of half the CPU cores and 4.

--- src/puppetlabs/puppetdb/config.clj
+++ src/puppetlabs/puppetdb/config.clj
@@ -145,7 +145,7 @@
     {:threads (pls/defaulted-maybe s/Int half-the-cores)
      :max-command-size (pls/defaulted-maybe s/Int (default-max-command-size))
      :reject-large-commands (pls/defaulted-maybe String "false")
-     :concurrent-writes (pls/defaulted-maybe s/Int 100)
+     :concurrent-writes (pls/defaulted-maybe s/Int (min half-the-cores 4))

      ;; Deprecated
      :dlo-compression-threshold (pls/defaulted-maybe String "1d")


Add profile with advanced compilation mode.

--- profiles.clj
+++ profiles.clj
@@ -17,6 +17,16 @@
            {"phantomjs"
             ["phantomjs" :runner
              "dev-resources/public/js/beatha.js"]}}}
+
+ :prod [:shared
+        {:cljsbuild
+         {:builds
+          {:beatha
+           {:compiler {:libs [""]
+                       :optimizations :advanced
+                       :pretty-print false
+                       :preamble ["react/react.min.js"]
+                       :externs ["react/externs/react.js"]}}}}}]

  :tdd [:shared]


Fix an ambiguous Thread/sleep call on JDK 19

Java 19 has introduced Thread.sleep(Duration) [1] that makes one of
the calls to Thread/sleep ambiguous. This has resulted in a compile
time warning:

    Reflection warning, riemann/jvm_profiler/stack.clj:177:27 - call
    to static method sleep on java.lang.Thread can't be resolved
    (argument types: java.lang.Object).

as well as a runtime error "No matching method sleep found."

This patch fixes it by explicitly coercing the double value to a long,
thus making the Thread/sleep call unambiguous.

Hat tip to @mvitz for helping me diagnose this problem.

[1]: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Thread.html#sleep%28java.time.Duration%29

--- src/riemann/jvm_profiler/stack.clj
+++ src/riemann/jvm_profiler/stack.clj
@@ -174,6 +174,7 @@
                           (/ 1e6 target-load)
                           (max 1)
                           (min 1000)
+                          (long)
                           (Thread/sleep))
                       t0)
                     (catch Exception e


open-url extension event

open-url extension event

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

--- src/status_im/extensions/core.cljs
+++ src/status_im/extensions/core.cljs
@@ -23,7 +23,8 @@
             status-im.extensions.camera
             [status-im.utils.ethereum.tokens :as tokens]
             [status-im.utils.ethereum.core :as ethereum]
-            [status-im.chat.commands.sending :as commands-sending]))
+            [status-im.chat.commands.sending :as commands-sending]
+            [status-im.browser.core :as browser]))

 (re-frame/reg-fx
  ::identity-event
@@ -319,6 +320,11 @@
  :extensions/arithmetic
  (fn [_ [_ _ m]]
    {::arithmetic m}))
+
+(handlers/register-handler-fx
+ :extensions/open-url
+ (fn [cofx [_ _ {:keys [url]}]]
+   (browser/open-url cofx url)))

 (defn button [{:keys [on-click enabled disabled] :as m} label]
   [button/secondary-button (merge {:disabled? (or (when (contains? m :enabled) (or (nil? enabled) (false? enabled))) disabled)}
@@ -478,6 +484,10 @@
                  :arguments   {:values    :vector
                                :operation {:one-of #{:plus :minus :times :divide}}
                                :on-result :event}}
+                'browser/open-url
+                {:permissions [:read]
+                 :value       :extensions/open-url
+                 :arguments   {:url :string}}
                 'camera/picture
                 {:permissions [:read]
                  :value       :extensions/camera-picture


Close drawer on 'switch users' click

Close drawer on 'switch users' click

Former-commit-id: 9ec8f70cfeba9a8bd99991d90434432baa4d940d

--- src/syng_im/components/drawer.cljs
+++ src/syng_im/components/drawer.cljs
@@ -80,7 +80,10 @@
                 :handler (fn [])}]]
    [view {:style {:paddingVertical 36
                   :alignItems :center}}
-    [touchable-opacity {}
+    [touchable-opacity {:onPress (fn []
+                                   (close-drawer)
+                                   ;; TODO not implemented
+                                   )}
      [text {:style {:fontSize   14
                     :fontFamily font
                     :lineHeight 21