don't do Chronos Protocol ability if Runner's hand is empty

--- src/clj/game/cards-identities.clj
+++ src/clj/game/cards-identities.clj
@@ -103,26 +103,29 @@
                      (corp-can-choose-damage? state)
                      (> (last targets) 0)))
       :effect (req (damage-defer state side :net (last targets))
-                   (show-wait-prompt state :runner "Corp to use Chronos Protocol: Selective Mind-mapping")
-                   (resolve-ability state side
-                     {:optional {:prompt (str "Use Chronos Protocol: Selective Mind-mapping to reveal the Runner's "
-                                              "Grip to select the first card trashed?") :player :corp
-                                 :yes-ability {:prompt (msg "Choose a card to trash")
-                                               :choices (req (:hand runner)) :not-distinct true
-                                               :msg (msg "trash " (:title target)
-                                                      (when (> (- (get-defer-damage state side :net nil) 1) 0)
-                                                        (str " and deal "
-                                                             (- (get-defer-damage state side :net nil) 1)
-                                                             " more net damage")))
-                                               :effect (req (clear-wait-prompt state :runner)
-                                                            (trash state side target {:cause :net :unpreventable true})
-                                                            (swap! state update-in [:damage] dissoc :damage-choose-corp)
-                                                            (damage state side :net (- (get-defer-damage state side :net nil) 1)
-                                                                    {:unpreventable true :card card}))}
-                                 :no-ability {:effect (req (swap! state update-in [:damage] dissoc :damage-choose-corp)
-                                                           (clear-wait-prompt state :runner)
-                                                           (damage state side :net (get-defer-damage state side :net nil)
-                                                                   {:unpreventable true :card card}))}}} card nil))}}
+                   (if (= 0 (count (:hand runner)))
+                     (do (swap! state update-in [:damage] dissoc :damage-choose-corp)
+                         (damage state side :net (get-defer-damage state side :net nil)
+                                 {:unpreventable true :card card}))
+                     (do (show-wait-prompt state :runner "Corp to use Chronos Protocol: Selective Mind-mapping")
+                         (resolve-ability state side
+                           {:optional {:prompt (str "Use Chronos Protocol: Selective Mind-mapping to reveal the Runner's "
+                                                    "Grip to select the first card trashed?") :player :corp
+                                       :yes-ability {:prompt (msg "Choose a card to trash")
+                                                     :choices (req (:hand runner)) :not-distinct true
+                                                     :msg (msg "trash " (:title target)
+                                                            (when (> (- (get-defer-damage state side :net nil) 1) 0)
+                                                              (str " and deal " (- (get-defer-damage state side :net nil) 1)
+                                                                   " more net damage")))
+                                                     :effect (req (clear-wait-prompt state :runner)
+                                                                  (trash state side target {:cause :net :unpreventable true})
+                                                                  (swap! state update-in [:damage] dissoc :damage-choose-corp)
+                                                                  (damage state side :net (- (get-defer-damage state side :net nil) 1)
+                                                                          {:unpreventable true :card card}))}
+                                       :no-ability {:effect (req (swap! state update-in [:damage] dissoc :damage-choose-corp)
+                                                                 (clear-wait-prompt state :runner)
+                                                                 (damage state side :net (get-defer-damage state side :net nil)
+                                                                         {:unpreventable true :card card}))}}} card nil))))}}
     :leave-play (req (swap! state update-in [:damage] dissoc :damage-choose-corp))}

    "Cybernetics Division: Humanity Upgraded"


remove dead code

remove dead code

--- src/clj_money/models/settings.clj
+++ src/clj_money/models/settings.clj
@@ -1,31 +1,15 @@
 (ns clj-money.models.settings
   (:refer-clojure :exclude [get])
   (:require [clojure.pprint :refer [pprint]]
-            [clojure.edn :as edn]
-            [clj-time.core :refer [local-date]]
-            [clj-time.format :refer [parse-local-date
-                                     unparse-local-date
-                                     formatters]]
             [clj-money.models.helpers :refer [with-storage]]
             [clj-money.models.storage :refer [put-setting
-                                              get-setting]])
-  (:import org.joda.time.LocalDate))
-
-(defmethod print-method LocalDate [this ^java.io.Writer w]
-  (doto w
-    (.write "#local-date \"")
-    (.write (unparse-local-date (:year-month-day formatters) this))
-    (.write "\"")))
+                                              get-setting]]))

 (defn put
   [storage-spec setting-name setting-value]
   (with-storage [s storage-spec]
     (put-setting s (name setting-name) (prn-str setting-value))))

-(defn- parse
-  [value]
-  (parse-local-date (:year-month-day formatters) value))
-
 (defn get
   [storage-spec setting-name]
   (with-storage [s storage-spec]


CLJS-259: remove clojure.core.reduce

CLJS-259: remove clojure.core.reduce

This is the initial version of the reducers library; the new version
resides in clojure.core.reducers.

--- src/cljs/clojure/core/reduce.cljs
+++ src/cljs/clojure/core/reduce.cljs
@@ -1,121 +0,0 @@
-;   Copyright (c) Rich Hickey. All rights reserved.
-;   The use and distribution terms for this software are covered by the
-;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
-;   which can be found in the file epl-v10.html at the root of this distribution.
-;   By using this software in any fashion, you are agreeing to be bound by
-;   the terms of this license.
-;   You must not remove this notice, or any other, from this software.
-
-(ns clojure.core.reduce
-  (:refer-clojure :exclude [map filter remove take take-while drop flatten]))
-
-(defn reducer
-  "Given a reducible collection, and a transformation function xf,
-  returns a reducible collection, where any supplied reducing
-  fn will be transformed by xf. xf is a function of reducing fn to
-  reducing fn."
-  [coll xf]
-  (reify cljs.core/IReduce
-    (-reduce [_ f1]
-      (throw (js/Error. "You must supply an init value for reducer-based reduce")))
-    (-reduce [_ f1 init]
-      (-reduce coll (xf f1) init))))
-
-(defn map
-  "Applies f to every value in the reduction of coll"
-  [f coll]
-  (reducer
-   coll
-   (fn [f1]
-     (fn [ret v] (f1 ret (f v))))))
-
-(defn filter
-  "Retains values in the reduction of coll for which (pred val) returns logical true"
-  [pred coll]
-  (reducer
-   coll
-   (fn [f1]
-     (fn [ret v]
-       (if (pred v)
-         (f1 ret v)
-         ret)))))
-
-(defn remove
-  "Removes values in the reduction of coll for which (pred val) returns logical true"
-  [pred coll]
-  (filter (complement pred) coll))
-
-(defn take-while
-  "Ends the reduction of coll when (pred val) returns logical false."
-  [pred coll]
-  (reducer
-   coll
-   (fn [f1]
-     (fn [ret v]
-       (if (pred v)
-         (f1 ret v)
-         (reduced ret))))))
-
-(defn take
-  "Ends the reduction of coll after consuming n values."
-  [n coll]
-  (reducer
-   coll
-   (fn [f1]
-     (let [cnt (atom n)]
-       (fn [ret v]
-         (swap! cnt dec)
-         (if (neg? @cnt)
-           (reduced ret)
-           (f1 ret v)))))))
-
-(defn drop
-  "Elides the first n values from the reduction of coll."
-  [n coll]
-  (reducer
-   coll
-   (fn [f1]
-     (let [cnt (atom n)]
-       (fn [ret v]
-         (swap! cnt dec)
-         (if (neg? @cnt)
-           (f1 ret v)
-           ret))))))
-
-(defn flatten
-  "Takes any nested combination of sequential things (lists, vectors,
-  etc.) and returns their contents as a single, flat reducible
-  collection."
-  [coll]
-  (reify cljs.core/IReduce
-    (-reduce [_ f1]
-      (throw (js/Error. "You must supply an init value for reducer-based reduce")))
-    (-reduce [_  f1 init]
-      (-reduce
-       coll
-       (fn [ret v]
-         (if (sequential? v)
-           (-reduce (flatten v) f1 ret)
-           (f1 ret v)))
-       init))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(comment
-(require '[clojure.core.reduce :as r])
-(def v (take 1000000 (range)))
-(reduce + 0 (r/map inc [1 2 3 4]))
-(into [] (r/take 12 (range 100)))
-(into [] (r/drop 12 (range 100)))
-(reduce + 0 (r/filter even? [1 2 3 4]))
-(into [] (r/filter even? [1 2 3 4]))
-(reduce + (filter even? [1 2 3 4]))
-(dotimes [_ 10] (time (reduce + 0 (r/map inc v))))
-(dotimes [_ 10] (time (reduce + 0 (map inc v))))
-(dotimes [_ 100] (time (reduce + 0 v)))
-(dotimes [_ 100] (time (reduce + 0 v)))
-(dotimes [_ 20] (time (reduce + 0 (r/map inc (r/filter even? v)))))
-(dotimes [_ 20] (time (reduce + 0 (map inc (filter even? v)))))
-(reduce + 0 (r/take-while even? [2 4 3]))
-(into [] (r/filter even? (r/flatten (r/remove #{4} [[1 2 3] 4 [5 [6 7 8]] [9] 10]))))
-(into [] (r/flatten nil))
-)


Performance improvements

Performance improvements

Split log entry row into its own component which prevents rerendering
(simple equiv check instead).
Split creation of viewed log entries out of log table code. This allows
quicker and more correct equiv tests for the entire table (probably not
a lot of difference until the deployment data changes without the log
changes).
Still very CPU bound. Next step is batching log entries together.

--- src/cljs/onyx_dashboard/core.cljs
+++ src/cljs/onyx_dashboard/core.cljs
@@ -62,8 +62,7 @@
           (dom/div
             (b/toolbar {}
                        (apply (partial b/dropdown {:bs-style "primary"
-                                                   :title (or (:id deployment)
-                                                              "Deployments")})
+                                                   :title (or (:id deployment) "Deployments")})
                               (for [[id info] (reverse (sort-by (comp :created-at val)
                                                                 deployments))]
                                 (b/menu-item {:key id
@@ -78,31 +77,27 @@
                           (:job-id entry))]
     (= entry-job-id job-id)))

-(defcomponent deployment-entries [{:keys [selected-job entries message-id-max]} owner]
-  (render [_]
-          (let [num-displayed 100
-                start-id (max 0 (- (inc message-id-max) num-displayed))
-                displayed-msg-ids (range start-id (inc message-id-max))]
+(defcomponent log-entry-row [entry owner]
+  (render [_]
+          (dom/tr {:key (str "entry-" (:message-id entry))
+                   :title (str (om/value entry))}
+                  (dom/td (str (:id (:args entry))))
+                  (dom/td (.fromNow (js/moment (str (js/Date. (:created-at entry))))))
+                  (dom/td (str (:fn entry))))))
+
+(defcomponent log-entries-table [entries owner]
+  (render [_]
+          (let []
             (dom/pre
              (dom/h4 "Cluster Activity")
              (table {:striped? true :bordered? true :condensed? true :hover? true}
-                    (dom/thead
-                     (dom/tr
-                      (dom/th "ID")
-                      (dom/th "Time")
-                      (dom/th "fn")))
+                    (dom/thead (dom/tr (dom/th "ID") (dom/th "Time") (dom/th "fn")))
                     (dom/tbody ;{:height "500px" :position "absolute" :overflow-y "scroll"}
-                                        ; Entries may not exist if they have come in out of order from sente,
-                                        ; thus we only keep the not nil entries
-                     (for [entry (keep entries (reverse displayed-msg-ids))]
-                       (dom/tr {:key (str "entry-" (:message-id entry))
-                                :title (str (om/value entry))}
-                               (dom/td (str (:id (:args entry))))
-                               (dom/td (.fromNow (js/moment (str (js/Date. (:created-at entry))))))
-                               (dom/td (str (:fn entry)))))))))))
+                               (map (fn [entry]
+                                      (om/build log-entry-row entry {}))
+                                    entries)))))))

 (defn select-job [id]
-  (println "Selecting job " id)
   (swap! app-state assoc-in [:deployment :selected-job] id))

 (defcomponent job-selector [{:keys [selected-job jobs]} owner]
@@ -150,6 +145,8 @@
                      :closeWith ["click" "button"]})))

 (defn msg-controller [type msg]
+  ; success notification currently notifys about bad tracking ids
+  ; probably going to need a better session management check
   (success-notification type)
   (swap! app-state
          (fn [state]
@@ -180,7 +177,7 @@
     (case msg-type
       :chsk/recv
       (let [[recv-type recv-msg] msg]
-        (println "Recv event " event)
+        ;(println "Recv event " event)
         (msg-controller recv-type recv-msg))
       :chsk/state (when (:first-open? msg)
                     (chsk-send! [:deployment/get-listing])
@@ -188,6 +185,12 @@
                     (println "First opened: " event)))))

 (sente/start-chsk-router! ch-chsk event-handler)
+
+(defn deployment->latest-log-entries [{:keys [entries message-id-max] :as deployment}]
+  (let [num-displayed 100
+        start-id (max 0 (- (inc message-id-max) num-displayed))
+        displayed-msg-ids (range start-id (inc message-id-max))]
+    (keep entries (reverse displayed-msg-ids))))

 (defn main []
   (om/root
@@ -206,6 +209,6 @@
             (dom/aside {}
                        (dom/nav (om/build job-selector (:deployment app) {}))
                        (dom/nav (om/build job-info (:deployment app) {}))
-                       (dom/nav (om/build deployment-entries (:deployment app) {}))))))))
+                       (dom/nav (om/build log-entries-table (deployment->latest-log-entries (:deployment app)) {}))))))))
     app-state
     {:target (. js/document (getElementById "app"))}))


my data translations

my data translations

--- src/cljs/salava/user/ui/data.cljs
+++ src/cljs/salava/user/ui/data.cljs
@@ -216,13 +216,12 @@
                  (for [e (reverse events)]
                    ^{:key e}[:tr
                              [:td [:div (t (keyword (str "social/"(:verb e))))]]
-                             [:td [:div (case (or (:type e) (:report_type e))
-                                          "page" (t (keyword (str "social/Emailpage")))
-                                          "badge" (t (keyword (str "social/Emailbadge")))
-                                           "user" (lower-case (t (keyword (str "social/User"))))
-                                           "ticket" (t (keyword (str "social/ticket")))
-                                          "admin" (lower-case (t (keyword (str "admin/Admin"))))
-                                          nil)]]
+                             [:td [:div (case (:type e)
+                                          "page" (t :social/Emailpage)
+                                          "badge" (t :social/Emailbadge)
+                                           "user" (lower-case (t :social/User))
+                                          "admin" (lower-case (t :admin/Admin))
+                                          "-")]]
                              [:td [:div (case (str (:verb e)(:type e))
                                           "publishpage"  (or (get-in e [:info :object_name]) "-")
                                           "unpublishpage" (or (get-in e [:info :object_name]) "-")
@@ -235,8 +234,8 @@
                                           "congratulatebadge" (or (get-in e [:info :object_name]) "-")
                                           "followbadge" (or (get-in e [:info :object_name]) "-")
                                           "followuser" (or (get-in e [:info :object_name]) "-")
-                                          "ticketadmin" (get-in e [:info :object_name])
-                                          nil)]]
+                                          "ticketadmin" (or (get-in e [:info :object_name]) "-")
+                                          "-")]]
                              [:td [:div (date-from-unix-time (* 1000 (:ctime e)))]]]
                    ))]]])
           ]]])]))


refactor: all moves in one go inside the turn

--- src/cljs/triboard/logic/turn.cljs
+++ src/cljs/triboard/logic/turn.cljs
@@ -26,18 +26,20 @@
 (defn- with-next-player
   "Find the next player to act - dismiss those that cannot play any move"
   [{:keys [moves player] :as game}]
-  (let [nexts (take 3 (iterate next-player (next-player player)))]
-    (assoc game :player
-                (some #(if (get moves %) % false) nexts))
+  (let [nexts (take 3 (iterate next-player (next-player player)))
+        next-valid (some #(if (get moves %) % false) nexts)]
+    (assoc game :player next-valid)
     ))

-(defn- apply-move
-  [turn move]
-  {:pre [(move/move? move)]}
-  (-> turn
-    (update :board move/apply-move move)
-    (update :scores scores/update-scores move)
-    ))
+(defn- apply-moves
+  [turn moves]
+  {:pre [(move/moves? moves)]}
+  (let [new-board (reduce move/apply-move (:board turn) moves)
+        new-scores (reduce scores/update-scores (:scores turn) moves)]
+    (-> turn
+      (assoc :board new-board)
+      (assoc :scores new-scores)
+      )))

 ;; -----------------------------------------
@@ -66,9 +68,8 @@
   [{:keys [player board] :as turn} point]
   {:pre [(board/board? board)]}
   (if-let [moves (get-move-at turn player point)]
-    (->
-      (reduce apply-move turn moves)
-      (apply-move (move/empty-cell-move player point))
+    (-> turn
+      (apply-moves (conj moves (move/empty-cell-move player point)))
       (with-available-moves)
       (with-next-player))
     turn))


Fix 'already refers to' compiler warnings

--- src/clojure/contrib/humanize.cljc
+++ src/clojure/contrib/humanize.cljc
@@ -1,4 +1,5 @@
 (ns clojure.contrib.humanize
+  (:refer-clojure :exclude [abs])
   (:require #?(:clj  [clojure.math.numeric-tower :refer [expt floor round abs]])
             [clojure.contrib.inflect :refer [pluralize-noun in?]]
             [clojure.string :refer [join]]


Moved XML helper functions to cmr-common-lib.

--- src/cmr/umm/echo10/collection.clj
+++ src/cmr/umm/echo10/collection.clj
@@ -2,44 +2,27 @@
   "Contains functions for parsing and generating the ECHO10 dialect."
   (:require [clojure.data.xml :as x]
             [clojure.java.io :as io]
+            [cmr.common.xml :as cx]
             [cmr.umm.collection :as c]
             [cmr.umm.xml-schema-validator :as v]))

-(defn- content-at-path
-  "This is a helper that will pull the XML content from the xml-struct at the given path.
-  Note this implementation is not likely to be particularly fast. We should investigate that as part
-  of another future issue."
-  [xml-struct path]
-  (if (sequential? path)
-    (reduce content-at-path xml-struct path)
-    (cond
-      (sequential? xml-struct) (->> xml-struct (filter #(= path (:tag %))) first :content)
-      (map? xml-struct) (when (= path (:tag xml-struct)) (:content xml-struct))
-      :else (throw (Exception.
-                     (format
-                       "Unexpected xml-struct at path. path: [%s] xml-struct: [%s]"
-                       path xml-struct))))))

-(defn- string-at-path
-  "Extracts a string from the given path in the XML structure."
-  [xml-struct path]
-  (-> (content-at-path xml-struct path) first str))

 (defn- xml-elem->Product
   "Returns a UMM Product from a parsed Collection XML structure"
   [xml-struct]
-  (let [collection-content (content-at-path xml-struct [:Collection])]
-    (c/map->Product {:short-name (string-at-path collection-content [:ShortName])
-                     :long-name (string-at-path collection-content [:LongName])
-                     :version-id (string-at-path collection-content [:VersionId])})))
+  (let [collection-content (cx/content-at-path xml-struct [:Collection])]
+    (c/map->Product {:short-name (cx/string-at-path collection-content [:ShortName])
+                     :long-name (cx/string-at-path collection-content [:LongName])
+                     :version-id (cx/string-at-path collection-content [:VersionId])})))

 (defn- xml-elem->Collection
   "Returns a UMM Product from a parsed Collection XML structure"
   [xml-struct]
-  (let [collection-content (content-at-path xml-struct [:Collection])
+  (let [collection-content (cx/content-at-path xml-struct [:Collection])
         product (xml-elem->Product xml-struct)]
     (c/map->UmmCollection {:entry-id (str (:short-name product) "_" (:version-id product))
-                           :entry-title (string-at-path collection-content [:DataSetId])
+                           :entry-title (cx/string-at-path collection-content [:DataSetId])
                            :product product})))

 (defn parse-collection


Parse SQS msg attribute values order-independent (#38)

I noticed recently that SQS was returning messages where the DataType
and StringValue nodes did not always come with DataType first.  This fix
just makes the parse of attribute value order-independent.

--- src/eulalie/sqs.cljc
+++ src/eulalie/sqs.cljc
@@ -96,14 +96,22 @@
 (defmethod restructure-response :send-message [_ body]
   (x/child-content->map body {:message-id :id :md-5-of-message-body :body-md5}))

+(defn attr-type->value-key [type]
+  (case type
+    :string :string-value
+    :number :string-value
+    :binary :binary-value))
+
 (defn message-attr->kv [attr]
   (let [a-name (x/child-content attr :name)
-        {[type value] :value} (x/child attr :value)
-        type (keyword (x/child-content type :data-type))
+        value-container (x/child attr :value)
+        type (keyword (x/child-content value-container :data-type))
         in-type ({:Binary :binary
                   :String :string
-                  :Number :number} type type)]
-    [(keyword a-name) [in-type (x/content value)]]))
+                  :Number :number} type type)
+        value-key (attr-type->value-key in-type)
+        value (x/child-content value-container value-key)]
+    [(keyword a-name) [in-type value]]))

 (defn message-attrs->map [message]
   (into {}


test fail

test fail

--- src/govalert/run.clj
+++ src/govalert/run.clj
@@ -30,8 +30,8 @@
               (store/add-subscription :email email :query query :updated updated))
             (log/info "Alerted" email "for query" query "on" index "with" c "matches."))
 ;          (catch Exception e
-;            (log/error "Failed to notify for" index "subscription" subscription)
-)))))
+;            (log/error "Failed to notify for" index "subscription" subscription))
+))))

 (defn db-count [index]
   (db/with-index index


Make Complete work with empty input (INTERIM CHECK-IN)

--- src/de/kotka/vimclojure/nails.clj
+++ src/de/kotka/vimclojure/nails.clj
@@ -158,11 +158,15 @@
   "Usage: ng de.kotka.vimclojure.nails.Complete"
   [[nspace n "Start completion in this namespace." "user"]]
   (let [_      (resolve-and-load-namespace nspace)
-        sym    (read)
-        symnam (name sym)
-        symspc (namespace sym)]
-    (println
-      (clj->vim
-        (map (fn [[sym sym-var]]
-               (make-completion-item sym sym-var))
-             (complete-var-in-namespace symnam (if symspc symspc nspace)))))))
+        eof    (Object.)
+        sym    (read *in* false eof)]
+    (if (not= sym eof)
+      (let [symnam (name sym)
+            symspc (namespace sym)]
+        (when (not= sym eof)
+          (-> (map (fn [[sym sym-var]]
+                     (make-completion-item sym sym-var))
+                   (complete-var-in-namespace symnam (if symspc symspc nspace)))
+            clj->vim
+            println)))
+      (println "[]"))))


[#1316] Fix sharing of all-raster maps

[#1316] Fix sharing of all-raster maps

--- backend/src/akvo/lumen/lib/public_impl.clj
+++ backend/src/akvo/lumen/lib/public_impl.clj
@@ -49,15 +49,20 @@

 (defmethod visualisation "map"
   [tenant-conn visualisation {:keys [windshaft-url]}]
-  (let [layers (get-in visualisation [:spec "layers"])
-        dataset-id (some #(get % "datasetId") layers)
-        [map-data-tag map-data] (maps/create tenant-conn windshaft-url layers)
-        [dataset-tag dataset] (dataset/fetch tenant-conn dataset-id)]
-    (when (and (= map-data-tag ::lib/ok)
-               (= dataset-tag ::lib/ok))
-      {"datasets" {dataset-id (dissoc dataset :rows)}
-       "visualisations" {(:id visualisation) (merge visualisation map-data)}
-       "metadata" {(:id visualisation) map-data}})))
+  (let [layers (get-in visualisation [:spec "layers"])]
+    (if (some #(get % "datasetId") layers)
+      (let [dataset-id (some #(get % "datasetId") layers)
+              [map-data-tag map-data] (maps/create tenant-conn windshaft-url layers)
+              [dataset-tag dataset] (dataset/fetch tenant-conn dataset-id)]
+          (when (and (= map-data-tag ::lib/ok)
+                     (= dataset-tag ::lib/ok))
+            {"datasets" {dataset-id (dissoc dataset :rows)}
+             "visualisations" {(:id visualisation) (merge visualisation map-data)}
+             "metadata" {(:id visualisation) map-data}}))
+      (let [[map-data-tag map-data] (maps/create tenant-conn windshaft-url layers)]
+          (when (= map-data-tag ::lib/ok))
+            {"visualisations" {(:id visualisation) (merge visualisation map-data)}
+             "metadata" {(:id visualisation) map-data}}))))

 (defmethod visualisation :default
   [tenant-conn visualisation config]


[#2964] Filter isEmpty option column as text type

--- backend/src/akvo/lumen/postgres/filter.clj
+++ backend/src/akvo/lumen/postgres/filter.clj
@@ -101,7 +101,7 @@

 (defmethod filter-sql "isEmpty"
   [{:keys [column operation]}]
-  (if (= (:type column) "text")
+  (if (or (= (:type column) "option") (= (:type column) "text"))
     (format "coalesce(%s, '') %s ''"
             (column :columnName)
             (if (= operation "keep") "=" "<>"))


Simplify doc impl

Simplify doc impl

--- ClojureScript/replete/src/replete/core.cljs
+++ ClojureScript/replete/src/replete/core.cljs
@@ -97,14 +97,13 @@
                 in-ns (reset! current-ns (second (second form)))
                 doc (if (repl-specials (second form))
                       (repl/print-doc (repl-special-doc (second form)))
-                      (let [var-ast (ana/analyze env `(var ~(second form)))
-                           var-js (with-out-str
-                                    (ensure
-                                      (c/emit var-ast)))
-                           var-ret (js/eval var-js)]
-                       (repl/print-doc (update (meta var-ret) :doc (if (user-interface-idiom-ipad?)
-                                                                     identity
-                                                                     reflow))))))
+                      (repl/print-doc
+                        (let [sym (second form)
+                              var (ana/resolve-var env sym)]
+                          (update (:meta var)
+                            :doc (if (user-interface-idiom-ipad?)
+                                   identity
+                                   reflow))))))
               (let [_ (when DEBUG (prn "form:" form))
                     ast (ana/analyze env form)
                     _ (when DEBUG (prn "ast:" ast))


fix whitespace.

fix whitespace.

--- src/leiningen/ancient/upgrade.clj
+++ src/leiningen/ancient/upgrade.clj
@@ -1,5 +1,5 @@
-(ns ^{ :doc "Rewrite project.clj to include latest versions of dependencies."
-       :author "Yannick Scherer" }
+(ns ^{:doc "Rewrite project.clj to include latest versions of dependencies."
+      :author "Yannick Scherer"}
   leiningen.ancient.upgrade
   (:require [leiningen.ancient.utils.test :as t]
             [leiningen.ancient.utils.projects :refer :all]
@@ -147,16 +147,16 @@
       (with-output-settings settings
         (if-let [outdated (seq
                             (->> artifacts
-                              (c/get-outdated-artifacts! repos settings)
-                              (filter-artifacts-with-prompt! settings)))]
+                                 (c/get-outdated-artifacts! repos settings)
+                                 (filter-artifacts-with-prompt! settings)))]
           (when-let [map-loc (read-zipper-fn path)]
             (when-let [new-loc (upgrade-artifact-map! map-loc settings outdated)]
               (when (:interactive settings) (main/info))
               (main/info (count outdated)
-                       (if (= (count outdated) 1)
-                         "artifact was"
-                         "artifacts were")
-                       "upgraded.")
+                         (if (= (count outdated) 1)
+                           "artifact was"
+                           "artifacts were")
+                         "upgraded.")
               (write-zipper! path new-loc settings)))
           (do (main/info "Nothing was upgraded.") ::nothing))))))

@@ -229,15 +229,15 @@
 (def upgrade-project-file!
   "Run upgrade on the given project file using the given settings."
   (-> upgrade-project-file!*
-    with-tests
-    with-backup
-    with-abort))
+      with-tests
+      with-backup
+      with-abort))

 (def upgrade-profiles-file!
   "Run upgrade on the given profiles file using the given settings."
   (-> upgrade-profiles-file!*
-    with-backup
-    with-abort))
+      with-backup
+      with-abort))

 ;; ## Wrappers

@@ -284,5 +284,5 @@
   [project args]
   (let [profiles-file (io/file (System/getProperty "user.home") ".lein" "profiles.clj")
         settings (-> (parse-cli args)
-                   (assoc :plugins true))]
+                     (assoc :plugins true))]
     (upgrade-profiles-file! project settings profiles-file)))


Clarify mk-session Clojure doc for #217 and #212

--- src/main/clojure/clara/rules.cljc
+++ src/main/clojure/clara/rules.cljc
@@ -282,24 +282,28 @@
      "Creates a new session using the given rule sources. The resulting session
       is immutable, and can be used with insert, retract, fire-rules, and query functions.

-      If no sources are provided, it will attempt to load rules from the caller's namespace.
+      If no sources are provided, it will attempt to load rules from the caller's namespace,
+      which is determined by reading Clojure's *ns* var.
+
       This will use rules defined with defrule, queries defined with defquery, and sequences
       of rule and/or query structures in vars that are annotated with the metadata ^:production-seq.

-      The caller may also specify keyword-style options at the end of the parameters. Currently four
-      options are supported:
+      The caller may also specify keyword-style options at the end of the parameters. Currently five
+      options are supported, although most users will either not need these or just the first two:

       * :fact-type-fn, which must have a value of a function used to determine the logical type of a given
         cache. Defaults to Clojure's type function.
       * :cache, indicating whether the session creation can be cached, effectively memoizing mk-session.
         Defaults to true. Callers may wish to set this to false when needing to dynamically reload rules.
+      * :ancestors-fn, which returns a sequence of ancestors for a given type. Defaults to Clojure's ancestors function. A
+        fact of a given type will match any rule that uses one of that type's ancestors.
       * :activation-group-fn, a function applied to production structures and returns the group they should be activated with.
         It defaults to checking the :salience property, or 0 if none exists.
       * :activation-group-sort-fn, a comparator function used to sort the values returned by the above :activation-group-fn.
         Defaults to >, so rules with a higher salience are executed first.

       This is not supported in ClojureScript, since it requires eval to dynamically build a session. ClojureScript
-      users must use pre-defined rulesessions using defsession."
+      users must use pre-defined rule sessions using defsession."
      [& args]
      (if (and (seq args) (not (keyword? (first args))))
        `(com/mk-session ~(vec args)) ; At least one namespace given, so use it.


Document api/list-groups

Document api/list-groups

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -12,8 +12,9 @@
 ;;--------------------------------------------------------------------

 (defmulti list-groups
-  "Returns a sequence of Thing[:group] representing all Maven groups
-  in the queried datastore."
+  "Succeeds with a result Seq[Group] representing all Maven groups in the
+  queried datastore. Will succeed with an empty result if there are no known
+  groups. Fails if the datstore isn't correctly configured or missing."

   {:arglists '[[config]]}
   dispatch)


Add note about factory fns in impl.

Add note about factory fns in impl.

--- src/main/clojure/clojure/tools/logging.clj
+++ src/main/clojure/clojure/tools/logging.clj
@@ -15,9 +15,10 @@
             runtime a specific implementation is selected from, in order, slf4j,
             Apache commons-logging, log4j, and finally java.util.logging.

-           The logging implementation can be expliticly determined by using
-           binding or alter-var-root to change the value of *logger-factory* to
-           another implementation of clojure.tools.logging.impl/LoggerFactory."}
+            The logging implementation can be expliticly determined by using
+            binding or alter-var-root to change the value of *logger-factory* to
+            another implementation of clojure.tools.logging.impl/LoggerFactory
+            (see also the *-factory functions in the impl namespace)."}
   clojure.tools.logging
   [:use
    [clojure.string :only [trim-newline]]


fix compile

fix compile

--- src/jsx_fun/core.clj
+++ src/jsx_fun/core.clj
@@ -109,10 +109,12 @@
    (compile dir "out"))
   ([dir outdir]
    (letfn [(dir? [^File x] (.isDirectory x))]
+     (.mkdir (io/file outdir))
      (doseq [file (remove dir? (file-seq (io/file dir)))]
-       (spit (io/file outdir (.getName file))
-         (transform-commonjs
-           (transform-jsx (slurp file))))))))
+       (let [out-file (io/file outdir (.getName file))]
+         (spit out-file
+           (transform-commonjs
+             (transform-jsx (slurp file)))))))))

 ;(defn transform-commonjs
 ;  [filename src]


Add parser to retract bogus roles

Add parser to retract bogus roles

--- src/kevin/loader.clj
+++ src/kevin/loader.clj
@@ -74,7 +74,13 @@
 (defn role-line? [^String line]
   (and
     (movie-line? line)
-    (not= -1 (.indexOf line ")")) ))
+    (not= -1 (.indexOf line ")"))))
+
+(defn legit-role? [^String line]
+  (and
+    (= -1 (.indexOf line "(archive footage)"))
+    (= -1 (.indexOf line "(unconfirmed)"))
+    (= -1 (.indexOf line "(archival"))))

 (defn split-by [pred coll]
   (let [remove-sep (fn [el] ((complement pred) (first el)))]
@@ -102,6 +108,19 @@
             actor-tx  { :db/id actor-id, :person/name actor }]
       (concat [actor-tx] movie-txs)))))

+(defn retract-roles
+  ([a] (actor-tx-data (db conn) a))
+  ([d {:keys [actor movies]}]
+   (->> (q '[:find ?actor ?movie
+             :in $ ?name [?title ...]
+             :where
+             [?actor :person/name ?name]
+             [?actor :actor/movies ?movie]
+             [?movie :movie/title ?title]]
+           d actor movies)
+        (map (fn [[actor movie]]
+               [:db/retract actor :actor/movies movie])))))
+
 (defn parse-genre [db ^String line]
   (let [[title genre] (map #(.trim %) (clojure.string/split line #"\t+"))]
     (when-let [g (genres genre)]
@@ -152,6 +171,27 @@
         (filter identity)
         (map parse-fn)
         (filter identity))))
+
+(defn parse-bogus-roles [lines]
+  (let [{actor :actor potential-roles :movies} (extract-potential-roles lines)
+        roles (map extract-role (filter #(and (role-line? %) (not (legit-role? %))) potential-roles))
+        movies (filter identity roles)]
+    (when (and (seq movies) actor)
+      { :actor actor :movies movies })))
+
+(defn retract-bogus-roles [lines]
+  (try
+    (let [actor-roles (actors-and-roles lines parse-bogus-roles)]
+      (doseq [batch (partition-all *batch-size* actor-roles)]
+        (let [d (db conn)
+              tx (mapcat (partial retract-roles d) batch)]
+          (if (empty? tx)
+            (print "-")
+            (do (d/transact-async conn tx)
+                (print "."))))
+        (flush)))
+    (catch Exception e))
+  (println "done"))

 (defn parse-actors [lines]
   (try


cleanup

cleanup

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/stats/regression.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/stats/regression.cljs
@@ -1,6 +1,4 @@
 (ns birdwatch.stats.regression)
-
-(enable-console-print!)

 (defn square [x] (* x x))
 (defn mean [xs]


Do not add any prefix to the library signature when archiving

--- src/mdr2/archive.clj
+++ src/mdr2/archive.clj
@@ -69,7 +69,7 @@
   ([production sektion volume]
    (case sektion
      :master (prod/dam-number production)
-     :dist-master (str "ds" (:library_signature production)
+     :dist-master (str (:library_signature production)
                        (when (and volume
                                   (prod/multi-volume? production))
                          (str "_" volume))))))


Added an HCard output example.

Added an HCard output example.

--- test/cassidy/core_test.clj
+++ test/cassidy/core_test.clj
@@ -66,9 +66,8 @@
   (-get-class-attribute [_] "stand.Img")
   (-write-str [img el]
     (html [el {:class (shon/-get-class-attribute img)}
-           [:div.image
            [:p [:label "Source URL: "] [:code (:src img)]]
-            [:img {:src (:src img) :alt (:alt-text img) :title (:alt-text img)}]]])))
+           [:img {:src (:src img) :alt (:alt-text img) :title (:alt-text img)}]])))

 ;;; We can even extend an existing java object with a custom representation. Let's use UUID as an example.
 (extend-protocol shon/SHONWriter
@@ -78,6 +77,37 @@
     (html [el {:class (shon/-get-class-attribute uuid)}
            [:label "UUID: "]
            [:span (str uuid)]])))
+
+;;; Let's do a custom format that is useful. Try an hCard address microformat
+(defrecord Adr [street-address locality region postal-code country-name]
+  shon/SHONWriter
+  (-get-class-attribute [_] "adr")
+  (-write-str [adr el]
+    (html [el {:class (shon/-get-class-attribute adr)}
+           [:div.street-address (:street-address adr)]
+           [:span.locality (:locality adr) ", "]
+           [:span.region (:region adr) ", "]
+           [:span.postal-code (:postal-code adr) " "]
+           [:span.country-name (:country-name adr)]])))
+
+(defrecord HCard [fn org email adr tel]
+  shon/SHONWriter
+  (-get-class-attribute [_] "shon.vcard")
+  (-write-str [hcard el]
+    (html [el {:class (shon/-get-class-attribute hcard)}
+           [:div.vcard
+            [:span.fn (:fn hcard)]
+            [:div.org (:org hcard)]
+            [:a.email {:href (str "mailto:" (:email hcard))} (:email hcard)]
+            (shon/write-str adr)
+            [:div.tel (:tel hcard)]]])))
+
+(def stan (->HCard "Stan Dyck"
+                   "Quest Diagnostics"
+                   "stan.dyck@medplus.com"
+                   (->Adr "8801 6th Av NW"
+                          "Seattle" "WA" "98117" "USA")
+                   "206-419-8059"))

 ;;; A macro that turned this (below) into the extend-protocol form above would be useful.
 #_(defshon-representation UUID [uuid]
@@ -98,7 +128,8 @@
     (let [bp (BPReading. 125 70)
           img (Image. "http://placekitten.com/g/300/450" "A Cute Kitten")
           uuid (java.util.UUID/randomUUID)
-          m {:bp-reading bp :image img :uuid uuid}]
+          m {:bp-reading bp :image img :uuid uuid
+             :hcard stan}]
       (println "bp:" bp)
       (println "img:" img)
       (shon/pprint m)


Tidy up

Tidy up

--- test/discuss/foo_test.cljs
+++ test/discuss/foo_test.cljs
@@ -1,5 +0,0 @@
- (ns discuss.foo-test
-   (:require [cljs.test :refer-macros [deftest is]]))
-
-(deftest do-i-work
-  (is (= 1 2)))


increasing git-test timeout to make sure the build is stable on travis

--- test/lambdacd/git_test.clj
+++ test/lambdacd/git_test.clj
@@ -40,7 +40,7 @@

 (defn get-value-or-timeout-from [c]
   (async/go
-    (async/<! (async/timeout 10000))
+    (async/<! (async/timeout 60000))
     (async/>! c {:status :timeout :current-revision "timeout"}))
   (async/<!! c))


Slightly prettier core test

Slightly prettier core test

--- test/merkki/core_test.cljc
+++ test/merkki/core_test.cljc
@@ -12,6 +12,41 @@
 ;;;
 ;;; Markdown test
 ;;;
+
+(def md-sample
+"Markdown Test
+=============
+
+This is a test of the merkki markdown rendering system.
+
+## Span Elements
+
+A subvector of strings can be passed, allowing usage of span elements like *emphasized*, **strong**, [links](http://www.google.com), and ``code``. We can also do auto-links like so: <http://www.github.com/jarcane/merkki>.
+
+![Here's a pug to show off images.](https://pbs.twimg.com/profile_images/378800000515894032/0758bced4b2f071fbf9916e15d28e7a8.jpeg)
+
+## Block Elements
+
+1. Here
+2. Is
+3. An
+4. Ordered
+5. List
+
+* Here's
+* An
+* Unordered
+* List
+
+```
+(defn some-code [] \"Hello World!\")
+```
+
+> Here is a big long block quote that is too long
+> so we've made it onto multiple lines because that
+> is just how we roll.
+
+")

 (deftest markdown-test
   (testing "Given a vector of block elements, return a string of markdown formatted text"
@@ -43,36 +78,4 @@
               "Here is a big long block quote that is too long"
               "so we've made it onto multiple lines because that"
               "is just how we roll."]])
-           "Markdown Test
-=============
-
-This is a test of the merkki markdown rendering system.
-
-## Span Elements
-
-A subvector of strings can be passed, allowing usage of span elements like *emphasized*, **strong**, [links](http://www.google.com), and ``code``. We can also do auto-links like so: <http://www.github.com/jarcane/merkki>.
-
-![Here's a pug to show off images.](https://pbs.twimg.com/profile_images/378800000515894032/0758bced4b2f071fbf9916e15d28e7a8.jpeg)
-
-## Block Elements
-
-1. Here
-2. Is
-3. An
-4. Ordered
-5. List
-
-* Here's
-* An
-* Unordered
-* List
-
-```
-(defn some-code [] \"Hello World!\")
-```
-
-> Here is a big long block quote that is too long
-> so we've made it onto multiple lines because that
-> is just how we roll.
-
-"))))
+           md-sample))))


Update a test to handle extra log output

--- test/runbld/tests_test.clj
+++ test/runbld/tests_test.clj
@@ -80,8 +80,8 @@
     (let [out (with-out-str (tests/capture-failures "test/xmls"))
           log (debug/get-log)]
       (is (re-find #"Failed to parse" out))
-      (is (re-find #"(?m)ErrorHandlerWrapper.createSAXParseException"
-                   (second log))))
+      (is (some #(re-find #"(?m)ErrorHandlerWrapper.createSAXParseException" %)
+                log)))
     (catch Exception e
       (is false "There shouldn't have been any exceptions")
       (stacktrace/print-cause-trace e))))


(PDB-2640) Add comment about gzip decompression and buffering perf

This commit adds a comment to the code where a decompression stream is
wrapped around the command input stream about how it's best for
performance to not wrap another buffered input stream between the
original command input stream and the decompression stream.

--- src/puppetlabs/puppetdb/queue.clj
+++ src/puppetlabs/puppetdb/queue.clj
@@ -254,6 +254,13 @@
         entry (cmdref->entry cmdref)]
     (with-open [command-stream (stock/stream q entry)]
       (assoc cmdref
+        ;; For performance reasons, it's best to wrap any decompression stream
+        ;; around the original command stream before calling into stream->json.
+        ;; stream->json wraps it's own BufferedReader around the stream before
+        ;; parsing bytes from it as json.  From testing, we've seen that if we
+        ;; wrap an extra buffered input stream between the original command
+        ;; stream and the decompressing stream, Gzip in particular, that
+        ;; throughput would be much worse - could be up to 400x times slower.
         :payload (stream->json (wrap-decompression-stream
                                 compression
                                 command-stream))


make map inspect a bit more compact

make map inspect a bit more compact

--- src/main/shadow/cljs/ui/pages/inspect.cljs
+++ src/main/shadow/cljs/ui/pages/inspect.cljs
@@ -128,7 +128,8 @@
      (fn [{:keys [summary] :as msg}]
        (swap! state assoc-in [::oid oid :summary] (add-ts summary))
        ;; FIXME: don't rerender just yet?
-       (refresh-ui [[::oid oid]])
+       (refresh-ui [[::oid oid]
+                    [::tap-page rid]])
        (maybe-fetch-initial-fragment state (get-in @state [::oid oid])))}))

 (defn add-first [prev head max]
@@ -229,15 +230,13 @@
       (swap! state update-in [::rid rid] merge {::object nil
                                                 ::nav-stack []}))))

-(defmutation select-object [{:keys [oid] :as params}]
+(defmutation select-tap-object [{:keys [rid oid] :as params}]
   (action [{:keys [state] :as env}]

-    (let [{::keys [rid] :as obj}
-          (get-in @state [::oid oid])]
-
+    (let [obj (get-in @state [::oid oid])]
       (maybe-fetch-initial-fragment state obj)

-      (swap! state update-in [::rid rid] merge
+      (swap! state update-in [::tap-page rid] merge
         {::object [::oid oid]
          ::nav-stack []}))

@@ -267,8 +266,9 @@
            (swap! state
              (fn [state]
                (-> state
-                   (update-in [::rid rid ::nav-stack] conj params)
-                   (assoc-in [::rid rid ::object] [::oid ref-oid]))))
+                   (update-in [::tap-page rid ::nav-stack] conj params)
+                   (assoc-in [::tap-page rid ::object] [::oid ref-oid]))))
+           (refresh-ui [[::tap-page rid]])
            (add-new-nav-obj state rid ref-oid))}))))

 (defmutation nav-stack-jump [{:keys [rid oid idx] :as params}]
@@ -277,8 +277,8 @@
     (swap! state
       (fn [state]
         (-> state
-            (assoc-in [::rid rid ::object] [::oid oid])
-            (update-in [::rid rid ::nav-stack] subvec 0 idx))))
+            (assoc-in [::tap-page rid ::object] [::oid oid])
+            (update-in [::tap-page rid ::nav-stack] subvec 0 idx))))
     ))

 (defmutation switch-object-display [{wanted-display :display :keys [oid] :as params}]
@@ -554,61 +554,85 @@
   [this summary fragment]
   (render-seq this summary fragment))

+(defstyled map-root :div [env]
+  {:display "grid"
+   :padding "0 1rem"
+   :grid-template-columns "min-content minmax(25%, auto)"
+   :grid-row-gap "1px"
+   :grid-column-gap ".5rem"})
+
+(defstyled map-span :div [env]
+  {:grid-column-start "span 2"})
+
+(defstyled map-entry :div [env]
+  {:display "contents"
+   :cursor "pointer"})
+
+;; {:className "pl-4 pr-2 font-bold whitespace-no-wrap truncate"}
+(defstyled map-key :div [env]
+  {:font-weight "bold"
+   :padding "0 .25rem"
+   :white-space "nowrap"
+   :overflow "hidden"
+   :text-overflow "ellipsis"
+   :background-color "#fafafa"
+   "&:hover"
+   {:background-color "#eee"}})
+
+;; {:className "pr-4 truncate"}
+(defstyled map-val :div [env]
+  {:white-space "nowrap"
+   :overflow "hidden"
+   :text-overflow "ellipsis"})
+
 (defmethod render-view :map
   [this {:keys [oid entries] :as summary} fragment]
-  (html/div {:className "bg-white w-full"}
+  (map-root {:class "font-mono"}
     (html/for [idx (range entries)
                :let [{:keys [key val] :as entry} (get fragment idx)
                      [key-limit-reached key-limit-text] key]]
       (cond
         (nil? entry)
-        (html/div {:key idx :className "border"
-                   :onMouseEnter
-                   (fn [e]
-                     (fc/transact! this [(request-fragment {:oid oid
-                                                            :idx idx})]))}
+        (map-span
+          {:key idx :className "border"
+           :onMouseEnter
+           (fn [e]
+             (fc/transact! this [(request-fragment {:oid oid
+                                                    :idx idx})]))}
           "not available, fetch")

         ;; started loading
         (empty? entry)
-        (html/div {:key idx :className "border"} "...")
+        (map-span
+          {:key idx :className "border"} "...")

         ;; long key
-        (or key-limit-reached
-            (> (count key-limit-text) 22))
-        (html/div {:key idx
-                   :className "border-b hover:bg-gray-200"
-                   :onClick
-                   (fn [e]
-                     (fc/transact! this [(nav-object {:oid oid
-                                                      :idx idx
-                                                      :key key})]))}
-          (html/div {:className "px-4 py-1 font-bold whitespace-no-wrap cursor-pointer truncate"}
+        #_#_(or key-limit-reached
+                (> (count key-limit-text) 22))
+            (html/div {:key idx
+                       :className "border-b hover:bg-gray-200"
+                       :onClick
+                       (fn [e]
+                         (fc/transact! this [(nav-object {:oid oid
+                                                          :idx idx
+                                                          :key key})]))}
+              (html/div {:className "px-4 py-1 font-bold whitespace-no-wrap cursor-pointer truncate"}
+                (render-edn-limit key))
+              (html/div {:className "pl-4 pr-4 py-1 cursor-pointer truncate"}
+                "↳ " (render-edn-limit val)))
+
+        :else
+        (map-entry {:key idx
+                    :onClick
+                    (fn [e]
+                      (fc/transact! this [(nav-object {:oid oid
+                                                       :idx idx
+                                                       :key key})]))}
+          (map-key
             (render-edn-limit key))
-          (html/div {:className "pl-4 pr-4 py-1 cursor-pointer truncate"}
-            "↳ " (render-edn-limit val)))
-
-        :else
-        (html/div {:key idx
-                   :className "flex py-1 border-b hover:bg-gray-200"
-                   :onClick ;; FIXME: only add if nav is actually supported
-                   (fn [e]
-                     (fc/transact! this [(nav-object {:oid oid
-                                                      :idx idx
-                                                      :key key})]))}
-          (html/div
-            {:className "pl-4 pr-2 font-bold whitespace-no-wrap cursor-pointer truncate"
-             :style {:flex "220px 0 0"}}
-            (render-edn-limit key)
-            #_(let [[limit-reached text] key
-                    len (count text)]
-                (if (> len 22)
-                  (str (subs text 0 6) "..." (subs text (- len 13) len))
-                  text)))
-          (html/div
-            {:className "pr-4 cursor-pointer truncate"}
-            (render-edn-limit val)
-            ))))))
+          (map-val
+            (render-edn-limit val)))
+        ))))

 (defsc Runtime [this {::keys [rid] :as props}]
   {:ident
@@ -861,65 +885,26 @@
   [this {::keys [rid] :as props}]
   {:ident
    (fn []
-     [::rid rid])
-
-   :initLocalState
-   (fn [this _]
-     (let [state-ref (atom {})]
-       {:state-ref state-ref
-        :scroll-ref
-        (fn [^js node]
-          (swap! state-ref assoc :node node)
-          #_(when node
-              (.addEventListener node "scroll"
-                (gfn/debounce
-                  (fn [e]
-                    (let [max (.-scrollHeight node)
-                          current (+ (.-scrollTop node) (.-offsetHeight node))
-
-                          is-near-bottom
-                          (> current (- max 25))]
-                      (swap! state-ref assoc :is-near-bottom is-near-bottom)))
-                  16))))}))
-
-   ;; FIXME: I'd like to have the last tap at the bottom
-   ;; auto scroll this to bottom has too many issues
-   ;; so leaving it at top for now
-
-   #_:componentDidUpdate
-   #_(fn [this _ _]
-       (let [state-ref (fc/get-state this :state-ref)
-             {:keys [node is-near-bottom]} @state-ref]
-         (when (and node is-near-bottom)
-           (js/setTimeout
-             (fn []
-               (let [scroll-top (.-scrollHeight node)]
-                 (js/console.log "setting scroll-top to" scroll-top)
-                 (set! (.-scrollTop node) scroll-top)))
-             ;; FIXME: do this properly
-             ;; this is only required because componentDidUpdate fires
-             ;; before all all the taps may have been added
-             ;; it might render an empty div first because it is still
-             ;; fetching the data, which means the scrollHeight is
-             ;; lower than it needs to be
-             ;; don't want to set a fixed height either though
-             50))))
+     [::tap-page rid])

    :query
    (fn []
      [::rid
-      ::runtime-info
-      ::supported-ops
+      {::runtime [::runtime-info
+                  ::supported-ops]}
       {::objects (fc/get-query ObjectListItem)}
       {::object (fc/get-query ObjectDetail)}
       ::nav-stack])}

-  (let [{::keys [runtime-info supported-ops objects object nav-stack]}
+  (let [{::keys [runtime objects object nav-stack]}
         props
+
+        {::keys [runtime-info supported-ops]}
+        runtime

         select-fn
         (fn [oid]
-          (fc/transact! this [(select-object {:rid rid :oid oid})]))
+          (fc/transact! this [(select-tap-object {:rid rid :oid oid})]))

         scroll-ref
         (fc/get-state this :scroll-ref)
@@ -1043,8 +1028,6 @@
   {:class RuntimeTapPage
    :factory ui-runtime-tap-page})

-
-
 (defn route [tokens]
   (if-not @tool-ref
     ;; wait for websocket connect first, then do actual route


use boolean to replace some?, backtype.storm.util is compatible with clojure 1.6

--- storm-core/src/clj/backtype/storm/util.clj
+++ storm-core/src/clj/backtype/storm/util.clj
@@ -566,10 +566,6 @@
   (while (not (apredicate))
     (Time/sleep 100)))

-(defn some?
-  [pred aseq]
-  ((complement nil?) (some pred aseq)))
-
 (defn time-delta
   [time-secs]
   (- (current-time-secs) time-secs))
@@ -803,7 +799,7 @@
 (defn zip-contains-dir?
   [zipfile target]
   (let [entries (->> zipfile (ZipFile.) .entries enumeration-seq (map (memfn getName)))]
-    (some? #(.startsWith % (str target "/")) entries)))
+    (boolean (some #(.startsWith % (str target "/")) entries))))

 (defn url-encode
   [s]


[#9139] Can not purchase sticker pack (too low no sign with password button)

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

--- src/status_im/ui/screens/signing/views.cljs
+++ src/status_im/ui/screens/signing/views.cljs
@@ -208,6 +208,51 @@
         [react/text (or formatted-data "")]]]
       [password-view sign]]]))

+(defn amount-item [prices wallet-currency amount amount-error display-symbol fee-display-symbol]
+  (let [converted-value (* amount (get-in prices [(keyword display-symbol) (keyword (:code wallet-currency)) :price]))]
+    [list-item/list-item
+     {:type  :small
+      :title :t/send-request-amount
+      :error amount-error
+      :accessories [[react/nested-text {:style {:color colors/gray}}
+                     [{:style {:color colors/black}} (str (or amount 0))]
+                     " "
+                     (or display-symbol fee-display-symbol)
+                     " • "
+                     [{:style {:color colors/black}}
+                      (if converted-value
+                        (str "~" (i18n/format-currency converted-value (:code wallet-currency)))
+                        [react/activity-indicator {:color   :colors/gray
+                                                   :ios   {:size  :small}
+                                                   :android {:size :16}}])]
+                     " "
+                     (str (:code wallet-currency))]]}]))
+
+(defn fee-item [prices wallet-currency fee-display-symbol fee gas-error]
+  (let [converted-fee-value (* fee (get-in prices [(keyword fee-display-symbol) (keyword (:code wallet-currency)) :price]))]
+    [list-item/list-item
+     {:type        :small
+      :title       :t/network-fee
+      :error       gas-error
+      :accessories [[react/nested-text {:style {:color colors/gray}}
+                     [{:style {:color colors/black}} fee]
+                     " "
+                     fee-display-symbol
+                     " • "
+                     [{:style {:color colors/black}}
+                      (if converted-fee-value
+                        (str "~" (i18n/format-currency converted-fee-value (:code wallet-currency)))
+                        [react/activity-indicator {:color   :colors/gray
+                                                   :ios   {:size  :small}
+                                                   :android {:size :16}}])]
+                     " "
+                     (str (:code wallet-currency))]
+                    :chevron]
+      :on-press    #(re-frame/dispatch
+                     [:signing.ui/open-fee-sheet
+                      {:content        (fn [] [sheets/fee-bottom-sheet fee-display-symbol])
+                       :content-height 270}])}]))
+
 (views/defview sheet [{:keys [from contact amount token approve?] :as tx}]
   (views/letsubs [fee                   [:signing/fee]
                   sign                  [:signing/sign]
@@ -217,9 +262,7 @@
                   prices                [:prices]
                   wallet-currency       [:wallet/currency]]
     (let [display-symbol     (wallet.utils/display-symbol token)
-          fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))
-          converted-value (* amount (get-in prices [(keyword display-symbol) (keyword (:code wallet-currency)) :price]))
-          converted-fee-value (* fee (get-in prices [(keyword fee-display-symbol) (keyword (:code wallet-currency)) :price]))]
+          fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))]
       [react/view styles/sheet
        [header sign tx display-symbol fee fee-display-symbol]
        [separator]
@@ -232,49 +275,15 @@
           [contact-item (i18n/label :t/to) contact]
           [separator]
           [token-item token display-symbol]
-          (when-not approve?
-            [react/view
-             [list-item/list-item
-              {:type  :small
-               :title :t/send-request-amount
-               :error amount-error
-               :accessories [[react/nested-text {:style {:color colors/gray}}
-                              [{:style {:color colors/black}} (if amount (str amount) "0")]
-                              " "
-                              (or display-symbol fee-display-symbol)
-                              " • "
-                              [{:style {:color colors/black}} (if converted-value (str "~" (i18n/format-currency converted-value (:code wallet-currency)))
-                                                                  [react/activity-indicator {:color   :colors/gray
-                                                                                :ios   {:size  :small}
-                                                                                :android {:size :16}}])]
-                              " "
-                              (str (:code wallet-currency))]]}]
-             [separator]
-             [list-item/list-item
-              {:type        :small
-               :title       :t/network-fee
-               :error       gas-error
-               :accessories [[react/nested-text {:style {:color colors/gray}}
-                              [{:style {:color colors/black}} fee]
-                              " "
-                              fee-display-symbol
-                              " • "
-                              [{:style {:color colors/black}} (if converted-fee-value (str "~" (i18n/format-currency converted-fee-value (:code wallet-currency)))
-                                                                  [react/activity-indicator {:color   :colors/gray
-                                                                                :ios   {:size  :small}
-                                                                                :android {:size :16}}])]
-                              " "
-                              (str (:code wallet-currency))] :chevron]
-               :on-press    #(re-frame/dispatch
-                              [:signing.ui/open-fee-sheet
-                               {:content        (fn [] [sheets/fee-bottom-sheet fee-display-symbol])
-                                :content-height 270}])}]
-             [react/view {:align-items :center :margin-top 16 :margin-bottom 40}
-              (if keycard-multiaccount?
-                [sign-with-keycard-button amount-error gas-error]
-                [button/button {:on-press  #(re-frame/dispatch [:set :signing/sign {:type :password}])
-                                :disabled? (or amount-error gas-error)
-                                :label     :t/sign-with-password}])]])])])))
+          [amount-item prices wallet-currency amount amount-error display-symbol fee-display-symbol]
+          [separator]
+          [fee-item prices wallet-currency fee-display-symbol fee gas-error]
+          [react/view {:align-items :center :margin-top 16 :margin-bottom 40}
+           (if keycard-multiaccount?
+             [sign-with-keycard-button amount-error gas-error]
+             [button/button {:on-press  #(re-frame/dispatch [:set :signing/sign {:type :password}])
+                             :disabled? (or amount-error gas-error)
+                             :label     :t/sign-with-password}])]])])))

 (defn signing-view [tx window-height]
   (let [bottom-anim-value (anim/create-value window-height)


Cleanup not needed follow-up emails.

Cleanup not needed follow-up emails.

--- src/oc/email/app.clj
+++ src/oc/email/app.clj
@@ -23,7 +23,6 @@
         :notify (mailer/send-notification msg-body)
         :reminder-alert (mailer/send-reminder-alert msg-body)
         :reminder-notification (mailer/send-reminder-notification msg-body)
-        :follow-up (mailer/send-follow-up msg-body)
         :bot-removed (mailer/send-bot-removed msg-body)
         (timbre/error "Unrecognized message type" msg-type))))
   (sqs/ack done-channel msg))


Update home.cljs

Update home.cljs

Christina - have changed the home page to make clear that this is just data about UK & Ireland and also included Ireland everywhere... A comment in the prof workshop made me realise that the Irish might not like being lumped in with the UK... ! Justin pointed out that at the moment if you're say American or European you might not realise for a while that this is UK+ IReland data only.

--- src/prais2/home.cljs
+++ src/prais2/home.cljs
@@ -41,7 +41,7 @@
      [:.chevron [:i.fa.fa-chevron-right]]
      [:.title "Data"]]
     [:p "Explore published survival statistics"]
-    [:p "Browse hospitals on a UK map"]
+    [:p "Browse hospitals on a UK & Ireland map"]
     [:p "View hospitals in a list"]]])

 (rum/defc everything-else []
@@ -71,13 +71,13 @@
           [:a {:href "https://www.ucl.ac.uk/nicor/audits/congenital/documents/datasets/NCHDA2011-14Report"} "published survival data"]
           "published survival data")

-        " about children’s heart surgery. "]
+        " about children’s heart surgery in the UK and Ireland. "]
        [:p "Our website will help you:"]
        [:ul {:style {:font-size "16px"
                      :font-weight 200}}
         [:li "explore what survival rates can and can’t tell you"]
         [:li "understand how the NHS monitors children’s heart surgery"]
-        [:li "explore published data for UK hospitals"]]]
+        [:li "explore published data for hospitals in the UK and Ireland"]]]
       (when (:show-nicor (rum/react core/app))
         [:a {:href "https://www.ucl.ac.uk/nicor/audits/congenital/documents/datasets/NCHDA2011-14Report"}
          [:img.img-responsive.col-sm-2 {:src "assets/nicor.png"}]])]]]


add some TODOs

add some TODOs

--- test/com/billpiel/mem_tracer/core_test.clj
+++ test/com/billpiel/mem_tracer/core_test.clj
@@ -419,10 +419,14 @@

 (comment "
 TODO
+- ws ns
 - wrap args that are funcs
  - and deep search values for funcs?
 - wrap returns that are funcs
  - and deep search values for funcs?
 - diff entries
 - tree query
+- save/load workspaces
+- re-exec traces
+- deep trace
 ")


use test-utils in core-test

use test-utils in core-test

--- test/com/billpiel/mem_tracer/core_test.clj
+++ test/com/billpiel/mem_tracer/core_test.clj
@@ -4,14 +4,15 @@
             [com.billpiel.mem-tracer.trace :as mtt]
             [com.billpiel.mem-tracer.query :as mq]
             [com.billpiel.mem-tracer.util.tree-query :as mtq]
+            [com.billpiel.mem-tracer.test-utils :as t-utils]
             com.billpiel.mem-tracer.test.ns1))

 (fact-group "basic test"
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]

     (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)
     (com.billpiel.mem-tracer.test.ns1/func1 :a)
@@ -46,7 +47,7 @@
         (->> trace
              mt/entry->string
 println
-             remove-iso-ctrl)
+             t-utils/remove-iso-ctrl)
         => "[31m [1;30;41m-[40m[31m[m[33m [33m|[1;30;43m-[40m[33mcom.billpiel.mem-tracer.test.ns1/func1[m [33m|  [33m:a[0m[m [33m| return =>  [33m|  [33m:a[0m[m[32m [33m|[32m|[1;30;42m-[40m[32mcom.billpiel.mem-tracer.test.ns1/func2[m [33m|[32m|  [33m:a[0m[m [33m|[32m| return =>  [33m|[32m|  [33m:a[0m[m [33m| return =>  [33m|  [33m:a[0m[m")

       (fact "remove trace"
@@ -60,8 +61,8 @@
 (fact-group "long values display nicely"
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]

     (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)
     (com.billpiel.mem-tracer.test.ns1/func-identity {:a 1
@@ -86,8 +87,8 @@
 (fact-group "about enable/disable -all-traces!"
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]

     (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)

@@ -134,8 +135,8 @@
 (fact-group "about remove-all-traces!"
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]

     (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)

@@ -361,8 +362,8 @@
 (fact-group "exception thrown"

   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]
     (let [trace-root (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)
           _ (try
               (com.billpiel.mem-tracer.test.ns1/func-throws :a)
@@ -415,8 +416,8 @@
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/clear-log!)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]
     (let [trace-root (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)
           _ (com.billpiel.mem-tracer.test.ns1/func3-1 3 8)
           trace (mt/deref-workspace!)]
@@ -462,8 +463,8 @@
   (mtt/untrace-ns* 'com.billpiel.mem-tracer.test.ns1)
   (mt/clear-log!)
   (mt/reset-workspace!)
-  (with-redefs [mtt/now (mock-now-fn)
-                gensym (mock-gensym-fn)]
+  (with-redefs [mtt/now (t-utils/mock-now-fn)
+                gensym (t-utils/mock-gensym-fn)]
     (let [trace-root (mt/add-trace-ns! 'com.billpiel.mem-tracer.test.ns1)
           _ (com.billpiel.mem-tracer.test.ns1/func3-1 3 8)
           trace (mt/deref-workspace!)]


:lipstick: Improve code of vertx timers ns.

--- backend/vendor/vertx/src/vertx/timers.clj
+++ backend/vendor/vertx/src/vertx/timers.clj
@@ -58,19 +58,19 @@
         state  (atom nil)
         taskfn (fn wrapped-task []
                  (-> (p/do! ((::fn opts) opts))
-                     (p/catch' (constantly nil)) ; explicitly ignore all errors
+                     (p/catch' (constantly nil))  ; explicitly ignore all errors
                      (p/then'  (fn [_]            ; the user needs to catch errors
-                                 (when repeat
+                                 (if repeat
                                    (let [tid (schedule-once! vsm delay wrapped-task)]
                                      (reset! state tid)
-                                     nil))))))
-        tid  (schedule-once! vsm delay taskfn)]
-    (reset! state tid)
+                                     nil))
+                                 (do
+                                   (reset! state nil)
+                                   nil)))))
+        tid (reset! state (schedule-once! vsm delay taskfn))]
     (reify
       java.lang.AutoCloseable
       (close [this]
-        (locking this
-          (when-let [timer-id (deref state)]
-            (.cancelTimer system timer-id)
-            (reset! state nil)))))))
+        (when (compare-and-set! state tid nil)
+          (.cancelTimer system tid))))))


Add tests for mkeid function.

Add tests for mkeid function.

--- test/continuo/postgresql_spec.clj
+++ test/continuo/postgresql_spec.clj
@@ -6,6 +6,7 @@
             [continuo.impl :as impl]
             [continuo.executor :as exec]
             [continuo.util.exceptions :refer [unwrap-exception]]
+            [continuo.postgresql.transaction :as tx]
             [continuo.postgresql.bootstrap :as boot]
             [continuo.postgresql.connection :as conn]
             [continuo.postgresql.schema :as schema])
@@ -64,3 +65,19 @@
         result (p/await (co/run-schema conn schema))]
     (t/is (= result
              {:user/username {:type :string, :ident :user/username}}))))
+
+(t/deftest mkeid-handling-test
+  (binding [tx/*eid-map* (volatile! {})]
+    (let [r1 (tx/mkeid 1)
+          r2 (tx/mkeid 2)
+          r3 (tx/mkeid 1)]
+      (t/is (= (impl/-resolve-eid r1)
+               (impl/-resolve-eid r1)))
+      (t/is (= (impl/-resolve-eid r1)
+               (impl/-resolve-eid r3)))
+      (t/is (not= (impl/-resolve-eid r2)
+                  (impl/-resolve-eid r3))))))
+;; (t/deftest simple-transact-with-tmpeid
+;;   (p/await (co/create uri))
+;;   (let [conn (p/await (co/open uri))]
+


:as :json

:as :json

--- src/clj_docker/container.clj
+++ src/clj_docker/container.clj
@@ -19,7 +19,8 @@
      (let [id (:id container)]
        (client/post cli (str "/containers/" id "/start")
                     (merge
-                     {:content-type :json}
+                     {:content-type :json
+                      :as :json}
                      (when host-config
                        {:body (json/generate-string host-config)}))))))


Add a card display on the right side of page

--- src/cljs/decktouch/core.cljs
+++ src/cljs/decktouch/core.cljs
@@ -8,6 +8,7 @@
             [decktouch.card-input :as card-input])
   (:import goog.History))

+(def displayed-card-url (reagent/atom ""))

 ;; -------------------------
 ;; Views
@@ -25,7 +26,8 @@
          :data-placement "bottom"
          :data-html true
          :data-trigger "hover"
-         :title (reagent/render-component-to-string [card-img image-link])}
+         :title (reagent/render-component-to-string [card-img image-link])
+         :onClick (fn [] (reset! displayed-card-url image-link))}
          (str (get card "name"))]]))

 (defn card-in-list-did-mount [card-id]
@@ -62,11 +64,11 @@
     [:strong "Add some cards!"]
     ;; else
     [:div.row
-      [:div.col-md-2
+      [:div.col-md-6
         [card-type-list cards "Creature"]
         [card-type-list cards "Land"]]
       (let [noncreature-cards (remove-cards-by-type cards "Creature")]
-        [:div.col-md-2
+        [:div.col-md-6
           [card-type-list cards "Planeswalker"]
           [card-type-list cards "Instant"]
           [card-type-list cards "Sorcery"]
@@ -124,7 +126,10 @@
                     [:p.text-right (str (count (remove-cards-by-type @card-data/card-list "Creature"))) " Non-creature Spells"]
                     [:p.text-right (str (count (filter-cards-by-type @card-data/card-list "Creature"))) " Creatures"]
                     [:p.text-right (str (count (filter-cards-by-type @card-data/card-list "Land"))) " Lands"]]]
-        [:div.row [card-list @card-data/card-list]]]])
+        [:div.col-md-4 [card-list @card-data/card-list]]
+        [:div.col-md-4 (if (clojure.string/blank? @displayed-card-url)
+                         [:div [:b "Click on a card!"]]
+                         (card-img @displayed-card-url))]]])

 (defn about-page []
   [:div [:h2 "About decktouch"]


Fix error.

Fix error.

--- src/cljs/nonojure/utils.cljs
+++ src/cljs/nonojure/utils.cljs
@@ -7,7 +7,6 @@
   (let [xhr (.-target evt)
         json-data (.getResponseJson xhr)
         clj-data (js->clj json-data)]
-    (log clj-data)
     (when on-success
      (on-success clj-data))))


[n.u.menu] Don't die if :show-as-action vector has one value

--- src/clojure/neko/ui/menu.clj
+++ src/clojure/neko/ui/menu.clj
@@ -117,7 +117,7 @@
   which bit-or operation will be applied."
   [^MenuItem wdg, {:keys [show-as-action]} _]
   (let [value (if (vector? show-as-action)
-                (apply bit-or (map show-as-action-value show-as-action))
+                (apply bit-or 0 (map show-as-action-value show-as-action))
                 (show-as-action-value show-as-action))]
     (.setShowAsAction wdg value)))


Now calling init in main

Now calling init in main

--- src/clojure_todo/handler.clj
+++ src/clojure_todo/handler.clj
@@ -138,4 +138,5 @@
   (run-jetty #'app {:port port :join? false}))

 (defn -main [port]
+  (init)
   (start (Integer/parseInt port)))


Lazy load next page on search

Lazy load next page on search

--- src/shokunin/cmr.clj
+++ src/shokunin/cmr.clj
@@ -3,21 +3,21 @@
             [clojure.data.json :as json]
             [clojure.string :as string]))

-(defn search [url params]
-  (let [defaults {:accept :json }
-        params+  (merge-with merge defaults params)
-        resp     (client/get url params+)
-        body     (client/json-decode (resp :body))]
-    body))
-
-(defn hits
+(defn hits-count
   ""
   [url params]
   (let [response (client/head url params)
         cmr-hits (get-in response [:headers "CMR-hits"])]
     (or (Integer/parseInt cmr-hits) 0)))

-(defn search
+(defn page-count
+  ""
+  [url params]
+  (let [hits (hits-count url params)
+        size (get-in params [:query-params :page-size])]
+    (-> hits (/ size) Math/ceil int)))
+
+(defn query
   ""
   [url params]
   (let [defaults {:accept :json }
@@ -28,24 +28,20 @@

 (defn http-seq
   ""
-  ;; this doesn't *set* defaults in the map... careful.
-  ([url {{:keys [page-num page-size]} :query-params
-          :or {page-num 1 page-size 10}
-          :as params}]
-     (let [last-page (int (Math/ceil (/ (hits url params) page-size)))
-           opts {:last-page last-page}]
+  ([url params]
+     (let [opts {:last-page (page-count url params)}]
        (http-seq url params opts)))
   ([url {{:keys [page-num page-size]} :query-params :as params}
         {:keys [last-page] :as opts}]
-       (let [entries     (get-in (search url params) ["feed" "entries"])
-             next-params (update-in params [:query-params :page-num] inc)]
-         (<= page-num last-page)
-         (concat entries (lazy-seq (http-seq url next-params opts))))))
+       (let [results     (get-in (query url params) ["feed" "entry"])
+             next-params (update-in params [:query-params :page-num] inc)
+             more-pages  (< page-num last-page)]
+         (lazy-cat results (if more-pages (http-seq url next-params opts))))))

-; an example
-(def params { :query-params {:short-name "MOD09A1" :page-num 1 :page-size 10}})
-(def opts {:last-page 10})
-(def url "https://cmr.earthdata.nasa.gov/search/granules")
-(def result (http-seq url params opts))
-(map #(get % "title") (take 2 result))
+(comment "usage example"
+  (let [params  { :query-params {:short-name "MOD09A1" :page-num 1 :page-size 25}}
+        url     "https://cmr.earthdata.nasa.gov/search/granules"
+        results (http-seq url params)]
+    (map #(get % "title") (take 5 results)))
+  results)


advanced mode can bite you quite well

advanced mode can bite you quite well

--- src/showkr/data.cljs
+++ src/showkr/data.cljs
@@ -33,7 +33,7 @@
                   :extras "original_format,description,path_alias"}
       (fn [data]
         (swap! world assoc-in [:sets id]
-          (with-meta (js->clj (.-photoset data) :keywordize-keys true)
+          (with-meta (js->clj (aget data "photoset") :keywordize-keys true)
             {:state :fetched}))))))

 (defn fetch-comments [set-id idx]
@@ -45,7 +45,7 @@
                     :photo_id (:id photo)}
         (fn [data]
           (swap! world assoc-in [:sets set-id :photo idx :comments]
-            (with-meta (js->clj (.-comments data) :keywordize-keys true)
+            (with-meta (js->clj (aget data "comments") :keywordize-keys true)
               {:state :fetched})))))))

 (defn fetch-user-sets [username]
@@ -57,7 +57,7 @@
                     :user_id (:id user)}
         (fn [data]
           (swap! world assoc-in [:users username :sets]
-            (with-meta (js->clj (.-photosets data) :keywordize-keys true)
+            (with-meta (js->clj (aget data "photosets") :keywordize-keys true)
               {:state :fetched})))))))

 (defn fetch-user [username]
@@ -68,7 +68,7 @@
                   :url (str "https://flickr.com/photos/" username)}
       (fn [data]
         (swap! world assoc-in [:users username]
-          (with-meta (js->clj (.-user data) :keywordize-keys true)
+          (with-meta (js->clj (aget data "user") :keywordize-keys true)
             {:state :fetched}))
         (fetch-user-sets username)
         #_ (fetch-user-info username)))))


wrapping receive in async/go (#309)

wrapping receive in async/go (#309)

--- server/src/spacon/components/mqtt/core.clj
+++ server/src/spacon/components/mqtt/core.clj
@@ -86,10 +86,10 @@
   ([mqtt-comp topic]
    (if (or (nil? @conn) (not (mh/connected? @conn)))
      (do (connectmqtt (:broker-url mqtt-comp))))
-   (log/debug "Subscribing to topic" topic)
+   (log/debugf "Subscribing to topic" topic)
    (mh/subscribe @conn {topic 2}
                  (fn [^String topic _ ^bytes payload]
-                   (receive mqtt-comp topic payload))
+                   (async/go (receive mqtt-comp topic payload)))
                  {:on-connection-lost (partial subscribe-mqtt mqtt-comp (:broker-url mqtt-comp))}))
   ([mqtt-comp]
    (doall (map (fn [topic-key]


Fix formatting

Fix formatting

--- src/braid/search/ui/search_page.cljs
+++ src/braid/search/ui/search_page.cljs
@@ -36,12 +36,12 @@
       (let [threads @(subscribe [:threads])
             loaded-threads (vals (select-keys threads thread-ids))
             sorted-threads (->> loaded-threads
-                                        ; sort-by last reply, newest first
-                               (sort-by
-                                 (comp (partial apply max)
-                                       (partial map :created-at)
-                                       :messages)
-                                 #(compare %2 %1)))]
+                                ;; sort-by last reply, newest first
+                                (sort-by
+                                  (comp (partial apply max)
+                                        (partial map :created-at)
+                                        :messages)
+                                  #(compare %2 %1)))]
         [:div.page.search
          [:div.title (str "Search for \"" query "\"")]
          [:div.content
@@ -74,10 +74,10 @@
            (fn [e]
              (let [target-classes (.. e -target -classList)
                    this-elt (.. e -target)]
-                                        ; TODO: check if threads-div needs to scroll?
+               ;; TODO: check if threads-div needs to scroll?
                (when (and (or (.contains target-classes "thread")
                               (.contains target-classes "threads"))
-                          (= 0 (.-deltaX e) (.-deltaZ e)))
+                       (= 0 (.-deltaX e) (.-deltaZ e)))
                  (set! (.-scrollLeft this-elt)
                        (- (.-scrollLeft this-elt) (.-deltaY e))))))}
           (doall


Add type hints to eliminate reflection.

Add type hints to eliminate reflection.

--- src/soy_clj/core.clj
+++ src/soy_clj/core.clj
@@ -5,10 +5,11 @@
             [clojure.set :as set]
             [clojure.string :as string]
             [clojure.walk :as walk])
-  (:import (com.google.template.soy SoyFileSet)
+  (:import (com.google.template.soy SoyFileSet SoyFileSet$Builder)
            (com.google.template.soy.data SanitizedContent$ContentKind
                                          UnsafeSanitizedContentOrdainer)
-           (com.google.template.soy.shared SoyGeneralOptions)))
+           (com.google.template.soy.shared SoyGeneralOptions)
+           (com.google.template.soy.tofu SoyTofu)))

 (def ^:private template-cache
   "Default to keeping the 32 most-used templates in cache."
@@ -22,7 +23,9 @@

 (defn- parse-uncached
   [files]
-  (let [builder (reduce #(.add %1 (io/resource %2)) (SoyFileSet/builder) files)
+  (let [^SoyFileSet$Builder builder
+        (reduce #(.add ^SoyFileSet$Builder %1 (io/resource %2))
+                (SoyFileSet/builder) files)
         opts (SoyGeneralOptions.)]
     (.setStrictAutoescapingRequired opts true)
     (.setGeneralOptions builder opts)
@@ -49,7 +52,7 @@
     (string/join (cons (string/lower-case (first uc)) (next uc)))))

 (defn- camelize-keys
-  [m]
+  ^java.util.Map [m]
   (let [f (fn [[k v]] (if (keyword? k) [(camel-case k) v] [k v]))]
     ;; only apply to maps
     (walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
@@ -69,7 +72,7 @@
   data and returns the result as a string as well as the _kind_ of data in the
   template (e.g. `:html`). Data keys of the form `:one-two` are converted into
   template variables of the form `oneTwo`."
-  [templates template-name data]
+  [^SoyTofu templates ^String template-name data]
   (let [content (.. templates
                     (newRenderer template-name)
                     (setData (camelize-keys data))


check for nil before deref state atom

check for nil before deref state atom

--- src-cljs/frontend/utils.cljs
+++ src-cljs/frontend/utils.cljs
@@ -57,7 +57,8 @@

 (defn logging-enabled? []
   (let [from-query-map (:logging-enabled? initial-query-map)
-        from-browser-settings (get-in @state/debug-state state/logging-enabled-path)
+        from-browser-settings (and state/debug-state
+                                   (get-in @state/debug-state state/logging-enabled-path))
         from-config (config/logging-enabled?)]
     (cond
       (= (type from-query-map) js/Boolean) from-query-map


working  graphing

working  graphing

--- src/conj_2016/util/graph.clj
+++ src/conj_2016/util/graph.clj
@@ -1,33 +1,48 @@
 (ns conj-2016.util.graph
-  (:require [dali.io :as d.io]))
+  (:require [dali.io :as d.io]
+            [taoensso.timbre :as log]))

-(def circle-radius 1)
-(def circle-stroke-width 1)
 (def label-font-size 5)
+(def label-percentage-size 0.1)
+(def page-border 10)

 (defn label
-  [title]
-  [:dali/place {:relative-to [(keyword title) :bottom]
-                :anchor :bottom
-                :offset [0 -2]}
-   [:text
-    {:font-size label-font-size :stroke :black :fill :black}
-    title]])
-
-(defn labelled-circle
   [title x y]
-  [[:circle {:id (keyword title)
-             :cx x :cy y
-             :r circle-radius
-             :stroke {:width circle-stroke-width}}]
-   (label title)])
+  [:text {:font-size label-font-size
+          :x x
+          :y y
+          :fill :black}
+   title])

 (defn page
   [coords titles]
-  [:dali/page
-   (reduce concat
-           []
+  (let [xs (map first coords)
+        min-x (apply min xs)
+        max-x (apply max xs)
+        ys (map second coords)
+        min-y (apply min ys)
+        max-y (apply max ys)
+        min-diff (min (Math/abs (- max-x min-x)) (Math/abs (- max-y min-y)))
+        scale (/ (max min-diff (/ label-font-size label-percentage-size))
+                 min-diff)
+        adjust-coord (fn [c min-c]
+                       (-> c
+                           (- min-c)
+                           (* scale)
+                           (+ page-border)))
+        adjusted-coords (map (fn [[x y]]
+                               [(adjust-coord x min-x)
+                                (adjust-coord y min-y)])
+                             coords)]
+    (apply vector
+           :dali/page
            (map (fn [title [x y]]
-                  (labelled-circle title x y))
+                  (label title x y))
                 titles
-                coords))])
+                adjusted-coords))))
+
+(comment
+  (try
+    (d.io/render-svg (page [[1 2] [3 4] [-1.5 3.1]] ["a" "b" "c"]) "/tmp/dali.demo.svg")
+    (catch Exception e
+      (log/error e))))


Save panel width to localstorage

Save panel width to localstorage

--- src/day8/re_frame/trace.cljs
+++ src/day8/re_frame/trace.cljs
@@ -270,7 +270,8 @@
   ;; Add clear button
   ;; Filter out different trace types
   (let [position          (r/atom :right)
-        panel-width-ratio (r/atom 0.35)
+        panel-width-ratio (r/atom (or (localstorage/get "panel-width-ratio")
+                                      0.35))
         showing?          (r/atom false)
         dragging?         (r/atom false)
         pin-to-bottom?    (r/atom true)
@@ -295,6 +296,11 @@
                                    y (.-clientY e)]
                                (.preventDefault e)
                                (reset! panel-width-ratio (/ (- window-width x) window-width)))))]
+
+    (add-watch panel-width-ratio
+               :update-panel-width-ratio
+               (fn [_ _ _ new-state]
+                 (localstorage/save! "panel-width-ratio" new-state)))
     (r/create-class
       {:component-will-mount   (fn []
                                  (js/window.addEventListener "keydown" handle-keys)


[#233] update test

[#233] update test

--- api/test/clojure/org/akvo/flow_api/datastore/survey_test.clj
+++ api/test/clojure/org/akvo/flow_api/datastore/survey_test.clj
@@ -34,6 +34,7 @@
       (are [x required-keys] (= (disj (set (keys x))
                                       :variable-name
                                       :modified-at
+                                      :version
                                       :created-at)
                                 required-keys)
         survey #{:id :name :forms :registration-form-id}


Add more ansi-codes to toggle attributes

--- src/zprint/ansi.cljc
+++ src/zprint/ansi.cljc
@@ -7,12 +7,22 @@

 (def ansi-codes
   {:off 0,
+   :reset 0,
    :bold 1,
+   :faint 2,
+   :italic 3,
    :underline 4,
    :blink 5,
    :reverse 7,
    :hidden 8,
    :strike 9,
+   :normal 22,
+   :italic-off 23,
+   :underline-off 24,
+   :blink-off 25,
+   :reverse-off 27,
+   :hidden-off 28,
+   :strike-off 29,
    :black 30,
    :none 30,
    :red 31,


core: use pure components.

core: use pure components.

we can switch over to om when we need it.

--- src/cfg/core.cljs
+++ src/cfg/core.cljs
@@ -93,92 +93,78 @@
   (str "0x" (string/upper-case (.toString n 16))))

-(defui BasicBlock
-  Object
-  (render
-   [this]
+(defn basicblock
+  [props]
+  (dom/div
+   {:class "basic-block"}
+   (dom/div {:class "bb-header"})
    (dom/div
-    {:class "basic-block"}
-    (dom/div {:class "bb-header"})
+    {:class "bb-content"}
+    (dom/table
+     (dom/thead)
+     (dom/tbody
+      (for [insn (:instructions props)]
+        (dom/tr {:key (str (:addr insn)) :class "insn"}
+                (dom/td {:class "addr"}
+                        (hex-format (:addr insn)))
+                (dom/td {:class "padding-1"})
+                (dom/td {:class "bytes"}
+                        (string/upper-case (:bytes insn)))
+                (dom/td {:class "padding-2"})
+                (dom/td {:class "mnem"}
+                        (:mnem insn))
+                (dom/td {:class "padding-3"})
+                (dom/td {:class "operands"}
+                        (:operands insn))
+                (dom/td {:class "padding-4"})
+                (dom/td {:class "comments"}
+                        (when (and (:comments insn)
+                                   (not= "" (:comments insn)))
+                          (str ";  " (:comments insn)))))))))))
+
+
+
+(defn function-list
+  [props]
+  (let [functions (:functions props)
+        functions (sort-by :name functions)
+        on-select-function (:select-function props)]
     (dom/div
-     {:class "bb-content"}
-     (dom/table
-      (dom/thead)
-      (dom/tbody
-       (for [insn (:instructions (om/props this))]
-         (dom/tr {:key (str (:addr insn)) :class "insn"}
-                 (dom/td {:class "addr"}
-                         (hex-format (:addr insn)))
-                 (dom/td {:class "padding-1"})
-                 (dom/td {:class "bytes"}
-                         (string/upper-case (:bytes insn)))
-                 (dom/td {:class "padding-2"})
-                 (dom/td {:class "mnem"}
-                         (:mnem insn))
-                 (dom/td {:class "padding-3"})
-                 (dom/td {:class "operands"}
-                         (:operands insn))
-                 (dom/td {:class "padding-4"})
-                 (dom/td {:class "comments"}
-                         (when (and (:comments insn)
-                                    (not= "" (:comments insn)))
-                           (str ";  " (:comments insn))))))))))))
-
-
-(def basicblock (om/factory BasicBlock))
-
-
-(defui FunctionList
-  Object
-  (render
-   [this]
-   (let [props (om/props this)
-         functions (:functions props)
-         functions (sort-by :name functions)
-         on-select-function (:select-function (om/get-computed this))]
-     (dom/div
-      {:class "function-list"}
-      (dom/h3 {:class "title"}
-              "functions (" (count functions) " total):")
-      (dom/ul
-       (for [function functions]
-         (dom/li {:key (str (:offset function))
-                  :class "function"
-                  :onClick #(on-select-function (:offset function))}
-                 (dom/span {:class "offset"}
-                           (hex-format (:offset function)))
-                 ": "
-                 (dom/span {:class "name"}
-                           (:name function))
-                 " ("
-                 (dom/span {:class "basic-block-count"}
-                           (:nbbs function))
-                 ")")))))))
-
-(def function-list (om/factory FunctionList))
-
-
-(defui BasicBlockList
-  Object
-  (render
-   [this]
-   (let [props (om/props this)
-         bbs (:basic-blocks props)
-         bbs (sort-by :addr bbs)
-         on-select-bb (:select-bb (om/get-computed this))]
-     (dom/div
-      {:class "bb-list"}
-      (dom/h3 {:class "title"}
-              "basic blocks (" (count bbs) " total):")
-      (dom/ul
-       (for [bb bbs]
-         (dom/li {:key (str (:addr bb))
-                  :class "bb"
-                  :onClick #(on-select-bb (:addr bb))}
-                 (dom/span {:class "offset"}
-                           (hex-format (:addr bb))))))))))
-
-(def basic-block-list (om/factory BasicBlockList))
+     {:class "function-list"}
+     (dom/h3 {:class "title"}
+             "functions (" (count functions) " total):")
+     (dom/ul
+      (for [function functions]
+        (dom/li {:key (str (:offset function))
+                 :class "function"
+                 :onClick #(on-select-function (:offset function))}
+                (dom/span {:class "offset"}
+                          (hex-format (:offset function)))
+                ": "
+                (dom/span {:class "name"}
+                          (:name function))
+                " ("
+                (dom/span {:class "basic-block-count"}
+                          (:nbbs function))
+                ")"))))))
+
+
+(defn basic-block-list
+  [props]
+  (let [bbs (:basic-blocks props)
+        bbs (sort-by :addr bbs)
+        on-select-bb (:select-bb props)]
+    (dom/div
+     {:class "bb-list"}
+     (dom/h3 {:class "title"}
+             "basic blocks (" (count bbs) " total):")
+     (dom/ul
+      (for [bb bbs]
+        (dom/li {:key (str (:addr bb))
+                 :class "bb"
+                 :onClick #(on-select-bb (:addr bb))}
+                (dom/span {:class "offset"}
+                          (hex-format (:addr bb)))))))))

 (def sqrt (.-sqrt js/Math))
@@ -328,61 +314,46 @@
             y2 (:y end)]
         (line x1 y1 x2 y2)))))

-
-(defui App
-  Object
-  (render
-   [this]
+(defn app
+  [props]
+  (dom/div
+   {:class "app"}
    (dom/div
-    {:class "app"}
-    (dom/div
-     {:class "panels"}
-     (function-list
-      (om/computed {:functions (vals (:functions (om/props this)))}
-                   {:select-function (fn [fva]
-                                       (update-model! {:selected-function fva})
-                                       (go
-                                         (let [afbj (<! (r2/get-basic-blocks fva))
-                                               basic-blocks (:response afbj)]
-                                           (update-model! [:functions fva :basic-blocks] basic-blocks)
-                                           (doseq [basic-block basic-blocks]
-                                             (go
-                                               (let [addr (:addr basic-block)
-                                                     ninstr (:ninstr basic-block)
-                                                     aoj (<! (r2/get-instructions addr ninstr))
-                                                     insns (map r2->insn (:response aoj))
-                                                     changes (assoc basic-block :instructions insns)]
-                                                 (update-model! [:basic-blocks addr] changes)))))))}))
-     (let [props (om/props this)]
-       (when (:selected-function props)
-         (let [fva (:selected-function props)
-               function (get-in props [:functions fva])
-               basic-blocks (:basic-blocks function)]
-           (basic-block-list
-            (om/computed {:basic-blocks basic-blocks}
-                         {:select-bb #(update-model! {:selected-basic-block %})}))))))
-    (if (:selected-function (om/props this))
-      (let [props (om/props this)
-            fva (:selected-function props)
+    {:class "panels"}
+    (function-list
+     {:functions (vals (:functions props))
+      :select-function (fn [fva]
+                         (update-model! {:selected-function fva})
+                         (go
+                           (let [afbj (<! (r2/get-basic-blocks fva))
+                                 basic-blocks (:response afbj)]
+                             (update-model! [:functions fva :basic-blocks] basic-blocks)
+                             (doseq [basic-block basic-blocks]
+                               (go
+                                 (let [addr (:addr basic-block)
+                                       ninstr (:ninstr basic-block)
+                                       aoj (<! (r2/get-instructions addr ninstr))
+                                       insns (map r2->insn (:response aoj))
+                                       changes (assoc basic-block :instructions insns)]
+                                   (update-model! [:basic-blocks addr] changes)))))))})
+    (when (:selected-function props)
+      (let [fva (:selected-function props)
             function (get-in props [:functions fva])
-            basic-blocks (:basic-blocks function)
-            basic-blocks (map #(get-in props [:basic-blocks (:addr %)]) basic-blocks)
-            g (layout-cfg basic-blocks)]
-        (canvas
-         {}
-         [(for [bb (:nodes g)]
+            basic-blocks (:basic-blocks function)]
+        (basic-block-list {:basic-blocks basic-blocks
+                           :select-bb #(update-model! {:selected-basic-block %})}))))
+   (when (:selected-function props)
+     (let [fva (:selected-function props)
+           function (get-in props [:functions fva])
+           basic-blocks (:basic-blocks function)
+           basic-blocks (map #(get-in props [:basic-blocks (:addr %)]) basic-blocks)
+           g (layout-cfg basic-blocks)]
+       (canvas
+        {}
+        [(for [bb (:nodes g)]
            (positioned bb (basicblock bb)))
-          (for [edge (:edges g)]
-           (edge-line edge))]))
-      (canvas
-       {}
-       (multi-line {}
-         [(line 1 1 6 9)
-          (line 1 1 9 6)]))))))
-
-
-
-(def app (om/factory App))
+         (for [edge (:edges g)]
+           (edge-line edge))])))))

 (defn- render!